From 19c6539b712e06428757b4128fb9464b8f6ff205 Mon Sep 17 00:00:00 2001 From: Marc Mims Date: Thu, 14 Sep 2017 16:33:56 -0700 Subject: [PATCH 1/2] Add failing test Fixtures dumps virtual columns which causes populate to fail because the column doesn't exist in the table. This failing test demonstrates the problem. --- dist.ini | 1 + t/20-virtual-column.t | 57 ++++++++++++++++++++++++ t/lib/DBICTest/Schema3.pm | 71 ++++++++++++++++++++++++++++++ t/var/configs/virtual-columns.json | 6 +++ 4 files changed, 135 insertions(+) create mode 100644 t/20-virtual-column.t create mode 100644 t/lib/DBICTest/Schema3.pm create mode 100644 t/var/configs/virtual-columns.json diff --git a/dist.ini b/dist.ini index 2d17c3e..22301fd 100644 --- a/dist.ini +++ b/dist.ini @@ -64,6 +64,7 @@ DBIx::Class::InflateColumn::FS = 0.01007 ExtUtils::MakeMaker = 6.59 Test::More = 0.98 Devel::Confess = 0 +Test::Fatal = 0 [Prereqs] Class::Accessor::Grouped = 0.1001 diff --git a/t/20-virtual-column.t b/t/20-virtual-column.t new file mode 100644 index 0000000..6d8de64 --- /dev/null +++ b/t/20-virtual-column.t @@ -0,0 +1,57 @@ +use DBIx::Class::Fixtures; +use Test::More; +use Test::Fatal; +use File::Path 'rmtree'; + +use lib qw(t/lib/DBICTest); +use Schema3; +use Test::TempDir::Tiny; +use IO::All; + +my $tempdir = tempdir; + +(my $schema = Schema3->connect( + 'DBI:SQLite::memory:','',''))->init_schema; + +ok my $row = $schema + ->resultset('Person') + ->first; + +ok $row->get_column('weight_to_height_ratio'), + 'has virtual column'; + +my $fixtures = DBIx::Class::Fixtures + ->new({ + config_dir => io->catfile(qw't var configs')->name, + debug => 0 }); + +ok( + $fixtures->dump({ + config => 'virtual-columns.json', + schema => $schema, + directory => io->catfile($tempdir, 'people')->name }), + 'fetch dump executed okay'); + +ok $schema->resultset('Person')->delete; + +is exception { + $fixtures->populate({ + no_deploy => 1, + schema => $schema, + directory => io->catfile($tempdir, 'people')->name + }) +}, undef, 'populated'; + +$row = $schema->resultset('Person')->first; + +BAIL_OUT("can't continue without data") unless $row; + +ok $row->get_column('weight_to_height_ratio'), + 'still has virtual column'; + +done_testing; + +END { + rmtree io->catfile(qw't var files')->name; + rmtree io->catfile($tempdir, 'people')->name; +} diff --git a/t/lib/DBICTest/Schema3.pm b/t/lib/DBICTest/Schema3.pm new file mode 100644 index 0000000..0150aa9 --- /dev/null +++ b/t/lib/DBICTest/Schema3.pm @@ -0,0 +1,71 @@ +package Schema3::Result::Person; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table('person'); + +__PACKAGE__->add_columns( + id => { + data_type => 'integer', + is_auto_increment => 1, + }, + name => { + data_type => 'varchar', + size => 255, + }, + weight => { + datatype => 'float', + }, + height => { + datatype => 'float', + }, +); + +__PACKAGE__->set_primary_key('id'); + +# Add virtual column +__PACKAGE__->resultset_attributes({ + '+select' => [ \'weight/height' ], + '+as' => [ 'weight_to_height_ratio' ], +}); + +package Schema3; + +use strict; +use warnings; + +use base 'DBIx::Class::Schema'; + +__PACKAGE__->register_class(Person => 'Schema3::Result::Person'); + +sub load_sql { + local $/ = undef; + my $sql = ; +} + +sub init_schema { + my $sql = (my $schema = shift) + ->load_sql; + + ($schema->storage->dbh->do($_) || + die "Error on SQL: $_\n") + for split(/;\n/, $sql); +} + +1; + +__DATA__ +CREATE TABLE person ( + id INTEGER PRIMARY KEY NOT NULL, + name varchar(255) NOT NULL, + weight FLOAT NOT NULL, + height FLOAT NOT NULL +); + +INSERT INTO person (name, weight, height) +VALUES +('Fred Flintstone', 220, 5.2), +('Barney Rubble', 190, 4.8) diff --git a/t/var/configs/virtual-columns.json b/t/var/configs/virtual-columns.json new file mode 100644 index 0000000..a7fd694 --- /dev/null +++ b/t/var/configs/virtual-columns.json @@ -0,0 +1,6 @@ +{ + "sets": [{ + "class": "Person", + "quantity": "all", + }] +} From 8b97485a1cd713f9984775497a43044158bd961e Mon Sep 17 00:00:00 2001 From: Marc Mims Date: Thu, 14 Sep 2017 16:58:54 -0700 Subject: [PATCH 2/2] Ignore virtual columns in dump_object Don't dump virtual columns since they don't exist in the table and populate will choke. --- Changes | 8 +++++--- lib/DBIx/Class/Fixtures.pm | 9 ++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Changes b/Changes index e4dc63e..e8a1478 100644 --- a/Changes +++ b/Changes @@ -2,6 +2,8 @@ Revision history for DBIx-Class-Fixtures {{$NEXT}} +- ignore virtual columns in dump_object + 1.001036 2016-03-21 14:59:55+00:00 UTC - releasing as stable @@ -102,7 +104,7 @@ Revision history for DBIx-Class-Fixtures 1.001013 - fixed functionality in last release by more deeply cloning parameters, which - prevents bad things when parameters get deleted in the wrong places. Also + prevents bad things when parameters get deleted in the wrong places. Also be sure we clear state properly after a dump. 1.001012 @@ -111,8 +113,8 @@ Revision history for DBIx-Class-Fixtures to make it easier when you need to dump all the fixtures programatically. - Added method 'dump_config_sets' to let you dump more than one set at a time more easily -- Added method 'dump_all_config_sets' which helps automate dumping all your - current config sets to a directory. +- Added method 'dump_all_config_sets' which helps automate dumping all your + current config sets to a directory. 1.001011 - Added an excludes resultsource option to the ->dump({all=>1,...}) feature diff --git a/lib/DBIx/Class/Fixtures.pm b/lib/DBIx/Class/Fixtures.pm index c979849..40e93cb 100644 --- a/lib/DBIx/Class/Fixtures.pm +++ b/lib/DBIx/Class/Fixtures.pm @@ -848,7 +848,14 @@ sub dump_object { # write file unless ($exists) { $self->msg('-- dumping ' . "$file", 2); - my %ds = $object->get_columns; + + # get_columns will return virtual columns; we just want stored columns. + # columns_info keys seems to be the actual storage column names, so we'll + # use that. + my $col_info = $src->columns_info; + my @column_names = keys %$col_info; + my %columns = $object->get_columns; + my %ds; @ds{@column_names} = @columns{@column_names}; if($set->{external}) { foreach my $field (keys %{$set->{external}}) {