]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Storage/CDBI.pm
"copy" conficts with CDBI, renaming to target_copy
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Storage / CDBI.pm
1 package OpenILS::Application::Storage::CDBI;
2 use base qw/Class::DBI/;
3 use Class::DBI;
4
5 use OpenILS::Application::Storage::CDBI::actor;
6 use OpenILS::Application::Storage::CDBI::action;
7 use OpenILS::Application::Storage::CDBI::asset;
8 use OpenILS::Application::Storage::CDBI::biblio;
9 use OpenILS::Application::Storage::CDBI::config;
10 use OpenILS::Application::Storage::CDBI::metabib;
11 use OpenILS::Application::Storage::CDBI::money;
12 use OpenILS::Application::Storage::CDBI::permission;
13
14 use OpenSRF::Utils::Logger;
15 use OpenSRF::EX qw/:try/;
16
17 our $VERSION = undef;
18 my $log = 'OpenSRF::Utils::Logger';
19
20 sub child_init {
21         my $self = shift;
22
23         $log->debug("Creating ImaDBI Querys", DEBUG);
24         __PACKAGE__->set_sql( 'OILSFastSearch', <<"     SQL", 'Main');
25                 SELECT  %s
26                   FROM  %s
27                   WHERE %s = ?
28         SQL
29
30         __PACKAGE__->set_sql( 'OILSFastOrderedSearchLike', <<"  SQL", 'Main');
31                 SELECT  %s
32                   FROM  %s
33                   WHERE %s ~ ?
34                   ORDER BY %s
35         SQL
36
37         __PACKAGE__->set_sql( 'OILSFastOrderedSearch', <<"      SQL", 'Main');
38                 SELECT  %s
39                   FROM  %s
40                   WHERE %s = ?
41                   ORDER BY %s
42         SQL
43
44         $log->debug("Calling Driver child_init", DEBUG);
45         $self->SUPER::child_init(@_);
46
47 }
48
49 sub fast_flesh_sth {
50         my $class = shift;
51         $class = ref($class) || $class;
52
53         my $field = shift;
54         my $value = shift;
55         my $order = shift;
56         my $like = shift;
57
58
59         if (!(defined($order) and ref($order) and ref($order) eq 'HASH')) {
60                 if (defined($value) and ref($value) and ref($value) eq 'HASH') {
61                         $order = $value;
62                         $value = undef;
63                 } else {
64                         $order = { order_by => $class->columns('Primary') }
65                 }
66         }
67
68         unless (defined $value) {
69                 $value = $field;
70                 $field = $class->primary_column;
71         }
72
73         unless (defined $field) {
74                 $field = $class->primary_column;
75         }
76
77         unless ($order->{order_by}) {
78                 $order = { order_by => $class->columns('Primary') }
79         }
80
81         my $fm_class = 'Fieldmapper::'.$class;
82         my $field_list = join ',', $class->columns('All');
83         
84         my $sth;
85         if (!$like) {
86                 $sth = $class->sql_OILSFastOrderedSearch( $field_list, $class->table, $field, $order->{order_by});
87         } else {
88                 $sth = $class->sql_OILSFastOrderedSearchLike( $field_list, $class->table, $field, $order->{order_by});
89         }
90         $sth->execute($value);
91         return $sth;
92 }
93
94 sub fast_flesh {
95         my $self = shift;
96         return map $class->construct($_), $self->fast_flesh_sth(@_)->fetchall_hash;
97 }
98
99 sub fast_fieldmapper {
100         my $self = shift;
101         my $id = shift;
102         my $col = shift;
103         my $like = shift;
104         my $class = ref($self) || $self;
105         my $fm_class = 'Fieldmapper::'.$class;
106         my @fms;
107         $log->debug("fast_fieldmapper() ==> Retrieving $fm_class", INTERNAL);
108         for my $hash ($self->fast_flesh_sth( $col, "$id", { order_by => $col }, $like )->fetchall_hash) {
109                 my $fm = $fm_class->new;
110                 for my $field ( $fm_class->real_fields ) {
111                         $fm->$field( $$hash{$field} );
112                 }
113                 push @fms, $fm;
114         }
115         return @fms;
116 }
117
118 sub retrieve {
119         my $self = shift;
120         my $arg = shift;
121         if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
122                 $arg = $arg->id;
123         }
124         $log->debug("Retrieving $self with $arg", INTERNAL);
125         my $rec;
126         try {
127                 $rec = $self->SUPER::retrieve("$arg");
128         } catch Error with {
129                 $log->debug("Could not retrieve $self with $arg! -- ".shift(), DEBUG);
130                 return undef;
131         };
132         return $rec;
133 }
134
135 sub to_fieldmapper {
136         my $obj = shift;
137         my $class = ref($obj) || $obj;
138
139         my $fm_class = 'Fieldmapper::'.$class;
140         my $fm = $fm_class->new;
141
142         if (ref($obj)) {
143                 for my $field ( $fm->real_fields ) {
144                         $fm->$field( $obj->$field );
145                 }
146         }
147
148         return $fm;
149 }
150
151 sub create {
152         my $self = shift;
153         my $arg = shift;
154
155         $log->debug("\$arg is $arg (".ref($arg).")",DEBUG);
156
157         if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
158                 return $self->create_from_fieldmapper($arg,@_);
159         }
160
161         return $self->SUPER::create($arg,@_);
162 }
163
164 sub create_from_fieldmapper {
165         my $obj = shift;
166         my $fm = shift;
167         my @params = @_;
168
169         $log->debug("Creating node of type ".ref($fm), DEBUG);
170
171         my $class = ref($obj) || $obj;
172         my $primary = $class->primary_column;
173
174         if (ref $fm) {
175                 my %hash = map { defined $fm->$_ ?
176                                         ($_ => $fm->$_) :
177                                         ()
178                                 } grep { $_ ne $primary } $class->columns('All');
179
180                 if ($class->find_column( 'last_xact_id' )) {
181                         my $xact_id = $class->current_xact_id;
182                         throw Error unless ($xact_id);
183                         $hash{last_xact_id} = $xact_id;
184                 }
185
186                 return $class->create( \%hash, @params );
187         } else {
188                 return undef;
189         }
190 }
191
192 sub delete {
193         my $self = shift;
194         my $arg = shift;
195
196         my $class = ref($self) || $self;
197
198         if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
199                 $self = $self->retrieve($arg);
200                 unless (defined $self) {
201                         $log->debug("ARG! Couldn't retrieve record ".$arg->id, DEBUG);
202                         throw OpenSRF::EX::WARN ("ARG! Couldn't retrieve record ");
203                 }
204         }
205
206         if ($class->find_column( 'last_xact_id' )) {
207                 my $xact_id = $self->current_xact_id;
208                 throw Error unless ($xact_id);
209                 $self->last_xact_id( $class->current_xact_id );
210                 $self->SUPER::update;
211         }
212
213         $self->SUPER::delete;
214         return 1;
215 }
216
217 sub update {
218         my $self = shift;
219         my $arg = shift;
220
221         $log->debug("Attempting to update using $arg", DEBUG) if ($arg);
222
223         if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
224                 $self = $self->modify_from_fieldmapper($arg);
225                 $log->debug("Modification of $self seems to have failed....", DEBUG);
226                 return undef unless (defined $self);
227         }
228
229         $log->debug("Calling Class::DBI->update on modified object $self", DEBUG);
230         return $self->SUPER::update if ($self->is_changed);
231         return 0;
232 }
233
234 sub modify_from_fieldmapper {
235         my $obj = shift;
236         my $fm = shift;
237
238         $log->debug("Modifying object using fieldmapper", DEBUG);
239
240         my $class = ref($obj) || $obj;
241
242         if (!ref($obj)) {
243                 $obj = $class->retrieve($fm);
244                 unless ($obj) {
245                         $log->debug("Retrieve of $class using $fm (".$fm->id.") failed! -- ".shift(), ERROR);
246                         throw OpenSRF::EX::WARN ("No $class with id of ".$fm->id."!!");
247                 }
248         }
249
250         my %hash = map { defined $fm->$_ ?
251                                 ($_ => ''.$fm->$_) :
252                                 ()
253                         } $fm->real_fields;
254
255         my $au = $obj->autoupdate;
256         $obj->autoupdate(0);
257         
258         for my $field ( keys %hash ) {
259                 $obj->$field( $hash{$field} ) if ($obj->$field ne $hash{$field});
260                 $log->debug("Setting field $field on $obj to $hash{$field}",INTERNAL);
261         }
262
263         if ($class->find_column( 'last_xact_id' ) and $obj->is_changed) {
264                 my $xact_id = $obj->current_xact_id;
265                 throw Error unless ($xact_id);
266                 $obj->last_xact_id( $xact_id );
267         } else {
268                 $obj->autoupdate($au)
269         }
270
271         return $obj;
272 }
273
274
275
276         #-------------------------------------------------------------------------------
277         actor::user->has_a( home_ou => 'actor::org_unit' );
278         actor::user->has_a( card => 'actor::card' );
279         actor::user->has_a( standing => 'config::standing' );
280         actor::user->has_a( profile => 'actor::profile' );
281         actor::user->has_a( mailing_address => 'actor::user_address' );
282         actor::user->has_a( billing_address => 'actor::user_address' );
283         actor::user->has_a( ident_type => 'config::identification_type' );
284         actor::user->has_a( ident_type2 => 'config::identification_type' );
285         actor::user->has_a( net_access_level => 'config::net_access_level' );
286
287         actor::user_address->has_a( usr => 'actor::user' );
288         
289         actor::card->has_a( usr => 'actor::user' );
290         
291         config::rules::age_hold_protect->has_a( radius => 'actor::org_unit_type' );
292         
293         actor::org_unit->has_a( parent_ou => 'actor::org_unit' );
294         actor::org_unit->has_a( ou_type => 'actor::org_unit_type' );
295         #actor::org_unit->has_a( address => 'actor::org_address' );
296
297         actor::stat_cat_entry->has_a( stat_cat => 'actor::stat_cat' );
298         actor::stat_cat->has_many( entries => 'actor::stat_cat_entry' );
299         actor::stat_cat_entry_user_map->has_a( stat_cat => 'actor::stat_cat' );
300         actor::stat_cat_entry_user_map->has_a( stat_cat_entry => 'actor::stat_cat_entry' );
301         actor::stat_cat_entry_user_map->has_a( target_usr => 'actor::user' );
302
303         asset::stat_cat_entry->has_a( stat_cat => 'asset::stat_cat' );
304         asset::stat_cat->has_many( entries => 'asset::stat_cat_entry' );
305         asset::stat_cat_entry_copy_map->has_a( stat_cat => 'asset::stat_cat' );
306         asset::stat_cat_entry_copy_map->has_a( stat_cat_entry => 'asset::stat_cat_entry' );
307         asset::stat_cat_entry_copy_map->has_a( owning_copy => 'asset::copy' );
308
309         action::survey_response->has_a( usr => 'actor::user' );
310         action::survey_response->has_a( survey => 'action::survey' );
311         action::survey_response->has_a( question => 'action::survey_question' );
312         action::survey_response->has_a( answer => 'action::survey_answer' );
313
314         action::survey_question->has_a( survey => 'action::survey' );
315
316         action::survey_answer->has_a( question => 'action::survey' );
317
318         asset::copy_note->has_a( owning_copy => 'asset::copy' );
319
320         actor::user->has_many( stat_cat_entries => [ 'actor::stat_cat_entry_user_map' => 'stat_cat_entry' ] );
321         actor::user->has_many( stat_cat_entry_user_maps => 'actor::stat_cat_entry_user_map' );
322
323         asset::copy->has_many( stat_cat_entries => [ 'asset::stat_cat_entry_copy_map' => 'stat_cat_entry' ] );
324         asset::copy->has_many( stat_cat_entry_copy_maps => 'asset::stat_cat_entry_copy_map' );
325
326         asset::copy->has_a( call_number => 'asset::call_number' );
327         asset::copy->has_a( creator => 'actor::user' );
328         asset::copy->has_a( editor => 'actor::user' );
329         asset::copy->has_a( status => 'config::copy_status' );
330         asset::copy->has_a( location => 'asset::copy_location' );
331         asset::copy->has_a( circ_lib => 'actor::org_unit' );
332
333         asset::call_number_note->has_a( call_number => 'asset::call_number' );
334
335         asset::call_number->has_a( record => 'biblio::record_entry' );
336         asset::call_number->has_a( creator => 'actor::user' );
337         asset::call_number->has_a( editor => 'actor::user' );
338
339         biblio::record_note->has_a( record => 'biblio::record_entry' );
340         
341         biblio::record_entry->has_a( creator => 'actor::user' );
342         biblio::record_entry->has_a( editor => 'actor::user' );
343         
344         metabib::metarecord->has_a( master_record => 'biblio::record_entry' );
345         
346         metabib::record_descriptor->has_a( record => 'biblio::record_entry' );
347         
348         metabib::full_rec->has_a( record => 'biblio::record_entry' );
349         
350         metabib::title_field_entry->has_a( source => 'biblio::record_entry' );
351         metabib::title_field_entry->has_a( field => 'config::metabib_field' );
352         
353         metabib::author_field_entry->has_a( source => 'biblio::record_entry' );
354         metabib::author_field_entry->has_a( field => 'config::metabib_field' );
355         
356         metabib::subject_field_entry->has_a( source => 'biblio::record_entry' );
357         metabib::subject_field_entry->has_a( field => 'config::metabib_field' );
358         
359         metabib::keyword_field_entry->has_a( source => 'biblio::record_entry' );
360         metabib::keyword_field_entry->has_a( field => 'config::metabib_field' );
361         
362         metabib::series_field_entry->has_a( source => 'biblio::record_entry' );
363         metabib::series_field_entry->has_a( field => 'config::metabib_field' );
364         
365         metabib::metarecord_source_map->has_a( metarecord => 'metabib::metarecord' );
366         metabib::metarecord_source_map->has_a( source => 'biblio::record_entry' );
367
368         action::circulation->has_a( usr => 'actor::user' );
369         action::circulation->has_a( target_copy => 'asset::copy' );
370         action::circulation->has_a( circ_lib => 'actor::org_unit' );
371
372         money::billable_transaction->has_a( usr => 'actor::user' );
373         
374         
375         #-------------------------------------------------------------------------------
376         actor::user->has_many( survey_responses => 'action::survey_response' );
377         actor::user->has_many( addresses => 'actor::user_address' );
378         actor::user->has_many( cards => 'actor::card' );
379
380         actor::org_unit->has_many( users => 'actor::user' );
381         actor::profile->has_many( users => 'actor::user' );
382
383         action::survey->has_many( questions => 'action::survey_question' );
384         action::survey->has_many( responses => 'action::survey_response' );
385         
386         action::survey_question->has_many( answers => 'action::survey_answer' );
387         action::survey_question->has_many( responses => 'action::survey_response' );
388
389         action::survey_answer->has_many( responses => 'action::survey_response' );
390
391         asset::copy->has_many( notes => 'asset::copy_note' );
392         asset::call_number->has_many( copies => 'asset::copy' );
393         asset::call_number->has_many( notes => 'asset::call_number_note' );
394
395         biblio::record_entry->has_many( record_descriptor => 'metabib::record_descriptor' );
396         biblio::record_entry->has_many( notes => 'biblio::record_note' );
397         biblio::record_entry->has_many( call_numbers => 'asset::call_number' );
398         biblio::record_entry->has_many( full_record_entries => 'metabib::full_rec' );
399         biblio::record_entry->has_many( title_field_entries => 'metabib::title_field_entry' );
400         biblio::record_entry->has_many( author_field_entries => 'metabib::author_field_entry' );
401         biblio::record_entry->has_many( subject_field_entries => 'metabib::subject_field_entry' );
402         biblio::record_entry->has_many( keyword_field_entries => 'metabib::keyword_field_entry' );
403         biblio::record_entry->has_many( series_field_entries => 'metabib::series_field_entry' );
404
405         metabib::metarecord->has_many( source_records => [ 'metabib::metarecord_source_map' => 'source'] );
406
407         money::billable_transaction->has_many( billings => 'money::billing' );
408         money::billable_transaction->has_many( payments => 'money::payment' );
409
410         money::billing->has_a( xact => 'money::billable_transaction' );
411         money::payment->has_a( xact => 'money::billable_transaction' );
412
413         money::cash_payment->has_a( xact => 'money::billable_transaction' );
414         money::cash_payment->has_a( accepting_usr => 'actor::user' );
415
416         money::check_payment->has_a( xact => 'money::billable_transaction' );
417         money::check_payment->has_a( accepting_usr => 'actor::user' );
418
419         money::credit_card_payment->has_a( xact => 'money::billable_transaction' );
420         money::credit_card_payment->has_a( accepting_usr => 'actor::user' );
421
422         money::forgive_payment->has_a( xact => 'money::billable_transaction' );
423         money::forgive_payment->has_a( accepting_usr => 'actor::user' );
424
425         money::work_payment->has_a( xact => 'money::billable_transaction' );
426         money::work_payment->has_a( accepting_usr => 'actor::user' );
427
428         money::credit_payment->has_a( xact => 'money::billable_transaction' );
429         money::credit_payment->has_a( accepting_usr => 'actor::user' );
430
431         permission::grp_tree->has_a( parent => 'permission::grp_tree' );
432
433         permission::grp_perm_map->has_a( grp => 'permission::grp_tree' );
434         permission::grp_perm_map->has_a(  perm => 'permission::perm_list' );
435         permission::grp_perm_map->has_a(  depth => 'actor::org_unit_type' );
436         
437         permission::usr_perm_map->has_a( usr => 'actor::user' );
438         permission::usr_perm_map->has_a(  perm => 'permission::perm_list' );
439         permission::usr_perm_map->has_a(  depth => 'actor::org_unit_type' );
440         
441         permission::usr_grp_map->has_a(  usr => 'actor::user' );
442         permission::usr_grp_map->has_a(  grp => 'permission::grp_tree' );
443
444         action::hold_notification->has_a(  hold => 'action::hold_request' );
445         
446         action::hold_copy_map->has_a(  hold => 'action::hold_request' );
447         action::hold_copy_map->has_a(  target_copy => 'asset::copy' );
448
449         action::hold_request->has_a(  current_copy => 'asset::copy' );
450         action::hold_request->has_a(  requestor => 'actor::user' );
451         action::hold_request->has_a(  usr => 'actor::user' );
452         action::hold_request->has_a(  pickup_lib => 'actor::org_unit' );
453
454         action::hold_request->has_many(  notifications => 'action::hold_notification' );
455         action::hold_request->has_many(  copy_maps => 'action::hold_copy_map' );
456
457         asset::copy->has_many(  hold_maps => 'action::hold_copy_map' );
458
459 1;