]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg.pm
Make Evergreen Perl modules installable via Module::Build to match OpenSRF
[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
149         sub current_xact_session {
150                 my $self = shift;
151                 if (defined($_xact_session)) {
152                         return $_xact_session;
153                 }
154                 return undef;
155         }
156
157         sub current_xact_is_auto {
158                 my $self = shift;
159                 my $auto = shift;
160                 if (defined($_xact_session) and ref($_xact_session)) {
161                         if (defined $auto) {
162                                 $_xact_session->session_data(autocommit => $auto);
163                         }
164                         return $_xact_session->session_data('autocommit'); 
165                 }
166         }
167
168         sub current_xact_id {
169                 my $self = shift;
170                 if (defined($_xact_session) and ref($_xact_session)) {
171                         return $_xact_session->session_id;
172                 }
173                 return undef;
174         }
175
176         sub set_xact_session {
177                 my $self = shift;
178                 my $ses = shift;
179                 if (!defined($ses)) {
180                         return undef;
181                 }
182                 $_xact_session = $ses;
183                 return $_xact_session;
184         }
185
186         sub unset_xact_session {
187                 my $self = shift;
188                 my $ses = $_xact_session;
189                 undef $_xact_session;
190                 return $ses;
191         }
192
193 }
194
195 1;