]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Storage/Driver/Pg/storage.pm
d4ecbd3ffa5cb1950b74c866644af3ddbecf0c7e
[working/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                 try {
104                         $log->debug("Committing trasaction with Open-ILS XACT-ID [$xact_id]", INFO);
105                         my $dbh = OpenILS::Application::Storage::CDBI->db_Main;
106                         $dbh->commit;
107
108                 } catch Error with {
109                         my $e = shift;
110                         $log->debug("Failed to commit trasaction with Open-ILS XACT-ID [$xact_id]: ".$e, INFO);
111                         return 0;
112                 };
113                 
114                 $pg->current_xact_session->unregister_callback( death => 
115                         $pg->current_xact_session->session_data( 'death_cb' )
116                 ) if ($pg->current_xact_session);
117
118                 if ($pg->current_xact_is_auto) {
119                         $pg->current_xact_session->unregister_callback( disconnect => 
120                                 $pg->current_xact_session->session_data( 'disconnect_cb' )
121                         );
122                 }
123
124                 $pg->unset_xact_session;
125
126                 return 1;
127                 
128         }
129         __PACKAGE__->register_method(
130                 method          => 'pg_commit_xaction',
131                 api_name        => 'open-ils.storage.transaction.commit',
132                 api_level       => 1,
133                 argc            => 0,
134         );
135
136         sub pg_rollback_xaction {
137                 my $self = shift;
138
139                 my $xact_id = $pg->current_xact_id;
140                 try {
141                         my $dbh = OpenILS::Application::Storage::CDBI->db_Main;
142                         $log->debug("Rolling back a trasaction with Open-ILS XACT-ID [$xact_id]", INFO);
143                         $dbh->rollback;
144
145                 } catch Error with {
146                         my $e = shift;
147                         $log->debug("Failed to roll back trasaction with Open-ILS XACT-ID [$xact_id]: ".$e, INFO);
148                         return 0;
149                 };
150         
151                 $pg->current_xact_session->unregister_callback( death =>
152                         $pg->current_xact_session->session_data( 'death_cb' )
153                 ) if ($pg->current_xact_session);
154
155                 if ($pg->current_xact_is_auto) {
156                         $pg->current_xact_session->unregister_callback( disconnect =>
157                                 $pg->current_xact_session->session_data( 'disconnect_cb' )
158                         );
159                 }
160
161                 $pg->unset_xact_session;
162
163                 return 1;
164         }
165         __PACKAGE__->register_method(
166                 method          => 'pg_rollback_xaction',
167                 api_name        => 'open-ils.storage.transaction.rollback',
168                 api_level       => 1,
169                 argc            => 0,
170         );
171
172         sub copy_create {
173                 my $self = shift;
174                 my $client = shift;
175                 my @fm_nodes = @_;
176
177                 return undef unless ($pg->current_xact_session);
178
179                 my $cdbi = $self->{cdbi};
180
181                 my $pri = $cdbi->columns('Primary');
182
183                 my @cols = grep {$_ ne $pri} $cdbi->columns('All');
184
185                 my $col_list = join ',', @cols;
186
187                 $log->debug('Starting COPY import for '.$cdbi->table." ($col_list)", DEBUG);
188                 $cdbi->sql_copy_start($cdbi->table, $col_list)->execute;
189
190                 my $dbh = $cdbi->db_Main;
191                 for my $node ( @fm_nodes ) {
192                         next unless ($node);
193                         my $line = join("\t", map { defined($node->$_()) ? $node->$_() : '\N' } @cols);
194                         $log->debug("COPY line: [$line]",DEBUG);
195                         $dbh->func($line."\n", 'putline');
196                 }
197
198                 $dbh->func('endcopy');
199
200                 return scalar(@fm_nodes);
201         }
202
203 }
204
205 1;