- 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( |