Merge branch 'current/for_cpan_index' into current/dq current/dq
Peter Rabbitson [Sat, 12 Apr 2014 07:50:18 +0000 (09:50 +0200)]
18 files changed:
1  2 
.travis.yml
Changes
Makefile.PL
lib/DBIx/Class.pm
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/ResultSetColumn.pm
lib/DBIx/Class/ResultSource/RowParser.pm
lib/DBIx/Class/Row.pm
lib/DBIx/Class/SQLMaker/LimitDialects.pm
lib/DBIx/Class/Storage/DBI.pm
lib/DBIx/Class/Storage/DBI/Replicated.pm
lib/DBIx/Class/Storage/DBI/mysql.pm
lib/DBIx/Class/Storage/DBIHacks.pm
t/lib/DBICTest.pm
t/lib/DBICTest/Schema/Artist.pm
t/sqlmaker/limit_dialects/fetch_first.t
t/sqlmaker/limit_dialects/torture.t
t/sqlmaker/msaccess.t

diff --cc .travis.yml
Simple merge
diff --cc Changes
+++ b/Changes
@@@ -1,13 -1,31 +1,37 @@@
  Revision history for DBIx::Class
  
- 0.08901-TRIAL (EXPERIMENTAL BETA RELEASE)
++<unreleased DQ stuff, last was 0.08901-TRIAL>
 +    * Start of experimental Data::Query-based release cycle
 +        - Any and all newly introduced syntax features may very well change
 +          or disappear altogether before the 0.09000 release
 +
-     * New Features / Changes
++<unreleased mainline>
+     * Fixes
+         - Fix on_connect_* not always firing in some cases - a race condition
+           existed between storage accessor setters and the determine_driver
+           routines, triggering a connection before the set-cycle is finished
+ 0.08270 2014-01-30 21:54 (PST)
+     * Fixes
+         - Fix 0.08260 regression in DBD::SQLite bound int handling. Inserted
+           data was not affected, but any function <=> integer comparison would
+           have failed (originally fixed way back in 0e773352)
+         - Fix failure to load DateTime formatter when connecting to Firebird
+           over ODBC
+     * Misc
+         - All drivers based on ::Storage::DBI::Firebird::Common now return the
+           same sqlt_type value (affects ::DBI::Interbase, ::DBI::Firebird and
+           ::DBI::ODBC::Firebird)
+ 0.08260 2014-01-28 18:52 (UTC)
+     * New Features
          - A new zero-to-DBIC style manual: DBIx::Class::Manual::QuickStart
  
+     * Notable Changes and Deprecations
+         - Explicitly deprecate combination of distinct and selecting a
+           non-column via $rs->get_column()
      * Fixes
          - More robust handling of circular relationship declarations by loading
            foreign classes less frequently (should resolve issues like
diff --cc Makefile.PL
@@@ -3,42 -3,9 +3,43 @@@ use warnings
  
  use 5.008001;
  use inc::Module::Install 1.06;
+ BEGIN { makemaker_args( NORECURS => 1 ) } # needs to happen early for old EUMM
  
  ##
 +## TEMPORARY (and non-portable)
 +## Get the dq stuff
 +##
 +my $target_libdir;
 +BEGIN {
 +  $target_libdir = 'lib/DBIx/Class/_TempExtlib';
 +
 +  if ($Module::Install::AUTHOR) {
 +
 +    `rm -rf $target_libdir`;
 +    `mkdir $target_libdir`;
 +    for (
 +      [ 'Data-Query' => 'master' ],
 +      [ 'SQL-Abstract' => 'dq' ],
 +    ) {
 +      my $tdir = "/tmp/dqlib/$_->[0]/";
 +
 +      `rm -rf $tdir`;
 +
 +      `GIT_SSH=maint/careless_ssh.bash git clone --bare --quiet --branch=$_->[1] --depth=1 git://git.shadowcat.co.uk/dbsrgits/$_->[0] $tdir`;
 +      printf "\nIncluding %s git rev %s\n",
 +        $_->[0],
 +        scalar `GIT_DIR=$tdir git rev-parse $_->[1]`,
 +      ;
 +      `git archive --format=tar --remote=file://$tdir $_->[1] lib/ | tar --strip-components=1 -xC $target_libdir`;
 +
 +      #`rm -rf $tdir`;
 +    }
 +  }
 +}
 +
 +use lib $target_libdir;
 +
 +##
  ## DO NOT USE THIS HACK IN YOUR DISTS!!! (it makes #toolchain sad)
  ##
  # get cpanX --installdeps . to behave in a checkout (most users do not expect
Simple merge
Simple merge
@@@ -478,12 -475,33 +475,33 @@@ sub throw_exception 
  sub _resultset {
    my $self = shift;
  
-   return $self->{_resultset} ||= $self->{_parent_resultset}->search(undef,
-     {
-       select => [$self->{_select}],
-       as => [$self->{_as}]
+   return $self->{_resultset} ||= do {
+     my $select = $self->{_select};
+     if ($self->{_parent_resultset}{attrs}{distinct}) {
+       my $alias = $self->{_parent_resultset}->current_source_alias;
+       my $rsrc = $self->{_parent_resultset}->result_source;
+       my %cols = map { $_ => 1, "$alias.$_" => 1 } $rsrc->columns;
+       unless( $cols{$select} ) {
+         carp_unique(
+           'Use of distinct => 1 while selecting anything other than a column '
+         . 'declared on the primary ResultSource is deprecated - please supply '
+         . 'an explicit group_by instead'
+         );
+         # collapse the selector to a literal so that it survives the distinct parse
+         # if it turns out to be an aggregate - at least the user will get a proper exception
+         # instead of silent drop of the group_by altogether
 -        $select = \ $rsrc->storage->sql_maker->_recurse_fields($select);
++        $select = \ ($rsrc->storage->sql_maker->_render_sqla(select_select => $select) =~ /^\s*SELECT\s*(.+)/i)[0],
+       }
      }
-   );
+     $self->{_parent_resultset}->search(undef, {
+       columns => { $self->{_as} => $select }
+     });
+   };
  }
  
  1;
@@@ -8,8 -8,6 +8,7 @@@ use base 'DBIx::Class'
  
  use Try::Tiny;
  use List::Util qw(first max);
- use B 'perlstring';
 +use Scalar::Util qw(blessed);
  
  use DBIx::Class::ResultSource::RowParser::Util qw(
    assemble_simple_parser
Simple merge
Simple merge
@@@ -106,15 -106,17 +106,17 @@@ sub _run_connection_actions 
  sub sql_maker {
    my $self = shift;
  
-   unless ($self->_sql_maker) {
-     my $maker = $self->next::method (@_);
+   # it is critical to get the version *before* calling next::method
+   # otherwise the potential connect will obliterate the sql_maker
+   # next::method will populate in the _sql_maker accessor
+   my $mysql_ver = $self->_server_info->{normalized_dbms_version};
  
-     # mysql 3 does not understand a bare JOIN
-     my $mysql_ver = $self->_dbh_get_info('SQL_DBMS_VER');
-     $maker->needs_inner_join(1) if $mysql_ver =~ /^3/;
-   }
+   my $sm = $self->next::method(@_);
+   # mysql 3 does not understand a bare JOIN
 -  $sm->{_default_jointype} = 'INNER' if $mysql_ver < 4;
++  $sm->needs_inner_join(1) if $mysql_ver < 4;
  
-   return $self->_sql_maker;
+   $sm;
  }
  
  sub sqlt_type {
@@@ -444,9 -429,7 +444,7 @@@ sub _resolve_aliastypes_from_select_arg
        ),
      ],
      selecting => [
-       ($attrs->{select}
-         ? ($sql_maker->_render_sqla(select_select => $attrs->{select}))[0]
-         : ()),
 -      map { $sql_maker->_recurse_fields($_) } @{$attrs->{select}},
++      map { $sql_maker->_render_sqla(select_select => $_) =~ /^SELECT\s+(.+)/ } @{$attrs->{select}||[]},
      ],
      ordering => [
        map { $_->[0] } $self->_extract_order_criteria ($attrs->{order_by}, $sql_maker),
Simple merge
Simple merge
Simple merge
@@@ -5,9 -5,81 +5,81 @@@ use lib qw(t/lib)
  use DBICTest;
  use DBIC::SqlMakerTest;
  
- use DBIx::Class::SQLMaker::ACCESS ();
+ # the entire point of the subclass is that parenthesis have to be
+ # just right for ACCESS to be happy
+ # globalize for entirety of the test
+ $SQL::Abstract::Test::parenthesis_significant = 1;
  
- my $sa = DBIx::Class::SQLMaker::ACCESS->new;
+ my $schema = DBICTest->init_schema (storage_type => 'DBIx::Class::Storage::DBI::ACCESS', no_deploy => 1, quote_names => 1);
+ is_same_sql_bind(
+   $schema->resultset('Artist')->search(
+     {
+       artistid => 1,
+     },
+     {
+       join => [{ cds => 'tracks' }],
+       '+select' => [ 'tracks.title' ],
+       '+as'     => [ 'track_title'  ],
+     }
+   )->as_query,
+   '(
+     SELECT [me].[artistid], [me].[name], [me].[rank], [me].[charfield],
+            [tracks].[title]
+       FROM (
+         (
+           [artist] [me]
+           LEFT JOIN cd [cds]
+             ON [cds].[artist] = [me].[artistid]
+         )
+         LEFT JOIN [track] [tracks]
+           ON [tracks].[cd] = [cds].[cdid]
+       )
 -    WHERE ( [artistid] = ? )
++    WHERE [artistid] = ?
+   )',
+   [
+     [{ sqlt_datatype => 'integer', dbic_colname => 'artistid' }
+       => 1 ],
+   ],
+   'correct SQL for two-step left join'
+ );
+ is_same_sql_bind(
+   $schema->resultset('Track')->search(
+     {
+       trackid => 1,
+     },
+     {
+       join => [{ cd => 'artist' }],
+       '+select' => [ 'artist.name' ],
+       '+as'     => [ 'artist_name'  ],
+     }
+   )->as_query,
+   '(
+     SELECT [me].[trackid], [me].[cd], [me].[position], [me].[title], [me].[last_updated_on], [me].[last_updated_at],
+            [artist].[name]
+       FROM (
+         (
+           [track] [me]
+           INNER JOIN cd [cd]
+             ON [cd].[cdid] = [me].[cd]
+         )
+         INNER JOIN [artist] [artist]
+           ON [artist].[artistid] = [cd].[artist]
+       )
 -    WHERE ( [trackid] = ? )
++    WHERE [trackid] = ?
+   )',
+   [
+     [{ sqlt_datatype => 'integer', dbic_colname => 'trackid' }
+       => 1 ],
+   ],
+   'correct SQL for two-step inner join',
+ );
+ my $sa = $schema->storage->sql_maker;
+ # the legacy tests assume no quoting - leave things as-is
 -local $sa->{quote_char};
++$sa->quote_char(undef);
  
  #  my ($self, $table, $fields, $where, $order, @rest) = @_;
  my ($sql, @bind) = $sa->select(