]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Storage/Driver/Pg/storage.pm
a06696953a04344f343fd9931a257833fe591608
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Storage / Driver / Pg / storage.pm
1 {
2         package OpenILS::Application::Storage;
3         use OpenSRF::Utils::Logger;
4         my $log = 'OpenSRF::Utils::Logger';
5
6         my $pg = 'OpenILS::Application::Storage::Driver::Pg';
7
8
9         sub current_xact {
10                 my $self = shift;
11                 my $client = shift;
12                 return $pg->current_xact_id;
13         }
14         __PACKAGE__->register_method(
15                 method          => 'current_xact',
16                 api_name        => 'open-ils.storage.transaction.current',
17                 api_level       => 1,
18                 argc            => 0,
19         );
20
21
22         sub pg_begin_xaction {
23                 my $self = shift;
24                 my $client = shift;
25
26                 if (my $old_xact = $pg->current_xact_session) {
27                         if ($pg->current_xact_is_auto) {
28                                 $log->debug("Commiting old autocommit transaction with Open-ILS XACT-ID [$old_xact]", INFO);
29                                 $self->pg_commit_xaction($client);
30                         } else {
31                                 $log->debug("Rolling back old NON-autocommit transaction with Open-ILS XACT-ID [$old_xact]", INFO);
32                                 $self->pg_rollback_xaction($client);
33                                 throw OpenSRF::DomainObject::oilsException->new(
34                                                 statusCode => 500,
35                                                 status => "Previous transaction rolled back!",
36                                 );
37                         }
38                 }
39                 
40                 $pg->set_xact_session( $client->session );
41                 my $xact_id = $pg->current_xact_id;
42
43                 $log->debug("Beginning a new trasaction with Open-ILS XACT-ID [$xact_id]", INFO);
44
45                 my $dbh = OpenILS::Application::Storage::CDBI->db_Main;
46                 
47                 try {
48                         $dbh->begin_work;
49
50                 } catch Error with {
51                         my $e = shift;
52                         $log->debug("Failed to begin a new trasaction with Open-ILS XACT-ID [$xact_id]: ".$e, INFO);
53                         throw $e;
54                 };
55
56
57                 my $death_cb = $client->session->register_callback(
58                         death => sub {
59                                 __PACKAGE__->pg_rollback_xaction;
60                         }
61                 );
62
63                 $log->debug("Registered 'death' callback [$death_cb] for new trasaction with Open-ILS XACT-ID [$xact_id]", DEBUG);
64
65                 $client->session->session_data( death_cb => $death_cb );
66
67                 if ($self->api_name =~ /autocommit$/o) {
68                         $pg->current_xact_is_auto(1);
69                         my $dc_cb = $client->session->register_callback(
70                                 disconnect => sub {
71                                         my $ses = shift;
72                                         $ses->unregister_callback(death => $death_cb);
73                                         __PACKAGE__->pg_commit_xaction;
74                                 }
75                         );
76                         $log->debug("Registered 'disconnect' callback [$dc_cb] for new trasaction with Open-ILS XACT-ID [$xact_id]", DEBUG);
77                         if ($client and $client->session) {
78                                 $client->session->session_data( disconnect_cb => $dc_cb );
79                         }
80                 }
81
82                 return 1;
83
84         }
85         __PACKAGE__->register_method(
86                 method          => 'pg_begin_xaction',
87                 api_name        => 'open-ils.storage.transaction.begin',
88                 api_level       => 1,
89                 argc            => 0,
90         );
91         __PACKAGE__->register_method(
92                 method          => 'pg_begin_xaction',
93                 api_name        => 'open-ils.storage.transaction.begin.autocommit',
94                 api_level       => 1,
95                 argc            => 0,
96         );
97
98         sub pg_commit_xaction {
99                 my $self = shift;
100
101                 my $xact_id = $pg->current_xact_id;
102
103                 my $success = 1;
104                 try {
105                         $log->debug("Committing trasaction with Open-ILS XACT-ID [$xact_id]", INFO);
106                         my $dbh = OpenILS::Application::Storage::CDBI->db_Main;
107                         $dbh->commit;
108
109                 } catch Error with {
110                         my $e = shift;
111                         $log->debug("Failed to commit trasaction with Open-ILS XACT-ID [$xact_id]: ".$e, INFO);
112                         $success = 0;
113                 };
114                 
115                 $pg->current_xact_session->unregister_callback( death => 
116                         $pg->current_xact_session->session_data( 'death_cb' )
117                 ) if ($pg->current_xact_session);
118
119                 if ($pg->current_xact_is_auto) {
120                         $pg->current_xact_session->unregister_callback( disconnect => 
121                                 $pg->current_xact_session->session_data( 'disconnect_cb' )
122                         );
123                 }
124
125                 $pg->unset_xact_session;
126
127                 return $success;
128                 
129         }
130         __PACKAGE__->register_method(
131                 method          => 'pg_commit_xaction',
132                 api_name        => 'open-ils.storage.transaction.commit',
133                 api_level       => 1,
134                 argc            => 0,
135         );
136
137         sub pg_rollback_xaction {
138                 my $self = shift;
139
140                 my $xact_id = $pg->current_xact_id;
141
142                 my $success = 1;
143                 try {
144                         my $dbh = OpenILS::Application::Storage::CDBI->db_Main;
145                         $log->debug("Rolling back a trasaction with Open-ILS XACT-ID [$xact_id]", INFO);
146                         $dbh->rollback;
147
148                 } catch Error with {
149                         my $e = shift;
150                         $log->debug("Failed to roll back trasaction with Open-ILS XACT-ID [$xact_id]: ".$e, INFO);
151                         $success = 0;
152                 };
153         
154                 $pg->current_xact_session->unregister_callback( death =>
155                         $pg->current_xact_session->session_data( 'death_cb' )
156                 ) if ($pg->current_xact_session);
157
158                 if ($pg->current_xact_is_auto) {
159                         $pg->current_xact_session->unregister_callback( disconnect =>
160                                 $pg->current_xact_session->session_data( 'disconnect_cb' )
161                         );
162                 }
163
164                 $pg->unset_xact_session;
165
166                 return $success;
167         }
168         __PACKAGE__->register_method(
169                 method          => 'pg_rollback_xaction',
170                 api_name        => 'open-ils.storage.transaction.rollback',
171                 api_level       => 1,
172                 argc            => 0,
173         );
174
175         sub set_savepoint {
176                 my $self = shift;
177                 my $client = shift;
178                 my $sp = shift || 'osrf_savepoint';
179                 return OpenILS::Application::Storage::CDBI->db_Main->pg_savepoint($sp);
180         }
181         __PACKAGE__->register_method(
182                 method          => 'set_savepoint',
183                 api_name        => 'open-ils.storage.savepoint.set',
184                 api_level       => 1,
185                 argc            => 1,
186         );
187
188         sub release_savepoint {
189                 my $self = shift;
190                 my $client = shift;
191                 my $sp = shift || 'osrf_savepoint';
192                 return OpenILS::Application::Storage::CDBI->db_Main->pg_release($sp);
193         }
194         __PACKAGE__->register_method(
195                 method          => 'release_savepoint',
196                 api_name        => 'open-ils.storage.savepoint.release',
197                 api_level       => 1,
198                 argc            => 1,
199         );
200
201         sub rollback_to_savepoint {
202                 my $self = shift;
203                 my $client = shift;
204                 my $sp = shift || 'osrf_savepoint';
205                 return OpenILS::Application::Storage::CDBI->db_Main->pg_rollback_to($sp);
206         }
207         __PACKAGE__->register_method(
208                 method          => 'rollback_to_savepoint',
209                 api_name        => 'open-ils.storage.savepoint.rollback',
210                 api_level       => 1,
211                 argc            => 1,
212         );
213
214
215         sub copy_create {
216                 my $self = shift;
217                 my $client = shift;
218                 my @fm_nodes = @_;
219
220                 return undef unless ($pg->current_xact_session);
221
222                 my $cdbi = $self->{cdbi};
223
224                 my $pri = $cdbi->columns('Primary');
225
226                 my @cols = grep {$_ ne $pri} $cdbi->columns('All');
227
228                 my $col_list = join ',', @cols;
229
230                 $log->debug('Starting COPY import for '.$cdbi->table." ($col_list)", DEBUG);
231                 $cdbi->sql_copy_start($cdbi->table, $col_list)->execute;
232
233                 my $dbh = $cdbi->db_Main;
234                 for my $node ( @fm_nodes ) {
235                         next unless ($node);
236                         my $line = join("\t", map { defined($node->$_()) ? $node->$_() : '\N' } @cols);
237                         $log->debug("COPY line: [$line]",DEBUG);
238                         $dbh->pg_putline($line."\n");
239                 }
240
241                 $dbh->pg_endcopy || $log->debug("Could not end COPY with pg_endcopy", WARN);
242
243                 $log->debug('COPY import for '.$cdbi->table." ($col_list) complete", DEBUG);
244
245                 return scalar(@fm_nodes);
246         }
247
248 }
249
250 1;