| ... | ... |
@@ -1,7 +1,8 @@ |
| 1 | 1 |
0.1711 |
| 2 | 2 |
- renamed EXPERIMENTAL available_type_name to available_typename |
| 3 | 3 |
- renamed EXPERIMENTAL available_data_type to available_datatype |
| 4 |
- - added EXPERIMENTAL DBIx::Custom::Where map_if method |
|
| 4 |
+ - added EXPERIMENTAL DBIx::Custom::Where if method |
|
| 5 |
+ - added EXPERIMENTAL DBIx::Custom::Where map attribute |
|
| 5 | 6 |
0.1710 |
| 6 | 7 |
- use more DBIx::Custom information in sub modules to decrease bugs |
| 7 | 8 |
(very sorry, this change can't keep backword compatible, |
| ... | ... |
@@ -10,8 +10,105 @@ 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 { [] },
|
|
| 14 |
- map_if => 'exists'; |
|
| 13 |
+ map => sub { {} },
|
|
| 14 |
+ clause => sub { [] };
|
|
| 15 |
+ |
|
| 16 |
+sub _map_param {
|
|
| 17 |
+ my $self = shift; |
|
| 18 |
+ my $param = shift; |
|
| 19 |
+ |
|
| 20 |
+ return $param if !defined $param; |
|
| 21 |
+ |
|
| 22 |
+ my %map = @_; |
|
| 23 |
+ |
|
| 24 |
+ # Mapping |
|
| 25 |
+ my $map_param = {};
|
|
| 26 |
+ foreach my $key (keys %$param) {
|
|
| 27 |
+ |
|
| 28 |
+ unless (exists $map{$key}) {
|
|
| 29 |
+ if (ref $param->{$key} eq 'ARRAY') {
|
|
| 30 |
+ $map_param->{$key} = [@{$param->{$key}}];
|
|
| 31 |
+ } |
|
| 32 |
+ else {
|
|
| 33 |
+ $map_param->{$key} = $param->{$key};
|
|
| 34 |
+ } |
|
| 35 |
+ next; |
|
| 36 |
+ } |
|
| 37 |
+ |
|
| 38 |
+ my $value_cb; |
|
| 39 |
+ my $condition; |
|
| 40 |
+ my $map_key; |
|
| 41 |
+ |
|
| 42 |
+ # Get mapping information |
|
| 43 |
+ if (ref $map{$key} eq 'ARRAY') {
|
|
| 44 |
+ foreach my $some (@{$map{$key}}) {
|
|
| 45 |
+ $map_key = $some unless ref $some; |
|
| 46 |
+ $condition = $some->{if} if ref $some eq 'HASH';
|
|
| 47 |
+ $value_cb = $some if ref $some eq 'CODE'; |
|
| 48 |
+ } |
|
| 49 |
+ } |
|
| 50 |
+ else {
|
|
| 51 |
+ $map_key = $map{$key};
|
|
| 52 |
+ } |
|
| 53 |
+ $value_cb ||= sub { $_[0] };
|
|
| 54 |
+ $condition ||= $self->if || 'exists'; |
|
| 55 |
+ |
|
| 56 |
+ # Map parameter |
|
| 57 |
+ my $value; |
|
| 58 |
+ if (ref $condition eq 'CODE') {
|
|
| 59 |
+ if (ref $param->{$key} eq 'ARRAY') {
|
|
| 60 |
+ $map_param->{$map_key} = [];
|
|
| 61 |
+ for (my $i = 0; $i < @{$param->{$key}}; $i++) {
|
|
| 62 |
+ $map_param->{$map_key}->[$i]
|
|
| 63 |
+ = $condition->($param->{$key}->[$i]) ? $param->{$key}->[$i]
|
|
| 64 |
+ : $self->dbi->not_exists; |
|
| 65 |
+ } |
|
| 66 |
+ } |
|
| 67 |
+ else {
|
|
| 68 |
+ $map_param->{$map_key} = $value_cb->($param->{$key})
|
|
| 69 |
+ if $condition->($param->{$key});
|
|
| 70 |
+ } |
|
| 71 |
+ } |
|
| 72 |
+ elsif ($condition eq 'exists') {
|
|
| 73 |
+ if (ref $param->{$key} eq 'ARRAY') {
|
|
| 74 |
+ $map_param->{$map_key} = [];
|
|
| 75 |
+ for (my $i = 0; $i < @{$param->{$key}}; $i++) {
|
|
| 76 |
+ $map_param->{$map_key}->[$i]
|
|
| 77 |
+ = exists $param->{$key}->[$i] ? $param->{$key}->[$i]
|
|
| 78 |
+ : $self->dbi->not_exists; |
|
| 79 |
+ } |
|
| 80 |
+ } |
|
| 81 |
+ else {
|
|
| 82 |
+ $map_param->{$map_key} = $value_cb->($param->{$key})
|
|
| 83 |
+ if exists $param->{$key};
|
|
| 84 |
+ } |
|
| 85 |
+ } |
|
| 86 |
+ else { croak qq/Condition must be code reference or "exists" / . _subname }
|
|
| 87 |
+ } |
|
| 88 |
+ |
|
| 89 |
+ return $map_param; |
|
| 90 |
+} |
|
| 91 |
+ |
|
| 92 |
+sub if {
|
|
| 93 |
+ my $self = shift; |
|
| 94 |
+ if (@_) {
|
|
| 95 |
+ my $if = $_[0]; |
|
| 96 |
+ |
|
| 97 |
+ $if = $if eq 'exists' ? $if |
|
| 98 |
+ : $if eq 'defined' ? sub { defined $_[0] }
|
|
| 99 |
+ : $if eq 'length' ? sub { length $_[0] }
|
|
| 100 |
+ : ref $if eq 'CODE' ? $if |
|
| 101 |
+ : undef; |
|
| 102 |
+ |
|
| 103 |
+ croak "You can must specify right value to C<if> " . _subname |
|
| 104 |
+ unless $if; |
|
| 105 |
+ |
|
| 106 |
+ $self->{if} = $if;
|
|
| 107 |
+ return $self; |
|
| 108 |
+ } |
|
| 109 |
+ $self->{if} = 'exists' unless exists $self->{if};
|
|
| 110 |
+ return $self->{if};
|
|
| 111 |
+} |
|
| 15 | 112 |
|
| 16 | 113 |
sub new {
|
| 17 | 114 |
my $self = shift->SUPER::new(@_); |
| ... | ... |
@@ -43,16 +140,18 @@ sub to_string {
|
| 43 | 140 |
$clause->[0] = 'and' unless @$clause; |
| 44 | 141 |
|
| 45 | 142 |
# 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 |
|
| 143 |
+ my $if = $self->if || ''; |
|
| 144 |
+ $if = $if eq 'exists' ? $if |
|
| 145 |
+ : $if eq 'defined' ? sub { defined $_[0] }
|
|
| 146 |
+ : $if eq 'length' ? sub { length $_[0] }
|
|
| 147 |
+ : ref $if eq 'CODE' ? $if |
|
| 51 | 148 |
: undef; |
| 52 | 149 |
|
| 53 |
- croak "You can must specify right value to C<map_if> " . _subname |
|
| 54 |
- unless $map_if; |
|
| 55 |
- $self->{_map_if} = $map_if;
|
|
| 150 |
+ croak "You can must specify right value to C<if> " . _subname |
|
| 151 |
+ unless $if; |
|
| 152 |
+ $self->{_if} = $if;
|
|
| 153 |
+ |
|
| 154 |
+ $self->{_param} = $self->_map_param($self->param, %{$self->map});
|
|
| 56 | 155 |
|
| 57 | 156 |
# Parse |
| 58 | 157 |
my $where = []; |
| ... | ... |
@@ -133,27 +232,27 @@ sub _parse {
|
| 133 | 232 |
my $count = ++$count->{$column};
|
| 134 | 233 |
|
| 135 | 234 |
# Push |
| 136 |
- my $param = $self->param; |
|
| 235 |
+ my $param = $self->{_param};
|
|
| 137 | 236 |
if (ref $param eq 'HASH') {
|
| 138 | 237 |
if (exists $param->{$column}) {
|
| 139 |
- my $map_if = $self->{_map_if};
|
|
| 238 |
+ my $if = $self->{_if};
|
|
| 140 | 239 |
|
| 141 | 240 |
if (ref $param->{$column} eq 'ARRAY') {
|
| 142 | 241 |
unless (ref $param->{$column}->[$count - 1] eq 'DBIx::Custom::NotExists') {
|
| 143 |
- if ($map_if eq 'exists') {
|
|
| 242 |
+ if ($if eq 'exists') {
|
|
| 144 | 243 |
$pushed = 1 if exists $param->{$column}->[$count - 1];
|
| 145 | 244 |
} |
| 146 | 245 |
else {
|
| 147 |
- $pushed = 1 if $map_if->($param->{$column}->[$count - 1]);
|
|
| 246 |
+ $pushed = 1 if $if->($param->{$column}->[$count - 1]);
|
|
| 148 | 247 |
} |
| 149 | 248 |
} |
| 150 | 249 |
} |
| 151 | 250 |
elsif ($count == 1) {
|
| 152 |
- if ($map_if eq 'exists') {
|
|
| 153 |
- $pushed = 1 if exists $param->{$column};
|
|
| 251 |
+ if ($if eq 'exists') {
|
|
| 252 |
+ $pushed = 1 if exists $param->{$column};
|
|
| 154 | 253 |
} |
| 155 | 254 |
else {
|
| 156 |
- $pushed = 1 if $map_if->($param->{$column});
|
|
| 255 |
+ $pushed = 1 if $if->($param->{$column});
|
|
| 157 | 256 |
} |
| 158 | 257 |
} |
| 159 | 258 |
} |
| ... | ... |
@@ -200,34 +299,43 @@ If all parameter names is exists. |
| 200 | 299 |
|
| 201 | 300 |
"where ( title = :title and ( date < :date or date > :date ) )" |
| 202 | 301 |
|
| 203 |
-=head2 C<map_if EXPERIMENTAL> |
|
| 204 |
- |
|
| 205 |
- my $map_if = $where->map_if($condition); |
|
| 206 |
- $where->map_if($condition); |
|
| 302 |
+=head2 C<map EXPERIMENTAL> |
|
| 303 |
+ |
|
| 304 |
+Mapping parameter key and value when C<to_stirng> method is executed. |
|
| 305 |
+ |
|
| 306 |
+ $where->map({
|
|
| 307 |
+ 'id' => 'book.id', |
|
| 308 |
+ 'author' => ['book.author' => sub { '%' . $_[0] . '%' }],
|
|
| 309 |
+ 'price' => [ |
|
| 310 |
+ 'book.price', {if => sub { length $_[0] }
|
|
| 311 |
+ ] |
|
| 312 |
+ }); |
|
| 313 |
+ |
|
| 314 |
+The following option is available. |
|
| 207 | 315 |
|
| 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 = ?'. |
|
| 316 |
+=over 4 |
|
| 212 | 317 |
|
| 213 |
-C<map_if> method can change this mapping rule. |
|
| 214 |
-Default is C<exists>. If the key exists, mapping is done. |
|
| 318 |
+=item * C<if> |
|
| 319 |
+ |
|
| 320 |
+By default, if parameter key is exists, mapping is done. |
|
| 215 | 321 |
|
| 216 |
- $where->map_if('exists');
|
|
| 322 |
+ if => 'exists'; |
|
| 217 | 323 |
|
| 218 | 324 |
In case C<defined> is specified, if the value is defined, |
| 219 | 325 |
mapping is done. |
| 220 | 326 |
|
| 221 |
- $where->map_if('defined');
|
|
| 327 |
+ if => 'defined'; |
|
| 222 | 328 |
|
| 223 | 329 |
In case C<length> is specified, the value is defined |
| 224 | 330 |
and the length is bigger than 0, mappting is done. |
| 225 | 331 |
|
| 226 |
- $where->map_if('length');
|
|
| 332 |
+ if => 'length'; |
|
| 227 | 333 |
|
| 228 | 334 |
You can also subroutine like C<sub { defined $_[0] }> for mappging.
|
| 229 | 335 |
|
| 230 |
- $where->map_if(sub { defined $_[0] });
|
|
| 336 |
+ if => sub { defined $_[0] }
|
|
| 337 |
+ |
|
| 338 |
+=back |
|
| 231 | 339 |
|
| 232 | 340 |
=head2 C<param> |
| 233 | 341 |
|
| ... | ... |
@@ -249,6 +357,13 @@ L<DBIx::Custom> object. |
| 249 | 357 |
L<DBIx::Custom::Where> inherits all methods from L<Object::Simple> |
| 250 | 358 |
and implements the following new ones. |
| 251 | 359 |
|
| 360 |
+=head2 C<if EXPERIMENTAL> |
|
| 361 |
+ |
|
| 362 |
+ my $if = $where->if($condition); |
|
| 363 |
+ $where->if($condition); |
|
| 364 |
+ |
|
| 365 |
+C<if> is default of C<map> method C<if> option. |
|
| 366 |
+ |
|
| 252 | 367 |
=head2 C<to_string> |
| 253 | 368 |
|
| 254 | 369 |
$where->to_string; |
| ... | ... |
@@ -1060,12 +1060,6 @@ $where = $dbi->where |
| 1060 | 1060 |
eval{$where->to_string};
|
| 1061 | 1061 |
like($@, qr/one column/); |
| 1062 | 1062 |
|
| 1063 |
-$where = $dbi->where |
|
| 1064 |
- ->clause('key1 = :key1')
|
|
| 1065 |
- ->param([]); |
|
| 1066 |
-eval{$where->to_string};
|
|
| 1067 |
-like($@, qr/Parameter/); |
|
| 1068 |
- |
|
| 1069 | 1063 |
$where = $dbi->where |
| 1070 | 1064 |
->clause(['or', ('key1 = :key1') x 3])
|
| 1071 | 1065 |
->param({key1 => [$dbi->not_exists, 1, 3]});
|
| ... | ... |
@@ -1231,7 +1225,7 @@ is_deeply($row, [{key1 => 1, key2 => 2}]);
|
| 1231 | 1225 |
$where = $dbi->where; |
| 1232 | 1226 |
$where->clause(['and', ':key1{=}']);
|
| 1233 | 1227 |
$where->param({key1 => undef});
|
| 1234 |
-$where->map_if('defined');
|
|
| 1228 |
+$where->if('defined');
|
|
| 1235 | 1229 |
$result = $dbi->execute("select * from table1 $where", {key1 => 1});
|
| 1236 | 1230 |
$row = $result->all; |
| 1237 | 1231 |
is_deeply($row, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}]);
|
| ... | ... |
@@ -1249,7 +1243,7 @@ is_deeply($row, [{key1 => 1, key2 => 2}]);
|
| 1249 | 1243 |
$where = $dbi->where; |
| 1250 | 1244 |
$where->clause(['and', ':key1{=}']);
|
| 1251 | 1245 |
$where->param({key1 => [undef, undef]});
|
| 1252 |
-$where->map_if('defined');
|
|
| 1246 |
+$where->if('defined');
|
|
| 1253 | 1247 |
$result = $dbi->execute("select * from table1 $where", {key1 => [1, 0]});
|
| 1254 | 1248 |
$row = $result->all; |
| 1255 | 1249 |
is_deeply($row, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}]);
|
| ... | ... |
@@ -1260,7 +1254,7 @@ is_deeply($row, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}]);
|
| 1260 | 1254 |
$where = $dbi->where; |
| 1261 | 1255 |
$where->clause(['and', ':key1{=}']);
|
| 1262 | 1256 |
$where->param({key1 => 0});
|
| 1263 |
-$where->map_if('length');
|
|
| 1257 |
+$where->if('length');
|
|
| 1264 | 1258 |
$result = $dbi->execute("select * from table1 $where", {key1 => 1});
|
| 1265 | 1259 |
$row = $result->all; |
| 1266 | 1260 |
is_deeply($row, [{key1 => 1, key2 => 2}]);
|
| ... | ... |
@@ -1268,7 +1262,7 @@ is_deeply($row, [{key1 => 1, key2 => 2}]);
|
| 1268 | 1262 |
$where = $dbi->where; |
| 1269 | 1263 |
$where->clause(['and', ':key1{=}']);
|
| 1270 | 1264 |
$where->param({key1 => ''});
|
| 1271 |
-$where->map_if('length');
|
|
| 1265 |
+$where->if('length');
|
|
| 1272 | 1266 |
$result = $dbi->execute("select * from table1 $where", {key1 => 1});
|
| 1273 | 1267 |
$row = $result->all; |
| 1274 | 1268 |
is_deeply($row, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}]);
|
| ... | ... |
@@ -1276,7 +1270,7 @@ is_deeply($row, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}]);
|
| 1276 | 1270 |
$where = $dbi->where; |
| 1277 | 1271 |
$where->clause(['and', ':key1{=}']);
|
| 1278 | 1272 |
$where->param({key1 => 5});
|
| 1279 |
-$where->map_if(sub { ($_[0] || '') eq 5 });
|
|
| 1273 |
+$where->if(sub { ($_[0] || '') eq 5 });
|
|
| 1280 | 1274 |
$result = $dbi->execute("select * from table1 $where", {key1 => 1});
|
| 1281 | 1275 |
$row = $result->all; |
| 1282 | 1276 |
is_deeply($row, [{key1 => 1, key2 => 2}]);
|
| ... | ... |
@@ -1284,7 +1278,7 @@ is_deeply($row, [{key1 => 1, key2 => 2}]);
|
| 1284 | 1278 |
$where = $dbi->where; |
| 1285 | 1279 |
$where->clause(['and', ':key1{=}']);
|
| 1286 | 1280 |
$where->param({key1 => 7});
|
| 1287 |
-$where->map_if(sub { ($_[0] || '') eq 5 });
|
|
| 1281 |
+$where->if(sub { ($_[0] || '') eq 5 });
|
|
| 1288 | 1282 |
$result = $dbi->execute("select * from table1 $where", {key1 => 1});
|
| 1289 | 1283 |
$row = $result->all; |
| 1290 | 1284 |
is_deeply($row, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}]);
|