File Coverage

blib/lib/KiokuDB/Backend.pm
Criterion Covered Total %
statement 15 23 65.2
branch 1 4 25.0
condition n/a
subroutine 5 7 71.4
pod 3 3 100.0
total 24 37 64.8


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package KiokuDB::Backend;
4 23     23   9764 use Moose::Role;
  23         32965  
  23         137  
5              
6 23     23   86199 use Moose::Util::TypeConstraints;
  23         45  
  23         155  
7 23     23   37222 use Try::Tiny;
  23         41  
  23         1560  
8              
9 23     23   114 use namespace::clean -except => 'meta';
  23         32  
  23         204  
10              
11             coerce ( __PACKAGE__,
12             from HashRef => via {
13             my %p = %$_;
14             my $class = delete $p{class} || die "Can't coerce backend from hash without a 'class' parameter";
15              
16             try {
17             Class::MOP::load_class("KiokuDB::Backend::$class");
18             "KiokuDB::Backend::$class"->new(%p);
19             } catch {
20             Class::MOP::load_class($class);
21             $class->new(%p);
22             };
23             },
24             );
25              
26             requires qw(
27             exists
28             insert
29             get
30             delete
31             );
32              
33             sub new_from_dsn {
34 52     52 1 187 my ( $class, $params, @extra ) = @_;
35              
36 52 50       178 if ( defined $params ) {
37 0         0 $class->new_from_dsn_params($class->parse_dsn_params($params), @extra);
38             } else {
39 52         1838 return $class->new(@extra);
40             }
41             }
42              
43             sub new_from_dsn_params {
44 0     0 1   my ( $class, @params ) = @_;
45 0           $class->new(@params);
46             }
47              
48             sub parse_dsn_params {
49 0     0 1   my ( $self, $params ) = @_;
50              
51 0           my @pairs = split ';', $params;
52              
53 0           return map {
54 0           my ( $key, $value ) = /(\w+)(?:=(.*))/;
55 0 0         length($value) ? ( $key, $value ) : ( $key => 1 );
56             } @pairs;
57             }
58              
59             __PACKAGE__
60              
61             __END__
62              
63             =pod
64              
65             =head1 NAME
66              
67             KiokuDB::Backend - Backend interface role
68              
69             =head1 SYNOPSIS
70              
71             package KiokuDB::Backend::Foo;
72             use Moose;
73              
74             # load the core api and additional interfaces based on backend capabilities
75             with qw(
76             KiokuDB::Backend
77              
78             KiokuDB::Backend::Role::TXN
79             KiokuDB::Backend::Role::Clear
80             KiokuDB::Backend::Role::Scan
81             KiokuDB::Backend::Role::UnicodeSafe
82             KiokuDB::Backend::Role::BinarySafe
83             );
84              
85             sub insert { ... }
86              
87             sub get { ... }
88              
89             sub delete { ... }
90              
91             sub exists { ... }
92              
93              
94              
95             # use the backend like this:
96              
97             my $dir = KiokuDB->new(
98             backend => KiokuDB::Backend::Foo->new( );
99             );
100              
101             =head1 DESCRIPTION
102              
103             L<KiokuDB> is designed to be fairly backend agnostic.
104              
105             This role defines the minimal API for writing new backends.
106              
107             =head1 TRANSACTIONS
108              
109             This role is supplemented by L<KiokuDB::Backend::Role::TXN>, a role for
110             first class transaction support that issues rollbacks using the
111             L<KiokuDB::Entry> objects.
112              
113             =head1 QUERYING
114              
115             This role is supplemented by L<KiokuDB::Backend::Role::Query>, a role for
116             backend specific queries.
117              
118             L<KiokuDB::Backend::Role::Query::Simple> provides a universal query api for
119             backends that can perform property based lookup.
120              
121             L<KiokuDB::Backend::Role::Query::GIN> is a role for using L<Search::GIN> based
122             indexing/querying with backends that do not natively support querying.
123              
124             =head1 REQUIRED METHODS
125              
126             =over 4
127              
128             =item get @ids
129              
130             Retrieve the L<KiokuDB::Entry> objects associated with the @ids.
131              
132             If any other error is encountered, this method should die.
133              
134             The backend may store private data in C<backend_data>, to be used in a subsequent update.
135              
136             Returns a list of L<KiokuDB::Entry>, with the order corresponding to C<@ids>.
137             If an entry does not exist then C<undef> should be returned in place of it. The
138             backend may abort retrieval on the first non existent entry.
139              
140             =item insert @entries
141              
142             Insert entries to the store.
143              
144             If the backend is transactional this operation should be atomic with respect to
145             the inserted/updated data.
146              
147             The backend is required to store the data in the fields C<data>, C<class> using
148             the key in C<id>.
149              
150             Entries which have an entry in C<prev> denote updates (either objects that have
151             been previously stored, or objects that were looked up). The previous entry may
152             be used to compare state for issuing a partial update, and will contain the
153             value of C<backend_data> for any other state tracking.
154              
155             C<object> is a weak reference to the object this entry is representing, and may
156             be used for high level indexing. Do not use this field for storage.
157              
158             If this backend implements some form of garbage collection, C<root> denotes
159             that the objects is part of the root set.
160              
161             After all entries have been successfully written, C<backend_data> should be set
162             if necessary just as in C<get>.
163              
164             Has no return value.
165              
166             If C<insert> does not die the write is assumed to be successful.
167              
168             =item delete @ids_or_entries
169              
170             Delete the specified IDs or entries.
171              
172             If the user provided objects then entries will be passed in. Any associated
173             state the entries may have (e.g. a revision) should be used in order to enforce
174             atomicity with respect to the time when the objects were loaded.
175              
176             After all entries have been successfully deleted, C<deleted> should be set. The
177             entry passed in is the same one as was loaded by C<get> or last written by
178             C<insert>, so it is already up to date in the live objects.
179              
180             Has no return value.
181              
182             If C<delete> does not die the write is assumed to be successful.
183              
184             =item exists @ids
185              
186             Check for existence of the specified IDs, without retrieving their data.
187              
188             Returns a list of true or false values.
189              
190             =back
191              
192             =head1 METHODS
193              
194             These methods are provided by the L<KiokuDB::Backend> role, and may be overridden.
195              
196             =over 4
197              
198             =item new_from_dsn
199              
200             Parses the second half of the DSN using C<parse_dsn_params> and instantiates a
201             new object using C<new_from_dsn>.
202              
203             See L<KiokuDB::Util>.
204              
205             =item new_from_dsn_params @args
206              
207             Takes DSN parameters and converts them to arguments suitable for C<new>
208              
209             =item parse_dsn_params $str
210              
211             The string is split on C<;> to produce arguments. Arguments in the form
212             C<foo=bar> are split on C<=> into a key/value pair, and other arguments are
213             treated as a boolean key and returned as C<< $arg => 1 >>.
214              
215             =back
216              
217             =head1 ADDITIONAL INTERFACES
218              
219             Your backend may include more roles, based on its capabilities.
220              
221             =over 4
222              
223             =item L<KiokuDB::Backend::Serialize>
224              
225             =item L<KiokuDB::Backend::Serialize::Delegate>
226              
227             For the actual serialization of entries, there are a number of serialization
228             roles.
229              
230             =item L<KiokuDB::Backend::Role::Clear>
231              
232             API for clearing all entries.
233              
234             =item L<KiokuDB::Backend::Role::Scan>
235              
236             API for enumerating entries.
237              
238             =item L<KiokuDB::Backend::Role::BinarySafe>
239              
240             =item L<KiokuDB::Backend::Role::UnicodeSafe>
241              
242             If your serialization is able to store arbitrary binary data and/or unicode
243             strings, these informational roles should be included.
244              
245             =item L<KiokuDB::Backend::Role::TXN>
246              
247             If your storage supports nested transactions (C<txn_begin>, C<txn_commit> etc)
248             this role provides the api to expose that functionality to the high level
249             L<KiokuDB> api.
250              
251             =item L<KiokuDB::Backend::Role::Query>
252              
253             =item L<KiokuDB::Backend::Role::Query::GIN>
254              
255             If your backend supports querying of some sort, these are the roles to include.
256              
257             The querying API uses backend specific lookups to fetch entries, which
258             L<KiokuDB> will then relink into result objects.
259              
260             =back
261              
262             =head1 SHARED BACKENDS
263              
264             A backend may be shared by several L<KiokuDB> instances, each with its own
265             distinct live object set. The backend may choose to share cached entry B<data>,
266             as that is not mutated by L<KiokuDB::Linker>, but not the L<KiokuDB::Entry>
267             instances themselves.
268              
269             =cut
270              
271