3 package OpenILS::Application::Storage;
4 use OpenSRF::Utils::Logger;
7 my $log = 'OpenSRF::Utils::Logger';
8 my $pg = 'OpenILS::Application::Storage::Driver::Pg';
11 $_->disconnect for $pg->db_Handles;
17 return $pg->current_xact_id;
19 __PACKAGE__->register_method(
20 method => 'current_xact',
21 api_name => 'open-ils.storage.transaction.current',
27 sub pg_begin_xaction {
31 local $OpenILS::Application::Storage::WRITE = 1;
33 if (my $old_xact = $pg->current_xact_session) {
34 if ($pg->current_xact_is_auto) {
35 $log->debug("Commiting old autocommit transaction with Open-ILS XACT-ID [$old_xact]", INFO);
36 $self->method_lookup("open-ils.storage.transaction.commit")->run();
38 $log->debug("Rolling back old NON-autocommit transaction with Open-ILS XACT-ID [$old_xact]", INFO);
39 $self->method_lookup("open-ils.storage.transaction.rollback")->run();
40 throw OpenSRF::DomainObject::oilsException->new(
42 status => "Previous transaction rolled back!",
47 $pg->set_xact_session( $client->session );
48 my $xact_id = $pg->current_xact_id;
50 $log->debug("Beginning a new transaction with Open-ILS XACT-ID [$xact_id]", INFO);
52 my $dbh = OpenILS::Application::Storage::CDBI->db_Main;
59 $log->debug("Failed to begin a new transaction with Open-ILS XACT-ID [$xact_id]: ".$e, INFO);
64 my $death_cb = $client->session->register_callback(
66 __PACKAGE__->pg_rollback_xaction;
70 $log->debug("Registered 'death' callback [$death_cb] for new transaction with Open-ILS XACT-ID [$xact_id]", DEBUG);
72 $client->session->session_data( death_cb => $death_cb );
74 if ($self->api_name =~ /autocommit$/o) {
75 $pg->current_xact_is_auto(1);
76 my $dc_cb = $client->session->register_callback(
79 $ses->unregister_callback(death => $death_cb);
80 __PACKAGE__->pg_commit_xaction;
83 $log->debug("Registered 'disconnect' callback [$dc_cb] for new transaction with Open-ILS XACT-ID [$xact_id]", DEBUG);
84 if ($client and $client->session) {
85 $client->session->session_data( disconnect_cb => $dc_cb );
92 __PACKAGE__->register_method(
93 method => 'pg_begin_xaction',
94 api_name => 'open-ils.storage.transaction.begin',
98 __PACKAGE__->register_method(
99 method => 'pg_begin_xaction',
100 api_name => 'open-ils.storage.transaction.begin.autocommit',
105 sub pg_commit_xaction {
108 local $OpenILS::Application::Storage::WRITE = 1;
110 my $xact_id = $pg->current_xact_id;
114 $log->debug("Committing transaction with Open-ILS XACT-ID [$xact_id]", INFO) if ($xact_id);
115 my $dbh = OpenILS::Application::Storage::CDBI->db_Main;
120 $log->debug("Failed to commit transaction with Open-ILS XACT-ID [$xact_id]: ".$e, INFO);
124 $pg->current_xact_session->unregister_callback( death =>
125 $pg->current_xact_session->session_data( 'death_cb' )
126 ) if ($pg->current_xact_session);
128 if ($pg->current_xact_is_auto) {
129 $pg->current_xact_session->unregister_callback( disconnect =>
130 $pg->current_xact_session->session_data( 'disconnect_cb' )
134 $pg->unset_xact_session;
139 __PACKAGE__->register_method(
140 method => 'pg_commit_xaction',
141 api_name => 'open-ils.storage.transaction.commit',
146 sub pg_rollback_xaction {
149 local $OpenILS::Application::Storage::WRITE = 1;
151 my $xact_id = $pg->current_xact_id;
155 my $dbh = OpenILS::Application::Storage::CDBI->db_Main;
156 $log->debug("Rolling back a transaction with Open-ILS XACT-ID [$xact_id]", INFO);
161 $log->debug("Failed to roll back transaction with Open-ILS XACT-ID [$xact_id]: ".$e, INFO);
165 $pg->current_xact_session->unregister_callback( death =>
166 $pg->current_xact_session->session_data( 'death_cb' )
167 ) if ($pg->current_xact_session);
169 if ($pg->current_xact_is_auto) {
170 $pg->current_xact_session->unregister_callback( disconnect =>
171 $pg->current_xact_session->session_data( 'disconnect_cb' )
175 $pg->unset_xact_session;
179 __PACKAGE__->register_method(
180 method => 'pg_rollback_xaction',
181 api_name => 'open-ils.storage.transaction.rollback',
189 my $sp = shift || 'osrf_savepoint';
190 return OpenILS::Application::Storage::CDBI->db_Main->pg_savepoint($sp);
192 __PACKAGE__->register_method(
193 method => 'set_savepoint',
194 api_name => 'open-ils.storage.savepoint.set',
199 sub release_savepoint {
202 my $sp = shift || 'osrf_savepoint';
203 return OpenILS::Application::Storage::CDBI->db_Main->pg_release($sp);
205 __PACKAGE__->register_method(
206 method => 'release_savepoint',
207 api_name => 'open-ils.storage.savepoint.release',
212 sub rollback_to_savepoint {
215 my $sp = shift || 'osrf_savepoint';
216 return OpenILS::Application::Storage::CDBI->db_Main->pg_rollback_to($sp);
218 __PACKAGE__->register_method(
219 method => 'rollback_to_savepoint',
220 api_name => 'open-ils.storage.savepoint.rollback',
226 sub copy_create_start {
230 local $OpenILS::Application::Storage::WRITE = 1;
232 #return undef unless ($pg->current_xact_session);
234 my @cols = $self->{cdbi}->columns('Essential');
236 my ($p) = $self->{cdbi}->columns('Primary');
237 @cols = grep { $_ ne $p } @cols;
240 my $col_list = join ',', @cols;
242 $log->debug('Starting COPY import for '.$self->{cdbi}->table." ($col_list)", DEBUG);
243 $self->{cdbi}->sql_copy_start($self->{cdbi}->table, $col_list)->execute;
248 sub copy_create_push {
253 local $OpenILS::Application::Storage::WRITE = 1;
255 #return undef unless ($pg->current_xact_session);
257 my @cols = $self->{cdbi}->columns('Essential');
259 my ($p) = $self->{cdbi}->columns('Primary');
260 @cols = grep { $_ ne $p } @cols;
263 my $dbh = $self->{cdbi}->db_Main;
264 for my $node ( @fm_nodes ) {
266 my $line = join("\t", map { defined($node->$_()) ? $node->$_() : '\N' } @cols);
267 $log->debug("COPY line: [$line]",DEBUG);
268 $dbh->pg_putline($line."\n");
271 return scalar(@fm_nodes);
274 sub copy_create_finish {
279 local $OpenILS::Application::Storage::WRITE = 1;
281 #return undef unless ($pg->current_xact_session);
283 my $dbh = $self->{cdbi}->db_Main;
285 $dbh->pg_endcopy || $log->debug("Could not end COPY with pg_endcopy", WARN);
287 $log->debug('COPY import for '.$self->{cdbi}->table." ($col_list) complete", DEBUG);
297 local $NOPRIMARY = 1;
299 copy_create_start( $self => $client );
300 copy_create_push( $self => $client => @fm_nodes );
301 copy_create_finish( $self => $client );
303 return scalar(@fm_nodes);
309 $NOPRIMARY = $val if (defined $val);