Rose-DB-Object
view release on metacpan or search on metacpan
t/save-cascade.t view on Meta::CPAN
BEGIN
{
require 't/test-lib.pl';
use_ok('Rose::DB::Object::Loader');
}
our %Have;
#
# Tests
#
#$Rose::DB::Object::Manager::Debug = 1;
foreach my $db_type (qw(mysql pg informix sqlite))
{
SKIP:
{
skip("$db_type tests", 22) unless($Have{$db_type});
}
next unless($Have{$db_type});
Rose::DB::Object::Metadata->unregister_all_classes;
Rose::DB->default_type($db_type);
my $class_prefix = ucfirst($db_type);
my $loader =
Rose::DB::Object::Loader->new(
db => Rose::DB->new,
class_prefix => $class_prefix);
my @classes = $loader->make_classes(include_tables =>
'^(?:products|prices|colors|vendors|product_colors)$');
#foreach my $class (@classes)
#{
# print $class->meta->perl_class_definition if($class->can('meta'));
#}
my $product_class = $class_prefix . '::Product';
my $vendor_class = $class_prefix . '::Vendor';
my $price_class = $class_prefix . '::Price';
my $color_class = $class_prefix . '::Color';
foreach my $i (0, 1)
{
$product_class->meta->default_update_changes_only($i);
$product_class->meta->default_insert_changes_only($i);
# Foreign key
my $p = $product_class->new(name => 'p1', vendor => { name => 'v1' });
$p->save;
$p = $product_class->new(id => $p->id)->load;
my $v = $p->vendor;
$v->name('v1.1');
$p->save(cascade => 1);
$v = $vendor_class->new(id => $v->id)->load;
is($v->name, 'v1.1', "cascade fk 1.$i - $db_type");
# One-to-many
$p->prices([ { price => 1.25 } ]);
$p->save;
$p = $product_class->new(id => $p->id)->load;
my $price = $p->prices->[0];
is($price->price, 1.25, "cascade one-to-many 1.$i - $db_type");
is($price->region, 'US', "cascade one-to-many 2.$i - $db_type");
$price->region('UK');
$p->add_prices({ price => 4.25 });
$p->save(cascade => 1);
$price = $price_class->new(price_id => $price->price_id)->load;
is($price->region, 'UK', "cascade one-to-many 3.$i - $db_type");
$price = (sort { $a->price <=> $b->price } @{$p->prices})[-1];
is($price->price, 4.25, "cascade one-to-many 4.$i - $db_type");
is($price->region, 'US', "cascade one-to-many 5.$i - $db_type");
# Many-to-many
$p->colors([ { code => 'f00', name => 'red' } ]);
$p->save;
$p = $product_class->new(id => $p->id)->load;
my $color = $p->colors->[0];
is($color->code, 'f00', "cascade many-to-many 1.$i - $db_type");
is($color->name, 'red', "cascade many-to-many 2.$i - $db_type");
$color->name('r3d');
$p->add_colors({ code => '0f0', name => 'green' });
$p->save(cascade => 1);
$color = $color_class->new(code => $color->code)->load;
is($color->name, 'r3d', "cascade many-to-many 3.$i - $db_type");
$color = (sort { $a->name cmp $b->name } @{$p->colors})[0];
is($color->code, '0f0', "cascade many-to-many 4.$i - $db_type");
is($color->name, 'green', "cascade many-to-many 5.$i - $db_type");
$p->dbh->do('DELETE FROM product_colors');
$p->dbh->do('DELETE FROM colors');
$p->dbh->do('DELETE FROM prices');
$p->dbh->do('DELETE FROM products');
$p->dbh->do('DELETE FROM vendors');
}
}
BEGIN
{
our %Have;
#
# PostgreSQL
#
my $dbh;
eval
{
$dbh = Rose::DB->new('pg_admin')->retain_dbh()
or die Rose::DB->error;
};
if(!$@ && $dbh)
{
$Have{'pg'} = 1;
$Have{'pg_with_schema'} = 1;
# Drop existing tables and create schema, ignoring errors
{
local $dbh->{'RaiseError'} = 0;
local $dbh->{'PrintError'} = 0;
$dbh->do('DROP TABLE product_colors CASCADE');
$dbh->do('DROP TABLE prices CASCADE');
$dbh->do('DROP TABLE products CASCADE');
$dbh->do('DROP TABLE colors CASCADE');
$dbh->do('DROP TABLE vendors CASCADE');
}
$dbh->do(<<"EOF");
CREATE TABLE vendors
(
id SERIAL PRIMARY KEY,
name VARCHAR(255)
)
EOF
$dbh->do(<<"EOF");
CREATE TABLE colors
(
code CHAR(3) NOT NULL PRIMARY KEY,
name VARCHAR(255)
)
EOF
$dbh->do(<<"EOF");
CREATE TABLE products
( run in 1.167 second using v1.01-cache-2.11-cpan-39bf76dae61 )