]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher.pm
removing "warn"s
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Storage / Publisher.pm
1 package OpenILS::Application::Storage::Publisher;
2 use base qw/OpenILS::Application::Storage/;
3 our $VERSION = 1;
4
5 use Data::Dumper;
6 use OpenSRF::EX qw/:try/;;
7 use OpenSRF::Utils::Logger;
8 my $log = 'OpenSRF::Utils::Logger';
9
10 use OpenILS::Utils::Fieldmapper;
11 #use OpenILS::Application::Storage::CDBI;
12
13 #use OpenILS::Application::Storage::CDBI::actor;
14 #use OpenILS::Application::Storage::CDBI::asset;
15 #use OpenILS::Application::Storage::CDBI::biblio;
16 #use OpenILS::Application::Storage::CDBI::config;
17 #use OpenILS::Application::Storage::CDBI::metabib;
18
19 sub register_method {
20         my $class = shift;
21         my %args = @_;
22         my %dup_args = %args;
23
24         $class = ref($class) || $class;
25
26         $args{package} ||= $class;
27         __PACKAGE__->SUPER::register_method( %args );
28
29         if (exists($dup_args{cachable}) and $dup_args{cachable}) {
30                 (my $name = $dup_args{api_name}) =~ s/^open-ils\.storage/open-ils.storage.cachable/o;
31                 if ($name ne $dup_args{api_name}) {
32                         $dup_args{real_api_name} = $dup_args{api_name};
33                         $dup_args{method} = 'cachable_wrapper';
34                         $dup_args{api_name} = $name;
35                         $dup_args{package} = __PACKAGE__;
36                         __PACKAGE__->SUPER::register_method( %dup_args );
37                 }
38         }
39 }
40
41 sub cachable_wrapper {
42         my $self = shift;
43         my $client = shift;
44         my @args = @_;
45
46         my %cache_args = (
47                 limit   => 100,
48                 offset  => 0,
49                 timeout => 300,
50         );
51
52         my @real_args;
53         my $key_string = $self->api_name;
54         for (my $ind = 0; $ind < scalar(@args); $ind++) {
55                 if (    "$args[$ind]" eq 'limit' ||
56                         "$args[$ind]" eq 'offset' ||
57                         "$args[$ind]" eq 'timeout' ) {
58
59                         my $key_ind = $ind;
60                         $ind++;
61                         my $value_ind = $ind;
62                         $cache_args{$args[$key_ind]} = $args[$value_ind];
63                         $log->debug("Cache limiter value for $args[$key_ind] is $args[$value_ind]", DEBUG);
64                         next;
65                 }
66                 $key_string .= $args[$ind];
67                 push @real_args, $args[$ind];
68         }
69
70         my $cache_key = md5_hex($key_string);
71
72         my $cached_res = OpenSRF::Utils::Cache->new->get_cache( $cache_key );
73         if (defined $cached_res) {
74                 $log->debug("Found ".scalar(@$cached_res)." records in the cache", INFO);
75                 $log->debug("Values from cache: ".join(', ', @$cached_res), INTERNAL);
76                 $client->respond( $_ ) for ( grep { defined } @$cached_res[$cache_args{offset} .. int($cache_args{offset} + $cache_args{limit} - 1)] );
77                 return undef;
78         }
79
80         my $method = $self->method_lookup($self->{real_api_name});
81         my @res = $method->run(@real_args);
82
83
84         $client->respond( $_ ) for ( grep { defined } @res[$cache_args{offset} .. int($cache_args{offset} + $cache_args{limit} - 1)] );
85
86         OpenSRF::Utils::Cache->new->put_cache( $cache_key => \@res => $cach_args{timeout});
87
88         return undef;
89 }
90
91 sub retrieve_node {
92         my $self = shift;
93         my $client = shift;
94         my @ids = @_;
95
96         my $cdbi = $self->{cdbi};
97
98         for my $id ( @ids ) {
99                 next unless ($id);
100
101                 my ($rec) = $cdbi->fast_fieldmapper($id);
102                 $client->respond( $rec ) if ($rec);
103
104                 last if ($self->api_name !~ /batch/o);
105         }
106         return undef;
107 }
108
109 sub search {
110         my $self = shift;
111         my $client = shift;
112         my $searches = shift;
113
114         my $cdbi = $self->{cdbi};
115
116         $log->debug("Searching $cdbi for { ".join(',', map { "$_ => $$searches{$_}" } keys %$searches).' }',DEBUG);
117
118         for my $obj ($cdbi->search($searches)) {
119                 $client->respond( $obj->to_fieldmapper );
120         }
121         return undef;
122 }
123
124 sub search_one_field {
125         my $self = shift;
126         my $client = shift;
127         my @terms = @_;
128
129         (my $search_type = $self->api_name) =~ s/.*\.(search[^.]*).*/$1/o;
130         (my $col = $self->api_name) =~ s/.*\.$search_type\.([^.]+).*/$1/;
131         my $cdbi = $self->{cdbi};
132
133         my $like = 0;
134         $like = 1 if ($search_type =~ /like$/o);
135
136         for my $term (@terms) {
137                 $log->debug("Searching $cdbi for $col using type $search_type, value '$term'",DEBUG);
138                 $client->respond( [ $cdbi->fast_fieldmapper($term,$col,$like) ] );
139         }
140         return undef;
141 }
142
143
144 sub create_node {
145         my $self = shift;
146         my $client = shift;
147         my $node = shift;
148
149         my $cdbi = $self->{cdbi};
150
151         my $success;
152         try {
153                 my $rec = $cdbi->create($node);
154                 $success = $rec->id if ($rec);
155         } catch Error with {
156                 $success = 0;
157         };
158
159         return $success;
160 }
161
162 sub update_node {
163         my $self = shift;
164         my $client = shift;
165         my $node = shift;
166
167         my $cdbi = $self->{cdbi};
168
169         return $cdbi->update($node);
170 }
171
172 sub mass_delete {
173         my $self = shift;
174         my $client = shift;
175         my $search = shift;
176
177         my $where = 'WHERE ';
178
179         my $cdbi = $self->{cdbi};
180         my $table = $cdbi->table;
181
182         my @keys = sort keys %$search;
183         
184         my @binds;
185         my @wheres;
186         for my $col ( @keys ) {
187                 if (ref($$search{$col}) and ref($$search{$col}) =~ /ARRAY/o) {
188                         push @wheres, "$col IN (" . join(',', map { '?' } @{ $$search{$col} }) . ')';
189                         push @binds, map { "$_" } @{ $$search{$col} };
190                 } else {
191                         push @wheres, "$col = ?";
192                         push @binds, $$search{$col};
193                 }
194         }
195         $where .= join ' AND ', @wheres;
196
197         my $delete = "DELETE FROM $table $where";
198
199         $log->debug("Performing MASS deletion : $delete",DEBUG);
200
201         my $dbh = $cdbi->db_Main;
202         my $success = 1;
203         try {
204                 my $sth = $dbh->prepare($delete);
205                 $sth->execute( @binds );
206                 $sth->finish;
207                 $log->debug("MASS Delete succeeded",DEBUG);
208         } catch Error with {
209                 $log->debug("MASS Delete FAILED : ".shift(),DEBUG);
210                 $success = 0;
211         };
212         return $success;
213 }
214
215 sub delete_node {
216         my $self = shift;
217         my $client = shift;
218         my $node = shift;
219
220         my $cdbi = $self->{cdbi};
221
222         my $success = 1;
223         try {
224                 $success = $cdbi->delete($node);
225         } catch Error with {
226                 $success = 0;
227         };
228         return $success;
229 }
230
231 sub batch_call {
232         my $self = shift;
233         my $client = shift;
234         my @nodes = @_;
235
236         my $cdbi = $self->{cdbi};
237         my $api_name = $self->api_name;
238         (my $single_call_api_name = $api_name) =~ s/batch\.//o;
239
240         $log->debug("Default $api_name looking up $single_call_api_name...",INTERNAL);
241         my $method = $self->method_lookup($single_call_api_name);
242
243         my @success;
244         while ( my $node = shift(@nodes) ) {
245                 my ($res) = $method->run( $node ); 
246                 push(@success, 1) if ($res >= 0);
247         }
248
249         my $insert_total = 0;
250         $insert_total += $_ for (@success);
251
252         return $insert_total;
253 }
254
255 eval '
256 use OpenILS::Application::Storage::Publisher::actor;
257 use OpenILS::Application::Storage::Publisher::action;
258 use OpenILS::Application::Storage::Publisher::asset;
259 use OpenILS::Application::Storage::Publisher::biblio;
260 use OpenILS::Application::Storage::Publisher::config;
261 use OpenILS::Application::Storage::Publisher::metabib;
262 ';
263
264 for my $fmclass ( Fieldmapper->classes ) {
265         (my $cdbi = $fmclass) =~ s/^Fieldmapper:://o;
266         (my $class = $cdbi) =~ s/::.*//o;
267         (my $api_class = $cdbi) =~ s/::/./go;
268         my $registration_class = __PACKAGE__ . "::$class";
269         my $api_prefix = 'open-ils.storage.direct.'.$api_class;
270
271         # Create the search method
272         unless ( __PACKAGE__->is_registered( $api_prefix.'.search' ) ) {
273                 __PACKAGE__->register_method(
274                         api_name        => $api_prefix.'.search',
275                         method          => 'search',
276                         api_level       => 1,
277                         stream          => 1,
278                         cdbi            => $cdbi,
279                         cachable        => 1,
280                 );
281         }
282
283         # Create the retrieve method
284         unless ( __PACKAGE__->is_registered( $api_prefix.'.retrieve' ) ) {
285                 __PACKAGE__->register_method(
286                         api_name        => $api_prefix.'.retrieve',
287                         method          => 'retrieve_node',
288                         api_level       => 1,
289                         cdbi            => $cdbi,
290                         cachable        => 1,
291                 );
292         }
293
294         # Create the batch retrieve method
295         unless ( __PACKAGE__->is_registered( $api_prefix.'.batch.retrieve' ) ) {
296                 __PACKAGE__->register_method(
297                         api_name        => $api_prefix.'.batch.retrieve',
298                         method          => 'retrieve_node',
299                         api_level       => 1,
300                         stream          => 1,
301                         cdbi            => $cdbi,
302                         cachable        => 1,
303                 );
304         }
305
306         for my $field ($fmclass->real_fields) {
307                 unless ( __PACKAGE__->is_registered( $api_prefix.'.search.'.$field ) ) {
308                         __PACKAGE__->register_method(
309                                 api_name        => $api_prefix.'.search.'.$field,
310                                 method          => 'search_one_field',
311                                 api_level       => 1,
312                                 cdbi            => $cdbi,
313                                 cachable        => 1,
314                         );
315                 }
316                 unless ( __PACKAGE__->is_registered( $api_prefix.'.search_like.'.$field ) ) {
317                         __PACKAGE__->register_method(
318                                 api_name        => $api_prefix.'.search_like.'.$field,
319                                 method          => 'search_one_field',
320                                 api_level       => 1,
321                                 cdbi            => $cdbi,
322                                 cachable        => 1,
323                         );
324                 }
325         }
326
327
328         # Create the create method
329         unless ( __PACKAGE__->is_registered( $api_prefix.'.create' ) ) {
330                 __PACKAGE__->register_method(
331                         api_name        => $api_prefix.'.create',
332                         method          => 'create_node',
333                         api_level       => 1,
334                         cdbi            => $cdbi,
335                 );
336         }
337
338         # Create the batch create method
339         unless ( __PACKAGE__->is_registered( $api_prefix.'.batch.create' ) ) {
340                 __PACKAGE__->register_method(
341                         api_name        => $api_prefix.'.batch.create',
342                         method          => 'batch_call',
343                         api_level       => 1,
344                         cdbi            => $cdbi,
345                 );
346         }
347
348         # Create the update method
349         unless ( __PACKAGE__->is_registered( $api_prefix.'.update' ) ) {
350                 __PACKAGE__->register_method(
351                         api_name        => $api_prefix.'.update',
352                         method          => 'update_node',
353                         api_level       => 1,
354                         cdbi            => $cdbi,
355                 );
356         }
357
358         # Create the batch update method
359         unless ( __PACKAGE__->is_registered( $api_prefix.'.batch.update' ) ) {
360                 __PACKAGE__->register_method(
361                         api_name        => $api_prefix.'.batch.update',
362                         method          => 'batch_call',
363                         api_level       => 1,
364                         cdbi            => $cdbi,
365                 );
366         }
367
368         # Create the delete method
369         unless ( __PACKAGE__->is_registered( $api_prefix.'.delete' ) ) {
370                 __PACKAGE__->register_method(
371                         api_name        => $api_prefix.'.delete',
372                         method          => 'delete_node',
373                         api_level       => 1,
374                         cdbi            => $cdbi,
375                 );
376         }
377
378         # Create the batch delete method
379         unless ( __PACKAGE__->is_registered( $api_prefix.'.batch.delete' ) ) {
380                 __PACKAGE__->register_method(
381                         api_name        => $api_prefix.'.batch.delete',
382                         method          => 'batch_call',
383                         api_level       => 1,
384                         cdbi            => $cdbi,
385                 );
386         }
387
388         # Create the search-based mass delete method
389         unless ( __PACKAGE__->is_registered( $api_prefix.'.mass_delete' ) ) {
390                 __PACKAGE__->register_method(
391                         api_name        => $api_prefix.'.mass_delete',
392                         method          => 'mass_delete',
393                         api_level       => 1,
394                         cdbi            => $cdbi,
395                 );
396         }
397
398 }
399
400 1;