2 { # The driver package itself just needs a db_Main method (or db_standbys if
3 #Class::DBI::Replication is in use) for Class::DBI to call.
5 # Any other fixups can go in here too... Also, the drivers should subclass the
6 # DBI driver that they are wrapping, or provide a 'quote()' method that calls
7 # the DBD::xxx::quote() method on FTI's behalf.
9 # The dirver MUST be a subclass of Class::DBI(::Replication) and
10 # OpenILS::Application::Storage.
11 #-------------------------------------------------------------------------------
12 package OpenILS::Application::Storage::Driver::Pg;
13 # The following modules add, or use, subroutines in modules that
14 # are not available when this module is compiled. We therefore
15 # "require" these modules rather than "use" them. Everything is
16 # available at run time.
17 require OpenILS::Application::Storage::Driver::Pg::cdbi;
18 require OpenILS::Application::Storage::Driver::Pg::fts;
19 require OpenILS::Application::Storage::Driver::Pg::storage;
20 require OpenILS::Application::Storage::Driver::Pg::dbi;
22 use UNIVERSAL::require;
24 'Class::DBI::Frozen::301'->use or 'Class::DBI'->use or die $@;
26 use base qw/Class::DBI OpenILS::Application::Storage/;
28 use OpenSRF::EX qw/:try/;
29 use OpenSRF::DomainObject::oilsResponse;
30 use OpenSRF::Utils::Logger qw/:level/;
31 my $log = 'OpenSRF::Utils::Logger';
33 __PACKAGE__->set_sql( retrieve_limited => 'SELECT * FROM __TABLE__ ORDER BY id LIMIT ?' );
34 __PACKAGE__->set_sql( copy_start => 'COPY %s (%s) FROM STDIN;' );
35 __PACKAGE__->set_sql( copy_end => '\.' );
42 return ($primary_db, @standby_dbs);
49 $log->debug("Running child_init inside ".__PACKAGE__, INTERNAL);
51 $_db_params = [ $_db_params ] unless (ref($_db_params) eq 'ARRAY');
53 my %attrs = ( %{$self->_default_attributes},
54 RootClass => 'DBIx::ContextualFetch',
55 ShowErrorStatement => 1,
60 #TraceLevel => "1|SQL",
62 pg_server_prepare => 0,
63 FetchHashKeyName => 'NAME_lc',
67 my $primary = shift @$_db_params;
68 $$primary{port} ||= '5432';
69 $$primary{host} ||= 'localhost';
70 $$primary{db} ||= 'openils';
72 $log->debug("Attempting to connect to $$primary{db} at $$primary{host}", INFO);
75 $primary_db = DBI->connect(
77 "host=$$primary{host};".
78 "port=$$primary{port};".
79 "dbname=$$primary{db}".
80 ($$primary{application_name} ? ";application_name='$$primary{application_name}'": ""),
87 "host=$$primary{host};".
88 "port=$$primary{port};".
89 "dbname=$$primary{db}".
90 ($$primary{application_name} ? ";application_name='$$primary{application_name}'": ""),
94 || throw OpenSRF::EX::ERROR
95 ("Couldn't connect to $$primary{db}".
96 " on $$primary{host}::$$primary{port}".
97 " as $$primary{user}!!");
100 $log->debug("Error connecting to database:\n\t$e\n\t$DBI::errstr", ERROR);
104 $log->debug("Connected to primary db $$primary{db} at $$primary{host}", INFO);
106 $primary_db->do("SET NAMES '$$primary{client_encoding}';") if ($$primary{client_encoding});
108 for my $db (@$_db_params) {
110 push @standby_dbs, DBI->connect("dbi:Pg:host=$$db{host};port=$$db{port};dbname=$$db{db}". ($$db{application_name} ? ";application_name='$$db{application_name}'" : ""),$$db{user},$$db{pw}, \%attrs)
111 || do { sleep(1); DBI->connect("dbi:Pg:host=$$db{host};port=$$db{port};dbname=$$db{db}". ($$db{application_name} ? ";application_name='$$db{application_name}'" : ""),$$db{user},$$db{pw}, \%attrs) }
112 || throw OpenSRF::EX::ERROR
113 ("Couldn't connect to $$db{db}".
114 " on $$db{host}::$$db{port}".
118 $log->debug("Error connecting to database:\n\t$e\n\t$DBI::errstr", ERROR);
122 $standby_dbs[-1]->do("SET NAMES '$$db{client_encoding}';") if ($$primary{client_encoding});
124 $log->debug("Connected to primary db '$$primary{db} at $$primary{host}", INFO);
127 $log->debug("All is well on the western front", INTERNAL);
132 return $primary_db if ($self->current_xact_session || $OpenILS::Application::Storage::WRITE);
133 return $primary_db unless (@standby_dbs);
134 return ($primary_db, @standby_dbs)[rand(scalar(@standby_dbs))];
139 return $self->db_Main->quote(@_)
142 # sub tsearch2_trigger {
144 # return unless ($self->value);
145 # $self->index_vector(
146 # $self->db_standbys->selectrow_array(
147 # "SELECT to_tsvector('default',?);",
157 sub current_xact_session {
159 if (defined($_xact_session)) {
160 return $_xact_session;
165 sub current_audit_session {
167 if (defined($_audit_session)) {
168 return $_audit_session;
173 sub current_xact_is_auto {
176 if (defined($_xact_session) and ref($_xact_session)) {
178 $_xact_session->session_data(autocommit => $auto);
180 return $_xact_session->session_data('autocommit');
184 sub current_xact_id {
186 if (defined($_xact_session) and ref($_xact_session)) {
187 return $_xact_session->session_id;
192 sub set_xact_session {
195 if (!defined($ses)) {
198 $_xact_session = $ses;
199 return $_xact_session;
202 sub set_audit_session {
205 if (!defined($ses)) {
208 $_audit_session = $ses;
209 return $_audit_session;
212 sub unset_xact_session {
214 my $ses = $_xact_session;
215 undef $_xact_session;
219 sub unset_audit_session {
221 my $ses = $_audit_session;
222 undef $_audit_session;