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 warn "Attempting to register cachable version of $dup_args{api_name}\n";
31 (my $name = $dup_args{api_name}) =~ s/^open-ils\.storage/open-ils.storage.cachable/o;
32 if ($name ne $dup_args{api_name}) {
33 $dup_args{real_api_name} = $dup_args{api_name};
34 $dup_args{method} = 'cachable_wrapper';
35 $dup_args{api_name} = $name;
36 $dup_args{package} = __PACKAGE__;
37 __PACKAGE__->SUPER::register_method( %dup_args );
38 warn "Registering cachable version of $dup_args{api_name} as $name\n";
43 sub cachable_wrapper {
55 my $key_string = $self->api_name;
56 for (my $ind = 0; $ind < scalar(@args); $ind++) {
57 if ( "$args[$ind]" eq 'limit' ||
58 "$args[$ind]" eq 'offset' ||
59 "$args[$ind]" eq 'timeout' ) {
64 $cache_args{$args[$key_ind]} = $args[$value_ind];
65 $log->debug("Cache limiter value for $args[$key_ind] is $args[$value_ind]", DEBUG);
68 $key_string .= $args[$ind];
69 push @real_args, $args[$ind];
72 my $cache_key = md5_hex($key_string);
74 my $cached_res = OpenSRF::Utils::Cache->new->get_cache( $cache_key );
75 if (defined $cached_res) {
76 $log->debug("Found ".scalar(@$cached_res)." records in the cache", INFO);
77 $log->debug("Values from cache: ".join(', ', @$cached_res), INTERNAL);
78 $client->respond( $_ ) for ( grep { defined } @$cached_res[$cache_args{offset} .. int($cache_args{offset} + $cache_args{limit} - 1)] );
82 my $method = $self->method_lookup($self->{real_api_name});
83 my @res = $method->run(@real_args);
86 $client->respond( $_ ) for ( grep { defined } @res[$cache_args{offset} .. int($cache_args{offset} + $cache_args{limit} - 1)] );
88 OpenSRF::Utils::Cache->new->put_cache( $cache_key => \@res => $cach_args{timeout});
98 my $cdbi = $self->{cdbi};
100 for my $id ( @ids ) {
103 my ($rec) = $cdbi->fast_fieldmapper($id);
104 $client->respond( $rec ) if ($rec);
106 last if ($self->api_name !~ /batch/o);
114 my $searches = shift;
116 my $cdbi = $self->{cdbi};
118 $log->debug("Searching $cdbi for { ".join(',', map { "$_ => $$searches{$_}" } keys %$searches).' }',DEBUG);
120 for my $obj ($cdbi->search($searches)) {
121 $client->respond( $obj->to_fieldmapper );
126 sub search_one_field {
131 (my $search_type = $self->api_name) =~ s/.*\.(search[^.]*).*/$1/o;
132 (my $col = $self->api_name) =~ s/.*\.$search_type\.([^.]+).*/$1/;
133 my $cdbi = $self->{cdbi};
136 $like = 1 if ($search_type =~ /like$/o);
138 for my $term (@terms) {
139 $log->debug("Searching $cdbi for $col using type $search_type, value '$term'",DEBUG);
140 $client->respond( [ $cdbi->fast_fieldmapper($term,$col,$like) ] );
151 my $cdbi = $self->{cdbi};
155 my $rec = $cdbi->create($node);
156 $success = $rec->id if ($rec);
169 my $cdbi = $self->{cdbi};
171 return $cdbi->update($node);
179 my $where = 'WHERE ';
181 my $cdbi = $self->{cdbi};
182 my $table = $cdbi->table;
184 my @keys = sort keys %$search;
188 for my $col ( @keys ) {
189 if (ref($$search{$col}) and ref($$search{$col}) =~ /ARRAY/o) {
190 push @wheres, "$col IN (" . join(',', map { '?' } @{ $$search{$col} }) . ')';
191 push @binds, map { "$_" } @{ $$search{$col} };
193 push @wheres, "$col = ?";
194 push @binds, $$search{$col};
197 $where .= join ' AND ', @wheres;
199 my $delete = "DELETE FROM $table $where";
201 $log->debug("Performing MASS deletion : $delete",DEBUG);
203 my $dbh = $cdbi->db_Main;
206 my $sth = $dbh->prepare($delete);
207 $sth->execute( @binds );
209 $log->debug("MASS Delete succeeded",DEBUG);
211 $log->debug("MASS Delete FAILED : ".shift(),DEBUG);
222 my $cdbi = $self->{cdbi};
226 $success = $cdbi->delete($node);
238 my $cdbi = $self->{cdbi};
239 my $api_name = $self->api_name;
240 (my $single_call_api_name = $api_name) =~ s/batch\.//o;
242 $log->debug("Default $api_name looking up $single_call_api_name...",INTERNAL);
243 my $method = $self->method_lookup($single_call_api_name);
246 while ( my $node = shift(@nodes) ) {
247 my ($res) = $method->run( $node );
248 push(@success, 1) if ($res >= 0);
251 my $insert_total = 0;
252 $insert_total += $_ for (@success);
254 return $insert_total;
258 use OpenILS::Application::Storage::Publisher::actor;
259 use OpenILS::Application::Storage::Publisher::action;
260 use OpenILS::Application::Storage::Publisher::asset;
261 use OpenILS::Application::Storage::Publisher::biblio;
262 use OpenILS::Application::Storage::Publisher::config;
263 use OpenILS::Application::Storage::Publisher::metabib;
266 for my $fmclass ( Fieldmapper->classes ) {
267 (my $cdbi = $fmclass) =~ s/^Fieldmapper:://o;
268 (my $class = $cdbi) =~ s/::.*//o;
269 (my $api_class = $cdbi) =~ s/::/./go;
270 my $registration_class = __PACKAGE__ . "::$class";
271 my $api_prefix = 'open-ils.storage.direct.'.$api_class;
273 # Create the search method
274 unless ( __PACKAGE__->is_registered( $api_prefix.'.search' ) ) {
275 __PACKAGE__->register_method(
276 api_name => $api_prefix.'.search',
285 # Create the retrieve method
286 unless ( __PACKAGE__->is_registered( $api_prefix.'.retrieve' ) ) {
287 __PACKAGE__->register_method(
288 api_name => $api_prefix.'.retrieve',
289 method => 'retrieve_node',
296 # Create the batch retrieve method
297 unless ( __PACKAGE__->is_registered( $api_prefix.'.batch.retrieve' ) ) {
298 __PACKAGE__->register_method(
299 api_name => $api_prefix.'.batch.retrieve',
300 method => 'retrieve_node',
308 for my $field ($fmclass->real_fields) {
309 unless ( __PACKAGE__->is_registered( $api_prefix.'.search.'.$field ) ) {
310 __PACKAGE__->register_method(
311 api_name => $api_prefix.'.search.'.$field,
312 method => 'search_one_field',
318 unless ( __PACKAGE__->is_registered( $api_prefix.'.search_like.'.$field ) ) {
319 __PACKAGE__->register_method(
320 api_name => $api_prefix.'.search_like.'.$field,
321 method => 'search_one_field',
330 # Create the create method
331 unless ( __PACKAGE__->is_registered( $api_prefix.'.create' ) ) {
332 __PACKAGE__->register_method(
333 api_name => $api_prefix.'.create',
334 method => 'create_node',
340 # Create the batch create method
341 unless ( __PACKAGE__->is_registered( $api_prefix.'.batch.create' ) ) {
342 __PACKAGE__->register_method(
343 api_name => $api_prefix.'.batch.create',
344 method => 'batch_call',
350 # Create the update method
351 unless ( __PACKAGE__->is_registered( $api_prefix.'.update' ) ) {
352 __PACKAGE__->register_method(
353 api_name => $api_prefix.'.update',
354 method => 'update_node',
360 # Create the batch update method
361 unless ( __PACKAGE__->is_registered( $api_prefix.'.batch.update' ) ) {
362 __PACKAGE__->register_method(
363 api_name => $api_prefix.'.batch.update',
364 method => 'batch_call',
370 # Create the delete method
371 unless ( __PACKAGE__->is_registered( $api_prefix.'.delete' ) ) {
372 __PACKAGE__->register_method(
373 api_name => $api_prefix.'.delete',
374 method => 'delete_node',
380 # Create the batch delete method
381 unless ( __PACKAGE__->is_registered( $api_prefix.'.batch.delete' ) ) {
382 __PACKAGE__->register_method(
383 api_name => $api_prefix.'.batch.delete',
384 method => 'batch_call',
390 # Create the search-based mass delete method
391 unless ( __PACKAGE__->is_registered( $api_prefix.'.mass_delete' ) ) {
392 __PACKAGE__->register_method(
393 api_name => $api_prefix.'.mass_delete',
394 method => 'mass_delete',