]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg.pm
LP2061136 - Stamping 1405 DB upgrade script
[Evergreen.git] / Open-ILS / src / perlmods / lib / OpenILS / Application / Storage / Driver / Pg.pm
1
2 { # The driver package itself just needs a db_Main method.
3   #
4   # Any other fixups can go in here too... Also, the drivers should subclass the
5   # DBI driver that they are wrapping, or provide a 'quote()' method that calls
6   # the DBD::xxx::quote() method on FTI's behalf.
7   #
8   # The dirver MUST be a subclass of Class::DBI and
9   # OpenILS::Application::Storage.
10   #-------------------------------------------------------------------------------
11     package OpenILS::Application::Storage::Driver::Pg;
12     # The following modules add, or use, subroutines in modules that
13     # are not available when this module is compiled.  We therefore
14     # "require" these modules rather than "use" them.  Everything is
15     # available at run time.
16     require OpenILS::Application::Storage::Driver::Pg::cdbi;
17     require OpenILS::Application::Storage::Driver::Pg::fts;
18     require OpenILS::Application::Storage::Driver::Pg::storage;
19     require OpenILS::Application::Storage::Driver::Pg::dbi;
20
21     use UNIVERSAL::require; 
22     BEGIN {                 
23         'Class::DBI::Frozen::301'->use or 'Class::DBI'->use or die $@;
24     }     
25     use base qw/Class::DBI OpenILS::Application::Storage/;
26     use DBI;
27     use OpenSRF::EX qw/:try/;
28     use OpenSRF::DomainObject::oilsResponse;
29     use OpenSRF::Utils::Logger qw/:level/;
30     my $log = 'OpenSRF::Utils::Logger';
31
32     __PACKAGE__->set_sql( retrieve_limited => 'SELECT * FROM __TABLE__ ORDER BY id LIMIT ?' );
33     __PACKAGE__->set_sql( copy_start => 'COPY %s (%s) FROM STDIN;' );
34     __PACKAGE__->set_sql( copy_end => '\.' );
35
36     my $primary_db;
37     my @standby_dbs;
38     my $_db_params;
39
40     sub db_Handles {
41         return ($primary_db, @standby_dbs);
42     }
43
44     sub child_init {
45         my $self = shift;
46         $_db_params = shift;
47
48         $log->debug("Running child_init inside ".__PACKAGE__, INTERNAL);
49
50         $_db_params = [ $_db_params ] unless (ref($_db_params) eq 'ARRAY');
51
52         my %attrs = (   %{$self->_default_attributes},
53                 RootClass => 'DBIx::ContextualFetch',
54                 ShowErrorStatement => 1,
55                 RaiseError => 1,
56                 AutoCommit => 1,
57                 PrintError => 1,
58                 Taint => 1,
59                 #TraceLevel => "1|SQL",
60                 pg_enable_utf8 => 1,
61                 pg_server_prepare => 0,
62                 FetchHashKeyName => 'NAME_lc',
63                 ChopBlanks => 1,
64         );
65
66         my $primary = shift @$_db_params;
67         $$primary{port} ||= '5432';
68         $$primary{host} ||= 'localhost';
69         $$primary{db} ||= 'openils';
70
71         $log->debug("Attempting to connect to $$primary{db} at $$primary{host}", INFO);
72
73         try {
74             $primary_db = DBI->connect(
75                 "dbi:Pg:".
76                     "host=$$primary{host};".
77                     "port=$$primary{port};".
78                     "dbname=$$primary{db}".
79                     ($$primary{application_name} ? ";application_name='$$primary{application_name}'": ""),
80                 $$primary{user},
81                 $$primary{pw},
82                 \%attrs)
83             || do { sleep(1);
84                 DBI->connect(
85                     "dbi:Pg:".
86                         "host=$$primary{host};".
87                         "port=$$primary{port};".
88                         "dbname=$$primary{db}".
89                         ($$primary{application_name} ? ";application_name='$$primary{application_name}'": ""),
90                     $$primary{user},
91                     $$primary{pw},
92                     \%attrs) }
93             || throw OpenSRF::EX::ERROR
94                 ("Couldn't connect to $$primary{db}".
95                  " on $$primary{host}::$$primary{port}".
96                  " as $$primary{user}!!");
97         } catch Error with {
98             my $e = shift;
99             $log->debug("Error connecting to database:\n\t$e\n\t$DBI::errstr", ERROR);
100             throw $e;
101         };
102
103         $log->debug("Connected to primary db $$primary{db} at $$primary{host}", INFO);
104         
105         $primary_db->do("SET NAMES '$$primary{client_encoding}';") if ($$primary{client_encoding});
106
107         for my $db (@$_db_params) {
108             try {
109                 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)
110                     || 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) }
111                     || throw OpenSRF::EX::ERROR
112                         ("Couldn't connect to $$db{db}".
113                         " on $$db{host}::$$db{port}".
114                         " as $$db{user}!!");
115             } catch Error with {
116                 my $e = shift;
117                 $log->debug("Error connecting to database:\n\t$e\n\t$DBI::errstr", ERROR);
118                 throw $e;
119             };
120
121             $standby_dbs[-1]->do("SET NAMES '$$db{client_encoding}';") if ($$primary{client_encoding});
122
123             $log->debug("Connected to primary db '$$primary{db} at $$primary{host}", INFO);
124         }
125
126         $log->debug("All is well on the western front", INTERNAL);
127     }
128
129     sub db_Main {
130         my $self = shift;
131         return $primary_db if ($self->current_xact_session || $OpenILS::Application::Storage::WRITE);
132         return $primary_db unless (@standby_dbs);
133         return ($primary_db, @standby_dbs)[rand(scalar(@standby_dbs))];
134     }
135
136     sub quote {
137         my $self = shift;
138         return $self->db_Main->quote(@_)
139     }
140
141     my $_xact_session;
142     my $_audit_session;
143
144     sub current_xact_session {
145         my $self = shift;
146         if (defined($_xact_session)) {
147             return $_xact_session;
148         }
149         return undef;
150     }
151
152     sub current_audit_session {
153         my $self = shift;
154         if (defined($_audit_session)) {
155             return $_audit_session;
156         }
157         return undef;
158     }
159
160     sub current_xact_is_auto {
161         my $self = shift;
162         my $auto = shift;
163         if (defined($_xact_session) and ref($_xact_session)) {
164             if (defined $auto) {
165                 $_xact_session->session_data(autocommit => $auto);
166             }
167             return $_xact_session->session_data('autocommit'); 
168         }
169     }
170
171     sub current_xact_id {
172         my $self = shift;
173         if (defined($_xact_session) and ref($_xact_session)) {
174             return $_xact_session->session_id;
175         }
176         return undef;
177     }
178
179     sub set_xact_session {
180         my $self = shift;
181         my $ses = shift;
182         if (!defined($ses)) {
183             return undef;
184         }
185         $_xact_session = $ses;
186         return $_xact_session;
187     }
188
189     sub set_audit_session {
190         my $self = shift;
191         my $ses = shift;
192         if (!defined($ses)) {
193             return undef;
194         }
195         $_audit_session = $ses;
196         return $_audit_session;
197     }
198
199     sub unset_xact_session {
200         my $self = shift;
201         my $ses = $_xact_session;
202         undef $_xact_session;
203         return $ses;
204     }
205
206     sub unset_audit_session {
207         my $self = shift;
208         my $ses = $_audit_session;
209         undef $_audit_session;
210         return $ses;
211     }
212
213 }
214
215 1;