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