Showing 4 changed files with 221 additions and 304 deletions
+2
Changes
... ...
@@ -1,3 +1,5 @@
1
+0.1712
2
+    - you can set any string as separator
1 3
 0.1711
2 4
     - renamed EXPERIMENTAL available_type_name to available_typename
3 5
     - renamed EXPERIMENTAL available_data_type to available_datatype
+10 -17
lib/DBIx/Custom.pm
... ...
@@ -54,6 +54,7 @@ has [qw/connector dsn password quote user/],
54 54
     query_builder => sub { DBIx::Custom::QueryBuilder->new(dbi => shift) },
55 55
     result_class  => 'DBIx::Custom::Result',
56 56
     safety_character => '\w',
57
+    separator => '.',
57 58
     stash => sub { {} },
58 59
     tag_parse => 1;
59 60
 
... ...
@@ -875,22 +876,6 @@ sub select {
875 876
     return $result;
876 877
 }
877 878
 
878
-sub separator {
879
-    my $self = shift;
880
-    
881
-    if (@_) {
882
-        my $separator = $_[0] || '';
883
-        croak qq{Separator must be "." or "__" or "-" } . _subname
884
-          unless $separator eq '.' || $separator eq '__'
885
-              || $separator eq '-';
886
-        
887
-        $self->{separator} = $separator;
888
-    
889
-        return $self;
890
-    }
891
-    return $self->{separator} ||= '.';
892
-}
893
-
894 879
 sub setup_model {
895 880
     my $self = shift;
896 881
     
... ...
@@ -1984,6 +1969,14 @@ Result class, default to L<DBIx::Custom::Result>.
1984 1969
 Regex of safety character for table and column name, default to '\w'.
1985 1970
 Note that you don't have to specify like '[\w]'.
1986 1971
 
1972
+=head2 C<separator>
1973
+
1974
+    my $separator = $self->separator;
1975
+    $dbi = $self->separator($separator);
1976
+
1977
+Separator whichi join table and column.
1978
+This is used by C<column> and C<mycolumn> method.
1979
+
1987 1980
 =head2 C<tag_parse>
1988 1981
 
1989 1982
     my $tag_parse = $dbi->tag_parse(0);
... ...
@@ -2038,7 +2031,7 @@ Create column clause. The follwoing column clause is created.
2038 2031
     book.author as "book.author",
2039 2032
     book.title as "book.title"
2040 2033
 
2041
-You can change separator by C<separator> method.
2034
+You can change separator by C<separator> attribute.
2042 2035
 
2043 2036
     # Separator is double underbar
2044 2037
     $dbi->separator('__');
+55 -1
t/common.t
... ...
@@ -133,7 +133,7 @@ use MyDBI1;
133 133
     sub connect {
134 134
         my $self = shift->SUPER::connect(@_);
135 135
         
136
-        $self->include_model('MyModel8')->setup_model;
136
+        $self->include_model('MyModel8');
137 137
         
138 138
         return $self;
139 139
     }
... ...
@@ -2174,6 +2174,60 @@ is($dbi->select(table => 'table1')->one->{key2}, 2);
2174 2174
 eval { $dbi->insert_param({";" => 1}) };
2175 2175
 like($@, qr/not safety/);
2176 2176
 
2177
+test 'mycolumn';
2178
+$dbi = MyDBI8->connect;
2179
+eval { $dbi->execute('drop table table1') };
2180
+eval { $dbi->execute('drop table table2') };
2181
+$dbi->execute($create_table1);
2182
+$dbi->execute($create_table2);
2183
+$dbi->setup_model;
2184
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
2185
+$dbi->insert(table => 'table2', param => {key1 => 1, key3 => 3});
2186
+$model = $dbi->model('table1');
2187
+$result = $model->select_at(
2188
+    column => [
2189
+        $model->mycolumn,
2190
+        $model->column('table2')
2191
+    ]
2192
+);
2193
+is_deeply($result->one,
2194
+          {key1 => 1, key2 => 2, 'table2.key1' => 1, 'table2.key3' => 3});
2195
+
2196
+$result = $model->select_at(
2197
+    column => [
2198
+        $model->mycolumn(['key1']),
2199
+        $model->column(table2 => ['key1'])
2200
+    ]
2201
+);
2202
+is_deeply($result->one,
2203
+          {key1 => 1, 'table2.key1' => 1});
2204
+$result = $model->select_at(
2205
+    column => [
2206
+        $model->mycolumn(['key1']),
2207
+        {table2 => ['key1']}
2208
+    ]
2209
+);
2210
+is_deeply($result->one,
2211
+          {key1 => 1, 'table2.key1' => 1});
2212
+
2213
+$result = $model->select_at(
2214
+    column => [
2215
+        $model->mycolumn(['key1']),
2216
+        ['table2.key1', as => 'table2.key1']
2217
+    ]
2218
+);
2219
+is_deeply($result->one,
2220
+          {key1 => 1, 'table2.key1' => 1});
2221
+
2222
+$result = $model->select_at(
2223
+    column => [
2224
+        $model->mycolumn(['key1']),
2225
+        ['table2.key1' => 'table2.key1']
2226
+    ]
2227
+);
2228
+is_deeply($result->one,
2229
+          {key1 => 1, 'table2.key1' => 1});
2230
+
2177 2231
 
2178 2232
 
2179 2233
 
+154 -286
t/sqlite.t
... ...
@@ -196,215 +196,11 @@ my $binary;
196 196
 # Prepare table
197 197
 $dbi = DBIx::Custom->connect;
198 198
 
199
-test 'join';
200
-$dbi = DBIx::Custom->connect;
201
-eval { $dbi->execute('drop table table1') };
202
-$dbi->execute($create_table1);
203
-$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
204
-$dbi->insert(table => 'table1', param => {key1 => 3, key2 => 4});
205
-$dbi->execute($create_table2);
206
-$dbi->insert(table => 'table2', param => {key1 => 1, key3 => 5});
207
-$dbi->execute('create table table3 (key3 int, key4 int);');
208
-$dbi->insert(table => 'table3', param => {key3 => 5, key4 => 4});
209
-$rows = $dbi->select(
210
-    table => 'table1',
211
-    column => 'table1.key1 as table1_key1, table2.key1 as table2_key1, key2, key3',
212
-    where   => {'table1.key2' => 2},
213
-    join  => ['left outer join table2 on table1.key1 = table2.key1']
214
-)->all;
215
-is_deeply($rows, [{table1_key1 => 1, table2_key1 => 1, key2 => 2, key3 => 5}]);
216
-
217
-$rows = $dbi->select(
218
-    table => 'table1',
219
-    where   => {'key1' => 1},
220
-    join  => ['left outer join table2 on table1.key1 = table2.key1']
221
-)->all;
222
-is_deeply($rows, [{key1 => 1, key2 => 2}]);
223
-
224
-eval {
225
-    $rows = $dbi->select(
226
-        table => 'table1',
227
-        column => 'table1.key1 as table1_key1, table2.key1 as table2_key1, key2, key3',
228
-        where   => {'table1.key2' => 2},
229
-        join  => {'table1.key1' => 'table2.key1'}
230
-    );
231
-};
232
-like ($@, qr/array/);
233
-
234
-$rows = $dbi->select(
235
-    table => 'table1',
236
-    where   => {'key1' => 1},
237
-    join  => ['left outer join table2 on table1.key1 = table2.key1',
238
-              'left outer join table3 on table2.key3 = table3.key3']
239
-)->all;
240
-is_deeply($rows, [{key1 => 1, key2 => 2}]);
241
-
242
-$rows = $dbi->select(
243
-    column => 'table3.key4 as table3__key4',
244
-    table => 'table1',
245
-    where   => {'table1.key1' => 1},
246
-    join  => ['left outer join table2 on table1.key1 = table2.key1',
247
-              'left outer join table3 on table2.key3 = table3.key3']
248
-)->all;
249
-is_deeply($rows, [{table3__key4 => 4}]);
250
-
251
-$rows = $dbi->select(
252
-    column => 'table1.key1 as table1__key1',
253
-    table => 'table1',
254
-    where   => {'table3.key4' => 4},
255
-    join  => ['left outer join table2 on table1.key1 = table2.key1',
256
-              'left outer join table3 on table2.key3 = table3.key3']
257
-)->all;
258
-is_deeply($rows, [{table1__key1 => 1}]);
259
-
260
-$dbi = DBIx::Custom->connect;
261
-$dbi->quote('"');
262
-eval { $dbi->execute('drop table table1') };
263
-$dbi->execute($create_table1);
264
-$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
265
-$dbi->execute($create_table2);
266
-$dbi->insert(table => 'table2', param => {key1 => 1, key3 => 5});
267
-$rows = $dbi->select(
268
-    table => 'table1',
269
-    column => '"table1"."key1" as "table1_key1", "table2"."key1" as "table2_key1", "key2", "key3"',
270
-    where   => {'table1.key2' => 2},
271
-    join  => ['left outer join "table2" on "table1"."key1" = "table2"."key1"'],
272
-)->all;
273
-is_deeply($rows, [{table1_key1 => 1, table2_key1 => 1, key2 => 2, key3 => 5}],
274
-          'quote');
275
-
276
-
277
-$dbi = DBIx::Custom->connect;
278
-eval { $dbi->execute('drop table table1') };
279
-$dbi->execute($create_table1);
280
-$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
281
-$sql = <<"EOS";
282
-left outer join (
283
-  select * from table1 as t1
284
-  where t1.key2 = (
285
-    select max(t2.key2) from table1 as t2
286
-    where t1.key1 = t2.key1
287
-  )
288
-) as latest_table1 on table1.key1 = latest_table1.key1
289
-EOS
290
-$join = [$sql];
291
-$rows = $dbi->select(
292
-    table => 'table1',
293
-    column => 'latest_table1.key1 as latest_table1__key1',
294
-    join  => $join
295
-)->all;
296
-is_deeply($rows, [{latest_table1__key1 => 1}]);
297
-
298
-$dbi = DBIx::Custom->connect;
299
-eval { $dbi->execute('drop table table1') };
300
-eval { $dbi->execute('drop table table2') };
301
-$dbi->execute($create_table1);
302
-$dbi->execute($create_table2);
303
-$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
304
-$dbi->insert(table => 'table2', param => {key1 => 1, key3 => 4});
305
-$dbi->insert(table => 'table2', param => {key1 => 1, key3 => 5});
306
-$result = $dbi->select(
307
-    table => 'table1',
308
-    join => [
309
-        "left outer join table2 on table2.key2 = '4' and table1.key1 = table2.key1"
310
-    ]
311
-);
312
-is_deeply($result->all, [{key1 => 1, key2 => 2}]);
313
-$result = $dbi->select(
314
-    table => 'table1',
315
-    column => [{table2 => ['key3']}],
316
-    join => [
317
-        "left outer join table2 on table2.key3 = '4' and table1.key1 = table2.key1"
318
-    ]
319
-);
320
-is_deeply($result->all, [{'table2.key3' => 4}]);
321
-$result = $dbi->select(
322
-    table => 'table1',
323
-    column => [{table2 => ['key3']}],
324
-    join => [
325
-        "left outer join table2 on table1.key1 = table2.key1 and table2.key3 = '4'"
326
-    ]
327
-);
328
-is_deeply($result->all, [{'table2.key3' => 4}]);
329
-
330
-$dbi = DBIx::Custom->connect;
331
-eval { $dbi->execute('drop table table1') };
332
-eval { $dbi->execute('drop table table2') };
333
-$dbi->execute($create_table1);
334
-$dbi->execute($create_table2);
335
-$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
336
-$dbi->insert(table => 'table2', param => {key1 => 1, key3 => 4});
337
-$dbi->insert(table => 'table2', param => {key1 => 1, key3 => 5});
338
-$result = $dbi->select(
339
-    table => 'table1',
340
-    column => [{table2 => ['key3']}],
341
-    join => [
342
-        {
343
-            clause => "left outer join table2 on table2.key3 = '4' and table1.key1 = table2.key1",
344
-            table => ['table1', 'table2']
345
-        }
346
-    ]
347
-);
348
-is_deeply($result->all, [{'table2.key3' => 4}]);
349
-
350
-test 'mycolumn';
351
-$dbi = MyDBI8->connect;
352
-eval { $dbi->execute('drop table table1') };
353
-eval { $dbi->execute('drop table table2') };
354
-$dbi->execute($create_table1);
355
-$dbi->execute($create_table2);
356
-$dbi->setup_model;
357
-$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
358
-$dbi->insert(table => 'table2', param => {key1 => 1, key3 => 3});
359
-$model = $dbi->model('table1');
360
-$result = $model->select_at(
361
-    column => [
362
-        $model->mycolumn,
363
-        $model->column('table2')
364
-    ]
365
-);
366
-is_deeply($result->one,
367
-          {key1 => 1, key2 => 2, 'table2.key1' => 1, 'table2.key3' => 3});
368
-
369
-$result = $model->select_at(
370
-    column => [
371
-        $model->mycolumn(['key1']),
372
-        $model->column(table2 => ['key1'])
373
-    ]
374
-);
375
-is_deeply($result->one,
376
-          {key1 => 1, 'table2.key1' => 1});
377
-$result = $model->select_at(
378
-    column => [
379
-        $model->mycolumn(['key1']),
380
-        {table2 => ['key1']}
381
-    ]
382
-);
383
-is_deeply($result->one,
384
-          {key1 => 1, 'table2.key1' => 1});
385
-
386
-$result = $model->select_at(
387
-    column => [
388
-        $model->mycolumn(['key1']),
389
-        ['table2.key1', as => 'table2.key1']
390
-    ]
391
-);
392
-is_deeply($result->one,
393
-          {key1 => 1, 'table2.key1' => 1});
394
-
395
-$result = $model->select_at(
396
-    column => [
397
-        $model->mycolumn(['key1']),
398
-        ['table2.key1' => 'table2.key1']
399
-    ]
400
-);
401
-is_deeply($result->one,
402
-          {key1 => 1, 'table2.key1' => 1});
403
-
404 199
 test 'dbi method from model';
405 200
 $dbi = MyDBI9->connect;
406 201
 eval { $dbi->execute('drop table table1') };
407 202
 $dbi->execute($create_table1);
203
+$dbi->setup_model;
408 204
 $model = $dbi->model('table1');
409 205
 eval{$model->execute('select * from table1')};
410 206
 ok(!$@);
... ...
@@ -413,6 +209,7 @@ test 'column table option';
413 209
 $dbi = MyDBI9->connect;
414 210
 eval { $dbi->execute('drop table table1') };
415 211
 $dbi->execute($create_table1);
212
+eval { $dbi->execute('drop table table2') };
416 213
 $dbi->execute($create_table2);
417 214
 $dbi->setup_model;
418 215
 $dbi->execute('insert into table1 (key1, key2) values (1, 2);');
... ...
@@ -447,75 +244,6 @@ $result = $model->select(
447 244
 is_deeply($result->one, 
448 245
           {'table2_alias-key1' => 1, 'table2_alias-key3' => 4});
449 246
 
450
-test 'type option'; # DEPRECATED!
451
-$dbi = DBIx::Custom->connect(
452
-    dbi_option => {
453
-        $DBD::SQLite::VERSION > 1.26 ? (sqlite_unicode => 1) : (unicode => 1)
454
-    }
455
-);
456
-$binary = pack("I3", 1, 2, 3);
457
-eval { $dbi->execute('drop table table1') };
458
-$dbi->execute('create table table1(key1, key2)');
459
-$dbi->insert(table => 'table1', param => {key1 => $binary, key2 => 'あ'}, type => [key1 => DBI::SQL_BLOB]);
460
-$result = $dbi->select(table => 'table1');
461
-$row   = $result->one;
462
-is_deeply($row, {key1 => $binary, key2 => 'あ'}, "basic");
463
-$result = $dbi->execute('select length(key1) as key1_length from table1');
464
-$row = $result->one;
465
-is($row->{key1_length}, length $binary);
466
-
467
-$dbi->insert(table => 'table1', param => {key1 => $binary, key2 => 'あ'}, type => [['key1'] => DBI::SQL_BLOB]);
468
-$result = $dbi->select(table => 'table1');
469
-$row   = $result->one;
470
-is_deeply($row, {key1 => $binary, key2 => 'あ'}, "basic");
471
-$result = $dbi->execute('select length(key1) as key1_length from table1');
472
-$row = $result->one;
473
-is($row->{key1_length}, length $binary);
474
-
475
-
476
-test 'bind_type option';
477
-$dbi = DBIx::Custom->connect(
478
-    dbi_option => {
479
-        $DBD::SQLite::VERSION > 1.26 ? (sqlite_unicode => 1) : (unicode => 1)
480
-    }
481
-);
482
-$binary = pack("I3", 1, 2, 3);
483
-eval { $dbi->execute('drop table table1') };
484
-$dbi->execute('create table table1(key1, key2)');
485
-$dbi->insert(table => 'table1', param => {key1 => $binary, key2 => 'あ'}, bind_type => [key1 => DBI::SQL_BLOB]);
486
-$result = $dbi->select(table => 'table1');
487
-$row   = $result->one;
488
-is_deeply($row, {key1 => $binary, key2 => 'あ'}, "basic");
489
-$result = $dbi->execute('select length(key1) as key1_length from table1');
490
-$row = $result->one;
491
-is($row->{key1_length}, length $binary);
492
-
493
-$dbi->insert(table => 'table1', param => {key1 => $binary, key2 => 'あ'}, bind_type => [['key1'] => DBI::SQL_BLOB]);
494
-$result = $dbi->select(table => 'table1');
495
-$row   = $result->one;
496
-is_deeply($row, {key1 => $binary, key2 => 'あ'}, "basic");
497
-$result = $dbi->execute('select length(key1) as key1_length from table1');
498
-$row = $result->one;
499
-is($row->{key1_length}, length $binary);
500
-
501
-test 'model type attribute';
502
-$dbi = DBIx::Custom->connect(
503
-    dbi_option => {
504
-        $DBD::SQLite::VERSION > 1.26 ? (sqlite_unicode => 1) : (unicode => 1)
505
-    }
506
-);
507
-$binary = pack("I3", 1, 2, 3);
508
-eval { $dbi->execute('drop table table1') };
509
-$dbi->execute('create table table1(key1, key2)');
510
-$model = $dbi->create_model(table => 'table1', bind_type => [key1 => DBI::SQL_BLOB]);
511
-$model->insert(param => {key1 => $binary, key2 => 'あ'});
512
-$result = $dbi->select(table => 'table1');
513
-$row   = $result->one;
514
-is_deeply($row, {key1 => $binary, key2 => 'あ'}, "basic");
515
-$result = $dbi->execute('select length(key1) as key1_length from table1');
516
-$row = $result->one;
517
-is($row->{key1_length}, length $binary);
518
-
519 247
 test 'create_model';
520 248
 $dbi = DBIx::Custom->connect;
521 249
 eval { $dbi->execute('drop table table1') };
... ...
@@ -586,6 +314,7 @@ eval { $dbi->execute('drop table table1') };
586 314
 $dbi->execute($create_table1);
587 315
 $dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
588 316
 $dbi->insert(table => 'table1', param => {key1 => 2, key2 => 3});
317
+eval { $dbi->execute('drop table table2') };
589 318
 $dbi->execute($create_table2);
590 319
 $dbi->insert(table => 'table2', param => {key1 => 1, key3 => 4});
591 320
 $dbi->insert(table => 'table2', param => {key1 => 2, key3 => 5});
... ...
@@ -1043,18 +772,6 @@ $dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
1043 772
 $rows = $dbi->select(prefix => 'key1,', column => 'key2', table => 'table1')->all;
1044 773
 is_deeply($rows, [{key1 => 1, key2 => 2}], "table");
1045 774
 
1046
-
1047
-test 'separator';
1048
-$dbi = DBIx::Custom->connect;
1049
-is($dbi->separator, '.');
1050
-$dbi->separator('-');
1051
-is($dbi->separator, '-');
1052
-$dbi->separator('__');
1053
-is($dbi->separator, '__');
1054
-eval { $dbi->separator('?') };
1055
-like($@, qr/Separator/);
1056
-
1057
-
1058 775
 test 'map_param';
1059 776
 $dbi = DBIx::Custom->connect;
1060 777
 $param = $dbi->map_param(
... ...
@@ -1519,6 +1236,157 @@ like($@, qr/unexpected "{"/, "error : 2");
1519 1236
 
1520 1237
 
1521 1238
 ### a little complex test
1239
+test 'join';
1240
+$dbi = DBIx::Custom->connect;
1241
+eval { $dbi->execute('drop table table1') };
1242
+$dbi->execute($create_table1);
1243
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
1244
+$dbi->insert(table => 'table1', param => {key1 => 3, key2 => 4});
1245
+$dbi->execute($create_table2);
1246
+$dbi->insert(table => 'table2', param => {key1 => 1, key3 => 5});
1247
+$dbi->execute('create table table3 (key3 int, key4 int);');
1248
+$dbi->insert(table => 'table3', param => {key3 => 5, key4 => 4});
1249
+$rows = $dbi->select(
1250
+    table => 'table1',
1251
+    column => 'table1.key1 as table1_key1, table2.key1 as table2_key1, key2, key3',
1252
+    where   => {'table1.key2' => 2},
1253
+    join  => ['left outer join table2 on table1.key1 = table2.key1']
1254
+)->all;
1255
+is_deeply($rows, [{table1_key1 => 1, table2_key1 => 1, key2 => 2, key3 => 5}]);
1256
+
1257
+$rows = $dbi->select(
1258
+    table => 'table1',
1259
+    where   => {'key1' => 1},
1260
+    join  => ['left outer join table2 on table1.key1 = table2.key1']
1261
+)->all;
1262
+is_deeply($rows, [{key1 => 1, key2 => 2}]);
1263
+
1264
+eval {
1265
+    $rows = $dbi->select(
1266
+        table => 'table1',
1267
+        column => 'table1.key1 as table1_key1, table2.key1 as table2_key1, key2, key3',
1268
+        where   => {'table1.key2' => 2},
1269
+        join  => {'table1.key1' => 'table2.key1'}
1270
+    );
1271
+};
1272
+like ($@, qr/array/);
1273
+
1274
+$rows = $dbi->select(
1275
+    table => 'table1',
1276
+    where   => {'key1' => 1},
1277
+    join  => ['left outer join table2 on table1.key1 = table2.key1',
1278
+              'left outer join table3 on table2.key3 = table3.key3']
1279
+)->all;
1280
+is_deeply($rows, [{key1 => 1, key2 => 2}]);
1281
+
1282
+$rows = $dbi->select(
1283
+    column => 'table3.key4 as table3__key4',
1284
+    table => 'table1',
1285
+    where   => {'table1.key1' => 1},
1286
+    join  => ['left outer join table2 on table1.key1 = table2.key1',
1287
+              'left outer join table3 on table2.key3 = table3.key3']
1288
+)->all;
1289
+is_deeply($rows, [{table3__key4 => 4}]);
1290
+
1291
+$rows = $dbi->select(
1292
+    column => 'table1.key1 as table1__key1',
1293
+    table => 'table1',
1294
+    where   => {'table3.key4' => 4},
1295
+    join  => ['left outer join table2 on table1.key1 = table2.key1',
1296
+              'left outer join table3 on table2.key3 = table3.key3']
1297
+)->all;
1298
+is_deeply($rows, [{table1__key1 => 1}]);
1299
+
1300
+$dbi = DBIx::Custom->connect;
1301
+$dbi->quote('"');
1302
+eval { $dbi->execute('drop table table1') };
1303
+$dbi->execute($create_table1);
1304
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
1305
+$dbi->execute($create_table2);
1306
+$dbi->insert(table => 'table2', param => {key1 => 1, key3 => 5});
1307
+$rows = $dbi->select(
1308
+    table => 'table1',
1309
+    column => '"table1"."key1" as "table1_key1", "table2"."key1" as "table2_key1", "key2", "key3"',
1310
+    where   => {'table1.key2' => 2},
1311
+    join  => ['left outer join "table2" on "table1"."key1" = "table2"."key1"'],
1312
+)->all;
1313
+is_deeply($rows, [{table1_key1 => 1, table2_key1 => 1, key2 => 2, key3 => 5}],
1314
+          'quote');
1315
+
1316
+
1317
+$dbi = DBIx::Custom->connect;
1318
+eval { $dbi->execute('drop table table1') };
1319
+$dbi->execute($create_table1);
1320
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
1321
+$sql = <<"EOS";
1322
+left outer join (
1323
+  select * from table1 as t1
1324
+  where t1.key2 = (
1325
+    select max(t2.key2) from table1 as t2
1326
+    where t1.key1 = t2.key1
1327
+  )
1328
+) as latest_table1 on table1.key1 = latest_table1.key1
1329
+EOS
1330
+$join = [$sql];
1331
+$rows = $dbi->select(
1332
+    table => 'table1',
1333
+    column => 'latest_table1.key1 as latest_table1__key1',
1334
+    join  => $join
1335
+)->all;
1336
+is_deeply($rows, [{latest_table1__key1 => 1}]);
1337
+
1338
+$dbi = DBIx::Custom->connect;
1339
+eval { $dbi->execute('drop table table1') };
1340
+eval { $dbi->execute('drop table table2') };
1341
+$dbi->execute($create_table1);
1342
+$dbi->execute($create_table2);
1343
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
1344
+$dbi->insert(table => 'table2', param => {key1 => 1, key3 => 4});
1345
+$dbi->insert(table => 'table2', param => {key1 => 1, key3 => 5});
1346
+$result = $dbi->select(
1347
+    table => 'table1',
1348
+    join => [
1349
+        "left outer join table2 on table2.key2 = '4' and table1.key1 = table2.key1"
1350
+    ]
1351
+);
1352
+is_deeply($result->all, [{key1 => 1, key2 => 2}]);
1353
+$result = $dbi->select(
1354
+    table => 'table1',
1355
+    column => [{table2 => ['key3']}],
1356
+    join => [
1357
+        "left outer join table2 on table2.key3 = '4' and table1.key1 = table2.key1"
1358
+    ]
1359
+);
1360
+is_deeply($result->all, [{'table2.key3' => 4}]);
1361
+$result = $dbi->select(
1362
+    table => 'table1',
1363
+    column => [{table2 => ['key3']}],
1364
+    join => [
1365
+        "left outer join table2 on table1.key1 = table2.key1 and table2.key3 = '4'"
1366
+    ]
1367
+);
1368
+is_deeply($result->all, [{'table2.key3' => 4}]);
1369
+
1370
+$dbi = DBIx::Custom->connect;
1371
+eval { $dbi->execute('drop table table1') };
1372
+eval { $dbi->execute('drop table table2') };
1373
+$dbi->execute($create_table1);
1374
+$dbi->execute($create_table2);
1375
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2});
1376
+$dbi->insert(table => 'table2', param => {key1 => 1, key3 => 4});
1377
+$dbi->insert(table => 'table2', param => {key1 => 1, key3 => 5});
1378
+$result = $dbi->select(
1379
+    table => 'table1',
1380
+    column => [{table2 => ['key3']}],
1381
+    join => [
1382
+        {
1383
+            clause => "left outer join table2 on table2.key3 = '4' and table1.key1 = table2.key1",
1384
+            table => ['table1', 'table2']
1385
+        }
1386
+    ]
1387
+);
1388
+is_deeply($result->all, [{'table2.key3' => 4}]);
1389
+
1522 1390
 
1523 1391
 test 'update_param';
1524 1392
 $dbi = DBIx::Custom->connect;