Showing 6 changed files with 152 additions and 105 deletions
+7
Changes
... ...
@@ -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
+31 -46
lib/DBIx/Custom.pm
... ...
@@ -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(
+11 -4
lib/DBIx/Custom/Model.pm
... ...
@@ -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
     
+70 -6
lib/DBIx/Custom/Where.pm
... ...
@@ -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
 
-2
t/common-sqlite.t
... ...
@@ -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;
+33 -47
t/common.t
... ...
@@ -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);