1 package OpenILS::Application::Storage::CDBI;
2 use base qw/Class::DBI/;
5 use OpenILS::Application::Storage::CDBI::config;
6 use OpenILS::Application::Storage::CDBI::actor;
7 use OpenILS::Application::Storage::CDBI::action;
8 use OpenILS::Application::Storage::CDBI::asset;
9 use OpenILS::Application::Storage::CDBI::biblio;
10 use OpenILS::Application::Storage::CDBI::metabib;
11 use OpenILS::Application::Storage::CDBI::money;
13 use OpenSRF::Utils::Logger;
16 my $log = 'OpenSRF::Utils::Logger';
21 $log->debug("Creating ImaDBI Querys", DEBUG);
22 __PACKAGE__->set_sql( 'OILSFastSearch', <<" SQL", 'Main');
28 __PACKAGE__->set_sql( 'OILSFastOrderedSearchLike', <<" SQL", 'Main');
35 __PACKAGE__->set_sql( 'OILSFastOrderedSearch', <<" SQL", 'Main');
42 $log->debug("Calling Driver child_init", DEBUG);
43 $self->SUPER::child_init(@_);
49 $class = ref($class) || $class;
57 if (!(defined($order) and ref($order) and ref($order) eq 'HASH')) {
58 if (defined($value) and ref($value) and ref($value) eq 'HASH') {
62 $order = { order_by => $class->columns('Primary') }
66 unless (defined $value) {
68 $field = $class->primary_column;
71 unless (defined $field) {
72 $field = $class->primary_column;
75 unless ($order->{order_by}) {
76 $order = { order_by => $class->columns('Primary') }
79 my $fm_class = 'Fieldmapper::'.$class;
80 my $field_list = join ',', $class->columns('All');
84 $sth = $class->sql_OILSFastOrderedSearch( $field_list, $class->table, $field, $order->{order_by});
86 $sth = $class->sql_OILSFastOrderedSearchLike( $field_list, $class->table, $field, $order->{order_by});
88 $sth->execute($value);
94 return map $class->construct($_), $self->fast_flesh_sth(@_)->fetchall_hash;
97 sub fast_fieldmapper {
102 my $class = ref($self) || $self;
103 my $fm_class = 'Fieldmapper::'.$class;
105 $log->debug("fast_fieldmapper() ==> Retrieving $fm_class", INTERNAL);
106 for my $hash ($self->fast_flesh_sth( $col, "$id", { order_by => $col }, $like )->fetchall_hash) {
107 my $fm = $fm_class->new;
108 for my $field ( $fm_class->real_fields ) {
109 $fm->$field( $$hash{$field} );
119 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
122 $log->debug("Retrieving $self with $arg", INTERNAL);
123 my $rec = $self->SUPER::retrieve("$arg");
125 $log->debug("Could not retrieve $self with $arg!", DEBUG);
133 my $class = ref($obj) || $obj;
135 my $fm_class = 'Fieldmapper::'.$class;
136 my $fm = $fm_class->new;
139 for my $field ( $fm->real_fields ) {
140 $fm->$field( $obj->$field );
151 $log->debug("\$arg is $arg (".ref($arg).")",DEBUG);
153 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
154 return $self->create_from_fieldmapper($arg,@_);
157 return $self->SUPER::create($arg,@_);
160 sub create_from_fieldmapper {
165 $log->debug("Creating node of type ".ref($fm), DEBUG);
167 my $class = ref($obj) || $obj;
170 my %hash = map { defined $fm->$_ ?
175 if ($class->find_column( 'last_xact_id' )) {
176 my $xact_id = $class->current_xact_id;
177 throw Error unless ($xact_id);
178 $hash{last_xact_id} = $xact_id;
181 return $class->create( \%hash, @params );
191 my $class = ref($self) || $self;
193 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
194 $self = $self->retrieve($arg);
195 unless (defined $self) {
196 $log->debug("ARG! Couldn't retrieve record ".$arg->id, DEBUG);
197 throw OpenSRF::EX::WARN ("ARG! Couldn't retrieve record ");
201 if ($class->find_column( 'last_xact_id' )) {
202 my $xact_id = $self->current_xact_id;
203 throw Error unless ($xact_id);
204 $self->last_xact_id( $class->current_xact_id );
205 $self->SUPER::update;
208 $self->SUPER::delete;
216 $log->debug("Attempting to update using $arg", DEBUG) if ($arg);
218 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
219 $self = $self->modify_from_fieldmapper($arg);
220 $log->debug("Modification of $self seems to have failed....", DEBUG);
221 return undef unless (defined $self);
224 $log->debug("Calling Class::DBI->update on modified object $self", DEBUG);
225 return $self->SUPER::update if ($self->is_changed);
229 sub modify_from_fieldmapper {
233 $log->debug("Modifying object using fieldmapper", DEBUG);
235 my $class = ref($obj) || $obj;
238 $obj = $class->retrieve($fm);
240 $log->debug("Rretrieve using $fm (".$fm->id.") failed!", ERROR);
241 throw OpenSRF::EX::WARN ("No $class with id of ".$fm->id."!!");
246 my %hash = map { defined $fm->$_ ?
251 my $au = $obj->autoupdate;
254 for my $field ( keys %hash ) {
255 $obj->$field( $hash{$field} ) if ($obj->$field ne $hash{$field});
256 $log->debug("Setting field $field on $obj to $hash{$field}",INTERNAL);
259 if ($class->find_column( 'last_xact_id' ) and $obj->is_changed) {
260 my $xact_id = $obj->current_xact_id;
261 throw Error unless ($xact_id);
262 $obj->last_xact_id( $xact_id );
264 $obj->autoupdate($au)
273 return if ($VERSION);
274 #-------------------------------------------------------------------------------
275 actor::user->has_a( home_ou => 'actor::org_unit' );
276 actor::user->has_many( survey_responses => 'action::survey_response' );
277 #-------------------------------------------------------------------------------
278 actor::org_unit->has_many( users => 'actor::user' );
279 actor::org_unit->has_a( parent_ou => 'actor::org_unit' );
280 actor::org_unit->has_a( ou_type => 'actor::org_unit_type' );
281 #actor::org_unit->has_a( address => 'actor::address' );
282 #-------------------------------------------------------------------------------
284 #-------------------------------------------------------------------------------
285 action::survey_response->has_a( usr => 'actor::user' );
286 action::survey_response->has_a( survey => 'action::survey' );
287 action::survey_response->has_a( question => 'action::survey_question' );
288 action::survey_response->has_a( answer => 'action::survey_answer' );
289 #-------------------------------------------------------------------------------
290 action::survey->has_many( questions => 'action::survey_question' );
291 action::survey->has_many( responses => 'action::survey_response' );
292 #-------------------------------------------------------------------------------
293 action::survey_question->has_a( survey => 'action::survey' );
294 action::survey_question->has_many( answers => 'action::survey_answer' );
295 action::survey_question->has_many( responses => 'action::survey_response' );
296 #-------------------------------------------------------------------------------
297 action::survey_answer->has_a( question => 'action::survey' );
298 action::survey_answer->has_many( responses => 'action::survey_response' );
299 #-------------------------------------------------------------------------------
301 #-------------------------------------------------------------------------------
302 asset::copy_note->has_a( owning_copy => 'asset::copy' );
303 #-------------------------------------------------------------------------------
304 asset::copy->has_a( call_number => 'asset::call_number' );
305 asset::copy->has_many( notes => 'asset::copy_note' );
306 asset::copy->has_a( creator => 'actor::user' );
307 asset::copy->has_a( editor => 'actor::user' );
308 #-------------------------------------------------------------------------------
309 asset::call_number_note->has_a( owning_call_number => 'asset::call_number' );
310 #-------------------------------------------------------------------------------
311 asset::call_number->has_a( record => 'biblio::record_entry' );
312 asset::call_number->has_many( copies => 'asset::copy' );
313 asset::call_number->has_many( notes => 'asset::call_number_note' );
314 asset::call_number->has_a( creator => 'actor::user' );
315 asset::call_number->has_a( editor => 'actor::user' );
316 #-------------------------------------------------------------------------------
319 #-------------------------------------------------------------------------------
320 biblio::record_note->has_a( record => 'biblio::record_entry' );
321 #-------------------------------------------------------------------------------
322 biblio::record_entry->has_a( creator => 'actor::user' );
323 biblio::record_entry->has_a( editor => 'actor::user' );
324 biblio::record_entry->has_many( record_descriptor => 'metabib::record_descriptor' );
325 biblio::record_entry->has_many( notes => 'biblio::record_note' );
326 biblio::record_entry->has_many( call_numbers => 'asset::call_number' );
328 # should we have just one field entry per class for each record???? (xslt vs xpath)
329 biblio::record_entry->has_many( full_record_entries => 'metabib::full_rec' );
330 biblio::record_entry->has_many( title_field_entries => 'metabib::title_field_entry' );
331 biblio::record_entry->has_many( author_field_entries => 'metabib::author_field_entry' );
332 biblio::record_entry->has_many( subject_field_entries => 'metabib::subject_field_entry' );
333 biblio::record_entry->has_many( keyword_field_entries => 'metabib::keyword_field_entry' );
334 #-------------------------------------------------------------------------------
337 #-------------------------------------------------------------------------------
338 metabib::metarecord->has_a( master_record => 'biblio::record_entry' );
339 metabib::metarecord->has_many( source_records => [ 'metabib::metarecord_source_map' => 'source'] );
340 #-------------------------------------------------------------------------------
341 metabib::record_descriptor->has_a( record => 'biblio::record_entry' );
342 #-------------------------------------------------------------------------------
343 metabib::full_rec->has_a( record => 'biblio::record_entry' );
344 #-------------------------------------------------------------------------------
345 metabib::title_field_entry->has_a( source => 'biblio::record_entry' );
346 metabib::title_field_entry->has_a( field => 'config::metabib_field' );
347 #-------------------------------------------------------------------------------
348 metabib::author_field_entry->has_a( source => 'biblio::record_entry' );
349 metabib::author_field_entry->has_a( field => 'config::metabib_field' );
350 #-------------------------------------------------------------------------------
351 metabib::subject_field_entry->has_a( source => 'biblio::record_entry' );
352 metabib::subject_field_entry->has_a( field => 'config::metabib_field' );
353 #-------------------------------------------------------------------------------
354 metabib::keyword_field_entry->has_a( source => 'biblio::record_entry' );
355 metabib::keyword_field_entry->has_a( field => 'config::metabib_field' );
356 #-------------------------------------------------------------------------------
357 metabib::metarecord_source_map->has_a( metarecord => 'metabib::metarecord' );
358 metabib::metarecord_source_map->has_a( source => 'biblio::record_entry' );
359 #-------------------------------------------------------------------------------
361 action::circulation->has_a( usr => 'actor::user' );
362 action::circulation->has_a( target_copy => 'asset::copy' );
364 #-------------------------------------------------------------------------------
366 money::billable_transaction->has_a( usr => 'actor::user' );
367 money::billable_transaction->has_many( billings => 'money::billing' );
368 money::billable_transaction->has_many( payments => 'money::payment' );
370 money::billing->has_a( transaction => 'money::billable_transaction' );
371 money::payment->has_a( transaction => 'money::billable_transaction' );
373 money::cash_payment->has_a( transaction => 'money::billable_transaction' );
374 money::cash_payment->has_a( accepting_usr => 'actor::user' );
376 money::check_payment->has_a( transaction => 'money::billable_transaction' );
377 money::check_payment->has_a( accepting_usr => 'actor::user' );
379 money::credit_card_payment->has_a( transaction => 'money::billable_transaction' );
380 money::credit_card_payment->has_a( accepting_usr => 'actor::user' );
382 money::forgive_payment->has_a( transaction => 'money::billable_transaction' );
383 money::forgive_payment->has_a( accepting_usr => 'actor::user' );
385 money::work_payment->has_a( transaction => 'money::billable_transaction' );
386 money::work_payment->has_a( accepting_usr => 'actor::user' );
388 money::credit_payment->has_a( transaction => 'money::billable_transaction' );
389 money::credit_payment->has_a( accepting_usr => 'actor::user' );
392 # should we have just one field entry per class for each record???? (xslt vs xpath)
393 #metabib::title_field_entry_source_map->has_a( field_entry => 'metabib::title_field_entry' );
394 #metabib::title_field_entry_source_map->has_a( source_record => 'biblio::record_entry' );
395 #metabib::title_field_entry_source_map->has_a( metarecord => 'metabib::metarecord' );
396 #-------------------------------------------------------------------------------
397 #metabib::subject_field_entry_source_map->has_a( field_entry => 'metabib::subject_field_entry' );
398 #metabib::subject_field_entry_source_map->has_a( source_record => 'biblio::record_entry' );
399 #metabib::subject_field_entry_source_map->has_a( metarecord => 'metabib::metarecord' );
400 #-------------------------------------------------------------------------------
401 #metabib::author_field_entry_source_map->has_a( field_entry => 'metabib::author_field_entry' );
402 #metabib::author_field_entry_source_map->has_a( source_record => 'biblio::record_entry' );
403 #metabib::author_field_entry_source_map->has_a( metarecord => 'metabib::metarecord' );
404 #-------------------------------------------------------------------------------
405 #metabib::keyword_field_entry_source_map->has_a( field_entry => 'metabib::keyword_field_entry' );
406 #metabib::keyword_field_entry_source_map->has_a( source_record => 'biblio::record_entry' );
407 #metabib::keyword_field_entry_source_map->has_a( metarecord => 'metabib::metarecord' );
408 #-------------------------------------------------------------------------------