Showing 10 changed files with 332 additions and 277 deletions
+6
Changes
... ...
@@ -1,3 +1,9 @@
1
+0.1684
2
+    - update_param_tag is DEPRECATED! use update_param instead.
3
+    - insert_param_tag is DEPRECATED! use insert_param instead.
4
+    - assing_param_tag is DEPRECATED! use assign_param instead.
5
+    - Tag system such as {? title}, {= title} is DEPRECATED!
6
+      and added paramter system such as :title.
1 7
 0.1683
2 8
     - data_source is DEPRECATED! It is renamed to dsn
3 9
 0.1682
+75 -92
lib/DBIx/Custom.pm
... ...
@@ -152,8 +152,7 @@ sub apply_filter {
152 152
     return $self;
153 153
 }
154 154
 
155
-
156
-sub assign_tag {
155
+sub assign_param {
157 156
     my ($self, $param) = @_;
158 157
     
159 158
     # Create set tag
... ...
@@ -163,9 +162,9 @@ sub assign_tag {
163 162
     foreach my $column (keys %$param) {
164 163
         croak qq{"$column" is not safety column name } . _subname
165 164
           unless $column =~ /^[$safety\.]+$/;
166
-        my $column = "$q$column$q";
167
-        $column =~ s/\./$q.$q/;
168
-        push @params, "$column = {? $column}";
165
+        my $column_quote = "$q$column$q";
166
+        $column_quote =~ s/\./$q.$q/;
167
+        push @params, "$column_quote = :$column";
169 168
     }
170 169
     my $tag = join(', ', @params);
171 170
     
... ...
@@ -595,20 +594,9 @@ sub insert {
595 594
     # Reserved word quote
596 595
     my $q = $self->reserved_word_quote;
597 596
     
598
-    # Columns
599
-    my @columns;
600
-    my $safety = $self->safety_character;
601
-    foreach my $column (keys %$param) {
602
-        croak qq{"$column" is not safety column name } . _subname
603
-          unless $column =~ /^[$safety\.]+$/;
604
-          $column = "$q$column$q";
605
-          $column =~ s/\./$q.$q/;
606
-        push @columns, $column;
607
-    }
608
-    
609 597
     # Insert statement
610 598
     my @sql;
611
-    push @sql, "insert into $q$table$q {insert_param ". join(' ', @columns) . '}';
599
+    push @sql, "insert into $q$table$q " . $self->insert_param($param);
612 600
     push @sql, $append if $append;
613 601
     my $sql = join (' ', @sql);
614 602
     
... ...
@@ -649,7 +637,7 @@ sub insert_at {
649 637
     return $self->insert(param => $param, %args);
650 638
 }
651 639
 
652
-sub insert_param_tag {
640
+sub insert_param {
653 641
     my ($self, $param) = @_;
654 642
     
655 643
     # Create insert parameter tag
... ...
@@ -660,10 +648,10 @@ sub insert_param_tag {
660 648
     foreach my $column (keys %$param) {
661 649
         croak qq{"$column" is not safety column name } . _subname
662 650
           unless $column =~ /^[$safety\.]+$/;
663
-        $column = "$q$column$q";
664
-        $column =~ s/\./$q.$q/;
665
-        push @columns, $column;
666
-        push @placeholders, "{? $column}";
651
+        my $column_quote = "$q$column$q";
652
+        $column_quote =~ s/\./$q.$q/;
653
+        push @columns, $column_quote;
654
+        push @placeholders, ":$column";
667 655
     }
668 656
     
669 657
     return '(' . join(', ', @columns) . ') ' . 'values ' .
... ...
@@ -1030,21 +1018,9 @@ sub update {
1030 1018
         croak qq{"$name" is wrong option } . _subname
1031 1019
           unless $UPDATE_ARGS{$name};
1032 1020
     }
1033
-    
1034
-    # Columns
1035
-    my @columns;
1036
-    my $safety = $self->safety_character;
1037
-    my $q = $self->reserved_word_quote;
1038
-    foreach my $column (keys %$param) {
1039
-        croak qq{"$column" is not safety column name } . _subname
1040
-          unless $column =~ /^[$safety\.]+$/;
1041
-          $column = "$q$column$q";
1042
-          $column =~ s/\./$q.$q/;
1043
-        push @columns, "$column";
1044
-    }
1045 1021
         
1046 1022
     # Update clause
1047
-    my $update_clause = '{update_param ' . join(' ', @columns) . '}';
1023
+    my $update_clause = $self->update_param($param);
1048 1024
 
1049 1025
     # Where
1050 1026
     my $where_clause = '';
... ...
@@ -1066,6 +1042,7 @@ sub update {
1066 1042
     
1067 1043
     # Update statement
1068 1044
     my @sql;
1045
+    my $q = $self->reserved_word_quote;
1069 1046
     push @sql, "update $q$table$q $update_clause $where_clause";
1070 1047
     push @sql, $append if $append;
1071 1048
     
... ...
@@ -1112,11 +1089,11 @@ sub update_at {
1112 1089
     return $self->update(where => $where_param, %args);
1113 1090
 }
1114 1091
 
1115
-sub update_param_tag {
1092
+sub update_param {
1116 1093
     my ($self, $param, $opt) = @_;
1117 1094
     
1118 1095
     # Create update parameter tag
1119
-    my $tag = $self->assign_tag($param);
1096
+    my $tag = $self->assign_param($param);
1120 1097
     $tag = "set $tag" unless $opt->{no_set};
1121 1098
 
1122 1099
     return $tag;
... ...
@@ -1340,9 +1317,9 @@ sub _where_to_obj {
1340 1317
         my $clause = ['and'];
1341 1318
         my $q = $self->reserved_word_quote;
1342 1319
         foreach my $column (keys %$where) {
1343
-            $column = "$q$column$q";
1344
-            $column =~ s/\./$q.$q/;
1345
-            push @$clause, "{= $column}" for keys %$where;
1320
+            my $column_quote = "$q$column$q";
1321
+            $column_quote =~ s/\./$q.$q/;
1322
+            push @$clause, "$column_quote = :$column" for keys %$where;
1346 1323
         }
1347 1324
         $obj = $self->where(clause => $clause, param => $where);
1348 1325
     }
... ...
@@ -1427,10 +1404,10 @@ sub default_fetch_filter {
1427 1404
 }
1428 1405
 
1429 1406
 # DEPRECATED!
1430
-sub insert_param {
1431
-    warn "insert_param is renamed to insert_param_tag."
1432
-       . " insert_param is DEPRECATED!";
1433
-    return shift->insert_param_tag(@_);
1407
+sub insert_param_tag {
1408
+    warn "insert_param_tag is DEPRECATED! " .
1409
+         "use insert_param instead!";
1410
+    return shift->insert_param(@_);
1434 1411
 }
1435 1412
 
1436 1413
 # DEPRECATED!
... ...
@@ -1439,10 +1416,10 @@ sub register_tag_processor {
1439 1416
 }
1440 1417
 
1441 1418
 # DEPRECATED!
1442
-sub update_param {
1443
-    warn "update_param is renamed to update_param_tag."
1444
-       . " update_param is DEPRECATED!";
1445
-    return shift->update_param_tag(@_);
1419
+sub update_param_tag {
1420
+    warn "update_param is DEPRECATED! " .
1421
+         "use update_param instead";
1422
+    return shift->update_param(@_);
1446 1423
 }
1447 1424
 # DEPRECATED!
1448 1425
 sub _push_relation {
... ...
@@ -1547,7 +1524,7 @@ DBIx::Custom - Useful database access, respecting SQL!
1547 1524
     
1548 1525
     # Execute SQL with parameter.
1549 1526
     $dbi->execute(
1550
-        "select id from book where {= author} and {like title}",
1527
+        "select id from book where author = :author and title like :title",
1551 1528
         param  => {author => 'ken', title => '%Perl%'}
1552 1529
     );
1553 1530
     
... ...
@@ -1758,15 +1735,15 @@ You can set multiple filters at once.
1758 1735
         }
1759 1736
     );
1760 1737
 
1761
-=head2 C<assign_tag> EXPERIMENTAL
1738
+=head2 C<assign_param> EXPERIMENTAL
1762 1739
 
1763
-    my $assign_tag = $dbi->assign_tag({title => 'a', age => 2});
1740
+    my $assign_param = $dbi->assign_param({title => 'a', age => 2});
1764 1741
 
1765 1742
 Create assign tag.
1766 1743
 
1767
-    title = {? title}, author = {? author}
1744
+    title = :title, author = :author
1768 1745
 
1769
-This is equal to C<update_param_tag> exept that set is not added.
1746
+This is equal to C<update_param> exept that set is not added.
1770 1747
 
1771 1748
 =head2 C<connect>
1772 1749
 
... ...
@@ -1848,7 +1825,7 @@ column name and column information.
1848 1825
 =head2 C<execute>
1849 1826
 
1850 1827
     my $result = $dbi->execute(
1851
-        "select * from book where {= title} and {like author}",
1828
+        "select * from book where title = :title and author like :author",
1852 1829
         param => {title => 'Perl', author => '%Ken%'}
1853 1830
     );
1854 1831
 
... ...
@@ -1943,14 +1920,14 @@ or array refrence, which contains where clause and paramter.
1943 1920
     
1944 1921
     # DBIx::Custom::Where object
1945 1922
     my $where = $dbi->where(
1946
-        clause => ['and', '{= author}', '{like title}'],
1923
+        clause => ['and', 'author = :author', 'title like :title'],
1947 1924
         param  => {author => 'Ken', title => '%Perl%'}
1948 1925
     );
1949 1926
     $dbi->delete(where => $where);
1950 1927
 
1951 1928
     # String(with where_param option)
1952 1929
     $dbi->delete(
1953
-        where => '{like title}',
1930
+        where => 'title like :title',
1954 1931
         where_param => {title => '%Perl%'}
1955 1932
     );
1956 1933
     
... ...
@@ -2190,13 +2167,13 @@ Place holders are set to 5 and 'Perl'.
2190 2167
 
2191 2168
 =back
2192 2169
 
2193
-=head2 C<insert_param_tag>
2170
+=head2 C<insert_param>
2194 2171
 
2195
-    my $insert_param_tag = $dbi->insert_param_tag({title => 'a', age => 2});
2172
+    my $insert_param = $dbi->insert_param({title => 'a', age => 2});
2196 2173
 
2197
-Create insert parameter tag.
2174
+Create insert parameters.
2198 2175
 
2199
-    (title, author) values ({? title}, {? author});
2176
+    (title, author) values (title = :title, age = :age);
2200 2177
 
2201 2178
 =head2 C<include_model>
2202 2179
 
... ...
@@ -2331,7 +2308,7 @@ This is used by C<clause> of L<DBIx::Custom::Where> .
2331 2308
     
2332 2309
 Register filters, used by C<filter> option of many methods.
2333 2310
 
2334
-=head2 C<register_tag>
2311
+=head2 C<register_tag> DEPRECATED!
2335 2312
 
2336 2313
     $dbi->register_tag(
2337 2314
         update => sub {
... ...
@@ -2412,14 +2389,14 @@ or array refrence, which contains where clause and paramter.
2412 2389
     
2413 2390
     # DBIx::Custom::Where object
2414 2391
     my $where = $dbi->where(
2415
-        clause => ['and', '{= author}', '{like title}'],
2392
+        clause => ['and', 'author = :author', 'title like :title'],
2416 2393
         param  => {author => 'Ken', title => '%Perl%'}
2417 2394
     );
2418 2395
     $dbi->select(where => $where);
2419 2396
 
2420 2397
     # String(with where_param option)
2421 2398
     $dbi->select(
2422
-        where => '{like title}',
2399
+        where => 'title like :title',
2423 2400
         where_param => {title => '%Perl%'}
2424 2401
     );
2425 2402
     
... ...
@@ -2462,7 +2439,7 @@ Parameter shown before where clause.
2462 2439
         table => 'table1',
2463 2440
         column => 'table1.key1 as table1_key1, key2, key3',
2464 2441
         where   => {'table1.key2' => 3},
2465
-        join  => ['inner join (select * from table2 where {= table2.key3})' . 
2442
+        join  => ['inner join (select * from table2 where table2.key3 = :table2.key3)' . 
2466 2443
                   ' as table2 on table1.key1 = table2.key1'],
2467 2444
         param => {'table2.key3' => 5}
2468 2445
     );
... ...
@@ -2622,7 +2599,7 @@ or array refrence.
2622 2599
     
2623 2600
     # DBIx::Custom::Where object
2624 2601
     my $where = $dbi->where(
2625
-        clause => ['and', '{= author}', '{like title}'],
2602
+        clause => ['and', 'author = :author', 'title like :title'],
2626 2603
         param  => {author => 'Ken', title => '%Perl%'}
2627 2604
     );
2628 2605
     $dbi->update(where => $where);
... ...
@@ -2739,28 +2716,20 @@ Place holders are set to 'Perl' and 5.
2739 2716
 
2740 2717
 =back
2741 2718
 
2742
-=head2 C<update_param_tag>
2719
+=head2 C<update_param>
2743 2720
 
2744
-    my $update_param_tag = $dbi->update_param_tag({title => 'a', age => 2});
2721
+    my $update_param = $dbi->update_param({title => 'a', age => 2});
2745 2722
 
2746 2723
 Create update parameter tag.
2747 2724
 
2748
-    set title = {? title}, author = {? author}
2725
+    set title = :title, author = :author
2749 2726
 
2750
-You can create tag without 'set '
2751
-by C<no_set> option.
2752
-
2753
-    my $update_param_tag = $dbi->update_param_tag(
2754
-        {title => 'a', age => 2}
2755
-        {no_set => 1}
2756
-    );
2757
-
2758
-    title = {? title}, author = {? author}
2727
+C<no_set> option is DEPRECATED! use C<assing_param> instead.
2759 2728
 
2760 2729
 =head2 C<where>
2761 2730
 
2762 2731
     my $where = $dbi->where(
2763
-        clause => ['and', '{= title}', '{= author}'],
2732
+        clause => ['and', 'title = :title', 'author = :author'],
2764 2733
         param => {title => 'Perl', author => 'Ken'}
2765 2734
     );
2766 2735
 
... ...
@@ -2773,71 +2742,87 @@ Create a new L<DBIx::Custom::Where> object.
2773 2742
 Setup all model objects.
2774 2743
 C<columns> of model object is automatically set, parsing database information.
2775 2744
 
2776
-=head1 Tags
2745
+=head1 Parameter
2746
+
2747
+Parameter start at ':'. This is replaced to place holoder
2748
+
2749
+    $dbi->execute(
2750
+        "select * from book where title = :title and author = :author"
2751
+        param => {title => 'Perl', author => 'Ken'}
2752
+    );
2753
+
2754
+    "select * from book where title = ? and author = ?"
2755
+
2756
+=head1 Tags DEPRECATED!
2757
+
2758
+B<Tag> system is DEPRECATED! use parameter system :name instead.
2759
+Parameter is simple and readable.
2760
+
2761
+Note that you can't use both tag and paramter at same time.
2777 2762
 
2778 2763
 The following tags is available.
2779 2764
 
2780
-=head2 C<?>
2765
+=head2 C<?> DEPRECATED!
2781 2766
 
2782 2767
 Placeholder tag.
2783 2768
 
2784 2769
     {? NAME}    ->   ?
2785 2770
 
2786
-=head2 C<=>
2771
+=head2 C<=> DEPRECATED!
2787 2772
 
2788 2773
 Equal tag.
2789 2774
 
2790 2775
     {= NAME}    ->   NAME = ?
2791 2776
 
2792
-=head2 C<E<lt>E<gt>>
2777
+=head2 C<E<lt>E<gt>> DEPRECATED!
2793 2778
 
2794 2779
 Not equal tag.
2795 2780
 
2796 2781
     {<> NAME}   ->   NAME <> ?
2797 2782
 
2798
-=head2 C<E<lt>>
2783
+=head2 C<E<lt>> DEPRECATED!
2799 2784
 
2800 2785
 Lower than tag
2801 2786
 
2802 2787
     {< NAME}    ->   NAME < ?
2803 2788
 
2804
-=head2 C<E<gt>>
2789
+=head2 C<E<gt>> DEPRECATED!
2805 2790
 
2806 2791
 Greater than tag
2807 2792
 
2808 2793
     {> NAME}    ->   NAME > ?
2809 2794
 
2810
-=head2 C<E<gt>=>
2795
+=head2 C<E<gt>=> DEPRECATED!
2811 2796
 
2812 2797
 Greater than or equal tag
2813 2798
 
2814 2799
     {>= NAME}   ->   NAME >= ?
2815 2800
 
2816
-=head2 C<E<lt>=>
2801
+=head2 C<E<lt>=> DEPRECATED!
2817 2802
 
2818 2803
 Lower than or equal tag
2819 2804
 
2820 2805
     {<= NAME}   ->   NAME <= ?
2821 2806
 
2822
-=head2 C<like>
2807
+=head2 C<like> DEPRECATED!
2823 2808
 
2824 2809
 Like tag
2825 2810
 
2826 2811
     {like NAME}   ->   NAME like ?
2827 2812
 
2828
-=head2 C<in>
2813
+=head2 C<in> DEPRECATED!
2829 2814
 
2830 2815
 In tag.
2831 2816
 
2832 2817
     {in NAME COUNT}   ->   NAME in [?, ?, ..]
2833 2818
 
2834
-=head2 C<insert_param>
2819
+=head2 C<insert_param> DEPRECATED!
2835 2820
 
2836 2821
 Insert parameter tag.
2837 2822
 
2838 2823
     {insert_param NAME1 NAME2}   ->   (NAME1, NAME2) values (?, ?)
2839 2824
 
2840
-=head2 C<update_param>
2825
+=head2 C<update_param> DEPRECATED!
2841 2826
 
2842 2827
 Updata parameter tag.
2843 2828
 
... ...
@@ -2879,5 +2864,3 @@ This program is free software; you can redistribute it and/or modify it
2879 2864
 under the same terms as Perl itself.
2880 2865
 
2881 2866
 =cut
2882
-
2883
-
+1 -1
lib/DBIx/Custom/Guide.pod
... ...
@@ -162,7 +162,7 @@ use C<connect()> to connect to database.
162 162
 Return value is L<DBIx::Custom> object.
163 163
 
164 164
     my $dbi = DBIx::Custom->connect(
165
-        dsn => "dbi:mysql:database=bookstore",
165
+        dsn => "dbi:mysql:database=bookshop",
166 166
         user => 'ken',
167 167
         password => '!LFKD%$&',
168 168
         dbi_options => {mysql_enable_utf8 => 1}
+6 -1
lib/DBIx/Custom/Query.pm
... ...
@@ -8,7 +8,12 @@ use base 'Object::Simple';
8 8
 use Carp 'croak';
9 9
 use DBIx::Custom::Util '_subname';
10 10
 
11
-__PACKAGE__->attr([qw/columns sql sth filters tables/]);
11
+__PACKAGE__->attr(
12
+    [qw/sth filters/],
13
+    sql => '',
14
+    tables => sub { [] },
15
+    columns => sub { [] }
16
+);
12 17
 
13 18
 sub filter {
14 19
     my $self = shift;
+165 -153
lib/DBIx/Custom/QueryBuilder.pm
... ...
@@ -13,120 +13,102 @@ use DBIx::Custom::Util '_subname';
13 13
 push @DBIx::Custom::CARP_NOT, __PACKAGE__;
14 14
 push @DBIx::Custom::Where::CARP_NOT, __PACKAGE__;
15 15
 
16
-# Attributes
17
-__PACKAGE__->attr('tags' => sub { {} });
16
+# Parameter regex
17
+our $PARAM_RE = qr/(^|[^\.\w]):([\.\w]+)([^\.\w]|$)/sm;
18 18
 
19 19
 sub build_query {
20
-    my ($self, $source)  = @_;
20
+    my ($self, $source) = @_;
21 21
     
22
-    # Parse
23
-    my $tree = $self->_parse($source);
22
+    my $query;
23
+    
24
+    # Parse tag. tag is DEPRECATED!
25
+    if ($source =~ /\{/ && $source =~ /\}/) {
26
+        $query = $self->_parse_tag($source);
27
+        my $tag_count = delete $query->{tag_count};
28
+        warn qq/Tag system such as {? name} is DEPRECATED! This will be removed after 2017/ .
29
+             qq/use parameter system :name instead/
30
+          if $tag_count;
31
+        my $query2 = $self->_parse_parameter($query->sql);
32
+        $query->sql($query2->sql);
33
+        for (my $i =0; $i < @{$query->columns}; $i++) {
34
+            my $column = $query->columns->[$i];
35
+            if ($column eq 'RESERVED_PARAMETER') {
36
+                my $column2 = shift @{$query2->columns};
37
+                croak ":name syntax is wrong"
38
+                  unless defined $column2;
39
+                $query->columns->[$i] = $column2;
40
+            }
41
+        }
42
+    }
24 43
     
25
-    # Build query
26
-    my $query = $self->_build_query($tree);
44
+    # Parse parameter
45
+    else {
46
+        $query = $self->_parse_parameter($source);
47
+    }
27 48
     
49
+    my $sql = $query->sql;
50
+    $sql .= ';' unless $source =~ /;$/;
51
+    $query->sql($sql);
52
+
53
+    # Check placeholder count
54
+    croak qq{Placeholder count in "$sql" must be same as column count}
55
+        . _subname
56
+      unless $self->_placeholder_count($sql) eq @{$query->columns};
57
+        
28 58
     return $query;
29 59
 }
30 60
 
31
-sub register_tag {
32
-    my $self = shift;
33
-    
34
-    # Merge tag
35
-    my $tags = ref $_[0] eq 'HASH' ? $_[0] : {@_};
36
-    $self->tags({%{$self->tags}, %$tags});
61
+sub _placeholder_count {
62
+    my ($self, $sql) = @_;
37 63
     
38
-    return $self;
64
+    # Count
65
+    $sql ||= '';
66
+    my $count = 0;
67
+    my $pos   = -1;
68
+    while (($pos = index($sql, '?', $pos + 1)) != -1) {
69
+        $count++;
70
+    }
71
+    return $count;
39 72
 }
40 73
 
41
-sub _build_query {
42
-    my ($self, $tree) = @_;
43
-    
44
-    # SQL
45
-    my $sql = '';
46
-    
47
-    # All Columns
48
-    my $all_columns = [];
49
-    
50
-    # Tables
51
-    my $tables = [];
74
+sub _parse_parameter {
75
+    my ($self, $source) = @_;
52 76
     
53
-    # Build SQL 
54
-    foreach my $node (@$tree) {
55
-        
56
-        # Text
57
-        if ($node->{type} eq 'text') { $sql .= $node->{value} }
58
-        
59
-        # Tag
60
-        else {
61
-            
62
-            # Tag name
63
-            my $tag_name = $node->{tag_name};
64
-            
65
-            # Tag arguments
66
-            my $tag_args = $node->{tag_args};
67
-            
68
-            # Table
69
-            if ($tag_name eq 'table') {
70
-                my $table = $tag_args->[0];
71
-                push @$tables, $table;
72
-                $sql .= $table;
73
-                next;
74
-            }
75
-
76
-            # Get tag
77
-            my $tag = $self->tag_processors->{$tag_name}
78
-                             || $self->tags->{$tag_name};
79
-            
80
-            # Tag is not registered
81
-            croak qq{Tag "$tag_name" is not registered } . _subname
82
-              unless $tag;
83
-            
84
-            # Tag not sub reference
85
-            croak qq{Tag "$tag_name" must be sub reference } . _subname
86
-              unless ref $tag eq 'CODE';
87
-            
88
-            # Execute tag
89
-            my $r = $tag->(@$tag_args);
90
-            
91
-            # Check tag return value
92
-            croak qq{Tag "$tag_name" must return [STRING, ARRAY_REFERENCE] }
93
-                . _subname
94
-              unless ref $r eq 'ARRAY' && defined $r->[0] && ref $r->[1] eq 'ARRAY';
95
-            
96
-            # Part of SQL statement and colum names
97
-            my ($part, $columns) = @$r;
98
-            
99
-            # Add columns
100
-            push @$all_columns, @$columns;
101
-            
102
-            # Join part tag to SQL
103
-            $sql .= $part;
104
-        }
77
+    # Get and replace parameters
78
+    my $sql = $source || '';
79
+    my $columns = [];
80
+    while ($source =~ /$PARAM_RE/g) {
81
+        push @$columns, $2;
105 82
     }
83
+    $sql =~ s/$PARAM_RE/$1?$3/g;
106 84
 
107
-    # Check placeholder count
108
-    my $placeholder_count = $self->_placeholder_count($sql);
109
-    my $column_count      = @$all_columns;
110
-    croak qq{Placeholder count in "$sql" must be same as column count $column_count}
111
-        . _subname
112
-      unless $placeholder_count eq @$all_columns;
113
-    
114
-    # Add semicolon
115
-    $sql .= ';' unless $sql =~ /;$/;
116
-    
117
-    # Query
85
+    # Create query
118 86
     my $query = DBIx::Custom::Query->new(
119 87
         sql => $sql,
120
-        columns => $all_columns,
121
-        tables => $tables
88
+        columns => $columns
122 89
     );
123 90
     
124 91
     return $query;
125 92
 }
126 93
 
127
-sub _parse {
128
-    my ($self, $source) = @_;
94
+# DEPRECATED!
95
+__PACKAGE__->attr('tags' => sub { {} });
96
+
97
+# DEPRECATED!
98
+sub register_tag {
99
+    my $self = shift;
129 100
     
101
+    # Merge tag
102
+    my $tags = ref $_[0] eq 'HASH' ? $_[0] : {@_};
103
+    $self->tags({%{$self->tags}, %$tags});
104
+    
105
+    return $self;
106
+}
107
+
108
+# DEPRECATED!
109
+sub _parse_tag {
110
+    my ($self, $source) = @_;
111
+
130 112
     # Source
131 113
     $source ||= '';
132 114
 
... ...
@@ -147,11 +129,17 @@ sub _parse {
147 129
     
148 130
     # Parse
149 131
     my $original = $source;
132
+    my $tag_count = 0;
150 133
     while (defined(my $c = substr($source, $pos, 1))) {
151 134
         
152 135
         # Last
153 136
         last unless length $c;
154 137
         
138
+        # Parameter
139
+        if ($c eq ':' && (substr($source, $pos + 1, 1) || '') =~ /\w/) {
140
+            push @tree, {type => 'param'};;
141
+        }
142
+        
155 143
         # State is text
156 144
         if ($state eq 'text') {
157 145
             
... ...
@@ -240,6 +228,9 @@ sub _parse {
240 228
                     
241 229
                     # Clear
242 230
                     $value = '';
231
+                    
232
+                    # Countup
233
+                    $tag_count++;
243 234
                 }
244 235
             }
245 236
             
... ...
@@ -258,24 +249,90 @@ sub _parse {
258 249
     croak qq{Tag not finished. "$original" } . _subname
259 250
       if $state eq 'tag';
260 251
     
252
+    # Not contains tag
253
+    return DBIx::Custom::Query->new(sql => $source, tag_count => $tag_count)
254
+      if $tag_count == 0;
255
+    
261 256
     # Add rest text
262 257
     push @tree, {type => 'text', value => $value}
263 258
       if $value;
259
+        
260
+    # SQL
261
+    my $sql = '';
264 262
     
265
-    return \@tree;
266
-}
267
-
268
-sub _placeholder_count {
269
-    my ($self, $expand) = @_;
263
+    # All Columns
264
+    my $all_columns = [];
270 265
     
271
-    # Count
272
-    $expand ||= '';
273
-    my $count = 0;
274
-    my $pos   = -1;
275
-    while (($pos = index($expand, '?', $pos + 1)) != -1) {
276
-        $count++;
266
+    # Tables
267
+    my $tables = [];
268
+    
269
+    # Build SQL 
270
+    foreach my $node (@tree) {
271
+        
272
+        # Text
273
+        if ($node->{type} eq 'text') { $sql .= $node->{value} }
274
+        
275
+        # Parameter
276
+        elsif ($node->{type} eq 'param') {
277
+            push @$all_columns, 'RESERVED_PARAMETER';
278
+        }
279
+        # Tag
280
+        else {
281
+            
282
+            # Tag name
283
+            my $tag_name = $node->{tag_name};
284
+            
285
+            # Tag arguments
286
+            my $tag_args = $node->{tag_args};
287
+            
288
+            # Table
289
+            if ($tag_name eq 'table') {
290
+                my $table = $tag_args->[0];
291
+                push @$tables, $table;
292
+                $sql .= $table;
293
+                next;
294
+            }
295
+
296
+            # Get tag
297
+            my $tag = $self->tag_processors->{$tag_name}
298
+                             || $self->tags->{$tag_name};
299
+            
300
+            # Tag is not registered
301
+            croak qq{Tag "$tag_name" is not registered } . _subname
302
+              unless $tag;
303
+            
304
+            # Tag not sub reference
305
+            croak qq{Tag "$tag_name" must be sub reference } . _subname
306
+              unless ref $tag eq 'CODE';
307
+            
308
+            # Execute tag
309
+            my $r = $tag->(@$tag_args);
310
+            
311
+            # Check tag return value
312
+            croak qq{Tag "$tag_name" must return [STRING, ARRAY_REFERENCE] }
313
+                . _subname
314
+              unless ref $r eq 'ARRAY' && defined $r->[0] && ref $r->[1] eq 'ARRAY';
315
+            
316
+            # Part of SQL statement and colum names
317
+            my ($part, $columns) = @$r;
318
+            
319
+            # Add columns
320
+            push @$all_columns, @$columns;
321
+            
322
+            # Join part tag to SQL
323
+            $sql .= $part;
324
+        }
277 325
     }
278
-    return $count;
326
+
327
+    # Query
328
+    my $query = DBIx::Custom::Query->new(
329
+        sql => $sql,
330
+        columns => $all_columns,
331
+        tables => $tables,
332
+        tag_count => $tag_count
333
+    );
334
+    
335
+    return $query;
279 336
 }
280 337
 
281 338
 # DEPRECATED!
... ...
@@ -285,6 +342,8 @@ __PACKAGE__->attr('tag_processors' => sub { {} });
285 342
 sub register_tag_processor {
286 343
     my $self = shift;
287 344
     
345
+    warn "register_tag_processor is DEPRECATED! use register_tag instead";
346
+    
288 347
     # Merge tag
289 348
     my $tag_processors = ref $_[0] eq 'HASH' ? $_[0] : {@_};
290 349
     $self->tag_processors({%{$self->tag_processors}, %{$tag_processors}});
... ...
@@ -302,18 +361,9 @@ DBIx::Custom::QueryBuilder - Query builder
302 361
     
303 362
     my $builder = DBIx::Custom::QueryBuilder->new;
304 363
     my $query = $builder->build_query(
305
-        "select from table {= k1} && {<> k2} || {like k3}"
364
+        "select from table title = :title and author = :author"
306 365
     );
307 366
 
308
-=head1 ATTRIBUTES
309
-
310
-=head2 C<tags>
311
-
312
-    my $tags = $builder->tags;
313
-    $builder = $builder->tags(\%tags);
314
-
315
-Tags.
316
-
317 367
 =head1 METHODS
318 368
 
319 369
 L<DBIx::Custom::QueryBuilder> inherits all methods from L<Object::Simple>
... ...
@@ -324,43 +374,5 @@ and implements the following new ones.
324 374
     my $query = $builder->build_query($source);
325 375
 
326 376
 Create a new L<DBIx::Custom::Query> object from SQL source.
327
-SQL source contains tags, such as {= title}, {like author}.
328
-
329
-C<{> and C<}> is reserved. If you use these charactors,
330
-you must escape them using '\'. Note that '\' is
331
-already perl escaped charactor, so you must write '\\'. 
332
-
333
-    'select * from books \\{ something statement \\}'
334
-
335
-B<Example:>
336
-
337
-SQL source
338
-
339
-      "select * from table where {= title} && {like author} || {<= price}"
340
-
341
-Query
342
-
343
-    {
344
-        sql     => "select * from table where title = ? && author like ? price <= ?;"
345
-        columns => ['title', 'author', 'price']
346
-    }
347
-
348
-=head2 C<register_tag>
349
-
350
-    $builder->register_tag(\%tags);
351
-    $builder->register_tag(%tags);
352
-
353
-Register tag.
354
-
355
-B<Example:>
356
-
357
-    $builder->register_tag(
358
-        '?' => sub {
359
-            my $column = shift;
360
-            
361
-            return ['?', [$column]];
362
-        }
363
-    );
364
-
365
-See also L<DBIx::Custom::Tag> to know tag.
366 377
 
378
+=cut
+5 -1
lib/DBIx/Custom/Tag.pm
... ...
@@ -1,3 +1,4 @@
1
+# DEPRECATED!
1 2
 package DBIx::Custom::Tag;
2 3
 
3 4
 use strict;
... ...
@@ -92,4 +93,7 @@ sub _basic {
92 93
 
93 94
 =head1 NAME
94 95
 
95
-DBIx::Custom::Tag - Tag processor
96
+DBIx::Custom::Tag - DEPRECATED!
97
+
98
+=cut
99
+
+10 -1
lib/DBIx/Custom/Where.pm
... ...
@@ -36,6 +36,14 @@ sub new {
36 36
 sub to_string {
37 37
     my $self = shift;
38 38
     
39
+    # Check if column name is safety character;
40
+    my $safety = $self->safety_character;
41
+    if (ref $self->param eq 'HASH') {
42
+        foreach my $column (keys %{$self->param}) {
43
+            croak qq{"$column" is not safety column name (} . _subname . ")"
44
+              unless $column =~ /^[$safety\.]+$/;
45
+        }
46
+    }
39 47
     # Clause
40 48
     my $clause = $self->clause;
41 49
     $clause = ['and', $clause] unless ref $clause eq 'ARRAY';
... ...
@@ -95,7 +103,7 @@ sub _parse {
95 103
             return $pushed;
96 104
         }
97 105
         elsif (@$columns != 1) {
98
-            croak qq{Each tag contains one column name: tag "$clause" (}
106
+            croak qq{Each part contains one column name: "$clause" (}
99 107
                   . _subname . ")";
100 108
         }
101 109
 
... ...
@@ -181,3 +189,4 @@ If all parameter names is exists.
181 189
 
182 190
 Convert where clause to string correspoinding to param name.
183 191
 
192
+=cut
+57 -25
t/dbix-custom-core-sqlite.t
... ...
@@ -204,6 +204,37 @@ $rows = $result->fetch_hash_all;
204 204
 is_deeply($rows, [{key1 => 1, key2 => 1, key3 => 1, key4 => 1, key5 => 5},
205 205
                   {key1 => 6, key2 => 7, key3 => 8, key4 => 9, key5 => 10}], "basic");
206 206
 
207
+
208
+test 'parameter';
209
+$dbi->execute($DROP_TABLE->{0});
210
+$dbi->execute($CREATE_TABLE->{1});
211
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2, key3 => 3, key4 => 4, key5 => 5});
212
+$dbi->insert(table => 'table1', param => {key1 => 6, key2 => 7, key3 => 8, key4 => 9, key5 => 10});
213
+
214
+$source = "select * from table1 where key1 = :key1 and key2 = :key2";
215
+$result = $dbi->execute($source, param => {key1 => 1, key2 => 2});
216
+$rows = $result->fetch_hash_all;
217
+is_deeply($rows, [{key1 => 1, key2 => 2, key3 => 3, key4 => 4, key5 => 5}]);
218
+
219
+$source = "select * from table1 where key1 = \n:key1\n and key2 = :key2";
220
+$result = $dbi->execute($source, param => {key1 => 1, key2 => 2});
221
+$rows = $result->fetch_hash_all;
222
+is_deeply($rows, [{key1 => 1, key2 => 2, key3 => 3, key4 => 4, key5 => 5}]);
223
+
224
+$source = "select * from table1 where key1 = :key1 or key1 = :key1";
225
+$result = $dbi->execute($source, param => {key1 => [1, 2]});
226
+$rows = $result->fetch_hash_all;
227
+is_deeply($rows, [{key1 => 1, key2 => 2, key3 => 3, key4 => 4, key5 => 5}]);
228
+
229
+$source = "select * from table1 where key1 = :table1.key1 and key2 = :table1.key2";
230
+$result = $dbi->execute(
231
+    $source,
232
+    param => {'table1.key1' => 1, 'table1.key2' => 1},
233
+    filter => {'table1.key2' => sub { $_[0] * 2 }}
234
+);
235
+$rows = $result->fetch_hash_all;
236
+is_deeply($rows, [{key1 => 1, key2 => 2, key3 => 3, key4 => 4, key5 => 5}]);
237
+
207 238
 test 'Error case';
208 239
 eval {DBIx::Custom->connect(dsn => 'dbi:SQLit')};
209 240
 ok($@, "connect error");
... ...
@@ -307,7 +338,7 @@ $dbi = DBIx::Custom->connect($NEW_ARGS->{0});
307 338
 $dbi->execute($CREATE_TABLE->{0});
308 339
 $dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
309 340
 $where = $dbi->where;
310
-$where->clause(['and', '{= key1}', '{= key2}']);
341
+$where->clause(['and', 'key1 = :key1', 'key2 = :key2']);
311 342
 $where->param({key1 => 1, key2 => 2});
312 343
 $dbi->update(table => 'table1', param => {key1 => 3}, where => $where);
313 344
 $result = $dbi->select(table => 'table1');
... ...
@@ -1354,7 +1385,7 @@ $dbi->default_bind_filter(undef);
1354 1385
 ok(!defined $dbi->default_bind_filter);
1355 1386
 $dbi->default_fetch_filter(undef);
1356 1387
 ok(!defined $dbi->default_fetch_filter);
1357
-eval {$dbi->execute('select * from table1 {= author') };
1388
+eval {$dbi->execute('select * from table1 {} {= author') };
1358 1389
 like($@, qr/Tag not finished/);
1359 1390
 
1360 1391
 $dbi = DBIx::Custom->connect($NEW_ARGS->{0});
... ...
@@ -1792,20 +1823,20 @@ $result = $model->select(
1792 1823
 is_deeply($result->fetch_hash_first,
1793 1824
           {key1 => 1, key2 => 2, 'table2__key1' => 1, 'table2__key3' => 3});
1794 1825
 
1795
-test 'update_param_tag';
1826
+test 'update_param';
1796 1827
 $dbi = DBIx::Custom->connect($NEW_ARGS->{0});
1797 1828
 $dbi->execute($CREATE_TABLE->{1});
1798 1829
 $dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2, key3 => 3, key4 => 4, key5 => 5});
1799 1830
 $dbi->insert(table => 'table1', param => {key1 => 6, key2 => 7, key3 => 8, key4 => 9, key5 => 10});
1800 1831
 
1801 1832
 $param = {key2 => 11};
1802
-$update_param = $dbi->update_param_tag($param);
1833
+$update_param = $dbi->update_param($param);
1803 1834
 $sql = <<"EOS";
1804
-update {table table1} $update_param
1835
+update table1 $update_param
1805 1836
 where key1 = 1
1806 1837
 EOS
1807 1838
 $dbi->execute($sql, param => $param);
1808
-$result = $dbi->execute($SELECT_SOURCES->{0});
1839
+$result = $dbi->execute($SELECT_SOURCES->{0}, table => 'table1');
1809 1840
 $rows   = $result->fetch_hash_all;
1810 1841
 is_deeply($rows, [{key1 => 1, key2 => 11, key3 => 3, key4 => 4, key5 => 5},
1811 1842
                   {key1 => 6, key2 => 7,  key3 => 8, key4 => 9, key5 => 10}],
... ...
@@ -1818,13 +1849,13 @@ $dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2, key3 => 3, key4
1818 1849
 $dbi->insert(table => 'table1', param => {key1 => 6, key2 => 7, key3 => 8, key4 => 9, key5 => 10});
1819 1850
 
1820 1851
 $param = {key2 => 11, key3 => 33};
1821
-$update_param = $dbi->update_param_tag($param);
1852
+$update_param = $dbi->update_param($param);
1822 1853
 $sql = <<"EOS";
1823
-update {table table1} $update_param
1854
+update table1 $update_param
1824 1855
 where key1 = 1
1825 1856
 EOS
1826 1857
 $dbi->execute($sql, param => $param);
1827
-$result = $dbi->execute($SELECT_SOURCES->{0});
1858
+$result = $dbi->execute($SELECT_SOURCES->{0}, table => 'table1');
1828 1859
 $rows   = $result->fetch_hash_all;
1829 1860
 is_deeply($rows, [{key1 => 1, key2 => 11, key3 => 33, key4 => 4, key5 => 5},
1830 1861
                   {key1 => 6, key2 => 7,  key3 => 8, key4 => 9, key5 => 10}],
... ...
@@ -1836,37 +1867,36 @@ $dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2, key3 => 3, key4
1836 1867
 $dbi->insert(table => 'table1', param => {key1 => 6, key2 => 7, key3 => 8, key4 => 9, key5 => 10});
1837 1868
 
1838 1869
 $param = {key2 => 11, key3 => 33};
1839
-$update_param = $dbi->update_param_tag($param, {no_set => 1});
1870
+$update_param = $dbi->update_param($param, {no_set => 1});
1840 1871
 $sql = <<"EOS";
1841
-update {table table1} set $update_param
1872
+update table1 set $update_param
1842 1873
 where key1 = 1
1843 1874
 EOS
1844 1875
 $dbi->execute($sql, param => $param);
1845
-$result = $dbi->execute($SELECT_SOURCES->{0});
1876
+$result = $dbi->execute($SELECT_SOURCES->{0}, table => 'table1');
1846 1877
 $rows   = $result->fetch_hash_all;
1847 1878
 is_deeply($rows, [{key1 => 1, key2 => 11, key3 => 33, key4 => 4, key5 => 5},
1848 1879
                   {key1 => 6, key2 => 7,  key3 => 8, key4 => 9, key5 => 10}],
1849 1880
                   "update param no_set");
1850 1881
 
1851 1882
             
1852
-eval { $dbi->update_param_tag({";" => 1}) };
1883
+eval { $dbi->update_param({";" => 1}) };
1853 1884
 like($@, qr/not safety/);
1854 1885
 
1855 1886
 
1856
-test 'set_tag';
1857
-test 'update_param_tag';
1887
+test 'update_param';
1858 1888
 $dbi = DBIx::Custom->connect($NEW_ARGS->{0});
1859 1889
 $dbi->execute($CREATE_TABLE->{1});
1860 1890
 $dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2, key3 => 3, key4 => 4, key5 => 5});
1861 1891
 $dbi->insert(table => 'table1', param => {key1 => 6, key2 => 7, key3 => 8, key4 => 9, key5 => 10});
1862 1892
 
1863 1893
 $param = {key2 => 11};
1864
-$update_param = $dbi->assign_tag($param);
1894
+$update_param = $dbi->assign_param($param);
1865 1895
 $sql = <<"EOS";
1866
-update {table table1} set $update_param
1896
+update table1 set $update_param
1867 1897
 where key1 = 1
1868 1898
 EOS
1869
-$dbi->execute($sql, param => $param);
1899
+$dbi->execute($sql, param => $param, table => 'table1');
1870 1900
 $result = $dbi->execute($SELECT_SOURCES->{0});
1871 1901
 $rows   = $result->fetch_hash_all;
1872 1902
 is_deeply($rows, [{key1 => 1, key2 => 11, key3 => 3, key4 => 4, key5 => 5},
... ...
@@ -1878,11 +1908,11 @@ test 'insert_param';
1878 1908
 $dbi = DBIx::Custom->connect($NEW_ARGS->{0});
1879 1909
 $dbi->execute($CREATE_TABLE->{1});
1880 1910
 $param = {key1 => 1, key2 => 2};
1881
-$insert_param = $dbi->insert_param_tag($param);
1911
+$insert_param = $dbi->insert_param($param);
1882 1912
 $sql = <<"EOS";
1883
-insert into {table table1} $insert_param
1913
+insert into table1 $insert_param
1884 1914
 EOS
1885
-$dbi->execute($sql, param => $param);
1915
+$dbi->execute($sql, param => $param, table => 'table1');
1886 1916
 is($dbi->select(table => 'table1')->fetch_hash_first->{key1}, 1);
1887 1917
 is($dbi->select(table => 'table1')->fetch_hash_first->{key2}, 2);
1888 1918
 
... ...
@@ -1890,15 +1920,15 @@ $dbi = DBIx::Custom->connect($NEW_ARGS->{0});
1890 1920
 $dbi->reserved_word_quote('"');
1891 1921
 $dbi->execute($CREATE_TABLE->{1});
1892 1922
 $param = {key1 => 1, key2 => 2};
1893
-$insert_param = $dbi->insert_param_tag($param);
1923
+$insert_param = $dbi->insert_param($param);
1894 1924
 $sql = <<"EOS";
1895
-insert into {table table1} $insert_param
1925
+insert into table1 $insert_param
1896 1926
 EOS
1897
-$dbi->execute($sql, param => $param);
1927
+$dbi->execute($sql, param => $param, table => 'table1');
1898 1928
 is($dbi->select(table => 'table1')->fetch_hash_first->{key1}, 1);
1899 1929
 is($dbi->select(table => 'table1')->fetch_hash_first->{key2}, 2);
1900 1930
 
1901
-eval { $dbi->insert_param_tag({";" => 1}) };
1931
+eval { $dbi->insert_param({";" => 1}) };
1902 1932
 like($@, qr/not safety/);
1903 1933
 
1904 1934
 
... ...
@@ -2238,3 +2268,5 @@ $dbi->update(
2238 2268
 );
2239 2269
 $rows = $dbi->select(table => 'table1')->fetch_hash_all;
2240 2270
 is_deeply($rows, [{key1 => 5, key2 => 2}]);
2271
+
2272
+=cut
+2
t/dbix-custom-mysql-private.t
... ...
@@ -2,6 +2,8 @@ use Test::More;
2 2
 use strict;
3 3
 use warnings;
4 4
 
5
+$SIG{__WARN__} = sub { warn $_[0] unless $_[0] =~ /DEPRECATED/};
6
+
5 7
 # user password database
6 8
 our ($USER, $PASSWORD, $DATABASE) = connect_info();
7 9
 
+5 -3
t/dbix-custom-querybuilder.t
... ...
@@ -8,6 +8,8 @@ use DBIx::Custom;
8 8
 # Function for test name
9 9
 sub test{ print "# $_[0]\n" }
10 10
 
11
+$SIG{__WARN__} = sub { warn $_[0] unless $_[0] =~ /DEPRECATED/};
12
+
11 13
 # Variable for test
12 14
 my $datas;
13 15
 my $builder;
... ...
@@ -57,7 +59,7 @@ for (my $i = 0; $i < @$datas; $i++) {
57 59
     my $builder = DBIx::Custom->new->query_builder;
58 60
     my $query = $builder->build_query($data->{source});
59 61
     is($query->{sql}, $data->{sql_expected}, "$data->{name} : sql");
60
-    is_deeply($query->{columns}, $data->{columns_expected}, "$data->{name} : columns");
62
+    is_deeply($query->columns, $data->{columns_expected}, "$data->{name} : columns");
61 63
 }
62 64
 
63 65
 
... ...
@@ -123,7 +125,7 @@ $builder->register_tag(
123 125
     }
124 126
 );
125 127
 eval{$builder->build_query("{a}")};
126
-like($@, qr/\QPlaceholder count in "? ? ?" must be same as column count 1/, "placeholder count is invalid");
128
+like($@, qr/\QPlaceholder count/, "placeholder count is invalid");
127 129
 
128 130
 
129 131
 test 'Default tag Error case';
... ...
@@ -166,4 +168,4 @@ $source = "a {= {}";
166 168
 eval{$builder->build_query($source)};
167 169
 like($@, qr/unexpected "{"/, "error : 2");
168 170
 
169
-
171
+=cut