From: Matt S Trout Date: Mon, 16 Apr 2012 03:46:07 +0000 (+0000) Subject: further steps towards conversion X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=9cb4ec4f186df6697ca67ed508a8d24c277a236f;p=dbsrgits%2FDBIx-Class-Historic.git further steps towards conversion --- diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 88409b0..c16b278 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -250,6 +250,16 @@ sub new { $self; } +sub _sqla_converter { shift->result_source->storage->sql_maker->converter } + +sub _order_by_dq { + my ($self) = @_; + if (my $o = $self->_resolved_attrs->{order_by}) { + return $self->_sqla_converter->_order_by_to_dq($o); + } + return undef; +} + =head2 search =over 4 diff --git a/lib/DBIx/Class/ResultSetColumn.pm b/lib/DBIx/Class/ResultSetColumn.pm index 8a92b2f..8979ef9 100644 --- a/lib/DBIx/Class/ResultSetColumn.pm +++ b/lib/DBIx/Class/ResultSetColumn.pm @@ -7,6 +7,8 @@ use base 'DBIx::Class'; use DBIx::Class::Carp; use DBIx::Class::Exception; +use Data::Query::Constants qw(DQ_IDENTIFIER); + # not importing first() as it will clash with our own method use List::Util (); @@ -72,11 +74,22 @@ sub new { # analyze the order_by, and see if it is done over a function/nonexistentcolumn # if this is the case we will need to wrap a subquery since the result of RSC # *must* be a single column select - if ( - scalar grep - { ! exists $colmap->{$_->[0]} } - ( $rsrc->schema->storage->_extract_order_criteria ($orig_attrs->{order_by} ) ) - ) { + + my $order_dq = $rs->_order_by_dq; + my $weirditude; + + ORDER_DQ: while ($order_dq) { + if ($order_dq->{by}{type} eq DQ_IDENTIFIER) { + if (exists $colmap->{join '.', @{$order_dq->{by}{elements}}}) { + $order_dq = $order_dq->{from}; + next ORDER_DQ; + } + } + $weirditude = 1; + last ORDER_DQ; + } + + if ($weirditude) { # nuke the prefetch before collapsing to sql my $subq_rs = $rs->search; $subq_rs->{attrs}{join} = $subq_rs->_merge_joinpref_attr( $subq_rs->{attrs}{join}, delete $subq_rs->{attrs}{prefetch} ); diff --git a/lib/DBIx/Class/SQLMaker.pm b/lib/DBIx/Class/SQLMaker.pm index 5855753..c418a3e 100644 --- a/lib/DBIx/Class/SQLMaker.pm +++ b/lib/DBIx/Class/SQLMaker.pm @@ -129,44 +129,12 @@ sub select { $limit = $self->__max_int; } - - my ($sql, @bind); - if ($limit) { - # this is legacy code-flow from SQLA::Limit, it is not set in stone - - ($sql, @bind) = $self->next::method ($table, $fields, $where); - - my $limiter = - $self->can ('emulate_limit') # also backcompat hook from SQLA::Limit - || - do { - my $dialect = $self->limit_dialect - or $self->throw_exception( "Unable to generate SQL-limit - no limit dialect specified on $self, and no emulate_limit method found" ); - $self->can ("_$dialect") - or $self->throw_exception(__PACKAGE__ . " does not implement the requested dialect '$dialect'"); - } - ; - - $sql = $self->$limiter ( - $sql, - { %{$rs_attrs||{}}, _selector_sql => $fields }, - $limit, - $offset - ); - } - else { - ($sql, @bind) = $self->next::method ($table, $fields, $where, $rs_attrs->{order_by}, $rs_attrs); - } - - push @{$self->{where_bind}}, @bind; - -# this *must* be called, otherwise extra binds will remain in the sql-maker - my @all_bind = $self->_assemble_binds; + my ($sql, @bind) = $self->next::method ($table, $fields, $where, $rs_attrs->{order_by}, { %{$rs_attrs}, limit => $limit, offset => $offset } ); $sql .= $self->_lock_select ($rs_attrs->{for}) if $rs_attrs->{for}; - return wantarray ? ($sql, @all_bind) : $sql; + return wantarray ? ($sql, @bind) : $sql; } sub _assemble_binds { diff --git a/lib/DBIx/Class/SQLMaker/Converter.pm b/lib/DBIx/Class/SQLMaker/Converter.pm index c3cd6e3..f492971 100644 --- a/lib/DBIx/Class/SQLMaker/Converter.pm +++ b/lib/DBIx/Class/SQLMaker/Converter.pm @@ -1,10 +1,26 @@ package DBIx::Class::SQLMaker::Converter; -use Data::Query::Constants qw(DQ_ALIAS DQ_GROUP DQ_WHERE DQ_JOIN); +use Data::Query::Constants qw(DQ_ALIAS DQ_GROUP DQ_WHERE DQ_JOIN DQ_SLICE); use Moo; extends 'SQL::Abstract::Converter'; +around _select_to_dq => sub { + my ($orig, $self) = (shift, shift); + my $attrs = $_[4]; + my $orig_dq = $self->$orig(@_); + return $orig_dq unless $attrs->{limit}; + +{ + type => DQ_SLICE, + from => $orig_dq, + limit => $self->_value_to_dq($attrs->{limit}), + ($attrs->{offset} + ? (offset => $self->_value_to_dq($attrs->{offset})) + : () + ), + }; +}; + around _select_field_to_dq => sub { my ($orig, $self) = (shift, shift); my ($field) = @_; diff --git a/lib/DBIx/Class/SQLMaker/SQLite.pm b/lib/DBIx/Class/SQLMaker/SQLite.pm index acf0337..f905b46 100644 --- a/lib/DBIx/Class/SQLMaker/SQLite.pm +++ b/lib/DBIx/Class/SQLMaker/SQLite.pm @@ -3,9 +3,11 @@ package # Hide from PAUSE use base qw( DBIx::Class::SQLMaker ); +sub renderer_class { 'Data::Query::Renderer::SQL::SQLite' } + # # SQLite does not understand SELECT ... FOR UPDATE # Disable it here -sub _lock_select () { '' }; +sub _lock_select { '' }; 1; diff --git a/lib/DBIx/Class/Storage/DBIHacks.pm b/lib/DBIx/Class/Storage/DBIHacks.pm index 3efd488..5d5ee96 100644 --- a/lib/DBIx/Class/Storage/DBIHacks.pm +++ b/lib/DBIx/Class/Storage/DBIHacks.pm @@ -26,7 +26,8 @@ sub _prune_unused_joins { my $self = shift; my ($from, $select, $where, $attrs) = @_; - return $from unless $self->_use_join_optimizer; + # XXX disabled temporarily while I hunt bigger game -- mst + return $from; # unless $self->_use_join_optimizer; if (ref $from ne 'ARRAY' || ref $from->[0] ne 'HASH' || ref $from->[1] ne 'ARRAY') { return $from; # only standard {from} specs are supported