[Bast-commits] r6907 - in
DBIx-Class/0.08/branches/unresolvable_prefetch: .
lib/DBIx/Class lib/DBIx/Class/Storage
lib/DBIx/Class/Storage/DBI t t/count t/prefetch t/relationship
ribasushi at dev.catalyst.perl.org
ribasushi at dev.catalyst.perl.org
Wed Jul 1 11:25:43 GMT 2009
Author: ribasushi
Date: 2009-07-01 11:25:42 +0000 (Wed, 01 Jul 2009)
New Revision: 6907
Added:
DBIx-Class/0.08/branches/unresolvable_prefetch/t/prefetch/grouped.t
Modified:
DBIx-Class/0.08/branches/unresolvable_prefetch/
DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/ResultSet.pm
DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/ResultSetColumn.pm
DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/SQLAHacks.pm
DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI.pm
DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Cursor.pm
DBIx-Class/0.08/branches/unresolvable_prefetch/t/31stats.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/60core.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/83cache.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/86might_have.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/88result_set_column.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/95sql_maker_quote.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/count/distinct.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/prefetch/multiple_hasmany.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/prefetch/standard.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/relationship/core.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/relationship/update_or_create_multi.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/relationship/update_or_create_single.t
Log:
r6907 at Thesaurus (orig r6906): ribasushi | 2009-07-01 13:23:46 +0200
r6821 at Thesaurus (orig r6820): ribasushi | 2009-06-28 13:09:11 +0200
Branch for prefetch+group play
r6823 at Thesaurus (orig r6822): ribasushi | 2009-06-28 14:38:36 +0200
Normalize group_by
r6824 at Thesaurus (orig r6823): ribasushi | 2009-06-28 14:39:54 +0200
Proper prefetch+group test
r6826 at Thesaurus (orig r6825): ribasushi | 2009-06-28 14:42:48 +0200
Whoops
r6828 at Thesaurus (orig r6827): ribasushi | 2009-06-28 15:06:57 +0200
Lose the literal sql bits - castaway is right it's silly to support those
r6833 at Thesaurus (orig r6832): ribasushi | 2009-06-28 22:38:43 +0200
Rogue comments
r6837 at Thesaurus (orig r6836): ribasushi | 2009-06-29 09:44:25 +0200
A couple of test fixes
r6838 at Thesaurus (orig r6837): ribasushi | 2009-06-29 09:46:13 +0200
Support for -select/-as in SQLAHacks field selection
r6839 at Thesaurus (orig r6838): ribasushi | 2009-06-29 09:49:53 +0200
This is tested elsewhere
r6840 at Thesaurus (orig r6839): ribasushi | 2009-06-29 09:50:43 +0200
This is tested elsewhere (2)
r6841 at Thesaurus (orig r6840): ribasushi | 2009-06-29 10:07:09 +0200
Test cleanups
r6842 at Thesaurus (orig r6841): ribasushi | 2009-06-29 10:11:13 +0200
Most of the grouped prefetch solution
r6843 at Thesaurus (orig r6842): ribasushi | 2009-06-29 10:14:45 +0200
clearer
r6845 at Thesaurus (orig r6844): ribasushi | 2009-06-29 12:05:37 +0200
And score! (all works)
r6882 at Thesaurus (orig r6881): ribasushi | 2009-06-30 16:23:06 +0200
rs->get_column now properly recognizes prefetch and collapses if at all possible
r6886 at Thesaurus (orig r6885): ribasushi | 2009-06-30 17:39:58 +0200
Whoops
Property changes on: DBIx-Class/0.08/branches/unresolvable_prefetch
___________________________________________________________________
Name: svk:merge
- 168d5346-440b-0410-b799-f706be625ff1:/DBIx-Class-current:2207
462d4d0c-b505-0410-bf8e-ce8f877b3390:/local/bast/DBIx-Class:3159
4d5fae46-8e6a-4e08-abee-817e9fb894a2:/local/bast/DBIx-Class/0.08/branches/resultsetcolumn_custom_columns:5160
4d5fae46-8e6a-4e08-abee-817e9fb894a2:/local/bast/DBIx-Class/0.08/branches/sqla_1.50_compat:5414
4d5fae46-8e6a-4e08-abee-817e9fb894a2:/local/bast/DBIx-Class/0.08/trunk:5969
9c88509d-e914-0410-b01c-b9530614cbfe:/local/DBIx-Class:32260
9c88509d-e914-0410-b01c-b9530614cbfe:/local/DBIx-Class-CDBICompat:54993
9c88509d-e914-0410-b01c-b9530614cbfe:/vendor/DBIx-Class:31122
ab17426e-7cd3-4704-a2a2-80b7c0a611bb:/local/dbic_column_attr:10946
ab17426e-7cd3-4704-a2a2-80b7c0a611bb:/local/dbic_trunk:11788
bd5ac9a7-f185-4d95-9186-dbb8b392a572:/local/os/bast/DBIx-Class/0.08/trunk:2798
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/belongs_to_null_col_fix:5244
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/cdbicompat_integration:4160
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/column_attr:5074
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/complex_join_rels:4589
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/count_distinct:6218
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/count_rs:6741
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/diamond_relationships:6310
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/file_column:3920
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/fix-update-and-delete-as_query:6162
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/joined_count:6323
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/multi_stuff:5565
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/mystery_join:6589
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/on_connect_call:6854
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/on_disconnect_do:3694
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/oracle-tweaks:6222
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/oracle_sequence:4173
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/order_by_refactor:6475
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/parser_fk_index:4485
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/prefetch:5699
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/prefetch_limit:6724
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/replication_dedux:4600
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/rsrc_in_storage:6577
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/rt_bug_41083:5437
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/savepoints:4223
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/search_related_prefetch:6818
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/sqla_1.50_compat:5321
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/storage-ms-access:4142
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/storage-tweaks:6262
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/subclassed_rsset:5930
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/subquery:5617
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/sybase:5651
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/sybase_mssql:6125
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/top_limit_altfix:6429
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/type_aware_update:6619
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/versioned_enhancements:4125
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/versioning:4578
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/views:5585
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/trunk:6903
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class-C3:318
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class-current:2222
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class-joins:173
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class-resultset:570
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/datetime:1716
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/find_compat:1855
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/find_unique_query_fixes:2142
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/inflate:1988
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/many_to_many:2025
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/re_refactor_bugfix:1944
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/reorganize_tests:1827
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/resultset-new-refactor:1766
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/resultset_2_electric_boogaloo:2175
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/resultset_cleanup:2102
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/sqlt_tests_refactor:2043
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/trunk/DBIx-Class:3606
fe160bb6-dc1c-0410-9f2b-d64a711b54a5:/local/DBIC-trunk-0.08:10510
+ 168d5346-440b-0410-b799-f706be625ff1:/DBIx-Class-current:2207
462d4d0c-b505-0410-bf8e-ce8f877b3390:/local/bast/DBIx-Class:3159
4d5fae46-8e6a-4e08-abee-817e9fb894a2:/local/bast/DBIx-Class/0.08/branches/resultsetcolumn_custom_columns:5160
4d5fae46-8e6a-4e08-abee-817e9fb894a2:/local/bast/DBIx-Class/0.08/branches/sqla_1.50_compat:5414
4d5fae46-8e6a-4e08-abee-817e9fb894a2:/local/bast/DBIx-Class/0.08/trunk:5969
9c88509d-e914-0410-b01c-b9530614cbfe:/local/DBIx-Class:32260
9c88509d-e914-0410-b01c-b9530614cbfe:/local/DBIx-Class-CDBICompat:54993
9c88509d-e914-0410-b01c-b9530614cbfe:/vendor/DBIx-Class:31122
ab17426e-7cd3-4704-a2a2-80b7c0a611bb:/local/dbic_column_attr:10946
ab17426e-7cd3-4704-a2a2-80b7c0a611bb:/local/dbic_trunk:11788
bd5ac9a7-f185-4d95-9186-dbb8b392a572:/local/os/bast/DBIx-Class/0.08/trunk:2798
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/belongs_to_null_col_fix:5244
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/cdbicompat_integration:4160
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/column_attr:5074
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/complex_join_rels:4589
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/count_distinct:6218
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/count_rs:6741
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/diamond_relationships:6310
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/file_column:3920
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/fix-update-and-delete-as_query:6162
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/grouped_prefetch:6885
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/joined_count:6323
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/multi_stuff:5565
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/mystery_join:6589
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/on_connect_call:6854
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/on_disconnect_do:3694
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/oracle-tweaks:6222
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/oracle_sequence:4173
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/order_by_refactor:6475
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/parser_fk_index:4485
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/prefetch:5699
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/prefetch_limit:6724
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/replication_dedux:4600
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/rsrc_in_storage:6577
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/rt_bug_41083:5437
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/savepoints:4223
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/search_related_prefetch:6818
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/sqla_1.50_compat:5321
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/storage-ms-access:4142
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/storage-tweaks:6262
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/subclassed_rsset:5930
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/subquery:5617
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/sybase:5651
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/sybase_mssql:6125
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/top_limit_altfix:6429
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/type_aware_update:6619
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/versioned_enhancements:4125
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/versioning:4578
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/views:5585
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/trunk:6906
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class-C3:318
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class-current:2222
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class-joins:173
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class-resultset:570
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/datetime:1716
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/find_compat:1855
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/find_unique_query_fixes:2142
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/inflate:1988
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/many_to_many:2025
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/re_refactor_bugfix:1944
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/reorganize_tests:1827
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/resultset-new-refactor:1766
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/resultset_2_electric_boogaloo:2175
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/resultset_cleanup:2102
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/sqlt_tests_refactor:2043
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/trunk/DBIx-Class:3606
fe160bb6-dc1c-0410-9f2b-d64a711b54a5:/local/DBIC-trunk-0.08:10510
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/ResultSet.pm
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/ResultSet.pm 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/ResultSet.pm 2009-07-01 11:25:42 UTC (rev 6907)
@@ -1243,8 +1243,8 @@
my $sub_attrs = { %$attrs };
- # these can not go in the subquery, and there is no point of ordering it
- delete $sub_attrs->{$_} for qw/collapse select as order_by/;
+ # extra selectors do not go in the subquery and there is no point of ordering it
+ delete $sub_attrs->{$_} for qw/collapse prefetch_select select as order_by/;
# if we prefetch, we group_by primary keys only as this is what we would get out of the rs via ->next/->all
# clobber old group_by regardless
@@ -1311,13 +1311,12 @@
my @obj;
- # TODO: don't call resolve here
if (keys %{$self->_resolved_attrs->{collapse}}) {
-# if ($self->{attrs}{prefetch}) {
- # Using $self->cursor->all is really just an optimisation.
- # If we're collapsing has_many prefetches it probably makes
- # very little difference, and this is cleaner than hacking
- # _construct_object to survive the approach
+ # Using $self->cursor->all is really just an optimisation.
+ # If we're collapsing has_many prefetches it probably makes
+ # very little difference, and this is cleaner than hacking
+ # _construct_object to survive the approach
+ $self->cursor->reset;
my @row = $self->cursor->next;
while (@row) {
push(@obj, $self->_construct_object(@row));
@@ -1344,6 +1343,8 @@
=back
Resets the resultset's cursor, so you can iterate through the elements again.
+Implicitly resets the storage cursor, so a subsequent L</next> will trigger
+another query.
=cut
@@ -2717,8 +2718,9 @@
: [ $attrs->{order_by} ]
);
}
- else {
- $attrs->{order_by} = [];
+
+ if ($attrs->{group_by} and ! ref $attrs->{group_by}) {
+ $attrs->{group_by} = [ $attrs->{group_by} ];
}
# If the order_by is otherwise empty - we will use this for TOP limit
@@ -2740,8 +2742,9 @@
my @prefetch =
$source->_resolve_prefetch( $prefetch, $alias, $join_map, $prefetch_ordering, $attrs->{collapse} );
- push( @{ $attrs->{select} }, map { $_->[0] } @prefetch );
- push( @{ $attrs->{as} }, map { $_->[1] } @prefetch );
+ $attrs->{prefetch_select} = [ map { $_->[0] } @prefetch ];
+ push @{ $attrs->{select} }, @{$attrs->{prefetch_select}};
+ push @{ $attrs->{as} }, (map { $_->[1] } @prefetch);
push( @{ $attrs->{order_by} }, @$prefetch_ordering );
$attrs->{_collapse_order_by} = \@$prefetch_ordering;
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/ResultSetColumn.pm
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/ResultSetColumn.pm 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/ResultSetColumn.pm 2009-07-01 11:25:42 UTC (rev 6907)
@@ -39,27 +39,48 @@
$rs->throw_exception("column must be supplied") unless $column;
- my $new_parent_rs = $rs->search_rs; # we don't want to mess up the original, so clone it
+ my $orig_attrs = $rs->_resolved_attrs;
+ my $new_parent_rs = $rs->search_rs;
# prefetch causes additional columns to be fetched, but we can not just make a new
# rs via the _resolved_attrs trick - we need to retain the separation between
# +select/+as and select/as. At the same time we want to preserve any joins that the
# prefetch would otherwise generate.
- my $init_attrs = $new_parent_rs->{attrs} ||= {};
- delete $init_attrs->{collapse};
- $init_attrs->{join} = $rs->_merge_attr( delete $init_attrs->{join}, delete $init_attrs->{prefetch} );
+ my $new_attrs = $new_parent_rs->{attrs} ||= {};
+ $new_attrs->{join} = $rs->_merge_attr( delete $new_attrs->{join}, delete $new_attrs->{prefetch} );
+
# If $column can be found in the 'as' list of the parent resultset, use the
# corresponding element of its 'select' list (to keep any custom column
# definition set up with 'select' or '+select' attrs), otherwise use $column
# (to create a new column definition on-the-fly).
- my $attrs = $new_parent_rs->_resolved_attrs;
- my $as_list = $attrs->{as} || [];
- my $select_list = $attrs->{select} || [];
+ my $as_list = $orig_attrs->{as} || [];
+ my $select_list = $orig_attrs->{select} || [];
my $as_index = List::Util::first { ($as_list->[$_] || "") eq $column } 0..$#$as_list;
my $select = defined $as_index ? $select_list->[$as_index] : $column;
+ # {collapse} would mean a has_many join was injected, which in turn means
+ # we need to group IF WE CAN (only if the column in question is unique)
+ if (!$new_attrs->{group_by} && keys %{$orig_attrs->{collapse}}) {
+
+ # scan for a constraint that would contain our column only - that'd be proof
+ # enough it is unique
+ my $constraints = { $rs->result_source->unique_constraints };
+ for my $constraint_columns ( values %$constraints ) {
+
+ next unless @$constraint_columns == 1;
+
+ my $col = $constraint_columns->[0];
+ my $fqcol = join ('.', $new_attrs->{alias}, $col);
+
+ if ($col eq $select or $fqcol eq $select) {
+ $new_attrs->{group_by} = [ $select ];
+ last;
+ }
+ }
+ }
+
my $new = bless { _select => $select, _as => $column, _parent_resultset => $new_parent_rs }, $class;
return $new;
}
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/SQLAHacks.pm
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/SQLAHacks.pm 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/SQLAHacks.pm 2009-07-01 11:25:42 UTC (rev 6907)
@@ -240,28 +240,39 @@
? ' AS col'.$self->{rownum_hack_count}++
: '')
} @$fields);
- } elsif ($ref eq 'HASH') {
- foreach my $func (keys %$fields) {
- if ($func eq 'distinct') {
- my $_fields = $fields->{$func};
- if (ref $_fields eq 'ARRAY' && @{$_fields} > 1) {
- croak (
- 'The select => { distinct => ... } syntax is not supported for multiple columns.'
- .' Instead please use { group_by => [ qw/' . (join ' ', @$_fields) . '/ ] }'
- .' or { select => [ qw/' . (join ' ', @$_fields) . '/ ], distinct => 1 }'
- );
- }
- else {
- $_fields = @{$_fields}[0] if ref $_fields eq 'ARRAY';
- carp (
- 'The select => { distinct => ... } syntax will be deprecated in DBIC version 0.09,'
- ." please use { group_by => '${_fields}' } or { select => '${_fields}', distinct => 1 }"
- );
- }
+ }
+ elsif ($ref eq 'HASH') {
+ my %hash = %$fields;
+ my ($select, $as);
+
+ if ($hash{-select}) {
+ $select = $self->_recurse_fields (delete $hash{-select});
+ $as = $self->_quote (delete $hash{-as});
+ }
+ else {
+ my ($func, $args) = each %hash;
+ delete $hash{$func};
+
+ if (lc ($func) eq 'distinct' && ref $args eq 'ARRAY' && @$args > 1) {
+ croak (
+ 'The select => { distinct => ... } syntax is not supported for multiple columns.'
+ .' Instead please use { group_by => [ qw/' . (join ' ', @$args) . '/ ] }'
+ .' or { select => [ qw/' . (join ' ', @$args) . '/ ], distinct => 1 }'
+ );
}
- return $self->_sqlcase($func)
- .'( '.$self->_recurse_fields($fields->{$func}).' )';
+ $select = sprintf ('%s( %s )',
+ $self->_sqlcase($func),
+ $self->_recurse_fields($args)
+ );
}
+
+ # there should be nothing left
+ if (keys %hash) {
+ croak "Malformed select argument - too many keys in hash: " . join (',', keys %$fields );
+ }
+
+ $select .= " AS $as" if $as;
+ return $select;
}
# Is the second check absolutely necessary?
elsif ( $ref eq 'REF' and ref($$fields) eq 'ARRAY' ) {
@@ -279,9 +290,8 @@
my $ret = '';
- if (defined $arg->{group_by}) {
- $ret = $self->_sqlcase(' group by ')
- .$self->_recurse_fields($arg->{group_by}, { no_rownum_hack => 1 });
+ if (my $g = $self->_recurse_fields($arg->{group_by}, { no_rownum_hack => 1 }) ) {
+ $ret = $self->_sqlcase(' group by ') . $g;
}
if (defined $arg->{having}) {
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Cursor.pm
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Cursor.pm 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Cursor.pm 2009-07-01 11:25:42 UTC (rev 6907)
@@ -68,7 +68,11 @@
my ($storage, $dbh, $self) = @_;
$self->_check_dbh_gen;
- if ($self->{attrs}{rows} && $self->{pos} >= $self->{attrs}{rows}) {
+ if (
+ $self->{attrs}{software_limit}
+ && $self->{attrs}{rows}
+ && $self->{pos} >= $self->{attrs}{rows}
+ ) {
$self->{sth}->finish if $self->{sth}->{Active};
delete $self->{sth};
$self->{done} = 1;
@@ -128,6 +132,7 @@
&& ($self->{attrs}{offset} || $self->{attrs}{rows})) {
return $self->next::method;
}
+
$self->{storage}->dbh_do($self->can('_dbh_all'), $self);
}
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI.pm
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI.pm 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI.pm 2009-07-01 11:25:42 UTC (rev 6907)
@@ -1383,25 +1383,38 @@
}
}
- my @limit;
- if ($attrs->{software_limit} ||
- $sql_maker->_default_limit_syntax eq "GenericSubQ") {
- $attrs->{software_limit} = 1;
- } else {
+ # adjust limits
+ if (
+ $attrs->{software_limit}
+ ||
+ $sql_maker->_default_limit_syntax eq "GenericSubQ"
+ ) {
+ $attrs->{software_limit} = 1;
+ }
+ else {
$self->throw_exception("rows attribute must be positive if present")
if (defined($attrs->{rows}) && !($attrs->{rows} > 0));
# MySQL actually recommends this approach. I cringe.
$attrs->{rows} = 2**48 if not defined $attrs->{rows} and defined $attrs->{offset};
+ }
- if ($attrs->{rows} && keys %{$attrs->{collapse}}) {
- ($ident, $select, $where, $attrs)
- = $self->_adjust_select_args_for_limited_prefetch ($ident, $select, $where, $attrs);
- }
- else {
- push @limit, $attrs->{rows}, $attrs->{offset};
- }
+ my @limit;
+
+ # see if we need to tear the prefetch apart (either limited has_many or grouped prefetch)
+ # otherwise delegate the limiting to the storage, unless software limit was requested
+ if (
+ ( $attrs->{rows} && keys %{$attrs->{collapse}} )
+ ||
+ ( $attrs->{group_by} && @{$attrs->{group_by}} &&
+ $attrs->{prefetch_select} && @{$attrs->{prefetch_select}} )
+ ) {
+ ($ident, $select, $where, $attrs)
+ = $self->_adjust_select_args_for_complex_prefetch ($ident, $select, $where, $attrs);
}
+ elsif (! $attrs->{software_limit} ) {
+ push @limit, $attrs->{rows}, $attrs->{offset};
+ }
###
# This would be the point to deflate anything found in $where
@@ -1418,43 +1431,54 @@
(qw/order_by group_by having _virtual_order_by/ )
};
-
$sql_maker->{for} = delete $attrs->{for};
return ('select', $attrs->{bind}, $ident, $bind_attrs, $select, $where, $order, @limit);
}
-sub _adjust_select_args_for_limited_prefetch {
+sub _adjust_select_args_for_complex_prefetch {
my ($self, $from, $select, $where, $attrs) = @_;
- if ($attrs->{group_by} and @{$attrs->{group_by}}) {
- $self->throw_exception ('Prefetch with limit (rows/offset) is not supported on resultsets with a group_by attribute');
- }
+ # copies for mangling
+ $from = [ @$from ];
+ $select = [ @$select ];
+ $attrs = { %$attrs };
- $self->throw_exception ('Prefetch with limit (rows/offset) is not supported on resultsets with a custom from attribute')
+ $self->throw_exception ('Complex prefetches are not supported on resultsets with a custom from attribute')
if (ref $from ne 'ARRAY');
-
# separate attributes
my $sub_attrs = { %$attrs };
- delete $attrs->{$_} for qw/where bind rows offset/;
- delete $sub_attrs->{$_} for qw/for collapse select order_by/;
+ delete $attrs->{$_} for qw/where bind rows offset group_by having/;
+ delete $sub_attrs->{$_} for qw/for collapse prefetch_select _collapse_order_by select as/;
my $alias = $attrs->{alias};
- # create subquery select list
- my $sub_select = [ grep { $_ =~ /^$alias\./ } @{$attrs->{select}} ];
+ # create subquery select list - loop only over primary columns
+ my $sub_select = [];
+ for my $i (0 .. @{$attrs->{select}} - @{$attrs->{prefetch_select}} - 1) {
+ my $sel = $attrs->{select}[$i];
+ # alias any functions to the dbic-side 'as' label
+ # adjust the outer select accordingly
+ if (ref $sel eq 'HASH' && !$sel->{-select}) {
+ $sel = { -select => $sel, -as => $attrs->{as}[$i] };
+ $select->[$i] = join ('.', $attrs->{alias}, $attrs->{as}[$i]);
+ }
+
+ push @$sub_select, $sel;
+ }
+
# bring over all non-collapse-induced order_by into the inner query (if any)
# the outer one will have to keep them all
+ delete $sub_attrs->{order_by};
if (my $ord_cnt = @{$attrs->{order_by}} - @{$attrs->{_collapse_order_by}} ) {
$sub_attrs->{order_by} = [
- @{$attrs->{order_by}}[ 0 .. ($#{$attrs->{order_by}} - $ord_cnt - 1) ]
+ @{$attrs->{order_by}}[ 0 .. $ord_cnt - 1]
];
}
# mangle {from}
- $from = [ @$from ];
my $select_root = shift @$from;
my @outer_from = @$from;
@@ -1486,7 +1510,7 @@
# away _any_ branches of the join tree that are:
# 1) not mentioned in the condition/order
# 2) left-join leaves (or left-join leaf chains)
- # Most of the join ocnditions will not satisfy this, but for real
+ # Most of the join conditions will not satisfy this, but for real
# complex queries some might, and we might make some RDBMS happy.
#
#
@@ -1549,7 +1573,7 @@
# the dot comes from some weirdness in collapse
# remove after the rewrite
if ($attrs->{collapse}{".$alias"}) {
- $sub_attrs->{group_by} = $sub_select;
+ $sub_attrs->{group_by} ||= $sub_select;
last;
}
}
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/31stats.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/31stats.t 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/31stats.t 2009-07-01 11:25:42 UTC (rev 6907)
@@ -4,12 +4,7 @@
use warnings;
use Test::More;
-BEGIN {
- eval "use DBD::SQLite";
- plan $@
- ? ( skip_all => 'needs DBD::SQLite for testing' )
- : ( tests => 12 );
-}
+plan tests => 12;
use lib qw(t/lib);
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/60core.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/60core.t 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/60core.t 2009-07-01 11:25:42 UTC (rev 6907)
@@ -9,7 +9,7 @@
my $schema = DBICTest->init_schema();
-plan tests => 106;
+plan tests => 103;
eval { require DateTime::Format::SQLite };
my $NO_DTFM = $@ ? 1 : 0;
@@ -229,20 +229,6 @@
is ($collapsed_or_rs->all, 4, 'Collapsed joined search with OR returned correct number of rows');
is ($collapsed_or_rs->count, 4, 'Collapsed search count with OR ok');
-my $pref_or_rs = $collapsed_or_rs->search ({}, { prefetch => [qw/tags/] });
-is_same_sql_bind (
- $pref_or_rs->as_query,
- '(SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track, tags.tagid, tags.cd, tags.tag FROM cd me LEFT JOIN tags tags ON tags.cd = me.cdid WHERE ( ( tags.tag = ? OR tags.tag = ? ) ) GROUP BY me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track, tags.tagid, tags.cd, tags.tag ORDER BY cdid, tags.cd, tags.tag)',
- [
- [ 'tags.tag' => 'Cheesy' ],
- [ 'tags.tag' => 'Blue' ],
- ],
- 'Prefetch + distinct resulted in correct group_by',
-);
-is ($pref_or_rs->all, 4, 'Prefetched grouped search with OR returned correct number of rows');
-is ($pref_or_rs->count, 4, 'Prefetched grouped count with OR ok');
-
-
{
my $tcount = $schema->resultset('Track')->search(
{},
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/83cache.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/83cache.t 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/83cache.t 2009-07-01 11:25:42 UTC (rev 6907)
@@ -9,9 +9,8 @@
my $queries;
$schema->storage->debugcb( sub{ $queries++ } );
+my $sdebug = $schema->storage->debug;
-eval "use DBD::SQLite";
-plan skip_all => 'needs DBD::SQLite for testing' if $@;
plan tests => 23;
my $rs = $schema->resultset("Artist")->search(
@@ -53,7 +52,7 @@
is( $queries, 1, 'revisiting a row does not issue a query when cache => 1' );
-$schema->storage->debug(0);
+$schema->storage->debug($sdebug);
my @a = $schema->resultset("Artist")->search(
{ },
@@ -99,7 +98,7 @@
is($queries, 1, 'only one SQL statement executed');
-$schema->storage->debug(0);
+$schema->storage->debug($sdebug);
# make sure related_resultset is deleted after object is updated
$artist->set_column('name', 'New Name');
@@ -136,7 +135,7 @@
is($queries, 1, 'only one SQL statement executed');
-$schema->storage->debug(0);
+$schema->storage->debug($sdebug);
my @objs;
#$artist = $rs->find(1);
@@ -185,5 +184,5 @@
is( $queries, 1, 'only one select statement on find with has_many prefetch on resultset' );
-$schema->storage->debug(0);
+$schema->storage->debug($sdebug);
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/86might_have.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/86might_have.t 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/86might_have.t 2009-07-01 11:25:42 UTC (rev 6907)
@@ -8,14 +8,11 @@
my $schema = DBICTest->init_schema();
my $queries;
-#$schema->storage->debugfh(IO::File->new('t/var/temp.trace', 'w'));
$schema->storage->debugcb( sub{ $queries++ } );
+my $sdebug = $schema->storage->debug;
-eval "use DBD::SQLite";
-plan skip_all => 'needs DBD::SQLite for testing' if $@;
plan tests => 2;
-
my $cd = $schema->resultset("CD")->find(1);
$cd->title('test');
@@ -28,7 +25,7 @@
is($queries, 1, 'liner_notes (might_have) not prefetched - do not load
liner_notes on update');
-$schema->storage->debug(0);
+$schema->storage->debug($sdebug);
my $cd2 = $schema->resultset("CD")->find(2, {prefetch => 'liner_notes'});
@@ -43,5 +40,4 @@
is($queries, 1, 'liner_notes (might_have) prefetched - do not load
liner_notes on update');
-$schema->storage->debug(0);
-
+$schema->storage->debug($sdebug);
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/88result_set_column.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/88result_set_column.t 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/88result_set_column.t 2009-07-01 11:25:42 UTC (rev 6907)
@@ -8,10 +8,9 @@
my $schema = DBICTest->init_schema();
-plan tests => 18;
+plan tests => 20;
-my $cd;
-my $rs = $cd = $schema->resultset("CD")->search({}, { order_by => 'cdid' });
+my $rs = $schema->resultset("CD")->search({}, { order_by => 'cdid' });
my $rs_title = $rs->get_column('title');
my $rs_year = $rs->get_column('year');
@@ -76,3 +75,22 @@
my $owner = $schema->resultset('Owners')->find ({ name => 'Newton' });
ok ($owner->books->count > 1, 'Owner Newton has multiple books');
is ($owner->search_related ('books')->get_column ('price')->sum, 60, 'Correctly calculated price of all owned books');
+
+
+# make sure joined/prefetched get_column of a PK dtrt
+
+$rs->reset;
+my $j_rs = $rs->search ({}, { join => 'tracks' })->get_column ('cdid');
+is_deeply (
+ [ $j_rs->all ],
+ [ map { my $c = $rs->next; ( ($c->id) x $c->tracks->count ) } (1 .. $rs->count) ],
+ 'join properly explodes amount of rows from get_column',
+);
+
+$rs->reset;
+my $p_rs = $rs->search ({}, { prefetch => 'tracks' })->get_column ('cdid');
+is_deeply (
+ [ $p_rs->all ],
+ [ $rs->get_column ('cdid')->all ],
+ 'prefetch properly collapses amount of rows from get_column',
+);
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/95sql_maker_quote.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/95sql_maker_quote.t 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/95sql_maker_quote.t 2009-07-01 11:25:42 UTC (rev 6907)
@@ -35,12 +35,23 @@
{
'artist.artistid' => 'me.artist'
}
- ]
+ ],
+ [
+ {
+ 'tracks' => 'tracks',
+ '-join_type' => 'left'
+ },
+ {
+ 'tracks.cd' => 'me.cdid'
+ }
+ ],
],
[
- {
- 'count' => '*'
- }
+ 'me.cdid',
+ { count => 'tracks.cd' },
+ { -select => 'me.artist' },
+ { -select => 'me.title', -as => 'name' },
+ { -select => { min => 'me.year' }, -as => 'me.minyear' },
],
{
'artist.name' => 'Caterwauler McCrae',
@@ -53,8 +64,15 @@
is_same_sql_bind(
$sql, \@bind,
- q/SELECT COUNT( * ) FROM `cd` `me` JOIN `artist` `artist` ON ( `artist`.`artistid` = `me`.`artist` ) WHERE ( `artist`.`name` = ? AND `me`.`year` = ? )/, [ ['artist.name' => 'Caterwauler McCrae'], ['me.year' => 2001] ],
- 'got correct SQL and bind parameters for count query with quoting'
+ q/
+ SELECT `me`.`cdid`, COUNT( `tracks`.`cd` ), `me`.`artist`, `me`.`title` AS `name`, MIN( `me`.`year` ) AS `me`.`minyear`
+ FROM `cd` `me`
+ JOIN `artist` `artist` ON ( `artist`.`artistid` = `me`.`artist` )
+ LEFT JOIN `tracks` `tracks` ON ( `tracks`.`cd` = `me`.`cdid` )
+ WHERE ( `artist`.`name` = ? AND `me`.`year` = ? )
+ /,
+ [ ['artist.name' => 'Caterwauler McCrae'], ['me.year' => 2001] ],
+ 'got correct SQL and bind parameters for complex select query with quoting'
);
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/count/distinct.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/count/distinct.t 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/count/distinct.t 2009-07-01 11:25:42 UTC (rev 6907)
@@ -11,7 +11,7 @@
my $schema = DBICTest->init_schema();
-plan tests => 58;
+plan tests => 56;
# The tag Blue is assigned to cds 1 2 3 and 5
# The tag Cheesy is assigned to cds 2 4 and 5
@@ -80,17 +80,6 @@
is($get_count->($rs), 3, 'Count by distinct function result as select literal');
}
-eval {
- my @warnings;
- local $SIG{__WARN__} = sub { $_[0] =~ /The select => { distinct => ... } syntax will be deprecated/
- ? push @warnings, @_
- : warn @_
- };
- my $row = $schema->resultset('Tag')->search({}, { select => { distinct => 'tag' } })->first;
- is (@warnings, 1, 'Warned about deprecated distinct') if $DBIx::Class::VERSION < 0.09;
-};
-ok ($@, 'Exception on deprecated distinct usage thrown') if $DBIx::Class::VERSION >= 0.09;
-
throws_ok(
sub { my $row = $schema->resultset('Tag')->search({}, { select => { distinct => [qw/tag cd/] } })->first },
qr/select => { distinct => \.\.\. } syntax is not supported for multiple columns/,
@@ -99,4 +88,3 @@
# These two rely on the database to throw an exception. This might not be the case one day. Please revise.
dies_ok(sub { my $count = $schema->resultset('Tag')->search({}, { '+select' => \'tagid AS tag_id', distinct => 1 })->count }, 'expecting to die');
-dies_ok(sub { my $count = $schema->resultset('Tag')->search({}, { select => { length => 'tag' }, distinct => 1 })->count }, 'expecting to die');
Added: DBIx-Class/0.08/branches/unresolvable_prefetch/t/prefetch/grouped.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/prefetch/grouped.t (rev 0)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/prefetch/grouped.t 2009-07-01 11:25:42 UTC (rev 6907)
@@ -0,0 +1,203 @@
+use strict;
+use warnings;
+use Test::More;
+
+use lib qw(t/lib);
+use DBICTest;
+use DBIC::SqlMakerTest;
+
+#plan tests => 6;
+plan 'no_plan';
+
+my $schema = DBICTest->init_schema();
+my $sdebug = $schema->storage->debug;
+
+my $cd_rs = $schema->resultset('CD')->search (
+ { 'tracks.cd' => { '!=', undef } },
+ { prefetch => 'tracks' },
+);
+
+# Database sanity check
+is($cd_rs->count, 5, 'CDs with tracks count');
+for ($cd_rs->all) {
+ is ($_->tracks->count, 3, '3 tracks for CD' . $_->id );
+}
+
+# Test a belongs_to prefetch of a has_many
+{
+ my $track_rs = $schema->resultset ('Track')->search (
+ { 'me.cd' => { -in => [ $cd_rs->get_column ('cdid')->all ] } },
+ {
+ # the select/as is deliberately silly to test both funcs and refs below
+ select => [
+ 'me.cd',
+ { count => 'me.trackid' },
+ ],
+ as => [qw/
+ cd
+ track_count
+ /],
+ group_by => [qw/me.cd/],
+ prefetch => 'cd',
+ },
+ );
+
+ # this used to fuck up ->all, do not remove!
+ ok ($track_rs->first, 'There is stuff in the rs');
+
+ is($track_rs->count, 5, 'Prefetched count with groupby');
+ is($track_rs->all, 5, 'Prefetched objects with groupby');
+
+ {
+ my $query_cnt = 0;
+ $schema->storage->debugcb ( sub { $query_cnt++ } );
+ $schema->storage->debug (1);
+
+ while (my $collapsed_track = $track_rs->next) {
+ my $cdid = $collapsed_track->get_column('cd');
+ is($collapsed_track->get_column('track_count'), 3, "Correct count of tracks for CD $cdid" );
+ ok($collapsed_track->cd->title, "Prefetched title for CD $cdid" );
+ }
+
+ is ($query_cnt, 1, 'Single query on prefetched titles');
+ $schema->storage->debugcb (undef);
+ $schema->storage->debug ($sdebug);
+ }
+
+ # Test sql by hand, as the sqlite db will simply paper over
+ # improper group/select combinations
+ #
+ # the exploded IN needs fixing below, coming in another branch
+ #
+ is_same_sql_bind (
+ $track_rs->count_rs->as_query,
+ '(
+ SELECT COUNT( * )
+ FROM (
+ SELECT me.cd
+ FROM track me
+ JOIN cd cd ON cd.cdid = me.cd
+ WHERE ( me.cd IN ( ?, ?, ?, ?, ? ) )
+ GROUP BY me.cd
+ )
+ count_subq
+ )',
+ [ map { [ 'me.cd' => $_] } ($cd_rs->get_column ('cdid')->all) ],
+ 'count() query generated expected SQL',
+ );
+
+ is_same_sql_bind (
+ $track_rs->as_query,
+ '(
+ SELECT me.cd, me.track_count, cd.cdid, cd.artist, cd.title, cd.year, cd.genreid, cd.single_track
+ FROM (
+ SELECT me.cd, COUNT (me.trackid) AS track_count,
+ FROM track me
+ JOIN cd cd ON cd.cdid = me.cd
+ WHERE ( me.cd IN ( ?, ?, ?, ?, ? ) )
+ GROUP BY me.cd
+ ) as me
+ JOIN cd cd ON cd.cdid = me.cd
+ WHERE ( me.cd IN ( ?, ?, ?, ?, ? ) )
+ )',
+ [ map { [ 'me.cd' => $_] } ( ($cd_rs->get_column ('cdid')->all) x 2 ) ],
+ 'next() query generated expected SQL',
+ );
+
+
+ # add an extra track to one of the cds, and then make sure we can get it on top
+ # (check if limit works)
+ my $top_cd = $cd_rs->slice (1,1)->next;
+ $top_cd->create_related ('tracks', {
+ title => 'over the top',
+ });
+
+ my $top_cd_collapsed_track = $track_rs->search ({}, {
+ rows => 2,
+ order_by => [
+ { -desc => 'track_count' },
+ ],
+ });
+
+ is ($top_cd_collapsed_track->count, 2);
+
+ is (
+ $top_cd->title,
+ $top_cd_collapsed_track->first->cd->title,
+ 'Correct collapsed track with prefetched CD returned on top'
+ );
+}
+
+# test a has_many/might_have prefetch at the same level
+# Note that one of the CDs now has 4 tracks instead of 3
+{
+ my $most_tracks_rs = $cd_rs->search ({}, {
+ prefetch => 'liner_notes', # tracks are alredy prefetched
+ select => ['me.cdid', { count => 'tracks.trackid' } ],
+ as => [qw/cdid track_count/],
+ group_by => 'me.cdid',
+ order_by => { -desc => 'track_count' },
+ rows => 2,
+ });
+
+ is_same_sql_bind (
+ $most_tracks_rs->count_rs->as_query,
+ '(
+ SELECT COUNT( * )
+ FROM (
+ SELECT me.cdid
+ FROM cd me
+ LEFT JOIN track tracks ON tracks.cd = me.cdid
+ LEFT JOIN liner_notes liner_notes ON liner_notes.liner_id = me.cdid
+ WHERE ( tracks.cd IS NOT NULL )
+ GROUP BY me.cdid
+ LIMIT 2
+ ) count_subq
+ )',
+ [],
+ 'count() query generated expected SQL',
+ );
+
+ is_same_sql_bind (
+ $most_tracks_rs->as_query,
+ '(
+ SELECT me.cdid, me.track_count, tracks.trackid, tracks.cd, tracks.position, tracks.title, tracks.last_updated_on, tracks.last_updated_at, liner_notes.liner_id, liner_notes.notes
+ FROM (
+ SELECT me.cdid, COUNT( tracks.trackid ) AS track_count
+ FROM cd me
+ LEFT JOIN track tracks ON tracks.cd = me.cdid
+ WHERE ( tracks.cd IS NOT NULL )
+ GROUP BY me.cdid
+ ORDER BY track_count DESC
+ LIMIT 2
+ ) me
+ LEFT JOIN track tracks ON tracks.cd = me.cdid
+ LEFT JOIN liner_notes liner_notes ON liner_notes.liner_id = me.cdid
+ WHERE ( tracks.cd IS NOT NULL )
+ ORDER BY track_count DESC, tracks.cd
+ )',
+ [],
+ 'next() query generated expected SQL',
+ );
+
+ is ($most_tracks_rs->count, 2, 'Limit works');
+ my $top_cd = $most_tracks_rs->first;
+ is ($top_cd->id, 2, 'Correct cd fetched on top'); # 2 because of the slice(1,1) earlier
+
+ my $query_cnt = 0;
+ $schema->storage->debugcb ( sub { $query_cnt++ } );
+ $schema->storage->debug (1);
+
+ is ($top_cd->get_column ('track_count'), 4, 'Track count fetched correctly');
+ is ($top_cd->tracks->count, 4, 'Count of prefetched tracks rs still correct');
+ is ($top_cd->tracks->all, 4, 'Number of prefetched track objects still correct');
+ is (
+ $top_cd->liner_notes->notes,
+ 'Buy Whiskey!',
+ 'Correct liner pre-fetched with top cd',
+ );
+
+ is ($query_cnt, 0, 'No queries executed during prefetched data access');
+ $schema->storage->debugcb (undef);
+ $schema->storage->debug ($sdebug);
+}
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/prefetch/multiple_hasmany.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/prefetch/multiple_hasmany.t 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/prefetch/multiple_hasmany.t 2009-07-01 11:25:42 UTC (rev 6907)
@@ -5,13 +5,13 @@
use Test::Exception;
use lib qw(t/lib);
use DBICTest;
-use Data::Dumper;
+use IO::File;
plan tests => 10;
my $schema = DBICTest->init_schema();
+my $sdebug = $schema->storage->debug;
-use IO::File;
# once the following TODO is complete, remove the 2 warning tests immediately
# after the TODO block
@@ -44,6 +44,9 @@
ok(! $o_mm_warn, 'no warning on attempt to prefetch several same level has_many\'s (1 -> M + M)');
is($queries, 1, 'prefetch one->(has_many,has_many) ran exactly 1 query');
+ $schema->storage->debugcb (undef);
+ $schema->storage->debug ($sdebug);
+
is($pr_tracks_count, $tracks_count, 'equal count of prefetched relations over several same level has_many\'s (1 -> M + M)');
for ($pr_tracks_rs, $tracks_rs) {
@@ -79,6 +82,8 @@
ok(! $m_o_mm_warn, 'no warning on attempt to prefetch several same level has_many\'s (M -> 1 -> M + M)');
is($queries, 1, 'prefetch one->(has_many,has_many) ran exactly 1 query');
+ $schema->storage->debugcb (undef);
+ $schema->storage->debug ($sdebug);
is($pr_tags_count, $tags_count, 'equal count of prefetched relations over several same level has_many\'s (M -> 1 -> M + M)');
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/prefetch/standard.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/prefetch/standard.t 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/prefetch/standard.t 2009-07-01 11:25:42 UTC (rev 6907)
@@ -6,13 +6,11 @@
use lib qw(t/lib);
use DBICTest;
use Data::Dumper;
+use IO::File;
my $schema = DBICTest->init_schema();
-
my $orig_debug = $schema->storage->debug;
-use IO::File;
-
plan tests => 44;
my $queries = 0;
@@ -291,3 +289,5 @@
is($queries, 0, 'chained search_related after has_many->has_many prefetch ran no queries');
+$schema->storage->debug($orig_debug);
+$schema->storage->debugobj->callback(undef);
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/relationship/core.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/relationship/core.t 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/relationship/core.t 2009-07-01 11:25:42 UTC (rev 6907)
@@ -7,6 +7,7 @@
use DBICTest;
my $schema = DBICTest->init_schema();
+my $sdebug = $schema->storage->debug;
plan tests => 78;
@@ -57,7 +58,7 @@
is($queries, 0, 'No SELECT made for belongs_to if key IS NULL');
$big_flop_cd->genre_inefficient; #should trigger a select query
is($queries, 1, 'SELECT made for belongs_to if key IS NULL when undef_on_null_fk disabled');
- $schema->storage->debug(0);
+ $schema->storage->debug($sdebug);
$schema->storage->debugcb(undef);
}
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/relationship/update_or_create_multi.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/relationship/update_or_create_multi.t 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/relationship/update_or_create_multi.t 2009-07-01 11:25:42 UTC (rev 6907)
@@ -8,9 +8,9 @@
use DBIC::SqlMakerTest;
my $schema = DBICTest->init_schema();
+my $sdebug = $schema->storage->debug;
-#plan tests => 4;
-plan 'no_plan';
+plan tests => 6;
my $artist = $schema->resultset ('Artist')->first;
@@ -74,6 +74,7 @@
});
$schema->storage->debugcb(undef);
+$schema->storage->debug ($sdebug);
is_same_sql (
$sql[0],
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/relationship/update_or_create_single.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/relationship/update_or_create_single.t 2009-07-01 11:23:46 UTC (rev 6906)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/relationship/update_or_create_single.t 2009-07-01 11:25:42 UTC (rev 6907)
@@ -7,8 +7,7 @@
my $schema = DBICTest->init_schema();
-#plan tests => 4;
-plan 'no_plan';
+plan tests => 9;
my $artist = $schema->resultset ('Artist')->first;
More information about the Bast-commits
mailing list