Showing 6 changed files with 417 additions and 213 deletions
+5 -1
Changes
... ...
@@ -1,5 +1,9 @@
1
+0.1608
2
+  update document
3
+  renamed DBIx::Custom::QueryBuilder::TagProcessors functions(not backword compatible)
1 4
 0.1607
2
-  renamed build_query to create_query(not backword compatible)
5
+  where argument of select() method can specify array(string, paramters)
6
+  renamed build_query() to create_query()(not backword compatible)
3 7
 0.1606
4 8
   fix testing bug
5 9
 0.1605
+319 -18
lib/DBIx/Custom.pm
... ...
@@ -106,7 +106,7 @@ sub insert {
106 106
     
107 107
     # Templte for insert
108 108
     my $source = "insert into $table {insert "
109
-                   . join(' ', @insert_keys) . '}';
109
+               . join(' ', @insert_keys) . '}';
110 110
     $source .= " $append" if $append;
111 111
     
112 112
     # Execute query
... ...
@@ -254,11 +254,10 @@ sub select {
254 254
     my $tables = $args{table} || [];
255 255
     $tables = [$tables] unless ref $tables eq 'ARRAY';
256 256
     my $columns  = $args{column} || [];
257
-    my $where    = $args{where} || {};
257
+    my $where    = $args{where};
258 258
     my $relation = $args{relation};
259 259
     my $append   = $args{append};
260 260
     my $filter   = $args{filter};
261
-    my $param    = $args{param} || {};
262 261
     
263 262
     # SQL template for select statement
264 263
     my $source = 'select ';
... ...
@@ -282,18 +281,26 @@ sub select {
282 281
     $source =~ s/, $/ /;
283 282
     
284 283
     # Where clause
285
-    my @where_keys = keys %$where;
286
-    if (@where_keys) {
287
-        $source .= 'where ';
288
-        foreach my $where_key (@where_keys) {
284
+    my $param;
285
+    if (ref $where eq 'HASH') {
286
+        $param = $where;
287
+        $source .= 'where (';
288
+        foreach my $where_key (keys %$where) {
289 289
             $source .= "{= $where_key} and ";
290 290
         }
291
+        $source =~ s/ and $//;
292
+        $source .= ') ';
293
+    }
294
+    elsif (ref $where eq 'ARRAY') {
295
+        my$where_str = $where->[0] || '';
296
+        $param = $where->[1];
297
+        
298
+        $source .= "where ($where_str) ";
291 299
     }
292
-    $source =~ s/ and $//;
293 300
     
294 301
     # Relation
295 302
     if ($relation) {
296
-        $source .= @where_keys ? "and " : "where ";
303
+        $source .= $where ? "and " : "where ";
297 304
         foreach my $rkey (keys %$relation) {
298 305
             $source .= "$rkey = " . $relation->{$rkey} . " and ";
299 306
         }
... ...
@@ -304,8 +311,8 @@ sub select {
304 311
     $source .= " $append" if $append;
305 312
     
306 313
     # Execute query
307
-    my $result = $self->execute($source, param  => $where, 
308
-                                           filter => $filter);
314
+    my $result = $self->execute($source, param  => $param, 
315
+                                         filter => $filter);
309 316
     
310 317
     return $result;
311 318
 }
... ...
@@ -345,7 +352,7 @@ sub create_query {
345 352
     
346 353
     # Prepare statement handle
347 354
     my $sth = eval {$self->dbh->prepare($query->{sql})};
348
-    croak $@ if $@;
355
+    croak qq{$@ SQL: "$query->{sql}"} if $@;
349 356
     
350 357
     # Set statement handle
351 358
     $query->sth($sth);
... ...
@@ -450,7 +457,7 @@ DBIx::Custom - DBI interface, having hash parameter binding and filtering system
450 457
 
451 458
 =cut
452 459
 
453
-our $VERSION = '0.1606';
460
+our $VERSION = '0.1608';
454 461
 
455 462
 =head1 STABILITY
456 463
 
... ...
@@ -573,9 +580,7 @@ so all people learing database system know it.
573 580
 If you know SQL statement,
574 581
 you learn a little thing about L<DBIx::Custom> to do your works.
575 582
 
576
-=head2 2. Basic usage
577
-
578
-=head3 connect to the database
583
+=head2 1. Connect to the database
579 584
 
580 585
 C<connect()> method create a new L<DBIx::Custom>
581 586
 object and connect to the database.
... ...
@@ -584,17 +589,313 @@ object and connect to the database.
584 589
     my $dbi = DBIx::Custom->connect(data_source => "dbi:mysql:database=books",
585 590
                                     user => 'ken', password => '!LFKD%$&');
586 591
 
587
-=head3 Suger methods
592
+If database is SQLite, use L<DBIx::Custom::SQLite>. you connect database easy way.
593
+
594
+    use DBIx::Custom::SQLite;
595
+    my $dbi = DBIx::Custom->connect(database => 'books');
596
+    
597
+If database is  MySQL, use L<DBIx::Costm::MySQL>.
598
+
599
+    use DBIx::Custom::MySQL;
600
+    my $dbi = DBIx::Custom->connect(database => 'books',
601
+                                    user => 'ken', password => '!LFKD%$&');
602
+
603
+=head2 2. Suger methods
588 604
 
589 605
 L<DBIx::Custom> has suger methods, such as C<insert()>, C<update()>,
590 606
 C<delete()> and C<select()>. If you want to do simple works,
591 607
 You don't have to create SQL statement.
592 608
 
593
-B<Execute insert statement:>
609
+=head3 insert()
610
+
611
+    $dbi->insert(table  => 'books',
612
+                 param  => {title => 'perl', author => 'Ken'});
613
+
614
+The following SQL is executed.
615
+
616
+    insert into (title, author) values (?, ?)
617
+
618
+The values of C<title> and C<author> is embedded into placeholders.
619
+
620
+C<append> and C<filter> argument can be specified if you need.
621
+
622
+=head3 update()
623
+
624
+    $dbi->update(table  => 'books', 
625
+                 param  => {title => 'aaa', author => 'Ken'}, 
626
+                 where  => {id => 5});
627
+
628
+The following SQL is executed.
629
+
630
+    update books set title = ?, author = ?;
631
+
632
+The values of C<title> and C<author> is embedded into placeholders.
633
+
634
+If you want to update all rows, use C<update_all()> method instead.
635
+
636
+C<append> and C<filter> argument can be specified if you need.
637
+
638
+=head3 delete()
639
+
640
+    $dbi->delete(table  => 'books',
641
+                 where  => {author => 'Ken'});
642
+
643
+The following SQL is executed.
644
+
645
+    delete from books where id = ?;
646
+
647
+The value of C<id> is embedded into a placehodler.
648
+
649
+C<append> and C<filter> argument can be specified if you need.
650
+
651
+If you want to delete all rows, use C<delete_all()> method instead.
652
+
653
+=head3 select()
654
+
655
+Specify only table:
656
+
657
+    my $result = $dbi->select(table => 'books');
658
+
659
+The following SQL is executed.
660
+
661
+    select * from books;
662
+
663
+the result of C<select()> method is L<DBIx::Custom::Result> object.
664
+use C<fetch()> method to fetch a row.
665
+
666
+    while (my $row = $result->fetch) {
667
+        my $title  = $row->[0];
668
+        my $author = $row->[1];
669
+    }
670
+
671
+L<DBIx::Custom::Result> has various methods to fetch row.
672
+See "3. Result of select statement".
673
+
674
+Specify C<column> and C<where> arguments:
675
+
676
+    my $result = $dbi->select(
677
+        table  => 'books',
678
+        column => [qw/author title/],
679
+        where  => {author => 'Ken'});
680
+
681
+The following SQL is executed.
682
+
683
+    select author, title from books where author = ?;
684
+
685
+the value of C<author> is embdded into placeholder.
686
+
687
+If C<relation> argument is specifed, you can join tables.
688
+
689
+    my $result = $dbi->select(
690
+        table    => ['books', 'rental'],
691
+        column   => ['books.name as book_name']
692
+        relation => {'books.id' => 'rental.book_id'}
693
+    );
694
+
695
+The following SQL is executed.
696
+
697
+    select books.name as book_name from books
698
+    where books.id = rental.book_id;
699
+
700
+C<append> argument add a string to the end of SQL statement.
701
+It is useful to add "order by" or "limit" cluase.
702
+
703
+    # Select, more complex
704
+    my $result = $dbi->select(
705
+        table  => 'books',
706
+        where  => {author => 'Ken'},
707
+        append => 'order by price limit 5',
708
+    );
709
+
710
+The following SQL is executed.
711
+
712
+    select * books where author = ? order by price limit 5;
713
+
714
+C<filter> argument can be specified if you need.
715
+
716
+=head2 3. Result of select statement
717
+
718
+C<select> method reurn L<DBIx::Custom::Result> object.
719
+Using various methods, you can fetch row.
720
+
721
+Fetch row into array.
722
+    
723
+    while (my $row = $result->fetch) {
724
+        my $author = $row->[0];
725
+        my $title  = $row->[1];
726
+        
727
+    }
728
+
729
+Fetch only a first row into array.
594 730
 
731
+    my $row = $result->fetch_first;
595 732
 
733
+Fetch multiple rows into array of array.
596 734
 
735
+    while (my $rows = $result->fetch_multi(5)) {
736
+        my $first_author  = $rows->[0][0];
737
+        my $first_title   = $rows->[0][1];
738
+        my $second_author = $rows->[1][0];
739
+        my $second_value  = $rows->[1][1];
740
+    
741
+    }
742
+    
743
+Fetch all rows into array of array.
744
+
745
+    my $rows = $result->fetch_all;
746
+
747
+Fetch row into hash.
748
+
749
+    # Fetch a row into hash
750
+    while (my $row = $result->fetch_hash) {
751
+        my $title  = $row->{title};
752
+        my $author = $row->{author};
753
+        
754
+    }
755
+
756
+Fetch only a first row into hash
757
+
758
+    my $row = $result->fetch_hash_first;
759
+    
760
+Fetch multiple rows into array of hash
761
+
762
+    while (my $rows = $result->fetch_hash_multi(5)) {
763
+        my $first_title   = $rows->[0]{title};
764
+        my $first_author  = $rows->[0]{author};
765
+        my $second_title  = $rows->[1]{title};
766
+        my $second_author = $rows->[1]{author};
767
+    
768
+    }
769
+    
770
+Fetch all rows into array of hash
771
+
772
+    my $rows = $result->fetch_hash_all;
773
+
774
+If you want to access row statement handle of L<DBI>, use sth() attribute.
775
+
776
+    my $sth = $result->sth;
777
+
778
+=head2 4. Hash parameter binding
779
+
780
+L<DBIx::Custom> provides hash parameter binding.
781
+
782
+At frist, I show normal way of parameter binding.
783
+
784
+    use DBI;
785
+    my $dbh = DBI->connect(...);
786
+    my $sth = $dbh->prepare(
787
+        "select * from books where author = ? and title like ?;"
788
+    );
789
+    $sth->execute('Ken', '%Perl%');
790
+
791
+This is very good way because database system enable SQL caching,
792
+and parameter is quoted automatically.
793
+
794
+L<DBIx::Custom>hash parameter binding system improve normal parameter binding to
795
+specify hash parameter.
796
+
797
+    my $result = $dbi->execute(
798
+        "select * from books where {= author} and {like title};"
799
+        param => {author => 'Ken', title => '%Perl%'}
800
+    );
801
+
802
+This is same as the normal way, execpt that the parameter is hash.
803
+{= author} is called C<tag>. tag is expand to placeholder internally.
804
+
805
+    select * from books where {= author} and {like title}
806
+      -> select * from books where author = ? and title like ?;
807
+
808
+See L<DBIx::Custom::QueryBuilder> to know all tags.
809
+
810
+=head2 5. Filtering
811
+
812
+Usually, Perl string is kept as internal string.
813
+If you want to save the string to database, You must encode the string.
814
+Filtering system help you to convert a data to another data
815
+when you save to the data and get the data form database.
816
+
817
+If you want to register filter, use register_filter() method.
818
+
819
+    $dbi->register_filter(
820
+        to_upper_case => sub {
821
+            my $value = shift;
822
+            return uc $value;
823
+        }
824
+    );
825
+
826
+C<encode_utf8> and C<decode_utf8> filter is registerd by default.
827
+
828
+You can specify these filters to C<filter> argument of C<execute()> method.
597 829
 
830
+    my $result = $dbi->execute(
831
+        "select * from books where {= author} and {like title};"
832
+        param => {author => 'Ken', title => '%Perl%'});
833
+        filter => {author => 'to_upper_case, title => 'encode_utf8'}
834
+    );
835
+
836
+you can also specify filter in suger methods, such as select(), update(), update_all,
837
+delete(), delete_all(), select().
838
+
839
+    $dbi->insert(table  => 'books',
840
+                 param  => {title => 'perl', author => 'Ken'},
841
+                 filter => {title => 'encode_utf8'});
842
+
843
+    my $result = $dbi->select(
844
+        table  => 'books',
845
+        column => [qw/author title/],
846
+        where  => {author => 'Ken'},
847
+        append => 'order by id limit 1',
848
+        filter => {title => 'encode_utf8'}
849
+    );
850
+
851
+Filter work to each parmeter, but you prepare default filter for all parameters.
852
+you can use C<default_bind_filter()> attribute.
853
+
854
+    $dbi->default_bind_filter('encode_utf8');
855
+
856
+C<filter()> argument overwrites the filter specified by C<default_bind_filter()>.
857
+    
858
+    $dbi->default_bind_filter('encode_utf8');
859
+    $dbi->insert(
860
+        table  => 'books',
861
+        param  => {title => 'perl', author => 'Ken', price => 1000},
862
+        filter => {author => 'to_upper_case', price => undef}
863
+    );
864
+
865
+This is same as the following one.
866
+
867
+    $dbi->insert(
868
+        table  => 'books',
869
+        param  => {title => 'perl', author => 'Ken', price => 1000},
870
+        filter => {title => 'encode_uft8' author => 'to_upper_case'}
871
+    );
872
+
873
+You can also specify filter when the row is fetching. This is reverse of bindig filter.
874
+
875
+    my $result = $dbi->select(table => 'books');
876
+    $result->filter({title => 'decode_utf8', author => 'to_upper_case'});
877
+
878
+you can specify C<default_fetch_filter()>.
879
+
880
+    $dbi->default_fetch_filter('decode_utf8');
881
+
882
+C<DBIx::Custom::Result::filter> overwrites the filter specified
883
+by C<default_fetch_filter()>
884
+
885
+    $dbi->default_fetch_filter('decode_utf8');
886
+    my $result = $dbi->select(
887
+        table => 'books',
888
+        columns => ['title', 'author', 'price']
889
+    );
890
+    $result->filter({author => 'to_upper_case', price => undef});
891
+
892
+This is same as the following one.
893
+
894
+    my $result = $dbi->select(
895
+        table => 'books',
896
+        columns => ['title', 'author', 'price']
897
+    );
898
+    $result->filter({title => 'decode_utf8', author => 'to_upper_case'});
598 899
 
599 900
 =head1 ATTRIBUTES
600 901
 
+67 -17
lib/DBIx/Custom/QueryBuilder.pm
... ...
@@ -11,17 +11,17 @@ use DBIx::Custom::QueryBuilder::TagProcessors;
11 11
 
12 12
 __PACKAGE__->dual_attr('tag_processors', default => sub { {} }, inherit => 'hash_copy');
13 13
 __PACKAGE__->register_tag_processor(
14
-    '?'      => \&DBIx::Custom::QueryBuilder::TagProcessors::placeholder,
15
-    '='      => \&DBIx::Custom::QueryBuilder::TagProcessors::equal,
16
-    '<>'     => \&DBIx::Custom::QueryBuilder::TagProcessors::not_equal,
17
-    '>'      => \&DBIx::Custom::QueryBuilder::TagProcessors::greater_than,
18
-    '<'      => \&DBIx::Custom::QueryBuilder::TagProcessors::lower_than,
19
-    '>='     => \&DBIx::Custom::QueryBuilder::TagProcessors::greater_than_equal,
20
-    '<='     => \&DBIx::Custom::QueryBuilder::TagProcessors::lower_than_equal,
21
-    'like'   => \&DBIx::Custom::QueryBuilder::TagProcessors::like,
22
-    'in'     => \&DBIx::Custom::QueryBuilder::TagProcessors::in,
23
-    'insert' => \&DBIx::Custom::QueryBuilder::TagProcessors::insert,
24
-    'update' => \&DBIx::Custom::QueryBuilder::TagProcessors::update
14
+    '?'      => \&DBIx::Custom::QueryBuilder::TagProcessors::expand_placeholder_tag,
15
+    '='      => \&DBIx::Custom::QueryBuilder::TagProcessors::expand_equal_tag,
16
+    '<>'     => \&DBIx::Custom::QueryBuilder::TagProcessors::expand_not_equal_tag,
17
+    '>'      => \&DBIx::Custom::QueryBuilder::TagProcessors::expand_greater_than_tag,
18
+    '<'      => \&DBIx::Custom::QueryBuilder::TagProcessors::expand_lower_than_tag,
19
+    '>='     => \&DBIx::Custom::QueryBuilder::TagProcessors::expand_greater_than_equal_tag,
20
+    '<='     => \&DBIx::Custom::QueryBuilder::TagProcessors::expand_lower_than_equal_tag,
21
+    'like'   => \&DBIx::Custom::QueryBuilder::TagProcessors::expand_like_tag,
22
+    'in'     => \&DBIx::Custom::QueryBuilder::TagProcessors::expand_in_tag,
23
+    'insert' => \&DBIx::Custom::QueryBuilder::TagProcessors::expand_insert_tag,
24
+    'update' => \&DBIx::Custom::QueryBuilder::TagProcessors::expand_update_tag
25 25
 );
26 26
 
27 27
 __PACKAGE__->attr(tag_start => '{');
... ...
@@ -267,19 +267,69 @@ See also L<DBIx::Custom::QueryBuilder::TagProcessors> to know tag processor.
267 267
 =head1 Tags
268 268
 
269 269
 The following tags is available.
270
-    
271
-    [Tags]           [Replaced]
270
+
271
+=head2 C<?>
272
+
273
+Placeholder tag.
274
+
272 275
     {? NAME}    ->   ?
276
+
277
+=head2 C<=>
278
+
279
+Equal tag.
280
+
273 281
     {= NAME}    ->   NAME = ?
282
+
283
+=head2 C<E<lt>E<gt>>
284
+
285
+Not equal tag.
286
+
274 287
     {<> NAME}   ->   NAME <> ?
275
-    
288
+
289
+=head2 C<E<lt>>
290
+
291
+Lower than tag
292
+
276 293
     {< NAME}    ->   NAME < ?
294
+
295
+=head2 C<E<gt>>
296
+
297
+Greater than tag
298
+
277 299
     {> NAME}    ->   NAME > ?
300
+
301
+=head2 C<E<gt>=>
302
+
303
+Greater than or equal tag
304
+
278 305
     {>= NAME}   ->   NAME >= ?
306
+
307
+=head2 C<E<lt>=>
308
+
309
+Lower than or equal tag
310
+
279 311
     {<= NAME}   ->   NAME <= ?
280
-    
281
-    {like NAME}       ->   NAME like ?
312
+
313
+=head2 C<like>
314
+
315
+Like tag
316
+
317
+    {like NAME}   ->   NAME like ?
318
+
319
+=head2 C<in>
320
+
321
+In tag.
322
+
282 323
     {in NAME COUNT}   ->   NAME in [?, ?, ..]
283
-    
324
+
325
+=head2 C<insert>
326
+
327
+Insert tag.
328
+
284 329
     {insert NAME1 NAME2}   ->   (NAME1, NAME2) values (?, ?)
330
+
331
+=head2 C<update>
332
+
333
+Updata tag.
334
+
285 335
     {update NAME1 NAME2}   ->   set NAME1 = ?, NAME2 = ?
+23 -23
lib/DBIx/Custom/QueryBuilder/TagProcessors.pm
... ...
@@ -5,7 +5,7 @@ use warnings;
5 5
 
6 6
 use Carp 'croak';
7 7
 
8
-sub _basic {
8
+sub _expand_basic_tag {
9 9
     my ($name, $column) = @_;
10 10
     
11 11
     # Check arguments
... ...
@@ -15,15 +15,15 @@ sub _basic {
15 15
     return ["$column $name ?", [$column]];
16 16
 }
17 17
 
18
-sub equal              { _basic('=',    @_) }
19
-sub not_equal          { _basic('<>',   @_) }
20
-sub greater_than       { _basic('>',    @_) }
21
-sub lower_than         { _basic('<',    @_) }
22
-sub greater_than_equal { _basic('>=',   @_) }
23
-sub lower_than_equal   { _basic('<=',   @_) }
24
-sub like               { _basic('like', @_) }
18
+sub expand_equal_tag              { _expand_basic_tag('=',    @_) }
19
+sub expand_not_equal_tag          { _expand_basic_tag('<>',   @_) }
20
+sub expand_greater_than_tag       { _expand_basic_tag('>',    @_) }
21
+sub expand_lower_than_tag         { _expand_basic_tag('<',    @_) }
22
+sub expand_greater_than_equal_tag { _expand_basic_tag('>=',   @_) }
23
+sub expand_lower_than_equal_tag   { _expand_basic_tag('<=',   @_) }
24
+sub expand_like_tag               { _expand_basic_tag('like', @_) }
25 25
 
26
-sub placeholder {
26
+sub expand_placeholder_tag {
27 27
     my $column = shift;
28 28
     
29 29
     # Check arguments
... ...
@@ -33,7 +33,7 @@ sub placeholder {
33 33
     return ['?', [$column]];
34 34
 }
35 35
 
36
-sub in {
36
+sub expand_in_tag {
37 37
     my ($column, $count) = @_;
38 38
     
39 39
     # Check arguments
... ...
@@ -55,7 +55,7 @@ sub in {
55 55
     return [$s, $columns];
56 56
 }
57 57
 
58
-sub insert {
58
+sub expand_insert_tag {
59 59
     my @columns = @_;
60 60
     
61 61
     # Part of insert statement
... ...
@@ -71,7 +71,7 @@ sub insert {
71 71
     return [$s, \@columns];
72 72
 }
73 73
 
74
-sub update {
74
+sub expand_update_tag {
75 75
     my @columns = @_;
76 76
     
77 77
     # Part of update statement
... ...
@@ -112,48 +112,48 @@ same as the count of column names.
112 112
         return [$s, $columns];
113 113
     }
114 114
 
115
-=head2 C<placeholder>
115
+=head2 C<expand_placeholder_tag>
116 116
 
117 117
     ('NAME')  ->  ['?', ['NAME']]
118 118
 
119
-=head2 C<equal>
119
+=head2 C<expand_equal_tag>
120 120
 
121 121
     ('NAME')  ->  ['NAME = ?', ['NAME']]
122 122
 
123
-=head2 C<not_equal>
123
+=head2 C<expand_not_equal_tag>
124 124
 
125 125
     ('NAME')  ->  ['NAME <> ?', ['NAME']]
126 126
 
127
-=head2 C<greater_than>
127
+=head2 C<expand_greater_than_tag>
128 128
 
129 129
     ('NAME')  ->  ['NAME > ?', ['NAME']]
130 130
 
131
-=head2 C<lower_than>
131
+=head2 C<expand_lower_than_tag>
132 132
 
133 133
     ('NAME')  ->  ['NAME < ?', ['NAME']]
134 134
 
135
-=head2 C<greater_than_equal>
135
+=head2 C<expand_greater_than_equal_tag>
136 136
 
137 137
     ('NAME')  ->  ['NAME >= ?', ['NAME']]
138 138
 
139
-=head2 C<lower_than_equal>
139
+=head2 C<expand_lower_than_equal_tag>
140 140
 
141 141
     ('NAME')  ->  ['NAME <= ?', ['NAME']]
142 142
 
143
-=head2 C<like>
143
+=head2 C<expand_like_tag>
144 144
 
145 145
     ('NAME')  ->  ['NAME like ?', ['NAME']]
146 146
 
147
-=head2 C<in>
147
+=head2 C<expand_in_tag>
148 148
 
149 149
     ('NAME', 3)  -> ['NAME in (?, ?, ?)', ['NAME', 'NAME', 'NAME']]
150 150
 
151
-=head2 C<insert>
151
+=head2 C<expand_insert_tag>
152 152
 
153 153
     ('NAME1', 'NAME2')
154 154
       ->  ['(NAME1, NAME2) values (?, ?, ?)', ['NAME1', 'NAME2']]
155 155
 
156
-=head2 C<update>
156
+=head2 C<expand_update_tag>
157 157
 
158 158
     ('NAME1', 'NAME2')
159 159
       ->  ['set NAME1 = ?, NAME2 = ?', ['NAME1', 'NAME2']]
+3
t/dbix-custom-core-sqlite.t
... ...
@@ -353,6 +353,9 @@ is_deeply($rows, [{key1 => 1}, {key1 => 3}], "$test : table and columns and wher
353 353
 $rows = $dbi->select(table => 'table1', where => {key1 => 1})->fetch_hash_all;
354 354
 is_deeply($rows, [{key1 => 1, key2 => 2}], "$test : table and columns and where key");
355 355
 
356
+$rows = $dbi->select(table => 'table1', where => ['{= key1} and {= key2}', {key1 => 1, key2 => 2}])->fetch_hash_all;
357
+is_deeply($rows, [{key1 => 1, key2 => 2}], "$test : table and columns and where string");
358
+
356 359
 $rows = $dbi->select(table => 'table1', column => ['key1'], where => {key1 => 3})->fetch_hash_all;
357 360
 is_deeply($rows, [{key1 => 3}], "$test : table and columns and where key");
358 361
 
-154
t/dbix-custom-sql-template.t
... ...
@@ -1,154 +0,0 @@
1
-use strict;
2
-use warnings;
3
-
4
-use Test::More 'no_plan';
5
-
6
-use DBIx::Custom::SQLTemplate;
7
-
8
-# Function for test name
9
-my $test;
10
-sub test{
11
-    $test = shift;
12
-}
13
-
14
-# Variable for test
15
-my $datas;
16
-my $sql_tmpl;
17
-my $query;
18
-my $ret_val;
19
-
20
-test "Various template pattern";
21
-$datas = [
22
-    # Basic tests
23
-    {   name            => 'placeholder basic',
24
-        tmpl            => "a {?  k1} b {=  k2} {<> k3} {>  k4} {<  k5} {>= k6} {<= k7} {like k8}", ,
25
-        sql_expected    => "a ? b k2 = ? k3 <> ? k4 > ? k5 < ? k6 >= ? k7 <= ? k8 like ?;",
26
-        columns_expected   => [qw/k1 k2 k3 k4 k5 k6 k7 k8/]
27
-    },
28
-    {
29
-        name            => 'placeholder in',
30
-        tmpl            => "{in k1 3};",
31
-        sql_expected    => "k1 in (?, ?, ?);",
32
-        columns_expected   => [qw/k1 k1 k1/]
33
-    },
34
-    
35
-    # Table name
36
-    {
37
-        name            => 'placeholder with table name',
38
-        tmpl            => "{= a.k1} {= a.k2}",
39
-        sql_expected    => "a.k1 = ? a.k2 = ?;",
40
-        columns_expected  => [qw/a.k1 a.k2/]
41
-    },
42
-    {   
43
-        name            => 'placeholder in with table name',
44
-        tmpl            => "{in a.k1 2} {in b.k2 2}",
45
-        sql_expected    => "a.k1 in (?, ?) b.k2 in (?, ?);",
46
-        columns_expected  => [qw/a.k1 a.k1 b.k2 b.k2/]
47
-    },
48
-    {
49
-        name            => 'not contain tag',
50
-        tmpl            => "aaa",
51
-        sql_expected    => "aaa;",
52
-        columns_expected  => [],
53
-    }
54
-];
55
-
56
-for (my $i = 0; $i < @$datas; $i++) {
57
-    my $data = $datas->[$i];
58
-    my $sql_tmpl = DBIx::Custom::SQLTemplate->new;
59
-    my $query = $sql_tmpl->create_query($data->{tmpl});
60
-    is($query->{sql}, $data->{sql_expected}, "$test : $data->{name} : sql");
61
-    is_deeply($query->{columns}, $data->{columns_expected}, "$test : $data->{name} : columns");
62
-}
63
-
64
-
65
-test 'Original tag processor';
66
-$sql_tmpl = DBIx::Custom::SQLTemplate->new;
67
-
68
-$ret_val = $sql_tmpl->register_tag_processor(
69
-    p => sub {
70
-        my ($tag_name, $args) = @_;
71
-        
72
-        my $expand    = "$tag_name ? $args->[0] $args->[1]";
73
-        my $columns = [2];
74
-        return ($expand, $columns);
75
-    }
76
-);
77
-
78
-$query = $sql_tmpl->create_query("{p a b}");
79
-is($query->{sql}, "p ? a b;", "$test : register_tag_processor sql");
80
-is_deeply($query->{columns}, [2], "$test : register_tag_processor columns");
81
-isa_ok($ret_val, 'DBIx::Custom::SQLTemplate');
82
-
83
-
84
-test "Tag processor error case";
85
-$sql_tmpl = DBIx::Custom::SQLTemplate->new;
86
-
87
-
88
-eval{$sql_tmpl->create_query("{a }")};
89
-like($@, qr/Tag '{a }' in SQL template is not exist/, "$test : tag_processor not exist");
90
-
91
-$sql_tmpl->register_tag_processor({
92
-    q => 'string'
93
-});
94
-
95
-eval{$sql_tmpl->create_query("{q}", {})};
96
-like($@, qr/Tag processor 'q' must be code reference/, "$test : tag_processor not code ref");
97
-
98
-$sql_tmpl->register_tag_processor({
99
-   r => sub {} 
100
-});
101
-
102
-eval{$sql_tmpl->create_query("{r}")};
103
-like($@, qr/\QTag processor 'r' must return (\E\$expand\Q, \E\$columns\Q)/, "$test : tag processor return noting");
104
-
105
-$sql_tmpl->register_tag_processor({
106
-   s => sub { return ("a", "")} 
107
-});
108
-
109
-eval{$sql_tmpl->create_query("{s}")};
110
-like($@, qr/\QTag processor 's' must return (\E\$expand\Q, \E\$columns\Q)/, "$test : tag processor return not array columns");
111
-
112
-$sql_tmpl->register_tag_processor(
113
-    t => sub {return ("a", [])}
114
-);
115
-
116
-eval{$sql_tmpl->create_query("{t ???}")};
117
-like($@, qr/Tag '{t }' arguments cannot contain '?'/, "$test : cannot contain '?' in tag argument");
118
-
119
-
120
-test 'General error case';
121
-$sql_tmpl = DBIx::Custom::SQLTemplate->new;
122
-$sql_tmpl->register_tag_processor(
123
-    a => sub {
124
-        return ("? ? ?", [[],[]]);
125
-    }
126
-);
127
-eval{$sql_tmpl->create_query("{a}")};
128
-like($@, qr/Placeholder count in SQL created by tag processor 'a' must be same as key informations count/, "$test placeholder count is invalid");
129
-
130
-
131
-test 'Default tag processor Error case';
132
-eval{$sql_tmpl->create_query("{= }")};
133
-like($@, qr/You must be pass key as argument to tag '{= }'/, "$test : basic '=' : key not exist");
134
-
135
-eval{$sql_tmpl->create_query("{in }")};
136
-like($@, qr/You must be pass key as first argument of tag '{in }'/, "$test : in : key not exist");
137
-
138
-eval{$sql_tmpl->create_query("{in a}")};
139
-like($@, qr/\QYou must be pass value count as second argument of tag '{in }'\E\n\QUsage: {in \E\$key\Q \E\$count\Q}/,
140
-     "$test : in : key not exist");
141
-
142
-eval{$sql_tmpl->create_query("{in a r}")};
143
-like($@, qr/\QYou must be pass value count as second argument of tag '{in }'\E\n\QUsage: {in \E\$key\Q \E\$count\Q}/,
144
-     "$test : in : key not exist");
145
-
146
-
147
-test 'Clone';
148
-$sql_tmpl = DBIx::Custom::SQLTemplate->new;
149
-$sql_tmpl
150
-  ->tag_start('[')
151
-  ->tag_end(']')
152
-  ->tag_syntax('syntax')
153
-  ->tag_processors({a => 1, b => 2});
154
-