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