... | ... |
@@ -1,5 +1,7 @@ |
1 | 1 |
0.1502 |
2 |
- update document |
|
2 |
+ added commit method |
|
3 |
+ added rollback method |
|
4 |
+ changed select argument, added relation option |
|
3 | 5 |
moved host attribute to DBIx::Custom::MySQL |
4 | 6 |
moved port attribute to DBIx::Custom::MySQL |
5 | 7 |
moved database attribute to DBIx::Custom::MySQL and DBIx::Custom::SQLite |
... | ... |
@@ -13,7 +13,6 @@ use DBIx::Custom::Query; |
13 | 13 |
use Encode qw/encode_utf8 decode_utf8/; |
14 | 14 |
|
15 | 15 |
__PACKAGE__->attr('dbh'); |
16 |
- |
|
17 | 16 |
__PACKAGE__->attr([qw/user password data_source/]); |
18 | 17 |
__PACKAGE__->attr([qw/default_query_filter default_fetch_filter/]); |
19 | 18 |
|
... | ... |
@@ -40,9 +39,6 @@ sub register_filter { |
40 | 39 |
sub auto_commit { |
41 | 40 |
my $self = shift; |
42 | 41 |
|
43 |
- # Not connected |
|
44 |
- croak("Not yet connect to database") unless $self->connected; |
|
45 |
- |
|
46 | 42 |
if (@_) { |
47 | 43 |
|
48 | 44 |
# Set AutoCommit |
... | ... |
@@ -53,6 +49,9 @@ sub auto_commit { |
53 | 49 |
return $self->dbh->{AutoCommit}; |
54 | 50 |
} |
55 | 51 |
|
52 |
+sub commit { shift->dbh->commit } |
|
53 |
+sub rollback { shift->dbh->rollback } |
|
54 |
+ |
|
56 | 55 |
sub connect { |
57 | 56 |
my $proto = shift; |
58 | 57 |
|
... | ... |
@@ -124,7 +123,7 @@ sub create_query { |
124 | 123 |
my $sql_template = $self->sql_template; |
125 | 124 |
|
126 | 125 |
# Get cached query |
127 |
- my $cache = $self->{_cache}->{"$template"}; |
|
126 |
+ my $cache = $self->{_cache}->{$template}; |
|
128 | 127 |
|
129 | 128 |
# Create query |
130 | 129 |
my $query; |
... | ... |
@@ -139,7 +138,7 @@ sub create_query { |
139 | 138 |
croak($@) if $@; |
140 | 139 |
|
141 | 140 |
$self->{_cache}->{$template} = $query |
142 |
- unless $self->{_cache}; |
|
141 |
+ unless $self->{_cache}->{$template}; |
|
143 | 142 |
} |
144 | 143 |
|
145 | 144 |
# Prepare statement handle |
... | ... |
@@ -457,7 +456,7 @@ sub delete_all { |
457 | 456 |
} |
458 | 457 |
|
459 | 458 |
our %VALID_SELECT_ARGS |
460 |
- = map { $_ => 1 } qw/table column where append filter/; |
|
459 |
+ = map { $_ => 1 } qw/table column where append relation filter param/; |
|
461 | 460 |
|
462 | 461 |
sub select { |
463 | 462 |
my $self = shift;; |
... | ... |
@@ -473,15 +472,17 @@ sub select { |
473 | 472 |
# Arguments |
474 | 473 |
my $tables = $args->{table} || []; |
475 | 474 |
$tables = [$tables] unless ref $tables eq 'ARRAY'; |
476 |
- my $columns = $args->{column} || []; |
|
477 |
- my $where_params = $args->{where} || {}; |
|
478 |
- my $append_statement = $args->{append} || ''; |
|
479 |
- my $filter = $args->{filter}; |
|
475 |
+ my $columns = $args->{column} || []; |
|
476 |
+ my $where = $args->{where} || {}; |
|
477 |
+ my $relation = $args->{relation}; |
|
478 |
+ my $append = $args->{append}; |
|
479 |
+ my $filter = $args->{filter}; |
|
480 |
+ my $param = $args->{param} || {}; |
|
480 | 481 |
|
481 | 482 |
# SQL template for select statement |
482 | 483 |
my $template = 'select '; |
483 | 484 |
|
484 |
- # Join column clause |
|
485 |
+ # Column clause |
|
485 | 486 |
if (@$columns) { |
486 | 487 |
foreach my $column (@$columns) { |
487 | 488 |
$template .= "$column, "; |
... | ... |
@@ -492,17 +493,15 @@ sub select { |
492 | 493 |
$template .= '* '; |
493 | 494 |
} |
494 | 495 |
|
495 |
- # Join table |
|
496 |
+ # Table |
|
496 | 497 |
$template .= 'from '; |
497 | 498 |
foreach my $table (@$tables) { |
498 | 499 |
$template .= "$table, "; |
499 | 500 |
} |
500 | 501 |
$template =~ s/, $/ /; |
501 | 502 |
|
502 |
- # Where clause keys |
|
503 |
- my @where_keys = keys %$where_params; |
|
504 |
- |
|
505 |
- # Join where clause |
|
503 |
+ # Where clause |
|
504 |
+ my @where_keys = keys %$where; |
|
506 | 505 |
if (@where_keys) { |
507 | 506 |
$template .= 'where '; |
508 | 507 |
foreach my $where_key (@where_keys) { |
... | ... |
@@ -511,21 +510,20 @@ sub select { |
511 | 510 |
} |
512 | 511 |
$template =~ s/ and $//; |
513 | 512 |
|
514 |
- # Append something to last of statement |
|
515 |
- if ($append_statement =~ s/^where //) { |
|
516 |
- if (@where_keys) { |
|
517 |
- $template .= " and $append_statement"; |
|
513 |
+ # Relation |
|
514 |
+ if ($relation) { |
|
515 |
+ $template .= @where_keys ? "and " : "where "; |
|
516 |
+ foreach my $rkey (keys %$relation) { |
|
517 |
+ $template .= "$rkey = " . $relation->{$rkey} . " and "; |
|
518 | 518 |
} |
519 |
- else { |
|
520 |
- $template .= " where $append_statement"; |
|
521 |
- } |
|
522 |
- } |
|
523 |
- else { |
|
524 |
- $template .= " $append_statement"; |
|
525 | 519 |
} |
520 |
+ $template =~ s/ and $//; |
|
521 |
+ |
|
522 |
+ # Append some statement |
|
523 |
+ $template .= " $append" if $append; |
|
526 | 524 |
|
527 | 525 |
# Execute query |
528 |
- my $result = $self->execute($template, param => $where_params, |
|
526 |
+ my $result = $self->execute($template, param => $where, |
|
529 | 527 |
filter => $filter); |
530 | 528 |
|
531 | 529 |
return $result; |
... | ... |
@@ -589,6 +587,13 @@ This module is not stable. Method name and functionality will be change. |
589 | 587 |
append => 'order by id limit 1', |
590 | 588 |
filter => {tilte => 'encode_utf8'} |
591 | 589 |
); |
590 |
+ |
|
591 |
+ # Select(Join table) |
|
592 |
+ my $result = $dbi->select( |
|
593 |
+ table => ['books', 'rental'], |
|
594 |
+ column => ['books.name as book_name'] |
|
595 |
+ relation => {'books.id' => 'rental.book_id'} |
|
596 |
+ ); |
|
592 | 597 |
|
593 | 598 |
# Execute SQL |
594 | 599 |
$dbi->execute("select title from books"); |
... | ... |
@@ -710,6 +715,26 @@ This is equal to |
710 | 715 |
$dbi->dbh->{AutoCommit} = 1; |
711 | 716 |
$auto_commit = $dbi->dbh->{AutoCommit}; |
712 | 717 |
|
718 |
+=head2 commit |
|
719 |
+ |
|
720 |
+Commit. |
|
721 |
+ |
|
722 |
+ $dbi->commit; |
|
723 |
+ |
|
724 |
+This is equal to |
|
725 |
+ |
|
726 |
+ $dbi->dbh->commit; |
|
727 |
+ |
|
728 |
+=head2 rollback |
|
729 |
+ |
|
730 |
+Rollback. |
|
731 |
+ |
|
732 |
+ $dbi->rollback |
|
733 |
+ |
|
734 |
+This is equal to |
|
735 |
+ |
|
736 |
+ $dbi->dbh->rollback; |
|
737 |
+ |
|
713 | 738 |
=head2 connect |
714 | 739 |
|
715 | 740 |
Connect to database. |
... | ... |
@@ -767,23 +792,19 @@ Example. |
767 | 792 |
|
768 | 793 |
=head2 create_query |
769 | 794 |
|
770 |
-Create Query instance parsing SQL template |
|
795 |
+Create the instance of L<DBIx::Custom::Query>. |
|
796 |
+This receive the string written by SQL template. |
|
771 | 797 |
|
772 | 798 |
my $query = $dbi->create_query("select * from authors where {= name} and {= age}"); |
773 | 799 |
|
774 |
-$query is <DBIx::Query> instance. This is executed by query method as the following |
|
775 |
- |
|
776 |
- $dbi->execute($query, $params); |
|
777 |
- |
|
778 |
-If you know SQL template, see also L<DBIx::Custom::SQLTemplate>. |
|
779 |
- |
|
780 | 800 |
=head2 execute |
781 | 801 |
|
782 |
-Query |
|
802 |
+Execute the query or the string written by SQL template. |
|
783 | 803 |
|
784 |
- $result = $dbi->execute($template, $params); |
|
804 |
+ $result = $dbi->execute($query, param => $params, filter => {%filter}); |
|
805 |
+ $result = $dbi->execute($template, param => $params, filter => {%filter}); |
|
785 | 806 |
|
786 |
-The following is query example |
|
807 |
+Example. |
|
787 | 808 |
|
788 | 809 |
$result = $dbi->execute("select * from authors where {= name} and {= age}", |
789 | 810 |
{name => 'taro', age => 19}); |
... | ... |
@@ -792,22 +813,22 @@ The following is query example |
792 | 813 |
# do something |
793 | 814 |
} |
794 | 815 |
|
795 |
-If you now syntax of template, See also L<DBIx::Custom::SQLTemplate> |
|
816 |
+See also L<DBIx::Custom::SQLTemplate>. |
|
796 | 817 |
|
797 |
-execute() return L<DBIx::Custom::Result> instance |
|
818 |
+Returned value L<DBIx::Custom::Result> instance. |
|
798 | 819 |
|
799 | 820 |
=head2 insert |
800 | 821 |
|
801 |
-Insert row |
|
822 |
+Insert row. |
|
802 | 823 |
|
803 | 824 |
$affected = $dbi->insert(table => $table, |
804 | 825 |
param => {%param}, |
805 | 826 |
append => $append, |
806 | 827 |
filter => {%filter}); |
807 | 828 |
|
808 |
-Retrun value is affected rows count |
|
829 |
+Retruned value is affected rows count. |
|
809 | 830 |
|
810 |
-Example |
|
831 |
+Example. |
|
811 | 832 |
|
812 | 833 |
# insert |
813 | 834 |
$dbi->insert(table => 'books', |
... | ... |
@@ -817,7 +838,7 @@ Example |
817 | 838 |
|
818 | 839 |
=head2 update |
819 | 840 |
|
820 |
-Update rows |
|
841 |
+Update rows. |
|
821 | 842 |
|
822 | 843 |
$affected = $dbi->update(table => $table, |
823 | 844 |
param => {%params}, |
... | ... |
@@ -825,29 +846,29 @@ Update rows |
825 | 846 |
append => $append, |
826 | 847 |
filter => {%filter}) |
827 | 848 |
|
828 |
-Retrun value is affected rows count |
|
849 |
+Retruned value is affected rows count |
|
829 | 850 |
|
830 |
-Example |
|
851 |
+Example. |
|
831 | 852 |
|
832 | 853 |
#update |
833 | 854 |
$dbi->update(table => 'books', |
834 | 855 |
param => {title => 'Perl', author => 'Taro'}, |
835 | 856 |
where => {id => 5}, |
836 | 857 |
append => "some statement", |
837 |
- filter => {title => 'encode_utf8'}) |
|
858 |
+ filter => {title => 'encode_utf8'}); |
|
838 | 859 |
|
839 | 860 |
=head2 update_all |
840 | 861 |
|
841 |
-Update all rows |
|
862 |
+Update all rows. |
|
842 | 863 |
|
843 | 864 |
$affected = $dbi->update_all(table => $table, |
844 | 865 |
param => {%params}, |
845 | 866 |
filter => {%filter}, |
846 | 867 |
append => $append); |
847 | 868 |
|
848 |
-Retrun value is affected rows count |
|
869 |
+Retruned value is affected rows count. |
|
849 | 870 |
|
850 |
-Example |
|
871 |
+Example. |
|
851 | 872 |
|
852 | 873 |
# update_all |
853 | 874 |
$dbi->update_all(table => 'books', |
... | ... |
@@ -856,17 +877,16 @@ Example |
856 | 877 |
|
857 | 878 |
=head2 delete |
858 | 879 |
|
859 |
-Delete rows |
|
880 |
+Delete rows. |
|
860 | 881 |
|
861 |
- # delete |
|
862 | 882 |
$affected = $dbi->delete(table => $table, |
863 | 883 |
where => {%where}, |
864 |
- append => $append |
|
884 |
+ append => $append, |
|
865 | 885 |
filter => {%filter}); |
866 | 886 |
|
867 | 887 |
Retrun value is affected rows count |
868 | 888 |
|
869 |
-Example |
|
889 |
+Example. |
|
870 | 890 |
|
871 | 891 |
# delete |
872 | 892 |
$dbi->delete(table => 'books', |
... | ... |
@@ -876,11 +896,11 @@ Example |
876 | 896 |
|
877 | 897 |
=head2 delete_all |
878 | 898 |
|
879 |
-Delete all rows |
|
899 |
+Delete all rows. |
|
880 | 900 |
|
881 | 901 |
$affected = $dbi->delete_all(table => $table); |
882 | 902 |
|
883 |
-Retrun value is affected rows count |
|
903 |
+Retruned value is affected rows count. |
|
884 | 904 |
|
885 | 905 |
Example |
886 | 906 |
|
... | ... |
@@ -889,19 +909,20 @@ Example |
889 | 909 |
|
890 | 910 |
=head2 select |
891 | 911 |
|
892 |
-Select rows |
|
912 |
+Select rows. |
|
893 | 913 |
|
894 |
- $result = $dbi->select(table => $table, |
|
895 |
- column => [@column], |
|
896 |
- where => {%where}, |
|
897 |
- append => $append, |
|
898 |
- filter => {%filter}); |
|
914 |
+ $result = $dbi->select(table => $table, |
|
915 |
+ column => [@column], |
|
916 |
+ where => {%where}, |
|
917 |
+ append => $append, |
|
918 |
+ relation => {%relation} |
|
919 |
+ filter => {%filter}); |
|
899 | 920 |
|
900 |
-$reslt is L<DBIx::Custom::Result> instance |
|
921 |
+Returned value is L<DBIx::Custom::Result> instance. |
|
901 | 922 |
|
902 |
-The following is some select examples |
|
923 |
+Example. |
|
903 | 924 |
|
904 |
- # select |
|
925 |
+ # select * from books; |
|
905 | 926 |
$result = $dbi->select('books'); |
906 | 927 |
|
907 | 928 |
# select * from books where title = 'Perl'; |
... | ... |
@@ -910,18 +931,17 @@ The following is some select examples |
910 | 931 |
# select title, author from books where id = 1 for update; |
911 | 932 |
$result = $dbi->select( |
912 | 933 |
table => 'books', |
913 |
- where => ['title', 'author'], |
|
934 |
+ column => ['title', 'author'], |
|
914 | 935 |
where => {id => 1}, |
915 | 936 |
appned => 'for update' |
916 | 937 |
); |
917 |
- |
|
918 |
-You can join multi tables |
|
919 | 938 |
|
920 |
- $result = $dbi->select( |
|
921 |
- ['table1', 'table2'], # tables |
|
922 |
- ['table1.id as table1_id', 'title'], # columns (alias is ok) |
|
923 |
- {table1.id => 1}, # where clase |
|
924 |
- "where table1.id = table2.id", # join clause (must start 'where') |
|
939 |
+ # select books.name as book_name from books, rental |
|
940 |
+ # where books.id = rental.book_id; |
|
941 |
+ my $result = $dbi->select( |
|
942 |
+ table => ['books', 'rental'], |
|
943 |
+ column => ['books.name as book_name'] |
|
944 |
+ relation => {'books.id' => 'rental.book_id'} |
|
925 | 945 |
); |
926 | 946 |
|
927 | 947 |
=head1 AUTHOR |
... | ... |
@@ -930,7 +950,7 @@ Yuki Kimoto, C<< <kimoto.yuki at gmail.com> >> |
930 | 950 |
|
931 | 951 |
Github L<http://github.com/yuki-kimoto> |
932 | 952 |
|
933 |
-I develope this module L<http://github.com/yuki-kimoto/DBIx-Custom> |
|
953 |
+I develope this module on L<http://github.com/yuki-kimoto/DBIx-Custom> |
|
934 | 954 |
|
935 | 955 |
=head1 COPYRIGHT & LICENSE |
936 | 956 |
|
... | ... |
@@ -389,9 +389,16 @@ $rows = $dbi->select( |
389 | 389 |
table => [qw/table1 table2/], |
390 | 390 |
column => ['table1.key1 as table1_key1', 'table2.key1 as table2_key1', 'key2', 'key3'], |
391 | 391 |
where => {'table1.key2' => 2}, |
392 |
- append => "where table1.key1 = table2.key1" |
|
392 |
+ relation => {'table1.key1' => 'table2.key1'} |
|
393 | 393 |
)->fetch_hash_all; |
394 |
-is_deeply($rows, [{table1_key1 => 1, table2_key1 => 1, key2 => 2, key3 => 5}], "$test : join"); |
|
394 |
+is_deeply($rows, [{table1_key1 => 1, table2_key1 => 1, key2 => 2, key3 => 5}], "$test : relation : exists where"); |
|
395 |
+ |
|
396 |
+$rows = $dbi->select( |
|
397 |
+ table => [qw/table1 table2/], |
|
398 |
+ column => ['table1.key1 as table1_key1', 'table2.key1 as table2_key1', 'key2', 'key3'], |
|
399 |
+ relation => {'table1.key1' => 'table2.key1'} |
|
400 |
+)->fetch_hash_all; |
|
401 |
+is_deeply($rows, [{table1_key1 => 1, table2_key1 => 1, key2 => 2, key3 => 5}], "$test : relation : no exists where"); |
|
395 | 402 |
|
396 | 403 |
test 'fetch filter'; |
397 | 404 |
$dbi = DBIx::Custom->connect($NEW_ARGS->{0}); |
... | ... |
@@ -416,3 +423,22 @@ is($dbi->filters->{decode_utf8}->(encode_utf8('あ')), |
416 | 423 |
is($dbi->filters->{encode_utf8}->('あ'), |
417 | 424 |
encode_utf8('あ'), "$test : encode_utf8"); |
418 | 425 |
|
426 |
+test 'transaction'; |
|
427 |
+$dbi = DBIx::Custom->connect($NEW_ARGS->{0}); |
|
428 |
+$dbi->execute($CREATE_TABLE->{0}); |
|
429 |
+$dbi->auto_commit(0); |
|
430 |
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2}); |
|
431 |
+$dbi->insert(table => 'table1', param => {key1 => 2, key2 => 3}); |
|
432 |
+$dbi->commit; |
|
433 |
+$result = $dbi->select(table => 'table1'); |
|
434 |
+is_deeply(scalar $result->fetch_hash_all, [{key1 => 1, key2 => 2}, {key1 => 2, key2 => 3}], |
|
435 |
+ "$test : commit"); |
|
436 |
+ |
|
437 |
+$dbi = DBIx::Custom->connect($NEW_ARGS->{0}); |
|
438 |
+$dbi->execute($CREATE_TABLE->{0}); |
|
439 |
+$dbi->auto_commit(0); |
|
440 |
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2}); |
|
441 |
+$dbi->rollback; |
|
442 |
+ |
|
443 |
+$result = $dbi->select(table => 'table1'); |
|
444 |
+ok(! $result->fetch_single, "$test: rollback"); |