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 #-------------------------------------------------------------------------------
10 if (ref($args[-1]) eq 'HASH') {
11 $args[-1]->{_placeholder} = "to_tsquery('default',?)";
13 push @args, {_placeholder => "to_tsquery('default',?)"};
15 $self->_do_search("@@" => @args);
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';
30 $self = ref($self) || $self;
31 $self = bless {} => $self;
33 $self->decompose($term);
35 my $newterm = join('&', $self->words);
38 $newterm = '('.$newterm.')&('. join('|', $self->nots) . ')';
41 $newterm = OpenILS::Application::Storage->driver->quote($newterm);
43 $self->{fts_query} = ["to_tsquery('default',$newterm)"];
44 $self->{fts_query_nots} = [];
45 $self->{fts_op} = '@@';
52 { # The driver package itself just needs a db_Main method (or db_Slaves if
53 #Class::DBI::Replication is in use) for Class::DBI to call.
55 # Any other fixups can go in here too... Also, the drivers should subclass the
56 # DBI driver that they are wrapping, or provide a 'quote()' method that calls
57 # the DBD::xxx::quote() method on FTI's behalf.
59 # The dirver MUST be a subclass of Class::DBI(::Replication) and
60 # OpenILS::Application::Storage.
61 #-------------------------------------------------------------------------------
62 package OpenILS::Application::Storage::Driver::Pg;
63 use Class::DBI::Replication;
64 use base qw/Class::DBI OpenILS::Application::Storage/;
66 use OpenSRF::EX qw/:try/;
67 use OpenSRF::Utils::Logger qw/:level/;
68 my $log = 'OpenSRF::Utils::Logger';
70 __PACKAGE__->set_sql( retrieve_limited => 'SELECT * FROM __TABLE__ ORDER BY id LIMIT ?' );
79 $log->debug("Running child_init inside ".__PACKAGE__, INTERNAL);
81 $_db_params = [ $_db_params ] unless (ref($_db_params) eq 'ARRAY');
83 my %attrs = ( %{$self->_default_attributes},
84 RootClass => 'DBIx::ContextualFetch',
85 ShowErrorStatement => 1,
91 FetchHashKeyName => 'NAME_lc',
95 my $master = shift @$_db_params;
96 $master_db = DBI->connect("dbi:Pg:host=$$master{host};dbname=$$master{db}",$$master{user},$$master{pw}, \%attrs);
98 $log->debug("Connected to MASTER db at $$master{host}", INTERNAL);
100 for my $db (@$_db_params) {
101 push @slave_dbs, DBI->connect("dbi:Pg:host=$$db{host};dbname=$$db{db}",$$db{user},$$db{pw}, \%attrs);
104 $log->debug("All is well on the western front", INTERNAL);
109 return $master_db if ($self->current_xact_session);
110 return $master_db unless (@slave_dbs);
111 return ($master_db, @slave_dbs)[rand(scalar(@slave_dbs))];
115 return __PACKAGE__->db_Main->quote(@_)
118 sub tsearch2_trigger {
120 return unless ($self->value);
122 $self->db_Slaves->selectrow_array(
123 "SELECT to_tsvector('default',?);",
131 sub current_xact_session {
134 $_xact_session = $ses if (defined $ses);
135 return $_xact_session;
142 package OpenILS::Application::Storage;
144 sub pg_begin_xaction {
148 OpenILS::Application::Storage::Driver::Pg->current_xact_session( $client->session->session_id );
150 $client->session->register_callback( disconnect => sub { __PACKAGE__->pg_commit_xaction($client); } )
151 if ($self->api_name =~ /autocommit$/o);
153 $client->session->register_callback( death => sub { __PACKAGE__->pg_rollback_xaction($client); } );
155 return $self->begin_xaction;
157 __PACKAGE__->register_method(
158 method => 'pg_begin_xaction',
159 api_name => 'open-ils.storage.transaction.begin',
163 __PACKAGE__->register_method(
164 method => 'pg_begin_xaction',
165 api_name => 'open-ils.storage.transaction.begin.autocommit',
170 sub pg_commit_xaction {
172 OpenILS::Application::Storage::Driver::Pg->current_xact_session( 0 );
173 return $self->commit_xaction(@_);
175 __PACKAGE__->register_method(
176 method => 'pg_commit_xaction',
177 api_name => 'open-ils.storage.transaction.commit',
182 sub pg_rollback_xaction {
184 OpenILS::Application::Storage::Driver::Pg->current_xact_session( 0 );
185 return $self->rollback_xaction(@_);
187 __PACKAGE__->register_method(
188 method => 'pg_rollback_xaction',
189 api_name => 'open-ils.storage.transaction.rollback',
197 #---------------------------------------------------------------------
198 package asset::call_number;
200 asset::call_number->table( 'asset.call_number' );
201 asset::call_number->sequence( 'asset.call_number_id_seq' );
203 #---------------------------------------------------------------------
206 asset::copy->table( 'asset.copy' );
207 asset::copy->sequence( 'asset.copy_id_seq' );
209 #---------------------------------------------------------------------
210 package biblio::record_entry;
212 biblio::record_entry->table( 'biblio.record_entry' );
213 biblio::record_entry->sequence( 'biblio.record_entry_id_seq' );
215 #---------------------------------------------------------------------
216 package biblio::record_node;
218 biblio::record_node->table( 'biblio.record_data' );
219 biblio::record_node->sequence( 'biblio.record_data_id_seq' );
221 #---------------------------------------------------------------------
222 package biblio::record_note;
224 biblio::record_note->table( 'biblio.record_note' );
225 biblio::record_note->sequence( 'biblio.record_note_id_seq' );
227 #---------------------------------------------------------------------
230 actor::user->table( 'actor.usr' );
231 actor::user->sequence( 'actor.usr_id_seq' );
233 #---------------------------------------------------------------------
234 package actor::org_unit_type;
236 actor::org_unit_type->table( 'actor.org_unit_type' );
237 actor::org_unit_type->sequence( 'actor.org_unit_type_id_seq' );
239 #---------------------------------------------------------------------
241 #-------------------------------------------------------------------------------
242 package metabib::metarecord;
244 metabib::metarecord->table( 'metabib.metarecord' );
245 metabib::metarecord->sequence( 'metabib.metarecord_id_seq' );
247 #-------------------------------------------------------------------------------
249 #-------------------------------------------------------------------------------
250 package metabib::title_field_entry;
252 metabib::title_field_entry->table( 'metabib.title_field_entry' );
253 metabib::title_field_entry->sequence( 'metabib.title_field_entry_id_seq' );
254 metabib::title_field_entry->columns( Primary => qw/id/ );
255 metabib::title_field_entry->columns( Essential => qw/id/ );
256 metabib::title_field_entry->columns( Others => qw/field value index_vector/ );
258 metabib::title_field_entry->add_trigger(
259 before_create => \&OpenILS::Application::Storage::Driver::Pg::tsearch2_trigger
261 metabib::title_field_entry->add_trigger(
262 before_update => \&OpenILS::Application::Storage::Driver::Pg::tsearch2_trigger
265 #-------------------------------------------------------------------------------
267 #-------------------------------------------------------------------------------
268 package metabib::author_field_entry;
270 metabib::author_field_entry->table( 'metabib.author_field_entry' );
271 metabib::author_field_entry->sequence( 'metabib.author_field_entry_id_seq' );
273 metabib::author_field_entry->add_trigger(
274 before_create => \&OpenILS::Application::Storage::Driver::Pg::tsearch2_trigger
276 metabib::author_field_entry->add_trigger(
277 before_update => \&OpenILS::Application::Storage::Driver::Pg::tsearch2_trigger
280 #-------------------------------------------------------------------------------
282 #-------------------------------------------------------------------------------
283 package metabib::subject_field_entry;
285 metabib::subject_field_entry->table( 'metabib.subject_field_entry' );
286 metabib::subject_field_entry->sequence( 'metabib.subject_field_entry_id_seq' );
288 metabib::subject_field_entry->add_trigger(
289 before_create => \&OpenILS::Application::Storage::Driver::Pg::tsearch2_trigger
291 metabib::subject_field_entry->add_trigger(
292 before_update => \&OpenILS::Application::Storage::Driver::Pg::tsearch2_trigger
295 #-------------------------------------------------------------------------------
297 #-------------------------------------------------------------------------------
298 package metabib::keyword_field_entry;
300 metabib::keyword_field_entry->table( 'metabib.keyword_field_entry' );
301 metabib::keyword_field_entry->sequence( 'metabib.keyword_field_entry_id_seq' );
303 metabib::keyword_field_entry->add_trigger(
304 before_create => \&OpenILS::Application::Storage::Driver::Pg::tsearch2_trigger
306 metabib::keyword_field_entry->add_trigger(
307 before_update => \&OpenILS::Application::Storage::Driver::Pg::tsearch2_trigger
310 #-------------------------------------------------------------------------------
312 #-------------------------------------------------------------------------------
313 package metabib::title_field_entry_source_map;
315 metabib::title_field_entry_source_map->table( 'metabib.title_field_entry_source_map' );
316 metabib::title_field_entry_source_map->table( 'metabib.title_field_entry_source_map_id_seq' );
318 #-------------------------------------------------------------------------------
320 #-------------------------------------------------------------------------------
321 package metabib::author_field_entry_source_map;
323 metabib::author_field_entry_source_map->table( 'metabib.author_field_entry_source_map' );
324 metabib::author_field_entry_source_map->sequence( 'metabib.author_field_entry_source_map_id_seq' );
326 #-------------------------------------------------------------------------------
328 #-------------------------------------------------------------------------------
329 package metabib::subject_field_entry_source_map;
331 metabib::subject_field_entry_source_map->table( 'metabib.subject_field_entry_source_map' );
332 metabib::subject_field_entry_source_map->sequence( 'metabib.subject_field_entry_source_map_id_seq' );
334 #-------------------------------------------------------------------------------