1 package OpenILS::Application::Storage::Publisher;
2 use base qw/OpenILS::Application::Storage/;
6 use OpenSRF::EX qw/:try/;;
7 use OpenSRF::Utils::Logger;
8 my $log = 'OpenSRF::Utils::Logger';
10 use OpenILS::Utils::Fieldmapper;
11 #use OpenILS::Application::Storage::CDBI;
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;
24 $class = ref($class) || $class;
26 $args{package} ||= $class;
27 __PACKAGE__->SUPER::register_method( %args );
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 );
41 sub cachable_wrapper {
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' ) {
62 $cache_args{$args[$key_ind]} = $args[$value_ind];
63 $log->debug("Cache limiter value for $args[$key_ind] is $args[$value_ind]", DEBUG);
66 $key_string .= $args[$ind];
67 push @real_args, $args[$ind];
70 my $cache_key = md5_hex($key_string);
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)] );
80 my $method = $self->method_lookup($self->{real_api_name});
81 my @res = $method->run(@real_args);
84 $client->respond( $_ ) for ( grep { defined } @res[$cache_args{offset} .. int($cache_args{offset} + $cache_args{limit} - 1)] );
86 OpenSRF::Utils::Cache->new->put_cache( $cache_key => \@res => $cach_args{timeout});
96 my $cdbi = $self->{cdbi};
101 my ($rec) = $cdbi->fast_fieldmapper($id);
102 $client->respond( $rec ) if ($rec);
104 last if ($self->api_name !~ /batch/o);
112 my $searches = shift;
114 my $cdbi = $self->{cdbi};
116 $log->debug("Searching $cdbi for { ".join(',', map { "$_ => $$searches{$_}" } keys %$searches).' }',DEBUG);
118 for my $obj ($cdbi->search($searches)) {
119 $client->respond( $obj->to_fieldmapper );
124 sub search_one_field {
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};
134 $like = 1 if ($search_type =~ /like$/o);
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) ] );
149 my $cdbi = $self->{cdbi};
153 my $rec = $cdbi->create($node);
154 $success = $rec->id if ($rec);
167 my $cdbi = $self->{cdbi};
169 return $cdbi->update($node);
177 my $where = 'WHERE ';
179 my $cdbi = $self->{cdbi};
180 my $table = $cdbi->table;
182 my @keys = sort keys %$search;
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} };
191 push @wheres, "$col = ?";
192 push @binds, $$search{$col};
195 $where .= join ' AND ', @wheres;
197 my $delete = "DELETE FROM $table $where";
199 $log->debug("Performing MASS deletion : $delete",DEBUG);
201 my $dbh = $cdbi->db_Main;
204 my $sth = $dbh->prepare($delete);
205 $sth->execute( @binds );
207 $log->debug("MASS Delete succeeded",DEBUG);
209 $log->debug("MASS Delete FAILED : ".shift(),DEBUG);
220 my $cdbi = $self->{cdbi};
224 $success = $cdbi->delete($node);
236 my $cdbi = $self->{cdbi};
237 my $api_name = $self->api_name;
238 (my $single_call_api_name = $api_name) =~ s/batch\.//o;
240 $log->debug("Default $api_name looking up $single_call_api_name...",INTERNAL);
241 my $method = $self->method_lookup($single_call_api_name);
244 while ( my $node = shift(@nodes) ) {
245 my ($res) = $method->run( $node );
246 push(@success, 1) if ($res >= 0);
249 my $insert_total = 0;
250 $insert_total += $_ for (@success);
252 return $insert_total;
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;
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;
271 # Create the search method
272 unless ( __PACKAGE__->is_registered( $api_prefix.'.search' ) ) {
273 __PACKAGE__->register_method(
274 api_name => $api_prefix.'.search',
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',
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',
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',
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',
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',
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',
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',
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',
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',
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',
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',