Merge branch 'current/for_cpan_index' into current/dq
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / SQLMaker.pm
index 0256793..bbb445e 100644 (file)
@@ -50,9 +50,21 @@ use namespace::clean;
 
 has limit_dialect => (
   is => 'rw', default => sub { 'LimitOffset' },
-  trigger => sub { shift->clear_renderer_class }
+  trigger => sub {
+    $_[0]->clear_renderer_class;
+    $_[0]->clear_converter;
+  }
 );
 
+sub BUILD {
+  if ($_[0]->can('emulate_limit')) {
+    die <<EODIE;
+The ancient and horrible emulate_limit method was deprecated for many moons.
+Now, it is no more. Time to rewrite the code in ${\ref($_[0])}
+EODIE
+  }
+}
+
 our %LIMIT_DIALECT_MAP = (
   'GenericSubQ' => 'GenericSubquery',
 );
@@ -135,79 +147,23 @@ sub _where_op_NEST {
   shift->next::method(@_);
 }
 
-# Handle limit-dialect selection
-sub select {
-  my ($self, $table, $fields, $where, $rs_attrs, $limit, $offset) = @_;
-
-  if (defined $offset) {
-    $self->throw_exception('A supplied offset must be a non-negative integer')
-      if ( $offset =~ /\D/ or $offset < 0 );
-  }
-  $offset ||= 0;
-
-  if (defined $limit) {
-    $self->throw_exception('A supplied limit must be a positive integer')
-      if ( $limit =~ /\D/ or $limit <= 0 );
-  }
-  elsif ($offset) {
-    $limit = $self->__max_int;
+around _converter_args => sub {
+  my ($orig, $self) = (shift, shift);
+  +{
+    %{$self->$orig(@_)},
+    name_sep => $self->name_sep,
+    limit_dialect => $self->mapped_limit_dialect,
+    slice_stability => { $self->renderer->slice_stability },
+    slice_subquery => { $self->renderer->slice_subquery },
   }
+};
 
-  my %final_attrs = (%{$rs_attrs||{}}, limit => $limit, offset => $offset);
-
-  if ($limit or $offset) {
-    my %slice_stability = $self->renderer->slice_stability;
-
-    if (my $stability = $slice_stability{$offset ? 'offset' : 'limit'}) {
-      my $source = $rs_attrs->{_rsroot_rsrc};
-      unless (
-        $final_attrs{order_is_stable}
-        = $final_attrs{preserve_order}
-        = $source->schema->storage
-                 ->_order_by_is_stable(
-                     @final_attrs{qw(from order_by where)}
-                   )
-      ) {
-        if ($stability eq 'requires') {
-          if ($self->converter->_order_by_to_dq($final_attrs{order_by})) {
-            $self->throw_exception(
-                $self->limit_dialect.' limit/offset implementation requires a stable order for offset'
-            );
-          }
-          if (my $ident_cols = $source->_identifying_column_set) {
-            $final_attrs{order_by} = [
-                map "$final_attrs{alias}.$_", @$ident_cols
-            ];
-            $final_attrs{order_is_stable} = 1;
-          } else {
-            $self->throw_exception(sprintf(
-              'Unable to auto-construct stable order criteria for "skimming type" 
-  limit '
-              . "dialect based on source '%s'", $source->name) );
-          }
-        }
-      }
-
-    }
-
-    my %slice_subquery = $self->renderer->slice_subquery;
-
-    if (my $subquery = $slice_subquery{$offset ? 'offset' : 'limit'}) {
-      $fields = [ map {
-        my $f = $fields->[$_];
-        if (ref $f) {
-          $f = { '' => $f } unless ref($f) eq 'HASH';
-          ($f->{-as} ||= $final_attrs{as}[$_]) =~ s/\Q${\$self->name_sep}/__/g;
-        } elsif ($f !~ /^\Q$final_attrs{alias}${\$self->name_sep}/) {
-          $f = { '' => $f };
-          ($f->{-as} ||= $final_attrs{as}[$_]) =~ s/\Q${\$self->name_sep}/__/g;
-        }
-        $f;
-        } 0 .. $#$fields ];
-    }
-  }
+# Handle limit-dialect selection
+sub select {
+  my $self = shift;
+  my ($table, $fields, $where, $rs_attrs, $limit, $offset) = @_;
 
-  my ($sql, @bind) = $self->next::method ($table, $fields, $where, $final_attrs{order_by}, \%final_attrs );
+  my ($sql, @bind) = $self->next::method(@_);
 
   $sql .= $self->_lock_select ($rs_attrs->{for})
     if $rs_attrs->{for};