Showing 4 changed files with 73 additions and 64 deletions
+2
Changes
... ...
@@ -1,4 +1,6 @@
1 1
 0.1740
2
+    - EXPERIMENTAL update_or_insert need id and primary_key option
3
+      and added option option
2 4
     - insert method created_at and updated_at option can receive scalar reference
3 5
     - update method updated_at option can receive scalar reference
4 6
     - select column option [COLUMN => ALIAS] syntax is DEPRECATED!
+38 -52
lib/DBIx/Custom.pm
... ...
@@ -1158,41 +1158,13 @@ sub update {
1158 1158
 sub update_all { shift->update(allow_update_all => 1, @_) };
1159 1159
 
1160 1160
 sub update_or_insert {
1161
-    my $self = shift;
1162
-
1163
-    # Options
1164
-    my $param  = shift;
1165
-    my %opt = @_;
1166
-    my $id = $opt{id};
1167
-    my $primary_key = $opt{primary_key};
1168
-    $primary_key = [$primary_key] unless ref $primary_key eq 'ARRAY';
1169
-    croak "update_or_insert method need primary_key option " .
1170
-          "when id is specified" . _subname
1171
-      if defined $id && !defined $primary_key;
1172
-    my $table  = $opt{table};
1173
-    croak qq{"table" option must be specified } . _subname
1174
-      unless defined $table;
1175
-    my $select_option = $opt{select_option};
1176
-    my $reuse = $opt{reuse};
1177
-    $opt{select_option}->{reuse} = $opt{reuse} if $opt{reuse};
1178
-    
1179
-    my $rows = $self->select(table => $table, id => $id,
1180
-        primary_key => $primary_key, %$select_option)->all;
1181
-    
1182
-    croak "selected row count must be one or zero" . _subname
1183
-      if @$rows > 1;
1184
-    
1185
-    my $row = $rows->[0];
1186
-    my @opt = (table => $table);
1187
-    push @opt, id => $id, primary_key => $primary_key if defined $id;
1188
-    push @opt, %opt;
1189
-    
1190
-    if ($row) {
1191
-        return $self->update($param, @opt);
1192
-    }
1193
-    else {
1194
-        return $self->insert($param, @opt);
1195
-    }
1161
+    my ($self, $param, %opt) = @_;
1162
+    croak "update_or_insert method need primary_key and id option "
1163
+      unless defined $opt{id} && defined $opt{primary_key};
1164
+    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} || {}});
1196 1168
 }
1197 1169
 
1198 1170
 sub update_timestamp {
... ...
@@ -3319,34 +3291,48 @@ Options is same as C<update> method.
3319 3291
 
3320 3292
 =head2 C<update_or_insert EXPERIMENTAL>
3321 3293
     
3322
-    # Where
3323
-    $dbi->update_or_insert(
3324
-        {id => 1, title => 'Perl'},
3325
-        table => 'book',
3326
-        where => {id => 1},
3327
-        select_option => {append => 'for update'}
3328
-    );
3329
-    
3330 3294
     # ID
3331 3295
     $dbi->update_or_insert(
3332 3296
         {title => 'Perl'},
3333 3297
         table => 'book',
3334 3298
         id => 1,
3335 3299
         primary_key => 'id',
3336
-        select_option => {append => 'for update'}
3300
+        option => {
3301
+            select => {
3302
+                 append => 'for update'
3303
+            }
3304
+        }
3337 3305
     );
3338
-    
3306
+
3339 3307
 Update or insert.
3340 3308
 
3341
-In both examples, the following SQL is executed.
3309
+C<update_or_insert> method execute C<select> method first to find row.
3310
+If the row is exists, C<update> is executed.
3311
+If not, C<insert> is executed.
3342 3312
 
3343
-    # In case insert
3344
-    insert into book (id, title) values (?, ?)
3345
-    
3346
-    # In case update
3347
-    update book set (id = ?, title = ?) where book.id = ?
3313
+C<OPTIONS>
3314
+
3315
+C<update_or_insert> method use all common option
3316
+in C<select>, C<update>, C<delete>, and has the following new ones.
3317
+
3318
+=over 4
3319
+
3320
+=item C<option>
3321
+
3322
+    option => {
3323
+        select => {
3324
+            append => '...'
3325
+        },
3326
+        insert => {
3327
+            prefix => '...'
3328
+        },
3329
+        update => {
3330
+            filter => {}
3331
+        }
3332
+    }
3348 3333
 
3349
-The following opitons are available adding to C<update> option.
3334
+If you want to pass option to each method,
3335
+you can use C<option> option.
3350 3336
 
3351 3337
 =over 4
3352 3338
 
+9 -9
t/common.t
... ...
@@ -616,6 +616,7 @@ is($row->{$key2}, $row->{$key3});
616 616
 test 'update_or_insert';
617 617
 eval { $dbi->execute("drop table $table1") };
618 618
 $dbi->execute($create_table1);
619
+$DB::single = 1;
619 620
 $dbi->update_or_insert(
620 621
     {$key2 => 2},
621 622
     table => $table1,
... ...
@@ -634,15 +635,14 @@ $dbi->update_or_insert(
634 635
 $rows = $dbi->select(id => 1, table => $table1, primary_key => $key1)->all;
635 636
 is_deeply($rows, [{$key1 => 1, $key2 => 3}], "basic");
636 637
 
637
-eval { $dbi->execute("drop table $table1") };
638
-$dbi->execute($create_table1);
639
-$dbi->update_or_insert(
640
-    {$key1 => 1, $key2 => 2},
641
-    table => $table1,
642
-    where => {$key1 => 1}
643
-);
644
-$row = $dbi->select(id => 1, table => $table1, primary_key => $key1)->one;
645
-is_deeply($row, {$key1 => 1, $key2 => 2}, "basic");
638
+eval {
639
+    $dbi->update_or_insert(
640
+        {$key2 => 3},
641
+        table => $table1,
642
+    );
643
+};
644
+
645
+like($@, qr/primary_key/);
646 646
 
647 647
 test 'default_bind_filter';
648 648
 $dbi->execute("delete from $table1");
+24 -3
t/mysql.t
... ...
@@ -47,16 +47,37 @@ $dbi->do('create table table1 (key1 varchar(255), key2 varchar(255)) engine=Inno
47 47
 
48 48
 test 'update_or_insert';
49 49
 $dbi->delete_all(table => 'table1');
50
+$ENV{DBIX_CUSTOM_DEBUG} = 1;
50 51
 $dbi->update_or_insert(
51
-    {key1 => 1, key2 => 2},
52
+    {key2 => 2},
52 53
     table => 'table1',
53
-    where => {key1 => 1},
54
-    select_option => {append => 'for update'}
54
+    id => 1,
55
+    primary_key => 'key1',
56
+    option => {
57
+        select => {append => 'for update'},
58
+        insert => {append => '    #'},
59
+        update => {append => '     #'}
60
+    }
55 61
 );
56 62
 
57 63
 my $row = $dbi->select(id => 1, table => 'table1', primary_key => 'key1')->one;
58 64
 is_deeply($row, {key1 => 1, key2 => 2}, "basic");
59 65
 
66
+$dbi->update_or_insert(
67
+    {key2 => 3},
68
+    table => 'table1',
69
+    id => 1,
70
+    primary_key => 'key1',
71
+    option => {
72
+        select => {append => 'for update'},
73
+        insert => {append => '    #'},
74
+        update => {append => '     #'}
75
+    }
76
+);
77
+
78
+my $row = $dbi->select(id => 1, table => 'table1', primary_key => 'key1')->one;
79
+is_deeply($row, {key1 => 1, key2 => 3}, "basic");
80
+
60 81
 # Test memory leaks
61 82
 for (1 .. 200) {
62 83
     $dbi = DBIx::Custom->connect(