my $orig = __PACKAGE__->can ($meth)
or die "$meth is not a ::Storage::DBI method!";
- my $is_getter = $storage_accessor_idx->{$meth} ? 0 : 1;
+ my $possibly_a_setter = $storage_accessor_idx->{$meth} ? 1 : 0;
quote_sub
- __PACKAGE__ ."::$meth", sprintf( <<'EOC', $is_getter, perlstring $meth ), { '$orig' => \$orig };
+ __PACKAGE__ ."::$meth", sprintf( <<'EOC', $possibly_a_setter, perlstring $meth ), { '$orig' => \$orig };
if (
+ # if this is an actual *setter* - just set it, no need to connect
+ # and determine the driver
+ !( %1$s and @_ > 1 )
+ and
# only fire when invoked on an instance, a valid class-based invocation
# would e.g. be setting a default for an inherited accessor
ref $_[0]
and
! $_[0]->{_in_determine_driver}
and
- # if this is a known *setter* - just set it, no need to connect
- # and determine the driver
- ( %1$s or @_ <= 1 )
- and
# Only try to determine stuff if we have *something* that either is or can
# provide a DSN. Allows for bare $schema's generated with a plain ->connect()
# to still be marginally useful
sub _determine_connector_driver {
my ($self, $conn) = @_;
- my $dbtype = $self->_dbh_get_info('SQL_DBMS_NAME');
+ my $dbtype = $self->_get_rdbms_name;
if (not $dbtype) {
$self->_warn_undetermined_driver(
}
}
+sub _get_rdbms_name { shift->_dbh_get_info('SQL_DBMS_NAME') }
+
sub _warn_undetermined_driver {
my ($self, $msg) = @_;
};
return [ map {
- my $resolved =
( ref $_ ne 'ARRAY' or @$_ != 2 ) ? [ {}, $_ ]
: ( ! defined $_->[0] ) ? [ {}, $_->[1] ]
: (ref $_->[0] eq 'HASH') ? [(
: [ $resolve_bindinfo->(
{ dbic_colname => $_->[0] }
), $_->[1] ]
- ;
-
- if (
- ! exists $resolved->[0]{dbd_attrs}
- and
- ! $resolved->[0]{sqlt_datatype}
- and
- length ref $resolved->[1]
- and
- ! is_plain_value $resolved->[1]
- ) {
- require Data::Dumper;
- local $Data::Dumper::Maxdepth = 1;
- local $Data::Dumper::Terse = 1;
- local $Data::Dumper::Useqq = 1;
- local $Data::Dumper::Indent = 0;
- local $Data::Dumper::Pad = ' ';
- $self->throw_exception(
- 'You must supply a datatype/bindtype (see DBIx::Class::ResultSet/DBIC BIND VALUES) '
- . 'for non-scalar value '. Data::Dumper::Dumper ($resolved->[1])
- );
- }
-
- $resolved;
-
} @$bind ];
}
my %returned_cols = %$to_insert;
if (my $retlist = $sqla_opts->{returning}) { # if IR is supported - we will get everything in one set
- @ir_container = try {
- local $SIG{__WARN__} = sub {};
- my @r = $sth->fetchrow_array;
- $sth->finish;
- @r;
- } unless @ir_container;
+
+ unless( @ir_container ) {
+ try {
+
+ # FIXME - need to investigate why Caelum silenced this in 4d4dc518
+ local $SIG{__WARN__} = sub {};
+
+ @ir_container = $sth->fetchrow_array;
+ $sth->finish;
+
+ } catch {
+ # Evict the $sth from the cache in case we got here, since the finish()
+ # is crucial, at least on older Firebirds, possibly on other engines too
+ #
+ # It would be too complex to make this a proper subclass override,
+ # and besides we already take the try{} penalty, adding a catch that
+ # triggers infrequently is a no-brainer
+ #
+ if( my $kids = $self->_dbh->{CachedKids} ) {
+ $kids->{$_} == $sth and delete $kids->{$_}
+ for keys %$kids
+ }
+ };
+ }
@returned_cols{@$retlist} = @ir_container if @ir_container;
}
# FIXME SUBOPTIMAL - DBI needs fixing to always stringify regardless of DBD
# For the time being forcibly stringify whatever is stringifiable
- (length ref $v and is_plain_value $v)
- ? "$v"
- : $v
- ;
+ my $vref;
+
+ ( !length ref $v or ! ($vref = is_plain_value $v) ) ? $v
+ : defined blessed( $$vref ) ? "$$vref"
+ : $$vref
+ ;
} map { $_->[0] } @$proto_bind ];
};
where => $where,
};
- # Sanity check the attributes (SQLMaker does it too, but
- # in case of a software_limit we'll never reach there)
- if (defined $attrs->{offset}) {
- $self->throw_exception('A supplied offset attribute must be a non-negative integer')
- if ( $attrs->{offset} =~ /\D/ or $attrs->{offset} < 0 );
- }
-
- if (defined $attrs->{rows}) {
- $self->throw_exception("The rows attribute must be a positive integer if present")
- if ( $attrs->{rows} =~ /\D/ or $attrs->{rows} <= 0 );
- }
- elsif ($attrs->{offset}) {
- # MySQL actually recommends this approach. I cringe.
- $attrs->{rows} = $sql_maker->__max_int;
- }
+ # MySQL actually recommends this approach. I cringe.
+ $attrs->{rows} ||= $sql_maker->__max_int
+ if $attrs->{offset};
# see if we will need to tear the prefetch apart to satisfy group_by == select
# this is *extremely tricky* to get right, I am still not sure I did