- removed EXPERIMENTAL status from the following...
...methods and functinalities.
... | ... |
@@ -1,3 +1,14 @@ |
1 |
+0.2107 |
|
2 |
+ - removed EXPERIMENTAL status from the following methods and functinalities. |
|
3 |
+ DBIx::Custom::Result::value method |
|
4 |
+ DBIx::Custom::Result::column method |
|
5 |
+ DBIx::Custom::insert method "bulk_insert" option |
|
6 |
+ DBIx::Custom::insert method "multiplue insert functinality" |
|
7 |
+ DBIx::Custom::select method "first argument is received as column option" |
|
8 |
+ DBIx::Custom::Model::created_at attribute |
|
9 |
+ DBIx::Custom::Model::updated_at attribute |
|
10 |
+ - added EXPERIMENTAL DBIx::Custom::execute method "prepare_attr" option |
|
11 |
+ - added EXPERIMETNAL DBIx::Custom::execute method "statement" option |
|
1 | 12 |
0.2106 |
2 | 13 |
- renamed DBIx::Custom::Result::fetch_hash_first to fethc_hash_one |
3 | 14 |
because first is misleading name. fethc_hash_first is DEPRECATED! |
... | ... |
@@ -354,6 +354,7 @@ sub execute { |
354 | 354 |
# Merge second parameter |
355 | 355 |
my @cleanup; |
356 | 356 |
my $saved_param; |
357 |
+ $opt{statement} ||= ''; |
|
357 | 358 |
if (($opt{statement} || '') ne 'insert' && ref $params eq 'ARRAY') { |
358 | 359 |
my $params2 = $params->[1]; |
359 | 360 |
$params = $params->[0]; |
... | ... |
@@ -395,7 +396,8 @@ sub execute { |
395 | 396 |
unless $column =~ /^[$c\.]+$/; |
396 | 397 |
} |
397 | 398 |
} |
398 |
- $query = $self->_create_query($sql,$opt{after_build_sql} || $opt{sqlfilter}); |
|
399 |
+ $query = $self->_create_query($sql, |
|
400 |
+ $opt{after_build_sql} || $opt{sqlfilter}, $opt{prepare_attr}); |
|
399 | 401 |
} |
400 | 402 |
$query->{statement} = $opt{statement} || ''; |
401 | 403 |
$opt{reuse}->{$sql} = $query if $opt{reuse}; |
... | ... |
@@ -554,7 +556,7 @@ sub execute { |
554 | 556 |
} |
555 | 557 |
|
556 | 558 |
# Not select statement |
557 |
- return $affected unless $sth->{NUM_OF_FIELDS}; |
|
559 |
+ return $affected if !$sth->{NUM_OF_FIELDS} && $opt{statement} ne 'select'; |
|
558 | 560 |
|
559 | 561 |
# Filter(DEPRECATED!) |
560 | 562 |
my $infilter = {}; |
... | ... |
@@ -1269,7 +1271,9 @@ sub where { DBIx::Custom::Where->new(dbi => shift, @_) } |
1269 | 1271 |
|
1270 | 1272 |
sub _create_query { |
1271 | 1273 |
|
1272 |
- my ($self, $source, $after_build_sql) = @_; |
|
1274 |
+ my ($self, $source, $after_build_sql, $prepare_attr) = @_; |
|
1275 |
+ |
|
1276 |
+ $prepare_attr ||= {}; |
|
1273 | 1277 |
|
1274 | 1278 |
# Cache |
1275 | 1279 |
my $cache = $self->{cache}; |
... | ... |
@@ -1344,7 +1348,7 @@ sub _create_query { |
1344 | 1348 |
|
1345 | 1349 |
# Prepare statement handle |
1346 | 1350 |
my $sth; |
1347 |
- eval { $sth = $self->dbh->prepare($query->{sql}) }; |
|
1351 |
+ eval { $sth = $self->dbh->prepare($query->{sql}, $prepare_attr) }; |
|
1348 | 1352 |
|
1349 | 1353 |
if ($@) { |
1350 | 1354 |
$self->_croak($@, qq{. Following SQL is executed.\n} |
... | ... |
@@ -2631,6 +2635,13 @@ The following SQL is executed. |
2631 | 2635 |
|
2632 | 2636 |
Append some statement after SQL. |
2633 | 2637 |
|
2638 |
+=item C<prepare_attr> EXPERIMENTAL |
|
2639 |
+ |
|
2640 |
+ prepare_attr => {async => 1} |
|
2641 |
+ |
|
2642 |
+Statemend handle attributes, |
|
2643 |
+this is L<DBI>'s C<prepare> method second argument. |
|
2644 |
+ |
|
2634 | 2645 |
=item C<bind_type> |
2635 | 2646 |
|
2636 | 2647 |
Specify database bind data type. |
... | ... |
@@ -2694,6 +2705,12 @@ because generally creating query object is slow. |
2694 | 2705 |
|
2695 | 2706 |
Priamry key. This is used for C<id> option. |
2696 | 2707 |
|
2708 |
+=item C<statement> EXPERIMETAL |
|
2709 |
+ |
|
2710 |
+ statement => 'select' |
|
2711 |
+ |
|
2712 |
+If you set statement to C<select>, return value is always L<DBIx::Custom::Result> object. |
|
2713 |
+ |
|
2697 | 2714 |
=item C<table> |
2698 | 2715 |
|
2699 | 2716 |
table => 'author' |
... | ... |
@@ -2790,7 +2807,6 @@ as parameter value. |
2790 | 2807 |
{date => \"NOW()"} |
2791 | 2808 |
|
2792 | 2809 |
You can pass multiple parameters, this is very fast. |
2793 |
-This is EXPERIMETNAL. |
|
2794 | 2810 |
|
2795 | 2811 |
$dbi->insert( |
2796 | 2812 |
[ |
... | ... |
@@ -2801,7 +2817,7 @@ This is EXPERIMETNAL. |
2801 | 2817 |
); |
2802 | 2818 |
|
2803 | 2819 |
In multiple insert, you can't use C<id> option. |
2804 |
-and only first parameter is used by creating sql. |
|
2820 |
+and only first parameter is used to create sql. |
|
2805 | 2821 |
|
2806 | 2822 |
B<options> |
2807 | 2823 |
|
... | ... |
@@ -2809,8 +2825,8 @@ C<insert> method use all of C<execute> method's options, |
2809 | 2825 |
and use the following new ones. |
2810 | 2826 |
|
2811 | 2827 |
=over 4 |
2812 |
-b |
|
2813 |
-=item C<bulk_insert> EXPERIMENTAL |
|
2828 |
+ |
|
2829 |
+=item C<bulk_insert> |
|
2814 | 2830 |
|
2815 | 2831 |
bulk_insert => 1 |
2816 | 2832 |
|
... | ... |
@@ -3030,7 +3046,6 @@ Register filters, used by C<filter> option of many methods. |
3030 | 3046 |
Execute select statement. |
3031 | 3047 |
|
3032 | 3048 |
You can pass odd number arguments. first argument is C<column>. |
3033 |
-This is EXPERIMENTAL. |
|
3034 | 3049 |
|
3035 | 3050 |
my $result = $dbi->select(['author', 'title'], table => 'book'); |
3036 | 3051 |
|
... | ... |
@@ -185,7 +185,7 @@ my $model = DBIx::Custom::Model->new(table => 'books'); |
185 | 185 |
|
186 | 186 |
L<DBIx::Custom> object. |
187 | 187 |
|
188 |
-=head2 C<created_at EXPERIMENTAL> |
|
188 |
+=head2 C<created_at> |
|
189 | 189 |
|
190 | 190 |
my $created_at = $model->created_at; |
191 | 191 |
$model = $model->created_at('created_datatime'); |
... | ... |
@@ -225,7 +225,7 @@ Database data type, this is used as type optioon of C<insert>, |
225 | 225 |
C<update>, C<update_all>, C<delete>, C<delete_all>, |
226 | 226 |
and C<select> method |
227 | 227 |
|
228 |
-=head2 C<updated_at EXPERIMENTAL> |
|
228 |
+=head2 C<updated_at> |
|
229 | 229 |
|
230 | 230 |
my $updated_at = $model->updated_at; |
231 | 231 |
$model = $model->updated_at('updated_datatime'); |
... | ... |
@@ -327,7 +327,7 @@ sub _cache { |
327 | 327 |
$self->{_type_map} = {}; |
328 | 328 |
$self->{_pos} = {}; |
329 | 329 |
$self->{_columns} = {}; |
330 |
- for (my $i = 0; $i < @{$self->{sth}->{NAME}}; $i++) { |
|
330 |
+ for (my $i = 0; $i < @{$self->{sth}->{NAME} || []}; $i++) { |
|
331 | 331 |
my $type = lc $self->{sth}{TYPE}[$i]; |
332 | 332 |
my $name = $self->{sth}{NAME}[$i]; |
333 | 333 |
$self->{_type_map}{$type} ||= []; |
... | ... |
@@ -496,7 +496,7 @@ and implements the following new ones. |
496 | 496 |
|
497 | 497 |
Same as C<fetch_hash_all>. |
498 | 498 |
|
499 |
-=head2 C<column> EXPERIMENTAL |
|
499 |
+=head2 C<column> |
|
500 | 500 |
|
501 | 501 |
my $column = $result->column; |
502 | 502 |
|
... | ... |
@@ -645,7 +645,7 @@ By default, type rule is on. |
645 | 645 |
Turn C<from2> type rule on. |
646 | 646 |
By default, type rule is on. |
647 | 647 |
|
648 |
-=head2 C<value> EXPERIMENTAL |
|
648 |
+=head2 C<value> |
|
649 | 649 |
|
650 | 650 |
my $value = $result->value; |
651 | 651 |
|
... | ... |
@@ -0,0 +1,96 @@ |
1 |
+use Test::More; |
|
2 |
+use strict; |
|
3 |
+use warnings; |
|
4 |
+use utf8; |
|
5 |
+ |
|
6 |
+use FindBin; |
|
7 |
+use DBIx::Custom; |
|
8 |
+ |
|
9 |
+my $dbi; |
|
10 |
+my $dsn; |
|
11 |
+my $args; |
|
12 |
+my $user = 'dbix_custom'; |
|
13 |
+my $password = 'dbix_custom'; |
|
14 |
+my $database = 'dbix_custom'; |
|
15 |
+ |
|
16 |
+$dsn = "dbi:mysql:database=$database"; |
|
17 |
+$args = {dsn => $dsn, user => $user, password => $password,}; |
|
18 |
+ |
|
19 |
+plan skip_all => 'mysql private test' unless -f "$FindBin::Bin/run/mysql-async.run" |
|
20 |
+ && eval { $dbi = DBIx::Custom->connect($args); 1 }; |
|
21 |
+plan 'no_plan'; |
|
22 |
+ |
|
23 |
+$SIG{__WARN__} = sub { warn $_[0] unless $_[0] =~ /DEPRECATED/}; |
|
24 |
+ |
|
25 |
+# Function for test name |
|
26 |
+sub test { print "# $_[0]\n" } |
|
27 |
+ |
|
28 |
+# Varialbes for tests |
|
29 |
+my $dbname; |
|
30 |
+my $row; |
|
31 |
+my $rows; |
|
32 |
+my $result; |
|
33 |
+my $result2; |
|
34 |
+my $model; |
|
35 |
+my $dbi2; |
|
36 |
+ |
|
37 |
+test 'connect'; |
|
38 |
+eval { |
|
39 |
+ $dbi = DBIx::Custom->connect( |
|
40 |
+ dsn => "dbi:mysql:database=$database;host=localhost;port=10000", |
|
41 |
+ user => $user, |
|
42 |
+ password => $password |
|
43 |
+ ); |
|
44 |
+}; |
|
45 |
+ok(!$@); |
|
46 |
+ |
|
47 |
+eval { $dbi->do('drop table table1') }; |
|
48 |
+$dbi->do('create table table1 (key1 varchar(255), key2 varchar(255)) engine=InnoDB'); |
|
49 |
+$dbi->insert({key1 => 1, key2 => 2}, table => 'table1'); |
|
50 |
+ |
|
51 |
+test 'async test'; |
|
52 |
+ |
|
53 |
+use AnyEvent; |
|
54 |
+use DBI; |
|
55 |
+my $cond = AnyEvent->condvar; |
|
56 |
+$result = $dbi->execute('SELECT SLEEP(1), 3', undef, |
|
57 |
+ prepare_attr => {async => 1}, statement => 'select'); |
|
58 |
+ |
|
59 |
+$dbi2 = DBIx::Custom->connect( |
|
60 |
+ dsn => "dbi:mysql:database=$database;host=localhost;port=10000", |
|
61 |
+ user => $user, |
|
62 |
+ password => $password |
|
63 |
+); |
|
64 |
+$result2 = $dbi2->select('key1', table => 'table1', prepare_attr => {async => 1}); |
|
65 |
+ |
|
66 |
+my $timer = AnyEvent->timer( |
|
67 |
+ interval => 1, |
|
68 |
+ cb => sub { |
|
69 |
+ 1; |
|
70 |
+ } |
|
71 |
+); |
|
72 |
+ |
|
73 |
+my $count = 0; |
|
74 |
+ |
|
75 |
+my $mysql_watcher = AnyEvent->io( |
|
76 |
+ fh => $dbi->dbh->mysql_fd, |
|
77 |
+ poll => 'r', |
|
78 |
+ cb => sub { |
|
79 |
+ my $row = $result->fetch_one; |
|
80 |
+ is($row->[1], 3, 'before'); |
|
81 |
+ $cond->send if ++$count == 2; |
|
82 |
+ undef $result; |
|
83 |
+ } |
|
84 |
+); |
|
85 |
+ |
|
86 |
+my $mysql_watcher2= AnyEvent->io( |
|
87 |
+ fh => $dbi2->dbh->mysql_fd, |
|
88 |
+ poll => 'r', |
|
89 |
+ cb => sub { |
|
90 |
+ my $row = $result2->fetch_one; |
|
91 |
+ is($row->[0], 1, 'after'); |
|
92 |
+ $cond->send if ++$count == 2; |
|
93 |
+ undef $result2; |
|
94 |
+ } |
|
95 |
+); |
|
96 |
+$cond->recv; |