... | ... |
@@ -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 |
... | ... |
@@ -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; |
... | ... |
@@ -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; |
... | ... |
@@ -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}); |