File Coverage

blib/lib/DBIx/Migration/Directories/Database.pm
Criterion Covered Total %
statement 131 165 79.3
branch 32 46 69.5
condition n/a
subroutine 28 28 100.0
pod 11 15 73.3
total 202 254 79.5


line stmt bran cond sub pod time code
1             #!perl
2              
3             package DBIx::Migration::Directories::Database;
4              
5 5     5   32 use strict;
  5         8  
  5         233  
6 5     5   49 use warnings;
  5         28  
  5         190  
7 5     5   28 use Carp qw(croak);
  5         8  
  5         251  
8 5     5   9722 use DBI;
  5         74368  
  5         8023  
9              
10             return 1;
11              
12             sub new {
13 20     20 1 79 my($class, %args) = @_;
14 20         100 ($class, %args) = ($class->set_preinit_defaults(%args));
15 19 50       120 if(my $self = $class->driver_load($args{driver}, %args)) {
16 19         89 $self->set_postinit_defaults();
17 19         84 return $self;
18             } else {
19 0         0 return;
20             }
21             }
22              
23             sub set_postinit_defaults {
24 19     19 0 37 return shift;
25             }
26              
27             sub set_preinit_defaults {
28 20     20 0 57 my($class, %args) = @_;
29 20 50       66 $class = ref($class) if ref($class);
30            
31 20 100       1745 croak qq{$class\->new\() requires "dbh" parameter}
32             unless defined $args{dbh};
33              
34 19 50       250 $args{driver} = $args{dbh}->{Driver}->{Name}
35             unless($args{driver});
36            
37 19         122 return($class, %args);
38             }
39              
40             sub driver {
41 6     6 1 65 my $self = shift;
42 6         221 return $self->{driver};
43             }
44              
45             sub driver_new {
46 19     19 0 83 my($class, %args) = @_;
47 19         78 my $self = bless \%args, $class;
48 19         185 return $self;
49             }
50              
51             sub driver_load {
52 19     19 0 60 my($class, $driver, %args) = @_;
53 19         59 my $pkg = __PACKAGE__ . "::$driver";
54 5     5   7782 eval "use $pkg; 1;";
  2     3   8  
  2     2   130  
  3     2   1021  
  2     2   4  
  2     2   51  
  2     1   552  
  1     1   3  
  1     1   20  
  2         839  
  1         2  
  1         18  
  2         539  
  1         4  
  1         25  
  2         1639  
  1         3  
  1         25  
  1         497  
  0         0  
  0         0  
  1         641  
  0         0  
  0         0  
  1         374  
  0         0  
  0         0  
  19         2789  
55 19 100       247 if($@) {
56 11         35 my $err = $@;
57 11 50       65 if($err =~ m{Can\'t locate}) {
58 11         66 return $class->driver_new(%args);
59             } else {
60 0         0 die $err;
61             }
62             } else {
63 8         72 return $pkg->driver_new(%args);
64             }
65             }
66              
67             sub sql_insert_migration_schema_version {
68 6     6 1 16 my($self, $myschema, $to) = @_;
69 6         70 return sprintf(
70             q{INSERT INTO migration_schema_version (name, version) VALUES (%s, %f)},
71             $self->{dbh}->quote($myschema), $to
72             );
73             }
74              
75             sub sql_update_migration_schema_version {
76 27     27 1 57 my($self, $myschema, $to) = @_;
77 27         773 return sprintf(
78             q{UPDATE migration_schema_version SET version = %f WHERE name = %s},
79             $to, $self->{dbh}->quote($myschema)
80             )
81             }
82              
83             sub sql_insert_migration_schema_log {
84 3     3 1 7 my($self, $myschema, $from, $to) = @_;
85 3         10 return sprintf(
86             q{
87             INSERT INTO migration_schema_log
88             (schema_name, event_time, old_version, new_version)
89             VALUES (%s, now(), %f, %f)
90             },
91             $self->{dbh}->quote($myschema), $from, $to
92             );
93             }
94              
95             sub sql_table_exists {
96 8     8 1 18 my($self, $table) = @_;
97 8         130 return sprintf(
98             q{SELECT 1 FROM information_schema.tables WHERE table_name = %s},
99             $self->{dbh}->quote($table)
100             );
101             }
102              
103             sub db_schema_version_log {
104 1     1 1 3 my($self, $schema) = @_;
105              
106 1         85 my $dbh = $self->{dbh};
107 1         7 $dbh->begin_work;
108 1 50       53 if($self->table_exists('migration_schema_log')) {
109 1 50       20 if(my $sth = $dbh->prepare_cached(q{
110             SELECT
111             schema_name, event_time, old_version, new_version
112             FROM
113             migration_schema_log
114             WHERE
115             schema_name = ?
116             ORDER BY
117             event_time, new_version
118             })) {
119 1 50       182 if($sth->execute($schema)) {
120 1 50       87 if(my $result = $sth->fetchall_arrayref({})) {
121 1         90 $sth->finish();
122 1         4 $dbh->commit();
123 1         300 return $result;
124             } else {
125 0         0 $sth->finish();
126 0         0 $dbh->rollback();
127 0         0 return;
128             }
129             }
130             } else {
131 0         0 my $err = $dbh->errstr;
132 0         0 $dbh->rollback();
133 0         0 croak "query for versions of $schema failed: ", $err;
134             }
135             } else {
136 0         0 $dbh->commit();
137 0         0 return;
138             }
139             }
140              
141             sub db_schemas {
142 6     6 1 16 my $self = shift;
143 6         17 my $dbh = $self->{dbh};
144 6         28 $dbh->begin_work;
145 6 100       248 if($self->table_exists('migration_schema_version')) {
146 5 50       49 if(my $sth = $dbh->prepare_cached(
147             "SELECT * FROM migration_schema_version"
148             )) {
149 5 50       209 if($sth->execute()) {
150 5 50       260 if(my $result = $sth->fetchall_hashref('name')) {
151 5         533 $sth->finish;
152 5         18 $dbh->commit;
153 5         1203 return $result;
154             } else {
155 0         0 $sth->finish;
156 0         0 $dbh->rollback;
157 0         0 return;
158             }
159            
160             } else {
161 0         0 my $err = $dbh->errstr;
162 0         0 $dbh->rollback;
163 0         0 croak "Failed to run query to obtain schemas: $err";
164             }
165             } else {
166 0         0 my $err = $dbh->errstr;
167 0         0 $dbh->rollback;
168 0         0 croak "Failed to prepare query to obtain schemas: $err";
169             }
170             } else {
171 1         9 $dbh->commit;
172 1         354 return;
173             }
174             }
175              
176             sub db_delete_schema_record {
177 3     3 1 15 my($self, $schema) = @_;
178 3         11 my $dbh = $self->{dbh};
179            
180 3         19 $dbh->begin_work;
181              
182 3         221 my $sth = $dbh->prepare_cached(
183             q{DELETE FROM migration_schema_log WHERE schema_name = ?}
184             );
185            
186 3 100       334 if($sth->execute($schema)) {
187 2         233 $sth->finish;
188 2         110 $sth = $dbh->prepare_cached(
189             q{DELETE FROM migration_schema_version WHERE name = ?}
190             );
191 2 50       84 if($sth->execute($schema)) {
192 2         116 $sth->finish;
193 2         7 $dbh->commit;
194 2         131 return 1;
195             } else {
196 0         0 $dbh->rollback;
197 0         0 return 0;
198             }
199             } else {
200 1         1327 $dbh->rollback;
201 1         471 return 0;
202             }
203             }
204              
205             sub db_get_current_version {
206 43     43 1 115 my($self, $schema) = @_;
207 43         186 my $rv;
208            
209 43         174 my $dbh = $self->{dbh};
210              
211 43 100       173 if($self->table_exists('migration_schema_version')) {
212 28         361 $dbh->begin_work;
213 28         1374 my $sth = $dbh->prepare(
214             "SELECT version FROM migration_schema_version WHERE name = ?"
215             );
216              
217 28 50       1363 if($sth->execute($schema)) {
218 28 100       8304 if(my $row = $sth->fetchrow_arrayref()) {
219 24         65 $rv = $row->[0];
220             } else {
221 4         9 $rv = undef;
222             }
223 28         366 $sth->finish();
224 28 100       108 if($dbh->transaction_error) {
225 1         13 $dbh->rollback();
226             } else {
227 27         366 $dbh->commit();
228             }
229             } else {
230 0         0 my $err = $dbh->errstr;
231 0         0 $dbh->rollback();
232 0         0 croak "querying migration version table failed: $err";
233             }
234             } else {
235 15         31 $rv = undef;
236             }
237            
238 43         6283 return $rv;
239             }
240              
241             sub table_exists {
242 50     50 1 126 my($self, $table) = @_;
243            
244 50         108 my $dbh = $self->{dbh};
245 50         85 my $rv;
246 50         380 $dbh->begin_work;
247 50         3319 my $query = $self->sql_table_exists($table);
248 50         1176 my $sth = $dbh->prepare($query);
249 50 50       3932 if($sth->execute()) {
250 50 100       20734 if($sth->fetchrow_arrayref()) {
251 34         83 $rv = 1;
252             } else {
253 16         254 $rv = 0;
254             }
255 50         292 $sth->finish();
256 50 100       272 if($dbh->transaction_error) {
257 10         106 $dbh->rollback();
258             } else {
259 40         693 $dbh->commit();
260             }
261             } else {
262 0         0 my $err = $dbh->errstr;
263 0         0 $dbh->rollback();
264 0         0 warn "table_exists query $query failed: $err";
265 0         0 $rv = undef;
266             }
267 50         11168 return $rv;
268             }
269