Showing 7 changed files with 135 additions and 23 deletions
+29 -16
lib/DBIx/Custom.pm
... ...
@@ -16,6 +16,7 @@ use DBIx::Custom::QueryBuilder;
16 16
 use DBIx::Custom::Where;
17 17
 use DBIx::Custom::Model;
18 18
 use DBIx::Custom::Tag;
19
+use DBIx::Custom::Util;
19 20
 use Encode qw/encode_utf8 decode_utf8/;
20 21
 
21 22
 __PACKAGE__->attr(
... ...
@@ -87,6 +88,7 @@ sub apply_filter {
87 88
     $self->{filter} ||= {};
88 89
     $self->{filter}{out} ||= {};
89 90
     $self->{filter}{in} ||= {};
91
+    $self->{filter}{end} ||= {};
90 92
     
91 93
     # Create filters
92 94
     my $usage = "Usage: \$dbi->apply_filter(" .
... ...
@@ -98,11 +100,18 @@ sub apply_filter {
98 100
         # Column
99 101
         my $column = $cinfos[$i];
100 102
         
103
+        if (ref $column eq 'ARRAY') {
104
+            foreach my $c (@$column) {
105
+                push @cinfos, $c, $cinfos[$i + 1];
106
+            }
107
+            next;
108
+        }
109
+        
101 110
         # Filter info
102 111
         my $finfo = $cinfos[$i + 1] || {};
103
-        croak $usage unless  ref $finfo eq 'HASH';
112
+        croak "$usage (table: $table)" unless  ref $finfo eq 'HASH';
104 113
         foreach my $ftype (keys %$finfo) {
105
-            croak $usage unless $ftype eq 'in' || $ftype eq 'out'
114
+            croak "$usage (table: $table 2)" unless $ftype eq 'in' || $ftype eq 'out'
106 115
                              || $ftype eq 'end'; 
107 116
         }
108 117
         
... ...
@@ -351,6 +360,7 @@ sub execute{
351 360
     
352 361
     # Applied filter
353 362
     my $filter = {};
363
+    
354 364
     my $tables = $query->tables;
355 365
     my $arg_tables = $args{table} || [];
356 366
     $arg_tables = [$arg_tables]
... ...
@@ -364,7 +374,8 @@ sub execute{
364 374
     }
365 375
     
366 376
     # Filter argument
367
-    my $f = $args{filter} || $query->filter || {};
377
+    my $f = DBIx::Custom::Util::array_filter_to_hash($args{filter})
378
+         || $query->filter || {};
368 379
     foreach my $column (keys %$f) {
369 380
         my $fname = $f->{$column};
370 381
         if (!defined $fname) {
... ...
@@ -773,7 +784,9 @@ sub include_model {
773 784
         $self->model($model->name, $model);
774 785
         
775 786
         # Apply filter
776
-        $self->apply_filter($model->table, %{$model->filter});
787
+        croak "${name_space}::$model_class filter must be array reference"
788
+          unless ref $model->filter eq 'ARRAY';
789
+        $self->apply_filter($model->table, @{$model->filter});
777 790
     }
778 791
     return $self;
779 792
 }
... ...
@@ -1075,23 +1088,23 @@ DBIx::Custom - DBI interface, having hash parameter binding and filtering system
1075 1088
     # Insert 
1076 1089
     $dbi->insert(table  => 'book',
1077 1090
                  param  => {title => 'Perl', author => 'Ken'},
1078
-                 filter => {title => 'to_something'});
1091
+                 filter => [title => 'to_something']);
1079 1092
     
1080 1093
     # Update 
1081 1094
     $dbi->update(table  => 'book', 
1082 1095
                  param  => {title => 'Perl', author => 'Ken'}, 
1083 1096
                  where  => {id => 5},
1084
-                 filter => {title => 'to_something'});
1097
+                 filter => [title => 'to_something']);
1085 1098
     
1086 1099
     # Update all
1087 1100
     $dbi->update_all(table  => 'book',
1088 1101
                      param  => {title => 'Perl'},
1089
-                     filter => {title => 'to_something'});
1102
+                     filter => [title => 'to_something']);
1090 1103
     
1091 1104
     # Delete
1092 1105
     $dbi->delete(table  => 'book',
1093 1106
                  where  => {author => 'Ken'},
1094
-                 filter => {title => 'to_something'});
1107
+                 filter => [title => 'to_something']);
1095 1108
     
1096 1109
     # Delete all
1097 1110
     $dbi->delete_all(table => 'book');
... ...
@@ -1103,7 +1116,7 @@ DBIx::Custom - DBI interface, having hash parameter binding and filtering system
1103 1116
         where  => {author => 'Ken'},
1104 1117
         relation => {'book.id' => 'rental.book_id'},
1105 1118
         append => 'order by id limit 5',
1106
-        filter => {title => 'to_something'}
1119
+        filter => [title => 'to_something']
1107 1120
     );
1108 1121
 
1109 1122
     # Execute SQL
... ...
@@ -1112,7 +1125,7 @@ DBIx::Custom - DBI interface, having hash parameter binding and filtering system
1112 1125
     # Execute SQL with hash binding and filtering
1113 1126
     $dbi->execute("select id from book where {= author} and {like title}",
1114 1127
                   param  => {author => 'ken', title => '%Perl%'},
1115
-                  filter => {title => 'to_something'});
1128
+                  filter => [title => 'to_something']);
1116 1129
 
1117 1130
     # Create query and execute it
1118 1131
     my $query = $dbi->create_query(
... ...
@@ -1331,8 +1344,8 @@ instead of suger methods.
1331 1344
 
1332 1345
 =head2 C<execute>
1333 1346
 
1334
-    my $result = $dbi->execute($query,  param => $params, filter => \%filter);
1335
-    my $result = $dbi->execute($source, param => $params, filter => \%filter);
1347
+    my $result = $dbi->execute($query,  param => $params, filter => \@filter);
1348
+    my $result = $dbi->execute($source, param => $params, filter => \@filter);
1336 1349
 
1337 1350
 Execute query or the source of SQL.
1338 1351
 Query is L<DBIx::Custom::Query> object.
... ...
@@ -1344,7 +1357,7 @@ or the count of affected rows if insert, update, delete statement is executed.
1344 1357
     $dbi->delete(table  => $table,
1345 1358
                  where  => \%where,
1346 1359
                  append => $append,
1347
-                 filter => \%filter,
1360
+                 filter => \@filter,
1348 1361
                  query  => 1);
1349 1362
 
1350 1363
 Execute delete statement.
... ...
@@ -1392,7 +1405,7 @@ You can also write arguments like this.
1392 1405
     $dbi->insert(table  => $table, 
1393 1406
                  param  => \%param,
1394 1407
                  append => $append,
1395
-                 filter => \%filter,
1408
+                 filter => \@filter,
1396 1409
                  query  => 1);
1397 1410
 
1398 1411
 Execute insert statement.
... ...
@@ -1594,7 +1607,7 @@ NOTE that you must pass array reference as C<where>.
1594 1607
                  param  => \%params,
1595 1608
                  where  => \%where,
1596 1609
                  append => $append,
1597
-                 filter => \%filter,
1610
+                 filter => \@filter,
1598 1611
                  query  => 1)
1599 1612
 
1600 1613
 Execute update statement.
... ...
@@ -1632,7 +1645,7 @@ C<columns> and C<primary_key> is automatically set.
1632 1645
 
1633 1646
     $dbi->update_all(table  => $table, 
1634 1647
                      param  => \%params,
1635
-                     filter => \%filter,
1648
+                     filter => \@filter,
1636 1649
                      append => $append);
1637 1650
 
1638 1651
 Execute update statement to update all rows.
+1 -1
lib/DBIx/Custom/Model.pm
... ...
@@ -13,7 +13,7 @@ push @DBIx::Custom::CARP_NOT, __PACKAGE__;
13 13
 __PACKAGE__->attr(
14 14
     ['dbi', 'name', 'table'],
15 15
     columns => sub { [] },
16
-    filter => sub { {} },
16
+    filter => sub { [] },
17 17
     primary_key => sub { [] },
18 18
     relation => sub { {} }
19 19
 );
+24 -1
lib/DBIx/Custom/Query.pm
... ...
@@ -13,7 +13,28 @@ sub filter {
13 13
     my $self = shift;
14 14
     
15 15
     if (@_) {
16
-        my $filter = ref $_[0] eq 'HASH' ? $_[0] : {@_};
16
+        my $filter = {};
17
+        
18
+        if (ref $_[0] eq 'HASH') {
19
+            $filter = $_[0];
20
+        }
21
+        else {
22
+            my $ef = @_ > 1 ? [@_] : $_[0];
23
+            
24
+            for (my $i = 0; $i < @$ef; $i += 2) {
25
+                my $column = $ef->[$i];
26
+                my $f = $ef->[$i + 1];
27
+                
28
+                if (ref $column eq 'ARRAY') {
29
+                    foreach my $c (@$column) {
30
+                        $filter->{$c} = $f;
31
+                    }
32
+                }
33
+                else {
34
+                    $filter->{$column} = $f;
35
+                }
36
+            }
37
+        }
17 38
         
18 39
         foreach my $column (keys %$filter) {
19 40
             my $fname = $filter->{$column};
... ...
@@ -65,6 +86,8 @@ Column names.
65 86
     $query     = $query->filter(author => 'to_something',
66 87
                                  title  => 'to_something');
67 88
 
89
+    $query     = $query->filter([qw/author title/] => 'to_something');
90
+
68 91
 Filters when parameter binding is executed.
69 92
 
70 93
 =head2 C<sql>
+26 -3
lib/DBIx/Custom/Result.pm
... ...
@@ -6,6 +6,7 @@ use warnings;
6 6
 use base 'Object::Simple';
7 7
 
8 8
 use Carp 'croak';
9
+use DBIx::Custom::Util;
9 10
 
10 11
 __PACKAGE__->attr(
11 12
     [qw/filters sth/],
... ...
@@ -16,8 +17,17 @@ sub filter {
16 17
     my $self = shift;
17 18
     
18 19
     if (@_) {
19
-        my $filter = ref $_[0] eq 'HASH' ? $_[0] : {@_};
20
+        my $filter = {};
20 21
         
22
+        if (ref $_[0] eq 'HASH') {
23
+            $filter = $_[0];
24
+        }
25
+        else {
26
+            $filter = DBIx::Custom::Util::array_filter_to_hash(
27
+                @_ > 1 ? [@_] : $_[0]
28
+            );
29
+        }
30
+                
21 31
         foreach my $column (keys %$filter) {
22 32
             my $fname = $filter->{$column};
23 33
 
... ...
@@ -44,7 +54,16 @@ sub end_filter {
44 54
     my $self = shift;
45 55
     
46 56
     if (@_) {
47
-        my $end_filter = ref $_[0] eq 'HASH' ? $_[0] : {@_};
57
+        my $end_filter = {};
58
+        
59
+        if (ref $_[0] eq 'HASH') {
60
+            $end_filter = $_[0];
61
+        }
62
+        else {
63
+            $end_filter = DBIx::Custom::Util::array_filter_to_hash(
64
+                @_ > 1 ? [@_] : $_[0]
65
+            );
66
+        }
48 67
         
49 68
         foreach my $column (keys %$end_filter) {
50 69
             my $fname = $end_filter->{$column};
... ...
@@ -339,9 +358,11 @@ and implements the following new ones.
339 358
 
340 359
 =head2 C<(experimental) end_filter>
341 360
 
342
-    $result    = $result->end_filter(title  => 'to_something',
361
+    $result = $result->end_filter(title  => 'to_something',
343 362
                                      author => 'to_something');
344 363
 
364
+    $result = $result->end_filter([qw/title author/] => 'to_something');
365
+
345 366
 End filters.
346 367
 These each filters is executed after the filters applied by C<apply_filter> of
347 368
 L<DBIx::Custom> or C<filter> method.
... ...
@@ -401,6 +422,8 @@ Row count must be specified.
401 422
     $result = $result->filter(title  => 'to_something',
402 423
                               author => 'to_something');
403 424
 
425
+    $result = $result->filter([qw/title author/] => 'to_something');
426
+
404 427
 Filters.
405 428
 These each filters override the filters applied by C<apply_filter> of
406 429
 L<DBIx::Custom>.
+35
lib/DBIx/Custom/Util.pm
... ...
@@ -0,0 +1,35 @@
1
+package DBIx::Custom::Util;
2
+
3
+use strict;
4
+use warnings;
5
+
6
+sub array_filter_to_hash {
7
+    my $array_filter = shift;
8
+    
9
+    return unless $array_filter;
10
+    return $array_filter if ref $array_filter eq 'HASH';
11
+    
12
+    my $filter = {};
13
+    
14
+    for (my $i = 0; $i < @$array_filter; $i += 2) {
15
+        my $column = $array_filter->[$i];
16
+        my $f = $array_filter->[$i + 1];
17
+        
18
+        if (ref $column eq 'ARRAY') {
19
+            foreach my $c (@$column) {
20
+                $filter->{$c} = $f;
21
+            }
22
+        }
23
+        else {
24
+            $filter->{$column} = $f;
25
+        }
26
+    }
27
+    return $filter;
28
+}
29
+
30
+1;
31
+
32
+=head1 NAME
33
+
34
+DBIx::Custom::Util - Utility class
35
+
+18
t/dbix-custom-core-sqlite.t
... ...
@@ -828,6 +828,24 @@ $result->end_filter(key1 => sub { $_[0] * 3 }, key2 => sub { $_[0] * 5 });
828 828
 $row = $result->fetch_first;
829 829
 is_deeply($row, [6, 40]);
830 830
 
831
+$dbi = DBIx::Custom->connect($NEW_ARGS->{0});
832
+$dbi->execute($CREATE_TABLE->{0});
833
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
834
+$result = $dbi->select(table => 'table1');
835
+$result->filter([qw/key1 key2/] => sub { $_[0] * 2 });
836
+$result->end_filter([[qw/key1 key2/] => sub { $_[0] * 3 }]);
837
+$row = $result->fetch_first;
838
+is_deeply($row, [6, 12]);
839
+
840
+$dbi = DBIx::Custom->connect($NEW_ARGS->{0});
841
+$dbi->execute($CREATE_TABLE->{0});
842
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
843
+$result = $dbi->select(table => 'table1');
844
+$result->filter([[qw/key1 key2/] => sub { $_[0] * 2 }]);
845
+$result->end_filter([qw/key1 key2/] => sub { $_[0] * 3 });
846
+$row = $result->fetch_first;
847
+is_deeply($row, [6, 12]);
848
+
831 849
 $dbi->register_filter(five_times => sub { $_[0] * 5 });
832 850
 $result = $dbi->select(table => 'table1');
833 851
 $result->filter(key1 => sub { $_[0] * 2 }, key2 => sub { $_[0] * 4 });
+2 -2
t/dbix-custom-core-sqlite/MyModel6/table3.pm
... ...
@@ -3,9 +3,9 @@ package MyModel6::table3;
3 3
 use base 'MyModel6';
4 4
 
5 5
 __PACKAGE__->attr(filter => sub {
6
-    {
6
+    [
7 7
         key1 => {in => sub { uc $_[0] }}
8
-    }
8
+    ]
9 9
 });
10 10
 
11 11
 1;