1 package OpenILS::Application::Storage::CDBI;
2 use base qw/Class::DBI/;
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;
13 use OpenSRF::Utils::Logger;
14 use OpenSRF::EX qw/:try/;
17 my $log = 'OpenSRF::Utils::Logger';
22 $log->debug("Creating ImaDBI Querys", DEBUG);
23 __PACKAGE__->set_sql( 'OILSFastSearch', <<" SQL", 'Main');
29 __PACKAGE__->set_sql( 'OILSFastOrderedSearchLike', <<" SQL", 'Main');
36 __PACKAGE__->set_sql( 'OILSFastOrderedSearch', <<" SQL", 'Main');
43 $log->debug("Calling Driver child_init", DEBUG);
44 $self->SUPER::child_init(@_);
50 $class = ref($class) || $class;
58 if (!(defined($order) and ref($order) and ref($order) eq 'HASH')) {
59 if (defined($value) and ref($value) and ref($value) eq 'HASH') {
63 $order = { order_by => $class->columns('Primary') }
67 unless (defined $value) {
69 $field = $class->primary_column;
72 unless (defined $field) {
73 $field = $class->primary_column;
76 unless ($order->{order_by}) {
77 $order = { order_by => $class->columns('Primary') }
80 my $fm_class = 'Fieldmapper::'.$class;
81 my $field_list = join ',', $class->columns('All');
85 $sth = $class->sql_OILSFastOrderedSearch( $field_list, $class->table, $field, $order->{order_by});
87 $sth = $class->sql_OILSFastOrderedSearchLike( $field_list, $class->table, $field, $order->{order_by});
89 $sth->execute($value);
95 return map $class->construct($_), $self->fast_flesh_sth(@_)->fetchall_hash;
98 sub fast_fieldmapper {
103 my $class = ref($self) || $self;
104 my $fm_class = 'Fieldmapper::'.$class;
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} );
120 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
123 $log->debug("Retrieving $self with $arg", INTERNAL);
126 $rec = $self->SUPER::retrieve("$arg");
128 $log->debug("Could not retrieve $self with $arg! -- ".shift(), DEBUG);
136 my $class = ref($obj) || $obj;
138 my $fm_class = 'Fieldmapper::'.$class;
139 my $fm = $fm_class->new;
142 for my $field ( $fm->real_fields ) {
143 $fm->$field( $obj->$field );
154 $log->debug("\$arg is $arg (".ref($arg).")",DEBUG);
156 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
157 return $self->create_from_fieldmapper($arg,@_);
160 return $self->SUPER::create($arg,@_);
163 sub create_from_fieldmapper {
168 $log->debug("Creating node of type ".ref($fm), DEBUG);
170 my $class = ref($obj) || $obj;
171 my $primary = $class->primary_column;
174 my %hash = map { defined $fm->$_ ?
177 } grep { $_ ne $primary } $class->columns('All');
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;
185 return $class->create( \%hash, @params );
195 my $class = ref($self) || $self;
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 ");
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;
212 $self->SUPER::delete;
220 $log->debug("Attempting to update using $arg", DEBUG) if ($arg);
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);
228 $log->debug("Calling Class::DBI->update on modified object $self", DEBUG);
229 return $self->SUPER::update if ($self->is_changed);
233 sub modify_from_fieldmapper {
237 $log->debug("Modifying object using fieldmapper", DEBUG);
239 my $class = ref($obj) || $obj;
242 $obj = $class->retrieve($fm);
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."!!");
249 my %hash = map { defined $fm->$_ ?
254 my $au = $obj->autoupdate;
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);
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 );
267 $obj->autoupdate($au)
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' );
286 actor::user_address->has_a( usr => 'actor::user' );
288 actor::card->has_a( usr => 'actor::user' );
290 config::rules::age_hold_protect->has_a( radius => 'actor::org_unit_type' );
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' );
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' );
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' );
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' );
313 action::survey_question->has_a( survey => 'action::survey' );
315 action::survey_answer->has_a( question => 'action::survey' );
317 asset::copy_note->has_a( owning_copy => 'asset::copy' );
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' );
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' );
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' );
332 asset::call_number_note->has_a( call_number => 'asset::call_number' );
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' );
338 biblio::record_note->has_a( record => 'biblio::record_entry' );
340 biblio::record_entry->has_a( creator => 'actor::user' );
341 biblio::record_entry->has_a( editor => 'actor::user' );
343 metabib::metarecord->has_a( master_record => 'biblio::record_entry' );
345 metabib::record_descriptor->has_a( record => 'biblio::record_entry' );
347 metabib::full_rec->has_a( record => 'biblio::record_entry' );
349 metabib::title_field_entry->has_a( source => 'biblio::record_entry' );
350 metabib::title_field_entry->has_a( field => 'config::metabib_field' );
352 metabib::author_field_entry->has_a( source => 'biblio::record_entry' );
353 metabib::author_field_entry->has_a( field => 'config::metabib_field' );
355 metabib::subject_field_entry->has_a( source => 'biblio::record_entry' );
356 metabib::subject_field_entry->has_a( field => 'config::metabib_field' );
358 metabib::keyword_field_entry->has_a( source => 'biblio::record_entry' );
359 metabib::keyword_field_entry->has_a( field => 'config::metabib_field' );
361 metabib::series_field_entry->has_a( source => 'biblio::record_entry' );
362 metabib::series_field_entry->has_a( field => 'config::metabib_field' );
364 metabib::metarecord_source_map->has_a( metarecord => 'metabib::metarecord' );
365 metabib::metarecord_source_map->has_a( source => 'biblio::record_entry' );
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' );
371 money::billable_transaction->has_a( usr => 'actor::user' );
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' );
379 actor::org_unit->has_many( users => 'actor::user' );
380 actor::profile->has_many( users => 'actor::user' );
382 action::survey->has_many( questions => 'action::survey_question' );
383 action::survey->has_many( responses => 'action::survey_response' );
385 action::survey_question->has_many( answers => 'action::survey_answer' );
386 action::survey_question->has_many( responses => 'action::survey_response' );
388 action::survey_answer->has_many( responses => 'action::survey_response' );
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' );
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' );
404 metabib::metarecord->has_many( source_records => [ 'metabib::metarecord_source_map' => 'source'] );
406 money::billable_transaction->has_many( billings => 'money::billing' );
407 money::billable_transaction->has_many( payments => 'money::payment' );
409 money::billing->has_a( xact => 'money::billable_transaction' );
410 money::payment->has_a( xact => 'money::billable_transaction' );
412 money::cash_payment->has_a( xact => 'money::billable_transaction' );
413 money::cash_payment->has_a( accepting_usr => 'actor::user' );
415 money::check_payment->has_a( xact => 'money::billable_transaction' );
416 money::check_payment->has_a( accepting_usr => 'actor::user' );
418 money::credit_card_payment->has_a( xact => 'money::billable_transaction' );
419 money::credit_card_payment->has_a( accepting_usr => 'actor::user' );
421 money::forgive_payment->has_a( xact => 'money::billable_transaction' );
422 money::forgive_payment->has_a( accepting_usr => 'actor::user' );
424 money::work_payment->has_a( xact => 'money::billable_transaction' );
425 money::work_payment->has_a( accepting_usr => 'actor::user' );
427 money::credit_payment->has_a( xact => 'money::billable_transaction' );
428 money::credit_payment->has_a( accepting_usr => 'actor::user' );