| ... | ... |
@@ -17,22 +17,16 @@ sub prototype : ClassAttr { auto_build => sub {
|
| 17 | 17 |
? $super->prototype->clone |
| 18 | 18 |
: $class->Object::Simple::new; |
| 19 | 19 |
|
| 20 |
- $class->prototype($prototype); |
|
| 20 |
+ $class->prototype(bless $prototype, $class); |
|
| 21 | 21 |
}} |
| 22 | 22 |
|
| 23 | 23 |
# New |
| 24 | 24 |
sub new {
|
| 25 |
- my $self = shift->Object::Simple::new(@_); |
|
| 26 |
- my $class = ref $self; |
|
| 27 |
- return bless {%{$class->prototype->clone}, %{$self}}, $class;
|
|
| 28 |
-} |
|
| 29 |
- |
|
| 30 |
-# Initialize class |
|
| 31 |
-sub initialize_class {
|
|
| 32 |
- my ($class, $callback) = @_; |
|
| 33 |
- |
|
| 34 |
- # Callback to initialize prototype |
|
| 35 |
- $callback->($class->prototype); |
|
| 25 |
+ my $invocant = shift; |
|
| 26 |
+ my $class = ref $invocant || $invocant; |
|
| 27 |
+ my $prototype = $class->prototype; |
|
| 28 |
+ my $self = $class->Object::Simple::new(%{$prototype->clone}, @_);
|
|
| 29 |
+ return bless $self, $class; |
|
| 36 | 30 |
} |
| 37 | 31 |
|
| 38 | 32 |
# Clone |
| ... | ... |
@@ -40,29 +34,35 @@ sub clone {
|
| 40 | 34 |
my $self = shift; |
| 41 | 35 |
my $new = $self->Object::Simple::new; |
| 42 | 36 |
|
| 43 |
- $new->connect_info(%{$self->connect_info || {}});
|
|
| 44 |
- $new->connect_info->{options} = \%{$self->connect_info->{options}};
|
|
| 37 |
+ # Scalar copy |
|
| 38 |
+ foreach my $attr (qw/bind_filter fetch_filter result_class/) {
|
|
| 39 |
+ $new->$attr($self->$attr); |
|
| 40 |
+ } |
|
| 45 | 41 |
|
| 46 |
- $new->filters(%{$self->filters || {}});
|
|
| 47 |
- $new->bind_filter($self->bind_filter); |
|
| 48 |
- $new->fetch_filter($self->fetch_filter); |
|
| 49 |
- $new->result_class($self->result_class); |
|
| 42 |
+ # Hash ref copy |
|
| 43 |
+ foreach my $attr (qw/connect_info filters valid_connect_info/) {
|
|
| 44 |
+ $new->$attr(\%{$self->$attr || {}});
|
|
| 45 |
+ } |
|
| 50 | 46 |
|
| 47 |
+ # Other |
|
| 48 |
+ $new->connect_info->{options} = \%{$self->connect_info->{options}};
|
|
| 51 | 49 |
$new->sql_template($self->sql_template->clone); |
| 52 | 50 |
} |
| 53 | 51 |
|
| 54 | 52 |
# Attribute |
| 55 |
-sub connect_info : Attr { type => 'hash', auto_build => sub { shift->connect_info({}) } }
|
|
| 56 |
- |
|
| 53 |
+sub connect_info : Attr { type => 'hash', default => sub { {} } }
|
|
| 57 | 54 |
sub bind_filter : Attr {}
|
| 58 | 55 |
sub fetch_filter : Attr {}
|
| 59 | 56 |
|
| 60 |
-sub filters : Attr { type => 'hash', deref => 1, auto_build => sub { shift->filters({}) } }
|
|
| 57 |
+sub filters : Attr { type => 'hash', deref => 1, default => sub { {} } }
|
|
| 61 | 58 |
sub add_filter { shift->filters(@_) }
|
| 62 | 59 |
|
| 63 |
-sub result_class : Attr { auto_build => sub { shift->result_class('DBI::Custom::Result') }}
|
|
| 60 |
+sub result_class : Attr { default => 'DBI::Custom::Result' }
|
|
| 64 | 61 |
sub dbh : Attr {}
|
| 65 |
-sub sql_template : Attr { auto_build => sub { shift->sql_template(DBI::Custom::SQL::Template->new) } }
|
|
| 62 |
+sub sql_template : Attr { default => sub { DBI::Custom::SQL::Template->new } }
|
|
| 63 |
+sub valid_connect_info : Attr { type => 'hash', deref => 1, default => sub {
|
|
| 64 |
+ return {map {$_ => 1} qw/data_source user password options/}
|
|
| 65 |
+}} |
|
| 66 | 66 |
|
| 67 | 67 |
# Auto commit |
| 68 | 68 |
sub auto_commit {
|
| ... | ... |
@@ -78,10 +78,6 @@ sub auto_commit {
|
| 78 | 78 |
return $self->dbh->{AutoCommit};
|
| 79 | 79 |
} |
| 80 | 80 |
|
| 81 |
-sub valid_connect_info : Attr { default => sub {
|
|
| 82 |
- {map {$_ => 1} qw/data_source user password options/}
|
|
| 83 |
-}} |
|
| 84 |
- |
|
| 85 | 81 |
# Connect |
| 86 | 82 |
sub connect {
|
| 87 | 83 |
my $self = shift; |
| ... | ... |
@@ -155,17 +151,6 @@ sub run_tranzaction {
|
| 155 | 151 |
$self->auto_commit(1); |
| 156 | 152 |
} |
| 157 | 153 |
|
| 158 |
-sub dbh_option {
|
|
| 159 |
- my $self = shift; |
|
| 160 |
- croak("Not connected") unless $self->connected;
|
|
| 161 |
- my $dbh = $self->dbh; |
|
| 162 |
- if (@_ > 1) {
|
|
| 163 |
- $dbh->{$_[0]} = $_[1];
|
|
| 164 |
- return $self; |
|
| 165 |
- } |
|
| 166 |
- return $dbh->{$_[0]}
|
|
| 167 |
-} |
|
| 168 |
- |
|
| 169 | 154 |
# Create SQL from SQL template |
| 170 | 155 |
sub create_sql {
|
| 171 | 156 |
my $self = shift; |
| ... | ... |
@@ -238,6 +223,7 @@ sub query_raw_sql {
|
| 238 | 223 |
|
| 239 | 224 |
Object::Simple->build_class; |
| 240 | 225 |
|
| 226 |
+ |
|
| 241 | 227 |
package DBI::Custom::Result; |
| 242 | 228 |
use Object::Simple; |
| 243 | 229 |
|
| ... | ... |
@@ -333,7 +319,7 @@ sub finish { shift->sth->finish }
|
| 333 | 319 |
sub error {
|
| 334 | 320 |
my $self = shift; |
| 335 | 321 |
my $sth = $self->sth; |
| 336 |
- wantarray ? ($sth->errstr, $sth->err, $sth->state) : $sth->errstr; |
|
| 322 |
+ return wantarray ? ($sth->errstr, $sth->err, $sth->state) : $sth->errstr; |
|
| 337 | 323 |
} |
| 338 | 324 |
|
| 339 | 325 |
Object::Simple->build_class; |
| ... | ... |
@@ -343,38 +329,36 @@ package DBI::Custom::SQL::Template; |
| 343 | 329 |
use Object::Simple; |
| 344 | 330 |
use Carp 'croak'; |
| 345 | 331 |
|
| 332 |
+# Clone |
|
| 346 | 333 |
sub clone {
|
| 347 | 334 |
my $self = shift; |
| 348 | 335 |
my $new = $self->Object::Simple::new; |
| 349 | 336 |
|
| 350 |
- $new->tag_start($self->tag_start); |
|
| 351 |
- $new->tag_end($self->tag_end); |
|
| 352 |
- $new->bind_filter($self->bind_filter); |
|
| 353 |
- $new->upper_case($self->upper_case); |
|
| 354 |
- $new->tag_syntax($self->tag_syntax); |
|
| 337 |
+ # Scalar copy |
|
| 338 |
+ foreach my $attr (qw/tag_start tag_end bind_filter upper_case tag_syntax template/) {
|
|
| 339 |
+ $new->$attr($self->$attr); |
|
| 340 |
+ } |
|
| 341 |
+ |
|
| 342 |
+ # Hash ref copy |
|
| 343 |
+ foreach my $attr (qw/tag_processors/) {
|
|
| 344 |
+ $new->$attr(\%{$self->$attr || {}});
|
|
| 345 |
+ } |
|
| 346 |
+ |
|
| 347 |
+ # Other |
|
| 348 |
+ $new->tree([]); |
|
| 349 |
+ |
|
| 350 |
+ return $new; |
|
| 355 | 351 |
} |
| 356 | 352 |
|
| 353 |
+ |
|
| 357 | 354 |
### Attributes; |
| 358 | 355 |
sub tag_start : Attr { default => '{' }
|
| 359 | 356 |
sub tag_end : Attr { default => '}' }
|
| 360 | 357 |
sub template : Attr {};
|
| 361 |
-sub tree : Attr { auto_build => sub { shift->tree([]) } }
|
|
| 358 |
+sub tree : Attr { default => sub { [] } }
|
|
| 362 | 359 |
sub bind_filter : Attr {}
|
| 363 |
-sub values : Attr {}
|
|
| 364 | 360 |
sub upper_case : Attr {default => 0}
|
| 365 | 361 |
|
| 366 |
-sub create_sql {
|
|
| 367 |
- my ($self, $template, $values, $filter) = @_; |
|
| 368 |
- |
|
| 369 |
- $filter ||= $self->bind_filter; |
|
| 370 |
- |
|
| 371 |
- $self->parse($template); |
|
| 372 |
- |
|
| 373 |
- my ($sql, @bind) = $self->build_sql({bind_filter => $filter, values => $values});
|
|
| 374 |
- |
|
| 375 |
- return ($sql, @bind); |
|
| 376 |
-} |
|
| 377 |
- |
|
| 378 | 362 |
sub tag_syntax : Attr { default => <<'EOS' };
|
| 379 | 363 |
{? name} ?
|
| 380 | 364 |
{= name} name = ?
|
| ... | ... |
@@ -392,12 +376,46 @@ sub tag_syntax : Attr { default => <<'EOS' };
|
| 392 | 376 |
{update_values} set key1 = ?, key2 = ?, key3 = ?
|
| 393 | 377 |
EOS |
| 394 | 378 |
|
| 379 |
+sub tag_processors : Attr {type => 'hash', deref => 1, auto_build => sub {
|
|
| 380 |
+ shift->tag_processors( |
|
| 381 |
+ '?' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 382 |
+ '=' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 383 |
+ '<>' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 384 |
+ '>' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 385 |
+ '<' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 386 |
+ '>=' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 387 |
+ '<=' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 388 |
+ 'like' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 389 |
+ 'in' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 390 |
+ 'insert_values' => \&DBI::Custom::SQL::Template::TagProcessor::expand_insert_values, |
|
| 391 |
+ 'update_set' => \&DBI::Custom::SQL::Template::TagProcessor::expand_update_set |
|
| 392 |
+ ); |
|
| 393 |
+}} |
|
| 394 |
+ |
|
| 395 |
+sub add_tag_processor {
|
|
| 396 |
+ my $class = shift; |
|
| 397 |
+ my $tag_processors = ref $_[0] eq 'HASH' ? $_[0] : {@_};
|
|
| 398 |
+ $class->tag_processor(%{$class->tag_processor}, %{$tag_processors});
|
|
| 399 |
+} |
|
| 400 |
+ |
|
| 401 |
+sub create_sql {
|
|
| 402 |
+ my ($self, $template, $values, $filter) = @_; |
|
| 403 |
+ |
|
| 404 |
+ $filter ||= $self->bind_filter; |
|
| 405 |
+ |
|
| 406 |
+ $self->parse($template); |
|
| 407 |
+ |
|
| 408 |
+ my ($sql, @bind) = $self->build_sql({bind_filter => $filter, values => $values});
|
|
| 409 |
+ |
|
| 410 |
+ return ($sql, @bind); |
|
| 411 |
+} |
|
| 412 |
+ |
|
| 395 | 413 |
sub parse {
|
| 396 | 414 |
my ($self, $template) = @_; |
| 397 | 415 |
$self->template($template); |
| 398 | 416 |
|
| 399 | 417 |
# Clean start; |
| 400 |
- delete $self->{tree};
|
|
| 418 |
+ $self->tree([]); |
|
| 401 | 419 |
|
| 402 | 420 |
# Tags |
| 403 | 421 |
my $tag_start = quotemeta $self->tag_start; |
| ... | ... |
@@ -423,7 +441,7 @@ sub parse {
|
| 423 | 441 |
$tag ||= ''; |
| 424 | 442 |
unless ($self->tag_processors->{$tag_name}) {
|
| 425 | 443 |
my $tag_syntax = $self->tag_syntax; |
| 426 |
- croak("Tag '$tag' in SQL template is not exist.\n\n" .
|
|
| 444 |
+ croak("Tag '{$tag}' in SQL template is not exist.\n\n" .
|
|
| 427 | 445 |
"SQL template tag syntax\n" . |
| 428 | 446 |
"$tag_syntax\n\n" . |
| 429 | 447 |
"Your SQL template is \n$original_template\n\n"); |
| ... | ... |
@@ -441,7 +459,7 @@ sub build_sql {
|
| 441 | 459 |
|
| 442 | 460 |
my $tree = $args->{tree} || $self->tree;
|
| 443 | 461 |
my $bind_filter = $args->{bind_filter} || $self->bind_filter;
|
| 444 |
- my $values = exists $args->{values} ? $args->{values} : $self->values;
|
|
| 462 |
+ my $values = $args->{values} || {};
|
|
| 445 | 463 |
|
| 446 | 464 |
my @bind_values_all; |
| 447 | 465 |
my $sql = ''; |
| ... | ... |
@@ -455,20 +473,21 @@ sub build_sql {
|
| 455 | 473 |
$sql .= $args->[0]; |
| 456 | 474 |
} |
| 457 | 475 |
elsif ($type eq 'tag') {
|
| 458 |
- my $tag_processor = $self->tag_processors->{$type};
|
|
| 476 |
+ my $tag_processor = $self->tag_processors->{$tag_name};
|
|
| 459 | 477 |
|
| 460 | 478 |
croak("Tag processor '$type' must be code reference")
|
| 461 | 479 |
unless ref $tag_processor eq 'CODE'; |
| 462 | 480 |
|
| 463 | 481 |
my ($expand, @bind_values) |
| 464 |
- = $self->tag_processors->{$type}->($tag_name, $args, $values,
|
|
| 465 |
- $bind_filter, $self); |
|
| 482 |
+ = $tag_processor->($tag_name, $args, $values, |
|
| 483 |
+ $bind_filter, $self); |
|
| 466 | 484 |
|
| 467 |
- unless ($self->place_holder_count($expand) eq @bind_values) {
|
|
| 485 |
+ $DB::single = 1; |
|
| 486 |
+ unless ($self->_placeholder_count($expand) == @bind_values) {
|
|
| 468 | 487 |
require Data::Dumper; |
| 469 | 488 |
|
| 470 | 489 |
my $bind_values_dump |
| 471 |
- = Data::Dumper->Dump([\@bind_values], ['@bind_values']); |
|
| 490 |
+ = Data::Dumper->Dump([\@bind_values], ['*bind_values']); |
|
| 472 | 491 |
|
| 473 | 492 |
croak("Place holder count must be same as bind value count\n" .
|
| 474 | 493 |
"Tag : $tag_name\n" . |
| ... | ... |
@@ -488,38 +507,19 @@ sub _placeholder_count {
|
| 488 | 507 |
$expand ||= ''; |
| 489 | 508 |
|
| 490 | 509 |
my $count = 0; |
| 491 |
- my $pos = 0; |
|
| 492 |
- while ((my $pos = index $expand, $pos) != -1) {
|
|
| 510 |
+ my $pos = -1; |
|
| 511 |
+ while (($pos = index($expand, '?', $pos + 1)) != -1) {
|
|
| 493 | 512 |
$count++; |
| 494 | 513 |
} |
| 495 | 514 |
return $count; |
| 496 | 515 |
} |
| 497 | 516 |
|
| 498 |
-sub tag_processors : Attr {type => 'hash', deref => 1, auto_build => sub {
|
|
| 499 |
- shift->tag_processors( |
|
| 500 |
- '?' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 501 |
- '=' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 502 |
- '<>' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 503 |
- '<' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 504 |
- '>=' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 505 |
- '<=' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 506 |
- 'like' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 507 |
- 'in' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 508 |
- 'insert_values' => \&DBI::Custom::SQL::Template::TagProcessor::expand_insert_values, |
|
| 509 |
- 'update_set' => \&DBI::Custom::SQL::Template::TagProcessor::expand_update_set |
|
| 510 |
- ); |
|
| 511 |
-}} |
|
| 512 |
- |
|
| 513 |
-sub add_tag_processor {
|
|
| 514 |
- my $class = shift; |
|
| 515 |
- my $tag_processors = ref $_[0] eq 'HASH' ? $_[0] : {@_};
|
|
| 516 |
- $class->tag_processor(%{$class->tag_processor}, %{$tag_processors});
|
|
| 517 |
-} |
|
| 518 |
- |
|
| 519 | 517 |
Object::Simple->build_class; |
| 520 | 518 |
|
| 521 | 519 |
|
| 522 | 520 |
package DBI::Custom::SQL::Template::TagProcessor; |
| 521 |
+use strict; |
|
| 522 |
+use warnings; |
|
| 523 | 523 |
|
| 524 | 524 |
sub expand_place_holder {
|
| 525 | 525 |
my ($tag_name, $args, $values, $bind_filter, $sql_tmpl_obj) = @_; |
| ... | ... |
@@ -550,20 +550,6 @@ sub expand_place_holder {
|
| 550 | 550 |
} |
| 551 | 551 |
} |
| 552 | 552 |
|
| 553 |
- if ($bind_filter) {
|
|
| 554 |
- if ($tag_name eq 'in') {
|
|
| 555 |
- for (my $i = 0; $i < @$values; $i++) {
|
|
| 556 |
- push @bind_values, scalar $bind_filter->($key, $values->{$key}->[$i]);
|
|
| 557 |
- } |
|
| 558 |
- } |
|
| 559 |
- else {
|
|
| 560 |
- push @bind_values, scalar $bind_filter->($key, $values->{$key});
|
|
| 561 |
- } |
|
| 562 |
- } |
|
| 563 |
- else {
|
|
| 564 |
- push @bind_values, $values->{$key};
|
|
| 565 |
- } |
|
| 566 |
- |
|
| 567 | 553 |
$tag_name = uc $tag_name if $sql_tmpl_obj->upper_case; |
| 568 | 554 |
|
| 569 | 555 |
my $expand; |
| ... | ... |
@@ -608,8 +594,8 @@ sub expand_insert_values {
|
| 608 | 594 |
$place_holders =~ s/, $//; |
| 609 | 595 |
$place_holders .= ')'; |
| 610 | 596 |
|
| 611 |
- my $expand = $sql_tmpl_obj->uppser_case ? "$insert_keys VALUES $place_holders" |
|
| 612 |
- : "$insert_keys values $place_holders"; |
|
| 597 |
+ my $expand = $sql_tmpl_obj->upper_case ? "$insert_keys VALUES $place_holders" |
|
| 598 |
+ : "$insert_keys values $place_holders"; |
|
| 613 | 599 |
|
| 614 | 600 |
return ($expand, @bind_values); |
| 615 | 601 |
} |
| ... | ... |
@@ -617,7 +603,7 @@ sub expand_insert_values {
|
| 617 | 603 |
sub expand_update_set {
|
| 618 | 604 |
my ($tag_name, $args, $values, $bind_filter, $sql_tmpl_obj) = @_; |
| 619 | 605 |
|
| 620 |
- my $expand = $sql_tmpl_obj->uppser_case ? 'SET ' : 'set '; |
|
| 606 |
+ my $expand = $sql_tmpl_obj->upper_case ? 'SET ' : 'set '; |
|
| 621 | 607 |
$values = $args->[0] ? $values->{$args->[0]} : $values->{update_set};
|
| 622 | 608 |
|
| 623 | 609 |
my @bind_values; |
| ... | ... |
@@ -667,8 +653,6 @@ Version 0.0101 |
| 667 | 653 |
|
| 668 | 654 |
=head2 filters |
| 669 | 655 |
|
| 670 |
-=head2 initialize_class |
|
| 671 |
- |
|
| 672 | 656 |
=head2 prototype |
| 673 | 657 |
|
| 674 | 658 |
=head2 new |
| ... | ... |
@@ -685,17 +669,15 @@ Version 0.0101 |
| 685 | 669 |
|
| 686 | 670 |
=head2 connected |
| 687 | 671 |
|
| 688 |
-=head2 dbh_option |
|
| 689 |
- |
|
| 690 | 672 |
=head2 disconnect |
| 691 | 673 |
|
| 692 | 674 |
=head2 reconnect |
| 693 | 675 |
|
| 694 | 676 |
=head2 result_class |
| 695 | 677 |
|
| 696 |
-=head2 commit |
|
| 678 |
+=head2 run_tranzaction |
|
| 697 | 679 |
|
| 698 |
-=head2 rollback |
|
| 680 |
+=head2 valid_connect_info |
|
| 699 | 681 |
|
| 700 | 682 |
|
| 701 | 683 |
=head1 AUTHOR |
| ... | ... |
@@ -5,13 +5,17 @@ use warnings; |
| 5 | 5 |
use DBI::Custom; |
| 6 | 6 |
use Scalar::Util qw/blessed/; |
| 7 | 7 |
|
| 8 |
+my $sql_tmpl1 = DBI::Custom::SQL::Template->new->upper_case(0); |
|
| 9 |
+my $sql_tmpl2 = DBI::Custom::SQL::Template->new->upper_case(1); |
|
| 10 |
+my $sql_tmpl3 = DBI::Custom::SQL::Template->new->upper_case(2); |
|
| 11 |
+ |
|
| 8 | 12 |
{
|
| 9 | 13 |
my $dbi = DBI::Custom->new( |
| 10 | 14 |
connect_info => {
|
| 11 |
- user => 'a', |
|
| 12 |
- password => 'b', |
|
| 13 |
- data_source => 'c', |
|
| 14 |
- options => {d => 1, e => 2}
|
|
| 15 |
+ user => 'a', |
|
| 16 |
+ password => 'b', |
|
| 17 |
+ data_source => 'c', |
|
| 18 |
+ options => {d => 1, e => 2}
|
|
| 15 | 19 |
}, |
| 16 | 20 |
filters => {
|
| 17 | 21 |
f => 3, |
| ... | ... |
@@ -19,37 +23,42 @@ use Scalar::Util qw/blessed/; |
| 19 | 23 |
bind_filter => 'f', |
| 20 | 24 |
fetch_filter => 'g', |
| 21 | 25 |
dbh => 'e', |
| 22 |
- result_class => 'g' |
|
| 26 |
+ result_class => 'g', |
|
| 27 |
+ sql_template => $sql_tmpl1, |
|
| 28 |
+ valid_connect_info => {i => 1}
|
|
| 23 | 29 |
); |
| 24 |
- |
|
| 25 | 30 |
is_deeply($dbi,{connect_info => {user => 'a', password => 'b', data_source => 'c',
|
| 26 | 31 |
options => {d => 1, e => 2}}, filters => {f => 3}, bind_filter => 'f',
|
| 27 |
- fetch_filter => 'g', dbh => 'e', result_class => 'g'}, 'new'); |
|
| 32 |
+ fetch_filter => 'g', dbh => 'e', result_class => 'g', |
|
| 33 |
+ sql_template => $sql_tmpl1, valid_connect_info => {i => 1}}, 'new');
|
|
| 28 | 34 |
|
| 29 | 35 |
isa_ok($dbi, 'DBI::Custom'); |
| 30 | 36 |
} |
| 31 | 37 |
|
| 38 |
+ |
|
| 32 | 39 |
{
|
| 33 | 40 |
package DBI::Custom::T1; |
| 34 | 41 |
use base 'DBI::Custom'; |
| 35 | 42 |
|
| 36 |
- __PACKAGE__->initialize_class(sub {
|
|
| 37 |
- my $class = shift; |
|
| 38 |
- |
|
| 39 |
- $class |
|
| 40 |
- ->connect_info( |
|
| 41 |
- user => 'a', |
|
| 42 |
- password => 'b', |
|
| 43 |
- data_source => 'c', |
|
| 44 |
- options => {d => 1, e => 2}
|
|
| 45 |
- ) |
|
| 46 |
- ->filters( |
|
| 47 |
- f => 3 |
|
| 48 |
- ) |
|
| 49 |
- ->bind_filter('f')
|
|
| 50 |
- ->fetch_filter('g')
|
|
| 51 |
- ->dbh('e')
|
|
| 52 |
- }); |
|
| 43 |
+ my $prototype = __PACKAGE__->prototype; |
|
| 44 |
+ |
|
| 45 |
+ $prototype |
|
| 46 |
+ ->connect_info( |
|
| 47 |
+ user => 'a', |
|
| 48 |
+ password => 'b', |
|
| 49 |
+ data_source => 'c', |
|
| 50 |
+ options => {d => 1, e => 2}
|
|
| 51 |
+ ) |
|
| 52 |
+ ->filters( |
|
| 53 |
+ f => 3 |
|
| 54 |
+ ) |
|
| 55 |
+ ->bind_filter('f')
|
|
| 56 |
+ ->fetch_filter('g')
|
|
| 57 |
+ ->dbh('e')
|
|
| 58 |
+ ->result_class('DBI::Custom::Result')
|
|
| 59 |
+ ->sql_template($sql_tmpl1) |
|
| 60 |
+ ->valid_connect_info({p => 1})
|
|
| 61 |
+ ; |
|
| 53 | 62 |
} |
| 54 | 63 |
{
|
| 55 | 64 |
my $dbi = DBI::Custom::T1->new( |
| ... | ... |
@@ -64,11 +73,16 @@ use Scalar::Util qw/blessed/; |
| 64 | 73 |
}, |
| 65 | 74 |
bind_filter => 'fo', |
| 66 | 75 |
fetch_filter => 'go', |
| 67 |
- result_class => 'ho' |
|
| 76 |
+ result_class => 'ho', |
|
| 77 |
+ sql_template => $sql_tmpl1, |
|
| 78 |
+ valid_connect_info => {io => 1}
|
|
| 68 | 79 |
); |
| 69 |
- |
|
| 80 |
+ my $sql_tmpl = delete $dbi->{sql_template};
|
|
| 81 |
+ is($sql_tmpl->upper_case, 0); |
|
| 70 | 82 |
is_deeply($dbi,{connect_info => {user => 'ao', password => 'bo', data_source => 'co', options => {do => 10, eo => 20}}
|
| 71 |
- ,filters => {fo => 30}, bind_filter => 'fo', fetch_filter => 'go', result_class => 'ho'}, 'new arguments');
|
|
| 83 |
+ ,filters => {fo => 30}, bind_filter => 'fo', fetch_filter => 'go', result_class => 'ho',
|
|
| 84 |
+ ,valid_connect_info => {io => 1}
|
|
| 85 |
+ }, 'new arguments'); |
|
| 72 | 86 |
|
| 73 | 87 |
isa_ok($dbi, 'DBI::Custom::T1'); |
| 74 | 88 |
} |
| ... | ... |
@@ -76,8 +90,10 @@ use Scalar::Util qw/blessed/; |
| 76 | 90 |
{
|
| 77 | 91 |
my $dbi = DBI::Custom::T1->new; |
| 78 | 92 |
|
| 93 |
+ my $sql_tmpl = delete $dbi->{sql_template};
|
|
| 79 | 94 |
is_deeply($dbi,{connect_info => {user => 'a', password => 'b', data_source => 'c', options => {d => 1, e => 2}},
|
| 80 |
- filters => {f => 3}, bind_filter => 'f', fetch_filter => 'g', result_class => 'DBI::Custom::Result'}, 'new custom class');
|
|
| 95 |
+ filters => {f => 3}, bind_filter => 'f', fetch_filter => 'g', result_class => 'DBI::Custom::Result',
|
|
| 96 |
+ valid_connect_info => {p => 1}}, 'new custom class');
|
|
| 81 | 97 |
|
| 82 | 98 |
isa_ok($dbi, 'DBI::Custom::T1'); |
| 83 | 99 |
|
| ... | ... |
@@ -91,8 +107,11 @@ use Scalar::Util qw/blessed/; |
| 91 | 107 |
{
|
| 92 | 108 |
my $dbi = DBI::Custom::T1_2->new; |
| 93 | 109 |
|
| 110 |
+ my $sql_tmpl = delete $dbi->{sql_template};
|
|
| 111 |
+ is($sql_tmpl->upper_case, 0); |
|
| 94 | 112 |
is_deeply($dbi,{connect_info => {user => 'a', password => 'b', data_source => 'c', options => {d => 1, e => 2}},
|
| 95 |
- filters => {f => 3}, bind_filter => 'f', fetch_filter => 'g', result_class => 'DBI::Custom::Result'}, 'new custom class inherit');
|
|
| 113 |
+ filters => {f => 3}, bind_filter => 'f', fetch_filter => 'g', result_class => 'DBI::Custom::Result',
|
|
| 114 |
+ valid_connect_info => {p => 1}}, 'new custom class inherit');
|
|
| 96 | 115 |
|
| 97 | 116 |
isa_ok($dbi, 'DBI::Custom::T1_2'); |
| 98 | 117 |
} |
| ... | ... |
@@ -101,33 +120,35 @@ use Scalar::Util qw/blessed/; |
| 101 | 120 |
package DBI::Custom::T1_3; |
| 102 | 121 |
use base 'DBI::Custom::T1'; |
| 103 | 122 |
|
| 104 |
- __PACKAGE__->initialize_class(sub {
|
|
| 105 |
- my $class = shift; |
|
| 123 |
+ my $prototype = __PACKAGE__->prototype; |
|
| 106 | 124 |
|
| 107 |
- $class |
|
| 108 |
- ->connect_info( |
|
| 109 |
- user => 'ao', |
|
| 110 |
- password => 'bo', |
|
| 111 |
- data_source => 'co', |
|
| 112 |
- options => {do => 10, eo => 20}
|
|
| 113 |
- ) |
|
| 114 |
- ->filters( |
|
| 115 |
- fo => 30 |
|
| 116 |
- ) |
|
| 117 |
- ->bind_filter('fo')
|
|
| 118 |
- ->fetch_filter('go')
|
|
| 119 |
- ->dbh('eo')
|
|
| 120 |
- ->result_class('ho');
|
|
| 121 |
- |
|
| 122 |
- }); |
|
| 123 |
- |
|
| 125 |
+ $prototype |
|
| 126 |
+ ->connect_info( |
|
| 127 |
+ user => 'ao', |
|
| 128 |
+ password => 'bo', |
|
| 129 |
+ data_source => 'co', |
|
| 130 |
+ options => {do => 10, eo => 20}
|
|
| 131 |
+ ) |
|
| 132 |
+ ->filters( |
|
| 133 |
+ fo => 30 |
|
| 134 |
+ ) |
|
| 135 |
+ ->bind_filter('fo')
|
|
| 136 |
+ ->fetch_filter('go')
|
|
| 137 |
+ ->dbh('eo')
|
|
| 138 |
+ ->result_class('ho')
|
|
| 139 |
+ ->sql_template($sql_tmpl2) |
|
| 140 |
+ ->valid_connect_info({p => 3})
|
|
| 141 |
+ ; |
|
| 124 | 142 |
} |
| 125 | 143 |
|
| 126 | 144 |
{
|
| 127 | 145 |
my $dbi = DBI::Custom::T1_3->new; |
| 128 | 146 |
|
| 147 |
+ my $sql_tmpl = delete $dbi->{sql_template};
|
|
| 148 |
+ is($sql_tmpl->upper_case, 1); |
|
| 129 | 149 |
is_deeply($dbi,{connect_info => {user => 'ao', password => 'bo', data_source => 'co', options => {do => 10, eo => 20}},
|
| 130 |
- filters => {fo => 30}, bind_filter => 'fo', fetch_filter => 'go', result_class => 'ho'}, 'new custom class');
|
|
| 150 |
+ filters => {fo => 30}, bind_filter => 'fo', fetch_filter => 'go', result_class => 'ho',
|
|
| 151 |
+ valid_connect_info => {p => 3}}, 'new custom class');
|
|
| 131 | 152 |
|
| 132 | 153 |
isa_ok($dbi, 'DBI::Custom::T1_3'); |
| 133 | 154 |
} |
| ... | ... |
@@ -146,11 +167,16 @@ use Scalar::Util qw/blessed/; |
| 146 | 167 |
bind_filter => 'f', |
| 147 | 168 |
fetch_filter => 'g', |
| 148 | 169 |
dbh => 'e', |
| 149 |
- result_class => 'h' |
|
| 170 |
+ result_class => 'h', |
|
| 171 |
+ sql_template => $sql_tmpl3, |
|
| 172 |
+ valid_connect_info => {p => 4}
|
|
| 150 | 173 |
); |
| 151 | 174 |
|
| 175 |
+ my $sql_tmpl = delete $dbi->{sql_template};
|
|
| 176 |
+ is($sql_tmpl->upper_case, 2); |
|
| 152 | 177 |
is_deeply($dbi,{connect_info => {user => 'a', password => 'b', data_source => 'c', options => {d => 1, e => 2}},
|
| 153 |
- filters => {f => 3}, bind_filter => 'f', fetch_filter => 'g', dbh => 'e', result_class => 'h'}, 'new');
|
|
| 178 |
+ filters => {f => 3}, bind_filter => 'f', fetch_filter => 'g', dbh => 'e', result_class => 'h',
|
|
| 179 |
+ valid_connect_info => {p => 4}}, 'new');
|
|
| 154 | 180 |
|
| 155 | 181 |
isa_ok($dbi, 'DBI::Custom'); |
| 156 | 182 |
} |