Showing 4 changed files with 74 additions and 69 deletions
+3
Changes
... ...
@@ -1,6 +1,9 @@
1
+0.1644
2
+  added experimental build_where method
1 3
 0.1633
2 4
   fixed test
3 5
 0.1632
6
+  added experimental where method
4 7
   added experimental DBIx::Custom::Where.
5 8
   removed DBIx::Custom::Or
6 9
 0.1631
+6 -2
lib/DBIx/Custom.pm
... ...
@@ -1,6 +1,6 @@
1 1
 package DBIx::Custom;
2 2
 
3
-our $VERSION = '0.1633';
3
+our $VERSION = '0.1634';
4 4
 
5 5
 use 5.008001;
6 6
 use strict;
... ...
@@ -686,7 +686,7 @@ sub update {
686 686
 
687 687
 sub update_all { shift->update(allow_update_all => 1, @_) };
688 688
 
689
-sub where { DBIx::Custom::Where->new }
689
+sub where { DBIx::Custom::Where->new(sql_builder => shift->sql_builder) }
690 690
 
691 691
 sub _build_binds {
692 692
     my ($self, $params, $columns, $filter) = @_;
... ...
@@ -1411,6 +1411,10 @@ B<Example:>
1411 1411
 
1412 1412
 Create a new L<DBIx::Custom::Where> object.
1413 1413
 
1414
+=head2 C<experimental) build_where>
1415
+
1416
+
1417
+
1414 1418
 =head2 C<(deprecated) default_bind_filter>
1415 1419
 
1416 1420
     my $default_bind_filter = $dbi->default_bind_filter;
+64 -66
lib/DBIx/Custom/Where.pm
... ...
@@ -10,85 +10,89 @@ use overload '""' => sub { shift->to_string }, fallback => 1;
10 10
 
11 11
 use Carp 'croak';
12 12
 
13
+__PACKAGE__->attr(clause => sub { [] });
13 14
 __PACKAGE__->attr(param => sub { {} });
15
+__PACKAGE__->attr(sql_builder => sub { {} });
14 16
 
15
-sub clause {
16
-    my $self = shift;
17
+sub to_string {
18
+    my ($self, $param, $clause) = @_;
17 19
     
18
-    if (@_) {
19
-        $self->{clause} = ref $_[0] eq 'HASH' ? $_[0] : {@_};
20
-        
21
-        return $self;
22
-    }
23
-    return $self->{clause} ||= {};
24
-}
25
-
26
-sub or_clause {
27
-    my $self = shift;
20
+    local $self->{_where}    = '';
21
+    local $self->{_count}    = {};
22
+    local $self->{_op_stack} = [];
23
+    local $self->{_param}    = $param;
28 24
     
29
-    if (@_) {
30
-        $self->{or_clause} = ref $_[0] eq 'HASH' ? $_[0] : {@_};
31
-        
32
-        return $self;
33
-    }
25
+    $clause = ['and', $clause] unless ref $clause eq 'ARRAY';
26
+    
27
+    $self->_forward($clause);
34 28
     
35
-    return $self->{or_clause} ||= {};
29
+    return $self->{_where};
36 30
 }
37 31
 
38
-sub to_string {
39
-    my $self = shift;
40
-    
41
-    my $param      = $self->param;
42
-    my $clauses    = $self->clause;
43
-    my $or_clauses = $self->or_clause;
44
-    
45
-    # Clause check
46
-    my $wexists = keys %$param;
32
+our %VALID_OPERATIONS = map { $_ => 1 } qw/and or or_repeat/;
33
+
34
+sub _forward {
35
+    my ($self, $clause) = @_;
47 36
     
48
-    # Where
49
-    my $where = '';
50
-    if ($wexists) {
51
-        $where .= 'where (';
37
+    if (ref $clause eq 'ARRAY') {
38
+        $self->{_where} .= '( ';
39
+        
40
+        my $op = $clause->[0] || '';
41
+        
42
+        croak qq{"$op" is invalid operation}
43
+          unless $VALID_OPERATIONS{$op};
44
+          
45
+        push @{$self->{_op_stack}}, $op;
46
+        
47
+        for (my $i = 1; $i < @$clause; $i++) {
48
+            $self->_forword($clause->[$i]);
49
+        }
52 50
         
53
-        foreach my $column (keys %$param) {
54
-
55
-            croak qq{"$column" is not found in "clause" or "or_clause"}
56
-              if exists $clauses->{$column}
57
-                  && exists $or_clauses->{$column};
58
-            
59
-            if (exists $clauses->{$column}) {
60
-                if (ref $clauses->{$column} eq 'ARRAY') {
61
-                    foreach my $clause (@{$clauses->{$column}}) {
62
-                        $where .= $clause . ' and ';
63
-                    }
51
+        pop @{$self->{_op_stack}};
52
+
53
+        if ($self->{_where} =~ /\( $/) {
54
+            $self->{_where} =~ s/\( $//;
55
+            $self->{_where} .= ' ';
56
+        }
57
+        $self->{_where} =~ s/ $op $//;
58
+        $self->{_where} .= ' ) ';
59
+    }
60
+    else {
61
+        my $op = $self->{_op_stack}->[-1];
62
+        
63
+        my $columns = $self->sql_builder->build_query($clause)->columns;
64
+        
65
+        croak qq{each tag contains one column name: tag "$clause"}
66
+          unless @$columns == 1;
67
+        
68
+        my $column = $columns->[0];
69
+        
70
+        my $ccount = ++$self->{_count}->{$column};
71
+        
72
+        my $param = $self->{_param};
73
+        
74
+        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];
64 79
                 }
65 80
                 else {
66
-                    $where .= $clauses->{$column} . ' and ';
81
+                    $self->{_where} .= $clause . " $op "
82
+                      if $ccount == 1;
67 83
                 }
68
-                            }
69
-            elsif (exists $or_clauses->{$column}) {
70
-                my $clause = $or_clauses->{$column};
71
-                
84
+            }
85
+            elsif ($op eq 'or_repeat') {
72 86
                 if (ref $param->{$column} eq 'ARRAY') {
73
-                    my $count = @{$param->{$column}};
74
-                    if ($count) {
75
-                        $where .= '( ';
76
-                        $where .= $clause . ' or ' for (1 .. $count);
77
-                        $where =~ s/ or $//;
78
-                        $where .= ' ) and ';
79
-                    }
87
+                    $self->{_where} .= $clause . " or "
88
+                      for (1 .. @{$param->{$column}});
80 89
                 }
81 90
                 else {
82
-                    $where .= $clause . ' and ';
91
+                    $self->{_where} .= $clause;
83 92
                 }
84 93
             }
85 94
         }
86
-
87
-        $where =~ s/ and $//;
88
-        $where .= ' )';
89 95
     }
90
-    
91
-    return $where;
92 96
 }
93 97
 
94 98
 1;
... ...
@@ -120,12 +124,6 @@ DBIx::Custom::Where - Where clause
120 124
 Where clause. These clauses is joined by ' and ' at C<to_string()>
121 125
 if corresponding parameter name is exists in C<param>.
122 126
 
123
-=head2 C<or_clause>
124
-
125
-    $where->or_clause(name => '{= name}');
126
-
127
-clause which has these parameter name is joined by ' or '.
128
-
129 127
 =head2 C<to_string>
130 128
 
131 129
     $where->to_string;
+1 -1
t/dbix-custom-core-sqlite.t
... ...
@@ -814,7 +814,7 @@ 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
-1;
817
+__END__
818 818
 
819 819
 test 'DBIx::Custom::Where';
820 820
 $dbi = DBIx::Custom->connect($NEW_ARGS->{0});