1use Test::More;
2use strict;
3use warnings;
4use Encode qw/encode_utf8/;
5use FindBin;
6use Scalar::Util 'isweak';
7
8 $ENV{DBIX_CUSTOM_SUPPRESS_DEPRECATION} = '0.39';
9
10plan skip_all => $ENV{DBIX_CUSTOM_SKIP_MESSAGE} || 'common.t is always skipped'
11  unless $ENV{DBIX_CUSTOM_TEST_RUN}
12    && eval { DBIx::Custom->connect; 1 };
13
14plan 'no_plan';
15
16# Dot to under score
17sub u($) {
18  my $value = shift;
19  $value =~ s/\./_/g;
20  return $value;
21}
22
23sub u2($) {
24  my $value = shift;
25  $value =~ s/\./__/g;
26  return $value;
27}
28
29sub hy($) {
30  my $value = shift;
31  $value =~ s/\./-/g;
32  return $value;
33}
34
35sub colon2 {
36  my $value = shift;
37  $value =~ s/\./::/g;
38  return $value;
39}
40
41sub table_only {
42  my $value = shift;
43  $value =~ s/^.+\.//;
44  return $value;
45}
46
47# Global variable
48my $table1;
49my $table2;
50my $table2_alias;
51my $table3;
52my $key1;
53my $key2;
54my $key3;
55my $key4;
56my $key5;
57my $key6;
58my $key7;
59my $key8;
60my $key9;
61my $key10;
62my $create_table1;
63my $create_table1_2;
64my $create_table1_type;
65my $create_table1_highperformance;
66my $create_table2;
67my $create_table2_2;
68my $create_table3;
69my $create_table_reserved;
70my ($q, $p);
71my $date_typename;
72my $datetime_typename;
73my $date_datatype;
74my $datetime_datatype;
75my $user_table_info;
76
77# Global setting
78{
79  my $dbi = DBIx::Custom->connect;
80
81  $table1 = $dbi->table1;
82  $table2 = $dbi->table2;
83  $table2_alias = $dbi->table2_alias;
84  $table3 = $dbi->table3;
85  $key1 = $dbi->key1;
86  $key2 = $dbi->key2;
87  $key3 = $dbi->key3;
88  $key4 = $dbi->key4;
89  $key5 = $dbi->key5;
90  $key6 = $dbi->key6;
91  $key7 = $dbi->key7;
92  $key8 = $dbi->key8;
93  $key9 = $dbi->key9;
94  $key10 = $dbi->key10;
95  $create_table1 = $dbi->create_table1;
96  $create_table1_2 = $dbi->create_table1_2;
97  $create_table1_type = $dbi->create_table1_type;
98  $create_table1_highperformance = $dbi->create_table1_highperformance;
99  $create_table2 = $dbi->create_table2;
100  $create_table2_2 = $dbi->create_table2_2;
101  $create_table3 = $dbi->create_table3;
102  $create_table_reserved = $dbi->create_table_reserved;
103  ($q, $p) = $dbi->_qp;
104  $date_typename = $dbi->date_typename;
105  $datetime_typename = $dbi->datetime_typename;
106  $date_datatype = $dbi->date_datatype;
107  $datetime_datatype = $dbi->datetime_datatype;
108}
109
110{
111  package MyModel2::Base1;
112
113  use strict;
114  use warnings;
115
116  use base 'DBIx::Custom::Model';
117
118  package MyModel2::table1;
119
120  use strict;
121  use warnings;
122
123  use base 'MyModel2::Base1';
124
125  sub insert {
126    my ($self, $param) = @_;
127
128    return $self->SUPER::insert($param);
129  }
130
131  sub list { shift->select; }
132
133  package MyModel2::table2;
134
135  use strict;
136  use warnings;
137
138  use base 'MyModel2::Base1';
139
140  sub insert {
141    my ($self, $param) = @_;
142
143    return $self->SUPER::insert($param);
144  }
145
146  sub list { shift->select; }
147
148  package MyModel2::TABLE1;
149
150  use strict;
151  use warnings;
152
153  use base 'MyModel2::Base1';
154
155  sub insert {
156    my ($self, $param) = @_;
157
158    return $self->SUPER::insert($param);
159  }
160
161  sub list { shift->select; }
162
163  package MyModel2::TABLE2;
164
165  use strict;
166  use warnings;
167
168  use base 'MyModel2::Base1';
169
170  sub insert {
171    my ($self, $param) = @_;
172
173    return $self->SUPER::insert($param);
174  }
175
176  sub list { shift->select; }
177
178
179  package MyModel2::main::table1;
180
181  use strict;
182  use warnings;
183
184  use base 'MyModel2::Base1';
185
186  sub insert {
187    my ($self, $param) = @_;
188
189    return $self->SUPER::insert($param);
190  }
191
192  sub list { shift->select; }
193
194  package MyModel2::main::table2;
195
196  use strict;
197  use warnings;
198
199  use base 'MyModel2::Base1';
200
201  sub insert {
202    my ($self, $param) = @_;
203
204    return $self->SUPER::insert($param);
205  }
206
207  sub list { shift->select; }
208
209  package MyModel2::dbix_custom::table1;
210
211  use strict;
212  use warnings;
213
214  use base 'MyModel2::Base1';
215
216  sub insert {
217    my ($self, $param) = @_;
218
219    return $self->SUPER::insert($param);
220  }
221
222  sub list { shift->select; }
223
224  package MyModel2::dbix_custom::table2;
225
226  use strict;
227  use warnings;
228
229  use base 'MyModel2::Base1';
230
231  sub insert {
232    my ($self, $param) = @_;
233
234    return $self->SUPER::insert($param);
235  }
236
237  sub list { shift->select; }
238}
239
240# Check safety character
241{
242  my $dbi = DBIx::Custom->connect;
243
244  # Check safety character - insert
245  eval{$dbi->insert({';' => 1}, table => $table1)};
246  like($@, qr/";" is not safety column name in values clause/);
247
248  # Check safety character - update
249  eval{$dbi->update({';' => 1}, table => $table1, where => {$key1 => 1})};
250  like($@, qr/";" is not safety column name in assign clause/);
251
252  # Check safety character - select
253  eval { $dbi->select(table => $table1, where => {';' => 1}) };
254  like($@, qr/";" is not safety column name in where clause/);
255}
256
257# model
258{
259  # model - table name is different
260  {
261    my $dbi = DBIx::Custom->connect;
262    eval { $dbi->execute("drop table $table1") };
263    $dbi->execute($create_table1);
264    $dbi->create_model(name => 'foo', table => $table1);
265
266    $dbi->model('foo')->insert({$key1 => 1, $key2 => 2});
267    is_deeply($dbi->model('foo')->select->all, [{$key1 => 1, $key2 => 2}]);
268  }
269
270  # model - one argument is table name
271  {
272    my $dbi = DBIx::Custom->connect;
273    eval { $dbi->execute("drop table $table1") };
274    $dbi->execute($create_table1);
275    $dbi->create_model($table1, join => ['aaa']);
276    is_deeply($dbi->model($table1)->join, ['aaa']);
277    $dbi->model($table1)->join([]);
278
279    $dbi->model($table1)->insert({$key1 => 1, $key2 => 2});
280    is_deeply($dbi->model($table1)->select->all, [{$key1 => 1, $key2 => 2}]);
281  }
282}
283
284# DBI compatible connect arguments
285{
286  my $dbi_tmp = DBIx::Custom->new;
287
288  my $dbi = DBIx::Custom->connect($dbi_tmp->dsn, $dbi_tmp->user, $dbi_tmp->password, {RaiseError => 0}, {last_sql => 'A'});
289
290  is($dbi->last_sql, 'A');
291  ok(!$dbi->dbh->{RaiseError});
292
293  eval { $dbi->execute("drop table $table1") };
294  $dbi->execute($create_table1);
295  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
296  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
297
298  {
299    my $rows = $dbi->select(table => $table1)->all;
300    is_deeply($rows, [{$key1 => 1, $key2 => 2},
301      {$key1 => 3, $key2 => 4}], "table");
302  }
303}
304
305# mycolumn and column
306{
307  my $dbi = DBIx::Custom->connect;
308  $dbi->user_table_info($user_table_info);
309  eval { $dbi->execute("drop table $table1") };
310  eval { $dbi->execute("drop table $table2") };
311  $dbi->execute($create_table1);
312  $dbi->execute($create_table2);
313
314  $dbi->include_model('MyModel6');
315
316  $dbi->separator('__');
317  $dbi->setup_model;
318  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
319  $dbi->insert({$key1 => 1, $key3 => 3}, table => $table2);
320  my $model = $dbi->model($table1);
321
322  {
323    my $result = $model->select(
324      column => [$model->mycolumn, $model->column($table2)],
325      where => {"$table1.$key1" => 1}
326    );
327    is_deeply($result->one,
328            {$key1 => 1, $key2 => 2, u2"${table2}__$key1" => 1, u2"${table2}__$key3" => 3});
329  }
330
331  {
332    my $result = $model->select(
333      column => [$model->mycolumn, $model->column($table2 => '*')],
334      where => {"$table1.$key1" => 1}
335    );
336    is_deeply($result->one,
337            {$key1 => 1, $key2 => 2, u2"${table2}__$key1" => 1, u2"${table2}__$key3" => 3});
338  }
339
340  {
341    my $result = $model->select(
342      column => [
343        {__MY__ => '*'},
344        {$table2 => '*'}
345      ],
346      where => {"$table1.$key1" => 1}
347    );
348    is_deeply($result->one,
349            {$key1 => 1, $key2 => 2, u2"${table2}__$key1" => 1, u2"${table2}__$key3" => 3});
350  }
351
352  {
353    my $result = $model->select(
354      column => [
355        {__MY2__ => '*'},
356        {$table2 => '*'}
357      ],
358      where => {"$table1.$key1" => 1},
359      mytable_symbol => '__MY2__'
360    );
361    is_deeply($result->one,
362            {$key1 => 1, $key2 => 2, u2"${table2}__$key1" => 1, u2"${table2}__$key3" => 3});
363  }
364
365  {
366    my $original = $model->dbi->mytable_symbol;
367    $model->dbi->mytable_symbol('__MY2__');
368    my $result = $model->select(
369      column => [
370        {__MY2__ => '*'},
371        {$table2 => '*'}
372      ],
373      where => {"$table1.$key1" => 1},
374    );
375    is_deeply($result->one,
376            {$key1 => 1, $key2 => 2, u2"${table2}__$key1" => 1, u2"${table2}__$key3" => 3});
377    $model->dbi->mytable_symbol($original);
378  }
379}
380
381
382# get_columns_from_db
383{
384  my $dbi = DBIx::Custom->connect;
385
386  eval { $dbi->execute("drop table $table1") };
387  $dbi->execute($create_table1_2);
388
389  my $columns = $dbi->get_columns_from_db($table1);
390  is_deeply($columns, [$key1, $key2, $key3, $key4, $key5]);
391}
392
393# query option
394{
395  my $dbi = DBIx::Custom->connect;
396
397  eval { $dbi->execute("drop table $table1") };
398  $dbi->execute($create_table1);
399
400  my $param = {$key1 => 1, $key2 => 2};
401  my $query = $dbi->insert($param, table => $table1, query => 1);
402
403  my $sth = $dbi->dbh->prepare($query->sql);
404  $sth->execute(@{$query->bind_values});
405
406  $param = {$key1 => 3, $key2 => 4};
407  $query->param($param);
408  $query->build;
409  $sth->execute(@{$query->bind_values});
410
411  my $result = $dbi->select(table => $table1);
412  my $rows = $result->all;
413  is_deeply($rows, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}]);
414}
415
416# insert
417{
418  my $dbi = DBIx::Custom->connect;
419  eval { $dbi->execute("drop table $table1") };
420  $dbi->execute($create_table1);
421  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
422  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
423  my $result = $dbi->execute("select * from $table1");
424  my $rows = $result->all;
425  is_deeply($rows, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}]);
426}
427
428{
429  my $dbi = DBIx::Custom->connect;
430  eval { $dbi->execute("drop table $table1") };
431  $dbi->execute($create_table1);
432  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
433  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
434  my $result = $dbi->execute("select * from $table1");
435  my $rows = $result->all;
436  is_deeply($rows, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}]);
437}
438
439{
440  my $dbi = DBIx::Custom->connect;
441
442  eval { $dbi->execute("drop table $table1") };
443  $dbi->execute($create_table1);
444  $dbi->register_filter(
445    three_times => sub { $_[0] * 3 }
446  );
447  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1, filter => {$key1 => 'three_times'});
448  my $result = $dbi->execute("select * from $table1");
449  my $rows = $result->all;
450  is_deeply($rows, [{$key1 => 3, $key2 => 2}]);
451  $dbi->delete_all(table => $table1);
452}
453
454{
455  my $dbi = DBIx::Custom->connect;
456  eval { $dbi->execute("drop table $table1") };
457  $dbi->execute($create_table1);
458  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
459  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
460  my $result = $dbi->execute("select * from $table1");
461  my $rows = $result->all;
462  is_deeply($rows, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}], "basic");
463}
464
465{
466  my $dbi = DBIx::Custom->connect;
467  eval { $dbi->execute("drop table $table1") };
468  $dbi->execute($create_table1);
469  $dbi->insert({$key1 => \"'1'", $key2 => 2}, table => $table1);
470  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
471  my $result = $dbi->execute("select * from $table1");
472  my $rows = $result->all;
473  is_deeply($rows, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}], "basic");
474}
475
476{
477  my $dbi = DBIx::Custom->connect;
478  eval { $dbi->execute("drop table $table1") };
479  $dbi->execute($create_table1);
480  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1,
481  wrap => {$key1 => sub { "$_[0] - 1" }});
482  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
483  my $result = $dbi->execute("select * from $table1");
484  my $rows = $result->all;
485  is_deeply($rows, [{$key1 => 0, $key2 => 2}, {$key1 => 3, $key2 => 4}], "basic");
486}
487
488{
489  my $dbi = DBIx::Custom->connect;
490  eval { $dbi->execute("drop table $table1") };
491  $dbi->execute($create_table1_2);
492  my $param = {$key1 => 1};
493  $dbi->insert($param, table => $table1, ctime => $key2);
494  my $result = $dbi->select(table => $table1);
495  is_deeply($param, {$key1 => 1});
496  my $row = $result->one;
497  is($row->{$key1}, 1);
498  like($row->{$key2}, qr/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/);
499}
500
501{
502  my $dbi = DBIx::Custom->connect;
503  eval { $dbi->execute("drop table $table1") };
504  $dbi->execute($create_table1_2);
505  my $param = {$key1 => 1};
506  $dbi->insert($param, table => $table1, mtime => $key3);
507  my $result = $dbi->select(table => $table1);
508  is_deeply($param, {$key1 => 1});
509  my $row = $result->one;
510  is($row->{$key1}, 1);
511  like($row->{$key3}, qr/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/);
512}
513
514{
515  my $dbi = DBIx::Custom->connect;
516  eval { $dbi->execute("drop table $table1") };
517  $dbi->execute($create_table1_2);
518  my $param = {$key1 => 1};
519  $dbi->insert($param, table => $table1, ctime => $key2, mtime => $key3);
520  my $result = $dbi->select(table => $table1);
521  is_deeply($param, {$key1 => 1});
522  my $row = $result->one;
523  is($row->{$key1}, 1);
524  like($row->{$key2}, qr/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/);
525  like($row->{$key3}, qr/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/);
526  is($row->{$key2}, $row->{$key3});
527}
528
529{
530  my $dbi = DBIx::Custom->connect;
531  eval { $dbi->execute("drop table $table1") };
532  $dbi->execute($create_table1_2);
533  my $model = $dbi->create_model(table => $table1, ctime => $key2);
534  my $param = {$key1 => 1};
535  $model->insert($param);
536  my $result = $dbi->select(table => $table1);
537  is_deeply($param, {$key1 => 1});
538  my $row   = $result->one;
539  is($row->{$key1}, 1);
540  like($row->{$key2}, qr/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/);
541}
542
543{
544  my $dbi = DBIx::Custom->connect;
545  eval { $dbi->execute("drop table $table1") };
546  $dbi->execute($create_table1_2);
547  my $param = {$key1 => 1};
548  my $model = $dbi->create_model(table => $table1, mtime => $key3);
549  $model->insert($param);
550  my $result = $dbi->select(table => $table1);
551  is_deeply($param, {$key1 => 1});
552  my $row   = $result->one;
553  is($row->{$key1}, 1);
554  like($row->{$key3}, qr/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/);
555}
556
557{
558  my $dbi = DBIx::Custom->connect;
559  eval { $dbi->execute("drop table $table1") };
560  $dbi->execute($create_table1_2);
561  my $param = {$key1 => 1};
562  my $model = $dbi->create_model(table => $table1, ctime=> $key2, mtime => $key3);
563  $model->insert($param);
564  my $result = $dbi->select(table => $table1);
565  is_deeply($param, {$key1 => 1});
566  my $row   = $result->one;
567  is($row->{$key1}, 1);
568  like($row->{$key2}, qr/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/);
569  like($row->{$key3}, qr/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/);
570  is($row->{$key2}, $row->{$key3});
571}
572
573{
574  my $dbi = DBIx::Custom->connect;
575
576  eval { $dbi->execute("drop table $table1") };
577  $dbi->execute($create_table1);
578  $dbi->insert([{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}] , table => $table1);
579  my $result = $dbi->execute("select * from $table1");
580  my $rows = $result->all;
581  is_deeply($rows, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}], "basic");
582}
583
584{
585  my $dbi = DBIx::Custom->connect;
586  eval { $dbi->execute("drop table $table1") };
587  $dbi->execute($create_table1_2);
588  $dbi->insert([{$key1 => 1}, {$key1 => 3}] ,
589    table => $table1,
590    mtime => $key2,
591    ctime => $key3
592  );
593  my $result = $dbi->execute("select * from $table1");
594  my $rows = $result->all;
595  is($rows->[0]->{$key1}, 1);
596  is($rows->[1]->{$key1}, 3);
597  like($rows->[0]->{$key2}, qr/\d{2}:/);
598  like($rows->[1]->{$key2}, qr/\d{2}:/);
599  like($rows->[0]->{$key3}, qr/\d{2}:/);
600  like($rows->[1]->{$key3}, qr/\d{2}:/);
601}
602
603{
604  my $dbi = DBIx::Custom->connect;
605
606  eval { $dbi->execute("drop table $table1") };
607  $dbi->execute($create_table1);
608  $dbi->insert([{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}] ,
609  table => $table1, filter => {$key1 => sub { $_[0] * 2 }});
610  my $result = $dbi->execute("select * from $table1");
611  my $rows = $result->all;
612  is_deeply($rows, [{$key1 => 2, $key2 => 2}, {$key1 => 6, $key2 => 4}], "basic");
613}
614
615# Create table
616{
617  my $dbi = DBIx::Custom->connect;
618  {
619    eval { $dbi->execute("drop table $table1") };
620    $dbi->execute($create_table1);
621    my $model = $dbi->create_model(table => $table1);
622    $model->insert({$key1 => 1, $key2 => 2});
623    is_deeply($model->select->all, [{$key1 => 1, $key2 => 2}]);
624  }
625  {
626    eval { $dbi->execute("drop table $table1") };
627    $dbi->execute($create_table1);
628    my $model = $dbi->create_model(table => $table1);
629    $model->insert({$key1 => 1, $key2 => 2});
630    is_deeply($model->select($key1)->all, [{$key1 => 1}]);
631  }
632}
633
634# execute reuse option (this option become no more meaning)
635{
636  my $dbi = DBIx::Custom->connect;
637
638  eval { $dbi->execute("drop table $table1") };
639  $dbi->execute($create_table1);
640  my $reuse = {};
641  for my $i (1 .. 2) {
642  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1, reuse => $reuse);
643  }
644  my $rows = $dbi->select(table => $table1)->all;
645  is_deeply($rows, [{$key1 => 1, $key2 => 2}, {$key1 => 1, $key2 => 2}]);
646}
647
648# Get user table info
649{
650  my $dbi = DBIx::Custom->connect;
651  eval { $dbi->execute("drop table $table1") };
652  eval { $dbi->execute("drop table $table2") };
653  eval { $dbi->execute("drop table $table3") };
654  $dbi->execute($create_table1);
655  $dbi->execute($create_table2);
656  $dbi->execute($create_table3);
657  $user_table_info = $dbi->get_table_info(exclude => $dbi->exclude_table);
658}
659
660# DBIx::Custom::Result test
661{
662  my $dbi = DBIx::Custom->connect;
663
664  eval { $dbi->execute("drop table $table1") };
665  $dbi->execute($create_table1);
666
667  $dbi->delete_all(table => $table1);
668  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
669  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
670
671  my $source = "select $key1, $key2 from $table1";
672  {
673    my $result = $dbi->execute($source);
674    my @rows = ();
675    while (my $row = $result->fetch) {
676      push @rows, [@$row];
677    }
678    is_deeply(\@rows, [[1, 2], [3, 4]], "fetch");
679  }
680
681  {
682    my $result = $dbi->execute($source);
683    my @rows = ();
684    while (my $row = $result->fetch_hash) {
685      push @rows, {%$row};
686    }
687    is_deeply(\@rows, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}], "fetch_hash");
688  }
689
690  {
691    my $result = $dbi->execute($source);
692    my $rows = $result->fetch_all;
693    is_deeply($rows, [[1, 2], [3, 4]]);
694  }
695
696  {
697    my $result = $dbi->execute($source);
698    my $rows = $result->fetch_hash_all;
699    is_deeply($rows, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}], "all");
700  }
701
702  is_deeply($dbi->select($key1, table => $table1)->values, [1, 3]);
703
704  is($dbi->select('count(*)', table => $table1)->value, 2);
705  ok(!defined $dbi->select($key1, table => $table1, where => {$key1 => 10})->value);
706}
707
708# Named placeholder
709{
710  my $dbi = DBIx::Custom->connect;
711  eval { $dbi->execute("drop table $table1") };
712  $dbi->execute($create_table1_2);
713  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}, table => $table1);
714  $dbi->insert({$key1 => 6, $key2 => 7, $key3 => 8, $key4 => 9, $key5 => 10}, table => $table1);
715  {
716    my $source = "select * from $table1 where $key1 = :$key1 and $key2 = :$key2";
717    my $result = $dbi->execute($source, {$key1 => 1, $key2 => 2});
718    my $rows = $result->all;
719    is_deeply($rows, [{$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}]);
720  }
721  {
722    my $source = "select * from $table1 where $key1 = \n:$key1\n and $key2 = :$key2";
723    my $result = $dbi->execute($source, {$key1 => 1, $key2 => 2});
724    my $rows = $result->all;
725    is_deeply($rows, [{$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}]);
726  }
727  {
728    my $source = "select * from $table1 where $key1 = :$key1 or $key1 = :$key1";
729    my $result = $dbi->execute($source, {$key1 => [1, 2]});
730    my $rows = $result->all;
731    is_deeply($rows, [{$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}]);
732  }
733  {
734    my $source = "select * from $table1 where $key1 = :$table1.$key1 and $key2 = :$table1.$key2";
735    my $result = $dbi->execute(
736      $source,
737      {"$table1.$key1" => 1, "$table1.$key2" => 1},
738      filter => {"$table1.$key2" => sub { $_[0] * 2 }}
739    );
740    my $rows = $result->all;
741    is_deeply($rows, [{$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}]);
742  }
743
744
745  {
746    eval { $dbi->execute("drop table $table1") };
747    $dbi->execute($create_table1);
748    $dbi->insert({$key1 => '2011-10-14 12:19:18', $key2 => 2}, table => $table1);
749    my $source = "select * from $table1 where $key1 = '2011-10-14 12:19:18' and $key2 = :$key2";
750    my $result = $dbi->execute(
751      $source,
752      {$key2 => 2},
753    );
754
755    my $rows = $result->all;
756    like($rows->[0]->{$key1}, qr/2011-10-14 12:19:18/);
757    is($rows->[0]->{$key2}, 2);
758  }
759
760  {
761    $dbi->delete_all(table => $table1);
762    $dbi->insert({$key1 => 'a:b c:d', $key2 => 2}, table => $table1);
763    my $source = "select * from $table1 where $key1 = 'a\\:b c\\:d' and $key2 = :$key2";
764    my $result = $dbi->execute(
765      $source,
766      {$key2 => 2},
767    );
768    my $rows = $result->all;
769    is_deeply($rows, [{$key1 => 'a:b c:d', $key2 => 2}]);
770  }
771
772  # Error case
773  eval {DBIx::Custom->connect(dsn => 'dbi:SQLit')};
774  ok($@, "connect error");
775}
776
777# update_or_insert
778{
779  my $dbi = DBIx::Custom->connect;
780
781  eval { $dbi->execute("drop table $table1") };
782  $dbi->execute($create_table1);
783  $dbi->update_or_insert(
784    {$key2 => 2},
785    table => $table1,
786    primary_key => $key1,
787    id => 1
788  );
789  {
790    my $row = $dbi->select(id => 1, table => $table1, primary_key => $key1)->one;
791    is_deeply($row, {$key1 => 1, $key2 => 2}, "basic");
792  }
793
794  $dbi->update_or_insert(
795    {$key2 => 3},
796    table => $table1,
797    primary_key => $key1,
798    id => 1
799  );
800  {
801    my $rows = $dbi->select(id => 1, table => $table1, primary_key => $key1)->all;
802    is_deeply($rows, [{$key1 => 1, $key2 => 3}], "basic");
803  }
804
805  eval {
806    $dbi->update_or_insert(
807      {$key2 => 3},
808      table => $table1,
809    );
810  };
811
812  like($@, qr/primary_key/);
813
814  eval {
815    $dbi->insert({$key1 => 1}, table => $table1);
816    $dbi->update_or_insert(
817      {$key2 => 3},
818      table => $table1,
819      primary_key => $key1,
820      id => 1
821    );
822  };
823  like($@, qr/one/);
824
825  eval { $dbi->execute("drop table $table1") };
826  $dbi->execute($create_table1);
827  $dbi->update_or_insert(
828    {},
829    table => $table1,
830    primary_key => $key1,
831    id => 1
832  );
833  my $row = $dbi->select(id => 1, table => $table1, primary_key => $key1)->one;
834  is($row->{$key1}, 1);
835
836  {
837    my $affected;
838    eval {
839      $affected = $dbi->update_or_insert(
840        {},
841        table => $table1,
842        primary_key => $key1,
843        id => 1
844      );
845    };
846    is($affected, 0);
847  }
848}
849
850# model update_or_insert
851{
852  my $dbi = DBIx::Custom->connect;
853
854  eval { $dbi->execute("drop table $table1") };
855  $dbi->execute($create_table1);
856  my $model = $dbi->create_model(
857    table => $table1,
858    primary_key => $key1
859  );
860  $model->update_or_insert({$key2 => 2}, id => 1);
861  my $row = $model->select(id => 1)->one;
862  is_deeply($row, {$key1 => 1, $key2 => 2}, "basic");
863
864  eval {
865    $model->insert({$key1 => 1});
866    $model->update_or_insert(
867      {$key2 => 3},
868      id => 1
869    );
870  };
871  like($@, qr/one/);
872}
873
874# bind filter
875{
876  my $dbi = DBIx::Custom->connect;
877
878  eval { $dbi->execute("drop table $table1") };
879  $dbi->execute($create_table1);
880
881  $dbi->register_filter(
882    three_times => sub { $_[0] * 3 }
883  );
884  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1, filter => {$key1 => 'three_times'});
885  my $result = $dbi->execute("select * from $table1");
886  my $rows = $result->all;
887  is_deeply($rows, [{$key1 => 3, $key2 => 2}], "filter");
888}
889
890# update
891{
892  my $dbi = DBIx::Custom->connect;
893
894  {
895    eval { $dbi->execute("drop table $table1") };
896    $dbi->execute($create_table1_2);
897    $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}, table => $table1);
898    $dbi->insert({$key1 => 6, $key2 => 7, $key3 => 8, $key4 => 9, $key5 => 10}, table => $table1);
899    $dbi->update({$key2 => 11}, table => $table1, where => {$key1 => 1});
900    my $result = $dbi->execute("select * from $table1 order by $key1");
901    my $rows = $result->all;
902    is_deeply($rows, [{$key1 => 1, $key2 => 11, $key3 => 3, $key4 => 4, $key5 => 5},
903      {$key1 => 6, $key2 => 7,  $key3 => 8, $key4 => 9, $key5 => 10}],
904      "basic");
905  }
906
907  {
908    eval { $dbi->execute("drop table $table1") };
909    $dbi->execute($create_table1_2);
910    $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}, table => $table1);
911    $dbi->insert({$key1 => 6, $key2 => 7, $key3 => 8, $key4 => 9, $key5 => 10}, table => $table1);
912    $dbi->update({$key2 => 11}, table => $table1, where => {$key1 => 1});
913    my $result = $dbi->execute("select * from $table1 order by $key1");
914    my $rows = $result->all;
915    is_deeply($rows, [{$key1 => 1, $key2 => 11, $key3 => 3, $key4 => 4, $key5 => 5},
916      {$key1 => 6, $key2 => 7,  $key3 => 8, $key4 => 9, $key5 => 10}],
917      "basic");
918  }
919
920  {
921    $dbi->execute("delete from $table1");
922    $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}, table => $table1);
923    $dbi->insert({$key1 => 6, $key2 => 7, $key3 => 8, $key4 => 9, $key5 => 10}, table => $table1);
924    $dbi->update({$key2 => 12}, table => $table1, where => {$key2 => 2, $key3 => 3});
925    my $result = $dbi->execute("select * from $table1 order by $key1");
926    my $rows = $result->all;
927    is_deeply($rows, [{$key1 => 1, $key2 => 12, $key3 => 3, $key4 => 4, $key5 => 5},
928      {$key1 => 6, $key2 => 7,  $key3 => 8, $key4 => 9, $key5 => 10}],
929      "update key same as search key");
930  }
931
932  {
933    $dbi->update({$key2 => [12]}, table => $table1, where => {$key2 => 2, $key3 => 3});
934    my $result = $dbi->execute("select * from $table1 order by $key1");
935    my $rows = $result->all;
936    is_deeply($rows, [{$key1 => 1, $key2 => 12, $key3 => 3, $key4 => 4, $key5 => 5},
937      {$key1 => 6, $key2 => 7,  $key3 => 8, $key4 => 9, $key5 => 10}],
938      "update key same as search key : param is array ref");
939  }
940  $dbi->execute("delete from $table1");
941  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}, table => $table1);
942  $dbi->insert({$key1 => 6, $key2 => 7, $key3 => 8, $key4 => 9, $key5 => 10}, table => $table1);
943  $dbi->register_filter(twice => sub { $_[0] * 2 });
944  $dbi->update({$key2 => 11}, table => $table1, where => {$key1 => 1},
945              filter => {$key2 => sub { $_[0] * 2 }});
946
947  {
948    my $result = $dbi->execute("select * from $table1 order by $key1");
949    my $rows = $result->all;
950    is_deeply($rows, [{$key1 => 1, $key2 => 22, $key3 => 3, $key4 => 4, $key5 => 5},
951      {$key1 => 6, $key2 => 7,  $key3 => 8, $key4 => 9, $key5 => 10}],
952      "filter");
953  }
954
955  {
956    my $result = $dbi->update({$key2 => 11}, table => $table1, where => {$key1 => 1}, append => '   ');
957
958    eval{$dbi->update(table => $table1)};
959    like($@, qr/where/, "not contain where");
960  }
961  {
962    eval { $dbi->execute("drop table $table1") };
963    $dbi->execute($create_table1);
964    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
965    my $where = $dbi->where;
966    $where->clause(['and', "$key1 = :$key1", "$key2 = :$key2"]);
967    $where->param({$key1 => 1, $key2 => 2});
968    $dbi->update({$key1 => 3}, table => $table1, where => $where);
969    my $result = $dbi->select(table => $table1);
970    is_deeply($result->all, [{$key1 => 3, $key2 => 2}], 'update() where');
971  }
972
973  {
974    eval { $dbi->execute("drop table $table1") };
975    $dbi->execute($create_table1);
976    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
977    $dbi->update(
978      {$key1 => 3},
979      table => $table1,
980      where => [
981        ['and', "$key1 = :$key1", "$key2 = :$key2"],
982        {$key1 => 1, $key2 => 2}
983      ]
984    );
985    my $result = $dbi->select(table => $table1);
986    is_deeply($result->all, [{$key1 => 3, $key2 => 2}], 'update() where');
987  }
988
989  {
990    eval { $dbi->execute("drop table $table1") };
991    $dbi->execute($create_table1);
992    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
993    my $where = $dbi->where;
994    $where->clause(['and', "$key2 = :$key2"]);
995    $where->param({$key2 => 2});
996    $dbi->update({$key1 => 3}, table => $table1, where => $where);
997    my $result = $dbi->select(table => $table1);
998    is_deeply($result->all, [{$key1 => 3, $key2 => 2}], 'update() where');
999  }
1000
1001  {
1002    eval { $dbi->execute("drop table $table1") };
1003    $dbi->execute($create_table1_2);
1004    $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}, table => $table1);
1005    $dbi->insert({$key1 => 6, $key2 => 7, $key3 => 8, $key4 => 9, $key5 => 10}, table => $table1);
1006    $dbi->update({$key2 => 11}, table => $table1, where => {$key1 => 1});
1007    my $result = $dbi->execute("select * from $table1 order by $key1");
1008    my $rows = $result->all;
1009    is_deeply($rows, [{$key1 => 1, $key2 => 11, $key3 => 3, $key4 => 4, $key5 => 5},
1010      {$key1 => 6, $key2 => 7,  $key3 => 8, $key4 => 9, $key5 => 10}],
1011      "basic");
1012  }
1013
1014  {
1015    eval { $dbi->execute("drop table $table1") };
1016    $dbi->execute($create_table1_2);
1017    $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}, table => $table1);
1018    $dbi->insert({$key1 => 6, $key2 => 7, $key3 => 8, $key4 => 9, $key5 => 10}, table => $table1);
1019    $dbi->update({$key2 => 11}, table => $table1, where => {$key1 => 1},
1020    wrap => {$key2 => sub { "$_[0] - 1" }});
1021    my $result = $dbi->execute("select * from $table1 order by $key1");
1022    my $rows = $result->all;
1023    is_deeply($rows, [{$key1 => 1, $key2 => 10, $key3 => 3, $key4 => 4, $key5 => 5},
1024      {$key1 => 6, $key2 => 7,  $key3 => 8, $key4 => 9, $key5 => 10}],
1025      "basic");
1026  }
1027
1028  {
1029    eval { $dbi->execute("drop table $table1") };
1030    $dbi->execute($create_table1_2);
1031    $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}, table => $table1);
1032    $dbi->insert({$key1 => 6, $key2 => 7, $key3 => 8, $key4 => 9, $key5 => 10}, table => $table1);
1033    $dbi->update({$key2 => \"'11'"}, table => $table1, where => {$key1 => 1});
1034    my $result = $dbi->execute("select * from $table1 order by $key1");
1035    my $rows = $result->all;
1036    is_deeply($rows, [{$key1 => 1, $key2 => 11, $key3 => 3, $key4 => 4, $key5 => 5},
1037      {$key1 => 6, $key2 => 7,  $key3 => 8, $key4 => 9, $key5 => 10}],
1038      "basic");
1039  }
1040}
1041
1042{
1043  my $dbi = DBIx::Custom->connect;
1044
1045  eval { $dbi->execute("drop table $table1") };
1046  $dbi->execute($create_table1_2);
1047  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}, table => $table1);
1048  $dbi->insert({$key1 => 6, $key2 => 7, $key3 => 8, $key4 => 9, $key5 => 10}, table => $table1);
1049  my $param = {$key2 => 11};
1050  $dbi->update($param, table => $table1, where => {$key1 => 1});
1051  is_deeply($param, {$key2 => 11});
1052  my $result = $dbi->execute("select * from $table1 order by $key1");
1053  my $rows = $result->all;
1054  is_deeply($rows, [{$key1 => 1, $key2 => 11, $key3 => 3, $key4 => 4, $key5 => 5},
1055    {$key1 => 6, $key2 => 7,  $key3 => 8, $key4 => 9, $key5 => 10}],
1056    "basic");
1057}
1058
1059{
1060  my $dbi = DBIx::Custom->connect;
1061
1062  eval { $dbi->execute("drop table $table1") };
1063  $dbi->execute($create_table1_2);
1064  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}, table => $table1);
1065  $dbi->insert({$key1 => 6, $key2 => 7, $key3 => 8, $key4 => 9, $key5 => 10}, table => $table1);
1066  my $param = {$key2 => 11};
1067  $dbi->update($param, table => $table1, where => {$key2 => 2});
1068  is_deeply($param, {$key2 => 11});
1069  my $result = $dbi->execute("select * from $table1 order by $key1");
1070  my $rows = $result->all;
1071  is_deeply($rows, [{$key1 => 1, $key2 => 11, $key3 => 3, $key4 => 4, $key5 => 5},
1072    {$key1 => 6, $key2 => 7,  $key3 => 8, $key4 => 9, $key5 => 10}],
1073    "basic");
1074}
1075
1076{
1077  my $dbi = DBIx::Custom->connect;
1078
1079  eval { $dbi->execute("drop table $table1") };
1080  $dbi->execute($create_table1_2);
1081  my $param = {$key3 => 4};
1082  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3}, table => $table1);
1083  $dbi->update($param, table => $table1, mtime => $key2, where => {$key1 => 1});
1084  my $result = $dbi->select(table => $table1);
1085  is_deeply($param, {$key3 => 4});
1086  my $row   = $result->one;
1087  is($row->{$key3}, 4);
1088  like($row->{$key2}, qr/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/);
1089}
1090
1091{
1092  my $dbi = DBIx::Custom->connect;
1093
1094  eval { $dbi->execute("drop table $table1") };
1095  $dbi->execute($create_table1_2);
1096  my $param = {$key3 => 4};
1097  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3}, table => $table1);
1098  $dbi->update($param, table => $table1, mtime => $key2, where => {$key3 => 3});
1099  my $result = $dbi->select(table => $table1);
1100  is_deeply($param, {$key3 => 4});
1101  my $row   = $result->one;
1102  is($row->{$key3}, 4);
1103  like($row->{$key2}, qr/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/);
1104}
1105
1106{
1107  my $dbi = DBIx::Custom->connect;
1108
1109  eval { $dbi->execute("drop table $table1") };
1110  $dbi->execute($create_table1_2);
1111  my $model = $dbi->create_model(table => $table1, mtime => $key2);
1112  my $param = {$key3 => 4};
1113  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3}, table => $table1);
1114  $model->update($param, where => {$key1 => 1});
1115  my $result = $dbi->select(table => $table1);
1116  is_deeply($param, {$key3 => 4});
1117  my $row   = $result->one;
1118  is($row->{$key3}, 4);
1119  like($row->{$key2}, qr/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/);
1120}
1121
1122# update_all
1123{
1124  my $dbi = DBIx::Custom->connect;
1125
1126  eval { $dbi->execute("drop table $table1") };
1127  $dbi->execute($create_table1_2);
1128  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}, table => $table1);
1129  $dbi->insert({$key1 => 6, $key2 => 7, $key3 => 8, $key4 => 9, $key5 => 10}, table => $table1);
1130  $dbi->register_filter(twice => sub { $_[0] * 2 });
1131  $dbi->update_all({$key2 => 10}, table => $table1, filter => {$key2 => 'twice'});
1132  my $result = $dbi->execute("select * from $table1");
1133  my $rows = $result->all;
1134  is_deeply($rows, [{$key1 => 1, $key2 => 20, $key3 => 3, $key4 => 4, $key5 => 5},
1135    {$key1 => 6, $key2 => 20, $key3 => 8, $key4 => 9, $key5 => 10}],
1136    "filter");
1137}
1138
1139# delete
1140{
1141  my $dbi = DBIx::Custom->connect;
1142
1143  {
1144    eval { $dbi->execute("drop table $table1") };
1145    $dbi->execute($create_table1);
1146    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1147    $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
1148    $dbi->delete(table => $table1, where => {$key1 => 1});
1149    my $result = $dbi->execute("select * from $table1");
1150    my $rows = $result->all;
1151    is_deeply($rows, [{$key1 => 3, $key2 => 4}], "basic");
1152  }
1153
1154  {
1155    $dbi->execute("delete from $table1");
1156    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1157    $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
1158    $dbi->register_filter(twice => sub { $_[0] * 2 });
1159    $dbi->delete(table => $table1, where => {$key2 => 1}, filter => {$key2 => 'twice'});
1160    my $result = $dbi->execute("select * from $table1");
1161    my $rows   = $result->all;
1162    is_deeply($rows, [{$key1 => 3, $key2 => 4}], "filter");
1163  }
1164
1165  $dbi->delete(table => $table1, where => {$key1 => 1}, append => '   ');
1166
1167  $dbi->delete_all(table => $table1);
1168  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1169  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
1170  $dbi->delete(table => $table1, where => {$key1 => 1, $key2 => 2});
1171  my $rows = $dbi->select(table => $table1)->all;
1172  is_deeply($rows, [{$key1 => 3, $key2 => 4}], "delete multi key");
1173
1174  {
1175    eval { $dbi->execute("drop table $table1") };
1176    $dbi->execute($create_table1);
1177    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1178    $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
1179    my $where = $dbi->where;
1180    $where->clause(['and', "$key1 = :$key1", "$key2 = :$key2"]);
1181    $where->param({ke1 => 1, $key2 => 2});
1182    $dbi->delete(table => $table1, where => $where);
1183    my $result = $dbi->select(table => $table1);
1184    is_deeply($result->all, [{$key1 => 3, $key2 => 4}], 'delete() where');
1185  }
1186
1187  {
1188    eval { $dbi->execute("drop table $table1") };
1189    $dbi->execute($create_table1);
1190    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1191    $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
1192    $dbi->delete(
1193      table => $table1,
1194      where => [
1195        ['and', "$key1 = :$key1", "$key2 = :$key2"],
1196        {ke1 => 1, $key2 => 2}
1197      ]
1198    );
1199    my $result = $dbi->select(table => $table1);
1200    is_deeply($result->all, [{$key1 => 3, $key2 => 4}], 'delete() where');
1201  }
1202
1203  {
1204    eval { $dbi->execute("drop table $table1") };
1205    $dbi->execute($create_table1);
1206    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1207    $dbi->delete(table => $table1, where => {$key1 => 1}, prefix => '    ');
1208    my $result = $dbi->execute("select * from $table1");
1209    $rows   = $result->all;
1210    is_deeply($rows, [], "basic");
1211  }
1212}
1213
1214# delete error
1215{
1216  my $dbi = DBIx::Custom->connect;
1217
1218  eval { $dbi->execute("drop table $table1") };
1219  $dbi->execute($create_table1);
1220  eval{$dbi->delete(table => $table1)};
1221  like($@, qr/where/, "where key-value pairs not specified");
1222}
1223
1224# delete_all
1225{
1226  my $dbi = DBIx::Custom->connect;
1227
1228  eval { $dbi->execute("drop table $table1") };
1229  $dbi->execute($create_table1);
1230  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1231  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
1232  $dbi->delete_all(table => $table1);
1233  my $result = $dbi->execute("select * from $table1");
1234  my $rows   = $result->all;
1235  is_deeply($rows, [], "basic");
1236}
1237
1238# select
1239{
1240  my $dbi = DBIx::Custom->connect;
1241
1242  eval { $dbi->execute("drop table $table1") };
1243  $dbi->execute($create_table1);
1244  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1245  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
1246
1247  {
1248    my $rows = $dbi->select(table => $table1)->all;
1249    is_deeply($rows, [{$key1 => 1, $key2 => 2},
1250      {$key1 => 3, $key2 => 4}], "table");
1251  }
1252
1253  {
1254    my $rows = $dbi->select(table => $table1, column => [$key1])->all;
1255    is_deeply($rows, [{$key1 => 1}, {$key1 => 3}], "table and columns and where key");
1256  }
1257
1258  {
1259    my $rows = $dbi->select(table => $table1, where => {$key1 => 1})->all;
1260    is_deeply($rows, [{$key1 => 1, $key2 => 2}], "table and columns and where key");
1261  }
1262
1263  {
1264    my $rows = $dbi->select(table => $table1, column => [$key1], where => {$key1 => 3})->all;
1265    is_deeply($rows, [{$key1 => 3}], "table and columns and where key");
1266  }
1267
1268  {
1269    $dbi->register_filter(decrement => sub { $_[0] - 1 });
1270    my $rows = $dbi->select(table => $table1, where => {$key1 => 2}, filter => {$key1 => 'decrement'})
1271              ->all;
1272    is_deeply($rows, [{$key1 => 1, $key2 => 2}], "filter");
1273  }
1274
1275  {
1276    eval { $dbi->execute("drop table $table1") };
1277    $dbi->execute($create_table1);
1278    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1279    my $row = $dbi->select($key1, table => $table1)->one;
1280    is_deeply($row, {$key1 => 1});
1281  }
1282
1283  eval { $dbi->execute("drop table $table1") };
1284  $dbi->execute($create_table1);
1285  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1286  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
1287  $dbi->insert({$key1 => 5, $key2 => 6}, table => $table1);
1288
1289  {
1290    my $rows = $dbi->select(table => $table1, where => {$key1 => [1, 5]})->all;
1291    is_deeply($rows, [
1292      {$key1 => 1, $key2 => 2},
1293      {$key1 => 5, $key2 => 6}
1294    ], "table");
1295  }
1296
1297  {
1298    my $rows = $dbi->select(table => $table1, where => {$key1 => []})->all;
1299    is_deeply($rows, [], "table");
1300  }
1301
1302  # fetch filter
1303  {
1304    eval { $dbi->execute("drop table $table1") };
1305    $dbi->register_filter(
1306      three_times => sub { $_[0] * 3 }
1307    );
1308    $dbi->execute($create_table1);
1309    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1310    my $result = $dbi->select(table => $table1);
1311    $result->filter({$key1 => 'three_times'});
1312    my $row = $result->one;
1313    is_deeply($row, {$key1 => 3, $key2 => 2});
1314  }
1315
1316  {
1317    eval { $dbi->execute("drop table $table1") };
1318    $dbi->execute($create_table1);
1319    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1320    my $result = $dbi->select(column => [$key1, $key1, $key2], table => $table1);
1321    $result->filter({$key1 => 'three_times'});
1322    my $row = $result->fetch_one;
1323    is_deeply($row, [3, 3, 2]);
1324  }
1325}
1326
1327# filters
1328{
1329  my $dbi = DBIx::Custom->new;
1330
1331  is($dbi->filters->{decode_utf8}->(encode_utf8('あ')),
1332    'あ', "decode_utf8");
1333
1334  is($dbi->filters->{encode_utf8}->('あ'),
1335    encode_utf8('あ'), "encode_utf8");
1336}
1337
1338# transaction1
1339{
1340  {
1341    my $dbi = DBIx::Custom->connect;
1342    eval { $dbi->execute("drop table $table1") };
1343    $dbi->execute($create_table1);
1344    $dbi->begin_work;
1345    $dbi->dbh->{AutoCommit} = 0;
1346    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1347    $dbi->rollback;
1348    $dbi->dbh->{AutoCommit} = 1;
1349
1350    my $result = $dbi->select(table => $table1);
1351    ok(! $result->fetch_one, "rollback");
1352  }
1353
1354  {
1355    my $dbi = DBIx::Custom->connect;
1356    eval { $dbi->execute("drop table $table1") };
1357    $dbi->execute($create_table1);
1358    $dbi->begin_work;
1359    $dbi->dbh->{AutoCommit} = 0;
1360    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1361    $dbi->insert({$key1 => 2, $key2 => 3}, table => $table1);
1362    $dbi->commit;
1363    $dbi->dbh->{AutoCommit} = 1;
1364    my $result = $dbi->select(table => $table1);
1365    is_deeply(scalar $result->all, [{$key1 => 1, $key2 => 2}, {$key1 => 2, $key2 => 3}],
1366      "commit");
1367  }
1368}
1369
1370# execute
1371{
1372  my $dbi = DBIx::Custom->connect;
1373
1374  eval { $dbi->execute("drop table $table1") };
1375  $dbi->execute($create_table1);
1376  {
1377    local $Carp::Verbose = 0;
1378    eval{$dbi->execute("select * frm $table1")};
1379    like($@, qr/\Qselect * frm $table1/, "fail prepare");
1380    like($@, qr/\.t /, "fail : not verbose");
1381  }
1382  {
1383    local $Carp::Verbose = 1;
1384    eval{$dbi->execute("select * frm $table1")};
1385    like($@, qr/Custom.*\.t /s, "fail : verbose");
1386  }
1387}
1388
1389# transaction2
1390{
1391  my $dbi = DBIx::Custom->connect;
1392  eval { $dbi->execute("drop table $table1") };
1393  $dbi->execute($create_table1);
1394
1395  $dbi->begin_work;
1396
1397  eval {
1398    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1399    die "Error";
1400    $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
1401  };
1402
1403  $dbi->rollback if $@;
1404
1405  {
1406    my $result = $dbi->select(table => $table1);
1407    my $rows = $result->all;
1408    is_deeply($rows, [], "rollback");
1409  }
1410
1411  $dbi->begin_work;
1412
1413  eval {
1414    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1415    $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
1416  };
1417
1418  $dbi->commit unless $@;
1419
1420  {
1421    my $result = $dbi->select(table => $table1);
1422    my $rows = $result->all;
1423    is_deeply($rows, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}], "commit");
1424  }
1425
1426  $dbi->dbh->{AutoCommit} = 0;
1427  eval{ $dbi->begin_work };
1428  ok($@, "exception");
1429  $dbi->dbh->{AutoCommit} = 1;
1430}
1431
1432# execute
1433{
1434  my $dbi = DBIx::Custom->connect;
1435
1436  eval { $dbi->execute("drop table $table1") };
1437  $dbi->execute($create_table1);
1438  {
1439    local $Carp::Verbose = 0;
1440    eval{$dbi->execute("select * frm $table1")};
1441    like($@, qr/\Qselect * frm $table1/, "fail prepare");
1442    like($@, qr/\.t /, "fail : not verbose");
1443  }
1444  {
1445    local $Carp::Verbose = 1;
1446    eval{$dbi->execute("select * frm $table1")};
1447    like($@, qr/Custom.*\.t /s, "fail : verbose");
1448  }
1449}
1450
1451# helper
1452{
1453  my $dbi = DBIx::Custom->connect;
1454
1455  $dbi->helper(
1456    one => sub { 1 }
1457  );
1458  $dbi->helper(
1459    two => sub { 2 }
1460  );
1461  $dbi->helper({
1462    twice => sub {
1463      my $self = shift;
1464      return $_[0] * 2;
1465    }
1466  });
1467
1468  is($dbi->one, 1, "first");
1469  is($dbi->two, 2, "second");
1470  is($dbi->twice(5), 10 , "second");
1471
1472  eval {$dbi->XXXXXX};
1473  ok($@, "not exists");
1474}
1475
1476# connect super
1477{
1478  {
1479    my $dbi = DBIx::Custom->connect;
1480    eval { $dbi->execute("drop table $table1") };
1481    $dbi->execute($create_table1);
1482    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1483    is($dbi->select(table => $table1)->one->{$key1}, 1);
1484  }
1485
1486  {
1487    my $dbi = DBIx::Custom->new;
1488    $dbi->connect;
1489    eval { $dbi->execute("drop table $table1") };
1490    $dbi->execute($create_table1);
1491    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1492    is($dbi->select(table => $table1)->one->{$key1}, 1);
1493  }
1494
1495  {
1496    my $dbi = DBIx::Custom->connect;
1497    eval { $dbi->execute("drop table $table1") };
1498    $dbi->execute($create_table1);
1499    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1500    is($dbi->select(table => $table1)->one->{$key1}, 1);
1501  }
1502}
1503
1504# empty where select
1505{
1506  my $dbi = DBIx::Custom->connect;
1507  eval { $dbi->execute("drop table $table1") };
1508  $dbi->execute($create_table1);
1509  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1510  my $result = $dbi->select(table => $table1, where => {});
1511  my $row = $result->one;
1512  is_deeply($row, {$key1 => 1, $key2 => 2});
1513}
1514
1515# where
1516{
1517  {
1518    my $dbi = DBIx::Custom->connect;
1519    eval { $dbi->execute("drop table $table1") };
1520    $dbi->execute($create_table1);
1521    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1522    $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
1523    {
1524      my $where = $dbi->where->clause(['and', "$key1 = :$key1", "$key2 = :$key2"]);
1525      is("$where", "where ( $key1 = :$key1 and $key2 = :$key2 )", 'no param');
1526    }
1527
1528    {
1529      my $where = $dbi->where
1530        ->clause(['and', "$key1 = :$key1", "$key2 = :$key2"])
1531        ->param({$key1 => 1});
1532
1533      my $result = $dbi->select(
1534        table => $table1,
1535        where => $where
1536      );
1537      my $row = $result->all;
1538      is_deeply($row, [{$key1 => 1, $key2 => 2}]);
1539    }
1540
1541    {
1542      my $result = $dbi->select(
1543        table => $table1,
1544        where => [
1545          ['and', "$key1 = :$key1", "$key2 = :$key2"],
1546          {$key1 => 1}
1547        ]
1548      );
1549      my $row = $result->all;
1550      is_deeply($row, [{$key1 => 1, $key2 => 2}]);
1551    }
1552
1553    {
1554      my $where = $dbi->where
1555        ->clause(['and', "$key1 = :$key1", "$key2 = :$key2"])
1556        ->param({$key1 => 1, $key2 => 2});
1557      my $result = $dbi->select(
1558        table => $table1,
1559        where => $where
1560      );
1561      my $row = $result->all;
1562      is_deeply($row, [{$key1 => 1, $key2 => 2}]);
1563    }
1564
1565    {
1566      my $where = $dbi->where
1567        ->clause(['and', "$key1 = :$key1", "$key2 = :$key2"])
1568        ->param({});
1569      my $result = $dbi->select(
1570        table => $table1,
1571        where => $where,
1572      );
1573      my $row = $result->all;
1574      is_deeply($row, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}]);
1575    }
1576
1577    {
1578      my $where = $dbi->where
1579        ->clause(['and', ['or', "$key1 > :$key1", "$key1 < :$key1"], "$key2 = :$key2"])
1580        ->param({$key1 => [0, 3], $key2 => 2});
1581      my $result = $dbi->select(
1582        table => $table1,
1583        where => $where,
1584      );
1585      my $row = $result->all;
1586      is_deeply($row, [{$key1 => 1, $key2 => 2}]);
1587    }
1588
1589    {
1590      my $where = $dbi->where;
1591      my $result = $dbi->select(
1592        table => $table1,
1593        where => $where
1594      );
1595      my $row = $result->all;
1596      is_deeply($row, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}]);
1597    }
1598
1599    eval {
1600      my $where = $dbi->where
1601                 ->clause(['uuu']);
1602      my $result = $dbi->select(
1603        table => $table1,
1604        where => $where
1605      );
1606    };
1607    ok($@);
1608
1609    {
1610      my $where = $dbi->where;
1611      is("$where", '');
1612    }
1613
1614    {
1615      my $where = $dbi->where
1616        ->clause(['or', ("$key1 = :$key1") x 2])
1617        ->param({$key1 => [1, 3]});
1618      my $result = $dbi->select(
1619        table => $table1,
1620        where => $where,
1621      );
1622      my $row = $result->all;
1623      is_deeply($row, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}]);
1624    }
1625
1626    {
1627      my $where = $dbi->where
1628         ->clause(['or', ("$key1 = :$key1") x 2])
1629         ->param({$key1 => [1]});
1630      my $result = $dbi->select(
1631        table => $table1,
1632        where => $where,
1633      );
1634      my $row = $result->all;
1635      is_deeply($row, [{$key1 => 1, $key2 => 2}]);
1636    }
1637
1638    {
1639      my $where = $dbi->where
1640        ->clause(['or', ("$key1 = :$key1") x 2])
1641        ->param({$key1 => 1});
1642      my $result = $dbi->select(
1643        table => $table1,
1644        where => $where,
1645      );
1646      my $row = $result->all;
1647      is_deeply($row, [{$key1 => 1, $key2 => 2}]);
1648    }
1649
1650    {
1651      my $where = $dbi->where
1652        ->clause("$key1 = :$key1")
1653        ->param({$key1 => 1});
1654      my $result = $dbi->select(
1655        table => $table1,
1656        where => $where,
1657      );
1658      my $row = $result->all;
1659      is_deeply($row, [{$key1 => 1, $key2 => 2}]);
1660    }
1661
1662    {
1663      my $where = $dbi->where
1664        ->clause(['or', ("$key1 = :$key1") x 3])
1665        ->param({$key1 => [$dbi->not_exists, 1, 3]});
1666      my $result = $dbi->select(
1667        table => $table1,
1668        where => $where,
1669      );
1670      my $row = $result->all;
1671      is_deeply($row, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}], 'not_exists');
1672    }
1673
1674    {
1675      my $where = $dbi->where
1676        ->clause(['or', ("$key1 = :$key1") x 3])
1677        ->param({$key1 => [1, $dbi->not_exists, 3]});
1678      my $result = $dbi->select(
1679        table => $table1,
1680        where => $where,
1681      );
1682      my $row = $result->all;
1683      is_deeply($row, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}], 'not_exists');
1684    }
1685
1686    {
1687      my $where = $dbi->where
1688        ->clause(['or', ("$key1 = :$key1") x 3])
1689        ->param({$key1 => [1, 3, $dbi->not_exists]});
1690      my $result = $dbi->select(
1691        table => $table1,
1692        where => $where,
1693      );
1694      my $row = $result->all;
1695      is_deeply($row, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}], 'not_exists');
1696    }
1697
1698    {
1699      my $where = $dbi->where
1700        ->clause(['or', ("$key1 = :$key1") x 3])
1701        ->param({$key1 => [1, $dbi->not_exists, $dbi->not_exists]});
1702      my $result = $dbi->select(
1703        table => $table1,
1704        where => $where,
1705      );
1706      my $row = $result->all;
1707      is_deeply($row, [{$key1 => 1, $key2 => 2}], 'not_exists');
1708    }
1709
1710    {
1711      my $where = $dbi->where
1712        ->clause(['or', ("$key1 = :$key1") x 3])
1713        ->param({$key1 => [$dbi->not_exists, 1, $dbi->not_exists]});
1714      my $result = $dbi->select(
1715        table => $table1,
1716        where => $where,
1717      );
1718      my $row = $result->all;
1719      is_deeply($row, [{$key1 => 1, $key2 => 2}], 'not_exists');
1720    }
1721
1722    {
1723      my $where = $dbi->where
1724        ->clause(['or', ("$key1 = :$key1") x 3])
1725        ->param({$key1 => [$dbi->not_exists, $dbi->not_exists, 1]});
1726      my $result = $dbi->select(
1727        table => $table1,
1728        where => $where,
1729      );
1730      my $row = $result->all;
1731      is_deeply($row, [{$key1 => 1, $key2 => 2}], 'not_exists');
1732    }
1733
1734    {
1735      my $where = $dbi->where
1736        ->clause(['or', ("$key1 = :$key1") x 3])
1737        ->param({$key1 => [$dbi->not_exists, $dbi->not_exists, $dbi->not_exists]});
1738      my $result = $dbi->select(
1739        table => $table1,
1740        where => $where,
1741      );
1742      my $row = $result->all;
1743      is_deeply($row, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}], 'not_exists');
1744    }
1745
1746    {
1747      my $where = $dbi->where
1748        ->clause(['or', ("$key1 = :$key1") x 3])
1749        ->param({$key1 => []});
1750      my $result = $dbi->select(
1751        table => $table1,
1752        where => $where,
1753      );
1754      my $row = $result->all;
1755      is_deeply($row, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}], 'not_exists');
1756    }
1757
1758    {
1759      my $where = $dbi->where
1760        ->clause(['and',"$key1 is not null", "$key2 is not null" ]);
1761      my $result = $dbi->select(
1762        table => $table1,
1763        where => $where,
1764      );
1765      my $row = $result->all;
1766      is_deeply($row, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}], 'not_exists');
1767
1768      eval {$dbi->where(ppp => 1) };
1769      like($@, qr/invalid/);
1770    }
1771
1772    {
1773      my $where = $dbi->where(
1774        clause => ['and', ['or'], ['and', "$key1 = :$key1", "$key2 = :$key2"]],
1775        param => {$key1 => 1, $key2 => 2}
1776      );
1777      my $result = $dbi->select(
1778        table => $table1,
1779        where => $where,
1780      );
1781      my $row = $result->all;
1782      is_deeply($row, [{$key1 => 1, $key2 => 2}]);
1783    }
1784
1785    {
1786      my $where = $dbi->where(
1787        clause => ['and', ['or'], ['or', ":$key1", ":$key2"]],
1788        param => {}
1789      );
1790      my $result = $dbi->select(
1791        table => $table1,
1792        where => $where,
1793      );
1794      my $row = $result->all;
1795      is_deeply($row, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}]);
1796    }
1797
1798    {
1799      my $where = $dbi->where;
1800      $where->clause(['and', ":${key1}{=}"]);
1801      $where->param({$key1 => undef});
1802      my $result = $dbi->execute("select * from $table1 $where", {$key1 => 1});
1803      my $row = $result->all;
1804      is_deeply($row, [{$key1 => 1, $key2 => 2}]);
1805    }
1806
1807    {
1808      my $where = $dbi->where;
1809      $where->clause(['or', ":${key1}{=}", ":${key1}{=}"]);
1810      $where->param({$key1 => [undef, undef]});
1811      {
1812        my $result = $dbi->execute("select * from $table1 $where", {$key1 => [1, 0]});
1813        my $row = $result->all;
1814        is_deeply($row, [{$key1 => 1, $key2 => 2}]);
1815      }
1816      {
1817        my $result = $dbi->execute("select * from $table1 $where", {$key1 => [0, 1]});
1818        my $row = $result->all;
1819        is_deeply($row, [{$key1 => 1, $key2 => 2}]);
1820      }
1821    }
1822  }
1823  {
1824    my $dbi = DBIx::Custom->connect;
1825    eval { $dbi->execute("drop table $table1") };
1826    $dbi->execute($create_table1);
1827    $dbi->insert({$key1 => 1, $key2 => '00:00:00'}, table => $table1);
1828    $dbi->insert({$key1 => 1, $key2 => '3'}, table => $table1);
1829    my $where = $dbi->where
1830      ->clause(['and', "$key1 = :$key1", "$key2 = '00:00:00'"])
1831      ->param({$key1 => 1});
1832
1833    my $result = $dbi->select(
1834      table => $table1,
1835      where => $where
1836    );
1837    my $row = $result->all;
1838    is_deeply($row, [{$key1 => 1, $key2 => '00:00:00'}]);
1839  }
1840
1841  # table not specify exception
1842  {
1843    my $dbi = DBIx::Custom->connect;
1844    eval {$dbi->select($key1)};
1845    ok($@);
1846
1847    eval{DBIx::Custom->connect(dsn => undef)};
1848    ok($@);
1849  }
1850
1851  {
1852    my $dbi = DBIx::Custom->connect;
1853    eval { $dbi->execute("drop table $table1") };
1854    $dbi->execute($create_table1);
1855    $dbi->register_filter(twice => sub { $_[0] * 2 });
1856    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1,
1857               filter => {$key1 => 'twice'});
1858    my $row = $dbi->select(table => $table1)->one;
1859    is_deeply($row, {$key1 => 2, $key2 => 2});
1860    eval {$dbi->insert({$key1 => 1, $key2 => 2}, table => $table1,
1861               filter => {$key1 => 'no'}) };
1862    like($@, qr//);
1863  }
1864
1865  {
1866    my $dbi = DBIx::Custom->connect;
1867    eval { $dbi->execute("drop table $table1") };
1868    $dbi->execute($create_table1);
1869    $dbi->register_filter(one => sub { 1 });
1870    my $result = $dbi->select(table => $table1);
1871    eval {$result->filter($key1 => 'no')};
1872    like($@, qr/not registered/);
1873  }
1874}
1875
1876# option
1877{
1878  my $dbi = DBIx::Custom->connect(option => {PrintError => 1});
1879  ok($dbi->dbh->{PrintError});
1880}
1881
1882# DBIx::Custom::Result stash()
1883{
1884  my $result = DBIx::Custom::Result->new;
1885  is_deeply($result->stash, {}, 'default');
1886  $result->stash->{foo} = 1;
1887  is($result->stash->{foo}, 1, 'get and set');
1888}
1889
1890# values_clause
1891{
1892  my $dbi = DBIx::Custom->connect;
1893  eval { $dbi->execute("drop table $table1") };
1894  $dbi->execute($create_table1_2);
1895  my $param = {$key1 => 1, $key2 => 2};
1896  my $values_clause = $dbi->values_clause($param);
1897  my $sql = <<"EOS";
1898insert into $table1 $values_clause
1899EOS
1900  $dbi->execute($sql, $param, table => $table1);
1901  is($dbi->select(table => $table1)->one->{$key1}, 1);
1902  is($dbi->select(table => $table1)->one->{$key2}, 2);
1903}
1904
1905# mycolumn
1906{
1907  my $dbi = DBIx::Custom->connect;
1908  $dbi->user_table_info($user_table_info);
1909  eval { $dbi->execute("drop table $table1") };
1910  eval { $dbi->execute("drop table $table2") };
1911  $dbi->execute($create_table1);
1912  $dbi->execute($create_table2);
1913
1914  $dbi->include_model('MyModel7');
1915
1916  $dbi->setup_model;
1917  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1918  $dbi->insert({$key1 => 1, $key3 => 3}, table => $table2);
1919  my $model = $dbi->model($table1);
1920  {
1921    my $result = $model->select(
1922      column => [
1923        $model->mycolumn,
1924        $model->column($table2)
1925      ]
1926    );
1927    is_deeply($result->one,
1928      {$key1 => 1, $key2 => 2, "$table2.$key1" => 1, "$table2.$key3" => 3});
1929  }
1930
1931  {
1932    my $result = $model->select(
1933      column => [
1934        $model->mycolumn([$key1]),
1935        $model->column($table2 => [$key1])
1936      ]
1937    );
1938    is_deeply($result->one,
1939            {$key1 => 1, "$table2.$key1" => 1});
1940  }
1941
1942  {
1943    my $result = $model->select(
1944      column => [
1945        $model->mycolumn([$key1]),
1946        {$table2 => [$key1]}
1947      ]
1948    );
1949    is_deeply($result->one,
1950            {$key1 => 1, "$table2.$key1" => 1});
1951  }
1952}
1953
1954# merge_param
1955{
1956  my $dbi = DBIx::Custom->new;
1957
1958  {
1959    my $params = [
1960      {$key1 => 1, $key2 => 2, $key3 => 3},
1961      {$key1 => 1, $key2 => 2},
1962    ];
1963    my $param = $dbi->merge_param($params->[0], $params->[1]);
1964    is_deeply($param, {$key1 => [1, 1], $key2 => [2, 2], $key3 => 3});
1965  }
1966
1967  {
1968    my $params = [
1969      {$key1 => [1, 2], $key2 => $dbi->not_exists, $key3 => [1, 2]},
1970      {$key1 => [3, 4], $key2 => [2, 3], $key3 => $dbi->not_exists}
1971    ];
1972    my $param = $dbi->merge_param($params->[0], $params->[1]);
1973    is_deeply($param, {$key1 => [1, 2, 3, 4], $key2 => [$dbi->not_exists, 2, 3], $key3 => [1, 2, $dbi->not_exists]});
1974  }
1975}
1976
1977# select() param option
1978{
1979  my $dbi = DBIx::Custom->connect;
1980  eval { $dbi->execute("drop table $table1") };
1981  $dbi->execute($create_table1);
1982  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
1983  $dbi->insert({$key1 => 2, $key2 => 3}, table => $table1);
1984  eval { $dbi->execute("drop table $table2") };
1985  $dbi->execute($create_table2);
1986  $dbi->insert({$key1 => 1, $key3 => 4}, table => $table2);
1987  $dbi->insert({$key1 => 2, $key3 => 5}, table => $table2);
1988  {
1989    my $rows = $dbi->select(
1990      table => $table1,
1991      column => "$table1.$key1 as " . u("${table1}_$key1") . ", $key2, $key3",
1992      where   => {"$table1.$key2" => 3},
1993      join  => ["inner join (select * from $table2 where :$table2.${key3}{=})" .
1994                " $q$table2$p on $table1.$key1 = $q$table2$p.$key1"],
1995      param => {"$table2.$key3" => 5}
1996    )->all;
1997    is_deeply($rows, [{u"${table1}_$key1" => 2, $key2 => 3, $key3 => 5}]);
1998  }
1999
2000  {
2001    my $rows = $dbi->select(
2002      table => $table1,
2003      column => "$table1.$key1 as " . u("${table1}_$key1") . ", $key2, $key3",
2004      where   => {"$table1.$key2" => 3},
2005      join  => "inner join (select * from $table2 where :$table2.${key3}{=})" .
2006               " $q$table2$p on $table1.$key1 = $q$table2$p.$key1",
2007      param => {"$table2.$key3" => 5}
2008    )->all;
2009    is_deeply($rows, [{u"${table1}_$key1" => 2, $key2 => 3, $key3 => 5}]);
2010  }
2011}
2012
2013# select() string where
2014{
2015  my $dbi = DBIx::Custom->connect;
2016  eval { $dbi->execute("drop table $table1") };
2017  $dbi->execute($create_table1);
2018  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
2019  $dbi->insert({$key1 => 2, $key2 => 3}, table => $table1);
2020  {
2021    my $rows = $dbi->select(
2022      table => $table1,
2023      where => ["$key1 = :$key1 and $key2 = :$key2", {$key1 => 1, $key2 => 2}]
2024    )->all;
2025    is_deeply($rows, [{$key1 => 1, $key2 => 2}]);
2026  }
2027
2028  {
2029    my $dbi = DBIx::Custom->connect;
2030    eval { $dbi->execute("drop table $table1") };
2031    $dbi->execute($create_table1);
2032    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
2033    $dbi->insert({$key1 => 2, $key2 => 3}, table => $table1);
2034    my $rows = $dbi->select(
2035      table => $table1,
2036      where => [
2037        "$key1 = :$key1 and $key2 = :$key2",
2038        {$key1 => 1, $key2 => 2}
2039      ]
2040    )->all;
2041    is_deeply($rows, [{$key1 => 1, $key2 => 2}]);
2042  }
2043
2044  {
2045    my $dbi = DBIx::Custom->connect;
2046    eval { $dbi->execute("drop table $table1") };
2047    $dbi->execute($create_table1);
2048    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
2049    $dbi->insert({$key1 => 2, $key2 => 3}, table => $table1);
2050    my $rows = $dbi->select(
2051      table => $table1,
2052      where => [
2053        "$key1 = :$key1 and $key2 = :$key2",
2054        {$key1 => 1, $key2 => 2}
2055      ]
2056    )->all;
2057    is_deeply($rows, [{$key1 => 1, $key2 => 2}]);
2058  }
2059}
2060
2061# delete() string where
2062{
2063  {
2064    my $dbi = DBIx::Custom->connect;
2065    eval { $dbi->execute("drop table $table1") };
2066    $dbi->execute($create_table1);
2067    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
2068    $dbi->insert({$key1 => 2, $key2 => 3}, table => $table1);
2069    $dbi->delete(
2070      table => $table1,
2071      where => ["$key1 = :$key1 and $key2 = :$key2", {$key1 => 1, $key2 => 2}]
2072    );
2073    my $rows = $dbi->select(table => $table1)->all;
2074    is_deeply($rows, [{$key1 => 2, $key2 => 3}]);
2075  }
2076
2077  {
2078    my $dbi = DBIx::Custom->connect;
2079    eval { $dbi->execute("drop table $table1") };
2080    $dbi->execute($create_table1);
2081    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
2082    $dbi->insert({$key1 => 2, $key2 => 3}, table => $table1);
2083    $dbi->delete(
2084      table => $table1,
2085      where => [
2086        "$key1 = :$key1 and $key2 = :$key2",
2087         {$key1 => 1, $key2 => 2}
2088      ]
2089    );
2090    my $rows = $dbi->select(table => $table1)->all;
2091    is_deeply($rows, [{$key1 => 2, $key2 => 3}]);
2092  }
2093}
2094
2095# update() string where
2096{
2097  {
2098    my $dbi = DBIx::Custom->connect;
2099    eval { $dbi->execute("drop table $table1") };
2100    $dbi->execute($create_table1);
2101    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
2102    $dbi->update(
2103      {$key1 => 5},
2104      table => $table1,
2105      where => ["$key1 = :$key1 and $key2 = :$key2", {$key1 => 1, $key2 => 2}]
2106    );
2107    my $rows = $dbi->select(table => $table1)->all;
2108    is_deeply($rows, [{$key1 => 5, $key2 => 2}]);
2109  }
2110
2111  {
2112    my $dbi = DBIx::Custom->connect;
2113    eval { $dbi->execute("drop table $table1") };
2114    $dbi->execute($create_table1);
2115    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
2116    $dbi->update(
2117      {$key1 => 5},
2118      table => $table1,
2119      where => [
2120        "$key1 = :$key1 and $key2 = :$key2",
2121        {$key1 => 1, $key2 => 2}
2122      ]
2123    );
2124    my $rows = $dbi->select(table => $table1)->all;
2125    is_deeply($rows, [{$key1 => 5, $key2 => 2}]);
2126  }
2127}
2128
2129# insert id and primary_key option
2130{
2131  my $dbi = DBIx::Custom->connect;
2132  eval { $dbi->execute("drop table $table1") };
2133  $dbi->execute($create_table1_2);
2134  $dbi->insert(
2135    {$key3 => 3},
2136    primary_key => [$key1, $key2],
2137    table => $table1,
2138    id => [1, 2],
2139  );
2140  is($dbi->select(table => $table1)->one->{$key1}, 1);
2141  is($dbi->select(table => $table1)->one->{$key2}, 2);
2142  is($dbi->select(table => $table1)->one->{$key3}, 3);
2143
2144  $dbi->insert(
2145    {$key3 => 3},
2146    primary_key => [$key1, $key2],
2147    table => $table1,
2148    id => [1, 2],
2149  );
2150  is($dbi->select(table => $table1)->one->{$key1}, 1);
2151  is($dbi->select(table => $table1)->one->{$key2}, 2);
2152  is($dbi->select(table => $table1)->one->{$key3}, 3);
2153
2154  $dbi->delete_all(table => $table1);
2155  $dbi->insert(
2156    {$key2 => 2, $key3 => 3},
2157    primary_key => $key1,
2158    table => $table1,
2159    id => 0,
2160  );
2161
2162  is($dbi->select(table => $table1)->one->{$key1}, 0);
2163  is($dbi->select(table => $table1)->one->{$key2}, 2);
2164  is($dbi->select(table => $table1)->one->{$key3}, 3);
2165
2166  $dbi = DBIx::Custom->connect;
2167  eval { $dbi->execute("drop table $table1") };
2168  $dbi->execute($create_table1_2);
2169  $dbi->insert(
2170    {$key3 => 3},
2171    primary_key => $key1,
2172    table => $table1,
2173    id => bless({value => 1}, 'AAAA'),
2174    filter => {$key1 => sub { shift->{value} }}
2175  );
2176  is($dbi->select(table => $table1)->one->{$key1}, 1);
2177  is($dbi->select(table => $table1)->one->{$key3}, 3);
2178
2179  $dbi = DBIx::Custom->connect;
2180  eval { $dbi->execute("drop table $table1") };
2181  $dbi->execute($create_table1_2);
2182  $dbi->insert(
2183    {$key3 => 3},
2184    primary_key => [$key1, $key2],
2185    table => $table1,
2186    id => 1,
2187  );
2188  is($dbi->select(table => $table1)->one->{$key1}, 1);
2189  ok(!$dbi->select(table => $table1)->one->{$key2});
2190  is($dbi->select(table => $table1)->one->{$key3}, 3);
2191
2192  $dbi = DBIx::Custom->connect;
2193  eval { $dbi->execute("drop table $table1") };
2194  $dbi->execute($create_table1_2);
2195  $dbi->insert(
2196    {$key3 => 3},
2197    primary_key => [$key1, $key2],
2198    table => $table1,
2199    id => [1, 2],
2200  );
2201  is($dbi->select(table => $table1)->one->{$key1}, 1);
2202  is($dbi->select(table => $table1)->one->{$key2}, 2);
2203  is($dbi->select(table => $table1)->one->{$key3}, 3);
2204}
2205
2206{
2207  my $dbi = DBIx::Custom->connect;
2208  eval { $dbi->execute("drop table $table1") };
2209  $dbi->execute($create_table1_2);
2210  my $param = {$key3 => 3, $key2 => 4};
2211  $dbi->insert(
2212    $param,
2213    primary_key => [$key1, $key2],
2214    table => $table1,
2215    id => [1, 2],
2216  );
2217  is($dbi->select(table => $table1)->one->{$key1}, 1);
2218  is($dbi->select(table => $table1)->one->{$key2}, 4);
2219  is($dbi->select(table => $table1)->one->{$key3}, 3);
2220  is_deeply($param, {$key3 => 3, $key2 => 4});
2221}
2222
2223# model insert id and primary_key option
2224{
2225 {
2226    my $dbi = DBIx::Custom->connect;
2227
2228    eval { $dbi->execute("drop table $table1") };
2229    $dbi->execute($create_table1_2);
2230
2231    $dbi->include_model('MyModel5');
2232
2233    $dbi->model($table1)->insert(
2234      {$key3 => 3},
2235      id => [1, 2],
2236    );
2237    my $result = $dbi->model($table1)->select;
2238    my $row = $result->one;
2239    is($row->{$key1}, 1);
2240    is($row->{$key2}, 2);
2241    is($row->{$key3}, 3);
2242  }
2243
2244  {
2245    my $dbi = DBIx::Custom->connect;
2246    eval { $dbi->execute("drop table $table1") };
2247    $dbi->execute($create_table1_2);
2248    $dbi->include_model('MyModel5');
2249    $dbi->model($table1)->insert(
2250      {$key3 => 3},
2251      id => [1, 2]
2252    );
2253    my $result = $dbi->model($table1)->select;
2254    my $row = $result->one;
2255    is($row->{$key1}, 1);
2256    is($row->{$key2}, 2);
2257    is($row->{$key3}, 3);
2258  }
2259}
2260
2261# update and id option
2262{
2263  {
2264    my $dbi = DBIx::Custom->connect;
2265    eval { $dbi->execute("drop table $table1") };
2266    $dbi->execute($create_table1_2);
2267    $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3}, table => $table1);
2268    $dbi->update(
2269      {$key3 => 4},
2270      table => $table1,
2271      primary_key => [$key1, $key2],
2272      id => [1, 2],
2273    );
2274    is($dbi->select(table => $table1)->one->{$key1}, 1);
2275    is($dbi->select(table => $table1)->one->{$key2}, 2);
2276    is($dbi->select(table => $table1)->one->{$key3}, 4);
2277
2278    $dbi->delete_all(table => $table1);
2279    $dbi->insert({$key1 => 0, $key2 => 2, $key3 => 3}, table => $table1);
2280    $dbi->update(
2281      {$key3 => 4},
2282      table => $table1,
2283      primary_key => $key1,
2284      id => 0,
2285    );
2286    is($dbi->select(table => $table1)->one->{$key1}, 0);
2287    is($dbi->select(table => $table1)->one->{$key2}, 2);
2288    is($dbi->select(table => $table1)->one->{$key3}, 4);
2289  }
2290
2291  {
2292    my $dbi = DBIx::Custom->connect;
2293    eval { $dbi->execute("drop table $table1") };
2294    $dbi->execute($create_table1_2);
2295    $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3}, table => $table1);
2296    $dbi->update(
2297      {$key3 => 4},
2298      table => $table1,
2299      primary_key => [$key1, $key2],
2300      id => [1, 2]
2301    );
2302    is($dbi->select(table => $table1)->one->{$key1}, 1);
2303    is($dbi->select(table => $table1)->one->{$key2}, 2);
2304    is($dbi->select(table => $table1)->one->{$key3}, 4);
2305
2306  }
2307
2308  {
2309    # model update and id option
2310    my $dbi = DBIx::Custom->connect;
2311    eval { $dbi->execute("drop table $table1") };
2312    $dbi->execute($create_table1_2);
2313    $dbi->include_model('MyModel5');
2314    $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3}, table => $table1);
2315    $dbi->model($table1)->update(
2316      {$key3 => 4},
2317      id => [1, 2],
2318    );
2319    my $result = $dbi->model($table1)->select;
2320    my $row = $result->one;
2321    is($row->{$key1}, 1);
2322    is($row->{$key2}, 2);
2323    is($row->{$key3}, 4);
2324  }
2325}
2326
2327# delete and id option
2328{
2329  my $dbi = DBIx::Custom->connect;
2330  eval { $dbi->execute("drop table $table1") };
2331  $dbi->execute($create_table1_2);
2332  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3}, table => $table1);
2333  $dbi->delete(
2334    table => $table1,
2335    primary_key => [$key1, $key2],
2336    id => [1, 2],
2337  );
2338  is_deeply($dbi->select(table => $table1)->all, []);
2339
2340  $dbi->insert({$key1 => 0, $key2 => 2, $key3 => 3}, table => $table1);
2341  $dbi->delete(
2342    table => $table1,
2343    primary_key => $key1,
2344    id => 0,
2345  );
2346  is_deeply($dbi->select(table => $table1)->all, []);
2347}
2348
2349# model delete and id option
2350{
2351  my $dbi = DBIx::Custom->connect;
2352  eval { $dbi->execute("drop table $table1") };
2353  eval { $dbi->execute("drop table $table2") };
2354  eval { $dbi->execute("drop table $table3") };
2355  $dbi->execute($create_table1_2);
2356  $dbi->execute($create_table2_2);
2357  $dbi->execute($create_table3);
2358  $dbi->include_model('MyModel5');
2359  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3}, table => $table1);
2360  $dbi->model($table1)->delete(id => [1, 2]);
2361  is_deeply($dbi->select(table => $table1)->all, []);
2362  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3}, table => $table2);
2363  $dbi->model($table1)->delete(id => [1, 2]);
2364  is_deeply($dbi->select(table => $table1)->all, []);
2365  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3}, table => $table3);
2366  $dbi->model($table3)->delete(id => [1, 2]);
2367  is_deeply($dbi->select(table => $table3)->all, []);
2368}
2369
2370# select and id option
2371{
2372  my $dbi = DBIx::Custom->connect;
2373  {
2374    eval { $dbi->execute("drop table $table1") };
2375    $dbi->execute($create_table1_2);
2376    $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3}, table => $table1);
2377    my $result = $dbi->select(
2378      table => $table1,
2379      primary_key => [$key1, $key2],
2380      id => [1, 2]
2381    );
2382    my $row = $result->one;
2383    is($row->{$key1}, 1);
2384    is($row->{$key2}, 2);
2385    is($row->{$key3}, 3);
2386  }
2387
2388  {
2389    $dbi->delete_all(table => $table1);
2390    $dbi->insert({$key1 => 0, $key2 => 2, $key3 => 3}, table => $table1);
2391    my $result = $dbi->select(
2392      table => $table1,
2393      primary_key => $key1,
2394      id => 0,
2395    );
2396    my $row = $result->one;
2397    is($row->{$key1}, 0);
2398    is($row->{$key2}, 2);
2399    is($row->{$key3}, 3);
2400  }
2401
2402  {
2403    $dbi->delete_all(table => $table1);
2404    $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3}, table => $table1);
2405    my $result = $dbi->select(
2406      table => $table1,
2407      primary_key => [$key1, $key2],
2408      id => [1, 2]
2409    );
2410    my $row = $result->one;
2411    is($row->{$key1}, 1);
2412    is($row->{$key2}, 2);
2413    is($row->{$key3}, 3);
2414  }
2415}
2416# column separator is default
2417{
2418  my $dbi = DBIx::Custom->connect;
2419  $dbi->user_table_info($user_table_info);
2420  eval { $dbi->execute("drop table $table1") };
2421  eval { $dbi->execute("drop table $table2") };
2422  $dbi->execute($create_table1);
2423  $dbi->execute($create_table2);
2424  $dbi->include_model('MyModel6');
2425  $dbi->setup_model;
2426  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
2427  $dbi->insert({$key1 => 1, $key3 => 3}, table => $table2);
2428  my $model = $dbi->model($table1);
2429
2430  {
2431    my $result = $model->select(
2432      column => [$model->column($table2)],
2433      where => {"$table1.$key1" => 1}
2434    );
2435    is_deeply($result->one,
2436            {"$table2.$key1" => 1, "$table2.$key3" => 3});
2437  }
2438
2439  {
2440    my $result = $model->select(
2441      column => [$model->column($table2 => [$key1, $key3])],
2442      where => {"$table1.$key1" => 1}
2443    );
2444    is_deeply($result->one,
2445            {"$table2.$key1" => 1, "$table2.$key3" => 3});
2446  }
2447}
2448
2449# separator
2450{
2451  my $dbi = DBIx::Custom->connect;
2452  $dbi->user_table_info($user_table_info);
2453  eval { $dbi->execute("drop table $table1") };
2454  eval { $dbi->execute("drop table $table2") };
2455  $dbi->execute($create_table1);
2456  $dbi->execute($create_table2);
2457
2458  $dbi->create_model(
2459    table => $table1,
2460    join => [
2461     "left outer join $table2 on $table1.$key1 = $table2.$key1"
2462    ],
2463    primary_key => [$key1],
2464  );
2465  my $model2 = $dbi->create_model(
2466    table => $table2,
2467  );
2468
2469  {
2470    $dbi->setup_model;
2471    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
2472    $dbi->insert({$key1 => 1, $key3 => 3}, table => $table2);
2473    my $model = $dbi->model($table1);
2474    my $result = $model->select(
2475      column => [
2476        $model->mycolumn,
2477        {$table2 => [$key1, $key3]}
2478      ],
2479      where => {"$table1.$key1" => 1}
2480    );
2481    is_deeply($result->one,
2482            {$key1 => 1, $key2 => 2, "$table2.$key1" => 1, "$table2.$key3" => 3});
2483    is_deeply($model2->select->one, {$key1 => 1, $key3 => 3});
2484  }
2485
2486  {
2487    $dbi->separator('__');
2488    my $model = $dbi->model($table1);
2489    my $result = $model->select(
2490      column => [
2491        $model->mycolumn,
2492        {$table2 => [$key1, $key3]}
2493      ],
2494      where => {"$table1.$key1" => 1}
2495    );
2496    is_deeply($result->one,
2497            {$key1 => 1, $key2 => 2, u2"${table2}__$key1" => 1, u2"${table2}__$key3" => 3});
2498    is_deeply($model2->select->one, {$key1 => 1, $key3 => 3});
2499  }
2500
2501  {
2502    $dbi->separator('-');
2503    my $model = $dbi->model($table1);
2504    my $result = $model->select(
2505      column => [
2506        $model->mycolumn,
2507        {$table2 => [$key1, $key3]}
2508      ],
2509      where => {"$table1.$key1" => 1}
2510    );
2511    is_deeply($result->one,
2512      {$key1 => 1, $key2 => 2, hy"$table2-$key1" => 1, hy"$table2-$key3" => 3});
2513    is_deeply($model2->select->one, {$key1 => 1, $key3 => 3});
2514  }
2515}
2516
2517# filter_off
2518{
2519  my $dbi = DBIx::Custom->connect;
2520  $dbi->user_table_info($user_table_info);
2521  eval { $dbi->execute("drop table $table1") };
2522  eval { $dbi->execute("drop table $table2") };
2523  $dbi->execute($create_table1);
2524  $dbi->execute($create_table2);
2525
2526  $dbi->create_model(
2527    table => $table1,
2528    join => [
2529     "left outer join $table2 on $table1.$key1 = $table2.$key1"
2530    ],
2531    primary_key => [$key1],
2532  );
2533  $dbi->setup_model;
2534  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
2535  my $model = $dbi->model($table1);
2536  my $result = $model->select(column => $key1);
2537  $result->filter($key1 => sub { $_[0] * 2 });
2538  is_deeply($result->one, {$key1 => 2});
2539}
2540
2541# available_datetype
2542{
2543  my $dbi = DBIx::Custom->connect;
2544  ok($dbi->can('available_datatype'));
2545}
2546
2547# select prefix option
2548{
2549  my $dbi = DBIx::Custom->connect;
2550  eval { $dbi->execute("drop table $table1") };
2551  $dbi->execute($create_table1);
2552  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
2553  my $rows = $dbi->select(prefix => "$key1,", column => $key2, table => $table1)->all;
2554  is_deeply($rows, [{$key1 => 1, $key2 => 2}], "table");
2555}
2556
2557# mapper
2558{
2559  {
2560    my $dbi = DBIx::Custom->connect;
2561    my $param = $dbi->mapper(param => {id => 1, author => 'Ken', price => 1900})->map(
2562      id => {key => "$table1.id"},
2563      author => ["$table1.author" => sub { '%' . $_[0] . '%' }],
2564      price => {key => "$table1.price", condition => sub { $_[0] eq 1900 }}
2565    );
2566    is_deeply($param, {"$table1.id" => 1, "$table1.author" => '%Ken%',
2567    "$table1.price" => 1900});
2568  }
2569
2570  my $dbi = DBIx::Custom->connect;
2571
2572  {
2573    my $param = $dbi->mapper(param => {id => 1, author => 'Ken', price => 1900})->map(
2574      id => {key => "$table1.id"},
2575      author => ["$table1.author" => $dbi->like_value],
2576      price => {key => "$table1.price", condition => sub { $_[0] eq 1900 }}
2577    );
2578    is_deeply($param, {"$table1.id" => 1, "$table1.author" => '%Ken%',
2579    "$table1.price" => 1900});
2580  }
2581
2582  {
2583    my $param = $dbi->mapper(param => {id => 0, author => 0, price => 0})->map(
2584      id => {key => "$table1.id"},
2585      author => ["$table1.author" => sub { '%' . $_[0] . '%' }],
2586      price => ["$table1.price", sub { '%' . $_[0] . '%' }, sub { $_[0] eq 0 }]
2587    );
2588    is_deeply($param, {"$table1.id" => 0, "$table1.author" => '%0%', "$table1.price" => '%0%'});
2589  }
2590
2591  {
2592    my $param = $dbi->mapper(param => {id => '', author => '', price => ''})->map(
2593      id => {key => "$table1.id"},
2594      author => ["$table1.author" => sub { '%' . $_[0] . '%' }],
2595      price => ["$table1.price", sub { '%' . $_[0] . '%' }, sub { $_[0] eq 1 }]
2596    );
2597    is_deeply($param, {});
2598  }
2599
2600  {
2601    my $param = $dbi->mapper(param => {id => undef, author => undef, price => undef})->map(
2602      id => {key => "$table1.id"},
2603      price => {key => "$table1.price", condition => 'exists'}
2604    );
2605    is_deeply($param, {"$table1.price" => undef});
2606  }
2607
2608  {
2609    my $param = $dbi->mapper(param => {price => 'a'})->map(
2610      id => {key => "$table1.id", condition => 'exists'},
2611      price => ["$table1.price", sub { '%' . $_[0] }, 'exists']
2612    );
2613    is_deeply($param, {"$table1.price" => '%a'});
2614  }
2615
2616  {
2617    my $param = $dbi->mapper(param => {price => 'a'}, condition => 'exists')->map(
2618      id => {key => "$table1.id"},
2619      price => ["$table1.price", sub { '%' . $_[0] }]
2620    );
2621    is_deeply($param, {"$table1.price" => '%a'});
2622  }
2623
2624  {
2625    my $param = $dbi->mapper(param => {price => 'a', author => 'b'})->map(
2626      price => sub { '%' . $_[0] },
2627      author => 'book.author'
2628    );
2629    is_deeply($param, {price => '%a', 'book.author' => 'b'});
2630  }
2631
2632  eval { $dbi->execute("drop table $table1") };
2633  $dbi->execute($create_table1);
2634  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
2635  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
2636
2637  {
2638    my $where = $dbi->where;
2639    $where->clause(['and', ":${key1}{=}"]);
2640    my $param = $dbi->mapper(param => {$key1 => undef}, condition => 'defined')->map;
2641    $where->param($param);
2642    my $result = $dbi->execute("select * from $table1 $where", {$key1 => 1});
2643    my $row = $result->all;
2644    is_deeply($row, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}]);
2645  }
2646
2647  {
2648    my $where = $dbi->where;
2649    $where->clause(['or', ":${key1}{=}", ":${key1}{=}"]);
2650
2651    {
2652      my $param = $dbi->mapper(param => {$key1 => [undef, undef]}, condition => 'exists')->map;
2653      my $result = $dbi->execute("select * from $table1 $where", {$key1 => [1, 0]});
2654      my $row = $result->all;
2655      is_deeply($row, [{$key1 => 1, $key2 => 2}]);
2656    }
2657
2658    {
2659      my $result = $dbi->execute("select * from $table1 $where", {$key1 => [0, 1]});
2660      my $row = $result->all;
2661      is_deeply($row, [{$key1 => 1, $key2 => 2}]);
2662    }
2663  }
2664
2665  {
2666    my $where = $dbi->where;
2667    $where->clause(['and', ":${key1}{=}"]);
2668    my $param = $dbi->mapper(param => {$key1 => [undef, undef]}, condition => 'defined')->map;
2669    $where->param($param);
2670
2671    {
2672      my $result = $dbi->execute("select * from $table1 $where", {$key1 => [1, 0]});
2673      my $row = $result->all;
2674      is_deeply($row, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}]);
2675    }
2676
2677    {
2678      my $result = $dbi->execute("select * from $table1 $where", {$key1 => [0, 1]});
2679      my $row = $result->all;
2680      is_deeply($row, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}]);
2681    }
2682  }
2683
2684  {
2685    my $where = $dbi->where;
2686    $where->clause(['and', ":${key1}{=}"]);
2687    my $param = $dbi->mapper(param => {$key1 => 0}, condition => 'length')
2688    ->pass([$key1, $key2])->map;
2689    $where->param($param);
2690    my $result = $dbi->execute("select * from $table1 $where", {$key1 => 1});
2691    my $row = $result->all;
2692    is_deeply($row, [{$key1 => 1, $key2 => 2}]);
2693  }
2694
2695  {
2696    my $where = $dbi->where;
2697    $where->clause(['and', ":${key1}{=}"]);
2698    my $param = $dbi->mapper(param => {$key1 => ''}, condition => 'length')->map;
2699    $where->param($param);
2700    my $result = $dbi->execute("select * from $table1 $where", {$key1 => 1});
2701    my $row = $result->all;
2702    is_deeply($row, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}]);
2703  }
2704
2705  {
2706    my $where = $dbi->where;
2707    $where->clause(['and', ":${key1}{=}"]);
2708    my $param = $dbi->mapper(param => {$key1 => 5}, condition => sub { ($_[0] || '') eq 5 })
2709    ->pass([$key1, $key2])->map;
2710    $where->param($param);
2711    my $result = $dbi->execute("select * from $table1 $where", {$key1 => 1});
2712    my $row = $result->all;
2713    is_deeply($row, [{$key1 => 1, $key2 => 2}]);
2714  }
2715
2716  {
2717    my $where = $dbi->where;
2718    $where->clause(['and', ":${key1}{=}"]);
2719    my $param = $dbi->mapper(param => {$key1 => 7}, condition => sub { ($_[0] || '') eq 5 })->map;
2720    $where->param($param);
2721    my $result = $dbi->execute("select * from $table1 $where", {$key1 => 1});
2722    my $row = $result->all;
2723    is_deeply($row, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}]);
2724  }
2725
2726  {
2727    my $where = $dbi->where;
2728    my $param = $dbi->mapper(param => {id => 1, author => 'Ken', price => 1900})->map(
2729      id => {key => "$table1.id"},
2730      author => ["$table1.author", sub { '%' . $_[0] . '%' }],
2731      price => {key => "$table1.price", condition => sub { $_[0] eq 1900 }}
2732    );
2733    $where->param($param);
2734    is_deeply($where->param, {"$table1.id" => 1, "$table1.author" => '%Ken%',
2735    "$table1.price" => 1900});
2736  }
2737
2738  {
2739    my $where = $dbi->where;
2740    my $param = $dbi->mapper(param => {id => 0, author => 0, price => 0})->map(
2741      id => {key => "$table1.id"},
2742      author => ["$table1.author", sub { '%' . $_[0] . '%' }],
2743      price => ["$table1.price", sub { '%' . $_[0] . '%' }, sub { $_[0] eq 0 }]
2744    );
2745    $where->param($param);
2746    is_deeply($where->param, {"$table1.id" => 0, "$table1.author" => '%0%', "$table1.price" => '%0%'});
2747  }
2748
2749  {
2750    my $where = $dbi->where;
2751    my $param = $dbi->mapper(param => {id => '', author => '', price => ''})->map(
2752      id => {key => "$table1.id"},
2753      author => ["$table1.author", sub { '%' . $_[0] . '%' }],
2754      price => ["$table1.price", sub { '%' . $_[0] . '%' }, sub { $_[0] eq 1 }]
2755    );
2756    $where->param($param);
2757    is_deeply($where->param, {});
2758  }
2759
2760  {
2761    my $where = $dbi->where;
2762    my $param = $dbi->mapper(param => {id => undef, author => undef, price => undef}, condition => 'exists')->map(
2763      id => {key => "$table1.id"},
2764      price => {key => "$table1.price", condition => 'exists'}
2765    );
2766    is_deeply($param, {"$table1.id"  => undef,"$table1.price" => undef});
2767  }
2768
2769  {
2770    my $where = $dbi->where;
2771    my $param = $dbi->mapper(param => {price => 'a'})->map(
2772      id => {key => "$table1.id", condition => 'exists'},
2773      price => ["$table1.price", sub { '%' . $_[0] }, 'exists']
2774    );
2775    is_deeply($param, {"$table1.price" => '%a'});
2776  }
2777
2778  {
2779    my $where = $dbi->where;
2780    my $param = $dbi->mapper(param => {id => [1, 2], author => 'Ken', price => 1900})->map(
2781      id => {key => "$table1.id"},
2782      author => ["$table1.author", sub { '%' . $_[0] . '%' }],
2783      price => {key => "$table1.price", condition => sub { $_[0] eq 1900 }}
2784    );
2785    is_deeply($param, {"$table1.id" => [1, 2], "$table1.author" => '%Ken%',
2786    "$table1.price" => 1900});
2787  }
2788
2789  {
2790    my $where = $dbi->where;
2791    my $param = $dbi->mapper(param => {id => ['', ''], author => 'Ken', price => 1900}, condition => 'length')->map(
2792      id => {key => "$table1.id"},
2793      author => ["$table1.author", sub { '%' . $_[0] . '%' }],
2794      price => {key => "$table1.price", condition => sub { $_[0] eq 1900 }}
2795    );
2796    is_deeply($param, {"$table1.id" => [$dbi->not_exists, $dbi->not_exists], "$table1.author" => '%Ken%',
2797    "$table1.price" => 1900});
2798  }
2799
2800  {
2801    my $where = $dbi->where;
2802    my $param = $dbi->mapper(param => {id => ['', ''], author => 'Ken', price => 1900})->map(
2803      id => {key => "$table1.id", condition => 'length'},
2804      author => ["$table1.author", sub { '%' . $_[0] . '%' }, 'defined'],
2805      price => {key => "$table1.price", condition => sub { $_[0] eq 1900 }}
2806    );
2807    is_deeply($param, {"$table1.id" => [$dbi->not_exists, $dbi->not_exists], "$table1.author" => '%Ken%',
2808    "$table1.price" => 1900});
2809  }
2810
2811  {
2812    my $where = $dbi->where;
2813    my $param = $dbi->mapper(param => {id => 'a', author => 'b', price => 'c'}, pass => [qw/id author/])
2814      ->map(price => {key => 'book.price'});
2815    is_deeply($param, {id => 'a', author => 'b', 'book.price' => 'c'});
2816  }
2817
2818  {
2819    my $param = $dbi->mapper(param => {author => 'Ken',})->map(
2820      author => ["$table1.author" => '%<value>%'],
2821    );
2822    is_deeply($param, {"$table1.author" => '%Ken%'});
2823  }
2824
2825  {
2826    my $param = $dbi->mapper(param => {author => 'Ken'})->map(
2827      author => ["$table1.author" => 'p'],
2828    );
2829    is_deeply($param, {"$table1.author" => 'p'});
2830  }
2831
2832  {
2833    my $param = $dbi->mapper(param => {author => 'Ken',})->map(
2834      author => {value => '%<value>%'}
2835    );
2836    is_deeply($param, {"author" => '%Ken%'});
2837  }
2838}
2839
2840# order
2841{
2842  my $dbi = DBIx::Custom->connect;
2843  eval { $dbi->execute("drop table $table1") };
2844  $dbi->execute($create_table1);
2845  $dbi->insert({$key1 => 1, $key2 => 1}, table => $table1);
2846  $dbi->insert({$key1 => 1, $key2 => 3}, table => $table1);
2847  $dbi->insert({$key1 => 2, $key2 => 2}, table => $table1);
2848  $dbi->insert({$key1 => 2, $key2 => 4}, table => $table1);
2849  my $order = $dbi->order;
2850
2851  {
2852    $order->prepend($key1, "$key2 desc");
2853    my $result = $dbi->select(table => $table1, append => $order);
2854    is_deeply($result->all, [{$key1 => 1, $key2 => 3}, {$key1 => 1, $key2 => 1},
2855      {$key1 => 2, $key2 => 4}, {$key1 => 2, $key2 => 2}]);
2856  }
2857
2858  {
2859    $order->prepend("$key1 desc");
2860    my $result = $dbi->select(table => $table1, append => $order);
2861    is_deeply($result->all, [{$key1 => 2, $key2 => 4}, {$key1 => 2, $key2 => 2},
2862    {$key1 => 1, $key2 => 3}, {$key1 => 1, $key2 => 1}]);
2863  }
2864}
2865
2866# DBIx::Custom header
2867{
2868  my $dbi = DBIx::Custom->connect;
2869  eval { $dbi->execute("drop table $table1") };
2870  $dbi->execute($create_table1);
2871  my $result = $dbi->execute("select $key1 as h1, $key2 as h2 from $table1");
2872  is_deeply([map { lc } @{$result->header}], [qw/h1 h2/]);
2873  $result->sth->finish;
2874}
2875
2876# Named placeholder :name(operater) syntax
2877{
2878  my $dbi = DBIx::Custom->connect;
2879
2880  eval { $dbi->execute("drop table $table1") };
2881  $dbi->execute($create_table1_2);
2882  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}, table => $table1);
2883  $dbi->insert({$key1 => 6, $key2 => 7, $key3 => 8, $key4 => 9, $key5 => 10}, table => $table1);
2884
2885  {
2886    my $source = "select * from $table1 where :${key1}{=} and :${key2}{=}";
2887    my $result = $dbi->execute($source, {$key1 => 1, $key2 => 2});
2888    my $rows = $result->all;
2889    is_deeply($rows, [{$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}]);
2890  }
2891
2892  {
2893    my $source = "select * from $table1 where :${key1}{ = } and :${key2}{=}";
2894    my $result = $dbi->execute($source, {$key1 => 1, $key2 => 2});
2895    my $rows = $result->all;
2896    is_deeply($rows, [{$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}]);
2897  }
2898
2899  {
2900    my $source = "select * from $table1 where :${key1}{<} and :${key2}{=}";
2901    my $result = $dbi->execute($source, {$key1 => 5, $key2 => 2});
2902    my $rows = $result->all;
2903    is_deeply($rows, [{$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}]);
2904  }
2905
2906  {
2907    my $source = "select * from $table1 where :$table1.${key1}{=} and :$table1.${key2}{=}";
2908    my $result = $dbi->execute(
2909      $source,
2910      {"$table1.$key1" => 1, "$table1.$key2" => 1},
2911      filter => {"$table1.$key2" => sub { $_[0] * 2 }}
2912    );
2913    my $rows = $result->all;
2914    is_deeply($rows, [{$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}]);
2915  }
2916}
2917
2918# result
2919{
2920  my $dbi = DBIx::Custom->connect;
2921  eval { $dbi->execute("drop table $table1") };
2922  $dbi->execute($create_table1);
2923  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
2924  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
2925
2926  {
2927    my $result = $dbi->select(table => $table1);
2928    my @rows = ();
2929    while (my $row = $result->fetch) {
2930      push @rows, [@$row];
2931    }
2932    is_deeply(\@rows, [[1, 2], [3, 4]]);
2933  }
2934
2935  {
2936    my $result = $dbi->select(table => $table1);
2937    my @rows = ();
2938    while (my $row = $result->fetch_hash) {
2939      push @rows, {%$row};
2940    }
2941    is_deeply(\@rows, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}]);
2942  }
2943}
2944
2945# fetch_all
2946{
2947  my $dbi = DBIx::Custom->connect;
2948  eval { $dbi->execute("drop table $table1") };
2949  $dbi->execute($create_table1);
2950  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
2951  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
2952
2953  {
2954    my $result = $dbi->select(table => $table1);
2955    my $rows = $result->fetch_all;
2956    is_deeply($rows, [[1, 2], [3, 4]]);
2957  }
2958
2959  {
2960    my $result = $dbi->select(table => $table1);
2961    my $rows = $result->fetch_hash_all;
2962    is_deeply($rows, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}]);
2963  }
2964
2965  {
2966    my $result = $dbi->select(table => $table1);
2967    $result->dbi->filters({three_times => sub { $_[0] * 3}});
2968    $result->filter({$key1 => 'three_times'});
2969    my $rows = $result->fetch_all;
2970    is_deeply($rows, [[3, 2], [9, 4]], "array");
2971  }
2972
2973  {
2974    my $result = $dbi->select(column => [$key1, $key1, $key2], table => $table1);
2975    $result->dbi->filters({three_times => sub { $_[0] * 3}});
2976    $result->filter({$key1 => 'three_times'});
2977    my $rows = $result->fetch_all;
2978    is_deeply($rows, [[3, 3, 2], [9, 9, 4]], "array");
2979  }
2980
2981  {
2982    my $result = $dbi->select(table => $table1);
2983    $result->dbi->filters({three_times => sub { $_[0] * 3}});
2984    $result->filter({$key1 => 'three_times'});
2985    my $rows = $result->fetch_hash_all;
2986    is_deeply($rows, [{$key1 => 3, $key2 => 2}, {$key1 => 9, $key2 => 4}], "hash");
2987  }
2988
2989  # flat
2990  {
2991    my $result = $dbi->select(table => $table1);
2992    my $rows = [$result->flat];
2993    is_deeply($rows, [1, 2, 3, 4]);
2994  }
2995}
2996
2997# kv
2998{
2999  my $dbi = DBIx::Custom->connect;
3000  {
3001    eval { $dbi->execute("drop table $table1") };
3002    $dbi->execute($create_table1);
3003    $dbi->insert({$key1 => 0, $key2 => 2}, table => $table1);
3004    $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
3005
3006    my $result = $dbi->select([$key1, $key2], table => $table1, append => "order by $key1");
3007    my $rows = $result->kv;
3008    is_deeply($rows, {0 => {$key2 => 2}, 3 => {$key2 => 4}});
3009  }
3010
3011  {
3012    eval { $dbi->execute("drop table $table1") };
3013    $dbi->execute($create_table1);
3014    $dbi->insert({$key1 => 0, $key2 => 1}, table => $table1);
3015    $dbi->insert({$key1 => 0, $key2 => 2}, table => $table1);
3016    $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
3017    $dbi->insert({$key1 => 3, $key2 => 5}, table => $table1);
3018  }
3019
3020  {
3021    my $result = $dbi->select([$key1, $key2], table => $table1, append => "order by $key2");
3022    my $rows = $result->kv(multi => 1);
3023    is_deeply($rows, {
3024      0 => [
3025        {$key2 => 1},
3026        {$key2 => 2}
3027      ],
3028      3 => [
3029        {$key2 => 4},
3030        {$key2 => 5}
3031      ]
3032    });
3033  }
3034
3035  {
3036    my $result = $dbi->select([$key1, $key2], table => $table1, append => "order by $key2");
3037    my $rows = $result->kvs;
3038    is_deeply($rows, {
3039      0 => [
3040        {$key2 => 1},
3041        {$key2 => 2}
3042      ],
3043      3 => [
3044        {$key2 => 4},
3045        {$key2 => 5}
3046      ]
3047    });
3048  }
3049}
3050
3051# DBIx::Custom::Result fetch_multi
3052{
3053  my $dbi = DBIx::Custom->connect;
3054
3055  eval { $dbi->execute("drop table $table1") };
3056  $dbi->execute($create_table1);
3057  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
3058  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
3059  $dbi->insert({$key1 => 5, $key2 => 6}, table => $table1);
3060  my $result = $dbi->select(table => $table1);
3061  {
3062    my $rows = $result->fetch_multi(2);
3063    is_deeply($rows, [[1, 2], [3, 4]]);
3064  }
3065  {
3066    my $rows = $result->fetch_multi(2);
3067    is_deeply($rows, [[5, 6]]);
3068  }
3069  {
3070    my $rows = $result->fetch_multi(2);
3071    ok(!$rows);
3072  }
3073}
3074
3075# DBIx::Custom::Result fetch_hash_multi
3076{
3077  my $dbi = DBIx::Custom->connect;
3078
3079  eval { $dbi->execute("drop table $table1") };
3080  $dbi->execute($create_table1);
3081  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
3082  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
3083  $dbi->insert({$key1 => 5, $key2 => 6}, table => $table1);
3084  my $result = $dbi->select(table => $table1);
3085  {
3086    my $rows = $result->fetch_hash_multi(2);
3087    is_deeply($rows, [{$key1 => 1, $key2 => 2}, {$key1 => 3, $key2 => 4}]);
3088  }
3089
3090  {
3091    my $rows = $result->fetch_hash_multi(2);
3092    is_deeply($rows, [{$key1 => 5, $key2 => 6}]);
3093  }
3094
3095  {
3096    my $rows = $result->fetch_hash_multi(2);
3097    ok(!$rows);
3098  }
3099}
3100
3101# select() after_build_sql option
3102{
3103  my $dbi = DBIx::Custom->connect;
3104  $dbi->user_table_info($user_table_info);
3105  eval { $dbi->execute("drop table $table1") };
3106  $dbi->execute($create_table1);
3107  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
3108  $dbi->insert({$key1 => 2, $key2 => 3}, table => $table1);
3109  my $rows = $dbi->select(
3110    table => $table1,
3111    column => $key1,
3112    after_build_sql => sub {
3113      my $sql = shift;
3114      $sql = "select * from ( $sql ) t where $key1 = 1";
3115      return $sql;
3116    }
3117  )->all;
3118  is_deeply($rows, [{$key1 => 1}]);
3119}
3120
3121# dbi method from model
3122{
3123  my $dbi = DBIx::Custom->connect;
3124  eval { $dbi->execute("drop table $table1") };
3125  $dbi->execute($create_table1);
3126  $dbi->include_model('MyModel8::MyModel1');
3127  $dbi->setup_model;
3128  my $model = $dbi->model($table1);
3129  eval{$model->execute("select * from $table1")};
3130  ok(!$@);
3131}
3132
3133# column table option
3134{
3135  my $dbi = DBIx::Custom->connect;
3136  $dbi->user_table_info($user_table_info);
3137  eval { $dbi->execute("drop table $table1") };
3138  $dbi->execute($create_table1);
3139  eval { $dbi->execute("drop table $table2") };
3140  $dbi->execute($create_table2);
3141  $dbi->include_model('MyModel8::MyModel1');
3142  $dbi->setup_model;
3143  $dbi->execute("insert into $table1 ($key1, $key2) values (1, 2)");
3144  $dbi->execute("insert into $table2 ($key1, $key3) values (1, 4)");
3145  my $model = $dbi->model($table1);
3146
3147  {
3148    my $result = $model->select(
3149      column => [
3150        $model->column($table2, {alias => u$table2_alias})
3151      ],
3152      where => {u($table2_alias) . ".$key3" => 4}
3153    );
3154    is_deeply($result->one,
3155            {u($table2_alias) . ".$key1" => 1, u($table2_alias) . ".$key3" => 4});
3156  }
3157
3158  {
3159    $dbi->separator('__');
3160    my $result = $model->select(
3161      column => [
3162        $model->column($table2, {alias => u$table2_alias})
3163      ],
3164      where => {u($table2_alias) . ".$key3" => 4}
3165    );
3166    is_deeply($result->one,
3167      {u(${table2_alias}) . "__$key1" => 1, u(${table2_alias}) . "__$key3" => 4});
3168  }
3169
3170  {
3171    $dbi->separator('-');
3172    my $result = $model->select(
3173      column => [
3174        $model->column($table2, {alias => u$table2_alias})
3175      ],
3176      where => {u($table2_alias) . ".$key3" => 4}
3177    );
3178    is_deeply($result->one,
3179      {u(${table2_alias}) . "-$key1" => 1, u(${table2_alias}) . "-$key3" => 4});
3180  }
3181
3182  # create_model
3183  $dbi = DBIx::Custom->connect;
3184  $dbi->user_table_info($user_table_info);
3185  eval { $dbi->execute("drop table $table1") };
3186  eval { $dbi->execute("drop table $table2") };
3187  $dbi->execute($create_table1);
3188  $dbi->execute($create_table2);
3189
3190  $dbi->create_model(
3191    table => $table1,
3192    join => [
3193     "left outer join $table2 on $table1.$key1 = $table2.$key1"
3194    ],
3195    primary_key => [$key1]
3196  );
3197}
3198
3199# model helper
3200{
3201  my $dbi = DBIx::Custom->connect;
3202  eval { $dbi->execute("drop table $table2") };
3203  $dbi->execute($create_table2);
3204  $dbi->insert({$key1 => 1, $key3 => 3}, table => $table2);
3205  my $model = $dbi->create_model(
3206    table => $table2
3207  );
3208  $model->helper(foo => sub { shift->select(@_) });
3209  is_deeply($model->foo->one, {$key1 => 1, $key3 => 3});
3210}
3211
3212# assign_clause
3213{
3214  my $dbi = DBIx::Custom->connect;
3215  eval { $dbi->execute("drop table $table1") };
3216  $dbi->execute($create_table1_2);
3217  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}, table => $table1);
3218  $dbi->insert({$key1 => 6, $key2 => 7, $key3 => 8, $key4 => 9, $key5 => 10}, table => $table1);
3219
3220  my $param = {$key2 => 11};
3221  my $assign_clause = $dbi->assign_clause($param);
3222  my $sql = <<"EOS";
3223update $table1 set $assign_clause
3224where $key1 = 1
3225EOS
3226  $dbi->execute($sql, $param);
3227  my $result = $dbi->execute("select * from $table1 order by $key1", table => $table1);
3228  my $rows   = $result->all;
3229  is_deeply($rows, [{$key1 => 1, $key2 => 11, $key3 => 3, $key4 => 4, $key5 => 5},
3230    {$key1 => 6, $key2 => 7,  $key3 => 8, $key4 => 9, $key5 => 10}],
3231    "basic");
3232}
3233
3234{
3235  my $dbi = DBIx::Custom->connect;
3236  eval { $dbi->execute("drop table $table1") };
3237  $dbi->execute($create_table1_2);
3238  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}, table => $table1);
3239  $dbi->insert({$key1 => 6, $key2 => 7, $key3 => 8, $key4 => 9, $key5 => 10}, table => $table1);
3240
3241  my $param = {$key2 => 11, $key3 => 33};
3242  my $assign_clause = $dbi->assign_clause($param);
3243  my $sql = <<"EOS";
3244update $table1 set $assign_clause
3245where $key1 = 1
3246EOS
3247  $dbi->execute($sql, $param);
3248  my $result = $dbi->execute("select * from $table1 order by $key1", table => $table1);
3249  my $rows   = $result->all;
3250  is_deeply($rows, [{$key1 => 1, $key2 => 11, $key3 => 33, $key4 => 4, $key5 => 5},
3251    {$key1 => 6, $key2 => 7,  $key3 => 8, $key4 => 9, $key5 => 10}],
3252    "basic");
3253}
3254
3255{
3256  my $dbi = DBIx::Custom->connect;
3257  eval { $dbi->execute("drop table $table1") };
3258  $dbi->execute($create_table1_2);
3259  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}, table => $table1);
3260  $dbi->insert({$key1 => 6, $key2 => 7, $key3 => 8, $key4 => 9, $key5 => 10}, table => $table1);
3261
3262  $dbi = DBIx::Custom->connect;
3263  eval { $dbi->execute("drop table $table1") };
3264  $dbi->execute($create_table1_2);
3265  $dbi->insert({$key1 => 1, $key2 => 2, $key3 => 3, $key4 => 4, $key5 => 5}, table => $table1);
3266  $dbi->insert({$key1 => 6, $key2 => 7, $key3 => 8, $key4 => 9, $key5 => 10}, table => $table1);
3267
3268  my $param = {$key2 => 11};
3269  my $assign_clause = $dbi->assign_clause($param);
3270  my $sql = <<"EOS";
3271update $table1 set $assign_clause
3272where $key1 = 1
3273EOS
3274  $dbi->execute($sql, $param, table => $table1);
3275  my $result = $dbi->execute("select * from $table1 order by $key1");
3276  my $rows   = $result->all;
3277  is_deeply($rows, [{$key1 => 1, $key2 => 11, $key3 => 3, $key4 => 4, $key5 => 5},
3278    {$key1 => 6, $key2 => 7,  $key3 => 8, $key4 => 9, $key5 => 10}],
3279    "basic");
3280}
3281
3282# Model class
3283{
3284  {
3285    {
3286      my $dbi = DBIx::Custom->connect;
3287      eval { $dbi->execute("drop table $table1") };
3288      $dbi->execute($create_table1);
3289      $dbi->include_model(
3290        MyModel1 => [
3291          $dbi->table1,
3292          $dbi->table2
3293        ]
3294      );
3295      my $model = $dbi->model($table1);
3296      $model->insert({$key1 => 'a', $key2 => 'b'});
3297      is_deeply($model->list->all, [{$key1 => 'a', $key2 => 'b'}], 'basic');
3298    }
3299    {
3300      my $dbi = DBIx::Custom->connect;
3301      eval { $dbi->execute("drop table $table2") };
3302      $dbi->execute($create_table2);
3303      $dbi->include_model(
3304        MyModel1 => [
3305          $dbi->table1,
3306          $dbi->table2
3307        ]
3308      );
3309      my $model = $dbi->model($table2);
3310      $model->insert({$key1 => 'a'});
3311      is_deeply($model->list->all, [{$key1 => 'a', $key3 => undef}], 'basic');
3312      is($dbi->models->{$table1}, $dbi->model($table1));
3313      is($dbi->models->{$table2}, $dbi->model($table2));
3314    }
3315  }
3316
3317  {
3318    {
3319      my $dbi = DBIx::Custom->connect;
3320      eval { $dbi->execute("drop table $table1") };
3321      $dbi->execute($create_table1);
3322      $dbi->include_model(
3323        MyModel2 => [
3324            $table1,
3325            {class => $table2, name => $table2}
3326        ]
3327      );
3328      my $model = $dbi->model($table1);
3329      $model->insert({$key1 => 'a', $key2 => 'b'});
3330      is_deeply($model->list->all, [{$key1 => 'a', $key2 => 'b'}], 'basic');
3331    }
3332    {
3333      my $dbi = DBIx::Custom->connect;
3334      $dbi->include_model(
3335        MyModel2 => [
3336            $table1,
3337            {class => $table2, name => $table2}
3338        ]
3339      );
3340      eval { $dbi->execute("drop table $table2") };
3341      $dbi->execute($create_table2);
3342      $dbi->include_model(
3343        MyModel2 => [
3344            $table1,
3345            {class => $table2, name => $table2}
3346        ]
3347      );
3348      my $model = $dbi->model($table2);
3349      $model->insert({$key1 => 'a'});
3350      is_deeply($model->list->all, [{$key1 => 'a', $key3 => undef}], 'basic');
3351    }
3352  }
3353  {
3354    my $dbi = DBIx::Custom->connect;
3355    eval { $dbi->execute("drop table $table1") };
3356    eval { $dbi->execute("drop table $table2") };
3357    $dbi->execute($create_table1);
3358    $dbi->execute($create_table2);
3359    $dbi->include_model('MyModel4');
3360
3361    {
3362      my $model = $dbi->model($table2);
3363      $model->insert({$key1 => 'a'});
3364      is_deeply($model->list->all, [{$key1 => 'a', $key3 => undef}], 'include all model');
3365    }
3366    {
3367      $dbi->insert({$key1 => 1}, table => $table1);
3368      my $model = $dbi->model($table1);
3369      is_deeply($model->list->all, [{$key1 => 1, $key2 => undef}], 'include all model');
3370    }
3371  }
3372}
3373# primary_key
3374{
3375  my $dbi = DBIx::Custom->connect;
3376  $dbi->include_model(
3377    MyModel1 => [
3378      $dbi->table1,
3379      $dbi->table2
3380    ]
3381  );
3382  my $model = $dbi->model($table1);
3383  $model->primary_key([$key1, $key2]);
3384  is_deeply($model->primary_key, [$key1, $key2]);
3385}
3386
3387# columns
3388{
3389  my $dbi = DBIx::Custom->connect;
3390  $dbi->include_model(
3391    MyModel1 => [
3392      $dbi->table1,
3393      $dbi->table2
3394    ]
3395  );
3396  my $model = $dbi->model($table1);
3397  $model->columns([$key1, $key2]);
3398  is_deeply($model->columns, [$key1, $key2]);
3399}
3400
3401# columns
3402{
3403  my $dbi = DBIx::Custom->connect;
3404  $dbi->include_model(
3405    MyModel1 => [
3406      $dbi->table1,
3407      $dbi->table2
3408    ]
3409  );
3410  my $model = $dbi->model($table1);
3411  $model->columns([$key1, $key2]);
3412  is_deeply($model->columns, [$key1, $key2]);
3413}
3414
3415# setup_model
3416{
3417  my $dbi = DBIx::Custom->connect;
3418  $dbi->user_table_info($user_table_info);
3419  eval { $dbi->execute("drop table $table1") };
3420  eval { $dbi->execute("drop table $table2") };
3421  $dbi->execute($create_table1);
3422  $dbi->execute($create_table2);
3423  $dbi->include_model(
3424    MyModel1 => [
3425      $dbi->table1,
3426      $dbi->table2
3427    ]
3428  );
3429  $dbi->setup_model;
3430  is_deeply([sort @{$dbi->model($table1)->columns}], [$key1, $key2]);
3431  is_deeply([sort @{$dbi->model($table2)->columns}], [$key1, $key3]);
3432}
3433
3434# each_column
3435{
3436  my $dbi = DBIx::Custom->connect;
3437  eval { $dbi->execute("drop table ${q}table$p") };
3438  eval { $dbi->execute("drop table $table1") };
3439  eval { $dbi->execute("drop table $table2") };
3440  eval { $dbi->execute("drop table $table3") };
3441  $dbi->execute($create_table1_type);
3442  $dbi->execute($create_table2);
3443
3444  my $infos = [];
3445  $dbi->each_column(sub {
3446    my ($self, $table, $column, $cinfo) = @_;
3447
3448    if ($table =~ /^table\d/i) {
3449       my $info = [$table, $column, $cinfo->{COLUMN_NAME}];
3450       push @$infos, $info;
3451    }
3452  });
3453  $infos = [sort { $a->[0] cmp $b->[0] || $a->[1] cmp $b->[1] } @$infos];
3454  is_deeply($infos,
3455    [
3456      [table_only($table1), $key1, $key1],
3457      [table_only($table1), $key2, $key2],
3458      [table_only($table2), $key1, $key1],
3459      [table_only($table2), $key3, $key3]
3460    ]
3461
3462  );
3463}
3464
3465# each_table
3466my $user_column_info;
3467{
3468  my $dbi = DBIx::Custom->connect;
3469  eval { $dbi->execute("drop table $table1") };
3470  eval { $dbi->execute("drop table $table2") };
3471  $dbi->execute($create_table2);
3472  $dbi->execute($create_table1_type);
3473
3474  {
3475    my $infos = [];
3476    $dbi->each_table(sub {
3477      my ($self, $table, $table_info) = @_;
3478
3479      if ($table =~ /^table\d/i) {
3480        my $info = [$table, $table_info->{TABLE_NAME}];
3481        push @$infos, $info;
3482      }
3483    });
3484    $infos = [sort { $a->[0] cmp $b->[0] || $a->[1] cmp $b->[1] } @$infos];
3485    is_deeply($infos,
3486      [
3487        [table_only($table1), table_only($table1)],
3488        [table_only($table2), table_only($table2)],
3489      ]
3490    );
3491
3492    $dbi = DBIx::Custom->connect;
3493    eval { $dbi->execute("drop table $table1") };
3494    eval { $dbi->execute("drop table $table2") };
3495    $dbi->execute($create_table2);
3496    $dbi->execute($create_table1_type);
3497  }
3498
3499  {
3500    my $infos = [];
3501    $dbi->user_table_info($user_table_info);
3502    $dbi->each_table(sub {
3503      my ($self, $table, $table_info) = @_;
3504
3505      if ($table =~ /^table\d/i) {
3506         my $info = [$table, $table_info->{TABLE_NAME}];
3507         push @$infos, $info;
3508      }
3509    });
3510    $infos = [sort { $a->[0] cmp $b->[0] || $a->[1] cmp $b->[1] } @$infos];
3511    is_deeply($infos,
3512      [
3513        [table_only($table1), table_only($table1)],
3514        [table_only($table2), table_only($table2)],
3515        [table_only($table3), table_only($table3)],
3516      ]
3517    );
3518  }
3519  $user_column_info = $dbi->get_column_info(exclude_table => $dbi->exclude_table);
3520}
3521
3522# type_rule into
3523{
3524  {
3525    my $dbi = DBIx::Custom->connect;
3526    eval { $dbi->execute("drop table $table1") };
3527    $dbi->execute($create_table1_type);
3528  }
3529
3530  {
3531    my $dbi = DBIx::Custom->connect;
3532    $dbi = DBIx::Custom->connect;
3533    eval { $dbi->execute("drop table $table1") };
3534    $dbi->execute($create_table1_type);
3535
3536    $dbi->user_column_info($user_column_info);
3537    $dbi->type_rule(
3538      into1 => {
3539        $date_typename => sub { '2010-' . $_[0] }
3540      }
3541    );
3542    $dbi->insert({$key1 => '01-01'}, table => $table1);
3543    my $result = $dbi->select(table => $table1);
3544    like($result->one->{$key1}, qr/^2010-01-01/);
3545  }
3546
3547  {
3548    my $dbi = DBIx::Custom->connect;
3549    eval { $dbi->execute("drop table $table1") };
3550    $dbi->execute($create_table1_type);
3551    $dbi->user_column_info($user_column_info);
3552    $dbi->type_rule(
3553      into1 => [
3554         [$date_typename, $datetime_typename] => sub {
3555            my $value = shift;
3556            $value =~ s/02/03/g;
3557            return $value;
3558         }
3559      ]
3560    );
3561    $dbi->insert({$key1 => '2010-01-02', $key2 => '2010-01-01 01:01:02'}, table => $table1);
3562    my $result = $dbi->select(table => $table1);
3563    my $row = $result->one;
3564    like($row->{$key1}, qr/^2010-01-03/);
3565    like($row->{$key2}, qr/^2010-01-01 01:01:03/);
3566  }
3567
3568  {
3569    my $dbi = DBIx::Custom->connect;
3570    eval { $dbi->execute("drop table $table1") };
3571    $dbi->execute($create_table1_type);
3572    $dbi->insert({$key1 => '2010-01-03', $key2 => '2010-01-01 01:01:03'}, table => $table1);
3573    $dbi->user_column_info($user_column_info);
3574    $dbi->type_rule(
3575      into1 => [
3576        [$date_typename, $datetime_typename] => sub {
3577          my $value = shift;
3578          $value =~ s/02/03/g;
3579          return $value;
3580        }
3581      ]
3582    );
3583    my $result = $dbi->execute(
3584      "select * from $table1 where $key1 = :$key1 and $key2 = :$table1.$key2",
3585      {$key1 => '2010-01-03', "$table1.$key2" => '2010-01-01 01:01:02'}
3586    );
3587    my $row = $result->one;
3588    like($row->{$key1}, qr/^2010-01-03/);
3589    like($row->{$key2}, qr/^2010-01-01 01:01:03/);
3590  }
3591
3592  {
3593    my $dbi = DBIx::Custom->connect;
3594    eval { $dbi->execute("drop table $table1") };
3595    $dbi->execute($create_table1_type);
3596    $dbi->insert({$key1 => '2010-01-03', $key2 => '2010-01-01 01:01:03'}, table => $table1);
3597    $dbi->user_column_info($user_column_info);
3598    $dbi->type_rule(
3599      into1 => [
3600        [$date_typename, $datetime_typename] => sub {
3601          my $value = shift;
3602          $value =~ s/02/03/g;
3603          return $value;
3604        }
3605      ]
3606    );
3607    my $result = $dbi->execute(
3608      "select * from $table1 where $key1 = :$key1 and $key2 = :$table1.$key2",
3609      {$key1 => '2010-01-02', "$table1.$key2" => '2010-01-01 01:01:02'},
3610      table => $table1
3611    );
3612    my $row = $result->one;
3613    like($row->{$key1}, qr/^2010-01-03/);
3614    like($row->{$key2}, qr/2010-01-01 01:01:03/);
3615  }
3616
3617  {
3618    my $dbi = DBIx::Custom->connect;
3619    eval { $dbi->execute("drop table $table1") };
3620    $dbi->execute($create_table1_type);
3621    $dbi->register_filter(convert => sub {
3622      my $value = shift || '';
3623      $value =~ s/02/03/;
3624      return $value;
3625    });
3626    $dbi->user_column_info($user_column_info);
3627    $dbi->type_rule(
3628      from1 => {
3629        $date_datatype => 'convert',
3630      },
3631      into1 => {
3632          $date_typename => 'convert',
3633      }
3634    );
3635    $dbi->insert({$key1 => '2010-02-02'}, table => $table1);
3636
3637    {
3638      my $result = $dbi->select(table => $table1);
3639      like($result->fetch->[0], qr/^2010-03-03/);
3640    }
3641
3642    {
3643      my $result = $dbi->select(column => [$key1, $key1], table => $table1);
3644      my $row = $result->fetch;
3645      like($row->[0], qr/^2010-03-03/);
3646      like($row->[1], qr/^2010-03-03/);
3647    }
3648  }
3649}
3650
3651# type_rule and filter order
3652{
3653  {
3654    my $dbi = DBIx::Custom->connect;
3655    eval { $dbi->execute("drop table $table1") };
3656    $dbi->execute($create_table1_type);
3657    $dbi->user_column_info($user_column_info);
3658    $dbi->type_rule(
3659      into1 => {
3660        $date_typename => sub { my $v = shift || ''; $v =~ s/4/5/; return $v }
3661      },
3662      into2 => {
3663        $date_typename => sub { my $v = shift || ''; $v =~ s/5/6/; return $v }
3664      },
3665      from1 => {
3666        $date_datatype => sub { my $v = shift || ''; $v =~ s/6/7/; return $v }
3667      },
3668      from2 => {
3669        $date_datatype => sub { my $v = shift || ''; $v =~ s/7/8/; return $v }
3670      }
3671    );
3672    $dbi->insert({$key1 => '2010-01-03'},
3673    table => $table1, filter => {$key1 => sub { my $v = shift || ''; $v =~ s/3/4/; return $v }});
3674    my $result = $dbi->select(table => $table1);
3675    $result->filter($key1 => sub { my $v = shift || ''; $v =~ s/8/9/; return $v });
3676    like($result->fetch_one->[0], qr/^2010-01-09/);
3677  }
3678
3679  {
3680    my $dbi = DBIx::Custom->connect;
3681    eval { $dbi->execute("drop table $table1") };
3682    $dbi->execute($create_table1_type);
3683    $dbi->user_column_info($user_column_info);
3684    $dbi->type_rule(
3685      from1 => {
3686        $date_datatype => sub { my $v = shift || ''; $v =~ s/3/4/; return $v }
3687      },
3688      from2 => {
3689        $date_datatype => sub { my $v = shift || ''; $v =~ s/4/5/; return $v }
3690      },
3691    );
3692    $dbi->insert({$key1 => '2010-01-03'}, table => $table1);
3693    my $result = $dbi->select(table => $table1);
3694    $dbi->user_column_info($user_column_info);
3695    $result->type_rule(
3696      from1 => {
3697        $date_datatype => sub { my $v = shift || ''; $v =~ s/3/6/; return $v }
3698      },
3699      from2 => {
3700        $date_datatype => sub { my $v = shift || ''; $v =~ s/6/8/; return $v }
3701      }
3702    );
3703    $result->filter($key1 => sub { my $v = shift || ''; $v =~ s/8/9/; return $v });
3704    like($result->fetch_one->[0], qr/^2010-01-09/);
3705  }
3706}
3707
3708# type_rule_off
3709{
3710  {
3711    my $dbi = DBIx::Custom->connect;
3712    eval { $dbi->execute("drop table $table1") };
3713    $dbi->execute($create_table1_type);
3714    $dbi->user_column_info($user_column_info);
3715    $dbi->type_rule(
3716      from1 => {
3717        $date_datatype => sub { my $v = shift || ''; $v =~ s/3/5/; return $v }
3718      },
3719      into1 => {
3720        $date_typename => sub { my $v = shift || ''; $v =~ s/3/4/; return $v }
3721      }
3722    );
3723    $dbi->insert({$key1 => '2010-01-03'}, table => $table1, type_rule_off => 1);
3724    my $result = $dbi->select(table => $table1, type_rule_off => 1);
3725    like($result->type_rule_off->fetch->[0], qr/^2010-01-03/);
3726  }
3727
3728  {
3729    my $dbi = DBIx::Custom->connect;
3730    eval { $dbi->execute("drop table $table1") };
3731    $dbi->execute($create_table1_type);
3732    $dbi->user_column_info($user_column_info);
3733    $dbi->type_rule(
3734      from1 => {
3735        $date_datatype => sub { my $v = shift || ''; $v =~ s/3/4/; return $v }
3736      },
3737      into1 => {
3738        $date_typename => sub { my $v = shift || ''; $v =~ s/3/5/; return $v }
3739      }
3740    );
3741    $dbi->insert({$key1 => '2010-01-03'}, table => $table1, type_rule_off => 1);
3742    my $result = $dbi->select(table => $table1, type_rule_off => 1);
3743    like($result->one->{$key1}, qr/^2010-01-04/);
3744  }
3745
3746  {
3747    my $dbi = DBIx::Custom->connect;
3748    eval { $dbi->execute("drop table $table1") };
3749    $dbi->execute($create_table1_type);
3750    $dbi->user_column_info($user_column_info);
3751    $dbi->type_rule(
3752      from1 => {
3753        $date_datatype => sub { my $v = shift || ''; $v =~ s/4/5/; return $v }
3754      },
3755      into1 => {
3756        $date_typename => sub { my $v = shift || ''; $v =~ s/3/4/; return $v }
3757      }
3758    );
3759    $dbi->insert({$key1 => '2010-01-03'}, table => $table1);
3760    my $result = $dbi->select(table => $table1);
3761    like($result->one->{$key1}, qr/^2010-01-05/);
3762  }
3763
3764  {
3765    my $dbi = DBIx::Custom->connect;
3766    eval { $dbi->execute("drop table $table1") };
3767    $dbi->execute($create_table1_type);
3768    $dbi->user_column_info($user_column_info);
3769    $dbi->type_rule(
3770      from1 => {
3771        $date_datatype => sub { my $v = shift || ''; $v =~ s/4/5/; return $v }
3772      },
3773      into1 => {
3774        $date_typename => sub { my $v = shift || ''; $v =~ s/3/4/; return $v }
3775      }
3776    );
3777    $dbi->insert({$key1 => '2010-01-03'}, table => $table1);
3778    my $result = $dbi->select(table => $table1);
3779    like($result->fetch->[0], qr/2010-01-05/);
3780  }
3781
3782  {
3783    my $dbi = DBIx::Custom->connect;
3784    eval { $dbi->execute("drop table $table1") };
3785    $dbi->execute($create_table1_type);
3786    $dbi->register_filter(ppp => sub { my $v = shift || ''; $v =~ s/3/4/; return $v });
3787    $dbi->user_column_info($user_column_info);
3788    $dbi->type_rule(
3789      into1 => {
3790        $date_typename => 'ppp'
3791      }
3792    );
3793    $dbi->insert({$key1 => '2010-01-03'}, table => $table1);
3794    my $result = $dbi->select(table => $table1);
3795    like($result->one->{$key1}, qr/^2010-01-04/);
3796
3797    eval{$dbi->type_rule(
3798      into1 => {
3799        $date_typename => 'pp'
3800      }
3801    )};
3802    like($@, qr/not registered/);
3803  }
3804
3805  {
3806    my $dbi = DBIx::Custom->connect;
3807    eval { $dbi->execute("drop table $table1") };
3808    $dbi->execute($create_table1_type);
3809    eval {
3810      $dbi->type_rule(
3811        from1 => {
3812          Date => sub { $_[0] * 2 },
3813        }
3814      );
3815    };
3816    like($@, qr/lower/);
3817
3818    eval {
3819      $dbi->type_rule(
3820        into1 => {
3821          Date => sub { $_[0] * 2 },
3822        }
3823      );
3824    };
3825    like($@, qr/lower/);
3826  }
3827
3828  {
3829    my $dbi = DBIx::Custom->connect;
3830    eval { $dbi->execute("drop table $table1") };
3831    $dbi->execute($create_table1_type);
3832    $dbi->user_column_info($user_column_info);
3833    $dbi->type_rule(
3834      from1 => {
3835        $date_datatype => sub { my $v = shift || ''; $v =~ s/4/5/; return $v }
3836      },
3837      into1 => {
3838        $date_typename => sub { my $v = shift || ''; $v =~ s/3/4/; return $v }
3839      }
3840    );
3841    $dbi->insert({$key1 => '2010-01-03'}, table => $table1);
3842    my $result = $dbi->select(table => $table1);
3843    $result->type_rule_off;
3844    like($result->one->{$key1}, qr/^2010-01-04/);
3845  }
3846
3847  {
3848    my $dbi = DBIx::Custom->connect;
3849
3850    {
3851      eval { $dbi->execute("drop table $table1") };
3852      $dbi->execute($create_table1_type);
3853      $dbi->user_column_info($user_column_info);
3854      $dbi->type_rule(
3855        from1 => {
3856          $date_datatype => sub { my $v = shift || ''; $v =~ s/3/4/; return $v },
3857          $datetime_datatype => sub { my $v = shift || ''; $v =~ s/3/4/; return $v }
3858        },
3859      );
3860      $dbi->insert({$key1 => '2010-01-03', $key2 => '2010-01-01 01:01:03'}, table => $table1);
3861      my $result = $dbi->select(table => $table1);
3862      $result->type_rule(
3863        from1 => {
3864          $date_datatype => sub { my $v = shift || ''; $v =~ s/3/5/; return $v }
3865        }
3866      );
3867      my $row = $result->one;
3868      like($row->{$key1}, qr/^2010-01-05/);
3869      like($row->{$key2}, qr/^2010-01-01 01:01:03/);
3870    }
3871
3872    {
3873      my $result = $dbi->select(table => $table1);
3874      $result->type_rule(
3875        from1 => {
3876          $date_datatype => sub { my $v = shift || ''; $v =~ s/3/5/; return $v }
3877        }
3878      );
3879      my $row = $result->one;
3880      like($row->{$key1}, qr/2010-01-05/);
3881      like($row->{$key2}, qr/2010-01-01 01:01:03/);
3882    }
3883
3884    {
3885      my $result = $dbi->select(table => $table1);
3886      $result->type_rule(
3887        from1 => {
3888          $date_datatype => sub { my $v = shift || ''; $v =~ s/3/5/; return $v }
3889        }
3890      );
3891      my $row = $result->one;
3892      like($row->{$key1}, qr/2010-01-05/);
3893      like($row->{$key2}, qr/2010-01-01 01:01:03/);
3894    }
3895
3896    {
3897      my $result = $dbi->select(table => $table1);
3898      $result->type_rule(
3899        from1 => [$date_datatype => sub { my $v = shift || ''; $v =~ s/3/5/; return $v }]
3900      );
3901      my $row = $result->one;
3902      like($row->{$key1}, qr/2010-01-05/);
3903      like($row->{$key2}, qr/2010-01-01 01:01:03/);
3904    }
3905
3906    {
3907      $dbi->register_filter(five => sub { my $v = shift || ''; $v =~ s/3/5/; return $v });
3908      my $result = $dbi->select(table => $table1);
3909      $result->type_rule(
3910        from1 => [$date_datatype => 'five']
3911      );
3912      my $row = $result->one;
3913      like($row->{$key1}, qr/^2010-01-05/);
3914      like($row->{$key2}, qr/^2010-01-01 01:01:03/);
3915    }
3916
3917    {
3918      my $result = $dbi->select(table => $table1);
3919      $result->type_rule(
3920        from1 => [$date_datatype => undef]
3921      );
3922      my $row = $result->one;
3923      like($row->{$key1}, qr/^2010-01-03/);
3924      like($row->{$key2}, qr/^2010-01-01 01:01:03/);
3925    }
3926  }
3927
3928  {
3929    my $dbi = DBIx::Custom->connect;
3930    eval { $dbi->execute("drop table $table1") };
3931    $dbi->execute($create_table1_type);
3932    $dbi->user_column_info($user_column_info);
3933    $dbi->type_rule(
3934      from1 => {
3935        $date_datatype => sub { my $v = shift || ''; $v =~ s/3/4/; return $v },
3936      },
3937    );
3938    $dbi->insert({$key1 => '2010-01-03'}, table => $table1);
3939    my $result = $dbi->select(table => $table1);
3940    $result->filter($key1 => sub { my $v = shift || ''; $v =~ s/4/5/; return $v });
3941    like($result->one->{$key1}, qr/^2010-01-05/);
3942  }
3943
3944  {
3945    my $dbi = DBIx::Custom->connect;
3946    eval { $dbi->execute("drop table $table1") };
3947    $dbi->execute($create_table1_type);
3948    $dbi->user_column_info($user_column_info);
3949    $dbi->type_rule(
3950      from1 => {
3951        $date_datatype => sub { my $v = shift || ''; $v =~ s/3/4/; return $v }
3952      },
3953    );
3954    $dbi->insert({$key1 => '2010-01-03'}, table => $table1);
3955    my $result = $dbi->select(table => $table1);
3956    $result->filter($key1 => sub { my $v = shift || ''; $v =~ s/4/5/; return $v });
3957    like($result->fetch->[0], qr/^2010-01-05/);
3958  }
3959
3960  {
3961    my $dbi = DBIx::Custom->connect;
3962    eval { $dbi->execute("drop table $table1") };
3963    $dbi->execute($create_table1_type);
3964    $dbi->user_column_info($user_column_info);
3965    $dbi->type_rule(
3966      into1 => {
3967        $date_typename => sub { my $v = shift || ''; $v =~ s/3/4/; return $v }
3968      },
3969      into2 => {
3970        $date_typename => sub { my $v = shift || ''; $v =~ s/3/5/; return $v }
3971      },
3972      from1 => {
3973        $date_datatype => sub { my $v = shift || ''; $v =~ s/3/6/; return $v }
3974      },
3975      from2 => {
3976        $date_datatype => sub { my $v = shift || ''; $v =~ s/(3|6)/7/; return $v }
3977      }
3978    );
3979    $dbi->insert({$key1 => '2010-01-03'}, table => $table1, type_rule_off => 1);
3980    {
3981      my $result = $dbi->select(table => $table1);
3982      like($result->type_rule_off->fetch_one->[0], qr/^2010-01-03/);
3983    }
3984    {
3985      my $result = $dbi->select(table => $table1);
3986      like($result->type_rule_on->fetch_one->[0], qr/^2010-01-07/);
3987    }
3988  }
3989
3990  {
3991    my $dbi = DBIx::Custom->connect;
3992    eval { $dbi->execute("drop table $table1") };
3993    $dbi->execute($create_table1_type);
3994    $dbi->user_column_info($user_column_info);
3995    $dbi->type_rule(
3996      into1 => {
3997        $date_typename => sub { my $v = shift || ''; $v =~ s/3/4/; return $v }
3998      },
3999      into2 => {
4000        $date_typename => sub { my $v = shift || ''; $v =~ s/3/5/; return $v }
4001      },
4002      from1 => {
4003        $date_datatype => sub { my $v = shift || ''; $v =~ s/(3|5)/6/; return $v }
4004      },
4005      from2 => {
4006        $date_datatype => sub { my $v = shift || ''; $v =~ s/6/7/; return $v }
4007      }
4008    );
4009    $dbi->insert({$key1 => '2010-01-03'}, table => $table1, type_rule1_off => 1);
4010    {
4011      my $result = $dbi->select(table => $table1);
4012      like($result->type_rule1_off->fetch_one->[0], qr/^2010-01-05/);
4013    }
4014    {
4015      my $result = $dbi->select(table => $table1);
4016      like($result->type_rule1_on->fetch_one->[0], qr/^2010-01-07/);
4017    }
4018  }
4019
4020  {
4021    my $dbi = DBIx::Custom->connect;
4022    eval { $dbi->execute("drop table $table1") };
4023    $dbi->execute($create_table1_type);
4024    $dbi->user_column_info($user_column_info);
4025    $dbi->type_rule(
4026      into1 => {
4027        $date_typename => sub { my $v = shift || ''; $v =~ s/3/5/; return $v }
4028      },
4029      into2 => {
4030        $date_typename => sub { my $v = shift || ''; $v =~ s/3/4/; return $v }
4031      },
4032      from1 => {
4033        $date_datatype => sub { my $v = shift || ''; $v =~ s/5/6/; return $v }
4034      },
4035      from2 => {
4036        $date_datatype => sub { my $v = shift || ''; $v =~ s/(3|6)/7/; return $v }
4037      }
4038    );
4039    $dbi->insert({$key1 => '2010-01-03'}, table => $table1, type_rule2_off => 1);
4040    {
4041      my $result = $dbi->select(table => $table1);
4042      like($result->type_rule2_off->fetch_one->[0], qr/^2010-01-06/);
4043    }
4044
4045    {
4046      my $result = $dbi->select(table => $table1);
4047      like($result->type_rule2_on->fetch_one->[0], qr/^2010-01-07/);
4048    }
4049  }
4050}
4051
4052# join
4053{
4054  {
4055    my $dbi = DBIx::Custom->connect;
4056    eval { $dbi->execute("drop table $table1") };
4057    $dbi->execute($create_table1);
4058    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
4059    $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
4060    eval { $dbi->execute("drop table $table2") };
4061    $dbi->execute($create_table2);
4062    $dbi->insert({$key1 => 1, $key3 => 5}, table => $table2);
4063    eval { $dbi->execute("drop table $table3") };
4064    $dbi->execute("create table $table3 ($key3 int, $key4 int)");
4065    $dbi->insert({$key3 => 5, $key4 => 4}, table => $table3);
4066    my $rows = $dbi->select(
4067      table => $table1,
4068      column => "$table1.$key1 as " . u("${table1}_$key1") . ", $table2.$key1 as " . u("${table2}_$key1") . ", $key2, $key3",
4069      where   => {"$table1.$key2" => 2},
4070      join  => ["left outer join $table2 on $table1.$key1 = $table2.$key1"]
4071    )->all;
4072    is_deeply($rows, [{u"${table1}_$key1" => 1, u"${table2}_$key1" => 1, $key2 => 2, $key3 => 5}]);
4073  }
4074
4075  {
4076    my $dbi = DBIx::Custom->connect;
4077    eval { $dbi->execute("drop table $table1") };
4078    $dbi->execute($create_table1);
4079    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
4080    $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
4081    eval { $dbi->execute("drop table $table2") };
4082    $dbi->execute($create_table2);
4083    $dbi->insert({$key1 => 1, $key3 => 5}, table => $table2);
4084    eval { $dbi->execute("drop table $table3") };
4085    $dbi->execute("create table $table3 ($key3 int, $key4 int)");
4086    $dbi->insert({$key3 => 5, $key4 => 4}, table => $table3);
4087    {
4088      my $rows = $dbi->select(
4089        table => $table1,
4090        column => "$table1.$key1 as " . u("${table1}_$key1") . ", $table2.$key1 as " . u("${table2}_$key1") . ", $key2, $key3",
4091        where   => {"$table1.$key2" => 2},
4092        join  => {
4093          clause => "left outer join $table2 on $table1.$key1 = $table2.$key1",
4094          table => [$table1, $table2]
4095        }
4096      )->all;
4097      is_deeply($rows, [{u"${table1}_$key1" => 1, u"${table2}_$key1" => 1, $key2 => 2, $key3 => 5}]);
4098    }
4099
4100    {
4101      my $rows = $dbi->select(
4102        table => $table1,
4103        where   => {$key1 => 1},
4104        join  => ["left outer join $table2 on $table1.$key1 = $table2.$key1"]
4105      )->all;
4106      is_deeply($rows, [{$key1 => 1, $key2 => 2}]);
4107    }
4108
4109    {
4110      my $rows = $dbi->select(
4111        table => $table1,
4112        where   => {$key1 => 1},
4113        join  => ["left outer join $table2 on $table1.$key1 = $table2.$key1",
4114                  "left outer join $table3 on $table2.$key3 = $table3.$key3"]
4115      )->all;
4116      is_deeply($rows, [{$key1 => 1, $key2 => 2}]);
4117    }
4118
4119    {
4120      my $rows = $dbi->select(
4121        column => "$table3.$key4 as " . u2("${table3}__$key4"),
4122        table => $table1,
4123        where   => {"$table1.$key1" => 1},
4124        join  => ["left outer join $table2 on $table1.$key1 = $table2.$key1",
4125                  "left outer join $table3 on $table2.$key3 = $table3.$key3"]
4126      )->all;
4127      is_deeply($rows, [{u2"${table3}__$key4" => 4}]);
4128    }
4129
4130    {
4131      my $rows = $dbi->select(
4132        column => "$table1.$key1 as " . u2("${table1}__$key1"),
4133        table => $table1,
4134        where   => {"$table3.$key4" => 4},
4135        join  => ["left outer join $table2 on $table1.$key1 = $table2.$key1",
4136                  "left outer join $table3 on $table2.$key3 = $table3.$key3"]
4137      )->all;
4138      is_deeply($rows, [{u2"${table1}__$key1" => 1}]);
4139    }
4140  }
4141
4142  {
4143    my $dbi = DBIx::Custom->connect;
4144    eval { $dbi->execute("drop table $table1") };
4145    $dbi->execute($create_table1);
4146    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
4147    eval { $dbi->execute("drop table $table2") };
4148    $dbi->execute($create_table2);
4149    $dbi->insert({$key1 => 1, $key3 => 5}, table => $table2);
4150    my $rows = $dbi->select(
4151      table => $table1,
4152      column => $dbi->_tq($table1) . ".${q}$key1$p as ${q}" . u("${table1}_$key1") . "$p, " . $dbi->_tq($table2) . ".${q}$key1$p as ${q}" . u("${table2}_$key1") . "$p, ${q}$key2$p, ${q}$key3$p",
4153      where   => {"$table1.$key2" => 2},
4154      join  => ["left outer join " . $dbi->_tq($table2) . " on " . $dbi->_tq($table1) . ".${q}$key1$p = " . $dbi->_tq($table2) . ".${q}$key1$p"],
4155    )->all;
4156    is_deeply($rows, [{u"${table1}_$key1" => 1, u"${table2}_$key1" => 1, $key2 => 2, $key3 => 5}],
4157      'quote');
4158
4159    {
4160      my $dbi = DBIx::Custom->connect;
4161      eval { $dbi->execute("drop table $table1") };
4162      $dbi->execute($create_table1);
4163      $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
4164      my $sql = <<"EOS";
4165left outer join (
4166select * from $table1 t1
4167  where t1.$key2 = (
4168    select max(t2.$key2) from $table1 t2
4169    where t1.$key1 = t2.$key1
4170  )
4171) $table3 on $table1.$key1 = $table3.$key1
4172EOS
4173      $sql =~ s/\Q.table3/_table3/g;
4174      my $join = [$sql];
4175      my $rows = $dbi->select(
4176        table => $table1,
4177        column => u($table3) . ".$key1 as " . u2("${table3}__$key1"),
4178        join  => $join
4179      )->all;
4180      is_deeply($rows, [{u2"${table3}__$key1" => 1}]);
4181    }
4182  }
4183  {
4184    my $dbi = DBIx::Custom->connect;
4185    eval { $dbi->execute("drop table $table1") };
4186    eval { $dbi->execute("drop table $table2") };
4187    $dbi->execute($create_table1);
4188    $dbi->execute($create_table2);
4189    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
4190    $dbi->insert({$key1 => 1, $key3 => 4}, table => $table2);
4191    $dbi->insert({$key1 => 1, $key3 => 5}, table => $table2);
4192    {
4193      my $result = $dbi->select(
4194        table => $table1,
4195        join => [
4196          "left outer join $table2 on $table2.$key2 = '4' and $table1.$key1 = $table2.$key1"
4197        ]
4198      );
4199      is_deeply($result->all, [{$key1 => 1, $key2 => 2}]);
4200    }
4201
4202    {
4203      my $result = $dbi->select(
4204        table => $table1,
4205        column => [{$table2 => [$key3]}],
4206        join => [
4207          "left outer join $table2 on $table2.$key3 = '4' and $table1.$key1 = $table2.$key1"
4208        ]
4209      );
4210      is_deeply($result->all, [{"$table2.$key3" => 4}]);
4211    }
4212
4213    {
4214      my $result = $dbi->select(
4215        table => $table1,
4216        column => [{$table2 => [$key3]}],
4217        join => [
4218          "left outer join $table2 on $table1.$key1 = $table2.$key1 and $table2.$key3 = '4'"
4219        ]
4220      );
4221      is_deeply($result->all, [{"$table2.$key3" => 4}]);
4222    }
4223  }
4224
4225  {
4226    my $dbi = DBIx::Custom->connect;
4227    eval { $dbi->execute("drop table $table1") };
4228    eval { $dbi->execute("drop table $table2") };
4229    $dbi->execute($create_table1);
4230    $dbi->execute($create_table2);
4231    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
4232    $dbi->insert({$key1 => 1, $key3 => 4}, table => $table2);
4233    $dbi->insert({$key1 => 1, $key3 => 5}, table => $table2);
4234    my $result = $dbi->select(
4235      table => $table1,
4236      column => [{$table2 => [$key3]}],
4237      join => [
4238        {
4239          clause => "left outer join $table2 on $table2.$key3 = '4' and $table1.$key1 = $table2.$key1",
4240          table => [$table1, $table2]
4241        }
4242      ]
4243    );
4244    is_deeply($result->all, [{"$table2.$key3" => 4}]);
4245  }
4246
4247  {
4248    my $dbi = DBIx::Custom->connect;
4249    eval { $dbi->execute("drop table $table1") };
4250    eval { $dbi->execute("drop table $table2") };
4251    $dbi->execute($create_table1);
4252    $dbi->execute($create_table2);
4253    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
4254    $dbi->insert({$key1 => 1, $key3 => 4}, table => $table2);
4255    $dbi->insert({$key1 => 1, $key3 => 1}, table => $table2);
4256    my $result = $dbi->select(
4257      table => $table1,
4258      column => [{$table2 => [$key3]}],
4259      join => [
4260        "left outer join $table2 on $table1.$key1 = $table2.$key1 and $table2.$key3 > '3'"
4261      ]
4262    );
4263    is_deeply($result->all, [{"$table2.$key3" => 4}]);
4264  }
4265
4266  {
4267    my $dbi = DBIx::Custom->connect;
4268    eval { $dbi->execute("drop table $table1") };
4269    eval { $dbi->execute("drop table $table2") };
4270    $dbi->execute($create_table1);
4271    $dbi->execute($create_table2);
4272    $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
4273    $dbi->insert({$key1 => 1, $key3 => 4}, table => $table2);
4274    $dbi->insert({$key1 => 1, $key3 => 1}, table => $table2);
4275    my $result = $dbi->select(
4276      table => $table1,
4277      column => [{$table2 => [$key3]}],
4278      join => [
4279        "left outer join $table2 on $table2.$key3 > '3' and $table1.$key1 = $table2.$key1"
4280      ]
4281    );
4282    is_deeply($result->all, [{"$table2.$key3" => 4}]);
4283  }
4284}
4285
4286# columns
4287{
4288  my $dbi = DBIx::Custom->connect;
4289  $dbi->include_model(
4290    MyModel1 => [
4291      $dbi->table1,
4292      $dbi->table2
4293    ]
4294  );
4295  my $model = $dbi->model($table1);
4296}
4297
4298# count
4299{
4300  my $dbi = DBIx::Custom->connect;
4301  eval { $dbi->execute("drop table $table1") };
4302  $dbi->execute($create_table1);
4303  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
4304  $dbi->insert({$key1 => 1, $key2 => 3}, table => $table1);
4305  is($dbi->count(table => $table1), 2);
4306  is($dbi->count(table => $table1, where => {$key2 => 2}), 1);
4307  {
4308    my $model = $dbi->create_model(table => $table1);
4309    is($model->count, 2);
4310  }
4311
4312  {
4313    eval { $dbi->execute("drop table $table1") };
4314    eval { $dbi->execute("drop table $table2") };
4315    $dbi->execute($create_table1);
4316    $dbi->execute($create_table2);
4317    my $model = $dbi->create_model(table => $table1, primary_key => $key1);
4318    $model->insert({$key1 => 1, $key2 => 2});
4319  }
4320  {
4321    my $model = $dbi->create_model(table => $table2, primary_key => $key1,
4322      join => ["left outer join $table1 on $table2.$key1 = $table1.$key1"]);
4323    $model->insert({$key1 => 1, $key3 => 3});
4324    is($model->count(id => 1), 1);
4325    is($model->count(where => {"$table2.$key3" => 3}), 1);
4326  }
4327}
4328
4329# table_alias option
4330{
4331  {
4332    my $dbi = DBIx::Custom->connect;
4333    eval { $dbi->execute("drop table $table1") };
4334    $dbi->execute($create_table1_type);
4335    $dbi->insert({$key1 => '2010-01-01'}, table => $table1);
4336    $dbi->user_column_info($user_column_info);
4337    $dbi->type_rule(
4338      into1 => {
4339        $date_typename => sub { '2010-' . $_[0] }
4340      }
4341    );
4342    my $result = $dbi->execute(
4343      "select * from $table1 TABLE1_ALIAS where :TABLE1_ALIAS.${key1}{=}",
4344      {"TABLE1_ALIAS.${key1}" => '01-01'},
4345      table_alias => {TABLE1_ALIAS => $table1}
4346    );
4347    like($result->one->{$key1}, qr/^2010-01-01/);
4348  }
4349
4350  {
4351    my $dbi = DBIx::Custom->connect;
4352    eval { $dbi->execute("drop table $table1") };
4353    $dbi->execute($create_table1_type);
4354    $dbi->insert({$key1 => '2010-01-01'}, table => $table1);
4355    $dbi->user_column_info($user_column_info);
4356    $dbi->type_rule(
4357      into2 => {
4358        $date_typename => sub { '2010-' . $_[0] }
4359      }
4360    );
4361    my $result = $dbi->execute(
4362      "select * from $table1 TABLE1_ALIAS where :TABLE1_ALIAS.${key1}{=}",
4363      {"TABLE1_ALIAS.${key1}" => '01-01'},
4364      table_alias => {TABLE1_ALIAS => $table1}
4365    );
4366    like($result->one->{$key1}, qr/^2010-01-01/);
4367  }
4368}
4369
4370# DBIx::Custom::Where join
4371{
4372  my $dbi = DBIx::Custom->connect;
4373  eval { $dbi->execute("drop table $table1") };
4374  $dbi->execute($create_table1);
4375  $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
4376  $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
4377  eval { $dbi->execute("drop table $table2") };
4378  $dbi->execute($create_table2);
4379  $dbi->insert({$key1 => 1, $key3 => 5}, table => $table2);
4380  eval { $dbi->execute("drop table $table3") };
4381  $dbi->execute("create table $table3 ($key3 int, $key4 int)");
4382  $dbi->insert({$key3 => 5, $key4 => 4}, table => $table3);
4383
4384  {
4385    my $where = $dbi->where;
4386    $where->param({$key1 => 1});
4387    $where->clause(":${key1}{=}");
4388    $where->join(["left outer join $table3 on $table2.$key3 = $table3.$key3"]);
4389
4390    my $rows = $dbi->select(
4391      table => $table1,
4392      where   => $where,
4393      join  => ["left outer join $table2 on $table1.$key1 = $table2.$key1"]
4394    )->all;
4395    is_deeply($rows, [{$key1 => 1, $key2 => 2}]);
4396  }
4397  {
4398    my $where = $dbi->where;
4399    $where->param({"$table1.$key1" => 1});
4400    $where->clause(":$table1.${key1}{=}");
4401    $where->join(["left outer join $table3 on $table2.$key3 = $table3.$key3"]);
4402
4403    my $rows = $dbi->select(
4404      column => "$table3.$key4 as " . u2("${table3}__$key4"),
4405      table => $table1,
4406      where   => $where,
4407      join  => ["left outer join $table2 on $table1.$key1 = $table2.$key1"]
4408    )->all;
4409    is_deeply($rows, [{u2"${table3}__$key4" => 4}]);
4410  }
4411  {
4412    my $where = $dbi->where;
4413    $where->param({"$table3.$key4" => 4});
4414    $where->clause(":$table3.${key4}{=}");
4415    $where->join(["left outer join $table3 on $table2.$key3 = $table3.$key3"]);
4416
4417    my $rows = $dbi->select(
4418      column => "$table1.$key1 as " . u2("${table1}__$key1"),
4419      table => $table1,
4420      where   => $where,
4421      join  => ["left outer join $table2 on $table1.$key1 = $table2.$key1"]
4422    )->all;
4423    is_deeply($rows, [{u2"${table1}__$key1" => 1}]);
4424  }
4425}
4426