tons of storage server changes... see diffs
[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 OpenSRF::EX qw/:try/;;
6 use OpenSRF::Utils::Logger;
7 my $log = 'OpenSRF::Utils::Logger';
8
9 use OpenILS::Utils::Fieldmapper;
10 use OpenILS::Application::Storage::CDBI;
11
12 #use OpenILS::Application::Storage::CDBI::actor;
13 #use OpenILS::Application::Storage::CDBI::asset;
14 #use OpenILS::Application::Storage::CDBI::biblio;
15 #use OpenILS::Application::Storage::CDBI::config;
16 #use OpenILS::Application::Storage::CDBI::metabib;
17
18 use OpenILS::Application::Storage::Publisher::actor;
19 use OpenILS::Application::Storage::Publisher::action;
20 use OpenILS::Application::Storage::Publisher::asset;
21 use OpenILS::Application::Storage::Publisher::biblio;
22 use OpenILS::Application::Storage::Publisher::config;
23 use OpenILS::Application::Storage::Publisher::metabib;
24
25 sub retrieve_node {
26         my $self = shift;
27         my $client = shift;
28         my @ids = @_;
29
30         my $cdbi = $self->{cdbi};
31
32         for my $id ( @ids ) {
33                 next unless ($id);
34
35                 my ($rec) = $cdbi->fast_fieldmapper($id);
36                 $client->respond( $rec ) if ($rec);
37
38                 last if ($self->api_name !~ /batch/o);
39         }
40         return undef;
41 }
42
43 sub search {
44         my $self = shift;
45         my $client = shift;
46         my $searches = shift;
47
48         my $cdbi = $self->{cdbi};
49
50         $log->debug("Searching $cdbi for { ".join(',', map { "$_ => $$searches{$_}" } keys %$searches).' }',DEBUG);
51
52         for my $obj ($cdbi->search($searches)) {
53                 $client->respond( $obj->to_fieldmapper );
54         }
55         return undef;
56 }
57
58 sub search_one_field {
59         my $self = shift;
60         my $client = shift;
61         my @terms = @_;
62
63         (my $search_type = $self->api_name) =~ s/.*\.(search[^.]*).*/$1/o;
64         (my $col = $self->api_name) =~ s/.*\.$search_type\.([^.]+).*/$1/;
65         my $cdbi = $self->{cdbi};
66
67         my $like = 0;
68         $like = 1 if ($search_type =~ /like$/o);
69
70         for my $term (@terms) {
71                 $log->debug("Searching $cdbi for $col using type $search_type, value '$term'",DEBUG);
72                 $client->respond( [ $cdbi->fast_fieldmapper($term,$col,$like) ] );
73         }
74         return undef;
75 }
76
77
78 sub create_node {
79         my $self = shift;
80         my $client = shift;
81         my $node = shift;
82
83         my $cdbi = $self->{cdbi};
84
85         my $success;
86         try {
87                 my $rec = $cdbi->create($node);
88                 $success = $rec->id if ($rec);
89         } catch Error with {
90                 $success = 0;
91         };
92
93         return $success;
94 }
95
96 sub update_node {
97         my $self = shift;
98         my $client = shift;
99         my $node = shift;
100
101         my $cdbi = $self->{cdbi};
102
103         return $cdbi->update($node);
104 }
105
106 sub mass_delete {
107         my $self = shift;
108         my $client = shift;
109         my $search = shift;
110
111         my $where = 'WHERE ';
112
113         my $cdbi = $self->{cdbi};
114         my $table = $cdbi->table;
115
116         my @keys = sort keys %$search;
117         
118         my @binds;
119         my @wheres;
120         for my $col ( @keys ) {
121                 if (ref($$search{$col}) and ref($$search{$col}) =~ /ARRAY/o) {
122                         push @wheres, "$col IN (" . join(',', map { '?' } @{ $$search{$col} }) . ')';
123                         push @binds, map { "$_" } @{ $$search{$col} };
124                 } else {
125                         push @wheres, "$col = ?";
126                         push @binds, $$search{$col};
127                 }
128         }
129         $where .= join ' AND ', @wheres;
130
131         my $delete = "DELETE FROM $table $where";
132
133         $log->debug("Performing MASS deletion : $delete",DEBUG);
134
135         my $dbh = $cdbi->db_Main;
136         my $success = 1;
137         try {
138                 my $sth = $dbh->prepare($delete);
139                 $sth->execute( @binds );
140                 $sth->finish;
141                 $log->debug("MASS Delete succeeded",DEBUG);
142         } catch Error with {
143                 $log->debug("MASS Delete FAILED : ".shift(),DEBUG);
144                 $success = 0;
145         };
146         return $success;
147 }
148
149 sub delete_node {
150         my $self = shift;
151         my $client = shift;
152         my $node = shift;
153
154         my $cdbi = $self->{cdbi};
155
156         my $success = 1;
157         try {
158                 $success = $cdbi->delete($node);
159         } catch Error with {
160                 $success = 0;
161         };
162         return $success;
163 }
164
165 sub batch_call {
166         my $self = shift;
167         my $client = shift;
168         my @nodes = @_;
169
170         my $cdbi = $self->{cdbi};
171         my $api_name = $self->api_name;
172         (my $single_call_api_name = $api_name) =~ s/batch\.//o;
173
174         $log->debug("Default $api_name looking up $single_call_api_name...",INTERNAL);
175         my $method = $self->method_lookup($single_call_api_name);
176
177         my @success;
178         while ( my $node = shift(@nodes) ) {
179                 my ($res) = $method->run( $node ); 
180                 push(@success, 1) if ($res >= 0);
181         }
182
183         my $insert_total = 0;
184         $insert_total += $_ for (@success);
185
186         return $insert_total;
187 }
188
189 for my $fmclass ( Fieldmapper->classes ) {
190         (my $cdbi = $fmclass) =~ s/^Fieldmapper:://o;
191         (my $class = $cdbi) =~ s/::.*//o;
192         (my $api_class = $cdbi) =~ s/::/./go;
193         my $registration_class = __PACKAGE__ . "::$class";
194         my $api_prefix = 'open-ils.storage.direct.'.$api_class;
195
196         # Create the search method
197         unless ( __PACKAGE__->is_registered( $api_prefix.'.search' ) ) {
198                 __PACKAGE__->register_method(
199                         api_name        => $api_prefix.'.search',
200                         method          => 'search',
201                         api_level       => 1,
202                         stream          => 1,
203                         cdbi            => $cdbi,
204                 );
205         }
206
207         # Create the retrieve method
208         unless ( __PACKAGE__->is_registered( $api_prefix.'.retrieve' ) ) {
209                 __PACKAGE__->register_method(
210                         api_name        => $api_prefix.'.retrieve',
211                         method          => 'retrieve_node',
212                         api_level       => 1,
213                         cdbi            => $cdbi,
214                 );
215         }
216
217         # Create the batch retrieve method
218         unless ( __PACKAGE__->is_registered( $api_prefix.'.batch.retrieve' ) ) {
219                 __PACKAGE__->register_method(
220                         api_name        => $api_prefix.'.batch.retrieve',
221                         method          => 'retrieve_node',
222                         api_level       => 1,
223                         stream          => 1,
224                         cdbi            => $cdbi,
225                 );
226         }
227
228         for my $field ($fmclass->real_fields) {
229                 unless ( __PACKAGE__->is_registered( $api_prefix.'.search.'.$field ) ) {
230                         __PACKAGE__->register_method(
231                                 api_name        => $api_prefix.'.search.'.$field,
232                                 method          => 'search_one_field',
233                                 api_level       => 1,
234                                 cdbi            => $cdbi,
235                         );
236                 }
237                 unless ( __PACKAGE__->is_registered( $api_prefix.'.search_like.'.$field ) ) {
238                         __PACKAGE__->register_method(
239                                 api_name        => $api_prefix.'.search_like.'.$field,
240                                 method          => 'search_one_field',
241                                 api_level       => 1,
242                                 cdbi            => $cdbi,
243                         );
244                 }
245         }
246
247
248         # Create the create method
249         unless ( __PACKAGE__->is_registered( $api_prefix.'.create' ) ) {
250                 __PACKAGE__->register_method(
251                         api_name        => $api_prefix.'.create',
252                         method          => 'create_node',
253                         api_level       => 1,
254                         cdbi            => $cdbi,
255                 );
256         }
257
258         # Create the batch create method
259         unless ( __PACKAGE__->is_registered( $api_prefix.'.batch.create' ) ) {
260                 __PACKAGE__->register_method(
261                         api_name        => $api_prefix.'.batch.create',
262                         method          => 'batch_call',
263                         api_level       => 1,
264                         cdbi            => $cdbi,
265                 );
266         }
267
268         # Create the update method
269         unless ( __PACKAGE__->is_registered( $api_prefix.'.update' ) ) {
270                 __PACKAGE__->register_method(
271                         api_name        => $api_prefix.'.update',
272                         method          => 'update_node',
273                         api_level       => 1,
274                         cdbi            => $cdbi,
275                 );
276         }
277
278         # Create the batch update method
279         unless ( __PACKAGE__->is_registered( $api_prefix.'.batch.update' ) ) {
280                 __PACKAGE__->register_method(
281                         api_name        => $api_prefix.'.batch.update',
282                         method          => 'batch_call',
283                         api_level       => 1,
284                         cdbi            => $cdbi,
285                 );
286         }
287
288         # Create the delete method
289         unless ( __PACKAGE__->is_registered( $api_prefix.'.delete' ) ) {
290                 __PACKAGE__->register_method(
291                         api_name        => $api_prefix.'.delete',
292                         method          => 'delete_node',
293                         api_level       => 1,
294                         cdbi            => $cdbi,
295                 );
296         }
297
298         # Create the batch delete method
299         unless ( __PACKAGE__->is_registered( $api_prefix.'.batch.delete' ) ) {
300                 __PACKAGE__->register_method(
301                         api_name        => $api_prefix.'.batch.delete',
302                         method          => 'batch_call',
303                         api_level       => 1,
304                         cdbi            => $cdbi,
305                 );
306         }
307
308         # Create the search-based mass delete method
309         unless ( __PACKAGE__->is_registered( $api_prefix.'.mass_delete' ) ) {
310                 __PACKAGE__->register_method(
311                         api_name        => $api_prefix.'.mass_delete',
312                         method          => 'mass_delete',
313                         api_level       => 1,
314                         cdbi            => $cdbi,
315                 );
316         }
317
318 }
319
320 1;