| ... | ... |
@@ -7,35 +7,35 @@ use Carp 'croak'; |
| 7 | 7 |
use DBI; |
| 8 | 8 |
|
| 9 | 9 |
# Model |
| 10 |
-sub model : ClassAttr { auto_build => \&_inherit_model }
|
|
| 10 |
+sub prototype : ClassAttr { auto_build => \&_inherit_prototype }
|
|
| 11 | 11 |
|
| 12 |
-# Inherit super class model |
|
| 13 |
-sub _inherit_model {
|
|
| 12 |
+# Inherit super class prototype |
|
| 13 |
+sub _inherit_prototype {
|
|
| 14 | 14 |
my $class = shift; |
| 15 | 15 |
my $super = do {
|
| 16 | 16 |
no strict 'refs'; |
| 17 | 17 |
${"${class}::ISA"}[0];
|
| 18 | 18 |
}; |
| 19 |
- my $model = eval{$super->can('model')}
|
|
| 20 |
- ? $super->model->clone |
|
| 19 |
+ my $prototype = eval{$super->can('prototype')}
|
|
| 20 |
+ ? $super->prototype->clone |
|
| 21 | 21 |
: $class->Object::Simple::new; |
| 22 | 22 |
|
| 23 |
- $class->model($model); |
|
| 23 |
+ $class->prototype($prototype); |
|
| 24 | 24 |
} |
| 25 | 25 |
|
| 26 | 26 |
# New |
| 27 | 27 |
sub new {
|
| 28 | 28 |
my $self = shift->Object::Simple::new(@_); |
| 29 | 29 |
my $class = ref $self; |
| 30 |
- return bless {%{$class->model->clone}, %{$self}}, $class;
|
|
| 30 |
+ return bless {%{$class->prototype->clone}, %{$self}}, $class;
|
|
| 31 | 31 |
} |
| 32 | 32 |
|
| 33 |
-# Initialize modle |
|
| 34 |
-sub initialize_model {
|
|
| 33 |
+# Initialize class |
|
| 34 |
+sub initialize_class {
|
|
| 35 | 35 |
my ($class, $callback) = @_; |
| 36 | 36 |
|
| 37 |
- # Callback to initialize model |
|
| 38 |
- $callback->($class->model); |
|
| 37 |
+ # Callback to initialize prototype |
|
| 38 |
+ $callback->($class->prototype); |
|
| 39 | 39 |
} |
| 40 | 40 |
|
| 41 | 41 |
# Clone |
| ... | ... |
@@ -60,7 +60,7 @@ sub add_filter { shift->filters(@_) }
|
| 60 | 60 |
|
| 61 | 61 |
sub result_class : Attr { auto_build => sub { shift->result_class('DBI::Custom::Result') }}
|
| 62 | 62 |
sub dbh : Attr {}
|
| 63 |
-sub sql_template : Attr { auto_build => sub { shift->sql_template(DBI::Custom::SQLTemplate->new) } }
|
|
| 63 |
+sub sql_template : Attr { auto_build => sub { shift->sql_template(DBI::Custom::SQL::Template->new) } }
|
|
| 64 | 64 |
|
| 65 | 65 |
# Auto commit |
| 66 | 66 |
sub auto_commit {
|
| ... | ... |
@@ -232,9 +232,11 @@ Object::Simple->build_class; |
| 232 | 232 |
package DBI::Custom::Result; |
| 233 | 233 |
use Object::Simple; |
| 234 | 234 |
|
| 235 |
+# Attributes |
|
| 235 | 236 |
sub sth : Attr {}
|
| 236 | 237 |
sub fetch_filter : Attr {}
|
| 237 | 238 |
|
| 239 |
+ |
|
| 238 | 240 |
# Fetch (array) |
| 239 | 241 |
sub fetch {
|
| 240 | 242 |
my ($self, $type) = @_; |
| ... | ... |
@@ -252,7 +254,8 @@ sub fetch {
|
| 252 | 254 |
my $keys = $sth->{NAME_lc};
|
| 253 | 255 |
my $types = $sth->{TYPE};
|
| 254 | 256 |
for (my $i = 0; $i < @$keys; $i++) {
|
| 255 |
- $row->[$i] = $fetch_filter->($keys->[$i], $row->[$i], $types->[$i], $sth, $i); |
|
| 257 |
+ $row->[$i]= $fetch_filter->($keys->[$i], $row->[$i], $types->[$i], |
|
| 258 |
+ $sth, $i); |
|
| 256 | 259 |
} |
| 257 | 260 |
} |
| 258 | 261 |
return wantarray ? @$row : $row; |
| ... | ... |
@@ -278,9 +281,12 @@ sub fetch_hash {
|
| 278 | 281 |
if ($fetch_filter) {
|
| 279 | 282 |
my $types = $sth->{TYPE};
|
| 280 | 283 |
for (my $i = 0; $i < @$keys; $i++) {
|
| 281 |
- $row_hash->{$keys->[$i]} = $fetch_filter->($keys->[$i], $row->[$i], $types->[$i], $sth, $i);
|
|
| 284 |
+ $row_hash->{$keys->[$i]} = $fetch_filter->($keys->[$i], $row->[$i],
|
|
| 285 |
+ $types->[$i], $sth, $i); |
|
| 282 | 286 |
} |
| 283 | 287 |
} |
| 288 |
+ |
|
| 289 |
+ # No filter |
|
| 284 | 290 |
else {
|
| 285 | 291 |
for (my $i = 0; $i < @$keys; $i++) {
|
| 286 | 292 |
$row_hash->{$keys->[$i]} = $row->[$i];
|
| ... | ... |
@@ -289,28 +295,6 @@ sub fetch_hash {
|
| 289 | 295 |
return wantarray ? %$row_hash : $row_hash; |
| 290 | 296 |
} |
| 291 | 297 |
|
| 292 |
-# Fetch (hash) |
|
| 293 |
-#sub fetch_hash {
|
|
| 294 |
-# my $self = shift; |
|
| 295 |
-# my $sth = $self->sth; |
|
| 296 |
-# my $fetch_filter = $self->fetch_filter; |
|
| 297 |
-# |
|
| 298 |
-# # Fetch |
|
| 299 |
-# my $row = $sth->fetchrow_hashref; |
|
| 300 |
-# |
|
| 301 |
-# # Cannot fetch |
|
| 302 |
-# return unless $row; |
|
| 303 |
-# |
|
| 304 |
-# # Filter |
|
| 305 |
-# if ($fetch_filter) {
|
|
| 306 |
-# foreach my $key (keys %$row) {
|
|
| 307 |
-# $row->{$key} = $fetch_filter->($key, $row->{$key});
|
|
| 308 |
-# } |
|
| 309 |
-# } |
|
| 310 |
-# return wantarray ? %$row : $row; |
|
| 311 |
-#} |
|
| 312 |
- |
|
| 313 |
- |
|
| 314 | 298 |
# Fetch all (array) |
| 315 | 299 |
sub fetch_all {
|
| 316 | 300 |
my $self = shift; |
| ... | ... |
@@ -333,15 +317,20 @@ sub fetch_all_hash {
|
| 333 | 317 |
return wantarray ? @$rows : $rows; |
| 334 | 318 |
} |
| 335 | 319 |
|
| 336 |
-sub err { shift->sth->err }
|
|
| 337 |
-sub errstr { shift->sth->errstr }
|
|
| 338 |
-sub state { shift->sth->state }
|
|
| 320 |
+# Finish |
|
| 339 | 321 |
sub finish { shift->sth->finish }
|
| 340 | 322 |
|
| 323 |
+# Error |
|
| 324 |
+sub error {
|
|
| 325 |
+ my $self = shift; |
|
| 326 |
+ my $sth = $self->sth; |
|
| 327 |
+ wantarray ? ($sth->errstr, $sth->err, $sth->state) : $sth->errstr; |
|
| 328 |
+} |
|
| 329 |
+ |
|
| 341 | 330 |
Object::Simple->build_class; |
| 342 | 331 |
|
| 343 | 332 |
|
| 344 |
-package DBI::Custom::SQLTemplate; |
|
| 333 |
+package DBI::Custom::SQL::Template; |
|
| 345 | 334 |
use Object::Simple; |
| 346 | 335 |
use Carp 'croak'; |
| 347 | 336 |
|
| ... | ... |
@@ -512,9 +501,91 @@ sub build_sql {
|
| 512 | 501 |
return ($sql, @bind_values); |
| 513 | 502 |
} |
| 514 | 503 |
|
| 504 |
+sub tag_processors : Attr {type => 'hash', deref => 1, auto_build => sub {
|
|
| 505 |
+ shift->tag_processors( |
|
| 506 |
+ '=' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 507 |
+ '<>' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 508 |
+ '<' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 509 |
+ '>=' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 510 |
+ '<=' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 511 |
+ 'like' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder, |
|
| 512 |
+ 'in' => \&DBI::Custom::SQL::Template::TagProcessor::expand_place_holder |
|
| 513 |
+ ); |
|
| 514 |
+}} |
|
| 515 |
+ |
|
| 516 |
+sub add_tag_processor {
|
|
| 517 |
+ |
|
| 518 |
+} |
|
| 515 | 519 |
|
| 516 | 520 |
Object::Simple->build_class; |
| 517 | 521 |
|
| 522 |
+ |
|
| 523 |
+package DBI::Custom::SQL::Template::TagProcessor; |
|
| 524 |
+ |
|
| 525 |
+sub expand_place_holder {
|
|
| 526 |
+ my ($tag_name, $args, $values, $bind_filter, $sql_tmpl_obj) = @_; |
|
| 527 |
+ |
|
| 528 |
+ my $key = $args->[0]; |
|
| 529 |
+ |
|
| 530 |
+ my @bind_values; |
|
| 531 |
+ # Filter Value |
|
| 532 |
+ if ($tag_name eq 'in') {
|
|
| 533 |
+ $values->{$key} = [$values->{$key}] unless ref $values->{$key} eq 'ARRAY';
|
|
| 534 |
+ if ($bind_filter) {
|
|
| 535 |
+ for (my $i = 0; $i < @$values; $i++) {
|
|
| 536 |
+ push @bind_values, scalar $bind_filter->($key, $values->{$key}->[$i]);
|
|
| 537 |
+ } |
|
| 538 |
+ } |
|
| 539 |
+ else {
|
|
| 540 |
+ for (my $i = 0; $i < @$values; $i++) {
|
|
| 541 |
+ push @bind_values, $values->{$key}->[$i];
|
|
| 542 |
+ } |
|
| 543 |
+ } |
|
| 544 |
+ } |
|
| 545 |
+ else {
|
|
| 546 |
+ if ($bind_filter) {
|
|
| 547 |
+ push @bind_values, scalar $bind_filter->($key, $values->{$key});
|
|
| 548 |
+ } |
|
| 549 |
+ else {
|
|
| 550 |
+ push @bind_values, $values->{$key};
|
|
| 551 |
+ } |
|
| 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 |
+ $tag_name = uc $tag_name if $sql_tmpl_obj->upper_case; |
|
| 568 |
+ |
|
| 569 |
+ my $expand; |
|
| 570 |
+ if ($tag_name eq '?') {
|
|
| 571 |
+ $expand = '?'; |
|
| 572 |
+ } |
|
| 573 |
+ elsif ($tag_name eq 'in') {
|
|
| 574 |
+ $expand = '(';
|
|
| 575 |
+ for (my $i = 0; $i < @$values; $i++) {
|
|
| 576 |
+ $expand .= '?, '; |
|
| 577 |
+ } |
|
| 578 |
+ $expand =~ s/, $'//; |
|
| 579 |
+ $expand .= ')'; |
|
| 580 |
+ } |
|
| 581 |
+ else {
|
|
| 582 |
+ $expand = "$key $tag_name ?"; |
|
| 583 |
+ } |
|
| 584 |
+ |
|
| 585 |
+ return ($expand, \@bind_values); |
|
| 586 |
+} |
|
| 587 |
+ |
|
| 588 |
+ |
|
| 518 | 589 |
package DBI::Custom; |
| 519 | 590 |
1; |
| 520 | 591 |
|
| ... | ... |
@@ -552,9 +623,9 @@ Version 0.0101 |
| 552 | 623 |
|
| 553 | 624 |
=head2 filters |
| 554 | 625 |
|
| 555 |
-=head2 initialize_model |
|
| 626 |
+=head2 initialize_class |
|
| 556 | 627 |
|
| 557 |
-=head2 model |
|
| 628 |
+=head2 prototype |
|
| 558 | 629 |
|
| 559 | 630 |
=head2 new |
| 560 | 631 |
|
| ... | ... |
@@ -33,7 +33,7 @@ use Scalar::Util qw/blessed/; |
| 33 | 33 |
package DBI::Custom::T1; |
| 34 | 34 |
use base 'DBI::Custom'; |
| 35 | 35 |
|
| 36 |
- __PACKAGE__->initialize_model(sub {
|
|
| 36 |
+ __PACKAGE__->initialize_class(sub {
|
|
| 37 | 37 |
my $model = shift; |
| 38 | 38 |
|
| 39 | 39 |
$model |
| ... | ... |
@@ -101,7 +101,7 @@ use Scalar::Util qw/blessed/; |
| 101 | 101 |
package DBI::Custom::T1_3; |
| 102 | 102 |
use base 'DBI::Custom::T1'; |
| 103 | 103 |
|
| 104 |
- __PACKAGE__->initialize_model(sub {
|
|
| 104 |
+ __PACKAGE__->initialize_class(sub {
|
|
| 105 | 105 |
my $model = shift; |
| 106 | 106 |
|
| 107 | 107 |
$model |