]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Storage/Driver/Pg.pm
big changes in little china
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Storage / Driver / Pg.pm
1 { # Based on the change to Class::DBI in OpenILS::Application::Storage.  This will
2   # allow us to use TSearch2 via a simple cdbi "search" interface.
3         #-------------------------------------------------------------------------------
4         use Class::DBI;
5         package Class::DBI;
6
7         sub search_fti {
8                 my $self = shift;
9                 my @args = @_;
10                 if (ref($args[-1]) eq 'HASH') {
11                         $args[-1]->{_placeholder} = "to_tsquery('default',?)";
12                 } else {
13                         push @args, {_placeholder => "to_tsquery('default',?)"};
14                 }
15                 $self->_do_search("@@"  => @args);
16         }
17 }
18
19 { # Every driver needs to provide a 'compile()' method to OpenILS::Application::Storage::FTS.
20   # If that driver wants to support FTI, that is...
21         #-------------------------------------------------------------------------------
22         package OpenILS::Application::Storage::FTS;
23         use OpenSRF::Utils::Logger qw/:level/;
24         my $log = 'OpenSRF::Utils::Logger';
25
26         sub compile {
27                 my $self = shift;
28                 my $term = shift;
29
30                 $self = ref($self) || $self;
31                 $self = bless {} => $self;
32
33                 $self->decompose($term);
34
35                 my $newterm = join('&', $self->words);
36
37                 if (@{$self->nots}) {
38                         $newterm = '('.$newterm.')&('. join('|', $self->nots) . ')';
39                 }
40
41                 $log->debug("Compiled term is [$newterm]", DEBUG);
42                 $newterm = OpenILS::Application::Storage::Driver::Pg->quote($newterm);
43                 $log->debug("Quoted term is [$newterm]", DEBUG);
44
45                 $self->{fts_query} = ["to_tsquery('default',$newterm)"];
46                 $self->{fts_query_nots} = [];
47                 $self->{fts_op} = '@@';
48                 $self->{text_col} = shift;
49                 $self->{fts_col} = shift;
50
51                 return $self;
52         }
53
54         sub sql_where_clause {
55                 my $self = shift;
56                 my $column = $self->fts_col;
57                 my @output;
58         
59                 my @ranks;
60                 for my $fts ( $self->fts_query ) {
61                         push @output, join(' ', $self->fts_col, $self->{fts_op}, $fts);
62                         push @ranks, "rank($column, $fts)";
63                 }
64                 $self->{fts_rank} = \@ranks;
65         
66                 my $phrase_match = $self->sql_exact_phrase_match();
67                 return join(' AND ', @output) . $phrase_match;
68         }
69
70 }
71
72
73 { # The driver package itself just needs a db_Main method (or db_Slaves if
74   #Class::DBI::Replication is in use) for Class::DBI to call.
75   #
76   # Any other fixups can go in here too... Also, the drivers should subclass the
77   # DBI driver that they are wrapping, or provide a 'quote()' method that calls
78   # the DBD::xxx::quote() method on FTI's behalf.
79   #
80   # The dirver MUST be a subclass of Class::DBI(::Replication) and
81   # OpenILS::Application::Storage.
82   #-------------------------------------------------------------------------------
83         package OpenILS::Application::Storage::Driver::Pg;
84         use Class::DBI;
85         use base qw/Class::DBI OpenILS::Application::Storage/;
86         use DBI;
87         use OpenSRF::EX qw/:try/;
88         use OpenSRF::DomainObject::oilsResponse;
89         use OpenSRF::Utils::Logger qw/:level/;
90         my $log = 'OpenSRF::Utils::Logger';
91
92         __PACKAGE__->set_sql( retrieve_limited => 'SELECT * FROM __TABLE__ ORDER BY id LIMIT ?' );
93         __PACKAGE__->set_sql( copy_start => 'COPY %s (%s) FROM STDIN;' );
94         __PACKAGE__->set_sql( copy_end => '\.' );
95
96         my $master_db;
97         my @slave_dbs;
98         my $_db_params;
99         sub child_init {
100                 my $self = shift;
101                 $_db_params = shift;
102
103                 $log->debug("Running child_init inside ".__PACKAGE__, INTERNAL);
104
105                 $_db_params = [ $_db_params ] unless (ref($_db_params) eq 'ARRAY');
106
107                 my %attrs = (   %{$self->_default_attributes},
108                                 RootClass => 'DBIx::ContextualFetch',
109                                 ShowErrorStatement => 1,
110                                 RaiseError => 1,
111                                 AutoCommit => 1,
112                                 PrintError => 1,
113                                 Taint => 1,
114                                 pg_enable_utf8 => 1,
115                                 FetchHashKeyName => 'NAME_lc',
116                                 ChopBlanks => 1,
117                 );
118
119                 my $master = shift @$_db_params;
120                 $master_db = DBI->connect("dbi:Pg:host=$$master{host};dbname=$$master{db}",$$master{user},$$master{pw}, \%attrs);
121                 $master_db->do("SET NAMES '$$master{client_encoding}';") if ($$master{client_encoding});
122
123                 $log->debug("Connected to MASTER db '$$master{db} at $$master{host}", INFO);
124                 
125                 for my $db (@$_db_params) {
126                         push @slave_dbs, DBI->connect("dbi:Pg:host=$$db{host};dbname=$$db{db}",$$db{user},$$db{pw}, \%attrs);
127                         $slave_dbs[-1]->do("SET NAMES '$$db{client_encoding}';") if ($$master{client_encoding});
128
129                         $log->debug("Connected to MASTER db '$$master{db} at $$master{host}", INFO);
130                 }
131
132                 $log->debug("All is well on the western front", INTERNAL);
133         }
134
135         sub db_Main {
136                 my $self = shift;
137                 return $master_db if ($self->current_xact_session);
138                 return $master_db unless (@slave_dbs);
139                 return ($master_db, @slave_dbs)[rand(scalar(@slave_dbs))];
140         }
141
142         sub quote {
143                 my $self = shift;
144                 return $self->db_Main->quote(@_)
145         }
146
147 #       sub tsearch2_trigger {
148 #               my $self = shift;
149 #               return unless ($self->value);
150 #               $self->index_vector(
151 #                       $self->db_Slaves->selectrow_array(
152 #                               "SELECT to_tsvector('default',?);",
153 #                               {},
154 #                               $self->value
155 #                       )
156 #               );
157 #       }
158
159         my $_xact_session;
160
161         sub current_xact_session {
162                 my $self = shift;
163                 if (defined($_xact_session)) {
164                         return $_xact_session;
165                 }
166                 return undef;
167         }
168
169         sub current_xact_is_auto {
170                 my $self = shift;
171                 my $auto = shift;
172                 if (defined($_xact_session) and ref($_xact_session)) {
173                         if (defined $auto) {
174                                 $_xact_session->session_data(autocommit => $auto);
175                         }
176                         return $_xact_session->session_data('autocommit'); 
177                 }
178         }
179
180         sub current_xact_id {
181                 my $self = shift;
182                 if (defined($_xact_session) and ref($_xact_session)) {
183                         return $_xact_session->session_id;
184                 }
185                 return undef;
186         }
187
188         sub set_xact_session {
189                 my $self = shift;
190                 my $ses = shift;
191                 if (!defined($ses)) {
192                         return undef;
193                 }
194                 $_xact_session = $ses;
195                 return $_xact_session;
196         }
197
198         sub unset_xact_session {
199                 my $self = shift;
200                 my $ses = $_xact_session;
201                 undef $_xact_session;
202                 return $ses;
203         }
204
205 }
206
207
208 {
209         package OpenILS::Application::Storage;
210         use OpenSRF::Utils::Logger;
211         my $log = 'OpenSRF::Utils::Logger';
212
213         my $pg = 'OpenILS::Application::Storage::Driver::Pg';
214
215         sub pg_begin_xaction {
216                 my $self = shift;
217                 my $client = shift;
218
219                 if (my $old_xact = $pg->current_xact_session) {
220                         if ($pg->current_xact_is_auto) {
221                                 $log->debug("Commiting old autocommit transaction with Open-ILS XACT-ID [$old_xact]", INFO);
222                                 $self->pg_commit_xaction($client);
223                         } else {
224                                 $log->debug("Rolling back old NON-autocommit transaction with Open-ILS XACT-ID [$old_xact]", INFO);
225                                 $self->pg_rollback_xaction($client);
226                                 throw OpenSRF::DomainObject::oilsException->new(
227                                                 statusCode => 500,
228                                                 status => "Previous transaction rolled back!",
229                                 );
230                         }
231                 }
232                 
233                 $pg->set_xact_session( $client->session );
234                 my $xact_id = $pg->current_xact_id;
235
236                 $log->debug("Beginning a new trasaction with Open-ILS XACT-ID [$xact_id]", INFO);
237
238                 my $dbh = OpenILS::Application::Storage::CDBI->db_Main;
239                 
240                 try {
241                         $dbh->begin_work;
242
243                 } catch Error with {
244                         my $e = shift;
245                         $log->debug("Failed to begin a new trasaction with Open-ILS XACT-ID [$xact_id]: ".$e, INFO);
246                         throw $e;
247                 };
248
249
250                 my $death_cb = $client->session->register_callback(
251                         death => sub {
252                                 __PACKAGE__->pg_rollback_xaction;
253                         }
254                 );
255
256                 $log->debug("Registered 'death' callback [$death_cb] for new trasaction with Open-ILS XACT-ID [$xact_id]", DEBUG);
257
258                 $client->session->session_data( death_cb => $death_cb );
259
260                 if ($self->api_name =~ /autocommit$/o) {
261                         $pg->current_xact_is_auto(1);
262                         my $dc_cb = $client->session->register_callback(
263                                 disconnect => sub {
264                                         my $ses = shift;
265                                         $ses->unregister_callback(death => $death_cb);
266                                         __PACKAGE__->pg_commit_xaction;
267                                 }
268                         );
269                         $log->debug("Registered 'disconnect' callback [$dc_cb] for new trasaction with Open-ILS XACT-ID [$xact_id]", DEBUG);
270                         if ($client and $client->session) {
271                                 $client->session->session_data( disconnect_cb => $dc_cb );
272                         }
273                 }
274
275                 return 1;
276
277         }
278         __PACKAGE__->register_method(
279                 method          => 'pg_begin_xaction',
280                 api_name        => 'open-ils.storage.transaction.begin',
281                 api_level       => 1,
282                 argc            => 0,
283         );
284         __PACKAGE__->register_method(
285                 method          => 'pg_begin_xaction',
286                 api_name        => 'open-ils.storage.transaction.begin.autocommit',
287                 api_level       => 1,
288                 argc            => 0,
289         );
290
291         sub pg_commit_xaction {
292                 my $self = shift;
293
294                 my $xact_id = $pg->current_xact_id;
295
296                 try {
297                         $log->debug("Committing trasaction with Open-ILS XACT-ID [$xact_id]", INFO);
298                         my $dbh = OpenILS::Application::Storage::CDBI->db_Main;
299                         $dbh->commit;
300
301                 } catch Error with {
302                         my $e = shift;
303                         $log->debug("Failed to commit trasaction with Open-ILS XACT-ID [$xact_id]: ".$e, INFO);
304                         return 0;
305                 };
306                 
307                 $pg->current_xact_session->unregister_callback( death => 
308                         $pg->current_xact_session->session_data( 'death_cb' )
309                 ) if ($pg->current_xact_session);
310
311                 if ($pg->current_xact_is_auto) {
312                         $pg->current_xact_session->unregister_callback( disconnect => 
313                                 $pg->current_xact_session->session_data( 'disconnect_cb' )
314                         );
315                 }
316
317                 $pg->unset_xact_session;
318
319                 return 1;
320                 
321         }
322         __PACKAGE__->register_method(
323                 method          => 'pg_commit_xaction',
324                 api_name        => 'open-ils.storage.transaction.commit',
325                 api_level       => 1,
326                 argc            => 0,
327         );
328
329         sub pg_rollback_xaction {
330                 my $self = shift;
331
332                 my $xact_id = $pg->current_xact_id;
333                 try {
334                         my $dbh = OpenILS::Application::Storage::CDBI->db_Main;
335                         $log->debug("Rolling back a trasaction with Open-ILS XACT-ID [$xact_id]", INFO);
336                         $dbh->rollback;
337
338                 } catch Error with {
339                         my $e = shift;
340                         $log->debug("Failed to roll back trasaction with Open-ILS XACT-ID [$xact_id]: ".$e, INFO);
341                         return 0;
342                 };
343         
344                 $pg->current_xact_session->unregister_callback( death =>
345                         $pg->current_xact_session->session_data( 'death_cb' )
346                 ) if ($pg->current_xact_session);
347
348                 if ($pg->current_xact_is_auto) {
349                         $pg->current_xact_session->unregister_callback( disconnect =>
350                                 $pg->current_xact_session->session_data( 'disconnect_cb' )
351                         );
352                 }
353
354                 $pg->unset_xact_session;
355
356                 return 1;
357         }
358         __PACKAGE__->register_method(
359                 method          => 'pg_rollback_xaction',
360                 api_name        => 'open-ils.storage.transaction.rollback',
361                 api_level       => 1,
362                 argc            => 0,
363         );
364
365         sub copy_create {
366                 my $self = shift;
367                 my $client = shift;
368                 my @fm_nodes = @_;
369
370                 return undef unless ($pg->current_xact_session);
371
372                 my $cdbi = $self->{cdbi};
373
374                 my $pri = $cdbi->columns('Primary');
375
376                 my @cols = grep {$_ ne $pri} $cdbi->columns('All');
377
378                 my $col_list = join ',', @cols;
379
380                 $log->debug('Starting COPY import for '.$cdbi->table." ($col_list)", DEBUG);
381                 $cdbi->sql_copy_start($cdbi->table, $col_list)->execute;
382
383                 my $dbh = $cdbi->db_Main;
384                 for my $node ( @fm_nodes ) {
385                         next unless ($node);
386                         my $line = join("\t", map { defined($node->$_()) ? $node->$_() : '\N' } @cols);
387                         $log->debug("COPY line: [$line]",DEBUG);
388                         $dbh->func($line."\n", 'putline');
389                 }
390
391                 $dbh->func('endcopy');
392
393                 return scalar(@fm_nodes);
394         }
395
396 }
397
398 {
399         #---------------------------------------------------------------------
400         package action::survey;
401         
402         action::survey->table( 'action.survey' );
403         action::survey->sequence( 'action.survey_id_seq' );
404         
405         #---------------------------------------------------------------------
406         package action::survey_question;
407         
408         action::survey_question->table( 'action.survey_question' );
409         action::survey_question->sequence( 'action.survey_question_id_seq' );
410         
411         #---------------------------------------------------------------------
412         package action::survey_answer;
413         
414         action::survey_answer->table( 'action.survey_answer' );
415         action::survey_answer->sequence( 'action.survey_answer_id_seq' );
416         
417         #---------------------------------------------------------------------
418         package action::survey_response;
419         
420         action::survey_response->table( 'action.survey_response' );
421         action::survey_response->sequence( 'action.survey_response_id_seq' );
422         
423         #---------------------------------------------------------------------
424         package config::metabib_field;
425         
426         config::metabib_field->table( 'config.metabib_field' );
427         config::metabib_field->sequence( 'config.metabib_field_id_seq' );
428         
429         #---------------------------------------------------------------------
430         package config::bib_source;
431         
432         config::bib_source->table( 'config.bib_source' );
433         config::bib_source->sequence( 'config.bib_source_id_seq' );
434         
435         #---------------------------------------------------------------------
436         package config::identification_type;
437         
438         config::identification_type->table( 'config.identification_type' );
439         config::identification_type->sequence( 'config.identification_type_id_seq' );
440         
441         #---------------------------------------------------------------------
442         package asset::call_number_note;
443         
444         asset::call_number->table( 'asset.call_number_note' );
445         asset::call_number->sequence( 'asset.call_number_note_id_seq' );
446         
447         #---------------------------------------------------------------------
448         package asset::copy_note;
449         
450         asset::copy->table( 'asset.copy_note' );
451         asset::copy->sequence( 'asset.copy_note_id_seq' );
452
453         #---------------------------------------------------------------------
454         package asset::call_number;
455         
456         asset::call_number->table( 'asset.call_number' );
457         asset::call_number->sequence( 'asset.call_number_id_seq' );
458         
459         #---------------------------------------------------------------------
460         package asset::copy;
461         
462         asset::copy->table( 'asset.copy' );
463         asset::copy->sequence( 'asset.copy_id_seq' );
464
465         #---------------------------------------------------------------------
466         package asset::stat_cat;
467         
468         asset::stat_cat->table( 'asset.stat_cat' );
469         asset::stat_cat->sequence( 'asset.stat_cat_id_seq' );
470         
471         #---------------------------------------------------------------------
472         package asset::stat_cat_entry;
473         
474         asset::stat_cat_entry->table( 'asset.stat_cat_entry' );
475         asset::stat_cat_entry->sequence( 'asset.stat_cat_entry_id_seq' );
476         
477         #---------------------------------------------------------------------
478         package asset::stat_cat_entry_copy_map;
479         
480         asset::stat_cat_entry_copy_map->table( 'asset.stat_cat_entry_copy_map' );
481         asset::stat_cat_entry_copy_map->sequence( 'asset.stat_cat_entry_copy_map_id_seq' );
482         
483         #---------------------------------------------------------------------
484         package biblio::record_entry;
485         
486         biblio::record_entry->table( 'biblio.record_entry' );
487         biblio::record_entry->sequence( 'biblio.record_entry_id_seq' );
488
489         #---------------------------------------------------------------------
490         #package biblio::record_marc;
491         #
492         #biblio::record_marc->table( 'biblio.record_marc' );
493         #biblio::record_marc->sequence( 'biblio.record_marc_id_seq' );
494         #
495         #---------------------------------------------------------------------
496         package biblio::record_note;
497         
498         biblio::record_note->table( 'biblio.record_note' );
499         biblio::record_note->sequence( 'biblio.record_note_id_seq' );
500         
501         #---------------------------------------------------------------------
502         package actor::user;
503         
504         actor::user->table( 'actor.usr' );
505         actor::user->sequence( 'actor.usr_id_seq' );
506         
507         #---------------------------------------------------------------------
508         package actor::org_unit_type;
509         
510         actor::org_unit_type->table( 'actor.org_unit_type' );
511         actor::org_unit_type->sequence( 'actor.org_unit_type_id_seq' );
512
513         #---------------------------------------------------------------------
514         package actor::org_unit;
515         
516         actor::org_unit->table( 'actor.org_unit' );
517         actor::org_unit->sequence( 'actor.org_unit_id_seq' );
518
519         #---------------------------------------------------------------------
520         package actor::stat_cat;
521         
522         actor::stat_cat->table( 'actor.stat_cat' );
523         actor::stat_cat->sequence( 'actor.stat_cat_id_seq' );
524         
525         #---------------------------------------------------------------------
526         package actor::stat_cat_entry;
527         
528         actor::stat_cat_entry->table( 'actor.stat_cat_entry' );
529         actor::stat_cat_entry->sequence( 'actor.stat_cat_entry_id_seq' );
530         
531         #---------------------------------------------------------------------
532         package actor::stat_cat_entry_user_map;
533         
534         actor::stat_cat_entry_user_map->table( 'actor.stat_cat_entry_copy_map' );
535         actor::stat_cat_entry_user_map->sequence( 'actor.stat_cat_entry_usr_map_id_seq' );
536         
537         #---------------------------------------------------------------------
538         package actor::card;
539         
540         actor::card->table( 'actor.card' );
541         actor::card->sequence( 'actor.card_id_seq' );
542         
543
544         #---------------------------------------------------------------------
545
546         #-------------------------------------------------------------------------------
547         package metabib::metarecord;
548
549         metabib::metarecord->table( 'metabib.metarecord' );
550         metabib::metarecord->sequence( 'metabib.metarecord_id_seq' );
551
552         OpenILS::Application::Storage->register_method(
553                 api_name        => 'open-ils.storage.direct.metabib.metarecord.batch.create',
554                 method          => 'copy_create',
555                 api_level       => 1,
556                 'package'       => 'OpenILS::Application::Storage',
557                 cdbi            => 'metabib::metarecord',
558         );
559
560
561         #-------------------------------------------------------------------------------
562
563         #-------------------------------------------------------------------------------
564         package metabib::title_field_entry;
565
566         metabib::title_field_entry->table( 'metabib.title_field_entry' );
567         metabib::title_field_entry->sequence( 'metabib.title_field_entry_id_seq' );
568         metabib::title_field_entry->columns( 'FTS' => 'index_vector' );
569
570 #       metabib::title_field_entry->add_trigger(
571 #               before_create => \&OpenILS::Application::Storage::Driver::Pg::tsearch2_trigger
572 #       );
573 #       metabib::title_field_entry->add_trigger(
574 #               before_update => \&OpenILS::Application::Storage::Driver::Pg::tsearch2_trigger
575 #       );
576
577         OpenILS::Application::Storage->register_method(
578                 api_name        => 'open-ils.storage.direct.metabib.title_field_entry.batch.create',
579                 method          => 'copy_create',
580                 api_level       => 1,
581                 'package'       => 'OpenILS::Application::Storage',
582                 cdbi            => 'metabib::title_field_entry',
583         );
584
585         #-------------------------------------------------------------------------------
586
587         #-------------------------------------------------------------------------------
588         package metabib::author_field_entry;
589
590         metabib::author_field_entry->table( 'metabib.author_field_entry' );
591         metabib::author_field_entry->sequence( 'metabib.author_field_entry_id_seq' );
592         metabib::author_field_entry->columns( 'FTS' => 'index_vector' );
593
594         OpenILS::Application::Storage->register_method(
595                 api_name        => 'open-ils.storage.direct.metabib.author_field_entry.batch.create',
596                 method          => 'copy_create',
597                 api_level       => 1,
598                 'package'       => 'OpenILS::Application::Storage',
599                 cdbi            => 'metabib::author_field_entry',
600         );
601
602         #-------------------------------------------------------------------------------
603
604         #-------------------------------------------------------------------------------
605         package metabib::subject_field_entry;
606
607         metabib::subject_field_entry->table( 'metabib.subject_field_entry' );
608         metabib::subject_field_entry->sequence( 'metabib.subject_field_entry_id_seq' );
609         metabib::subject_field_entry->columns( 'FTS' => 'index_vector' );
610
611         OpenILS::Application::Storage->register_method(
612                 api_name        => 'open-ils.storage.direct.metabib.subject_field_entry.batch.create',
613                 method          => 'copy_create',
614                 api_level       => 1,
615                 'package'       => 'OpenILS::Application::Storage',
616                 cdbi            => 'metabib::subject_field_entry',
617         );
618
619         #-------------------------------------------------------------------------------
620
621         #-------------------------------------------------------------------------------
622         package metabib::keyword_field_entry;
623
624         metabib::keyword_field_entry->table( 'metabib.keyword_field_entry' );
625         metabib::keyword_field_entry->sequence( 'metabib.keyword_field_entry_id_seq' );
626         metabib::keyword_field_entry->columns( 'FTS' => 'index_vector' );
627
628         OpenILS::Application::Storage->register_method(
629                 api_name        => 'open-ils.storage.direct.metabib.keyword_field_entry.batch.create',
630                 method          => 'copy_create',
631                 api_level       => 1,
632                 'package'       => 'OpenILS::Application::Storage',
633                 cdbi            => 'metabib::keyword_field_entry',
634         );
635
636         #-------------------------------------------------------------------------------
637
638         #-------------------------------------------------------------------------------
639         #package metabib::title_field_entry_source_map;
640
641         #metabib::title_field_entry_source_map->table( 'metabib.title_field_entry_source_map' );
642
643         #-------------------------------------------------------------------------------
644
645         #-------------------------------------------------------------------------------
646         #package metabib::author_field_entry_source_map;
647
648         #metabib::author_field_entry_source_map->table( 'metabib.author_field_entry_source_map' );
649
650         #-------------------------------------------------------------------------------
651
652         #-------------------------------------------------------------------------------
653         #package metabib::subject_field_entry_source_map;
654
655         #metabib::subject_field_entry_source_map->table( 'metabib.subject_field_entry_source_map' );
656
657         #-------------------------------------------------------------------------------
658
659         #-------------------------------------------------------------------------------
660         #package metabib::keyword_field_entry_source_map;
661
662         #metabib::keyword_field_entry_source_map->table( 'metabib.keyword_field_entry_source_map' );
663
664         #-------------------------------------------------------------------------------
665
666         #-------------------------------------------------------------------------------
667         package metabib::metarecord_source_map;
668
669         metabib::metarecord_source_map->table( 'metabib.metarecord_source_map' );
670         OpenILS::Application::Storage->register_method(
671                 api_name        => 'open-ils.storage.direct.metabib.metarecord_source_map.batch.create',
672                 method          => 'copy_create',
673                 api_level       => 1,
674                 'package'       => 'OpenILS::Application::Storage',
675                 cdbi            => 'metabib::metarecord_source_map',
676         );
677
678
679         #-------------------------------------------------------------------------------
680         package metabib::record_descriptor;
681
682         metabib::record_descriptor->table( 'metabib.rec_descriptor' );
683         metabib::record_descriptor->sequence( 'metabib.rec_descriptor_id_seq' );
684
685         OpenILS::Application::Storage->register_method(
686                 api_name        => 'open-ils.storage.direct.metabib.record_descriptor.batch.create',
687                 method          => 'copy_create',
688                 api_level       => 1,
689                 'package'       => 'OpenILS::Application::Storage',
690                 cdbi            => 'metabib::record_descriptor',
691         );
692
693         #-------------------------------------------------------------------------------
694
695
696         #-------------------------------------------------------------------------------
697         package metabib::full_rec;
698
699         metabib::full_rec->table( 'metabib.full_rec' );
700         metabib::full_rec->sequence( 'metabib.full_rec_id_seq' );
701         metabib::full_rec->columns( 'FTS' => 'index_vector' );
702
703         OpenILS::Application::Storage->register_method(
704                 api_name        => 'open-ils.storage.direct.metabib.full_rec.batch.create',
705                 method          => 'copy_create',
706                 api_level       => 1,
707                 'package'       => 'OpenILS::Application::Storage',
708                 cdbi            => 'metabib::full_rec',
709         );
710
711
712         #-------------------------------------------------------------------------------
713 }
714
715 1;