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