DBIx-Class-Fixtures
view release on metacpan or search on metacpan
lib/DBIx/Class/Fixtures.pm view on Meta::CPAN
my ( $self, $v ) = @_;
if (! defined($ENV{$v})) {
return "";
} else {
return $ENV{ $v };
}
},
ATTR => sub {
my ($self, $v) = @_;
if(my $attr = $self->config_attrs->{$v}) {
return $attr;
} else {
return "";
}
},
catfile => sub {
my ($self, @args) = @_;
io->catfile(@args);
},
catdir => sub {
my ($self, @args) = @_;
io->catdir(@args);
},
};
my $subsre = join( '|', keys %$subs );
$_ =~ s{__($subsre)(?:\((.+?)\))?__}{ $subs->{ $1 }->( $self, $2 ? split( /,/, $2 ) : () ) }eg;
return $_;
}
);
$v->visit( $config_set );
my %sets_by_src;
if($config_set) {
%sets_by_src = map { delete($_->{class}) => $_ }
@{$config_set->{sets}}
}
if (-e "$tmp_fixture_dir") {
$self->msg("- deleting existing temp directory $tmp_fixture_dir");
$tmp_fixture_dir->rmtree;
}
$self->msg("- creating temp dir");
$tmp_fixture_dir->mkpath();
for ( map { $self->_name_for_source($schema->source($_)) } $schema->sources) {
my $from_dir = io->catdir($fixture_dir, $_);
next unless -e "$from_dir";
$from_dir->copy( io->catdir($tmp_fixture_dir, $_)."" );
}
unless (-d "$tmp_fixture_dir") {
DBIx::Class::Exception->throw("Unable to create temporary fixtures dir: $tmp_fixture_dir: $!");
}
my $fixup_visitor;
my $formatter = $schema->storage->datetime_parser;
unless ($@ || !$formatter) {
my %callbacks;
if ($params->{datetime_relative_to}) {
$callbacks{'DateTime::Duration'} = sub {
$params->{datetime_relative_to}->clone->add_duration($_);
};
} else {
$callbacks{'DateTime::Duration'} = sub {
$formatter->format_datetime(DateTime->today->add_duration($_))
};
}
$callbacks{object} ||= "visit_ref";
$fixup_visitor = new Data::Visitor::Callback(%callbacks);
}
my @sorted_source_names = $self->_get_sorted_sources( $schema );
$schema->storage->txn_do(sub {
$schema->storage->with_deferred_fk_checks(sub {
foreach my $source (@sorted_source_names) {
$self->msg("- adding " . $source);
my $rs = $schema->resultset($source);
my $source_dir = io->catdir($tmp_fixture_dir, $self->_name_for_source($rs->result_source));
next unless (-e "$source_dir");
my @rows;
while (my $file = $source_dir->next) {
next unless ($file =~ /\.fix$/);
next if $file->is_dir;
my $contents = $file->slurp;
my $HASH1;
eval($contents);
$HASH1 = $fixup_visitor->visit($HASH1) if $fixup_visitor;
if(my $external = delete $HASH1->{external}) {
my @fields = keys %{$sets_by_src{$source}->{external}};
foreach my $field(@fields) {
my $key = $HASH1->{$field};
my $content = decode_base64 ($external->{$field});
my $args = $sets_by_src{$source}->{external}->{$field}->{args};
my ($plus, $class) = ( $sets_by_src{$source}->{external}->{$field}->{class}=~/^(\+)*(.+)$/);
$class = "DBIx::Class::Fixtures::External::$class" unless $plus;
eval "use $class";
$class->restore($key, $content, $args);
}
}
if ( $params->{use_create} ) {
$rs->create( $HASH1 );
} elsif( $params->{use_find_or_create} ) {
$rs->find_or_create( $HASH1 );
} else {
push(@rows, $HASH1);
}
}
$rs->populate(\@rows) if scalar(@rows);
## Now we need to do some db specific cleanup
## this probably belongs in a more isolated space. Right now this is
## to just handle postgresql SERIAL types that use Sequences
## Will completely ignore sequences in Oracle due to having to drop
## and recreate them
my $table = $rs->result_source->name;
for my $column(my @columns = $rs->result_source->columns) {
my $info = $rs->result_source->column_info($column);
if(my $sequence = $info->{sequence}) {
$self->msg("- updating sequence $sequence");
$rs->result_source->storage->dbh_do(sub {
my ($storage, $dbh, @cols) = @_;
if ( $dbh->{Driver}->{Name} eq "Oracle" ) {
$self->msg("- Cannot change sequence values in Oracle");
} else {
$self->msg(
my $sql = sprintf("SELECT setval(?, (SELECT max(%s) FROM %s));",$dbh->quote_identifier($column),$dbh->quote_identifier($table))
);
my $sth = $dbh->prepare($sql);
( run in 2.158 seconds using v1.01-cache-2.11-cpan-302cb4679cc )