further steps towards conversion
Matt S Trout [Mon, 16 Apr 2012 03:46:07 +0000 (03:46 +0000)]
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/ResultSetColumn.pm
lib/DBIx/Class/SQLMaker.pm
lib/DBIx/Class/SQLMaker/Converter.pm
lib/DBIx/Class/SQLMaker/SQLite.pm
lib/DBIx/Class/Storage/DBIHacks.pm

index 88409b0..c16b278 100644 (file)
@@ -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
index 8a92b2f..8979ef9 100644 (file)
@@ -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} );
index 5855753..c418a3e 100644 (file)
@@ -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 {
index c3cd6e3..f492971 100644 (file)
@@ -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) = @_;
index acf0337..f905b46 100644 (file)
@@ -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;
index 3efd488..5d5ee96 100644 (file)
@@ -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