X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FStorage%2FDBI.pm;h=f5794479d727e08e6d43c5f01806493547ec9fd3;hb=de705b510619176ba54e8addd4ff4f0d6c97ce61;hp=2a4d84ad08e665cd8ab7c6032eeaba3a551a9e11;hpb=8b445e337a0dbacf4ccb827211002f8d691ad671;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index 2a4d84a..f579447 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -1,15 +1,23 @@ package DBIx::Class::Storage::DBI; +use strict; +use warnings; use DBI; +use SQL::Abstract::Limit; +use DBIx::Class::Storage::DBI::Cursor; use base qw/DBIx::Class/; -__PACKAGE__->load_components(qw/SQL::Abstract SQL Exception AccessorGroup/); +__PACKAGE__->load_components(qw/Exception AccessorGroup/); -__PACKAGE__->mk_group_accessors('simple' => qw/connect_info _dbh/); +__PACKAGE__->mk_group_accessors('simple' => + qw/connect_info _dbh _sql_maker debug cursor/); sub new { - bless({}, ref $_[0] || $_[0]); + my $new = bless({}, ref $_[0] || $_[0]); + $new->cursor("DBIx::Class::Storage::DBI::Cursor"); + $new->debug(1) if $ENV{DBIX_CLASS_STORAGE_DBI_DEBUG}; + return $new; } sub get_simple { @@ -47,6 +55,14 @@ sub dbh { return $self->_dbh; } +sub sql_maker { + my ($self) = @_; + unless ($self->_sql_maker) { + $self->_sql_maker(new SQL::Abstract::Limit( limit_dialect => $self->dbh )); + } + return $self->_sql_maker; +} + sub _populate_dbh { my ($self) = @_; my @info = @{$self->connect_info || []}; @@ -78,54 +94,59 @@ Issues a rollback again the current dbh sub rollback { $_[0]->dbh->rollback; } +sub _execute { + my ($self, $op, $extra_bind, $ident, @args) = @_; + my ($sql, @bind) = $self->sql_maker->$op($ident, @args); + unshift(@bind, @$extra_bind) if $extra_bind; + warn "$sql: @bind" if $self->debug; + my $sth = $self->sth($sql); + @bind = map { ref $_ ? ''.$_ : $_ } @bind; # stringify args + my $rv = $sth->execute(@bind); + return (wantarray ? ($rv, $sth, @bind) : $rv); +} + sub insert { my ($self, $ident, $to_insert) = @_; - my $sql = $self->create_sql('insert', [ keys %{$to_insert} ], $ident, undef); - my $sth = $self->sth($sql); - $sth->execute(values %{$to_insert}); - $self->throw( "Couldn't insert ".join(%to_insert)." into ${ident}" ) - unless $sth->rows; + $self->throw( "Couldn't insert ".join(', ', map "$_ => $to_insert->{$_}", keys %$to_insert)." into ${ident}" ) + unless ($self->_execute('insert' => [], $ident, $to_insert) > 0); return $to_insert; } sub update { - my ($self, $ident, $to_update, $condition) = @_; - my $attrs = { }; - my $set_sql = $self->_cond_resolve($to_update, $attrs, ','); - $set_sql =~ s/^\(//; - $set_sql =~ s/\)$//; - my $cond_sql = $self->_cond_resolve($condition, $attrs); - my $sql = $self->create_sql('update', $set_sql, $ident, $cond_sql); - my $sth = $self->sth($sql); - my $rows = $sth->execute( @{$attrs->{bind}||[]} ); - return $rows; + return shift->_execute('update' => [], @_); } sub delete { - my ($self, $ident, $condition) = @_; - my $attrs = { }; - my $cond_sql = $self->_cond_resolve($condition, $attrs); - my $sql = $self->create_sql('delete', undef, $ident, $cond_sql); - #warn "$sql ".join(', ',@{$attrs->{bind}||[]}); - my $sth = $self->sth($sql); - return $sth->execute( @{$attrs->{bind}||[]} ); + return shift->_execute('delete' => [], @_); } -sub select { +sub _select { my ($self, $ident, $select, $condition, $attrs) = @_; - $attrs ||= { }; - #my $select_sql = $self->_cond_resolve($select, $attrs, ','); - my $cond_sql = $self->_cond_resolve($condition, $attrs); - 1 while $cond_sql =~ s/^\s*\(\s*(.*ORDER.*)\s*\)\s*$/$1/; - my $sql = $self->create_sql('select', $select, $ident, $cond_sql); - #warn $sql.' '.join(', ', @{$attrs->{bind}||[]}); - my $sth = $self->sth($sql); - if (@{$attrs->{bind}||[]}) { - $sth->execute( @{$attrs->{bind}||[]} ); + my $order = $attrs->{order_by}; + if (ref $condition eq 'SCALAR') { + $order = $1 if $$condition =~ s/ORDER BY (.*)$//i; + } + $ident = $self->_build_from($ident) if ref $ident; + my @args = ('select', $attrs->{bind}, $ident, $select, $condition, $order); + if ($self->sql_maker->_default_limit_syntax eq "GenericSubQ") { + $attrs->{software_limit} = 1; } else { - $sth->execute; + push @args, $attrs->{rows}, $attrs->{offset}; } - return $sth; + return $self->_execute(@args); +} + +sub select { + my $self = shift; + my ($ident, $select, $condition, $attrs) = @_; + my ($rv, $sth, @bind) = $self->_select(@_); + return $self->cursor->new($sth, \@bind, $attrs); +} + +sub select_single { + my $self = shift; + my ($rv, $sth, @bind) = $self->_select(@_); + return $sth->fetchrow_array; } sub sth { @@ -138,7 +159,9 @@ sub sth { =head1 AUTHORS -Matt S. Trout +Matt S. Trout + +Andy Grundman =head1 LICENSE