- removed DEPRECATED status from insert method's id...
...option
... | ... |
@@ -1,4 +1,8 @@ |
1 |
+0.1731 |
|
2 |
+ - removed DEPRECATED status from insert method's id option |
|
3 |
+ - renamed EXPERIMENTAL insert_or_update to update_or_insert |
|
1 | 4 |
0.1730 |
5 |
+ - added EXPERIMENTAL insert_or_update method |
|
2 | 6 |
- method method of DBIx::Custom::Model is renamed to helper, |
3 | 7 |
method is DEPRECATED! |
4 | 8 |
- method method is renamed to helper, method is DEPRECATED! |
... | ... |
@@ -1,7 +1,7 @@ |
1 | 1 |
package DBIx::Custom; |
2 | 2 |
use Object::Simple -base; |
3 | 3 |
|
4 |
-our $VERSION = '0.1730'; |
|
4 |
+our $VERSION = '0.1731'; |
|
5 | 5 |
use 5.008001; |
6 | 6 |
|
7 | 7 |
use Carp 'croak'; |
... | ... |
@@ -627,6 +627,7 @@ sub insert { |
627 | 627 |
my $prefix = delete $args{prefix}; |
628 | 628 |
my $wrap = delete $args{wrap}; |
629 | 629 |
my $timestamp = $args{timestamp}; |
630 |
+ delete $args{where}; |
|
630 | 631 |
|
631 | 632 |
# Timestamp |
632 | 633 |
if ($timestamp && (my $insert_timestamp = $self->insert_timestamp)) { |
... | ... |
@@ -639,7 +640,6 @@ sub insert { |
639 | 640 |
|
640 | 641 |
# Merge parameter |
641 | 642 |
if (defined $id) { |
642 |
- warn "insert method's id option is DEPRECATED!"; |
|
643 | 643 |
my $id_param = $self->_create_param_from_id($id, $primary_key); |
644 | 644 |
$param = $self->merge_param($id_param, $param); |
645 | 645 |
} |
... | ... |
@@ -656,6 +656,42 @@ sub insert { |
656 | 656 |
return $self->execute($sql, $param, table => $table, %args); |
657 | 657 |
} |
658 | 658 |
|
659 |
+sub update_or_insert { |
|
660 |
+ my $self = shift; |
|
661 |
+ |
|
662 |
+ # Arguments |
|
663 |
+ my $param = shift; |
|
664 |
+ my %args = @_; |
|
665 |
+ my $id = delete $args{id}; |
|
666 |
+ my $primary_key = delete $args{primary_key}; |
|
667 |
+ $primary_key = [$primary_key] unless ref $primary_key eq 'ARRAY'; |
|
668 |
+ croak "update_or_insert method need primary_key option " . |
|
669 |
+ "when id is specified" . _subname |
|
670 |
+ if defined $id && !defined $primary_key; |
|
671 |
+ my $table = delete $args{table}; |
|
672 |
+ croak qq{"table" option must be specified } . _subname |
|
673 |
+ unless defined $table; |
|
674 |
+ my $select_option = delete $args{select_option}; |
|
675 |
+ |
|
676 |
+ my $rows = $self->select(table => $table, id => $id, |
|
677 |
+ primary_key => $primary_key, %$select_option)->all; |
|
678 |
+ |
|
679 |
+ croak "selected row count must be one or zero" . _subname |
|
680 |
+ if @$rows > 1; |
|
681 |
+ |
|
682 |
+ my $row = $rows->[0]; |
|
683 |
+ my @options = (table => $table); |
|
684 |
+ push @options, id => $id, primary_key => $primary_key if defined $id; |
|
685 |
+ push @options, %args; |
|
686 |
+ |
|
687 |
+ if ($row) { |
|
688 |
+ return $self->update($param, @options); |
|
689 |
+ } |
|
690 |
+ else { |
|
691 |
+ return $self->insert($param, @options); |
|
692 |
+ } |
|
693 |
+} |
|
694 |
+ |
|
659 | 695 |
sub insert_timestamp { |
660 | 696 |
my $self = shift; |
661 | 697 |
|
... | ... |
@@ -3439,6 +3475,46 @@ Create update parameter tag. |
3439 | 3475 |
|
3440 | 3476 |
set title = :title, author = :author |
3441 | 3477 |
|
3478 |
+=head2 C<update_or_insert EXPERIMENTAL> |
|
3479 |
+ |
|
3480 |
+ # Where |
|
3481 |
+ $dbi->update_or_insert( |
|
3482 |
+ {id => 1, title => 'Perl'}, |
|
3483 |
+ table => 'book', |
|
3484 |
+ where => {id => 1}, |
|
3485 |
+ select_option => {append => 'for update'} |
|
3486 |
+ ); |
|
3487 |
+ |
|
3488 |
+ # ID |
|
3489 |
+ $dbi->update_or_insert( |
|
3490 |
+ {title => 'Perl'}, |
|
3491 |
+ table => 'book', |
|
3492 |
+ id => 1, |
|
3493 |
+ primary_key => 'id', |
|
3494 |
+ select_option => {append => 'for update'} |
|
3495 |
+ ); |
|
3496 |
+ |
|
3497 |
+Update or insert. |
|
3498 |
+ |
|
3499 |
+In both examples, the following SQL is executed. |
|
3500 |
+ |
|
3501 |
+ # In case insert |
|
3502 |
+ insert into book (id, title) values (?, ?) |
|
3503 |
+ |
|
3504 |
+ # In case update |
|
3505 |
+ update book set (id = ?, title = ?) where book.id = ? |
|
3506 |
+ |
|
3507 |
+The following opitons are available adding to C<update> option. |
|
3508 |
+ |
|
3509 |
+=over 4 |
|
3510 |
+ |
|
3511 |
+=item C<select_option> |
|
3512 |
+ |
|
3513 |
+ select_option => {append => 'for update'} |
|
3514 |
+ |
|
3515 |
+select method option, |
|
3516 |
+select method is used to check the row is already exists. |
|
3517 |
+ |
|
3442 | 3518 |
=head2 C<update_timestamp> |
3443 | 3519 |
|
3444 | 3520 |
$dbi->update_timestamp(updated_at => sub { localtime }); |
... | ... |
@@ -12,7 +12,7 @@ use DBIx::Custom; |
12 | 12 |
package DBIx::Custom; |
13 | 13 |
no warnings 'redefine'; |
14 | 14 |
|
15 |
- has dbi_option => sub { |
|
15 |
+ has option => sub { |
|
16 | 16 |
{ |
17 | 17 |
Callbacks => { |
18 | 18 |
connected => sub { |
... | ... |
@@ -538,6 +538,51 @@ $result = $dbi->execute("select * from $table1"); |
538 | 538 |
$rows = $result->all; |
539 | 539 |
is($rows->[0]->{$key1}, $rows->[0]->{$key2}); |
540 | 540 |
|
541 |
+test 'update_or_insert'; |
|
542 |
+eval { $dbi->execute("drop table $table1") }; |
|
543 |
+$dbi->execute($create_table1); |
|
544 |
+$dbi->update_or_insert( |
|
545 |
+ {$key2 => 2}, |
|
546 |
+ table => $table1, |
|
547 |
+ primary_key => $key1, |
|
548 |
+ id => 1 |
|
549 |
+); |
|
550 |
+$row = $dbi->select(id => 1, table => $table1, primary_key => $key1)->one; |
|
551 |
+is_deeply($row, {$key1 => 1, $key2 => 2}, "basic"); |
|
552 |
+ |
|
553 |
+$dbi->update_or_insert( |
|
554 |
+ {$key2 => 3}, |
|
555 |
+ table => $table1, |
|
556 |
+ primary_key => $key1, |
|
557 |
+ id => 1 |
|
558 |
+); |
|
559 |
+$rows = $dbi->select(id => 1, table => $table1, primary_key => $key1)->all; |
|
560 |
+is_deeply($rows, [{$key1 => 1, $key2 => 3}], "basic"); |
|
561 |
+ |
|
562 |
+eval { $dbi->execute("drop table $table1") }; |
|
563 |
+$dbi->execute($create_table1); |
|
564 |
+$dbi->update_or_insert( |
|
565 |
+ {$key1 => 1, $key2 => 2}, |
|
566 |
+ table => $table1, |
|
567 |
+ where => {$key1 => 1} |
|
568 |
+); |
|
569 |
+$row = $dbi->select(id => 1, table => $table1, primary_key => $key1)->one; |
|
570 |
+is_deeply($row, {$key1 => 1, $key2 => 2}, "basic"); |
|
571 |
+ |
|
572 |
+ |
|
573 |
+test 'default_bind_filter'; |
|
574 |
+$dbi->execute("delete from $table1"); |
|
575 |
+$dbi->register_filter( |
|
576 |
+ twice => sub { $_[0] * 2 }, |
|
577 |
+ three_times => sub { $_[0] * 3 } |
|
578 |
+); |
|
579 |
+$dbi->default_bind_filter('twice'); |
|
580 |
+$dbi->insert(table => $table1, param => {$key1 => 1, $key2 => 2}, filter => {$key1 => 'three_times'}); |
|
581 |
+$result = $dbi->execute("select * from $table1"); |
|
582 |
+$rows = $result->all; |
|
583 |
+is_deeply($rows, [{$key1 => 3, $key2 => 4}], "filter"); |
|
584 |
+$dbi->default_bind_filter(undef); |
|
585 |
+ |
|
541 | 586 |
test 'update'; |
542 | 587 |
eval { $dbi->execute("drop table $table1") }; |
543 | 588 |
$dbi->execute($create_table1_2); |
... | ... |
@@ -34,7 +34,7 @@ my $result; |
34 | 34 |
|
35 | 35 |
test 'connect'; |
36 | 36 |
eval { |
37 |
- $dbi = DBIx::Custom->new( |
|
37 |
+ $dbi = DBIx::Custom->connect( |
|
38 | 38 |
dsn => "dbi:mysql:database=$database;host=localhost;port=10000", |
39 | 39 |
user => $user, |
40 | 40 |
password => $password |
... | ... |
@@ -42,6 +42,21 @@ eval { |
42 | 42 |
}; |
43 | 43 |
ok(!$@); |
44 | 44 |
|
45 |
+eval { $dbi->do('drop table table1') }; |
|
46 |
+$dbi->do('create table table1 (key1 varchar(255), key2 varchar(255)) engine=InnoDB'); |
|
47 |
+ |
|
48 |
+test 'update_or_insert'; |
|
49 |
+$dbi->delete_all(table => 'table1'); |
|
50 |
+$dbi->update_or_insert( |
|
51 |
+ {key1 => 1, key2 => 2}, |
|
52 |
+ table => 'table1', |
|
53 |
+ where => {key1 => 1}, |
|
54 |
+ select_option => {append => 'for update'} |
|
55 |
+); |
|
56 |
+ |
|
57 |
+my $row = $dbi->select(id => 1, table => 'table1', primary_key => 'key1')->one; |
|
58 |
+is_deeply($row, {key1 => 1, key2 => 2}, "basic"); |
|
59 |
+ |
|
45 | 60 |
# Test memory leaks |
46 | 61 |
for (1 .. 200) { |
47 | 62 |
$dbi = DBIx::Custom->connect( |