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::asset;
8 use OpenILS::Application::Storage::CDBI::biblio;
9 use OpenILS::Application::Storage::CDBI::metabib;
11 use OpenILS::Utils::Fieldmapper;
12 use OpenSRF::Utils::Logger;
15 my $log = 'OpenSRF::Utils::Logger';
20 $log->debug("Creating ImaDBI Querys", DEBUG);
21 __PACKAGE__->set_sql( 'OILSFastSearch', <<" SQL", 'Main');
27 __PACKAGE__->set_sql( 'OILSFastOrderedSearch', <<" SQL", 'Main');
34 $log->debug("Calling Driver child_init", DEBUG);
35 $self->SUPER::child_init(@_);
41 $class = ref($class) || $class;
47 if (!(defined($order) and ref($order) and ref($order) eq 'HASH')) {
48 if (defined($value) and ref($order) and ref($order) eq 'HASH') {
51 $field = $class->primary_column;
53 $order = { order_by => 'id' }
57 unless (defined $value) {
59 $field = $class->primary_column;
62 my $fm_class = 'Fieldmapper::'.$class;
63 my $field_list = join ',', $class->columns('All');
65 my $sth = $class->sql_OILSFastOrderedSearch( $field_list, $class->table, $field, $order->{order_by});
66 $sth->execute($value);
72 return map $class->construct($_), $self->fast_flesh_sth(@_)->fetchall_hash;
75 sub fast_fieldmapper {
77 my $class = ref($self) || $self;
78 my $fm_class = 'Fieldmapper::'.$class;
80 for my $hash ($self->fast_flesh_sth(@_)->fetchall_hash) {
81 my $fm = $fm_class->new;
82 for my $field ( keys %$hash ) {
83 $fm->$field( $$hash{$field} );
93 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
96 $log->debug("Retrieving $self with $arg", INTERNAL);
97 my $rec = $self->SUPER::retrieve("$arg");
99 $log->debug("Could not retrieve $self with $arg!", DEBUG);
107 my $class = ref($obj) || $obj;
109 my $fm_class = 'Fieldmapper::'.$class;
110 my $fm = $fm_class->new;
113 for my $field ( $fm->real_fields ) {
114 $fm->$field( $obj->$field );
125 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
126 return $self->create_from_fieldmapper($arg,@_);
129 return $self->SUPER::create($arg,@_);
132 sub create_from_fieldmapper {
137 my $class = ref($obj) || $obj;
140 my %hash = map { defined $fm->$_ ?
145 if ($class->find_column( 'last_xact_id' )) {
146 my $xact_id = $class->current_xact_id;
147 throw Error unless ($xact_id);
148 $hash{last_xact_id} = $xact_id;
151 return $class->create( \%hash, @params );
161 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
162 $self = $self->retrieve($arg);
165 if ($class->find_column( 'last_xact_id' )) {
166 my $xact_id = $self->current_xact_id;
167 throw Error unless ($xact_id);
168 $self->last_xact_id( $self->current_xact_id );
172 $self->SUPER::delete;
180 $log->debug("Attempting to update using $arg", DEBUG) if ($arg);
182 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
183 $self = $self->modify_from_fieldmapper($arg);
184 $log->debug("Modification of $self seems to have failed....", DEBUG);
185 return undef unless (defined $self);
188 $log->debug("Calling Class::DBI->update on modified object $self", DEBUG);
189 return $self->SUPER::update if ($self->is_changed);
193 sub modify_from_fieldmapper {
197 $log->debug("Modifying object using fieldmapper", DEBUG);
199 my $class = ref($obj) || $obj;
202 $obj = $class->retrieve($fm);
204 $log->debug("Rretrieve using $fm (".$fm->id.") failed!", ERROR);
205 throw OpenSRF::EX::WARN ("No $class with id of ".$fm->id."!!");
210 my %hash = map { defined $fm->$_ ?
215 my $au = $obj->autoupdate;
218 for my $field ( keys %hash ) {
219 $obj->$field( $hash{$field} ) if ($obj->$field ne $hash{$field});
220 $log->debug("Setting field $field on $obj to $hash{$field}",INTERNAL);
223 if ($class->find_column( 'last_xact_id' ) and $obj->is_changed) {
224 my $xact_id = $obj->current_xact_id;
225 throw Error unless ($xact_id);
226 $obj->last_xact_id( $xact_id );
228 $obj->autoupdate($au)
237 return if ($VERSION);
238 #-------------------------------------------------------------------------------
239 actor::user->has_a( home_ou => 'actor::org_unit' );
240 #actor::org_unit->has_a( address => 'actor::address' );
241 #-------------------------------------------------------------------------------
242 actor::org_unit->has_many( users => 'actor::user' );
243 actor::org_unit->has_a( parent_ou => 'actor::org_unit' );
244 actor::org_unit->has_a( ou_type => 'actor::org_unit_type' );
245 #actor::org_unit->has_a( address => 'actor::address' );
246 #-------------------------------------------------------------------------------
248 #-------------------------------------------------------------------------------
249 asset::copy->has_a( call_number => 'asset::call_number' );
250 #asset::copy->might_have( metadata => 'asset::copy_metadata' );
251 #-------------------------------------------------------------------------------
252 #asset::copy_metadata->might_have( copy => 'asset::copy' );
253 asset::copy_metadata->has_a( circulating_location => 'actor::org_unit');
254 asset::copy_metadata->has_a( hold_radius => 'actor::org_unit_type');
255 #-------------------------------------------------------------------------------
256 asset::call_number->has_a( record => 'biblio::record_entry' );
257 asset::call_number->has_many( copies => 'asset::copy' );
258 #-------------------------------------------------------------------------------
261 #-------------------------------------------------------------------------------
262 biblio::record_note->has_a( record => 'biblio::record_entry' );
263 #-------------------------------------------------------------------------------
264 biblio::record_entry->has_a( creator => 'actor::user' );
265 biblio::record_entry->has_a( editor => 'actor::user' );
266 biblio::record_entry->might_have( mods_entry => 'biblio::record_mods' => qw/mods/ );
267 biblio::record_entry->has_many( notes => 'biblio::record_note' );
268 biblio::record_entry->has_many( nodes => 'biblio::record_node', { order_by => 'intra_doc_id' } );
269 biblio::record_entry->has_many( call_numbers => 'asset::call_number' );
271 # should we have just one field entry per class for each record???? (xslt vs xpath)
272 #biblio::record_entry->has_a( title_field_entries => 'metabib::title_field_entry' );
273 #biblio::record_entry->has_a( author_field_entries => 'metabib::author_field_entry' );
274 #biblio::record_entry->has_a( subject_field_entries => 'metabib::subject_field_entry' );
275 #biblio::record_entry->has_a( keyword_field_entries => 'metabib::keyword_field_entry' );
276 #-------------------------------------------------------------------------------
277 biblio::record_node->has_a( owner_doc => 'biblio::record_entry' );
278 #biblio::record_node->has_a(
279 # parent_node => 'biblio::record_node::subnode',
280 # inflate => sub { return biblio::record_node::subnode::_load(@_) }
282 #-------------------------------------------------------------------------------
284 #-------------------------------------------------------------------------------
285 metabib::metarecord->has_a( master_record => 'biblio::record_entry' );
286 metabib::metarecord->has_many( source_records => [ 'metabib::metarecord_source_map' => 'source_record'] );
287 #-------------------------------------------------------------------------------
288 metabib::title_field_entry->has_many( source_records => [ 'metabib::title_field_entry_source_map' => 'source_record'] );
289 metabib::title_field_entry->has_a( field => 'config::metabib_field' );
290 #-------------------------------------------------------------------------------
291 metabib::author_field_entry->has_many( source_records => [ 'metabib::author_field_entry_source_map' => 'source_record'] );
292 metabib::author_field_entry->has_a( field => 'config::metabib_field' );
293 #-------------------------------------------------------------------------------
294 metabib::subject_field_entry->has_many( source_records => [ 'metabib::title_field_entry_source_map' => 'source_record'] );
295 metabib::subject_field_entry->has_a( field => 'config::metabib_field' );
296 #-------------------------------------------------------------------------------
297 metabib::keyword_field_entry->has_many( source_records => [ 'metabib::keyword_field_entry_source_map' => 'source_record'] );
298 metabib::keyword_field_entry->has_a( field => 'config::metabib_field' );
299 #-------------------------------------------------------------------------------
300 metabib::metarecord_source_map->has_a( metarecord => 'metabib::metarecord' );
301 metabib::metarecord_source_map->has_a( source_record => 'biblio::record_entry' );
302 #-------------------------------------------------------------------------------
305 # should we have just one field entry per class for each record???? (xslt vs xpath)
306 metabib::title_field_entry_source_map->has_a( field_entry => 'metabib::title_field_entry' );
307 metabib::title_field_entry_source_map->has_a( source_record => 'biblio::record_entry' );
308 #-------------------------------------------------------------------------------
309 metabib::subject_field_entry_source_map->has_a( field_entry => 'metabib::subject_field_entry' );
310 metabib::subject_field_entry_source_map->has_a( source_record => 'biblio::record_entry' );
311 #-------------------------------------------------------------------------------
312 metabib::author_field_entry_source_map->has_a( field_entry => 'metabib::author_field_entry' );
313 metabib::author_field_entry_source_map->has_a( source_record => 'biblio::record_entry' );
314 #-------------------------------------------------------------------------------
315 metabib::keyword_field_entry_source_map->has_a( field_entry => 'metabib::keyword_field_entry' );
316 metabib::keyword_field_entry_source_map->has_a( source_record => 'biblio::record_entry' );
317 #-------------------------------------------------------------------------------