... | ... |
@@ -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 |
} |