| ... | ... |
@@ -13,7 +13,6 @@ use DBI::Custom::Query; |
| 13 | 13 |
sub user : ClassObjectAttr { initialize => {clone => 'scalar'} }
|
| 14 | 14 |
sub password : ClassObjectAttr { initialize => {clone => 'scalar'} }
|
| 15 | 15 |
sub data_source : ClassObjectAttr { initialize => {clone => 'scalar'} }
|
| 16 |
-sub database : ClassObjectAttr { initialize => {clone => 'scalar'} }
|
|
| 17 | 16 |
sub dbi_options : ClassObjectAttr { initialize => {clone => 'hash',
|
| 18 | 17 |
default => sub { {} } } }
|
| 19 | 18 |
|
| ... | ... |
@@ -67,7 +66,7 @@ sub _auto_commit {
|
| 67 | 66 |
my $self = shift; |
| 68 | 67 |
|
| 69 | 68 |
croak("Cannot change AutoCommit becouse of not connected")
|
| 70 |
- unless $self->dbh; |
|
| 69 |
+ unless $self->dbh; |
|
| 71 | 70 |
|
| 72 | 71 |
if (@_) {
|
| 73 | 72 |
$self->dbh->{AutoCommit} = $_[0];
|
| ... | ... |
@@ -109,7 +108,7 @@ sub DESTROY {
|
| 109 | 108 |
# Is connected? |
| 110 | 109 |
sub connected {
|
| 111 | 110 |
my $self = shift; |
| 112 |
- return exists $self->{dbh} && eval {$self->{dbh}->can('prepare')};
|
|
| 111 |
+ return ref $self->{dbh} eq 'DBI::db';
|
|
| 113 | 112 |
} |
| 114 | 113 |
|
| 115 | 114 |
# Disconnect |
| ... | ... |
@@ -132,41 +131,87 @@ sub reconnect {
|
| 132 | 131 |
sub run_tranzaction {
|
| 133 | 132 |
my ($self, $tranzaction) = @_; |
| 134 | 133 |
|
| 134 |
+ # Auto commit off |
|
| 135 | 135 |
$self->_auto_commit(0); |
| 136 | 136 |
|
| 137 |
- eval {
|
|
| 138 |
- $tranzaction->(); |
|
| 139 |
- $self->dbh->commit; |
|
| 140 |
- }; |
|
| 137 |
+ # Run tranzaction |
|
| 138 |
+ eval {$tranzaction->()};
|
|
| 141 | 139 |
|
| 142 |
- if ($@) {
|
|
| 143 |
- my $tranzaction_error = $@; |
|
| 140 |
+ # Tranzaction error |
|
| 141 |
+ my $tranzaction_error = $@; |
|
| 142 |
+ |
|
| 143 |
+ # RaiseError on |
|
| 144 |
+ my $old_raise_error = $self->dbh->{RaiseError};
|
|
| 145 |
+ $self->dbh->{RaiseError} = 1;
|
|
| 146 |
+ |
|
| 147 |
+ # Tranzaction is failed. |
|
| 148 |
+ if ($tranzaction_error) {
|
|
| 149 |
+ # Rollback |
|
| 150 |
+ eval{$self->dbh->rollback};
|
|
| 151 |
+ |
|
| 152 |
+ # Rollback error |
|
| 153 |
+ my $rollback_error = $@; |
|
| 144 | 154 |
|
| 145 |
- $self->dbh->rollback or croak("$@ and rollback also failed");
|
|
| 146 |
- croak("$tranzaction_error");
|
|
| 155 |
+ # Auto commit on |
|
| 156 |
+ $self->_auto_commit(1); |
|
| 157 |
+ |
|
| 158 |
+ # Restore RaiseError value |
|
| 159 |
+ $self->dbh->{RaiseError} = $old_raise_error;
|
|
| 160 |
+ |
|
| 161 |
+ if ($rollback_error) {
|
|
| 162 |
+ # Rollback is failed |
|
| 163 |
+ croak("${tranzaction_error}Rollback is failed : $rollback_error");
|
|
| 164 |
+ } |
|
| 165 |
+ else {
|
|
| 166 |
+ # Rollback is success |
|
| 167 |
+ croak("${tranzaction_error}Rollback is success");
|
|
| 168 |
+ } |
|
| 169 |
+ } |
|
| 170 |
+ # Tranzaction is success |
|
| 171 |
+ else {
|
|
| 172 |
+ # Commit |
|
| 173 |
+ eval{$self->dbh->commit};
|
|
| 174 |
+ my $commit_error = $@; |
|
| 175 |
+ |
|
| 176 |
+ # Auto commit on |
|
| 177 |
+ $self->_auto_commit(1); |
|
| 178 |
+ |
|
| 179 |
+ # Restore RaiseError value |
|
| 180 |
+ $self->dbh->{RaiseError} = $old_raise_error;
|
|
| 181 |
+ |
|
| 182 |
+ # Commit is failed |
|
| 183 |
+ croak($commit_error) if $commit_error; |
|
| 147 | 184 |
} |
| 148 |
- $self->_auto_commit(1); |
|
| 149 | 185 |
} |
| 150 | 186 |
|
| 187 |
+# Prepare statement handle |
|
| 151 | 188 |
sub prepare {
|
| 152 | 189 |
my ($self, $sql) = @_; |
| 190 |
+ |
|
| 191 |
+ # Connect if not |
|
| 153 | 192 |
eval{$self->connect unless $self->connected};
|
| 154 | 193 |
croak($@) if $@; |
| 155 | 194 |
|
| 195 |
+ # Prepare |
|
| 156 | 196 |
my $sth = eval{$self->dbh->prepare($sql)};
|
| 157 | 197 |
croak($@) if $@; |
| 158 | 198 |
return $sth; |
| 159 | 199 |
} |
| 160 | 200 |
|
| 201 |
+# Execute SQL directly |
|
| 161 | 202 |
sub do{
|
| 162 | 203 |
my ($self, $sql, @bind_values) = @_; |
| 204 |
+ |
|
| 205 |
+ # Connect if not |
|
| 163 | 206 |
eval{$self->connect unless $self->connected};
|
| 164 | 207 |
croak($@) if $@; |
| 165 | 208 |
|
| 209 |
+ # Do |
|
| 166 | 210 |
eval{$self->dbh->do($sql, @bind_values)};
|
| 167 | 211 |
croak($@) if $@; |
| 168 | 212 |
} |
| 169 | 213 |
|
| 214 |
+# Create query |
|
| 170 | 215 |
sub create_query {
|
| 171 | 216 |
my ($self, $template) = @_; |
| 172 | 217 |
|
| ... | ... |
@@ -178,8 +223,9 @@ sub create_query {
|
| 178 | 223 |
# Create Query object; |
| 179 | 224 |
$query = DBI::Custom::Query->new($query); |
| 180 | 225 |
|
| 181 |
- # connect if not |
|
| 182 |
- $self->connect unless $self->connected; |
|
| 226 |
+ # Connect if not |
|
| 227 |
+ eval{$self->connect unless $self->connected};
|
|
| 228 |
+ croak($@) if $@; |
|
| 183 | 229 |
|
| 184 | 230 |
# Prepare statement handle |
| 185 | 231 |
my $sth = eval{$self->dbh->prepare($query->{sql})};
|
| ... | ... |
@@ -207,6 +253,7 @@ sub create_query {
|
| 207 | 253 |
return $query; |
| 208 | 254 |
} |
| 209 | 255 |
|
| 256 |
+# Execute query |
|
| 210 | 257 |
sub execute {
|
| 211 | 258 |
my ($self, $query, $params) = @_; |
| 212 | 259 |
$params ||= {};
|
| ... | ... |
@@ -225,6 +272,8 @@ sub execute {
|
| 225 | 272 |
# Execute |
| 226 | 273 |
my $sth = $query->sth; |
| 227 | 274 |
my $ret_val = eval{$sth->execute(@$bind_values)};
|
| 275 |
+ |
|
| 276 |
+ # Execute error |
|
| 228 | 277 |
if ($@) {
|
| 229 | 278 |
require Data::Dumper; |
| 230 | 279 |
my $sql = $query->{sql} || '';
|
| ... | ... |
@@ -236,7 +285,11 @@ sub execute {
|
| 236 | 285 |
|
| 237 | 286 |
# Return resultset if select statement is executed |
| 238 | 287 |
if ($sth->{NUM_OF_FIELDS}) {
|
| 288 |
+ |
|
| 289 |
+ # Get result class |
|
| 239 | 290 |
my $result_class = $self->result_class; |
| 291 |
+ |
|
| 292 |
+ # Create result |
|
| 240 | 293 |
my $result = $result_class->new({
|
| 241 | 294 |
sth => $sth, |
| 242 | 295 |
fetch_filter => $query->fetch_filter, |
| ... | ... |
@@ -247,9 +300,9 @@ sub execute {
|
| 247 | 300 |
return $ret_val; |
| 248 | 301 |
} |
| 249 | 302 |
|
| 303 |
+# Build binding values |
|
| 250 | 304 |
sub _build_bind_values {
|
| 251 | 305 |
my ($self, $query, $params) = @_; |
| 252 |
- |
|
| 253 | 306 |
my $key_infos = $query->key_infos; |
| 254 | 307 |
my $bind_filter = $query->bind_filter; |
| 255 | 308 |
my $no_bind_filters_map = $query->_no_bind_filters_map || {};
|
| ... | ... |
@@ -259,58 +312,96 @@ sub _build_bind_values {
|
| 259 | 312 |
|
| 260 | 313 |
# Create bind values |
| 261 | 314 |
foreach my $key_info (@$key_infos) {
|
| 262 |
- my $filtering_key = $key_info->{key};
|
|
| 263 |
- my $access_keys = $key_info->{access_keys};
|
|
| 264 |
- |
|
| 315 |
+ # Set variable |
|
| 316 |
+ my $access_keys = $key_info->{access_keys};
|
|
| 265 | 317 |
my $original_key = $key_info->{original_key} || '';
|
| 266 | 318 |
my $table = $key_info->{table} || '';
|
| 267 | 319 |
my $column = $key_info->{column} || '';
|
| 268 | 320 |
|
| 321 |
+ # Key is found? |
|
| 269 | 322 |
my $found; |
| 323 |
+ |
|
| 324 |
+ # Build bind values |
|
| 270 | 325 |
ACCESS_KEYS : |
| 271 | 326 |
foreach my $access_key (@$access_keys) {
|
| 327 |
+ # Root parameter |
|
| 272 | 328 |
my $root_params = $params; |
| 329 |
+ |
|
| 330 |
+ # Search corresponding value |
|
| 273 | 331 |
for (my $i = 0; $i < @$access_key; $i++) {
|
| 274 |
- my $key = $access_key->[$i]; |
|
| 332 |
+ # Current key |
|
| 333 |
+ my $current_key = $access_key->[$i]; |
|
| 275 | 334 |
|
| 335 |
+ # Each access key must be string or array reference |
|
| 276 | 336 |
croak("'access_keys' each value must be string or array reference")
|
| 277 |
- unless (ref $key eq 'ARRAY' || ($key && !ref $key)); |
|
| 337 |
+ unless (ref $current_key eq 'ARRAY' || |
|
| 338 |
+ ($current_key && !ref $current_key)); |
|
| 278 | 339 |
|
| 340 |
+ # Last key |
|
| 279 | 341 |
if ($i == @$access_key - 1) {
|
| 280 |
- if (ref $key eq 'ARRAY') {
|
|
| 281 |
- if ($bind_filter && !$no_bind_filters_map->{$original_key}) {
|
|
| 342 |
+ # Key is array reference |
|
| 343 |
+ if (ref $current_key eq 'ARRAY') {
|
|
| 344 |
+ # Filtering |
|
| 345 |
+ if ($bind_filter && |
|
| 346 |
+ !$no_bind_filters_map->{$original_key})
|
|
| 347 |
+ {
|
|
| 282 | 348 |
push @bind_values, |
| 283 |
- $bind_filter->($original_key, $root_params->[$key->[0]], |
|
| 349 |
+ $bind_filter->($original_key, |
|
| 350 |
+ $root_params->[$current_key->[0]], |
|
| 284 | 351 |
$table, $column); |
| 285 | 352 |
} |
| 353 |
+ # Not filtering |
|
| 286 | 354 |
else {
|
| 287 |
- push @bind_values, scalar $root_params->[$key->[0]]; |
|
| 355 |
+ push @bind_values, |
|
| 356 |
+ scalar $root_params->[$current_key->[0]]; |
|
| 288 | 357 |
} |
| 289 | 358 |
} |
| 359 |
+ # Key is string |
|
| 290 | 360 |
else {
|
| 291 |
- next ACCESS_KEYS unless exists $root_params->{$key};
|
|
| 292 |
- if ($bind_filter && !$no_bind_filters_map->{$original_key}) {
|
|
| 361 |
+ # Key is not found |
|
| 362 |
+ next ACCESS_KEYS |
|
| 363 |
+ unless exists $root_params->{$current_key};
|
|
| 364 |
+ |
|
| 365 |
+ # Filtering |
|
| 366 |
+ if ($bind_filter && |
|
| 367 |
+ !$no_bind_filters_map->{$original_key})
|
|
| 368 |
+ {
|
|
| 293 | 369 |
push @bind_values, |
| 294 |
- $bind_filter->($original_key, $root_params->{$key},
|
|
| 370 |
+ $bind_filter->($original_key, |
|
| 371 |
+ $root_params->{$current_key},
|
|
| 295 | 372 |
$table, $column); |
| 296 | 373 |
} |
| 374 |
+ # Not filtering |
|
| 297 | 375 |
else {
|
| 298 |
- push @bind_values, scalar $root_params->{$key};
|
|
| 376 |
+ push @bind_values, |
|
| 377 |
+ scalar $root_params->{$current_key};
|
|
| 299 | 378 |
} |
| 300 | 379 |
} |
| 380 |
+ |
|
| 381 |
+ # Key is found |
|
| 301 | 382 |
$found = 1; |
| 302 | 383 |
} |
| 303 |
- |
|
| 304 |
- if (ref $key eq 'ARRAY') {
|
|
| 305 |
- $root_params = $root_params->[$key->[0]]; |
|
| 306 |
- } |
|
| 384 |
+ # First or middle key |
|
| 307 | 385 |
else {
|
| 308 |
- next ACCESS_KEYS unless exists $root_params->{$key};
|
|
| 309 |
- $root_params = $root_params->{$key};
|
|
| 386 |
+ # Key is array reference |
|
| 387 |
+ if (ref $current_key eq 'ARRAY') {
|
|
| 388 |
+ # Go next key |
|
| 389 |
+ $root_params = $root_params->[$current_key->[0]]; |
|
| 390 |
+ } |
|
| 391 |
+ # Key is string |
|
| 392 |
+ else {
|
|
| 393 |
+ # Not found |
|
| 394 |
+ next ACCESS_KEYS |
|
| 395 |
+ unless exists $root_params->{$current_key};
|
|
| 396 |
+ |
|
| 397 |
+ # Go next key |
|
| 398 |
+ $root_params = $root_params->{$current_key};
|
|
| 399 |
+ } |
|
| 310 | 400 |
} |
| 311 | 401 |
} |
| 312 | 402 |
} |
| 313 | 403 |
|
| 404 |
+ # Key is not found |
|
| 314 | 405 |
unless ($found) {
|
| 315 | 406 |
require Data::Dumper; |
| 316 | 407 |
my $key_info_dump = Data::Dumper->Dump([$key_info], ['*key_info']); |
| ... | ... |
@@ -334,7 +425,14 @@ DBI::Custom - Customizable simple DBI |
| 334 | 425 |
|
| 335 | 426 |
Version 0.0101 |
| 336 | 427 |
|
| 337 |
-=cut |
|
| 428 |
+=head1 CAUTION |
|
| 429 |
+ |
|
| 430 |
+This module is now experimental stage. |
|
| 431 |
+ |
|
| 432 |
+I want you to try this module |
|
| 433 |
+because I want this module stable, and not to damage your DB data by this module bug. |
|
| 434 |
+ |
|
| 435 |
+Please tell me bug if you find |
|
| 338 | 436 |
|
| 339 | 437 |
=head1 SYNOPSIS |
| 340 | 438 |
|
| ... | ... |
@@ -576,8 +674,6 @@ See also L<DBI::Custom::SQL::Template> |
| 576 | 674 |
If tranzaction is success, commit is execute. |
| 577 | 675 |
If tranzation is died, rollback is execute. |
| 578 | 676 |
|
| 579 |
- |
|
| 580 |
- |
|
| 581 | 677 |
=head1 AUTHOR |
| 582 | 678 |
|
| 583 | 679 |
Yuki Kimoto, C<< <kimoto.yuki at gmail.com> >> |
| ... | ... |
@@ -591,7 +687,4 @@ Copyright 2009 Yuki Kimoto, all rights reserved. |
| 591 | 687 |
This program is free software; you can redistribute it and/or modify it |
| 592 | 688 |
under the same terms as Perl itself. |
| 593 | 689 |
|
| 594 |
- |
|
| 595 | 690 |
=cut |
| 596 |
- |
|
| 597 |
-1; # End of DBI::Custom |
| ... | ... |
@@ -3,7 +3,6 @@ use strict; |
| 3 | 3 |
use warnings; |
| 4 | 4 |
|
| 5 | 5 |
use DBI::Custom; |
| 6 |
-use Scalar::Util qw/blessed/; |
|
| 7 | 6 |
use DBI::Custom::SQL::Template; |
| 8 | 7 |
|
| 9 | 8 |
# Function for test name |
| ... | ... |
@@ -12,15 +11,16 @@ sub test {
|
| 12 | 11 |
$test = shift; |
| 13 | 12 |
} |
| 14 | 13 |
|
| 15 |
-# Varialbes for test |
|
| 14 |
+# Variables for test |
|
| 15 |
+our $SQL_TMPL = {
|
|
| 16 |
+ 0 => DBI::Custom::SQL::Template->new->tag_start(0), |
|
| 17 |
+ 1 => DBI::Custom::SQL::Template->new->tag_start(1), |
|
| 18 |
+ 2 => DBI::Custom::SQL::Template->new->tag_start(2) |
|
| 19 |
+}; |
|
| 16 | 20 |
my $dbi; |
| 17 |
-my $sql_tmpl; |
|
| 18 | 21 |
|
| 19 |
-my $sql_tmpl1 = DBI::Custom::SQL::Template->new->tag_start(0); |
|
| 20 |
-my $sql_tmpl2 = DBI::Custom::SQL::Template->new->tag_start(1); |
|
| 21 |
-my $sql_tmpl3 = DBI::Custom::SQL::Template->new->tag_start(2); |
|
| 22 | 22 |
|
| 23 |
-test 'constructor'; |
|
| 23 |
+test 'Constructor'; |
|
| 24 | 24 |
$dbi = DBI::Custom->new( |
| 25 | 25 |
user => 'a', |
| 26 | 26 |
password => 'b', |
| ... | ... |
@@ -32,12 +32,12 @@ $dbi = DBI::Custom->new( |
| 32 | 32 |
bind_filter => 'f', |
| 33 | 33 |
fetch_filter => 'g', |
| 34 | 34 |
result_class => 'g', |
| 35 |
- sql_template => $sql_tmpl1, |
|
| 35 |
+ sql_template => $SQL_TMPL->{0},
|
|
| 36 | 36 |
); |
| 37 | 37 |
is_deeply($dbi,{user => 'a', password => 'b', data_source => 'c',
|
| 38 | 38 |
dbi_options => {d => 1, e => 2}, filters => {f => 3}, bind_filter => 'f',
|
| 39 | 39 |
fetch_filter => 'g', result_class => 'g', |
| 40 |
- sql_template => $sql_tmpl1}, $test); |
|
| 40 |
+ sql_template => $SQL_TMPL->{0}}, $test);
|
|
| 41 | 41 |
isa_ok($dbi, 'DBI::Custom'); |
| 42 | 42 |
|
| 43 | 43 |
|
| ... | ... |
@@ -57,7 +57,7 @@ test 'Sub class constructor'; |
| 57 | 57 |
->bind_filter('f')
|
| 58 | 58 |
->fetch_filter('g')
|
| 59 | 59 |
->result_class('DBI::Custom::Result')
|
| 60 |
- ->sql_template($sql_tmpl1) |
|
| 60 |
+ ->sql_template($SQL_TMPL->{0})
|
|
| 61 | 61 |
; |
| 62 | 62 |
} |
| 63 | 63 |
$dbi = DBI::Custom::T1->new( |
| ... | ... |
@@ -71,7 +71,7 @@ $dbi = DBI::Custom::T1->new( |
| 71 | 71 |
bind_filter => 'fo', |
| 72 | 72 |
fetch_filter => 'go', |
| 73 | 73 |
result_class => 'ho', |
| 74 |
- sql_template => $sql_tmpl1, |
|
| 74 |
+ sql_template => $SQL_TMPL->{0},
|
|
| 75 | 75 |
); |
| 76 | 76 |
is($dbi->user, 'ao', "$test : user"); |
| 77 | 77 |
is($dbi->password, 'bo', "$test : passowr"); |
| ... | ... |
@@ -97,12 +97,12 @@ is($dbi->result_class, 'DBI::Custom::Result', "$test : result_class"); |
| 97 | 97 |
is($dbi->sql_template->tag_start, 0, "$test : sql_template"); |
| 98 | 98 |
isa_ok($dbi, 'DBI::Custom::T1'); |
| 99 | 99 |
|
| 100 |
+ |
|
| 100 | 101 |
test 'Sub sub class constructor default'; |
| 101 | 102 |
{
|
| 102 | 103 |
package DBI::Custom::T1_2; |
| 103 | 104 |
use base 'DBI::Custom::T1'; |
| 104 | 105 |
} |
| 105 |
- |
|
| 106 | 106 |
$dbi = DBI::Custom::T1_2->new; |
| 107 | 107 |
is($dbi->user, 'a', "$test : user"); |
| 108 | 108 |
is($dbi->password, 'b', "$test : passowrd"); |
| ... | ... |
@@ -132,7 +132,7 @@ test 'Customized sub class constructor default'; |
| 132 | 132 |
->bind_filter('fo')
|
| 133 | 133 |
->fetch_filter('go')
|
| 134 | 134 |
->result_class('ho')
|
| 135 |
- ->sql_template($sql_tmpl2) |
|
| 135 |
+ ->sql_template($SQL_TMPL->{1})
|
|
| 136 | 136 |
; |
| 137 | 137 |
} |
| 138 | 138 |
$dbi = DBI::Custom::T1_3->new; |
| ... | ... |
@@ -160,7 +160,7 @@ $dbi = DBI::Custom::T1_3->new( |
| 160 | 160 |
bind_filter => 'f', |
| 161 | 161 |
fetch_filter => 'g', |
| 162 | 162 |
result_class => 'h', |
| 163 |
- sql_template => $sql_tmpl3, |
|
| 163 |
+ sql_template => $SQL_TMPL->{2},
|
|
| 164 | 164 |
); |
| 165 | 165 |
is($dbi->user, 'a', "$test : user"); |
| 166 | 166 |
is($dbi->password, 'b', "$test : password"); |
| ... | ... |
@@ -173,3 +173,9 @@ is($dbi->result_class, 'h', "$test : result_class"); |
| 173 | 173 |
is($dbi->sql_template->tag_start, 2, "$test : sql_template"); |
| 174 | 174 |
isa_ok($dbi, 'DBI::Custom'); |
| 175 | 175 |
|
| 176 |
+ |
|
| 177 |
+test 'add_filters'; |
|
| 178 |
+$dbi = DBI::Custom->new; |
|
| 179 |
+$dbi->add_filter(a => sub {1});
|
|
| 180 |
+is($dbi->filters->{a}->(), 1, $test);
|
|
| 181 |
+ |
| ... | ... |
@@ -18,6 +18,8 @@ sub test {
|
| 18 | 18 |
$test = shift; |
| 19 | 19 |
} |
| 20 | 20 |
|
| 21 |
+ |
|
| 22 |
+ |
|
| 21 | 23 |
# Varialbes for test |
| 22 | 24 |
our $CREATE_TABLE = {
|
| 23 | 25 |
0 => 'create table table1 (key1 char(255), key2 char(255));', |
| ... | ... |
@@ -28,6 +30,10 @@ our $SELECT_TMPL = {
|
| 28 | 30 |
0 => 'select * from table1;' |
| 29 | 31 |
}; |
| 30 | 32 |
|
| 33 |
+our $DROP_TABLE = {
|
|
| 34 |
+ 0 => 'drop table table1' |
|
| 35 |
+}; |
|
| 36 |
+ |
|
| 31 | 37 |
my $dbi; |
| 32 | 38 |
my $sth; |
| 33 | 39 |
my $tmpl; |
| ... | ... |
@@ -46,13 +52,18 @@ my $update_query; |
| 46 | 52 |
my $ret_val; |
| 47 | 53 |
|
| 48 | 54 |
|
| 49 |
- |
|
| 50 |
-test 'Disconnect'; |
|
| 55 |
+test 'disconnect'; |
|
| 51 | 56 |
$dbi = DBI::Custom->new(data_source => 'dbi:SQLite:dbname=:memory:'); |
| 52 | 57 |
$dbi->connect; |
| 53 | 58 |
$dbi->disconnect; |
| 54 | 59 |
ok(!$dbi->dbh, $test); |
| 55 | 60 |
|
| 61 |
+test 'connected'; |
|
| 62 |
+$dbi = DBI::Custom->new(data_source => 'dbi:SQLite:dbname=:memory:'); |
|
| 63 |
+ok(!$dbi->connected, "$test : not connected"); |
|
| 64 |
+$dbi->connect; |
|
| 65 |
+ok($dbi->connected, "$test : connected"); |
|
| 66 |
+ |
|
| 56 | 67 |
# Prepare table |
| 57 | 68 |
$dbi = DBI::Custom->new(data_source => 'dbi:SQLite:dbname=:memory:'); |
| 58 | 69 |
$dbi->connect; |
| ... | ... |
@@ -112,7 +123,7 @@ is_deeply(\@rows, [[1, 2], [3, 4]], "$test : fetch_all_hash list context"); |
| 112 | 123 |
|
| 113 | 124 |
|
| 114 | 125 |
test 'Insert query return value'; |
| 115 |
-$dbi->reconnect; |
|
| 126 |
+$dbi->do($DROP_TABLE->{0});
|
|
| 116 | 127 |
$dbi->do($CREATE_TABLE->{0});
|
| 117 | 128 |
$tmpl = "insert into table1 {insert key1 key2}";
|
| 118 | 129 |
$query = $dbi->create_query($tmpl); |
| ... | ... |
@@ -121,7 +132,7 @@ ok($ret_val, $test); |
| 121 | 132 |
|
| 122 | 133 |
|
| 123 | 134 |
test 'Direct execute'; |
| 124 |
-$dbi->reconnect; |
|
| 135 |
+$dbi->do($DROP_TABLE->{0});
|
|
| 125 | 136 |
$dbi->do($CREATE_TABLE->{0});
|
| 126 | 137 |
$insert_tmpl = "insert into table1 {insert key1 key2}";
|
| 127 | 138 |
$dbi->execute($insert_tmpl, {key1 => 1, key2 => 2}, sub {
|
| ... | ... |
@@ -140,7 +151,7 @@ is_deeply($rows, [{key1 => 1, key2 => 3}], $test);
|
| 140 | 151 |
|
| 141 | 152 |
|
| 142 | 153 |
test 'Filter basic'; |
| 143 |
-$dbi->reconnect; |
|
| 154 |
+$dbi->do($DROP_TABLE->{0});
|
|
| 144 | 155 |
$dbi->do($CREATE_TABLE->{0});
|
| 145 | 156 |
|
| 146 | 157 |
$insert_tmpl = "insert into table1 {insert key1 key2};";
|
| ... | ... |
@@ -173,7 +184,7 @@ $result = $dbi->execute($select_query); |
| 173 | 184 |
$rows = $result->fetch_all_hash; |
| 174 | 185 |
is_deeply($rows, [{key1 => 1, key2 => 2}], "$test : no_fetch_filters no_bind_filters");
|
| 175 | 186 |
|
| 176 |
-$dbi->reconnect; |
|
| 187 |
+$dbi->do($DROP_TABLE->{0});
|
|
| 177 | 188 |
$dbi->do($CREATE_TABLE->{0});
|
| 178 | 189 |
$insert_tmpl = "insert into table1 {insert table1.key1 table1.key2}";
|
| 179 | 190 |
$insert_query = $dbi->create_query($insert_tmpl); |
| ... | ... |
@@ -209,7 +220,7 @@ is_deeply($rows, [{key1 => 2, key2 => 4}], "$test : bind_filter");
|
| 209 | 220 |
|
| 210 | 221 |
|
| 211 | 222 |
test 'DBI::Custom::SQL::Template basic tag'; |
| 212 |
-$dbi->reconnect; |
|
| 223 |
+$dbi->do($DROP_TABLE->{0});
|
|
| 213 | 224 |
$dbi->do($CREATE_TABLE->{1});
|
| 214 | 225 |
$sth = $dbi->prepare("insert into table1 (key1, key2, key3, key4, key5) values (?, ?, ?, ?, ?);");
|
| 215 | 226 |
$sth->execute(1, 2, 3, 4, 5); |
| ... | ... |
@@ -253,7 +264,7 @@ is_deeply($rows, [{key1 => 1, key2 => 2, key3 => 3, key4 => 4, key5 => 5}], "$te
|
| 253 | 264 |
|
| 254 | 265 |
|
| 255 | 266 |
test 'DIB::Custom::SQL::Template in tag'; |
| 256 |
-$dbi->reconnect; |
|
| 267 |
+$dbi->do($DROP_TABLE->{0});
|
|
| 257 | 268 |
$dbi->do($CREATE_TABLE->{1});
|
| 258 | 269 |
$sth = $dbi->prepare("insert into table1 (key1, key2, key3, key4, key5) values (?, ?, ?, ?, ?);");
|
| 259 | 270 |
$sth->execute(1, 2, 3, 4, 5); |
| ... | ... |
@@ -366,3 +377,34 @@ $rows = $result->fetch_all_hash; |
| 366 | 377 |
is_deeply($rows, [{key1 => 6, key2 => 6, key3 => 6, key4 => 6, key5 => 5},
|
| 367 | 378 |
{key1 => 6, key2 => 7, key3 => 8, key4 => 9, key5 => 10}], "$test : update tag #update with table name dot");
|
| 368 | 379 |
|
| 380 |
+ |
|
| 381 |
+test 'run_tansaction'; |
|
| 382 |
+$dbi->do($DROP_TABLE->{0});
|
|
| 383 |
+$dbi->do($CREATE_TABLE->{0});
|
|
| 384 |
+$dbi->run_tranzaction(sub {
|
|
| 385 |
+ $insert_tmpl = 'insert into table1 {insert key1 key2}';
|
|
| 386 |
+ $dbi->execute($insert_tmpl, {key1 => 1, key2 => 2});
|
|
| 387 |
+ $dbi->execute($insert_tmpl, {key1 => 3, key2 => 4});
|
|
| 388 |
+}); |
|
| 389 |
+$result = $dbi->execute($SELECT_TMPL->{0});
|
|
| 390 |
+$rows = $result->fetch_all_hash; |
|
| 391 |
+is_deeply($rows, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}], "$test : commit");
|
|
| 392 |
+ |
|
| 393 |
+$dbi->do($DROP_TABLE->{0});
|
|
| 394 |
+$dbi->do($CREATE_TABLE->{0});
|
|
| 395 |
+$dbi->dbh->{RaiseError} = 0;
|
|
| 396 |
+eval{
|
|
| 397 |
+ $dbi->run_tranzaction(sub {
|
|
| 398 |
+ $insert_tmpl = 'insert into table1 {insert key1 key2}';
|
|
| 399 |
+ $dbi->execute($insert_tmpl, {key1 => 1, key2 => 2});
|
|
| 400 |
+ die "Fatal Error"; |
|
| 401 |
+ $dbi->execute($insert_tmpl, {key1 => 3, key2 => 4});
|
|
| 402 |
+ }) |
|
| 403 |
+}; |
|
| 404 |
+like($@, qr/Fatal Error.*Rollback is success/ms, "$test : Rollback success message"); |
|
| 405 |
+ok(!$dbi->dbh->{RaiseError}, "$test : restore RaiseError value");
|
|
| 406 |
+$result = $dbi->execute($SELECT_TMPL->{0});
|
|
| 407 |
+$rows = $result->fetch_all_hash; |
|
| 408 |
+is_deeply($rows, [], "$test : rollback"); |
|
| 409 |
+ |
|
| 410 |
+ |
| ... | ... |
@@ -3,9 +3,9 @@ use strict; |
| 3 | 3 |
use warnings; |
| 4 | 4 |
|
| 5 | 5 |
# user password database |
| 6 |
-our ($U, $P, $D) = connect_info(); |
|
| 6 |
+our ($USER, $PASSWORD, $DATABASE) = connect_info(); |
|
| 7 | 7 |
|
| 8 |
-plan skip_all => 'private MySQL test' unless $U; |
|
| 8 |
+plan skip_all => 'private MySQL test' unless $USER; |
|
| 9 | 9 |
|
| 10 | 10 |
plan 'no_plan'; |
| 11 | 11 |
|
| ... | ... |
@@ -13,9 +13,9 @@ use DBI::Custom; |
| 13 | 13 |
use Scalar::Util 'blessed'; |
| 14 | 14 |
{
|
| 15 | 15 |
my $dbi = DBI::Custom->new( |
| 16 |
- user => $U, |
|
| 17 |
- password => $P, |
|
| 18 |
- data_source => "dbi:mysql:dbname=$D" |
|
| 16 |
+ user => $USER, |
|
| 17 |
+ password => $PASSWORD, |
|
| 18 |
+ data_source => "dbi:mysql:dbname=$DATABASE" |
|
| 19 | 19 |
); |
| 20 | 20 |
$dbi->connect; |
| 21 | 21 |
|