1 package OpenILS::Application::Storage::CDBI;
4 use base qw/Class::DBI/;
6 use OpenILS::Utils::Fieldmapper;
11 use OpenILS::Application::Storage::CDBI::config;
12 use OpenILS::Application::Storage::CDBI::actor;
13 use OpenILS::Application::Storage::CDBI::asset;
14 use OpenILS::Application::Storage::CDBI::biblio;
15 use OpenILS::Application::Storage::CDBI::metabib;
20 __PACKAGE__->set_sql( 'OILSFastSearch', <<" SQL", 'Main');
26 __PACKAGE__->set_sql( 'OILSFastOrderedSearch', <<" SQL", 'Main');
33 $self->SUPER::child_init(@_);
39 $class = ref($class) || $class;
45 if (!(defined($order) and ref($order) and ref($order) eq 'HASH')) {
46 if (defined($value) and ref($order) and ref($order) eq 'HASH') {
49 $field = $class->primary_column;
51 $order = { order_by => 'id' }
55 unless (defined $value) {
57 $field = $class->primary_column;
60 my $fm_class = 'Fieldmapper::'.$class;
61 my $field_list = join ',', $class->columns('All');
63 my $sth = $class->sql_OILSFastOrderedSearch( $field_list, $class->table, $field, $order->{order_by});
64 $sth->execute($value);
70 return map $class->construct($_), $self->fast_flesh_sth(@_)->fetchall_hash;
73 sub fast_fieldmapper {
75 my $class = ref($self) || $self;
76 my $fm_class = 'Fieldmapper::'.$class;
78 for my $hash ($self->fast_flesh_sth(@_)->fetchall_hash) {
79 my $fm = $fm_class->new;
80 for my $field ( keys %$hash ) {
81 $fm->$field( $$hash{$field} );
91 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
94 return $self->SUPER::retrieve("$arg");
99 my $class = ref($obj) || $obj;
101 my $fm_class = 'Fieldmapper::'.$class;
102 my $fm = $fm_class->new;
105 for my $field ( $fm->real_fields ) {
106 $fm->$field( $obj->$field );
117 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
118 return $self->create_from_fieldmapper($arg,@_);
121 return $self->SUPER::create($arg,@_);
124 sub create_from_fieldmapper {
129 my $class = ref($obj) || $obj;
132 my %hash = map { defined $fm->$_ ?
137 if ($class->find_column( 'last_xact_id' )) {
138 my $xact_id = $class->current_xact_id;
139 throw Error unless ($xact_id);
140 $hash{last_xact_id} = $xact_id;
143 return $class->create( \%hash, @params );
153 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
154 $self = $self->modify_from_fieldmapper($arg);
157 $self->SUPER::update;
165 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
166 $self = $self->retrieve($arg);
169 if ($class->find_column( 'last_xact_id' )) {
170 my $xact_id = $self->current_xact_id;
171 throw Error unless ($xact_id);
172 $self->last_xact_id( $self->current_xact_id );
176 $self->SUPER::delete;
180 sub modify_from_fieldmapper {
184 my $class = ref($obj) || $obj;
187 $obj = $class->retieve($fm);
188 return undef unless ($obj);
191 my %hash = map { defined $fm->$_ ?
196 if ($class->find_column( 'last_xact_id' )) {
197 my $xact_id = $obj->current_xact_id;
198 throw Error unless ($xact_id);
199 $hash{last_xact_id} = $xact_id;
202 my $au = $obj->autoupdate;
205 for my $field ( keys %hash ) {
206 $obj->$field( $hash{$field} );
209 $obj->autoupdate($au);
217 #-------------------------------------------------------------------------------
218 actor::user->has_a( home_ou => 'actor::org_unit' );
219 #actor::org_unit->has_a( address => 'actor::address' );
220 #-------------------------------------------------------------------------------
221 actor::org_unit->has_many( users => 'actor::user' );
222 actor::org_unit->has_a( parent_ou => 'actor::org_unit' );
223 actor::org_unit->has_a( ou_type => 'actor::org_unit_type' );
224 #actor::org_unit->has_a( address => 'actor::address' );
225 #-------------------------------------------------------------------------------
227 #-------------------------------------------------------------------------------
228 asset::copy->has_a( call_number => 'asset::call_number' );
229 #asset::copy->might_have( metadata => 'asset::copy_metadata' );
230 #-------------------------------------------------------------------------------
231 #asset::copy_metadata->might_have( copy => 'asset::copy' );
232 asset::copy_metadata->has_a( circulating_location => 'actor::org_unit');
233 asset::copy_metadata->has_a( hold_radius => 'actor::org_unit_type');
234 #-------------------------------------------------------------------------------
235 asset::call_number->has_a( record => 'biblio::record_entry' );
236 asset::call_number->has_many( copies => 'asset::copy' );
237 #-------------------------------------------------------------------------------
240 #-------------------------------------------------------------------------------
241 biblio::record_note->has_a( record => 'biblio::record_entry' );
242 #-------------------------------------------------------------------------------
243 biblio::record_entry->has_a( creator => 'actor::user' );
244 biblio::record_entry->has_a( editor => 'actor::user' );
245 biblio::record_entry->might_have( mods_entry => 'biblio::record_mods' => qw/mods/ );
246 biblio::record_entry->has_many( notes => 'biblio::record_note' );
247 biblio::record_entry->has_many( nodes => 'biblio::record_node', { order_by => 'intra_doc_id' } );
248 biblio::record_entry->has_many( call_numbers => 'asset::call_number' );
250 # should we have just one field entry per class for each record???? (xslt vs xpath)
251 #biblio::record_entry->has_a( title_field_entries => 'metabib::title_field_entry' );
252 #biblio::record_entry->has_a( author_field_entries => 'metabib::author_field_entry' );
253 #biblio::record_entry->has_a( subject_field_entries => 'metabib::subject_field_entry' );
254 #biblio::record_entry->has_a( keyword_field_entries => 'metabib::keyword_field_entry' );
255 #-------------------------------------------------------------------------------
256 biblio::record_node->has_a( owner_doc => 'biblio::record_entry' );
257 #biblio::record_node->has_a(
258 # parent_node => 'biblio::record_node::subnode',
259 # inflate => sub { return biblio::record_node::subnode::_load(@_) }
261 #-------------------------------------------------------------------------------
263 #-------------------------------------------------------------------------------
264 metabib::metarecord->has_a( master_record => 'biblio::record_entry' );
265 metabib::metarecord->has_many( source_records => [ 'metabib::metarecord_source_map' => 'source_record'] );
266 #-------------------------------------------------------------------------------
267 metabib::title_field_entry->has_many( source_records => [ 'metabib::title_field_entry_source_map' => 'source_record'] );
268 #metabib::title_field_entry->has_a( field => 'config::metabib_field_map' );
269 #-------------------------------------------------------------------------------
270 metabib::author_field_entry->has_many( source_records => [ 'metabib::author_field_entry_source_map' => 'source_record'] );
271 #metabib::author_field_entry->has_a( field => 'config::metabib_field_map' );
272 #-------------------------------------------------------------------------------
273 metabib::subject_field_entry->has_many( source_records => [ 'metabib::title_field_entry_source_map' => 'source_record'] );
274 #metabib::subject_field_entry->has_a( field => 'config::metabib_field_map' );
275 #-------------------------------------------------------------------------------
276 metabib::keyword_field_entry->has_many( source_records => [ 'metabib::keyword_field_entry_source_map' => 'source_record'] );
277 #metabib::keyword_field_entry->has_a( field => 'config::metabib_field_map' );
278 #-------------------------------------------------------------------------------
279 metabib::metarecord_source_map->has_a( metarecord => 'metabib::metarecord' );
280 metabib::metarecord_source_map->has_a( source_record => 'biblio::record_entry' );
281 #-------------------------------------------------------------------------------
284 # should we have just one field entry per class for each record???? (xslt vs xpath)
285 metabib::title_field_entry_source_map->has_a( field_entry => 'metabib::title_field_entry' );
286 metabib::title_field_entry_source_map->has_a( source_record => 'biblio::record_entry' );
287 #-------------------------------------------------------------------------------
288 metabib::subject_field_entry_source_map->has_a( field_entry => 'metabib::subject_field_entry' );
289 metabib::subject_field_entry_source_map->has_a( source_record => 'biblio::record_entry' );
290 #-------------------------------------------------------------------------------
291 metabib::author_field_entry_source_map->has_a( field_entry => 'metabib::author_field_entry' );
292 metabib::author_field_entry_source_map->has_a( source_record => 'biblio::record_entry' );
293 #-------------------------------------------------------------------------------
294 metabib::keyword_field_entry_source_map->has_a( field_entry => 'metabib::keyword_field_entry' );
295 metabib::keyword_field_entry_source_map->has_a( source_record => 'biblio::record_entry' );
296 #-------------------------------------------------------------------------------