added insert, update, update_all, delete, delete_all...
..., select method to DBIx::Custom...
... | ... |
@@ -1,3 +1,6 @@ |
1 |
+0.1627 |
|
2 |
+ added insert, update, update_all, delete, delete_all, select method to DBIx::Custom::Table |
|
3 |
+ added experimental txn_scope |
|
1 | 4 |
0.1626 |
2 | 5 |
simplified DBIx::Custom::Model and DBIx::Custom::Table |
3 | 6 |
0.1625 |
... | ... |
@@ -1,6 +1,6 @@ |
1 | 1 |
package DBIx::Custom; |
2 | 2 |
|
3 |
-our $VERSION = '0.1626'; |
|
3 |
+our $VERSION = '0.1627'; |
|
4 | 4 |
|
5 | 5 |
use 5.008001; |
6 | 6 |
use strict; |
... | ... |
@@ -606,6 +606,17 @@ sub select { |
606 | 606 |
return $result; |
607 | 607 |
} |
608 | 608 |
|
609 |
+sub txn_scope { |
|
610 |
+ my $self = shift; |
|
611 |
+ |
|
612 |
+ require DBIx::TransactionManager; |
|
613 |
+ |
|
614 |
+ $self->{_transaction_manager} |
|
615 |
+ ||= DBIx::TransactionManager->new($self->dbh); |
|
616 |
+ |
|
617 |
+ return $self->{_transaction_manager}->txn_scope; |
|
618 |
+} |
|
619 |
+ |
|
609 | 620 |
our %VALID_UPDATE_ARGS |
610 | 621 |
= map { $_ => 1 } qw/auto_filter_table table param |
611 | 622 |
where append filter allow_update_all/; |
... | ... |
@@ -753,37 +764,37 @@ Connect to the database. |
753 | 764 |
Insert, update, and delete |
754 | 765 |
|
755 | 766 |
# Insert |
756 |
- $dbi->insert(table => 'books', |
|
767 |
+ $dbi->insert(table => 'book', |
|
757 | 768 |
param => {title => 'Perl', author => 'Ken'}, |
758 | 769 |
filter => {title => 'encode_utf8'}); |
759 | 770 |
|
760 | 771 |
# Update |
761 |
- $dbi->update(table => 'books', |
|
772 |
+ $dbi->update(table => 'book', |
|
762 | 773 |
param => {title => 'Perl', author => 'Ken'}, |
763 | 774 |
where => {id => 5}, |
764 | 775 |
filter => {title => 'encode_utf8'}); |
765 | 776 |
|
766 | 777 |
# Update all |
767 |
- $dbi->update_all(table => 'books', |
|
778 |
+ $dbi->update_all(table => 'book', |
|
768 | 779 |
param => {title => 'Perl'}, |
769 | 780 |
filter => {title => 'encode_utf8'}); |
770 | 781 |
|
771 | 782 |
# Delete |
772 |
- $dbi->delete(table => 'books', |
|
783 |
+ $dbi->delete(table => 'book', |
|
773 | 784 |
where => {author => 'Ken'}, |
774 | 785 |
filter => {title => 'encode_utf8'}); |
775 | 786 |
|
776 | 787 |
# Delete all |
777 |
- $dbi->delete_all(table => 'books'); |
|
788 |
+ $dbi->delete_all(table => 'book'); |
|
778 | 789 |
|
779 | 790 |
Select |
780 | 791 |
|
781 | 792 |
# Select |
782 |
- my $result = $dbi->select(table => 'books'); |
|
793 |
+ my $result = $dbi->select(table => 'book'); |
|
783 | 794 |
|
784 | 795 |
# Select, more complex |
785 | 796 |
my $result = $dbi->select( |
786 |
- table => 'books', |
|
797 |
+ table => 'book', |
|
787 | 798 |
column => [qw/author title/], |
788 | 799 |
where => {author => 'Ken'}, |
789 | 800 |
append => 'order by id limit 5', |
... | ... |
@@ -792,14 +803,14 @@ Select |
792 | 803 |
|
793 | 804 |
# Select, join table |
794 | 805 |
my $result = $dbi->select( |
795 |
- table => ['books', 'rental'], |
|
796 |
- column => ['books.name as book_name'] |
|
797 |
- relation => {'books.id' => 'rental.book_id'} |
|
806 |
+ table => ['book', 'rental'], |
|
807 |
+ column => ['book.name as book_name'] |
|
808 |
+ relation => {'book.id' => 'rental.book_id'} |
|
798 | 809 |
); |
799 | 810 |
|
800 | 811 |
# Select, more flexible where |
801 | 812 |
my $result = $dbi->select( |
802 |
- table => 'books', |
|
813 |
+ table => 'book', |
|
803 | 814 |
where => ['{= author} and {like title}', |
804 | 815 |
{author => 'Ken', title => '%Perl%'}] |
805 | 816 |
); |
... | ... |
@@ -807,16 +818,16 @@ Select |
807 | 818 |
Execute SQL |
808 | 819 |
|
809 | 820 |
# Execute SQL |
810 |
- $dbi->execute("select title from books"); |
|
821 |
+ $dbi->execute("select title from book"); |
|
811 | 822 |
|
812 | 823 |
# Execute SQL with hash binding and filtering |
813 |
- $dbi->execute("select id from books where {= author} and {like title}", |
|
824 |
+ $dbi->execute("select id from book where {= author} and {like title}", |
|
814 | 825 |
param => {author => 'ken', title => '%Perl%'}, |
815 | 826 |
filter => {title => 'encode_utf8'}); |
816 | 827 |
|
817 | 828 |
# Create query and execute it |
818 | 829 |
my $query = $dbi->create_query( |
819 |
- "select id from books where {= author} and {like title}" |
|
830 |
+ "select id from book where {= author} and {like title}" |
|
820 | 831 |
); |
821 | 832 |
$dbi->execute($query, param => {author => 'Ken', title => '%Perl%'}) |
822 | 833 |
|
... | ... |
@@ -998,7 +1009,7 @@ arguments. |
998 | 1009 |
|
999 | 1010 |
B<Example:> |
1000 | 1011 |
|
1001 |
- $dbi->auto_filter('books', 'sale_date', 'to_date', 'date_to'); |
|
1012 |
+ $dbi->auto_filter('book', 'sale_date', 'to_date', 'date_to'); |
|
1002 | 1013 |
|
1003 | 1014 |
=head2 C<begin_work> |
1004 | 1015 |
|
... | ... |
@@ -1030,7 +1041,7 @@ and C<PrintError> option is false by default. |
1030 | 1041 |
=head2 C<create_query> |
1031 | 1042 |
|
1032 | 1043 |
my $query = $dbi->create_query( |
1033 |
- "select * from books where {= author} and {like title};" |
|
1044 |
+ "select * from book where {= author} and {like title};" |
|
1034 | 1045 |
); |
1035 | 1046 |
|
1036 | 1047 |
Create the instance of L<DBIx::Custom::Query> from the source of SQL. |
... | ... |
@@ -1065,7 +1076,7 @@ or the count of affected rows if insert, update, delete statement is executed. |
1065 | 1076 |
B<Example:> |
1066 | 1077 |
|
1067 | 1078 |
my $result = $dbi->execute( |
1068 |
- "select * from books where {= author} and {like title}", |
|
1079 |
+ "select * from book where {= author} and {like title}", |
|
1069 | 1080 |
param => {author => 'Ken', title => '%Perl%'} |
1070 | 1081 |
); |
1071 | 1082 |
|
... | ... |
@@ -1080,11 +1091,11 @@ B<Example:> |
1080 | 1091 |
|
1081 | 1092 |
The following hash |
1082 | 1093 |
|
1083 |
- {books => {title => 'Perl', author => 'Ken'}} |
|
1094 |
+ {book => {title => 'Perl', author => 'Ken'}} |
|
1084 | 1095 |
|
1085 | 1096 |
is expanded to |
1086 | 1097 |
|
1087 |
- ('books.title' => 'Perl', 'books.author' => 'Ken') |
|
1098 |
+ ('book.title' => 'Perl', 'book.author' => 'Ken') |
|
1088 | 1099 |
|
1089 | 1100 |
This is used in C<select()> |
1090 | 1101 |
|
... | ... |
@@ -1107,7 +1118,7 @@ Return value of C<delete()> is the count of affected rows. |
1107 | 1118 |
|
1108 | 1119 |
B<Example:> |
1109 | 1120 |
|
1110 |
- $dbi->delete(table => 'books', |
|
1121 |
+ $dbi->delete(table => 'book', |
|
1111 | 1122 |
where => {id => 5}, |
1112 | 1123 |
append => 'some statement', |
1113 | 1124 |
filter => {id => 'encode_utf8'}); |
... | ... |
@@ -1123,7 +1134,7 @@ Return value of C<delete_all()> is the count of affected rows. |
1123 | 1134 |
|
1124 | 1135 |
B<Example:> |
1125 | 1136 |
|
1126 |
- $dbi->delete_all(table => 'books'); |
|
1137 |
+ $dbi->delete_all(table => 'book'); |
|
1127 | 1138 |
|
1128 | 1139 |
=head2 C<(experimental) helper> |
1129 | 1140 |
|
... | ... |
@@ -1162,7 +1173,7 @@ Return value of C<insert()> is the count of affected rows. |
1162 | 1173 |
|
1163 | 1174 |
B<Example:> |
1164 | 1175 |
|
1165 |
- $dbi->insert(table => 'books', |
|
1176 |
+ $dbi->insert(table => 'book', |
|
1166 | 1177 |
param => {title => 'Perl', author => 'Taro'}, |
1167 | 1178 |
append => "some statement", |
1168 | 1179 |
filter => {title => 'encode_utf8'}) |
... | ... |
@@ -1262,33 +1273,33 @@ C<filter> is filters when parameter binding is executed. |
1262 | 1273 |
|
1263 | 1274 |
B<Example:> |
1264 | 1275 |
|
1265 |
- # select * from books; |
|
1266 |
- my $result = $dbi->select(table => 'books'); |
|
1276 |
+ # select * from book; |
|
1277 |
+ my $result = $dbi->select(table => 'book'); |
|
1267 | 1278 |
|
1268 |
- # select * from books where title = ?; |
|
1269 |
- my $result = $dbi->select(table => 'books', where => {title => 'Perl'}); |
|
1279 |
+ # select * from book where title = ?; |
|
1280 |
+ my $result = $dbi->select(table => 'book', where => {title => 'Perl'}); |
|
1270 | 1281 |
|
1271 |
- # select title, author from books where id = ? for update; |
|
1282 |
+ # select title, author from book where id = ? for update; |
|
1272 | 1283 |
my $result = $dbi->select( |
1273 |
- table => 'books', |
|
1284 |
+ table => 'book', |
|
1274 | 1285 |
column => ['title', 'author'], |
1275 | 1286 |
where => {id => 1}, |
1276 | 1287 |
appned => 'for update' |
1277 | 1288 |
); |
1278 | 1289 |
|
1279 |
- # select books.name as book_name from books, rental |
|
1280 |
- # where books.id = rental.book_id; |
|
1290 |
+ # select book.name as book_name from book, rental |
|
1291 |
+ # where book.id = rental.book_id; |
|
1281 | 1292 |
my $result = $dbi->select( |
1282 |
- table => ['books', 'rental'], |
|
1283 |
- column => ['books.name as book_name'] |
|
1284 |
- relation => {'books.id' => 'rental.book_id'} |
|
1293 |
+ table => ['book', 'rental'], |
|
1294 |
+ column => ['book.name as book_name'] |
|
1295 |
+ relation => {'book.id' => 'rental.book_id'} |
|
1285 | 1296 |
); |
1286 | 1297 |
|
1287 | 1298 |
If you use more complex condition, |
1288 | 1299 |
you can specify a array reference to C<where> argument. |
1289 | 1300 |
|
1290 | 1301 |
my $result = $dbi->select( |
1291 |
- table => 'books', |
|
1302 |
+ table => 'book', |
|
1292 | 1303 |
column => ['title', 'author'], |
1293 | 1304 |
where => ['{= title} or {like author}', |
1294 | 1305 |
{title => '%Perl%', author => 'Ken'}] |
... | ... |
@@ -1319,12 +1330,27 @@ Return value of C<update()> is the count of affected rows. |
1319 | 1330 |
|
1320 | 1331 |
B<Example:> |
1321 | 1332 |
|
1322 |
- $dbi->update(table => 'books', |
|
1333 |
+ $dbi->update(table => 'book', |
|
1323 | 1334 |
param => {title => 'Perl', author => 'Taro'}, |
1324 | 1335 |
where => {id => 5}, |
1325 | 1336 |
append => "some statement", |
1326 | 1337 |
filter => {title => 'encode_utf8'}); |
1327 | 1338 |
|
1339 |
+=head2 C<(experimental) txn_scope> |
|
1340 |
+ |
|
1341 |
+ { |
|
1342 |
+ my $txn = $dbi->txn_scope; |
|
1343 |
+ $dbi->insert(table => 'book', param => {title => 'Perl'}); |
|
1344 |
+ $dbi->insert(table => 'book', param => {title => 'Good days'}); |
|
1345 |
+ $txn->commit; |
|
1346 |
+ } |
|
1347 |
+ |
|
1348 |
+Create transaction scope. If you escape scope(that is { .. }) and commited, |
|
1349 |
+Rollback is automatically done. |
|
1350 |
+ |
|
1351 |
+Note that this is feature of L<DBIx::TransactionManager> |
|
1352 |
+L<DBIx::TransactionManager> is required. |
|
1353 |
+ |
|
1328 | 1354 |
=head2 C<update_all> |
1329 | 1355 |
|
1330 | 1356 |
$dbi->update_all(table => $table, |
... | ... |
@@ -1339,7 +1365,7 @@ Return value of C<update_all()> is the count of affected rows. |
1339 | 1365 |
|
1340 | 1366 |
B<Example:> |
1341 | 1367 |
|
1342 |
- $dbi->update_all(table => 'books', |
|
1368 |
+ $dbi->update_all(table => 'book', |
|
1343 | 1369 |
param => {author => 'taro'}, |
1344 | 1370 |
filter => {author => 'encode_utf8'}); |
1345 | 1371 |
|
... | ... |
@@ -18,12 +18,13 @@ sub table { |
18 | 18 |
my $table_class = $self->table_class; |
19 | 19 |
croak qq{Invalid table class name "$table_class"} |
20 | 20 |
unless $table_class =~ /^[\w:]+$/; |
21 |
- eval "use $table_class"; |
|
22 |
- croak $@ if $@; |
|
23 |
- |
|
21 |
+ unless ($table_class->can('isa')) { |
|
22 |
+ eval "require $table_class"; |
|
23 |
+ croak $@ if $@; |
|
24 |
+ } |
|
24 | 25 |
# Create table |
25 | 26 |
$self->tables->{$name} |
26 |
- = $table_class->new(name => $name, dbi => $self->dbi) |
|
27 |
+ = $table_class->new(name => $name, dbi => $self->dbi, model => $self) |
|
27 | 28 |
unless defined $self->tables->{$name}; |
28 | 29 |
|
29 | 30 |
return $self->{tables}{$name}; |
... | ... |
@@ -7,7 +7,7 @@ use base 'Object::Simple'; |
7 | 7 |
|
8 | 8 |
use Carp 'croak'; |
9 | 9 |
|
10 |
-__PACKAGE__->attr(['dbi', 'name']); |
|
10 |
+__PACKAGE__->attr(['dbi', 'name', 'model']); |
|
11 | 11 |
|
12 | 12 |
our $AUTOLOAD; |
13 | 13 |
|
... | ... |
@@ -36,6 +36,21 @@ sub helper { |
36 | 36 |
return $self; |
37 | 37 |
} |
38 | 38 |
|
39 |
+sub new { |
|
40 |
+ my $self = shift->SUPER::new(@_); |
|
41 |
+ |
|
42 |
+ my @methods = qw/insert update update_all delete delete_all select/; |
|
43 |
+ foreach my $method (@methods) { |
|
44 |
+ $self->helper( |
|
45 |
+ $method => sub { |
|
46 |
+ my $self = shift; |
|
47 |
+ return $self->dbi->$method(table => $self->name, @_); |
|
48 |
+ } |
|
49 |
+ ); |
|
50 |
+ } |
|
51 |
+ return $self; |
|
52 |
+} |
|
53 |
+ |
|
39 | 54 |
sub DESTROY { } |
40 | 55 |
|
41 | 56 |
1; |
... | ... |
@@ -55,6 +70,20 @@ my $table = DBIx::Custom::Table->new(name => 'books'); |
55 | 70 |
L<DBIx::Custom> inherits all methods from L<Object::Simple> |
56 | 71 |
and implements the following new ones. |
57 | 72 |
|
73 |
+=head2 C<delete> |
|
74 |
+ |
|
75 |
+ $table->delete(where => \%where); |
|
76 |
+ |
|
77 |
+Same as C<delete()> of L<DBIx::Custom> except that |
|
78 |
+you don't have to specify table name. |
|
79 |
+ |
|
80 |
+=head2 C<delete_all> |
|
81 |
+ |
|
82 |
+ $table->delete_all(param => $param); |
|
83 |
+ |
|
84 |
+Same as C<delete_all()> of L<DBIx::Custom> except that |
|
85 |
+you don't have to specify table name. |
|
86 |
+ |
|
58 | 87 |
=head2 C<helper> |
59 | 88 |
|
60 | 89 |
$table->helper(insert => sub { |
... | ... |
@@ -65,3 +94,49 @@ and implements the following new ones. |
65 | 94 |
|
66 | 95 |
Add helper method to a L<DBIx::Custom::Table> object. |
67 | 96 |
|
97 |
+=head2 C<insert> |
|
98 |
+ |
|
99 |
+ $table->insert(param => \%param); |
|
100 |
+ |
|
101 |
+Same as C<insert()> of L<DBIx::Custom> except that |
|
102 |
+you don't have to specify table name. |
|
103 |
+ |
|
104 |
+=head2 C<method> |
|
105 |
+ |
|
106 |
+ $table->method( |
|
107 |
+ select_complex => sub { |
|
108 |
+ my $self = shift; |
|
109 |
+ |
|
110 |
+ return $self->dbi->select($self->name, ...); |
|
111 |
+ }, |
|
112 |
+ some_method => sub { ... } |
|
113 |
+ ); |
|
114 |
+ |
|
115 |
+Define method. |
|
116 |
+ |
|
117 |
+=head2 C<new> |
|
118 |
+ |
|
119 |
+ my $table = DBIx::Custom::Table->new; |
|
120 |
+ |
|
121 |
+Create a L<DBIx::Custom::Table> object. |
|
122 |
+ |
|
123 |
+=head2 C<select> |
|
124 |
+ |
|
125 |
+ $table->select(param => $param); |
|
126 |
+ |
|
127 |
+Same as C<select()> of L<DBIx::Custom> except that |
|
128 |
+you don't have to specify table name. |
|
129 |
+ |
|
130 |
+=head2 C<update> |
|
131 |
+ |
|
132 |
+ $table->update(param => \%param, where => \%where); |
|
133 |
+ |
|
134 |
+Same as C<update()> of L<DBIx::Custom> except that |
|
135 |
+you don't have to specify table name. |
|
136 |
+ |
|
137 |
+=head2 C<update_all> |
|
138 |
+ |
|
139 |
+ $table->update_all(param => \%param); |
|
140 |
+ |
|
141 |
+Same as C<update_all()> of L<DBIx::Custom> except that |
|
142 |
+you don't have to specify table name. |
... | ... |
@@ -762,38 +762,14 @@ test 'model'; |
762 | 762 |
|
763 | 763 |
$self->dbi($dbi); |
764 | 764 |
|
765 |
- $self->table('table1')->helper( |
|
766 |
- insert => sub { |
|
767 |
- my $self = shift; |
|
768 |
- $self->dbi->insert(table => $self->name, @_); |
|
769 |
- }, |
|
770 |
- update => sub { |
|
771 |
- my $self = shift; |
|
772 |
- $self->dbi->update(table => $self->name, @_); |
|
773 |
- }, |
|
774 |
- update_all => sub { |
|
775 |
- my $self = shift; |
|
776 |
- $self->dbi->update_all(table => $self->name, @_); |
|
777 |
- }, |
|
778 |
- delete => sub { |
|
779 |
- my $self = shift; |
|
780 |
- $self->dbi->delete(table => $self->name, @_); |
|
781 |
- }, |
|
782 |
- delete_all => sub { |
|
783 |
- my $self = shift; |
|
784 |
- $self->dbi->delete_all(table => $self->name, @_); |
|
785 |
- }, |
|
786 |
- select => sub { |
|
787 |
- my $self = shift; |
|
788 |
- $self->dbi->select(table => $self->name, @_); |
|
789 |
- }, |
|
790 |
- ); |
|
791 | 765 |
return $self; |
792 | 766 |
} |
793 | 767 |
} |
794 | 768 |
$model = MyModel1->new; |
795 | 769 |
$model->dbi->execute($CREATE_TABLE->{0}); |
796 | 770 |
$table = $model->table('table1'); |
771 |
+is($table, $model->table('table1')); |
|
772 |
+is($table->model, $model); |
|
797 | 773 |
$table->insert(param => {key1 => 1, key2 => 2}); |
798 | 774 |
$table->insert(param => {key1 => 3, key2 => 4}); |
799 | 775 |
$rows = $table->select->fetch_hash_all; |
... | ... |
@@ -817,3 +793,5 @@ is_deeply($rows, [{key1 => 3, key2 => 4}], "$test: update_all"); |
817 | 793 |
$table->delete_all; |
818 | 794 |
$rows = $table->select->fetch_hash_all; |
819 | 795 |
is_deeply($rows, [], "$test: delete_all"); |
796 |
+ |
|
797 |
+ |
... | ... |
@@ -0,0 +1,53 @@ |
1 |
+use Test::More; |
|
2 |
+ |
|
3 |
+eval {require DBIx::TransactionManager; 1} |
|
4 |
+ or plan skip_all => 'required DBIx::TransactionManager'; |
|
5 |
+ |
|
6 |
+plan 'no_plan'; |
|
7 |
+ |
|
8 |
+use DBIx::Custom; |
|
9 |
+ |
|
10 |
+# Function for test name |
|
11 |
+my $test; |
|
12 |
+sub test {$test = shift } |
|
13 |
+ |
|
14 |
+# Constant varialbes for test |
|
15 |
+my $CREATE_TABLE = { |
|
16 |
+ 0 => 'create table table1 (key1 char(255), key2 char(255));', |
|
17 |
+}; |
|
18 |
+ |
|
19 |
+my $NEW_ARGS = { |
|
20 |
+ 0 => {data_source => 'dbi:SQLite:dbname=:memory:'} |
|
21 |
+}; |
|
22 |
+ |
|
23 |
+# Variables |
|
24 |
+my $dbi; |
|
25 |
+my $result; |
|
26 |
+my $txn; |
|
27 |
+ |
|
28 |
+test 'transaction'; |
|
29 |
+$dbi = DBIx::Custom->connect($NEW_ARGS->{0}); |
|
30 |
+$dbi->execute($CREATE_TABLE->{0}); |
|
31 |
+{ |
|
32 |
+ my $txn = $dbi->txn_scope; |
|
33 |
+ $dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2}); |
|
34 |
+ $dbi->insert(table => 'table1', param => {key1 => 2, key2 => 3}); |
|
35 |
+ $txn->commit; |
|
36 |
+} |
|
37 |
+$result = $dbi->select(table => 'table1'); |
|
38 |
+is_deeply(scalar $result->fetch_hash_all, [{key1 => 1, key2 => 2}, {key1 => 2, key2 => 3}], |
|
39 |
+ "$test : commit"); |
|
40 |
+ |
|
41 |
+$dbi = DBIx::Custom->connect($NEW_ARGS->{0}); |
|
42 |
+$dbi->execute($CREATE_TABLE->{0}); |
|
43 |
+ |
|
44 |
+{ |
|
45 |
+ local $SIG{__WARN__} = sub {}; |
|
46 |
+ { |
|
47 |
+ my $txn = $dbi->txn_scope; |
|
48 |
+ $dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2}); |
|
49 |
+ } |
|
50 |
+} |
|
51 |
+$result = $dbi->select(table => 'table1'); |
|
52 |
+ok(! $result->fetch_first, "$test: rollback"); |
|
53 |
+ |