... | ... |
@@ -1,3 +1,7 @@ |
1 |
+0.1711 |
|
2 |
+ - renamed EXPERIMENTAL available_type_name to available_typename |
|
3 |
+ - renamed EXPERIMENTAL available_data_type to available_datatype |
|
4 |
+ - added EXPERIMENTAL DBIx::Custom::Where map_if method |
|
1 | 5 |
0.1710 |
2 | 6 |
- use more DBIx::Custom information in sub modules to decrease bugs |
3 | 7 |
(very sorry, this change can't keep backword compatible, |
... | ... |
@@ -905,7 +905,7 @@ sub setup_model { |
905 | 905 |
return $self; |
906 | 906 |
} |
907 | 907 |
|
908 |
-sub available_data_type { |
|
908 |
+sub available_datatype { |
|
909 | 909 |
my $self = shift; |
910 | 910 |
|
911 | 911 |
my $data_types = ''; |
... | ... |
@@ -921,7 +921,7 @@ sub available_data_type { |
921 | 921 |
return $data_types; |
922 | 922 |
} |
923 | 923 |
|
924 |
-sub available_type_name { |
|
924 |
+sub available_typename { |
|
925 | 925 |
my $self = shift; |
926 | 926 |
|
927 | 927 |
# Type Names |
... | ... |
@@ -2004,16 +2004,16 @@ L<DBIx::Custom> inherits all methods from L<Object::Simple> |
2004 | 2004 |
and use all methods of L<DBI> |
2005 | 2005 |
and implements the following new ones. |
2006 | 2006 |
|
2007 |
-=head2 C<available_data_type> EXPERIMENTAL |
|
2007 |
+=head2 C<available_datatype> EXPERIMENTAL |
|
2008 | 2008 |
|
2009 |
- print $dbi->available_data_type; |
|
2009 |
+ print $dbi->available_datatype; |
|
2010 | 2010 |
|
2011 | 2011 |
Get available data types. You can use these data types |
2012 | 2012 |
in C<type rule>'s C<from1> and C<from2> section. |
2013 | 2013 |
|
2014 |
-=head2 C<available_type_name> EXPERIMENTAL |
|
2014 |
+=head2 C<available_typename> EXPERIMENTAL |
|
2015 | 2015 |
|
2016 |
- print $dbi->available_type_name; |
|
2016 |
+ print $dbi->available_typename; |
|
2017 | 2017 |
|
2018 | 2018 |
Get available type names. You can use these type names in |
2019 | 2019 |
C<type_rule>'s C<into1> and C<into2> section. |
... | ... |
@@ -2709,15 +2709,15 @@ This need C<table> option in each method. |
2709 | 2709 |
|
2710 | 2710 |
=back |
2711 | 2711 |
|
2712 |
-You get all type name used in database by C<available_type_name>. |
|
2712 |
+You get all type name used in database by C<available_typename>. |
|
2713 | 2713 |
|
2714 |
- print $dbi->available_type_name; |
|
2714 |
+ print $dbi->available_typename; |
|
2715 | 2715 |
|
2716 | 2716 |
In C<from1> and C<from2> you specify data type, not type name. |
2717 | 2717 |
C<from2> is executed after C<from1>. |
2718 |
-You get all data type by C<available_data_type>. |
|
2718 |
+You get all data type by C<available_datatype>. |
|
2719 | 2719 |
|
2720 |
- print $dbi->available_data_type; |
|
2720 |
+ print $dbi->available_datatype; |
|
2721 | 2721 |
|
2722 | 2722 |
You can also specify multiple types at once. |
2723 | 2723 |
|
... | ... |
@@ -10,7 +10,8 @@ use overload '""' => sub { shift->to_string }, fallback => 1; |
10 | 10 |
push @DBIx::Custom::CARP_NOT, __PACKAGE__; |
11 | 11 |
|
12 | 12 |
has [qw/dbi param/], |
13 |
- clause => sub { [] }; |
|
13 |
+ clause => sub { [] }, |
|
14 |
+ map_if => 'exists'; |
|
14 | 15 |
|
15 | 16 |
sub new { |
16 | 17 |
my $self = shift->SUPER::new(@_); |
... | ... |
@@ -40,7 +41,19 @@ sub to_string { |
40 | 41 |
my $clause = $self->clause; |
41 | 42 |
$clause = ['and', $clause] unless ref $clause eq 'ARRAY'; |
42 | 43 |
$clause->[0] = 'and' unless @$clause; |
43 |
- |
|
44 |
+ |
|
45 |
+ # Map condition |
|
46 |
+ my $map_if = $self->map_if || ''; |
|
47 |
+ $map_if = $map_if eq 'exists' ? $map_if |
|
48 |
+ : $map_if eq 'defined' ? sub { defined $_[0] } |
|
49 |
+ : $map_if eq 'length' ? sub { length $_[0] } |
|
50 |
+ : ref $map_if eq 'CODE' ? $map_if |
|
51 |
+ : undef; |
|
52 |
+ |
|
53 |
+ croak "You can must specify right value to C<map_if> " . _subname |
|
54 |
+ unless $map_if; |
|
55 |
+ $self->{_map_if} = $map_if; |
|
56 |
+ |
|
44 | 57 |
# Parse |
45 | 58 |
my $where = []; |
46 | 59 |
my $count = {}; |
... | ... |
@@ -123,13 +136,25 @@ sub _parse { |
123 | 136 |
my $param = $self->param; |
124 | 137 |
if (ref $param eq 'HASH') { |
125 | 138 |
if (exists $param->{$column}) { |
139 |
+ my $map_if = $self->{_map_if}; |
|
140 |
+ |
|
126 | 141 |
if (ref $param->{$column} eq 'ARRAY') { |
127 |
- $pushed = 1 |
|
128 |
- if exists $param->{$column}->[$count - 1] |
|
129 |
- && ref $param->{$column}->[$count - 1] ne 'DBIx::Custom::NotExists'; |
|
142 |
+ unless (ref $param->{$column}->[$count - 1] eq 'DBIx::Custom::NotExists') { |
|
143 |
+ if ($map_if eq 'exists') { |
|
144 |
+ $pushed = 1 if exists $param->{$column}->[$count - 1]; |
|
145 |
+ } |
|
146 |
+ else { |
|
147 |
+ $pushed = 1 if $map_if->($param->{$column}->[$count - 1]); |
|
148 |
+ } |
|
149 |
+ } |
|
130 | 150 |
} |
131 | 151 |
elsif ($count == 1) { |
132 |
- $pushed = 1; |
|
152 |
+ if ($map_if eq 'exists') { |
|
153 |
+ $pushed = 1 if exists $param->{$column}; |
|
154 |
+ } |
|
155 |
+ else { |
|
156 |
+ $pushed = 1 if $map_if->($param->{$column}); |
|
157 |
+ } |
|
133 | 158 |
} |
134 | 159 |
} |
135 | 160 |
push @$where, $clause if $pushed; |
... | ... |
@@ -175,6 +200,35 @@ If all parameter names is exists. |
175 | 200 |
|
176 | 201 |
"where ( title = :title and ( date < :date or date > :date ) )" |
177 | 202 |
|
203 |
+=head2 C<map_if EXPERIMENTAL> |
|
204 |
+ |
|
205 |
+ my $map_if = $where->map_if($condition); |
|
206 |
+ $where->map_if($condition); |
|
207 |
+ |
|
208 |
+If C<clause> contain named placeholder like ':title{=}' |
|
209 |
+and C<param> contain the corresponding key like {title => 'Perl'}, |
|
210 |
+C<to_string> method join the cluase and convert to placeholder |
|
211 |
+like 'title = ?'. |
|
212 |
+ |
|
213 |
+C<map_if> method can change this mapping rule. |
|
214 |
+Default is C<exists>. If the key exists, mapping is done. |
|
215 |
+ |
|
216 |
+ $where->map_if('exists'); |
|
217 |
+ |
|
218 |
+In case C<defined> is specified, if the value is defined, |
|
219 |
+mapping is done. |
|
220 |
+ |
|
221 |
+ $where->map_if('defined'); |
|
222 |
+ |
|
223 |
+In case C<length> is specified, the value is defined |
|
224 |
+and the length is bigger than 0, mappting is done. |
|
225 |
+ |
|
226 |
+ $where->map_if('length'); |
|
227 |
+ |
|
228 |
+You can also subroutine like C<sub { defined $_[0] }> for mappging. |
|
229 |
+ |
|
230 |
+ $where->map_if(sub { defined $_[0] }); |
|
231 |
+ |
|
178 | 232 |
=head2 C<param> |
179 | 233 |
|
180 | 234 |
my $param = $where->param; |
... | ... |
@@ -238,4 +238,6 @@ $result = $dbi->execute( |
238 | 238 |
$rows = $result->all; |
239 | 239 |
is_deeply($rows, [{key1 => 'a:b c:d', key2 => 2}]); |
240 | 240 |
|
241 |
+ |
|
242 |
+ |
|
241 | 243 |
1; |
... | ... |
@@ -1221,6 +1221,74 @@ $result = $dbi->select( |
1221 | 1221 |
$row = $result->all; |
1222 | 1222 |
is_deeply($row, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}]); |
1223 | 1223 |
|
1224 |
+$where = $dbi->where; |
|
1225 |
+$where->clause(['and', ':key1{=}']); |
|
1226 |
+$where->param({key1 => undef}); |
|
1227 |
+$result = $dbi->execute("select * from table1 $where", {key1 => 1}); |
|
1228 |
+$row = $result->all; |
|
1229 |
+is_deeply($row, [{key1 => 1, key2 => 2}]); |
|
1230 |
+ |
|
1231 |
+$where = $dbi->where; |
|
1232 |
+$where->clause(['and', ':key1{=}']); |
|
1233 |
+$where->param({key1 => undef}); |
|
1234 |
+$where->map_if('defined'); |
|
1235 |
+$result = $dbi->execute("select * from table1 $where", {key1 => 1}); |
|
1236 |
+$row = $result->all; |
|
1237 |
+is_deeply($row, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}]); |
|
1238 |
+ |
|
1239 |
+$where = $dbi->where; |
|
1240 |
+$where->clause(['or', ':key1{=}', ':key1{=}']); |
|
1241 |
+$where->param({key1 => [undef, undef]}); |
|
1242 |
+$result = $dbi->execute("select * from table1 $where", {key1 => [1, 0]}); |
|
1243 |
+$row = $result->all; |
|
1244 |
+is_deeply($row, [{key1 => 1, key2 => 2}]); |
|
1245 |
+$result = $dbi->execute("select * from table1 $where", {key1 => [0, 1]}); |
|
1246 |
+$row = $result->all; |
|
1247 |
+is_deeply($row, [{key1 => 1, key2 => 2}]); |
|
1248 |
+ |
|
1249 |
+$where = $dbi->where; |
|
1250 |
+$where->clause(['and', ':key1{=}']); |
|
1251 |
+$where->param({key1 => [undef, undef]}); |
|
1252 |
+$where->map_if('defined'); |
|
1253 |
+$result = $dbi->execute("select * from table1 $where", {key1 => [1, 0]}); |
|
1254 |
+$row = $result->all; |
|
1255 |
+is_deeply($row, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}]); |
|
1256 |
+$result = $dbi->execute("select * from table1 $where", {key1 => [0, 1]}); |
|
1257 |
+$row = $result->all; |
|
1258 |
+is_deeply($row, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}]); |
|
1259 |
+ |
|
1260 |
+$where = $dbi->where; |
|
1261 |
+$where->clause(['and', ':key1{=}']); |
|
1262 |
+$where->param({key1 => 0}); |
|
1263 |
+$where->map_if('length'); |
|
1264 |
+$result = $dbi->execute("select * from table1 $where", {key1 => 1}); |
|
1265 |
+$row = $result->all; |
|
1266 |
+is_deeply($row, [{key1 => 1, key2 => 2}]); |
|
1267 |
+ |
|
1268 |
+$where = $dbi->where; |
|
1269 |
+$where->clause(['and', ':key1{=}']); |
|
1270 |
+$where->param({key1 => ''}); |
|
1271 |
+$where->map_if('length'); |
|
1272 |
+$result = $dbi->execute("select * from table1 $where", {key1 => 1}); |
|
1273 |
+$row = $result->all; |
|
1274 |
+is_deeply($row, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}]); |
|
1275 |
+ |
|
1276 |
+$where = $dbi->where; |
|
1277 |
+$where->clause(['and', ':key1{=}']); |
|
1278 |
+$where->param({key1 => 5}); |
|
1279 |
+$where->map_if(sub { ($_[0] || '') eq 5 }); |
|
1280 |
+$result = $dbi->execute("select * from table1 $where", {key1 => 1}); |
|
1281 |
+$row = $result->all; |
|
1282 |
+is_deeply($row, [{key1 => 1, key2 => 2}]); |
|
1283 |
+ |
|
1284 |
+$where = $dbi->where; |
|
1285 |
+$where->clause(['and', ':key1{=}']); |
|
1286 |
+$where->param({key1 => 7}); |
|
1287 |
+$where->map_if(sub { ($_[0] || '') eq 5 }); |
|
1288 |
+$result = $dbi->execute("select * from table1 $where", {key1 => 1}); |
|
1289 |
+$row = $result->all; |
|
1290 |
+is_deeply($row, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}]); |
|
1291 |
+ |
|
1224 | 1292 |
|
1225 | 1293 |
test 'dbi_option default'; |
1226 | 1294 |
$dbi = DBIx::Custom->new; |
... | ... |
@@ -3108,9 +3176,9 @@ $result = $model->select(column => 'key1'); |
3108 | 3176 |
$result->filter(key1 => sub { $_[0] * 2 }); |
3109 | 3177 |
is_deeply($result->one, {key1 => 2}); |
3110 | 3178 |
|
3111 |
-test 'available_date_type'; |
|
3179 |
+test 'available_datetype'; |
|
3112 | 3180 |
$dbi = DBIx::Custom->connect(%memory); |
3113 |
-ok($dbi->can('available_data_type')); |
|
3181 |
+ok($dbi->can('available_datatype')); |
|
3114 | 3182 |
|
3115 | 3183 |
|
3116 | 3184 |
test 'select prefix option'; |
... | ... |
@@ -3560,3 +3628,4 @@ like($@, qr/unexpected "}"/, "error : 1"); |
3560 | 3628 |
$source = "a {= {}"; |
3561 | 3629 |
eval{$builder->build_query($source)}; |
3562 | 3630 |
like($@, qr/unexpected "{"/, "error : 2"); |
3631 |
+ |