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
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
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;
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
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 {
),
],
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),
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(