- id option work if id count is lower than primary...
...key count.
... | ... |
@@ -1,3 +1,10 @@ |
1 |
+0.1744 |
|
2 |
+ - id option work if id count is lower than primary key count. |
|
3 |
+ - removed EXPERIMETNAL status from update_or_insert method and |
|
4 |
+ DBIx::Custom::Model's update_or_insert method |
|
5 |
+ - removed EXPERIMENTAL status from reuse option |
|
6 |
+ - removed EXPERIMENTAL status from update_at option and created_at option |
|
7 |
+ - removed EXPERIMETNAL status from now attribute |
|
1 | 8 |
0.1743 |
2 | 9 |
- DBIx::Custom::Model execute method is DEPRECATED! |
3 | 10 |
- fixed bug that update_all can't receive parameter as first argument |
... | ... |
@@ -1,7 +1,7 @@ |
1 | 1 |
package DBIx::Custom; |
2 | 2 |
use Object::Simple -base; |
3 | 3 |
|
4 |
-our $VERSION = '0.1743'; |
|
4 |
+our $VERSION = '0.1744'; |
|
5 | 5 |
use 5.008001; |
6 | 6 |
|
7 | 7 |
use Carp 'croak'; |
... | ... |
@@ -674,15 +674,6 @@ sub insert { |
674 | 674 |
$self->execute($sql, $param, %opt); |
675 | 675 |
} |
676 | 676 |
|
677 |
-sub _merge_id_to_param { |
|
678 |
- my ($self, $id, $primary_keys, $param) = @_; |
|
679 |
- |
|
680 |
- # Create parameter |
|
681 |
- $id = [$id] unless ref $id; |
|
682 |
- |
|
683 |
- return $param; |
|
684 |
-} |
|
685 |
- |
|
686 | 677 |
sub insert_timestamp { |
687 | 678 |
my $self = shift; |
688 | 679 |
|
... | ... |
@@ -1162,9 +1153,17 @@ sub update_or_insert { |
1162 | 1153 |
croak "update_or_insert method need primary_key and id option " |
1163 | 1154 |
unless defined $opt{id} && defined $opt{primary_key}; |
1164 | 1155 |
my $statement_opt = $opt{option} || {}; |
1165 |
- my $row = $self->select(%opt, %{$statement_opt->{select} || {}})->one; |
|
1166 |
- return $row ? $self->update($param, %opt, %{$statement_opt->{update} || {}}) |
|
1167 |
- : $self->insert($param, %opt, %{$statement_opt->{insert} || {}}); |
|
1156 |
+ |
|
1157 |
+ my $rows = $self->select(%opt, %{$statement_opt->{select} || {}})->all; |
|
1158 |
+ if (@$rows == 0) { |
|
1159 |
+ return $self->insert($param, %opt, %{$statement_opt->{insert} || {}}); |
|
1160 |
+ } |
|
1161 |
+ elsif (@$rows == 1) { |
|
1162 |
+ return $self->update($param, %opt, %{$statement_opt->{update} || {}}); |
|
1163 |
+ } |
|
1164 |
+ else { |
|
1165 |
+ croak "selected row must be one " . _subname; |
|
1166 |
+ } |
|
1168 | 1167 |
} |
1169 | 1168 |
|
1170 | 1169 |
sub update_timestamp { |
... | ... |
@@ -1355,7 +1354,7 @@ sub _id_to_param { |
1355 | 1354 |
|
1356 | 1355 |
# Check primary key |
1357 | 1356 |
croak "primary_key option " . |
1358 |
- "must be specified with id option " . _subname |
|
1357 |
+ "must be specified when id option is used" . _subname |
|
1359 | 1358 |
unless defined $primary_keys; |
1360 | 1359 |
$primary_keys = [$primary_keys] unless ref $primary_keys eq 'ARRAY'; |
1361 | 1360 |
|
... | ... |
@@ -1363,13 +1362,7 @@ sub _id_to_param { |
1363 | 1362 |
my $param = {}; |
1364 | 1363 |
if (defined $id) { |
1365 | 1364 |
$id = [$id] unless ref $id; |
1366 |
- croak qq{"id" must be constant value or array reference} |
|
1367 |
- . " (" . (caller 1)[3] . ")" |
|
1368 |
- unless !ref $id || ref $id eq 'ARRAY'; |
|
1369 |
- croak qq{"id" must contain values same count as primary key} |
|
1370 |
- . " (" . (caller 1)[3] . ")" |
|
1371 |
- unless @$primary_keys eq @$id; |
|
1372 |
- for(my $i = 0; $i < @$primary_keys; $i ++) { |
|
1365 |
+ for(my $i = 0; $i < @$id; $i++) { |
|
1373 | 1366 |
my $key = $primary_keys->[$i]; |
1374 | 1367 |
$key = "$table." . $key if $table; |
1375 | 1368 |
$param->{$key} = $id->[$i]; |
... | ... |
@@ -1575,12 +1568,7 @@ sub _where_clause_and_param { |
1575 | 1568 |
|
1576 | 1569 |
my $obj; |
1577 | 1570 |
|
1578 |
- if (ref $where eq 'ARRAY' && !ref $where->[0]) { |
|
1579 |
- $w->{clause} = "where " . $where->[0]; |
|
1580 |
- $w->{param} = $where->[1]; |
|
1581 |
- } |
|
1582 |
- elsif (ref $where) { |
|
1583 |
- |
|
1571 |
+ if (ref $where) { |
|
1584 | 1572 |
if (ref $where eq 'HASH') { |
1585 | 1573 |
my $clause = ['and']; |
1586 | 1574 |
my $column_join = ''; |
... | ... |
@@ -2160,12 +2148,12 @@ Filters, registered by C<register_filter> method. |
2160 | 2148 |
|
2161 | 2149 |
Get last successed SQL executed by C<execute> method. |
2162 | 2150 |
|
2163 |
-=head2 C<now EXPERIMENTAL> |
|
2151 |
+=head2 C<now> |
|
2164 | 2152 |
|
2165 | 2153 |
my $now = $dbi->now; |
2166 | 2154 |
$dbi = $dbi->now($now); |
2167 | 2155 |
|
2168 |
-Code reference which return time now, default to the following code reference. |
|
2156 |
+Code reference which return current time, default to the following code reference. |
|
2169 | 2157 |
|
2170 | 2158 |
sub { |
2171 | 2159 |
my ($sec, $min, $hour, $mday, $mon, $year) = localtime; |
... | ... |
@@ -2174,7 +2162,10 @@ Code reference which return time now, default to the following code reference. |
2174 | 2162 |
return sprintf("%04d-%02d-%02d %02d:%02d:%02d"); |
2175 | 2163 |
} |
2176 | 2164 |
|
2177 |
-This return the time like "2011-10-14 05:05:27". |
|
2165 |
+This return the time like C<2011-10-14 05:05:27>. |
|
2166 |
+ |
|
2167 |
+This is used by C<insert> method's C<created_at> option and C<updated_at> option, |
|
2168 |
+and C<update> method's C<updated_at> option. |
|
2178 | 2169 |
|
2179 | 2170 |
=head2 C<models> |
2180 | 2171 |
|
... | ... |
@@ -2652,7 +2643,7 @@ Table alias. Key is real table name, value is alias table name. |
2652 | 2643 |
If you set C<table_alias>, you can enable C<into1> and C<into2> type rule |
2653 | 2644 |
on alias table name. |
2654 | 2645 |
|
2655 |
-=item C<reuse EXPERIMENTAL> |
|
2646 |
+=item C<reuse> |
|
2656 | 2647 |
|
2657 | 2648 |
reuse => $hash_ref |
2658 | 2649 |
|
... | ... |
@@ -2742,7 +2733,7 @@ and use the following new ones. |
2742 | 2733 |
|
2743 | 2734 |
=over 4 |
2744 | 2735 |
|
2745 |
-=item C<created_at EXPERIMETNAL> |
|
2736 |
+=item C<created_at> |
|
2746 | 2737 |
|
2747 | 2738 |
created_at => 'created_datetime' |
2748 | 2739 |
|
... | ... |
@@ -2786,7 +2777,7 @@ prefix before table name section |
2786 | 2777 |
|
2787 | 2778 |
Table name. |
2788 | 2779 |
|
2789 |
-=item C<updated_at EXPERIMENTAL> |
|
2780 |
+=item C<updated_at> |
|
2790 | 2781 |
|
2791 | 2782 |
This option is same as C<update> method C<updated_at> option. |
2792 | 2783 |
|
... | ... |
@@ -2918,7 +2909,7 @@ This is used in C<param> of L<DBIx::Custom::Where> . |
2918 | 2909 |
|
2919 | 2910 |
Create a new L<DBIx::Custom::Order> object. |
2920 | 2911 |
|
2921 |
-=head2 C<q EXPERIMENTAL> |
|
2912 |
+=head2 C<q> |
|
2922 | 2913 |
|
2923 | 2914 |
my $quooted = $dbi->q("title"); |
2924 | 2915 |
|
... | ... |
@@ -3091,21 +3082,15 @@ Table name. |
3091 | 3082 |
|
3092 | 3083 |
# DBIx::Custom::Where object |
3093 | 3084 |
where => $dbi->where( |
3094 |
- clause => ['and', 'author = :author', 'title like :title'], |
|
3085 |
+ clause => ['and', ':author{=}', ':title{like}'], |
|
3095 | 3086 |
param => {author => 'Ken', title => '%Perl%'} |
3096 | 3087 |
); |
3097 | 3088 |
|
3098 |
- # Array reference 1 (array reference, hash referenc). same as above |
|
3089 |
+ # Array reference, this is same as above |
|
3099 | 3090 |
where => [ |
3100 |
- ['and', 'author = :author', 'title like :title'], |
|
3091 |
+ ['and', ':author{=}', ':title{like}'], |
|
3101 | 3092 |
{author => 'Ken', title => '%Perl%'} |
3102 |
- ]; |
|
3103 |
- |
|
3104 |
- # Array reference 2 (String, hash reference) |
|
3105 |
- where => [ |
|
3106 |
- 'title like :title', |
|
3107 |
- {title => '%Perl%'} |
|
3108 |
- ] |
|
3093 |
+ ]; |
|
3109 | 3094 |
|
3110 | 3095 |
# String |
3111 | 3096 |
where => 'title is null' |
... | ... |
@@ -3269,7 +3254,7 @@ is executed, the following SQL is executed. |
3269 | 3254 |
|
3270 | 3255 |
update book set price = ? + 5; |
3271 | 3256 |
|
3272 |
-=item C<updated_at EXPERIMETNAL> |
|
3257 |
+=item C<updated_at> |
|
3273 | 3258 |
|
3274 | 3259 |
updated_at => 'updated_datetime' |
3275 | 3260 |
|
... | ... |
@@ -3286,7 +3271,7 @@ C<now> attribute. |
3286 | 3271 |
Execute update statement for all rows. |
3287 | 3272 |
Options is same as C<update> method. |
3288 | 3273 |
|
3289 |
-=head2 C<update_or_insert EXPERIMENTAL> |
|
3274 |
+=head2 C<update_or_insert> |
|
3290 | 3275 |
|
3291 | 3276 |
# ID |
3292 | 3277 |
$dbi->update_or_insert( |
... | ... |
@@ -74,9 +74,16 @@ sub update_or_insert { |
74 | 74 |
&& (defined $opt{primary_key} || defined $self->{primary_key}); |
75 | 75 |
|
76 | 76 |
my $statement_opt = $opt{option} || {}; |
77 |
- my $row = $self->select(%opt, %{$statement_opt->{select} || {}})->one; |
|
78 |
- return $row ? $self->update($param, %opt, %{$statement_opt->{update} || {}}) |
|
79 |
- : $self->insert($param, %opt, %{$statement_opt->{insert} || {}}); |
|
77 |
+ my $rows = $self->select(%opt, %{$statement_opt->{select} || {}})->all; |
|
78 |
+ if (@$rows == 0) { |
|
79 |
+ return $self->insert($param, %opt, %{$statement_opt->{insert} || {}}); |
|
80 |
+ } |
|
81 |
+ elsif (@$rows == 1) { |
|
82 |
+ return $self->update($param, %opt, %{$statement_opt->{update} || {}}); |
|
83 |
+ } |
|
84 |
+ else { |
|
85 |
+ croak "selected row must be one " . _subname; |
|
86 |
+ } |
|
80 | 87 |
} |
81 | 88 |
|
82 | 89 |
sub execute { |
... | ... |
@@ -311,7 +318,7 @@ you don't have to specify options if you set attribute in model. |
311 | 318 |
Same as C<update_all> of L<DBIx::Custom> except that |
312 | 319 |
you don't have to specify options if you set attribute in model. |
313 | 320 |
|
314 |
-=head2 C<update_or_insert EXPERIMENTAL> |
|
321 |
+=head2 C<update_or_insert> |
|
315 | 322 |
|
316 | 323 |
$model->update_or_insert(...); |
317 | 324 |
|
... | ... |
@@ -145,9 +145,73 @@ sub _parse { |
145 | 145 |
DBIx::Custom::Where - Where clause |
146 | 146 |
|
147 | 147 |
=head1 SYNOPSYS |
148 |
- |
|
149 |
- my $where = DBIx::Custom::Where->new; |
|
150 |
- my $string_where = "$where"; |
|
148 |
+ |
|
149 |
+ # Create DBIx::Custom::Where object |
|
150 |
+ my $where = $dbi->where; |
|
151 |
+ |
|
152 |
+ # Set clause and parameter |
|
153 |
+ $where->clause(['and', ':title{like}', ':price{=}']); |
|
154 |
+ |
|
155 |
+ # Create where clause by to_string method |
|
156 |
+ my $where_clause = $where->to_string; |
|
157 |
+ |
|
158 |
+ # Create where clause by stringify |
|
159 |
+ my $where_clause = "$where"; |
|
160 |
+ |
|
161 |
+ # Created where clause in the above way |
|
162 |
+ where :title{=} and :price{like} |
|
163 |
+ |
|
164 |
+ # Only price condition |
|
165 |
+ $where->clause(['and', ':title{like}', ':price{=}']); |
|
166 |
+ $where->param({price => 1900}); |
|
167 |
+ my $where_clause = "$where"; |
|
168 |
+ |
|
169 |
+ # Created where clause in the above way |
|
170 |
+ where :price{=} |
|
171 |
+ |
|
172 |
+ # Only title condition |
|
173 |
+ $where->clause(['and', ':title{like}', ':price{=}']); |
|
174 |
+ $where->param({title => 'Perl'}); |
|
175 |
+ my $where_clause = "$where"; |
|
176 |
+ |
|
177 |
+ # Created where clause in the above way |
|
178 |
+ where :title{like} |
|
179 |
+ |
|
180 |
+ # Nothing |
|
181 |
+ $where->clause(['and', ':title{like}', ':price{=}']); |
|
182 |
+ $where->param({}); |
|
183 |
+ my $where_clause = "$where"; |
|
184 |
+ |
|
185 |
+ # or condition |
|
186 |
+ $where->clause(['or', ':title{like}', ':price{=}']); |
|
187 |
+ |
|
188 |
+ # More than one parameter |
|
189 |
+ $where->clause(['and', ':price{>}', ':price{<}']); |
|
190 |
+ $where->param({price => [1000, 2000]}); |
|
191 |
+ |
|
192 |
+ # Only first condition |
|
193 |
+ $where->clause(['and', ':price{>}', ':price{<}']); |
|
194 |
+ $where->param({price => [1000, $dbi->not_exists]}); |
|
195 |
+ |
|
196 |
+ # Only second condition |
|
197 |
+ $where->clause(['and', ':price{>}', ':price{<}']); |
|
198 |
+ $where->param({price => [$dbi->not_exists, 2000]}); |
|
199 |
+ |
|
200 |
+ # More complex condition |
|
201 |
+ $where->clause( |
|
202 |
+ [ |
|
203 |
+ 'and', |
|
204 |
+ ':price{=}', |
|
205 |
+ ['or', ':title{=}', ':title{=}', ':title{=}'] |
|
206 |
+ ] |
|
207 |
+ ); |
|
208 |
+ my $where_clause = "$where"; |
|
209 |
+ |
|
210 |
+ # Created where clause in the above way |
|
211 |
+ where :price{=} and (:title{=} or :title{=} or :title{=}) |
|
212 |
+ |
|
213 |
+ # Using Full-qualified column name |
|
214 |
+ $where->clause(['and', ':book.title{like}', ':book.price{=}']); |
|
151 | 215 |
|
152 | 216 |
=head1 ATTRIBUTES |
153 | 217 |
|
... | ... |
@@ -156,15 +220,15 @@ DBIx::Custom::Where - Where clause |
156 | 220 |
my $clause = $where->clause; |
157 | 221 |
$where = $where->clause( |
158 | 222 |
['and', |
159 |
- 'title = :title', |
|
160 |
- ['or', 'date < :date', 'date > :date'] |
|
223 |
+ ':title{=}', |
|
224 |
+ ['or', ':date{<}', ':date{>}'] |
|
161 | 225 |
] |
162 | 226 |
); |
163 | 227 |
|
164 | 228 |
Where clause. Above one is expanded to the following SQL by to_string |
165 | 229 |
If all parameter names is exists. |
166 | 230 |
|
167 |
- "where ( title = :title and ( date < :date or date > :date ) )" |
|
231 |
+ where title = :title and ( date < :date or date > :date ) |
|
168 | 232 |
|
169 | 233 |
=head2 C<param> |
170 | 234 |
|
... | ... |
@@ -5,8 +5,6 @@ use FindBin; |
5 | 5 |
use lib "$FindBin::Bin/common"; |
6 | 6 |
$ENV{DBIX_CUSTOM_TEST_RUN} = 1; |
7 | 7 |
|
8 |
- |
|
9 |
- |
|
10 | 8 |
use DBIx::Custom; |
11 | 9 |
{ |
12 | 10 |
package DBIx::Custom; |
... | ... |
@@ -651,6 +651,17 @@ eval { |
651 | 651 |
|
652 | 652 |
like($@, qr/primary_key/); |
653 | 653 |
|
654 |
+eval { |
|
655 |
+ $dbi->insert({$key1 => 1}, table => $table1); |
|
656 |
+ $dbi->update_or_insert( |
|
657 |
+ {$key2 => 3}, |
|
658 |
+ table => $table1, |
|
659 |
+ primary_key => $key1, |
|
660 |
+ id => 1 |
|
661 |
+ ); |
|
662 |
+}; |
|
663 |
+like($@, qr/one/); |
|
664 |
+ |
|
654 | 665 |
test 'model update_or_insert'; |
655 | 666 |
eval { $dbi->execute("drop table $table1") }; |
656 | 667 |
$dbi->execute($create_table1); |
... | ... |
@@ -662,6 +673,15 @@ $model->update_or_insert({$key2 => 2}, id => 1); |
662 | 673 |
$row = $model->select(id => 1)->one; |
663 | 674 |
is_deeply($row, {$key1 => 1, $key2 => 2}, "basic"); |
664 | 675 |
|
676 |
+eval { |
|
677 |
+ $model->insert({$key1 => 1}); |
|
678 |
+ $model->update_or_insert( |
|
679 |
+ {$key2 => 3}, |
|
680 |
+ id => 1 |
|
681 |
+ ); |
|
682 |
+}; |
|
683 |
+like($@, qr/one/); |
|
684 |
+ |
|
665 | 685 |
test 'default_bind_filter'; |
666 | 686 |
$dbi->execute("delete from $table1"); |
667 | 687 |
$dbi->register_filter( |
... | ... |
@@ -1987,16 +2007,6 @@ is($dbi->select(table => $table1)->one->{$key1}, 1); |
1987 | 2007 |
is($dbi->select(table => $table1)->one->{$key2}, 2); |
1988 | 2008 |
is($dbi->select(table => $table1)->one->{$key3}, 3); |
1989 | 2009 |
|
1990 |
-eval { |
|
1991 |
- $dbi->insert_at( |
|
1992 |
- {$key1 => 1, $key2 => 2, $key3 => 3}, |
|
1993 |
- table => $table1, |
|
1994 |
- primary_key => [$key1, $key2], |
|
1995 |
- where => {}, |
|
1996 |
- ); |
|
1997 |
-}; |
|
1998 |
-like($@, qr/must be/); |
|
1999 |
- |
|
2000 | 2010 |
$dbi = DBIx::Custom->connect; |
2001 | 2011 |
eval { $dbi->execute("drop table $table1") }; |
2002 | 2012 |
$dbi->execute($create_table1_2); |
... | ... |
@@ -2090,43 +2100,6 @@ is($row->{$key1}, 1); |
2090 | 2100 |
is($row->{$key2}, 2); |
2091 | 2101 |
is($row->{$key3}, 3); |
2092 | 2102 |
|
2093 |
-eval { |
|
2094 |
- $result = $dbi->select_at( |
|
2095 |
- table => $table1, |
|
2096 |
- primary_key => [$key1, $key2], |
|
2097 |
- where => {}, |
|
2098 |
- ); |
|
2099 |
-}; |
|
2100 |
-like($@, qr/must be/); |
|
2101 |
- |
|
2102 |
-eval { |
|
2103 |
- $result = $dbi->select_at( |
|
2104 |
- table => $table1, |
|
2105 |
- primary_key => [$key1, $key2], |
|
2106 |
- where => [1], |
|
2107 |
- ); |
|
2108 |
-}; |
|
2109 |
-like($@, qr/same/); |
|
2110 |
- |
|
2111 |
-eval { |
|
2112 |
- $result = $dbi->update_at( |
|
2113 |
- {$key1 => 1, $key2 => 2}, |
|
2114 |
- table => $table1, |
|
2115 |
- primary_key => [$key1, $key2], |
|
2116 |
- where => {}, |
|
2117 |
- ); |
|
2118 |
-}; |
|
2119 |
-like($@, qr/must be/); |
|
2120 |
- |
|
2121 |
-eval { |
|
2122 |
- $result = $dbi->delete_at( |
|
2123 |
- table => $table1, |
|
2124 |
- primary_key => [$key1, $key2], |
|
2125 |
- where => {}, |
|
2126 |
- ); |
|
2127 |
-}; |
|
2128 |
-like($@, qr/must be/); |
|
2129 |
- |
|
2130 | 2103 |
test 'model delete_at'; |
2131 | 2104 |
$dbi = MyDBI6->connect; |
2132 | 2105 |
eval { $dbi->execute("drop table $table1") }; |
... | ... |
@@ -2461,6 +2434,19 @@ is($dbi->select(table => $table1)->one->{$key1}, 0); |
2461 | 2434 |
is($dbi->select(table => $table1)->one->{$key2}, 2); |
2462 | 2435 |
is($dbi->select(table => $table1)->one->{$key3}, 3); |
2463 | 2436 |
|
2437 |
+$dbi = DBIx::Custom->connect; |
|
2438 |
+eval { $dbi->execute("drop table $table1") }; |
|
2439 |
+$dbi->execute($create_table1_2); |
|
2440 |
+$dbi->insert( |
|
2441 |
+ {$key3 => 3}, |
|
2442 |
+ primary_key => [$key1, $key2], |
|
2443 |
+ table => $table1, |
|
2444 |
+ id => 1, |
|
2445 |
+); |
|
2446 |
+is($dbi->select(table => $table1)->one->{$key1}, 1); |
|
2447 |
+ok(!$dbi->select(table => $table1)->one->{$key2}); |
|
2448 |
+is($dbi->select(table => $table1)->one->{$key3}, 3); |
|
2449 |
+ |
|
2464 | 2450 |
$dbi = DBIx::Custom->connect; |
2465 | 2451 |
eval { $dbi->execute("drop table $table1") }; |
2466 | 2452 |
$dbi->execute($create_table1_2); |