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