Showing 4 changed files with 127 additions and 56 deletions
+4
Changes
... ...
@@ -1,4 +1,8 @@
1
+0.1746
2
+    - micro optimization
1 3
 0.1745
4
+    - DBIx::Custom::Order prepend method receiving array reference
5
+      is DEPRECATED!
2 6
     - DBIx::Custom::QueryBuilder class is DEPRECATED!
3 7
     - added DBIX_CUSTOM_DISABLE_MODEL_EXECUTE environment variable
4 8
     - added DBIX_CUSTOM_TAG_PARSE environment variable
+6
lib/DBIx/Custom.pm
... ...
@@ -3511,6 +3511,12 @@ L<DBIx::Custom::Tag>
3511 3511
 
3512 3512
     This module is DEPRECATED! # will be removed at 2017/1/1
3513 3513
 
3514
+L<DBIx::Custom::Order>
3515
+
3516
+    # Other
3517
+    prepend method array reference receiving
3518
+      $order->prepend(['book', 'desc']); # will be removed 2017/1/1
3519
+
3514 3520
 =head1 BACKWARDS COMPATIBILITY POLICY
3515 3521
 
3516 3522
 If a functionality is DEPRECATED, you can know it by DEPRECATED warnings
+2 -12
lib/DBIx/Custom/Order.pm
... ...
@@ -13,6 +13,8 @@ sub prepend {
13 13
     
14 14
     for my $order (reverse @_) {
15 15
         if (ref $order eq 'ARRAY') {
16
+            warn "prepend method receiving array reference is DEPRECATED! " .
17
+                 "use q method to quote column name.";
16 18
             my $column = shift @$order;
17 19
             $column = $self->dbi->q($column) if defined $column;
18 20
             my $derection = shift @$order;
... ...
@@ -83,18 +85,6 @@ and implements the following new ones.
83 85
 
84 86
 Prepend order parts to C<orders>.
85 87
 
86
-You can pass array reference, which contain column name and direction.
87
-Column name is quoted properly
88
-    
89
-    # Column name and direction
90
-    $order->prepend(['book-title']);
91
-    $order->prepend([qw/book-title desc/]);
92
-
93
-This is expanded to the following way.
94
-
95
-    "book-title"
96
-    "book-title" desc
97
-
98 88
 =head2 C<to_string>
99 89
 
100 90
     my $order_by = $order->to_string;
+115 -44
lib/DBIx/Custom/Result.pm
... ...
@@ -39,6 +39,121 @@ sub filter {
39 39
     return $self->{filter} ||= {};
40 40
 }
41 41
 
42
+sub _cache {
43
+    my $self = shift;
44
+    $self->{_type_map} = {};
45
+    $self->{_pos} = {};
46
+    $self->{_columns} = {};
47
+    for (my $i = 0; $i < @{$self->{sth}->{NAME}}; $i++) {
48
+        my $type = lc $self->{sth}{TYPE}[$i];
49
+        my $name = $self->{sth}{NAME}[$i];
50
+        $self->{_type_map}{$type} ||= [];
51
+        push @{$self->{_type_map}{$type}}, $name;
52
+        $self->{_pos}{$name} ||= [];
53
+        push @{$self->{_pos}{$name}}, $i;
54
+        $self->{_columns}{$name} = 1;
55
+    }
56
+    $self->{_cache} = 1;
57
+}
58
+
59
+=pod
60
+sub fetch {
61
+    my $self = shift;
62
+    
63
+    # Info
64
+    $self->_cache unless $self->{_cache};
65
+    
66
+    # Fetch
67
+    my @row = $self->{sth}->fetchrow_array;
68
+    return unless @row;
69
+    
70
+    # Type rule
71
+    if ((my $from = $self->type_rule->{from1}) && !$self->{type_rule_off} && !$self->{type_rule1_off}) {
72
+        for my $type (keys %$from) {
73
+            for my $column (@{$self->{_type_map}->{$type}}) {
74
+                $row[$_] = $from->{$type}->($row[$_])
75
+                  for @{$self->{_pos}{$column}};
76
+            }
77
+        }
78
+    }
79
+    if ((my $from = $self->type_rule->{from2}) && !$self->{type_rule_off} && !$self->{type_rule2_off}) {
80
+        for my $type (keys %$from) {
81
+            for my $column (@{$self->{_type_map}->{$type}}) {
82
+                $row[$_] = $from->{$type}->($row[$_])
83
+                  for @{$self->{_pos}{$column}};
84
+            }
85
+        }
86
+    }
87
+    
88
+    # Filter
89
+    if (($self->{filter} || $self->{default_filter}) && !$self->{filter_off}) {
90
+        for my $column (keys %{$self->{filter}}) {
91
+            $row[$_] = ($self->{filter}->{$column} || $self->{default_filter} || sub { shift })
92
+                ->($row[$_])
93
+              for @{$self->{_pos}{$column}};
94
+        }
95
+    }
96
+    if ($self->{end_filter} && !$self->{filter_off}) {
97
+         for my $column (keys %{$self->{end_filter}}) {
98
+             $row[$_] = $self->{end_filter}->{$column}->($row[$_])
99
+               for @{$self->{_pos}{$column}};
100
+         }
101
+    }
102
+
103
+    return \@row;
104
+}
105
+=cut
106
+
107
+sub fetch_hash {
108
+    my $self = shift;
109
+    
110
+    # Info
111
+    $self->_cache unless $self->{_cache};
112
+    
113
+    # Fetch
114
+    return unless my $row = $self->{sth}->fetchrow_hashref;
115
+    
116
+    # Type rule
117
+    if ($self->{type_rule}->{from1} &&
118
+      !$self->{type_rule_off} && !$self->{type_rule1_off})
119
+    {
120
+        my $from = $self->{type_rule}->{from1};
121
+        for my $type (keys %$from) {
122
+            $from->{$type} and $row->{$_} = $from->{$type}->($row->{$_})
123
+              for @{$self->{_type_map}->{$type}};
124
+        }
125
+    }
126
+    if ($self->{type_rule}->{from2} &&
127
+      !$self->{type_rule_off} && !$self->{type_rule2_off})
128
+    {
129
+        my $from = $self->{type_rule}->{from2};
130
+        for my $type (keys %{$self->{type_rule}->{from2}}) {
131
+            $from->{$type} and $row->{$_} = $from->{$type}->($row->{$_})
132
+              for @{$self->{_type_map}->{$type}};
133
+        }
134
+    }        
135
+    # Filter
136
+    if (($self->{filter} || $self->{default_filter}) &&
137
+      !$self->{filter_off})
138
+    {
139
+         my @columns = $self->{default_filter} ? keys %{$self->{_columns}}
140
+           : keys %{$self->{filter}};
141
+         
142
+         for my $column (@columns) {
143
+             next unless exists $row->{$column};
144
+             my $filter = exists $self->{filter}->{$column} ? $self->{filter}->{$column}
145
+               : $self->{default_filter};
146
+             $row->{$column} = $filter->($row->{$column}) if $filter;
147
+         }
148
+    }
149
+    if ($self->{end_filter} && !$self->{filter_off}) {
150
+         exists $self->{_columns}{$_} && $self->{end_filter}->{$_} and
151
+             $row->{$_} = $self->{end_filter}->{$_}->($row->{$_})
152
+           for keys %{$self->{end_filter}};
153
+    }
154
+    $row;
155
+}
156
+
42 157
 sub fetch {
43 158
     my $self = shift;
44 159
     
... ...
@@ -104,50 +219,6 @@ sub fetch_first {
104 219
     return $row;
105 220
 }
106 221
 
107
-sub fetch_hash {
108
-    my $self = shift;
109
-    
110
-    # Info
111
-    my $columns = $self->{sth}->{NAME};
112
-    my $types = $self->{sth}->{TYPE};
113
-    
114
-    # Fetch
115
-    my $row = $self->{sth}->fetchrow_arrayref;
116
-    return unless $row;
117
-
118
-    # Filter
119
-    my $hash_row = {};
120
-    my $filter  = $self->filter;
121
-    my $end_filter = $self->{end_filter} || {};
122
-    my $type_rule1 = $self->type_rule->{from1} || {};
123
-    my $type_rule2 = $self->type_rule->{from2} || {};
124
-    for (my $i = 0; $i < @$columns; $i++) {
125
-        
126
-        # Column
127
-        my $column = $columns->[$i];
128
-        $hash_row->{$column} = $row->[$i];
129
-        
130
-        # Type rule
131
-        my $type_filter1 = $type_rule1->{lc($types->[$i])};
132
-        $hash_row->{$column} = $type_filter1->($hash_row->{$column})
133
-        if  !$self->{type_rule_off} && !$self->{type_rule1_off}
134
-         && $type_filter1;
135
-        my $type_filter2 = $type_rule2->{lc($types->[$i])};
136
-        $hash_row->{$column} = $type_filter2->($hash_row->{$column})
137
-        if  !$self->{type_rule_off} && !$self->{type_rule2_off}
138
-         && $type_filter2;
139
-        
140
-        # Filter
141
-        my $f = $filter->{$column} || $self->{default_filter};
142
-        $hash_row->{$column} = $f->($hash_row->{$column})
143
-          if $f && !$self->{filter_off};
144
-        $hash_row->{$column} = $end_filter->{$column}->($hash_row->{$column})
145
-          if $end_filter->{$column} && !$self->{filter_off};
146
-    }
147
-    
148
-    return $hash_row;
149
-}
150
-
151 222
 sub fetch_hash_all {
152 223
     my $self = shift;
153 224