Showing 3 changed files with 130 additions and 22 deletions
+15 -15
lib/DBIx/Custom.pm
... ...
@@ -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
+64 -6
lib/DBIx/Custom/Guide/Ja.pod
... ...
@@ -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
 
+51 -1
t/dbix-custom-core-sqlite.t
... ...
@@ -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, {});