Showing 5 changed files with 359 additions and 160 deletions
+1
Changes
... ...
@@ -1,4 +1,5 @@
1 1
 0.1694
2
+    - EXPERIMENTAL type_rule argument format is changed
2 3
     - DBIx::Custom::Result type_rule method on setting return self 
3 4
     - reserved_word_quote is DEPRECATED! this is renamed to quote
4 5
     - DBIx::Custom::Model type attribute is DEPRECATED!
+152 -75
lib/DBIx/Custom.pm
... ...
@@ -20,7 +20,7 @@ use constant DEBUG => $ENV{DBIX_CUSTOM_DEBUG} || 0;
20 20
 use constant DEBUG_ENCODING => $ENV{DBIX_CUSTOM_DEBUG_ENCODING} || 'UTF-8';
21 21
 
22 22
 our @COMMON_ARGS = qw/bind_type table query filter id primary_key
23
-                      type_rule_off type/;
23
+                      type_rule_off type_rule1_off type_rule2_off type/;
24 24
 
25 25
 has [qw/connector dsn password quote user/],
26 26
     cache => 0,
... ...
@@ -362,6 +362,10 @@ sub execute {
362 362
     my $bind_type = delete $args{bind_type} || delete $args{type};
363 363
     $bind_type = _array_to_hash($bind_type);
364 364
     my $type_rule_off = delete $args{type_rule_off};
365
+    my $type_rule_off_parts = {
366
+        1 => delete $args{type_rule1_off},
367
+        2 => delete $args{type_rule2_off}
368
+    };
365 369
     my $query_return = delete $args{query};
366 370
     
367 371
     # Check argument names
... ...
@@ -384,7 +388,7 @@ sub execute {
384 388
     }
385 389
     
386 390
     # Type rule
387
-    my $type_filter = {};
391
+    my $type_filters = {};
388 392
     unless ($type_rule_off) {
389 393
         foreach my $name (keys %$param) {
390 394
             my $table;
... ...
@@ -395,12 +399,16 @@ sub execute {
395 399
             }
396 400
             $table ||= $main_table;
397 401
             
398
-            my $into = $self->{_into} || {};
399
-            if (defined $table && $into->{$table} &&
400
-                (my $rule = $into->{$table}->{$column}))
401
-            {
402
-                $type_filter->{$column} = $rule;
403
-                $type_filter->{"$table.$column"} = $rule;
402
+            foreach my $i (1 .. 2) {
403
+                unless ($type_rule_off_parts->{$i}) {
404
+                    my $into = $self->{"_into$i"} || {};
405
+                    if (defined $table && $into->{$table} &&
406
+                        (my $rule = $into->{$table}->{$column}))
407
+                    {
408
+                        $type_filters->{$i}->{$column} = $rule;
409
+                        $type_filters->{$i}->{"$table.$column"} = $rule;
410
+                    }
411
+                }
404 412
             }
405 413
         }
406 414
     }
... ...
@@ -433,7 +441,7 @@ sub execute {
433 441
         $param,
434 442
         $query->columns,
435 443
         $filter,
436
-        $type_filter,
444
+        $type_filters,
437 445
         $bind_type
438 446
     );
439 447
     
... ...
@@ -495,7 +503,10 @@ sub execute {
495 503
             default_filter => $self->{default_in_filter},
496 504
             filter => $filter->{in} || {},
497 505
             end_filter => $filter->{end} || {},
498
-            type_rule => \%{$self->type_rule->{from}},
506
+            type_rule => {
507
+                from1 => $self->type_rule->{from1},
508
+                from2 => $self->type_rule->{from2}
509
+            },
499 510
         );
500 511
 
501 512
         return $result;
... ...
@@ -960,46 +971,50 @@ sub type_rule {
960 971
         my $type_rule = ref $_[0] eq 'HASH' ? $_[0] : {@_};
961 972
         
962 973
         # Into
963
-        $type_rule->{into} = _array_to_hash($type_rule->{into});
964
-        $self->{type_rule} = $type_rule;
965
-        $self->{_into} = {};
966
-        foreach my $type_name (keys %{$type_rule->{into} || {}}) {
967
-            croak qq{type name of into section must be lower case}
968
-              if $type_name =~ /[A-Z]/;
969
-        }
970
-        $self->each_column(sub {
971
-            my ($dbi, $table, $column, $column_info) = @_;
972
-            
973
-            my $type_name = lc $column_info->{TYPE_NAME};
974
-            if ($type_rule->{into} &&
975
-                (my $filter = $type_rule->{into}->{$type_name}))
976
-            {
977
-                return unless exists $type_rule->{into}->{$type_name};
978
-                if  (defined $filter && ref $filter ne 'CODE') 
974
+        foreach my $i (1 .. 2) {
975
+            my $into = "into$i";
976
+            $type_rule->{$into} = _array_to_hash($type_rule->{$into});
977
+            $self->{type_rule} = $type_rule;
978
+            $self->{"_$into"} = {};
979
+            foreach my $type_name (keys %{$type_rule->{$into} || {}}) {
980
+                croak qq{type name of $into section must be lower case}
981
+                  if $type_name =~ /[A-Z]/;
982
+            }
983
+            $self->each_column(sub {
984
+                my ($dbi, $table, $column, $column_info) = @_;
985
+                
986
+                my $type_name = lc $column_info->{TYPE_NAME};
987
+                if ($type_rule->{$into} &&
988
+                    (my $filter = $type_rule->{$into}->{$type_name}))
979 989
                 {
980
-                    my $fname = $filter;
990
+                    return unless exists $type_rule->{$into}->{$type_name};
991
+                    if  (defined $filter && ref $filter ne 'CODE') 
992
+                    {
993
+                        my $fname = $filter;
994
+                        croak qq{Filter "$fname" is not registered" } . _subname
995
+                          unless exists $self->filters->{$fname};
996
+                        
997
+                        $filter = $self->filters->{$fname};
998
+                    }
999
+
1000
+                    $self->{"_$into"}{$table}{$column} = $filter;
1001
+                }
1002
+            });
1003
+        }
1004
+
1005
+        # From
1006
+        foreach my $i (1 .. 2) {
1007
+            $type_rule->{"from$i"} = _array_to_hash($type_rule->{"from$i"});
1008
+            foreach my $data_type (keys %{$type_rule->{"from$i"} || {}}) {
1009
+                croak qq{data type of from$i section must be lower case or number}
1010
+                  if $data_type =~ /[A-Z]/;
1011
+                my $fname = $type_rule->{"from$i"}{$data_type};
1012
+                if (defined $fname && ref $fname ne 'CODE') {
981 1013
                     croak qq{Filter "$fname" is not registered" } . _subname
982 1014
                       unless exists $self->filters->{$fname};
983 1015
                     
984
-                    $filter = $self->filters->{$fname};
1016
+                    $type_rule->{"from$i"}{$data_type} = $self->filters->{$fname};
985 1017
                 }
986
-
987
-                $self->{_into}{$table}{$column} = $filter;
988
-            }
989
-        });
990
-        
991
-
992
-        # From
993
-        $type_rule->{from} = _array_to_hash($type_rule->{from});
994
-        foreach my $data_type (keys %{$type_rule->{from} || {}}) {
995
-            croak qq{data type of into section must be lower case or number}
996
-              if $data_type =~ /[A-Z]/;
997
-            my $fname = $type_rule->{from}{$data_type};
998
-            if (defined $fname && ref $fname ne 'CODE') {
999
-                croak qq{Filter "$fname" is not registered" } . _subname
1000
-                  unless exists $self->filters->{$fname};
1001
-                
1002
-                $type_rule->{from}{$data_type} = $self->filters->{$fname};
1003 1018
             }
1004 1019
         }
1005 1020
         
... ...
@@ -1177,7 +1192,7 @@ sub _apply_filter {
1177 1192
 }
1178 1193
 
1179 1194
 sub _create_bind_values {
1180
-    my ($self, $params, $columns, $filter, $type_filter, $bind_type) = @_;
1195
+    my ($self, $params, $columns, $filter, $type_filters, $bind_type) = @_;
1181 1196
     
1182 1197
     # Create bind values
1183 1198
     my $bind = [];
... ...
@@ -1210,8 +1225,11 @@ sub _create_bind_values {
1210 1225
         $value = $f->($value) if $f;
1211 1226
         
1212 1227
         # Type rule
1213
-        my $tf = $type_filter->{$column};
1214
-        $value = $tf->($value) if $tf;
1228
+        foreach my $i (1 .. 2) {
1229
+            my $type_filter = $type_filters->{$i};
1230
+            my $tf = $type_filter->{$column};
1231
+            $value = $tf->($value) if $tf;
1232
+        }
1215 1233
         
1216 1234
         # Bind values
1217 1235
         push @$bind, {value => $value, bind_type => $bind_type->{$column}};
... ...
@@ -2104,7 +2122,19 @@ by C<insert()>, C<update()>, C<delete()>, C<select()>.
2104 2122
 
2105 2123
     type_rule_off => 1
2106 2124
 
2107
-Trun type rule off.
2125
+Turn C<into1> and C<into2> type rule off.
2126
+
2127
+=item C<type_rule1_off> EXPERIMENTAL
2128
+
2129
+    type_rule1_off => 1
2130
+
2131
+Turn C<into1> type rule off.
2132
+
2133
+=item C<type_rule2_off> EXPERIMENTAL
2134
+
2135
+    type_rule2_off => 1
2136
+
2137
+Turn C<into2> type rule off.
2108 2138
 
2109 2139
 =back
2110 2140
 
... ...
@@ -2168,6 +2198,18 @@ Same as C<execute> method's C<type> option.
2168 2198
 
2169 2199
 Same as C<execute> method's C<type_rule_off> option.
2170 2200
 
2201
+=item C<type_rule1_off> EXPERIMENTAL
2202
+
2203
+    type_rule1_off => 1
2204
+
2205
+Same as C<execute> method's C<type_rule1_off> option.
2206
+
2207
+=item C<type_rule2_off> EXPERIMENTAL
2208
+
2209
+    type_rule2_off => 1
2210
+
2211
+Same as C<execute> method's C<type_rule2_off> option.
2212
+
2171 2213
 =back
2172 2214
 
2173 2215
 =head2 C<delete_all>
... ...
@@ -2253,6 +2295,18 @@ Same as C<execute> method's C<type> option.
2253 2295
 
2254 2296
 Same as C<execute> method's C<type_rule_off> option.
2255 2297
 
2298
+=item C<type_rule1_off> EXPERIMENTAL
2299
+
2300
+    type_rule1_off => 1
2301
+
2302
+Same as C<execute> method's C<type_rule1_off> option.
2303
+
2304
+=item C<type_rule2_off> EXPERIMENTAL
2305
+
2306
+    type_rule2_off => 1
2307
+
2308
+Same as C<execute> method's C<type_rule2_off> option.
2309
+
2256 2310
 =back
2257 2311
 
2258 2312
 =over 4
... ...
@@ -2401,14 +2455,23 @@ Register filters, used by C<filter> option of many methods.
2401 2455
 =head2 C<type_rule> EXPERIMENTAL
2402 2456
 
2403 2457
     $dbi->type_rule(
2404
-        into => {
2458
+        into1 => {
2405 2459
             date => sub { ... },
2406 2460
             datetime => sub { ... }
2407 2461
         },
2408
-        from => {
2462
+        into2 => {
2463
+            date => sub { ... },
2464
+            datetime => sub { ... }
2465
+        },
2466
+        from1 => {
2467
+            # DATE
2468
+            9 => sub { ... },
2469
+            # DATETIME or TIMESTAMP
2470
+            11 => sub { ... },
2471
+        }
2472
+        from2 => {
2409 2473
             # DATE
2410 2474
             9 => sub { ... },
2411
-            
2412 2475
             # DATETIME or TIMESTAMP
2413 2476
             11 => sub { ... },
2414 2477
         }
... ...
@@ -2417,12 +2480,17 @@ Register filters, used by C<filter> option of many methods.
2417 2480
 Filtering rule when data is send into and get from database.
2418 2481
 This has a little complex problem.
2419 2482
 
2420
-In C<into> you can specify type name as same as type name defined
2483
+In C<into1> and C<into2> you can specify
2484
+type name as same as type name defined
2421 2485
 by create table, such as C<DATETIME> or C<DATE>.
2422
-Type rule of C<into> is enabled on the following pattern.
2486
+
2487
+C<into2> is executed after C<into1>.
2423 2488
 
2424 2489
 Note that type name and data type don't contain upper case.
2425
-If that contain upper case charactor, you specify it lower case.
2490
+If these contain upper case charactor, you convert it to lower case.
2491
+
2492
+Type rule of C<into1> and C<into2> is enabled on the following
2493
+column name.
2426 2494
 
2427 2495
 =over 4
2428 2496
 
... ...
@@ -2442,33 +2510,18 @@ You get all type name used in database by C<available_type_name>.
2442 2510
 
2443 2511
     print $dbi->available_type_name;
2444 2512
 
2445
-In C<from> you can't specify type name defined by create table.
2446
-You must specify data type, this is internal one.
2513
+In C<from1> and C<from2> you data type, not type name.
2514
+C<from2> is executed after C<from1>.
2447 2515
 You get all data type by C<available_data_type>.
2448 2516
 
2449 2517
     print $dbi->available_data_type;
2450 2518
 
2451
-Type rule of C<from> is enabled on the following pattern.
2452
-
2453
-=item 4. table name and column name, separator is hyphen
2454
-
2455
-    book-issue_date
2456
-    book-issue_datetime
2457
-
2458
-This is useful in HTML.
2459
-
2460
-=back
2461
-
2462
-You can also specify multiple types
2519
+You can also specify multiple types at once.
2463 2520
 
2464 2521
     $dbi->type_rule(
2465
-        into => [
2522
+        into1 => [
2466 2523
             [qw/DATE DATETIME/] => sub { ... },
2467 2524
         ],
2468
-        from => {
2469
-            # DATE
2470
-            [qw/9 11/] => sub { ... },
2471
-        }
2472 2525
     );
2473 2526
 
2474 2527
 =head2 C<select>
... ...
@@ -2624,6 +2677,18 @@ Table name.
2624 2677
 
2625 2678
 Same as C<execute> method's C<type_rule_off> option.
2626 2679
 
2680
+=item C<type_rule1_off> EXPERIMENTAL
2681
+
2682
+    type_rule1_off => 1
2683
+
2684
+Same as C<execute> method's C<type_rule1_off> option.
2685
+
2686
+=item C<type_rule2_off> EXPERIMENTAL
2687
+
2688
+    type_rule2_off => 1
2689
+
2690
+Same as C<execute> method's C<type_rule2_off> option.
2691
+
2627 2692
 =item C<where>
2628 2693
     
2629 2694
     # Hash refrence
... ...
@@ -2729,7 +2794,19 @@ Same as C<execute> method's C<type> option.
2729 2794
 
2730 2795
 =item C<type_rule_off> EXPERIMENTAL
2731 2796
 
2732
-Same as C<execute> method's <type_rule_off>.
2797
+Same as C<execute> method's C<type_rule_off> option.
2798
+
2799
+=item C<type_rule1_off> EXPERIMENTAL
2800
+
2801
+    type_rule1_off => 1
2802
+
2803
+Same as C<execute> method's C<type_rule1_off> option.
2804
+
2805
+=item C<type_rule2_off> EXPERIMENTAL
2806
+
2807
+    type_rule2_off => 1
2808
+
2809
+Same as C<execute> method's C<type_rule2_off> option.
2733 2810
 
2734 2811
 =back
2735 2812
 
+54 -30
lib/DBIx/Custom/Result.pm
... ...
@@ -4,7 +4,7 @@ use Object::Simple -base;
4 4
 use Carp 'croak';
5 5
 use DBIx::Custom::Util qw/_array_to_hash _subname/;
6 6
 
7
-has [qw/filters filter_off sth type_rule_off/];
7
+has [qw/filters filter_off sth type_rule_off type_rule1_off type_rule2_off/];
8 8
 has stash => sub { {} };
9 9
 
10 10
 *all = \&fetch_hash_all;
... ...
@@ -49,7 +49,8 @@ sub fetch {
49 49
     # Filtering
50 50
     my $columns = $self->{sth}->{NAME};
51 51
     my $types = $self->{sth}->{TYPE};
52
-    my $type_rule = $self->type_rule || {};
52
+    my $type_rule1 = $self->type_rule->{from1} || {};
53
+    my $type_rule2 = $self->type_rule->{from2} || {};
53 54
     my $filter = $self->filter;
54 55
     my $end_filter = $self->end_filter;
55 56
     for (my $i = 0; $i < @$columns; $i++) {
... ...
@@ -58,9 +59,14 @@ sub fetch {
58 59
         my $column = $columns->[$i];
59 60
         
60 61
         # Type rule
61
-        my $type_filter = $type_rule->{lc($types->[$i])};
62
-        $row[$i] = $type_filter->($row[$i])
63
-          if $type_filter && !$self->{type_rule_off};
62
+        my $type_filter1 = $type_rule1->{lc($types->[$i])};
63
+        $row[$i] = $type_filter1->($row[$i])
64
+          if  $type_filter1 && !$self->{type_rule_off}
65
+           && !$self->{type_rule1_off};
66
+        my $type_filter2 = $type_rule2->{lc($types->[$i])};
67
+        $row[$i] = $type_filter2->($row[$i])
68
+          if  $type_filter2 && !$self->{type_rule_off}
69
+           && !$self->{type_rule2_off};
64 70
         
65 71
         # Filter
66 72
         my $filter  = $filter->{$column} || $self->{default_filter};
... ...
@@ -109,18 +115,23 @@ sub fetch_hash {
109 115
     my $end_filter = $self->end_filter || {};
110 116
     my $columns = $self->{sth}->{NAME};
111 117
     my $types = $self->{sth}->{TYPE};
112
-    my $type_rule = $self->type_rule || {};
118
+    my $type_rule1 = $self->type_rule->{from1} || {};
119
+    my $type_rule2 = $self->type_rule->{from2} || {};
113 120
     for (my $i = 0; $i < @$columns; $i++) {
114 121
         
115 122
         # Column
116 123
         my $column = $columns->[$i];
124
+        $hash_row->{$column} = $row->[$i];
117 125
         
118 126
         # Type rule
119
-        my $type_filter = $type_rule->{lc($types->[$i])};
120
-        if (!$self->{type_rule_off} && $type_filter) {
121
-            $hash_row->{$column} = $type_filter->($row->[$i]);
122
-        }
123
-        else { $hash_row->{$column} = $row->[$i] }
127
+        my $type_filter1 = $type_rule1->{lc($types->[$i])};
128
+        $hash_row->{$column} = $type_filter1->($hash_row->{$column})
129
+        if  !$self->{type_rule_off} && !$self->{type_rule1_off}
130
+         && $type_filter1;
131
+        my $type_filter2 = $type_rule2->{lc($types->[$i])};
132
+        $hash_row->{$column} = $type_filter2->($hash_row->{$column})
133
+        if  !$self->{type_rule_off} && !$self->{type_rule2_off}
134
+         && $type_filter2;
124 135
         
125 136
         # Filter
126 137
         my $f = $filter->{$column} || $self->{default_filter};
... ...
@@ -197,31 +208,30 @@ sub fetch_multi {
197 208
 sub type_rule {
198 209
     my $self = shift;
199 210
     
200
-    # Merge type rule
201 211
     if (@_) {
202
-        my $type_rule = @_ == 1 ? $_[0] : [@_];
203
-        $type_rule = _array_to_hash($type_rule) || {};
204
-        foreach my $data_type (keys %{$type_rule || {}}) {
205
-            croak qq{data type of into section must be lower case or number}
206
-              if $data_type =~ /[A-Z]/;
207
-            my $fname = $type_rule->{$data_type};
208
-            if (defined $fname && ref $fname ne 'CODE') {
209
-                croak qq{Filter "$fname" is not registered" } . _subname
210
-                  unless exists $self->filters->{$fname};
211
-                
212
-                $type_rule->{$data_type} = $self->filters->{$fname};
212
+        my $type_rule = ref $_[0] eq 'HASH' ? $_[0] : {@_};
213
+
214
+        # From
215
+        foreach my $i (1 .. 2) {
216
+            $type_rule->{"from$i"} = _array_to_hash($type_rule->{"from$i"});
217
+            foreach my $data_type (keys %{$type_rule->{"from$i"} || {}}) {
218
+                croak qq{data type of from$i section must be lower case or number}
219
+                  if $data_type =~ /[A-Z]/;
220
+                my $fname = $type_rule->{"from$i"}{$data_type};
221
+                if (defined $fname && ref $fname ne 'CODE') {
222
+                    croak qq{Filter "$fname" is not registered" } . _subname
223
+                      unless exists $self->filters->{$fname};
224
+                    
225
+                    $type_rule->{"from$i"}{$data_type} = $self->filters->{$fname};
226
+                }
213 227
             }
214 228
         }
215
-        
216
-        # Replace
217
-        if (@_ == 1) { $self->{type_rule} = $type_rule }
218
-        # Merge
219
-        else { $self->{type_rule} = {%{$self->type_rule}, %$type_rule} }
229
+        $self->{type_rule} = $type_rule;
220 230
         
221 231
         return $self;
222 232
     }
223 233
     
224
-    return $self->{type_rule} ||= {};
234
+    return $self->{type_rule} || {};
225 235
 }
226 236
 
227 237
 # DEPRECATED!
... ...
@@ -355,7 +365,21 @@ Statement handle of L<DBI>.
355 365
     my $type_rule_off = $result->type_rule_off;
356 366
     $result = $result->type_rule_off(1);
357 367
 
358
-Filtering by C<type_rule> is turned off.
368
+Turn C<from1> and C<from2> type rule off.
369
+
370
+=head2 C<type_rule1_off> EXPERIMENTAL
371
+
372
+    my $type_rule1_off = $result->type_rule1_off;
373
+    $result = $result->type_rule1_off(1);
374
+
375
+Turn C<from1> type rule off.
376
+
377
+=head2 C<type_rule2_off> EXPERIMENTAL
378
+
379
+    my $type_rule2_off = $result->type_rule2_off;
380
+    $result = $result->type_rule2_off(1);
381
+
382
+Turn C<from2> type rule off.
359 383
 
360 384
 =head1 METHODS
361 385
 
+150 -53
t/dbix-custom-core-sqlite.t
... ...
@@ -2648,7 +2648,7 @@ is_deeply($result->one,
2648 2648
 test 'type_rule from';
2649 2649
 $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2650 2650
 $dbi->type_rule(
2651
-    from => {
2651
+    from1 => {
2652 2652
         date => sub { uc $_[0] }
2653 2653
     }
2654 2654
 );
... ...
@@ -2665,7 +2665,7 @@ test 'type_rule into';
2665 2665
 $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2666 2666
 $dbi->execute("create table table1 (key1 Date, key2 datetime)");
2667 2667
 $dbi->type_rule(
2668
-    into => {
2668
+    into1 => {
2669 2669
         date => sub { uc $_[0] }
2670 2670
     }
2671 2671
 );
... ...
@@ -2676,7 +2676,7 @@ is($result->one->{key1}, 'A');
2676 2676
 $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2677 2677
 $dbi->execute("create table table1 (key1 date, key2 datetime)");
2678 2678
 $dbi->type_rule(
2679
-    into => [
2679
+    into1 => [
2680 2680
          [qw/date datetime/] => sub { uc $_[0] }
2681 2681
     ]
2682 2682
 );
... ...
@@ -2690,7 +2690,7 @@ $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2690 2690
 $dbi->execute("create table table1 (key1 Date, key2 datetime)");
2691 2691
 $dbi->insert({key1 => 'a', key2 => 'B'}, table => 'table1');
2692 2692
 $dbi->type_rule(
2693
-    into => [
2693
+    into1 => [
2694 2694
         [qw/date datetime/] => sub { uc $_[0] }
2695 2695
     ]
2696 2696
 );
... ...
@@ -2706,7 +2706,7 @@ $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2706 2706
 $dbi->execute("create table table1 (key1 Date, key2 datetime)");
2707 2707
 $dbi->insert({key1 => 'A', key2 => 'B'}, table => 'table1');
2708 2708
 $dbi->type_rule(
2709
-    into => [
2709
+    into1 => [
2710 2710
         [qw/date datetime/] => sub { uc $_[0] }
2711 2711
     ]
2712 2712
 );
... ...
@@ -2723,10 +2723,10 @@ $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2723 2723
 $dbi->execute("create table table1 (key1 date, key2 datetime)");
2724 2724
 $dbi->register_filter(twice => sub { $_[0] * 2 });
2725 2725
 $dbi->type_rule(
2726
-    from => {
2726
+    from1 => {
2727 2727
         date => 'twice',
2728 2728
     },
2729
-    into => {
2729
+    into1 => {
2730 2730
         date => 'twice',
2731 2731
     }
2732 2732
 );
... ...
@@ -2738,26 +2738,55 @@ test 'type_rule and filter order';
2738 2738
 $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2739 2739
 $dbi->execute("create table table1 (key1 Date, key2 datetime)");
2740 2740
 $dbi->type_rule(
2741
-    into => {
2741
+    into1 => {
2742 2742
         date => sub { $_[0] . 'b' }
2743 2743
     },
2744
-    from => {
2744
+    into2 => {
2745 2745
         date => sub { $_[0] . 'c' }
2746
+    },
2747
+    from1 => {
2748
+        date => sub { $_[0] . 'd' }
2749
+    },
2750
+    from2 => {
2751
+        date => sub { $_[0] . 'e' }
2746 2752
     }
2747 2753
 );
2748 2754
 $dbi->insert({key1 => '1'}, table => 'table1', filter => {key1 => sub { $_[0] . 'a' }});
2749 2755
 $result = $dbi->select(table => 'table1');
2750
-$result->filter(key1 => sub { $_[0] . 'd' });
2751
-is($result->fetch_first->[0], '1abcd');
2756
+$result->filter(key1 => sub { $_[0] . 'f' });
2757
+is($result->fetch_first->[0], '1abcdef');
2758
+
2759
+$dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2760
+$dbi->execute("create table table1 (key1 Date, key2 datetime)");
2761
+$dbi->type_rule(
2762
+    from1 => {
2763
+        date => sub { $_[0] . 'p' }
2764
+    },
2765
+    from2 => {
2766
+        date => sub { $_[0] . 'q' }
2767
+    },
2768
+);
2769
+$dbi->insert({key1 => '1'}, table => 'table1');
2770
+$result = $dbi->select(table => 'table1');
2771
+$result->type_rule(
2772
+    from1 => {
2773
+        date => sub { $_[0] . 'd' }
2774
+    },
2775
+    from2 => {
2776
+        date => sub { $_[0] . 'e' }
2777
+    }
2778
+);
2779
+$result->filter(key1 => sub { $_[0] . 'f' });
2780
+is($result->fetch_first->[0], '1def');
2752 2781
 
2753 2782
 test 'type_rule_off';
2754 2783
 $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2755 2784
 $dbi->execute("create table table1 (key1 Date, key2 datetime)");
2756 2785
 $dbi->type_rule(
2757
-    from => {
2786
+    from1 => {
2758 2787
         date => sub { $_[0] * 2 },
2759 2788
     },
2760
-    into => {
2789
+    into1 => {
2761 2790
         date => sub { $_[0] * 2 },
2762 2791
     }
2763 2792
 );
... ...
@@ -2768,10 +2797,10 @@ is($result->type_rule_off(1)->fetch->[0], 2);
2768 2797
 $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2769 2798
 $dbi->execute("create table table1 (key1 Date, key2 datetime)");
2770 2799
 $dbi->type_rule(
2771
-    from => {
2800
+    from1 => {
2772 2801
         date => sub { $_[0] * 2 },
2773 2802
     },
2774
-    into => {
2803
+    into1 => {
2775 2804
         date => sub { $_[0] * 3 },
2776 2805
     }
2777 2806
 );
... ...
@@ -2782,10 +2811,10 @@ is($result->one->{key1}, 4);
2782 2811
 $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2783 2812
 $dbi->execute("create table table1 (key1 Date, key2 datetime)");
2784 2813
 $dbi->type_rule(
2785
-    from => {
2814
+    from1 => {
2786 2815
         date => sub { $_[0] * 2 },
2787 2816
     },
2788
-    into => {
2817
+    into1 => {
2789 2818
         date => sub { $_[0] * 3 },
2790 2819
     }
2791 2820
 );
... ...
@@ -2796,10 +2825,10 @@ is($result->one->{key1}, 12);
2796 2825
 $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2797 2826
 $dbi->execute("create table table1 (key1 Date, key2 datetime)");
2798 2827
 $dbi->type_rule(
2799
-    from => {
2828
+    from1 => {
2800 2829
         date => sub { $_[0] * 2 },
2801 2830
     },
2802
-    into => {
2831
+    into1 => {
2803 2832
         date => sub { $_[0] * 3 },
2804 2833
     }
2805 2834
 );
... ...
@@ -2811,7 +2840,7 @@ $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2811 2840
 $dbi->execute("create table table1 (key1 Date, key2 datetime)");
2812 2841
 $dbi->register_filter(ppp => sub { uc $_[0] });
2813 2842
 $dbi->type_rule(
2814
-    into => {
2843
+    into1 => {
2815 2844
         date => 'ppp'
2816 2845
     }
2817 2846
 );
... ...
@@ -2820,32 +2849,17 @@ $result = $dbi->select(table => 'table1');
2820 2849
 is($result->one->{key1}, 'A');
2821 2850
 
2822 2851
 eval{$dbi->type_rule(
2823
-    into => {
2852
+    into1 => {
2824 2853
         date => 'pp'
2825 2854
     }
2826 2855
 )};
2827 2856
 like($@, qr/not registered/);
2828 2857
 
2829
-$dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2830
-$dbi->execute("create table table1 (key1 Date, key2 datetime)");
2831
-$dbi->type_rule(
2832
-    from => {
2833
-        date => sub { $_[0] * 2 },
2834
-    },
2835
-    into => {
2836
-        date => sub { $_[0] * 3 },
2837
-    }
2838
-);
2839
-$dbi->insert({key1 => 2}, table => 'table1');
2840
-$result = $dbi->select(table => 'table1');
2841
-delete $result->type_rule->{date};
2842
-is($result->one->{key1}, 6);
2843
-
2844 2858
 $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2845 2859
 $dbi->execute("create table table1 (key1 Date, key2 datetime)");
2846 2860
 eval {
2847 2861
     $dbi->type_rule(
2848
-        from => {
2862
+        from1 => {
2849 2863
             Date => sub { $_[0] * 2 },
2850 2864
         }
2851 2865
     );
... ...
@@ -2854,7 +2868,7 @@ like($@, qr/lower/);
2854 2868
 
2855 2869
 eval {
2856 2870
     $dbi->type_rule(
2857
-        into => {
2871
+        into1 => {
2858 2872
             Date => sub { $_[0] * 2 },
2859 2873
         }
2860 2874
     );
... ...
@@ -2864,10 +2878,10 @@ like($@, qr/lower/);
2864 2878
 $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2865 2879
 $dbi->execute("create table table1 (key1 Date, key2 datetime)");
2866 2880
 $dbi->type_rule(
2867
-    from => {
2881
+    from1 => {
2868 2882
         date => sub { $_[0] * 2 },
2869 2883
     },
2870
-    into => {
2884
+    into1 => {
2871 2885
         date => sub { $_[0] * 3 },
2872 2886
     }
2873 2887
 );
... ...
@@ -2879,48 +2893,68 @@ is($result->one->{key1}, 6);
2879 2893
 $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2880 2894
 $dbi->execute("create table table1 (key1 Date, key2 datetime)");
2881 2895
 $dbi->type_rule(
2882
-    from => {
2896
+    from1 => {
2883 2897
         date => sub { $_[0] * 2 },
2884 2898
         datetime => sub { $_[0] * 4 },
2885 2899
     },
2886 2900
 );
2887 2901
 $dbi->insert({key1 => 2, key2 => 2}, table => 'table1');
2888 2902
 $result = $dbi->select(table => 'table1');
2889
-$result->type_rule(date => sub { $_[0] * 3 });
2903
+$result->type_rule(
2904
+    from1 => {
2905
+        date => sub { $_[0] * 3 }
2906
+    }
2907
+);
2890 2908
 $row = $result->one;
2891 2909
 is($row->{key1}, 6);
2892
-is($row->{key2}, 8);
2910
+is($row->{key2}, 2);
2911
+
2893 2912
 $result = $dbi->select(table => 'table1');
2894
-$result->type_rule(date => sub { $_[0] * 3 });
2913
+$result->type_rule(
2914
+    from1 => {
2915
+        date => sub { $_[0] * 3 }
2916
+    }
2917
+);
2895 2918
 $row = $result->one;
2896 2919
 is($row->{key1}, 6);
2897
-is($row->{key2}, 8);
2920
+is($row->{key2}, 2);
2921
+
2898 2922
 $result = $dbi->select(table => 'table1');
2899
-$result->type_rule({date => sub { $_[0] * 3 }});
2923
+$result->type_rule(
2924
+    from1 => {
2925
+        date => sub { $_[0] * 3 }
2926
+    }
2927
+);
2900 2928
 $row = $result->one;
2901 2929
 is($row->{key1}, 6);
2902 2930
 is($row->{key2}, 2);
2903 2931
 $result = $dbi->select(table => 'table1');
2904
-$result->type_rule([date => sub { $_[0] * 3 }]);
2932
+$result->type_rule(
2933
+    from1 => [date => sub { $_[0] * 3 }]
2934
+);
2905 2935
 $row = $result->one;
2906 2936
 is($row->{key1}, 6);
2907 2937
 is($row->{key2}, 2);
2908 2938
 $dbi->register_filter(fivetimes => sub { $_[0] * 5});
2909 2939
 $result = $dbi->select(table => 'table1');
2910
-$result->type_rule(date => 'fivetimes');
2940
+$result->type_rule(
2941
+    from1 => [date => 'fivetimes']
2942
+);
2911 2943
 $row = $result->one;
2912 2944
 is($row->{key1}, 10);
2913
-is($row->{key2}, 8);
2945
+is($row->{key2}, 2);
2914 2946
 $result = $dbi->select(table => 'table1');
2915
-$result->type_rule(date => undef);
2947
+$result->type_rule(
2948
+    from1 => [date => undef]
2949
+);
2916 2950
 $row = $result->one;
2917 2951
 is($row->{key1}, 2);
2918
-is($row->{key2}, 8);
2952
+is($row->{key2}, 2);
2919 2953
 
2920 2954
 $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2921 2955
 $dbi->execute("create table table1 (key1 Date, key2 datetime)");
2922 2956
 $dbi->type_rule(
2923
-    from => {
2957
+    from1 => {
2924 2958
         date => sub { $_[0] * 2 },
2925 2959
     },
2926 2960
 );
... ...
@@ -2932,7 +2966,7 @@ is($result->one->{key1}, 12);
2932 2966
 $dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2933 2967
 $dbi->execute("create table table1 (key1 Date, key2 datetime)");
2934 2968
 $dbi->type_rule(
2935
-    from => {
2969
+    from1 => {
2936 2970
         date => sub { $_[0] * 2 },
2937 2971
     },
2938 2972
 );
... ...
@@ -2941,6 +2975,69 @@ $result = $dbi->select(table => 'table1');
2941 2975
 $result->filter(key1 => sub { $_[0] * 3 });
2942 2976
 is($result->fetch->[0], 12);
2943 2977
 
2978
+$dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
2979
+$dbi->execute("create table table1 (key1 Date, key2 datetime)");
2980
+$dbi->type_rule(
2981
+    into1 => {
2982
+        date => sub { $_[0] . 'b' }
2983
+    },
2984
+    into2 => {
2985
+        date => sub { $_[0] . 'c' }
2986
+    },
2987
+    from1 => {
2988
+        date => sub { $_[0] . 'd' }
2989
+    },
2990
+    from2 => {
2991
+        date => sub { $_[0] . 'e' }
2992
+    }
2993
+);
2994
+$dbi->insert({key1 => '1'}, table => 'table1', type_rule_off => 1);
2995
+$result = $dbi->select(table => 'table1');
2996
+$result->type_rule_off(1);
2997
+is($result->fetch_first->[0], '1');
2998
+
2999
+$dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
3000
+$dbi->execute("create table table1 (key1 Date, key2 datetime)");
3001
+$dbi->type_rule(
3002
+    into1 => {
3003
+        date => sub { $_[0] . 'b' }
3004
+    },
3005
+    into2 => {
3006
+        date => sub { $_[0] . 'c' }
3007
+    },
3008
+    from1 => {
3009
+        date => sub { $_[0] . 'd' }
3010
+    },
3011
+    from2 => {
3012
+        date => sub { $_[0] . 'e' }
3013
+    }
3014
+);
3015
+$dbi->insert({key1 => '1'}, table => 'table1', type_rule1_off => 1);
3016
+$result = $dbi->select(table => 'table1');
3017
+$result->type_rule1_off(1);
3018
+is($result->fetch_first->[0], '1ce');
3019
+
3020
+$dbi = DBIx::Custom->connect(dsn => 'dbi:SQLite:dbname=:memory:');
3021
+$dbi->execute("create table table1 (key1 Date, key2 datetime)");
3022
+$dbi->type_rule(
3023
+    into1 => {
3024
+        date => sub { $_[0] . 'b' }
3025
+    },
3026
+    into2 => {
3027
+        date => sub { $_[0] . 'c' }
3028
+    },
3029
+    from1 => {
3030
+        date => sub { $_[0] . 'd' }
3031
+    },
3032
+    from2 => {
3033
+        date => sub { $_[0] . 'e' }
3034
+    }
3035
+);
3036
+$dbi->insert({key1 => '1'}, table => 'table1', type_rule2_off => 1);
3037
+$result = $dbi->select(table => 'table1');
3038
+$result->type_rule2_off(1);
3039
+is($result->fetch_first->[0], '1bd');
3040
+
2944 3041
 test 'separator';
2945 3042
 $dbi = DBIx::Custom->connect($NEW_ARGS->{0});
2946 3043
 $dbi->execute($CREATE_TABLE->{0});
+2 -2
t/dbix-custom-mysql-private.t
... ...
@@ -141,7 +141,7 @@ $dbi->each_column(
141 141
 );
142 142
 
143 143
 $dbi->type_rule(
144
-    into => {
144
+    into1 => {
145 145
         date=> sub {
146 146
             my $date = shift;
147 147
             $date =~ s/aaaaa//g;
... ...
@@ -153,7 +153,7 @@ $dbi->type_rule(
153 153
             return $date;
154 154
         },
155 155
     },
156
-    from => {
156
+    from1 => {
157 157
         # DATE
158 158
         9 => sub {
159 159
                 my $date = shift;