... | ... |
@@ -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, {}); |