]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Storage/CDBI.pm
added tons more SQL level stuff... I am going to bed now
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Storage / CDBI.pm
1 package OpenILS::Application::Storage::CDBI;
2 use vars qw/@ISA/;
3 use Class::DBI;
4 use base qw/Class::DBI/;
5
6 use OpenILS::Utils::Fieldmapper;
7
8 our $VERSION = 1;
9
10
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;
15
16 sub child_init {
17         my $self = shift;
18
19         __PACKAGE__->set_sql( 'OILSFastSearch', <<"     SQL", 'Main');
20                 SELECT  %s
21                   FROM  %s
22                   WHERE %s = ?
23         SQL
24
25         __PACKAGE__->set_sql( 'OILSFastOrderedSearch', <<"      SQL", 'Main');
26                 SELECT  %s
27                   FROM  %s
28                   WHERE %s = ?
29                   ORDER BY %s
30         SQL
31
32         $self->SUPER::child_init(@_);
33
34 }
35
36 sub fast_flesh_sth {
37         my $class = shift;
38         $class = ref($class) || $class;
39
40         my $field = shift;
41         my $value = shift;
42         my $order = shift;
43
44         if (!(defined($order) and ref($order) and ref($order) eq 'HASH')) {
45                 if (defined($value) and ref($order) and ref($order) eq 'HASH') {
46                         $order = $value;
47                         $value = $field;
48                         $field = $class->primary_column;
49                 } else {
50                         $order = { order_by => 'id' }
51                 }
52         }
53
54         unless (defined $value) {
55                 $value = $field;
56                 $field = $class->primary_column;
57         }
58
59         my $fm_class = 'Fieldmapper::'.$class;
60         my $field_list = join ',', $class->columns('All');
61         
62         my $sth = $class->sql_OILSFastOrderedSearch( $field_list, $class->table, $field, $order->{order_by});
63         $sth->execute($value);
64         return $sth;
65 }
66
67 sub fast_flesh {
68         my $self = shift;
69         return map $class->construct($_), $self->fast_flesh_sth(@_)->fetchall_hash;
70 }
71
72 sub fast_fieldmapper {
73         my $self = shift;
74         my $class = ref($self) || $self;
75         my $fm_class = 'Fieldmapper::'.$class;
76         my @fms;
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} );
81                 }
82                 push @fms, $fm;
83         }
84         return @fms;
85 }
86
87 sub retrieve {
88         my $self = shift;
89         my $arg = shift;
90         if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
91                 $arg = $arg->id;
92         }
93         return $self->SUPER::retrieve("$arg");
94 }
95
96 sub to_fieldmapper {
97         my $obj = shift;
98         my $class = ref($obj) || $obj;
99
100         my $fm_class = 'Fieldmapper::'.$class;
101         my $fm = $fm_class->new;
102
103         if (ref($obj)) {
104                 for my $field ( $fm->real_fields ) {
105                         $fm->$field( $obj->$field );
106                 }
107         }
108
109         return $fm;
110 }
111
112 sub create {
113         my $self = shift;
114         my $arg = shift;
115
116         if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
117                 return $self->create_from_fieldmapper($arg,@_);
118         }
119
120         return $self->SUPER::create($arg,@_);
121 }
122
123 sub create_from_fieldmapper {
124         my $obj = shift;
125         my $fm = shift;
126         my @params = @_;
127
128         my $class = ref($obj) || $obj;
129
130         if (ref $fm) {
131                 my %hash = map { defined $fm->$_ ?
132                                         ($_ => $fm->$_) :
133                                         ()
134                                 } $fm->real_fields;
135
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;
140                 }
141
142                 return $class->create( \%hash, @params );
143         } else {
144                 return undef;
145         }
146 }
147
148 sub update {
149         my $self = shift;
150         my $arg = shift;
151
152         if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
153                 $self = $self->modify_from_fieldmapper($arg);
154         }
155
156         $self->SUPER::update;
157         return $self;
158 }
159
160 sub delete {
161         my $self = shift;
162         my $arg = shift;
163
164         if (ref($arg) and UNIVERSAL::isa($arg => 'Fieldmapper')) {
165                 $self = $self->retrieve($arg);
166         }
167
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 );
172                 $self->update;
173         }
174
175         $self->SUPER::delete;
176         return $arg;
177 }
178
179 sub modify_from_fieldmapper {
180         my $obj = shift;
181         my $fm = shift;
182
183         my $class = ref($obj) || $obj;
184
185         if (!ref($obj)) {
186                 $obj = $class->retieve($fm);
187                 return undef unless ($obj);
188         }
189
190         my %hash = map { defined $fm->$_ ?
191                                 ($_ => $fm->$_) :
192                                 ()
193                         } $fm->real_fields;
194
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;
199         }
200
201         my $au = $obj->autoupdate;
202         $obj->autoupdate(0);
203         
204         for my $field ( keys %hash ) {
205                 $obj->$field( $hash{$field} );
206         }
207
208         $obj->autoupdate($au);
209
210         return $obj;
211 }
212
213
214
215
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 #-------------------------------------------------------------------------------
225
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 #-------------------------------------------------------------------------------
237
238
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' );
248
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(@_) }
259 #);
260 #-------------------------------------------------------------------------------
261
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 #-------------------------------------------------------------------------------
281
282
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 #-------------------------------------------------------------------------------
296
297
298 1;