| ... | ... |
@@ -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 |
+ |