1 package OpenILS::Application::Storage::CDBI;
4 use base qw/Class::DBI/;
6 use OpenILS::Utils::Fieldmapper;
11 use OpenILS::Application::Storage::CDBI::actor;
12 use OpenILS::Application::Storage::CDBI::asset;
13 use OpenILS::Application::Storage::CDBI::biblio;
14 use OpenILS::Application::Storage::CDBI::metabib;
19 __PACKAGE__->set_sql( 'OILSFastSearch', <<" SQL", 'Main');
25 __PACKAGE__->set_sql( 'OILSFastOrderedSearch', <<" SQL", 'Main');
32 $self->SUPER::child_init(@_);
38 $class = ref($class) || $class;
44 if (!(defined($order) and ref($order) and ref($order) eq 'HASH')) {
45 if (defined($value) and ref($order) and ref($order) eq 'HASH') {
48 $field = $class->primary_column;
50 $order = { order_by => 'id' }
54 unless (defined $value) {
56 $field = $class->primary_column;
59 my $fm_class = 'Fieldmapper::'.$class;
60 my $field_list = join ',', $class->columns('All');
62 my $sth = $class->sql_OILSFastOrderedSearch( $field_list, $class->table, $field, $order->{order_by});
63 $sth->execute($value);
69 return map $class->construct($_), $self->fast_flesh_sth(@_)->fetchall_hash;
72 sub fast_fieldmapper {
74 my $class = ref($self) || $self;
75 my $fm_class = 'Fieldmapper::'.$class;
77 for my $hash ($self->fast_flesh_sth(@_)->fetchall_hash) {
78 my $fm = $fm_class->new;
79 for my $field ( keys %$hash ) {
80 $fm->$field( $$hash{$field} );
90 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
93 return $self->SUPER::retrieve("$arg");
98 my $class = ref($obj) || $obj;
100 my $fm_class = 'Fieldmapper::'.$class;
101 my $fm = $fm_class->new;
104 for my $field ( $fm->real_fields ) {
105 $fm->$field( $obj->$field );
116 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
117 return $self->create_from_fieldmapper($arg,@_);
120 return $self->SUPER::create($arg,@_);
123 sub create_from_fieldmapper {
128 my $class = ref($obj) || $obj;
131 my %hash = map { defined $fm->$_ ?
136 if ($class->find_column( 'last_xact_id' )) {
137 my $xact_id = $class->current_xact_id;
138 throw Error unless ($xact_id);
139 $hash{last_xact_id} = $xact_id;
142 return $class->create( \%hash, @params );
152 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
153 $self = $self->modify_from_fieldmapper($arg);
156 $self->SUPER::update;
164 if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
165 $self = $self->retrieve($arg);
168 if ($class->find_column( 'last_xact_id' )) {
169 my $xact_id = $self->current_xact_id;
170 throw Error unless ($xact_id);
171 $self->last_xact_id( $self->current_xact_id );
175 $self->SUPER::delete;
179 sub modify_from_fieldmapper {
183 my $class = ref($obj) || $obj;
186 $obj = $class->retieve($fm);
187 return undef unless ($obj);
190 my %hash = map { defined $fm->$_ ?
195 if ($class->find_column( 'last_xact_id' )) {
196 my $xact_id = $obj->current_xact_id;
197 throw Error unless ($xact_id);
198 $hash{last_xact_id} = $xact_id;
201 my $au = $obj->autoupdate;
204 for my $field ( keys %hash ) {
205 $obj->$field( $hash{$field} );
208 $obj->autoupdate($au);
216 #-------------------------------------------------------------------------------
217 actor::user->has_a( home_ou => 'actor::org_unit' );
218 #actor::org_unit->has_a( address => 'actor::address' );
219 #-------------------------------------------------------------------------------
220 actor::org_unit->has_many( users => 'actor::user' );
221 actor::org_unit->has_a( parent_ou => 'actor::org_unit' );
222 actor::org_unit->has_a( ou_type => 'actor::org_unit_type' );
223 #actor::org_unit->has_a( address => 'actor::address' );
224 #-------------------------------------------------------------------------------
226 #-------------------------------------------------------------------------------
227 asset::copy->has_a( call_number => 'asset::call_number' );
228 #asset::copy->might_have( metadata => 'asset::copy_metadata' );
229 #-------------------------------------------------------------------------------
230 #asset::copy_metadata->might_have( copy => 'asset::copy' );
231 asset::copy_metadata->has_a( circulating_location => 'actor::org_unit');
232 asset::copy_metadata->has_a( hold_radius => 'actor::org_unit_type');
233 #-------------------------------------------------------------------------------
234 asset::call_number->has_a( record => 'biblio::record_entry' );
235 asset::call_number->has_many( copies => 'asset::copy' );
236 #-------------------------------------------------------------------------------
239 #-------------------------------------------------------------------------------
240 biblio::record_note->has_a( record => 'biblio::record_entry' );
241 #-------------------------------------------------------------------------------
242 biblio::record_entry->has_a( creator => 'actor::user' );
243 biblio::record_entry->has_a( editor => 'actor::user' );
244 biblio::record_entry->might_have( mods_entry => 'biblio::record_mods' => qw/mods/ );
245 biblio::record_entry->has_many( notes => 'biblio::record_note' );
246 biblio::record_entry->has_many( nodes => 'biblio::record_node', { order_by => 'intra_doc_id' } );
247 biblio::record_entry->has_many( call_numbers => 'asset::call_number' );
249 # should we have just one field entry per class for each record???? (xslt vs xpath)
250 #biblio::record_entry->has_a( title_field_entries => 'metabib::title_field_entry' );
251 #biblio::record_entry->has_a( author_field_entries => 'metabib::author_field_entry' );
252 #biblio::record_entry->has_a( subject_field_entries => 'metabib::subject_field_entry' );
253 #biblio::record_entry->has_a( keyword_field_entries => 'metabib::keyword_field_entry' );
254 #-------------------------------------------------------------------------------
255 biblio::record_node->has_a( owner_doc => 'biblio::record_entry' );
256 #biblio::record_node->has_a(
257 # parent_node => 'biblio::record_node::subnode',
258 # inflate => sub { return biblio::record_node::subnode::_load(@_) }
260 #-------------------------------------------------------------------------------
262 #-------------------------------------------------------------------------------
263 metabib::metarecord->has_a( master_record => 'biblio::record_entry' );
264 metabib::metarecord->has_many( source_records => [ 'metabib::metarecord_source_map' => 'source_record'] );
265 #-------------------------------------------------------------------------------
266 metabib::title_field_entry->has_many( source_records => [ 'metabib::title_field_entry_source_map' => 'source_record'] );
267 #metabib::title_field_entry->has_a( field => 'config::metabib_field_map' );
268 #-------------------------------------------------------------------------------
269 metabib::author_field_entry->has_many( source_records => [ 'metabib::author_field_entry_source_map' => 'source_record'] );
270 #metabib::author_field_entry->has_a( field => 'config::metabib_field_map' );
271 #-------------------------------------------------------------------------------
272 metabib::subject_field_entry->has_many( source_records => [ 'metabib::title_field_entry_source_map' => 'source_record'] );
273 #metabib::subject_field_entry->has_a( field => 'config::metabib_field_map' );
274 #-------------------------------------------------------------------------------
275 metabib::keyword_field_entry->has_many( source_records => [ 'metabib::keyword_field_entry_source_map' => 'source_record'] );
276 #metabib::keyword_field_entry->has_a( field => 'config::metabib_field_map' );
277 #-------------------------------------------------------------------------------
278 metabib::metarecord_source_map->has_a( metarecord => 'metabib::metarecord' );
279 metabib::metarecord_source_map->has_a( source_record => 'biblio::record_entry' );
280 #-------------------------------------------------------------------------------
283 # should we have just one field entry per class for each record???? (xslt vs xpath)
284 metabib::title_field_entry_source_map->has_a( field_entry => 'metabib::title_field_entry' );
285 metabib::title_field_entry_source_map->has_a( source_record => 'biblio::record_entry' );
286 #-------------------------------------------------------------------------------
287 metabib::subject_field_entry_source_map->has_a( field_entry => 'metabib::subject_field_entry' );
288 metabib::subject_field_entry_source_map->has_a( source_record => 'biblio::record_entry' );
289 #-------------------------------------------------------------------------------
290 metabib::author_field_entry_source_map->has_a( field_entry => 'metabib::author_field_entry' );
291 metabib::author_field_entry_source_map->has_a( source_record => 'biblio::record_entry' );
292 #-------------------------------------------------------------------------------
293 metabib::keyword_field_entry_source_map->has_a( field_entry => 'metabib::keyword_field_entry' );
294 metabib::keyword_field_entry_source_map->has_a( source_record => 'biblio::record_entry' );
295 #-------------------------------------------------------------------------------