Showing 4 changed files with 53 additions and 79 deletions
+1 -1
Changes
... ...
@@ -1,5 +1,5 @@
1 1
 0.1644
2
-  added experimental build_where method
2
+  changed DBIx::Custom::Where greatly
3 3
 0.1633
4 4
   fixed test
5 5
 0.1632
+2 -1
lib/DBIx/Custom.pm
... ...
@@ -686,7 +686,8 @@ sub update {
686 686
 
687 687
 sub update_all { shift->update(allow_update_all => 1, @_) };
688 688
 
689
-sub where { DBIx::Custom::Where->new(sql_builder => shift->sql_builder) }
689
+sub where { DBIx::Custom::Where->new(
690
+              query_builder => shift->query_builder) }
690 691
 
691 692
 sub _build_binds {
692 693
     my ($self, $params, $columns, $filter) = @_;
+43 -49
lib/DBIx/Custom/Where.pm
... ...
@@ -10,88 +10,82 @@ use overload '""' => sub { shift->to_string }, fallback => 1;
10 10
 
11 11
 use Carp 'croak';
12 12
 
13
-__PACKAGE__->attr(clause => sub { [] });
14
-__PACKAGE__->attr(param => sub { {} });
15
-__PACKAGE__->attr(sql_builder => sub { {} });
13
+__PACKAGE__->attr(
14
+  'query_builder',
15
+  clause => sub { [] },
16
+  param => sub { {} }
17
+);
16 18
 
17 19
 sub to_string {
18
-    my ($self, $param, $clause) = @_;
19
-    
20
-    local $self->{_where}    = '';
21
-    local $self->{_count}    = {};
22
-    local $self->{_op_stack} = [];
23
-    local $self->{_param}    = $param;
20
+    my $self = shift;
24 21
     
22
+    my $clause = $self->clause;
25 23
     $clause = ['and', $clause] unless ref $clause eq 'ARRAY';
24
+    $clause->[0] = 'and' unless @$clause;
25
+
26
+    my $where = [];
27
+    my $count = {};
28
+    $self->_forward($clause, $where, $count, 'and');
29
+
30
+    unshift @$where, 'where' if @$where;
26 31
     
27
-    $self->_forward($clause);
28
-    
29
-    return $self->{_where};
32
+    return join(' ', @$where);
30 33
 }
31 34
 
32
-our %VALID_OPERATIONS = map { $_ => 1 } qw/and or or_repeat/;
35
+our %VALID_OPERATIONS = map { $_ => 1 } qw/and or/;
33 36
 
34 37
 sub _forward {
35
-    my ($self, $clause) = @_;
38
+    my ($self, $clause, $where, $count, $op) = @_;
36 39
     
37 40
     if (ref $clause eq 'ARRAY') {
38
-        $self->{_where} .= '( ';
41
+        push @$where, '(';
39 42
         
40 43
         my $op = $clause->[0] || '';
41 44
         
42 45
         croak qq{"$op" is invalid operation}
43 46
           unless $VALID_OPERATIONS{$op};
44 47
           
45
-        push @{$self->{_op_stack}}, $op;
46
-        
47 48
         for (my $i = 1; $i < @$clause; $i++) {
48
-            $self->_forword($clause->[$i]);
49
+            my $pushed = $self->_forward($clause->[$i], $where, $count, $op);
50
+            push @$where, $op if $pushed;
49 51
         }
50 52
         
51
-        pop @{$self->{_op_stack}};
52
-
53
-        if ($self->{_where} =~ /\( $/) {
54
-            $self->{_where} =~ s/\( $//;
55
-            $self->{_where} .= ' ';
53
+        pop @$where if $where->[-1] eq $op;
54
+        
55
+        if ($where->[-1] eq '(') {
56
+            pop @$where;
57
+            pop @$where;
58
+        }
59
+        else {
60
+            push @$where, ')';
56 61
         }
57
-        $self->{_where} =~ s/ $op $//;
58
-        $self->{_where} .= ' ) ';
59 62
     }
60 63
     else {
61
-        my $op = $self->{_op_stack}->[-1];
62
-        
63
-        my $columns = $self->sql_builder->build_query($clause)->columns;
64 64
         
65
+        # Column
66
+        my $columns = $self->query_builder->build_query($clause)->columns;
65 67
         croak qq{each tag contains one column name: tag "$clause"}
66 68
           unless @$columns == 1;
67
-        
68 69
         my $column = $columns->[0];
69 70
         
70
-        my $ccount = ++$self->{_count}->{$column};
71
-        
72
-        my $param = $self->{_param};
71
+        # Count up
72
+        my $count = ++$count->{$column};
73 73
         
74
+        # Push element
75
+        my $param    = $self->param;
76
+        my $pushed;
74 77
         if (exists $param->{$column}) {
75
-            if ($op eq 'and' || $op eq 'or') {
76
-                if (ref $param->{$column} eq 'ARRAY') {
77
-                    $self->{_where} .= $clause . " $op "
78
-                      if exists $param->{$column}->[$ccount];
79
-                }
80
-                else {
81
-                    $self->{_where} .= $clause . " $op "
82
-                      if $ccount == 1;
83
-                }
78
+            if (ref $param->{$column} eq 'ARRAY') {
79
+                $pushed = 1 if exists $param->{$column}->[$count - 1];
84 80
             }
85
-            elsif ($op eq 'or_repeat') {
86
-                if (ref $param->{$column} eq 'ARRAY') {
87
-                    $self->{_where} .= $clause . " or "
88
-                      for (1 .. @{$param->{$column}});
89
-                }
90
-                else {
91
-                    $self->{_where} .= $clause;
92
-                }
81
+            elsif ($count == 1) {
82
+                $pushed = 1;
93 83
             }
94 84
         }
85
+        
86
+        push @$where, $clause if $pushed;
87
+        
88
+        return $pushed;
95 89
     }
96 90
 }
97 91
 
+7 -28
t/dbix-custom-core-sqlite.t
... ...
@@ -814,16 +814,15 @@ is(ref $query, 'DBIx::Custom::Query');
814 814
 $query = $dbi->select(table => 'table1', where => {key1 => 1, key2 => 2}, query => 1);
815 815
 is(ref $query, 'DBIx::Custom::Query');
816 816
 
817
-__END__
818
-
819 817
 test 'DBIx::Custom::Where';
820 818
 $dbi = DBIx::Custom->connect($NEW_ARGS->{0});
821 819
 $dbi->execute($CREATE_TABLE->{0});
822 820
 $dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
823 821
 $dbi->insert(table => 'table1', param => {key1 => 3, key2 => 4});
824 822
 $where = $dbi->where
825
-             ->clause(key1 => '{= key1}', key2 => '{= key2}')
823
+             ->clause(['and', '{= key1}', '{= key2}'])
826 824
              ->param({key1 => 1});
825
+
827 826
 $result = $dbi->select(
828 827
     table => 'table1',
829 828
     where => $where
... ...
@@ -832,7 +831,7 @@ $row = $result->fetch_hash_all;
832 831
 is_deeply($row, [{key1 => 1, key2 => 2}]);
833 832
 
834 833
 $where = $dbi->where
835
-             ->clause(key1 => '{= key1}', key2 => '{= key2}')
834
+             ->clause(['and', '{= key1}', '{= key2}'])
836 835
              ->param({key1 => 1, key2 => 2});
837 836
 $result = $dbi->select(
838 837
     table => 'table1',
... ...
@@ -842,7 +841,7 @@ $row = $result->fetch_hash_all;
842 841
 is_deeply($row, [{key1 => 1, key2 => 2}]);
843 842
 
844 843
 $where = $dbi->where
845
-             ->clause(key1 => '{= key1}', key2 => '{= key2}')
844
+             ->clause(['and', '{= key1}', '{= key2}'])
846 845
              ->param({});
847 846
 $result = $dbi->select(
848 847
     table => 'table1',
... ...
@@ -852,7 +851,7 @@ $row = $result->fetch_hash_all;
852 851
 is_deeply($row, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}]);
853 852
 
854 853
 $where = $dbi->where
855
-             ->clause(key1 => ['{> key1}', '{< key1}'], key2 => '{= key2}')
854
+             ->clause(['and', ['or', '{> key1}', '{< key1}'], '{= key2}'])
856 855
              ->param({key1 => [0, 3], key2 => 2});
857 856
 $result = $dbi->select(
858 857
     table => 'table1',
... ...
@@ -861,28 +860,6 @@ $result = $dbi->select(
861 860
 $row = $result->fetch_hash_all;
862 861
 is_deeply($row, [{key1 => 1, key2 => 2}]);
863 862
 
864
-$where = $dbi->where
865
-             ->clause(key1 => "{= key1}" )
866
-             ->or_clause(key2 => "{= key2}" )
867
-             ->param({ key1 => 1, key2 => [1, 2]});
868
-$result = $dbi->select(
869
-    table => 'table1',
870
-    where => $where,
871
-);
872
-$row = $result->fetch_hash_all;
873
-is_deeply($row, [{key1 => 1, key2 => 2}]);
874
-
875
-$where = $dbi->where
876
-             ->clause(key1 => "{= key1}" )
877
-             ->or_clause(key2 => "{= key2}" )
878
-             ->param({ key1 => 1, key2 => [2]});
879
-$result = $dbi->select(
880
-    table => 'table1',
881
-    where => $where
882
-);
883
-$row = $result->fetch_hash_all;
884
-is_deeply($row, [{key1 => 1, key2 => 2}]);
885
-
886 863
 $where = $dbi->where;
887 864
 $result = $dbi->select(
888 865
     table => 'table1',
... ...
@@ -891,6 +868,8 @@ $result = $dbi->select(
891 868
 $row = $result->fetch_hash_all;
892 869
 is_deeply($row, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}]);
893 870
 
871
+__END__
872
+
894 873
 eval {
895 874
 $where = $dbi->where
896 875
              ->clause(key1 => "{= key1}" )