.'( '.$self->_recurse_fields($fields->{$func}).' )';
}
}
+ # Is the second check absolutely necessary?
+ elsif ( $ref eq 'REF' and ref($$fields) eq 'ARRAY' ) {
+ return $self->_bind_to_sql( $fields );
+ }
+ else {
+ Carp::croak($ref . qq{ unexpected in _recurse_fields()})
+ }
}
sub _order_by {
return join('', @sqlf);
}
+sub _bind_to_sql {
+ my $self = shift;
+ my $arr = shift;
+ my $sql = shift @$$arr;
+ $sql =~ s/\?/$self->_quote((shift @$$arr)->[1])/eg;
+ return $sql
+}
+
sub _make_as {
my ($self, $from) = @_;
- return join(' ', map { (ref $_ eq 'SCALAR' ? $$_ : $self->_quote($_)) }
- reverse each %{$self->_skip_options($from)});
+ return join(' ', map { (ref $_ eq 'SCALAR' ? $$_
+ : ref $_ eq 'REF' ? $self->_bind_to_sql($_)
+ : $self->_quote($_))
+ } reverse each %{$self->_skip_options($from)});
}
sub _skip_options {
sub _dbh_execute {
my ($self, $dbh, $op, $extra_bind, $ident, $bind_attributes, @args) = @_;
-
+
my ($sql, $bind) = $self->_prep_for_execute($op, $extra_bind, $ident, \@args);
$self->_query_start( $sql, @$bind );
my $ident = $source->from;
my $bind_attributes = $self->source_bind_attributes($source);
+ my $updated_cols = {};
+
$self->ensure_connected;
foreach my $col ( $source->columns ) {
if ( !defined $to_insert->{$col} ) {
my $col_info = $source->column_info($col);
if ( $col_info->{auto_nextval} ) {
- $to_insert->{$col} = $self->_sequence_fetch( 'nextval', $col_info->{sequence} || $self->_dbh_get_autoinc_seq($self->dbh, $source) );
+ $updated_cols->{$col} = $to_insert->{$col} = $self->_sequence_fetch( 'nextval', $col_info->{sequence} || $self->_dbh_get_autoinc_seq($self->dbh, $source) );
}
}
}
$self->_execute('insert' => [], $source, $bind_attributes, $to_insert);
- return $to_insert;
+ return $updated_cols;
}
## Still not quite perfect, and EXPERIMENTAL
my ($self, $ident, $select, $condition, $attrs) = @_;
my $order = $attrs->{order_by};
- if (ref $condition eq 'SCALAR') {
- my $unwrap = ${$condition};
- if ($unwrap =~ s/ORDER BY (.*)$//i) {
- $order = $1;
- $condition = \$unwrap;
- }
- }
-
my $for = delete $attrs->{for};
my $sql_maker = $self->sql_maker;
- local $sql_maker->{for} = $for;
+ $sql_maker->{for} = $for;
if (exists $attrs->{group_by} || $attrs->{having}) {
$order = {
$attrs->{rows} = 2**48 if not defined $attrs->{rows} and defined $attrs->{offset};
push @args, $attrs->{rows}, $attrs->{offset};
}
-
return @args;
}
=cut
sub _dbh_last_insert_id {
- my ($self, $dbh, $source, $col) = @_;
- # XXX This is a SQLite-ism as a default... is there a DBI-generic way?
- $dbh->func('last_insert_rowid');
+ # All Storage's need to register their own _dbh_last_insert_id
+ # the old SQLite-based method was highly inappropriate
+
+ my $self = shift;
+ my $class = ref $self;
+ $self->throw_exception (<<EOE);
+
+No _dbh_last_insert_id() method found in $class.
+Since the method of obtaining the autoincrement id of the last insert
+operation varies greatly between different databases, this method must be
+individually implemented for every storage class.
+EOE
}
sub last_insert_id {
foreach my $db (@$databases) {
$sqlt->reset();
- $sqlt = $self->configure_sqlt($sqlt, $db);
$sqlt->{schema} = $sqlt_schema;
$sqlt->producer($db);
$t->debug( 0 );
$t->trace( 0 );
$t->parser( $db ) or die $t->error;
- $t = $self->configure_sqlt($t, $db);
my $out = $t->translate( $prefilename ) or die $t->error;
$source_schema = $t->schema;
unless ( $source_schema->name ) {
$t->debug( 0 );
$t->trace( 0 );
$t->parser( $db ) or die $t->error;
- $t = $self->configure_sqlt($t, $db);
my $out = $t->translate( $filename ) or die $t->error;
$dest_schema = $t->schema;
$dest_schema->name( $filename )
}
}
-sub configure_sqlt() {
- my $self = shift;
- my $tr = shift;
- my $db = shift || $self->sqlt_type;
- if ($db eq 'PostgreSQL') {
- $tr->quote_table_names(0);
- $tr->quote_field_names(0);
- }
- return $tr;
-}
-
=head2 deployment_statements
=over 4
$type ||= $self->sqlt_type;
$version ||= $schema->schema_version || '1.x';
$dir ||= './';
- my $filename = $schema->ddl_filename($type, $dir, $version);
+ my $filename = $schema->ddl_filename($type, $version, $dir);
if(-f $filename)
{
my $file;