| ... | ... |
@@ -252,24 +252,24 @@ sub delete {
|
| 252 | 252 |
my $filter = $args{filter};
|
| 253 | 253 |
my $allow_delete_all = $args{allow_delete_all};
|
| 254 | 254 |
|
| 255 |
- # Where keys |
|
| 256 |
- my @where_keys = keys %$where; |
|
| 257 |
- |
|
| 258 |
- # Not exists where keys |
|
| 259 |
- croak qq{"where" argument must be specified and } .
|
|
| 260 |
- qq{contains the pairs of column name and value}
|
|
| 261 |
- if !@where_keys && !$allow_delete_all; |
|
| 262 |
- |
|
| 263 |
- # Where clause |
|
| 264 |
- my $where_clause = ''; |
|
| 265 |
- if (@where_keys) {
|
|
| 266 |
- $where_clause = 'where '; |
|
| 267 |
- $where_clause .= "{= $_} and " for @where_keys;
|
|
| 268 |
- $where_clause =~ s/ and $//; |
|
| 255 |
+ # Where |
|
| 256 |
+ my $w; |
|
| 257 |
+ if (ref $where eq 'HASH') {
|
|
| 258 |
+ my $clause = ['and']; |
|
| 259 |
+ push @$clause, "{= $_}" for keys %$where;
|
|
| 260 |
+ $w = $self->where; |
|
| 261 |
+ $w->clause($clause); |
|
| 269 | 262 |
} |
| 263 |
+ else { $w = $where }
|
|
| 270 | 264 |
|
| 265 |
+ croak qq{"where" must be hash refernce or DBIx::Custom::Where object}
|
|
| 266 |
+ unless ref $w eq 'DBIx::Custom::Where'; |
|
| 267 |
+ |
|
| 268 |
+ croak qq{"where" must be specified}
|
|
| 269 |
+ if "$w" eq '' && !$allow_delete_all; |
|
| 270 |
+ |
|
| 271 | 271 |
# Source of SQL |
| 272 |
- my $source = "delete from $table $where_clause"; |
|
| 272 |
+ my $source = "delete from $table $w"; |
|
| 273 | 273 |
$source .= " $append" if $append; |
| 274 | 274 |
|
| 275 | 275 |
# Create query |
| ... | ... |
@@ -951,22 +951,80 @@ where句を生成することができます。 |
| 951 | 951 |
|
| 952 | 952 |
これはSQLの中にwhere句を埋め込むときにとても役立つ機能です。 |
| 953 | 953 |
|
| 954 |
-また同一の列名を持つ場合はパラメータを配列のリファレンスにしてください。 |
|
| 954 |
+=head3 同一の列名を含む場合 |
|
| 955 | 955 |
|
| 956 |
-[undef, undef] |
|
| 956 |
+タグの中に同一の名前を持つものが存在した場合でも動的に |
|
| 957 |
+where句を作成することができます。 |
|
| 957 | 958 |
|
| 958 |
-[sub {'not exists'}, 1]
|
|
| 959 |
- |
|
| 959 |
+たとえば、パラメータとして開始日付と終了日付を受け取ったことを |
|
| 960 |
+考えてみてください。 |
|
| 960 | 961 |
|
| 962 |
+ my $param = {start_date => '2010-11-15', end_date => '2011-11-21'};
|
|
| 961 | 963 |
|
| 964 |
+また開始日付と終了日付の片方だけや、どちらも受け取らない場合もあるかもしれません。 |
|
| 962 | 965 |
|
| 966 |
+この場合は次のようなパラメータに変換することで対応することができます。 |
|
| 963 | 967 |
|
| 964 |
-=head3 select()との連携 |
|
| 968 |
+ my $p = {date => ['2010-11-15', '2011-11-21']};
|
|
| 965 | 969 |
|
| 970 |
+値が配列のリファレンスになっていることに注目してください。このようにすれば |
|
| 971 |
+同名の列を含むタグに順番に埋め込むことができます。 |
|
| 966 | 972 |
|
| 973 |
+ $where->clause( |
|
| 974 |
+ ['and', '{> date}', '{< date}']
|
|
| 975 |
+ ); |
|
| 976 |
+ $where->param($p); |
|
| 977 |
+ |
|
| 978 |
+また開始日付が存在しない場合は次のようなデータを作成します。 |
|
| 979 |
+ |
|
| 980 |
+ my $p = {date => [$dbi->not_exists, '2011-11-21']};
|
|
| 981 |
+ |
|
| 982 |
+L<DBIx::Custom>のC<not_exists>でDBIx::Custom::NotExistsオブジェクトを |
|
| 983 |
+取得できます。これは対応する値が存在しないことを示すためのものです。 |
|
| 984 |
+ |
|
| 985 |
+また終了日付が存在しない場合は次のようなデータを作成します。 |
|
| 986 |
+ |
|
| 987 |
+ my $p = {date => ['2010-11-15']};
|
|
| 967 | 988 |
|
| 968 |
-=head3 execute()との連携 |
|
| 989 |
+どちらも存在しない場合は次のようなデータを作成します。 |
|
| 990 |
+ |
|
| 991 |
+ my $p = {date => []};
|
|
| 992 |
+ |
|
| 993 |
+少し難しいので一番簡単に作成できるロジックを示しておきます。 |
|
| 994 |
+ |
|
| 995 |
+ my @date; |
|
| 996 |
+ push @date, exists $param->{start_date} ? $param->{start_date}
|
|
| 997 |
+ : $dbi->not_exists; |
|
| 998 |
+ push @date, $param->{end_date} if exists $param->{end_date};
|
|
| 999 |
+ my $p = {date => \@date};
|
|
| 1000 |
+ |
|
| 1001 |
+=head3 C<select()>との連携 |
|
| 1002 |
+ |
|
| 1003 |
+C<select()>との連携です。C<select()>のC<where>に直接渡すことが |
|
| 1004 |
+できます。 |
|
| 1005 |
+ |
|
| 1006 |
+ my $where = $dbi->where; |
|
| 1007 |
+ $where->clause(...); |
|
| 1008 |
+ $where->param($param); |
|
| 1009 |
+ my $result = $dbi->select(table => 'book', where => $where); |
|
| 1010 |
+ |
|
| 1011 |
+あるいはC<update>、C<delete>と連携することが可能です。 |
|
| 1012 |
+ |
|
| 1013 |
+=head3 C<execute()>との連携 |
|
| 1014 |
+ |
|
| 1015 |
+C<execute()>との連携です。SQLを作成するときに埋め込むことができます。 |
|
| 1016 |
+ |
|
| 1017 |
+ |
|
| 1018 |
+ my $where = $dbi->where; |
|
| 1019 |
+ $where->clause(...); |
|
| 1020 |
+ $where->param($param); |
|
| 1021 |
+ |
|
| 1022 |
+ my $sql = <<"EOS" |
|
| 1023 |
+ select * from book; |
|
| 1024 |
+ $where |
|
| 1025 |
+ EOS |
|
| 969 | 1026 |
|
| 1027 |
+ $dbi->execute($sql, param => $param); |
|
| 970 | 1028 |
|
| 971 | 1029 |
=head2 7. パフォーマンスの改善 |
| 972 | 1030 |
|
| ... | ... |
@@ -331,7 +331,7 @@ test 'delete error'; |
| 331 | 331 |
$dbi = DBIx::Custom->connect($NEW_ARGS->{0});
|
| 332 | 332 |
$dbi->execute($CREATE_TABLE->{0});
|
| 333 | 333 |
eval{$dbi->delete(table => 'table1')};
|
| 334 |
-like($@, qr/"where" argument must be specified and contains the pairs of column name and value/, |
|
| 334 |
+like($@, qr/"where" must be specified/, |
|
| 335 | 335 |
"where key-value pairs not specified"); |
| 336 | 336 |
|
| 337 | 337 |
test 'delete_all'; |
| ... | ... |
@@ -1033,6 +1033,56 @@ $result = $dbi->select( |
| 1033 | 1033 |
$row = $result->fetch_hash_all; |
| 1034 | 1034 |
is_deeply($row, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}], 'not_exists');
|
| 1035 | 1035 |
|
| 1036 |
+$where = $dbi->where |
|
| 1037 |
+ ->clause(['or', ('{= key1}') x 3])
|
|
| 1038 |
+ ->param({key1 => []});
|
|
| 1039 |
+$result = $dbi->select( |
|
| 1040 |
+ table => 'table1', |
|
| 1041 |
+ where => $where, |
|
| 1042 |
+); |
|
| 1043 |
+$row = $result->fetch_hash_all; |
|
| 1044 |
+is_deeply($row, [{key1 => 1, key2 => 2}, {key1 => 3, key2 => 4}], 'not_exists');
|
|
| 1045 |
+ |
|
| 1046 |
+$where = $dbi->where |
|
| 1047 |
+ ->clause(['and', '{> key1}', '{< key1}' ])
|
|
| 1048 |
+ ->param({key1 => [2, $dbi->not_exists]});
|
|
| 1049 |
+$result = $dbi->select( |
|
| 1050 |
+ table => 'table1', |
|
| 1051 |
+ where => $where, |
|
| 1052 |
+); |
|
| 1053 |
+$row = $result->fetch_hash_all; |
|
| 1054 |
+is_deeply($row, [{key1 => 3, key2 => 4}], 'not_exists');
|
|
| 1055 |
+ |
|
| 1056 |
+$where = $dbi->where |
|
| 1057 |
+ ->clause(['and', '{> key1}', '{< key1}' ])
|
|
| 1058 |
+ ->param({key1 => [$dbi->not_exists, 2]});
|
|
| 1059 |
+$result = $dbi->select( |
|
| 1060 |
+ table => 'table1', |
|
| 1061 |
+ where => $where, |
|
| 1062 |
+); |
|
| 1063 |
+$row = $result->fetch_hash_all; |
|
| 1064 |
+is_deeply($row, [{key1 => 1, key2 => 2}], 'not_exists');
|
|
| 1065 |
+ |
|
| 1066 |
+$where = $dbi->where |
|
| 1067 |
+ ->clause(['and', '{> key1}', '{< key1}' ])
|
|
| 1068 |
+ ->param({key1 => [$dbi->not_exists, $dbi->not_exists]});
|
|
| 1069 |
+$result = $dbi->select( |
|
| 1070 |
+ table => 'table1', |
|
| 1071 |
+ where => $where, |
|
| 1072 |
+); |
|
| 1073 |
+$row = $result->fetch_hash_all; |
|
| 1074 |
+is_deeply($row, [{key1 => 1, key2 => 2},{key1 => 3, key2 => 4}], 'not_exists');
|
|
| 1075 |
+ |
|
| 1076 |
+$where = $dbi->where |
|
| 1077 |
+ ->clause(['and', '{> key1}', '{< key1}' ])
|
|
| 1078 |
+ ->param({key1 => [0, 2]});
|
|
| 1079 |
+$result = $dbi->select( |
|
| 1080 |
+ table => 'table1', |
|
| 1081 |
+ where => $where, |
|
| 1082 |
+); |
|
| 1083 |
+$row = $result->fetch_hash_all; |
|
| 1084 |
+is_deeply($row, [{key1 => 1, key2 => 2}], 'not_exists');
|
|
| 1085 |
+ |
|
| 1036 | 1086 |
test 'dbi_option default'; |
| 1037 | 1087 |
$dbi = DBIx::Custom->new; |
| 1038 | 1088 |
is_deeply($dbi->dbi_option, {});
|