DBIx-QuickORM
view release on metacpan or search on metacpan
t/AI/row_state.t view on Meta::CPAN
use Test2::V0;
use DBI;
use File::Temp qw/tempdir/;
# Exercises the row state model documented in DBIx::QuickORM::Row,
# DBIx::QuickORM::Role::Row, and DBIx::QuickORM::Connection::RowData:
# stored vs pending vs inflated/raw views, save/discard/update/refresh,
# delete, the storage/validity predicates, the field-hash views, clone,
# and the primary-key helpers.
BEGIN {
skip_all "DBD::SQLite is required for these tests"
unless eval { require DBD::SQLite; 1 };
}
require DBIx::QuickORM;
my $dir = tempdir(CLEANUP => 1);
my $file = "$dir/row_state.sqlite";
my $dsn = "dbi:SQLite:dbname=$file";
{
my $dbh = DBI->connect($dsn, '', '', {RaiseError => 1, PrintError => 0});
$dbh->do('CREATE TABLE users (user_id INTEGER PRIMARY KEY, name TEXT NOT NULL, email TEXT, meta_json TEXT)');
$dbh->do('INSERT INTO users (name, email, meta_json) VALUES (?, ?, ?)', undef, 'bob', 'bob@example.com', '{"age":42}');
$dbh->disconnect;
}
# Read a column straight from the database, bypassing the ORM and any
# row cache, so we can verify what was actually persisted.
sub db_value {
my ($col, $pk) = @_;
my $dbh = DBI->connect($dsn, '', '', {RaiseError => 1, PrintError => 0});
my ($val) = $dbh->selectrow_array("SELECT $col FROM users WHERE user_id = ?", undef, $pk);
$dbh->disconnect;
return $val;
}
my $con = DBIx::QuickORM->quick(credentials => {dsn => $dsn}, auto_types => ['JSON']);
isa_ok($con, ['DBIx::QuickORM::Connection'], "got a live Connection");
my $bob = $con->handle('users')->where({name => 'bob'})->one;
my $bob_pk = $bob->field('user_id');
ok(defined($bob_pk), "fetched bob and have a primary key");
subtest field_get_set_and_pending => sub {
ok($bob->is_stored, "freshly fetched row is stored");
ok($bob->in_storage, "freshly fetched row is in_storage");
ok($bob->is_valid, "freshly fetched row is valid");
ok(!$bob->is_invalid, "freshly fetched row is not invalid");
ok(!$bob->has_pending, "no pending changes after fetch");
is($bob->field('name'), 'bob', "field() returns the stored value");
$bob->field(name => 'robert');
ok($bob->has_pending, "setting a field stages a pending change");
is($bob->field('name'), 'robert', "field() reflects the pending value");
is($bob->stored_field('name'), 'bob', "stored_field() still shows the original db value");
# Database is untouched until save.
is(db_value(name => $bob_pk), 'bob', "database row unchanged before save");
$bob->save;
ok(!$bob->has_pending, "save() clears pending");
is($bob->field('name'), 'robert', "value persists in the row after save");
is(db_value(name => $bob_pk), 'robert', "save() wrote the change to the database");
# Reset for later subtests.
$bob->update({name => 'bob'});
is(db_value(name => $bob_pk), 'bob', "reset name back to bob");
};
subtest modify_now_save_later => sub {
$bob->field(name => 'robert');
$bob->field(email => 'r@example.com');
ok($bob->has_pending, "multiple staged changes are pending together");
is($bob->field('name'), 'robert', "first pending change visible");
is($bob->field('email'), 'r@example.com', "second pending change visible");
is($bob->stored_field('name'), 'bob', "stored name unchanged while pending");
is($bob->stored_field('email'), 'bob@example.com', "stored email unchanged while pending");
is(db_value(name => $bob_pk), 'bob', "db name unchanged while pending");
is(db_value(email => $bob_pk), 'bob@example.com', "db email unchanged while pending");
$bob->save;
is(db_value(name => $bob_pk), 'robert', "both changes saved together (name)");
is(db_value(email => $bob_pk), 'r@example.com', "both changes saved together (email)");
$bob->update({name => 'bob', email => 'bob@example.com'});
};
subtest inflated_vs_raw_vs_stored => sub {
is($bob->field('meta_json'), {age => 42}, "field() inflates JSON to a ref");
is($bob->raw_field('meta_json'), '{"age":42}', "raw_field() returns the raw db string");
$bob->field(meta_json => {age => 43});
is($bob->field('meta_json'), {age => 43}, "pending inflated value");
is($bob->pending_field('meta_json'), {age => 43}, "pending_field() shows pending value");
is($bob->stored_field('meta_json'), {age => 42}, "stored_field() inflates the original");
is($bob->raw_stored_field('meta_json'), '{"age":42}', "raw_stored_field() shows original raw db value");
( run in 0.521 second using v1.01-cache-2.11-cpan-5b529ec07f3 )