Showing 2 changed files with 115 additions and 44 deletions
+113 -42
lib/DBI/Custom.pm
... ...
@@ -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
 
+2 -2
t/01-core.t
... ...
@@ -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