my ($self, $table, $fields, $where, $order, @rest) = @_;
$table = $self->_quote($table) unless ref($table);
@rest = (-1) unless defined $rest[0];
+ die "LIMIT 0 Does Not Compute" if $rest[0] == 0;
+ # and anyway, SQL::Abstract::Limit will cause a barf if we don't first
local $self->{having_bind} = [];
my ($sql, @ret) = $self->SUPER::select(
$table, $self->_recurse_fields($fields), $where, $order, @rest
Executes the sql statements given as a listref on every db connect.
+=head2 quote_char
+
+Specifies what characters to use to quote table and column names. If
+you use this you will want to specify L<name_sep> as well.
+
+quote_char expectes either a single character, in which case is it is placed
+on either side of the table/column, or an array of length 2 in which case the
+table/column name is placed between the elements.
+
+For example under MySQL you'd use C<quote_char('`')>, and user SQL Server you'd
+use C<quote_char(qw/[ ]/)>.
+
+=head2 name_sep
+
+This only needs to be used in conjunction with L<quote_char>, and is used to
+specify the charecter that seperates elements (schemas, tables, columns) from
+each other. In most cases this is simply a C<.>.
+
=head2 debug
Causes SQL trace information to be emitted on C<debugfh> filehandle
}
}
+=head2 dbh
+
+Returns the dbh - a data base handle of class L<DBI>.
+
+=cut
+
sub dbh {
my ($self) = @_;
sub txn_begin {
my $self = shift;
- $self->dbh->begin_work
- if $self->{transaction_depth}++ == 0 and $self->dbh->{AutoCommit};
+ if ($self->{transaction_depth}++ == 0) {
+ my $dbh = $self->dbh;
+ if ($dbh->{AutoCommit}) {
+ $self->debugfh->print("BEGIN WORK\n")
+ if ($self->debug);
+ $dbh->begin_work;
+ }
+ }
}
=head2 txn_commit
sub txn_commit {
my $self = shift;
+ my $dbh = $self->dbh;
if ($self->{transaction_depth} == 0) {
- $self->dbh->commit unless $self->dbh->{AutoCommit};
+ unless ($dbh->{AutoCommit}) {
+ $self->debugfh->print("COMMIT\n")
+ if ($self->debug);
+ $dbh->commit;
+ }
}
else {
- $self->dbh->commit if --$self->{transaction_depth} == 0;
+ if (--$self->{transaction_depth} == 0) {
+ $self->debugfh->print("COMMIT\n")
+ if ($self->debug);
+ $dbh->commit;
+ }
}
}
my $self = shift;
eval {
+ my $dbh = $self->dbh;
if ($self->{transaction_depth} == 0) {
- $self->dbh->rollback unless $self->dbh->{AutoCommit};
+ unless ($dbh->{AutoCommit}) {
+ $self->debugfh->print("ROLLBACK\n")
+ if ($self->debug);
+ $dbh->rollback;
+ }
}
else {
- --$self->{transaction_depth} == 0 ?
- $self->dbh->rollback :
+ if (--$self->{transaction_depth} == 0) {
+ $self->debugfh->print("ROLLBACK\n")
+ if ($self->debug);
+ $dbh->rollback;
+ }
+ else {
die DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION->new;
+ }
}
};
my ($sql, @bind) = $self->sql_maker->$op($ident, @args);
unshift(@bind, @$extra_bind) if $extra_bind;
if ($self->debug) {
- my @debug_bind = map { defined $_ ? qq{`$_'} : q{`NULL'} } @bind;
- $self->debugfh->print("$sql: " . join(', ', @debug_bind) . "\n");
+ my $bind_str = join(', ', map {
+ defined $_ ? qq{`$_'} : q{`NULL'}
+ } @bind);
+ $self->debugfh->print("$sql ($bind_str)\n");
}
my $sth = eval { $self->sth($sql,$op) };
if (!$sth || $@) {
- $self->throw_exception('no sth generated via sql (' . ($@ || $self->_dbh->errstr) . "): $sql");
+ $self->throw_exception(
+ 'no sth generated via sql (' . ($@ || $self->_dbh->errstr) . "): $sql"
+ );
}
-
@bind = map { ref $_ ? ''.$_ : $_ } @bind; # stringify args
- my $rv;
- if ($sth) {
- $rv = eval { $sth->execute(@bind) };
-
- if ($@ || !$rv) {
- $self->throw_exception("Error executing '$sql': ".($@ || $sth->errstr));
- }
- } else {
- $self->throw_exception("'$sql' did not generate a statement.");
+ my $rv = eval { $sth->execute(@bind) };
+ if ($@ || !$rv) {
+ my $bind_str = join(', ', map {
+ defined $_ ? qq{`$_'} : q{`NULL'}
+ } @bind);
+ $self->throw_exception(
+ "Error executing '$sql' ($bind_str): ".($@ || $sth->errstr)
+ );
}
return (wantarray ? ($rv, $sth, @bind) : $rv);
}
$self->sql_maker->_default_limit_syntax eq "GenericSubQ") {
$attrs->{software_limit} = 1;
} else {
+ $self->throw_exception("rows attribute must be positive if present")
+ if (defined($attrs->{rows}) && !($attrs->{rows} > 0));
push @args, $attrs->{rows}, $attrs->{offset};
}
return $self->_execute(@args);
sub columns_info_for {
my ($self, $table) = @_;
- if ($self->dbh->can('column_info')) {
+ my $dbh = $self->dbh;
+
+ if ($dbh->can('column_info')) {
my %result;
- my $old_raise_err = $self->dbh->{RaiseError};
- my $old_print_err = $self->dbh->{PrintError};
- $self->dbh->{RaiseError} = 1;
- $self->dbh->{PrintError} = 0;
+ my $old_raise_err = $dbh->{RaiseError};
+ my $old_print_err = $dbh->{PrintError};
+ $dbh->{RaiseError} = 1;
+ $dbh->{PrintError} = 0;
eval {
- my $sth = $self->dbh->column_info( undef, undef, $table, '%' );
+ my $sth = $dbh->column_info( undef, undef, $table, '%' );
$sth->execute();
while ( my $info = $sth->fetchrow_hashref() ){
my %column_info;
$result{$info->{COLUMN_NAME}} = \%column_info;
}
};
- $self->dbh->{RaiseError} = $old_raise_err;
- $self->dbh->{PrintError} = $old_print_err;
+ $dbh->{RaiseError} = $old_raise_err;
+ $dbh->{PrintError} = $old_print_err;
return \%result if !$@;
}
my %result;
- my $sth = $self->dbh->prepare("SELECT * FROM $table WHERE 1=0");
+ my $sth = $dbh->prepare("SELECT * FROM $table WHERE 1=0");
$sth->execute;
my @columns = @{$sth->{NAME_lc}};
for my $i ( 0 .. $#columns ){
my %column_info;
my $type_num = $sth->{TYPE}->[$i];
my $type_name;
- if(defined $type_num && $self->dbh->can('type_info')) {
- my $type_info = $self->dbh->type_info($type_num);
+ if(defined $type_num && $dbh->can('type_info')) {
+ my $type_info = $dbh->type_info($type_num);
$type_name = $type_info->{TYPE_NAME} if $type_info;
}
$column_info{data_type} = $type_name ? $type_name : $type_num;
If the value is of the form C<1=/path/name> then the trace output is
written to the file C</path/name>.
+This environment variable is checked when the storage object is first
+created (when you call connect on your schema). So, run-time changes
+to this environment variable will not take effect unless you also
+re-connect on your schema.
+
=head1 AUTHORS
Matt S. Trout <mst@shadowcatsystems.co.uk>