| ... | ... | @@ -260,7 +260,7 @@ sub delete { | 
| 260 | 260 |  | 
| 261 | 261 |  sub delete_all { shift->delete(allow_delete_all => 1, @_) } | 
| 262 | 262 |  | 
| 263 | -sub DESTROY { } | |
| 263 | +sub DESTROY {} | |
| 264 | 264 |  | 
| 265 | 265 |  sub create_model { | 
| 266 | 266 | my $self = shift; | 
| ... | ... | @@ -233,165 +233,6 @@ require MyDBI1; | 
| 233 | 233 | } | 
| 234 | 234 | } | 
| 235 | 235 |  | 
| 236 | -test 'join'; | |
| 237 | -$dbi = DBIx::Custom->connect; | |
| 238 | -eval { $dbi->execute("drop table $table1") }; | |
| 239 | -$dbi->execute($create_table1); | |
| 240 | -$dbi->insert(table => $table1, param => {$key1 => 1, $key2 => 2}); | |
| 241 | -$dbi->insert(table => $table1, param => {$key1 => 3, $key2 => 4}); | |
| 242 | -eval { $dbi->execute("drop table $table2") }; | |
| 243 | -$dbi->execute($create_table2); | |
| 244 | -$dbi->insert(table => $table2, param => {$key1 => 1, $key3 => 5}); | |
| 245 | -eval { $dbi->execute("drop table $table3") }; | |
| 246 | -$dbi->execute("create table $table3 ($key3 int, $key4 int)"); | |
| 247 | -$dbi->insert(table => $table3, param => {$key3 => 5, $key4 => 4}); | |
| 248 | -$rows = $dbi->select( | |
| 249 | - table => $table1, | |
| 250 | -    column => "$table1.$key1 as ${table1}_$key1, $table2.$key1 as ${table2}_$key1, $key2, $key3", | |
| 251 | -    where   => {"$table1.$key2" => 2}, | |
| 252 | - join => ["left outer join $table2 on $table1.$key1 = $table2.$key1"] | |
| 253 | -)->all; | |
| 254 | -is_deeply($rows, [{"${table1}_$key1" => 1, "${table2}_$key1" => 1, $key2 => 2, $key3 => 5}]); | |
| 255 | - | |
| 256 | -$rows = $dbi->select( | |
| 257 | - table => $table1, | |
| 258 | -    where   => {$key1 => 1}, | |
| 259 | - join => ["left outer join $table2 on $table1.$key1 = $table2.$key1"] | |
| 260 | -)->all; | |
| 261 | -is_deeply($rows, [{$key1 => 1, $key2 => 2}]); | |
| 262 | - | |
| 263 | -eval { | |
| 264 | - $rows = $dbi->select( | |
| 265 | - table => $table1, | |
| 266 | -        column => "$table1.$key1 as ${table1}_$key1, $table2.$key1 as ${table2}_$key1, $key2, $key3", | |
| 267 | -        where   => {"$table1.$key2" => 2}, | |
| 268 | -        join  => {"$table1.$key1" => "$table2.$key1"} | |
| 269 | - ); | |
| 270 | -}; | |
| 271 | -like ($@, qr/array/); | |
| 272 | - | |
| 273 | -$rows = $dbi->select( | |
| 274 | - table => $table1, | |
| 275 | -    where   => {$key1 => 1}, | |
| 276 | - join => ["left outer join $table2 on $table1.$key1 = $table2.$key1", | |
| 277 | - "left outer join $table3 on $table2.$key3 = $table3.$key3"] | |
| 278 | -)->all; | |
| 279 | -is_deeply($rows, [{$key1 => 1, $key2 => 2}]); | |
| 280 | - | |
| 281 | -$rows = $dbi->select( | |
| 282 | -    column => "$table3.$key4 as ${table3}__$key4", | |
| 283 | - table => $table1, | |
| 284 | -    where   => {"$table1.$key1" => 1}, | |
| 285 | - join => ["left outer join $table2 on $table1.$key1 = $table2.$key1", | |
| 286 | - "left outer join $table3 on $table2.$key3 = $table3.$key3"] | |
| 287 | -)->all; | |
| 288 | -is_deeply($rows, [{"${table3}__$key4" => 4}]); | |
| 289 | - | |
| 290 | -$rows = $dbi->select( | |
| 291 | -    column => "$table1.$key1 as ${table1}__$key1", | |
| 292 | - table => $table1, | |
| 293 | -    where   => {"$table3.$key4" => 4}, | |
| 294 | - join => ["left outer join $table2 on $table1.$key1 = $table2.$key1", | |
| 295 | - "left outer join $table3 on $table2.$key3 = $table3.$key3"] | |
| 296 | -)->all; | |
| 297 | -is_deeply($rows, [{"${table1}__$key1" => 1}]); | |
| 298 | - | |
| 299 | -$dbi = DBIx::Custom->connect; | |
| 300 | -eval { $dbi->execute("drop table $table1") }; | |
| 301 | -$dbi->execute($create_table1); | |
| 302 | -$dbi->insert(table => $table1, param => {$key1 => 1, $key2 => 2}); | |
| 303 | -eval { $dbi->execute("drop table $table2") }; | |
| 304 | -$dbi->execute($create_table2); | |
| 305 | -$dbi->insert(table => $table2, param => {$key1 => 1, $key3 => 5}); | |
| 306 | -$rows = $dbi->select( | |
| 307 | - table => $table1, | |
| 308 | -    column => "${q}$table1$p.${q}$key1$p as ${q}${table1}_$key1$p, ${q}$table2$p.${q}$key1$p as ${q}${table2}_$key1$p, ${q}$key2$p, ${q}$key3$p", | |
| 309 | -    where   => {"$table1.$key2" => 2}, | |
| 310 | -    join  => ["left outer join ${q}$table2$p on ${q}$table1$p.${q}$key1$p = ${q}$table2$p.${q}$key1$p"], | |
| 311 | -)->all; | |
| 312 | -is_deeply($rows, [{"${table1}_$key1" => 1, "${table2}_$key1" => 1, $key2 => 2, $key3 => 5}], | |
| 313 | - 'quote'); | |
| 314 | - | |
| 315 | - | |
| 316 | -$dbi = DBIx::Custom->connect; | |
| 317 | -eval { $dbi->execute("drop table $table1") }; | |
| 318 | -$dbi->execute($create_table1); | |
| 319 | -$dbi->insert(table => $table1, param => {$key1 => 1, $key2 => 2}); | |
| 320 | -$sql = <<"EOS"; | |
| 321 | -left outer join ( | |
| 322 | - select * from $table1 t1 | |
| 323 | - where t1.$key2 = ( | |
| 324 | - select max(t2.$key2) from $table1 t2 | |
| 325 | - where t1.$key1 = t2.$key1 | |
| 326 | - ) | |
| 327 | -) $table3 on $table1.$key1 = $table3.$key1 | |
| 328 | -EOS | |
| 329 | -$join = [$sql]; | |
| 330 | -$rows = $dbi->select( | |
| 331 | - table => $table1, | |
| 332 | -    column => "$table3.$key1 as ${table3}__$key1", | |
| 333 | - join => $join | |
| 334 | -)->all; | |
| 335 | -$DB::single = 1; | |
| 336 | -is_deeply($rows, [{"${table3}__$key1" => 1}]); | |
| 337 | - | |
| 338 | -$dbi = DBIx::Custom->connect; | |
| 339 | -eval { $dbi->execute("drop table $table1") }; | |
| 340 | -eval { $dbi->execute("drop table $table2") }; | |
| 341 | -$dbi->execute($create_table1); | |
| 342 | -$dbi->execute($create_table2); | |
| 343 | -$dbi->insert(table => $table1, param => {$key1 => 1, $key2 => 2}); | |
| 344 | -$dbi->insert(table => $table2, param => {$key1 => 1, $key3 => 4}); | |
| 345 | -$dbi->insert(table => $table2, param => {$key1 => 1, $key3 => 5}); | |
| 346 | -$result = $dbi->select( | |
| 347 | - table => $table1, | |
| 348 | - join => [ | |
| 349 | - "left outer join $table2 on $table2.$key2 = '4' and $table1.$key1 = $table2.$key1" | |
| 350 | - ] | |
| 351 | -); | |
| 352 | -is_deeply($result->all, [{$key1 => 1, $key2 => 2}]); | |
| 353 | -$result = $dbi->select( | |
| 354 | - table => $table1, | |
| 355 | -    column => [{$table2 => [$key3]}], | |
| 356 | - join => [ | |
| 357 | - "left outer join $table2 on $table2.$key3 = '4' and $table1.$key1 = $table2.$key1" | |
| 358 | - ] | |
| 359 | -); | |
| 360 | -is_deeply($result->all, [{"$table2.$key3" => 4}]); | |
| 361 | -$result = $dbi->select( | |
| 362 | - table => $table1, | |
| 363 | -    column => [{$table2 => [$key3]}], | |
| 364 | - join => [ | |
| 365 | - "left outer join $table2 on $table1.$key1 = $table2.$key1 and $table2.$key3 = '4'" | |
| 366 | - ] | |
| 367 | -); | |
| 368 | -is_deeply($result->all, [{"$table2.$key3" => 4}]); | |
| 369 | - | |
| 370 | -$dbi = DBIx::Custom->connect; | |
| 371 | -eval { $dbi->execute("drop table $table1") }; | |
| 372 | -eval { $dbi->execute("drop table $table2") }; | |
| 373 | -$dbi->execute($create_table1); | |
| 374 | -$dbi->execute($create_table2); | |
| 375 | -$dbi->insert(table => $table1, param => {$key1 => 1, $key2 => 2}); | |
| 376 | -$dbi->insert(table => $table2, param => {$key1 => 1, $key3 => 4}); | |
| 377 | -$dbi->insert(table => $table2, param => {$key1 => 1, $key3 => 5}); | |
| 378 | -$result = $dbi->select( | |
| 379 | - table => $table1, | |
| 380 | -    column => [{$table2 => [$key3]}], | |
| 381 | - join => [ | |
| 382 | -        { | |
| 383 | - clause => "left outer join $table2 on $table2.$key3 = '4' and $table1.$key1 = $table2.$key1", | |
| 384 | - table => [$table1, $table2] | |
| 385 | - } | |
| 386 | - ] | |
| 387 | -); | |
| 388 | -is_deeply($result->all, [{"$table2.$key3" => 4}]); | |
| 389 | - | |
| 390 | -test 'columns'; | |
| 391 | -$DB::single = 1; | |
| 392 | -$dbi = MyDBI1->connect; | |
| 393 | -$model = $dbi->model($table1); | |
| 394 | - | |
| 395 | 236 | # Create table | 
| 396 | 237 | $dbi = DBIx::Custom->connect; | 
| 397 | 238 |  eval { $dbi->execute("drop table $table1") }; | 
| ... | ... | @@ -3855,5 +3696,162 @@ like($result->type_rule2_off->fetch_first->[0], qr/^2010-01-06/); | 
| 3855 | 3696 | $result = $dbi->select(table => $table1); | 
| 3856 | 3697 | like($result->type_rule2_on->fetch_first->[0], qr/^2010-01-07/); | 
| 3857 | 3698 |  | 
| 3699 | +test 'join'; | |
| 3700 | +$dbi = DBIx::Custom->connect; | |
| 3701 | +eval { $dbi->execute("drop table $table1") }; | |
| 3702 | +$dbi->execute($create_table1); | |
| 3703 | +$dbi->insert(table => $table1, param => {$key1 => 1, $key2 => 2}); | |
| 3704 | +$dbi->insert(table => $table1, param => {$key1 => 3, $key2 => 4}); | |
| 3705 | +eval { $dbi->execute("drop table $table2") }; | |
| 3706 | +$dbi->execute($create_table2); | |
| 3707 | +$dbi->insert(table => $table2, param => {$key1 => 1, $key3 => 5}); | |
| 3708 | +eval { $dbi->execute("drop table $table3") }; | |
| 3709 | +$dbi->execute("create table $table3 ($key3 int, $key4 int)"); | |
| 3710 | +$dbi->insert(table => $table3, param => {$key3 => 5, $key4 => 4}); | |
| 3711 | +$rows = $dbi->select( | |
| 3712 | + table => $table1, | |
| 3713 | +    column => "$table1.$key1 as ${table1}_$key1, $table2.$key1 as ${table2}_$key1, $key2, $key3", | |
| 3714 | +    where   => {"$table1.$key2" => 2}, | |
| 3715 | + join => ["left outer join $table2 on $table1.$key1 = $table2.$key1"] | |
| 3716 | +)->all; | |
| 3717 | +is_deeply($rows, [{"${table1}_$key1" => 1, "${table2}_$key1" => 1, $key2 => 2, $key3 => 5}]); | |
| 3718 | + | |
| 3719 | +$rows = $dbi->select( | |
| 3720 | + table => $table1, | |
| 3721 | +    where   => {$key1 => 1}, | |
| 3722 | + join => ["left outer join $table2 on $table1.$key1 = $table2.$key1"] | |
| 3723 | +)->all; | |
| 3724 | +is_deeply($rows, [{$key1 => 1, $key2 => 2}]); | |
| 3725 | + | |
| 3726 | +eval { | |
| 3727 | + $rows = $dbi->select( | |
| 3728 | + table => $table1, | |
| 3729 | +        column => "$table1.$key1 as ${table1}_$key1, $table2.$key1 as ${table2}_$key1, $key2, $key3", | |
| 3730 | +        where   => {"$table1.$key2" => 2}, | |
| 3731 | +        join  => {"$table1.$key1" => "$table2.$key1"} | |
| 3732 | + ); | |
| 3733 | +}; | |
| 3734 | +like ($@, qr/array/); | |
| 3735 | + | |
| 3736 | +$rows = $dbi->select( | |
| 3737 | + table => $table1, | |
| 3738 | +    where   => {$key1 => 1}, | |
| 3739 | + join => ["left outer join $table2 on $table1.$key1 = $table2.$key1", | |
| 3740 | + "left outer join $table3 on $table2.$key3 = $table3.$key3"] | |
| 3741 | +)->all; | |
| 3742 | +is_deeply($rows, [{$key1 => 1, $key2 => 2}]); | |
| 3743 | + | |
| 3744 | +$rows = $dbi->select( | |
| 3745 | +    column => "$table3.$key4 as ${table3}__$key4", | |
| 3746 | + table => $table1, | |
| 3747 | +    where   => {"$table1.$key1" => 1}, | |
| 3748 | + join => ["left outer join $table2 on $table1.$key1 = $table2.$key1", | |
| 3749 | + "left outer join $table3 on $table2.$key3 = $table3.$key3"] | |
| 3750 | +)->all; | |
| 3751 | +is_deeply($rows, [{"${table3}__$key4" => 4}]); | |
| 3752 | + | |
| 3753 | +$rows = $dbi->select( | |
| 3754 | +    column => "$table1.$key1 as ${table1}__$key1", | |
| 3755 | + table => $table1, | |
| 3756 | +    where   => {"$table3.$key4" => 4}, | |
| 3757 | + join => ["left outer join $table2 on $table1.$key1 = $table2.$key1", | |
| 3758 | + "left outer join $table3 on $table2.$key3 = $table3.$key3"] | |
| 3759 | +)->all; | |
| 3760 | +is_deeply($rows, [{"${table1}__$key1" => 1}]); | |
| 3761 | + | |
| 3762 | +$dbi = DBIx::Custom->connect; | |
| 3763 | +eval { $dbi->execute("drop table $table1") }; | |
| 3764 | +$dbi->execute($create_table1); | |
| 3765 | +$dbi->insert(table => $table1, param => {$key1 => 1, $key2 => 2}); | |
| 3766 | +eval { $dbi->execute("drop table $table2") }; | |
| 3767 | +$dbi->execute($create_table2); | |
| 3768 | +$dbi->insert(table => $table2, param => {$key1 => 1, $key3 => 5}); | |
| 3769 | +$rows = $dbi->select( | |
| 3770 | + table => $table1, | |
| 3771 | +    column => "${q}$table1$p.${q}$key1$p as ${q}${table1}_$key1$p, ${q}$table2$p.${q}$key1$p as ${q}${table2}_$key1$p, ${q}$key2$p, ${q}$key3$p", | |
| 3772 | +    where   => {"$table1.$key2" => 2}, | |
| 3773 | +    join  => ["left outer join ${q}$table2$p on ${q}$table1$p.${q}$key1$p = ${q}$table2$p.${q}$key1$p"], | |
| 3774 | +)->all; | |
| 3775 | +is_deeply($rows, [{"${table1}_$key1" => 1, "${table2}_$key1" => 1, $key2 => 2, $key3 => 5}], | |
| 3776 | + 'quote'); | |
| 3777 | + | |
| 3778 | + | |
| 3779 | +$dbi = DBIx::Custom->connect; | |
| 3780 | +eval { $dbi->execute("drop table $table1") }; | |
| 3781 | +$dbi->execute($create_table1); | |
| 3782 | +$dbi->insert(table => $table1, param => {$key1 => 1, $key2 => 2}); | |
| 3783 | +$sql = <<"EOS"; | |
| 3784 | +left outer join ( | |
| 3785 | + select * from $table1 t1 | |
| 3786 | + where t1.$key2 = ( | |
| 3787 | + select max(t2.$key2) from $table1 t2 | |
| 3788 | + where t1.$key1 = t2.$key1 | |
| 3789 | + ) | |
| 3790 | +) $table3 on $table1.$key1 = $table3.$key1 | |
| 3791 | +EOS | |
| 3792 | +$join = [$sql]; | |
| 3793 | +$rows = $dbi->select( | |
| 3794 | + table => $table1, | |
| 3795 | +    column => "$table3.$key1 as ${table3}__$key1", | |
| 3796 | + join => $join | |
| 3797 | +)->all; | |
| 3798 | +is_deeply($rows, [{"${table3}__$key1" => 1}]); | |
| 3799 | + | |
| 3800 | +$dbi = DBIx::Custom->connect; | |
| 3801 | +eval { $dbi->execute("drop table $table1") }; | |
| 3802 | +eval { $dbi->execute("drop table $table2") }; | |
| 3803 | +$dbi->execute($create_table1); | |
| 3804 | +$dbi->execute($create_table2); | |
| 3805 | +$dbi->insert(table => $table1, param => {$key1 => 1, $key2 => 2}); | |
| 3806 | +$dbi->insert(table => $table2, param => {$key1 => 1, $key3 => 4}); | |
| 3807 | +$dbi->insert(table => $table2, param => {$key1 => 1, $key3 => 5}); | |
| 3808 | +$result = $dbi->select( | |
| 3809 | + table => $table1, | |
| 3810 | + join => [ | |
| 3811 | + "left outer join $table2 on $table2.$key2 = '4' and $table1.$key1 = $table2.$key1" | |
| 3812 | + ] | |
| 3813 | +); | |
| 3814 | +is_deeply($result->all, [{$key1 => 1, $key2 => 2}]); | |
| 3815 | +$result = $dbi->select( | |
| 3816 | + table => $table1, | |
| 3817 | +    column => [{$table2 => [$key3]}], | |
| 3818 | + join => [ | |
| 3819 | + "left outer join $table2 on $table2.$key3 = '4' and $table1.$key1 = $table2.$key1" | |
| 3820 | + ] | |
| 3821 | +); | |
| 3822 | +is_deeply($result->all, [{"$table2.$key3" => 4}]); | |
| 3823 | +$result = $dbi->select( | |
| 3824 | + table => $table1, | |
| 3825 | +    column => [{$table2 => [$key3]}], | |
| 3826 | + join => [ | |
| 3827 | + "left outer join $table2 on $table1.$key1 = $table2.$key1 and $table2.$key3 = '4'" | |
| 3828 | + ] | |
| 3829 | +); | |
| 3830 | +is_deeply($result->all, [{"$table2.$key3" => 4}]); | |
| 3831 | + | |
| 3832 | +$dbi = DBIx::Custom->connect; | |
| 3833 | +eval { $dbi->execute("drop table $table1") }; | |
| 3834 | +eval { $dbi->execute("drop table $table2") }; | |
| 3835 | +$dbi->execute($create_table1); | |
| 3836 | +$dbi->execute($create_table2); | |
| 3837 | +$dbi->insert(table => $table1, param => {$key1 => 1, $key2 => 2}); | |
| 3838 | +$dbi->insert(table => $table2, param => {$key1 => 1, $key3 => 4}); | |
| 3839 | +$dbi->insert(table => $table2, param => {$key1 => 1, $key3 => 5}); | |
| 3840 | +$result = $dbi->select( | |
| 3841 | + table => $table1, | |
| 3842 | +    column => [{$table2 => [$key3]}], | |
| 3843 | + join => [ | |
| 3844 | +        { | |
| 3845 | + clause => "left outer join $table2 on $table2.$key3 = '4' and $table1.$key1 = $table2.$key1", | |
| 3846 | + table => [$table1, $table2] | |
| 3847 | + } | |
| 3848 | + ] | |
| 3849 | +); | |
| 3850 | +is_deeply($result->all, [{"$table2.$key3" => 4}]); | |
| 3851 | + | |
| 3852 | +test 'columns'; | |
| 3853 | +$dbi = MyDBI1->connect; | |
| 3854 | +$model = $dbi->model($table1); | |
| 3855 | + | |
| 3858 | 3856 |  | 
| 3859 | 3857 | 1; | 
| ... | ... | @@ -36,6 +36,18 @@ eval { | 
| 36 | 36 | }; | 
| 37 | 37 | ok(!$@); | 
| 38 | 38 |  | 
| 39 | +# Test memory leaks | |
| 40 | +for (1 .. 200) { | |
| 41 | + $dbi = DBIx::Custom->connect( | |
| 42 | + dsn => "dbi:mysql:database=$database;host=localhost;port=10000", | |
| 43 | + user => $user, | |
| 44 | + password => $password | |
| 45 | + ); | |
| 46 | + $dbi->query_builder; | |
| 47 | + $dbi->create_model(table => $table1); | |
| 48 | + $dbi->create_model(table => $table2); | |
| 49 | +} | |
| 50 | + | |
| 39 | 51 | test 'limit'; | 
| 40 | 52 | $dbi = DBIx::Custom->connect( | 
| 41 | 53 | dsn => "dbi:mysql:database=$database", |