[Bast-commits] r6948 - in
DBIx-Class/0.08/branches/unresolvable_prefetch: .
lib/DBIx/Class lib/DBIx/Class/Storage
lib/DBIx/Class/Storage/DBI lib/DBIx/Class/Storage/DBI/Oracle
lib/DBIx/Class/Storage/DBI/Sybase t t/cdbi t/count t/prefetch
t/relationship
ribasushi at dev.catalyst.perl.org
ribasushi at dev.catalyst.perl.org
Thu Jul 2 20:55:02 GMT 2009
Author: ribasushi
Date: 2009-07-02 20:55:02 +0000 (Thu, 02 Jul 2009)
New Revision: 6948
Added:
DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Sybase/Base.pm
Modified:
DBIx-Class/0.08/branches/unresolvable_prefetch/
DBIx-Class/0.08/branches/unresolvable_prefetch/Changes
DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/ResultSet.pm
DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/ResultSource.pm
DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Row.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/Oracle/Generic.pm
DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Sybase.pm
DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Sybase/Microsoft_SQL_Server.pm
DBIx-Class/0.08/branches/unresolvable_prefetch/t/746sybase.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/74mssql.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/83cache.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/cdbi/02-Film.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/count/count_rs.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/count/joined.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/count/prefetch.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/prefetch/count.t
DBIx-Class/0.08/branches/unresolvable_prefetch/t/relationship/core.t
Log:
r6910 at Thesaurus (orig r6909): ribasushi | 2009-07-01 13:27:15 +0200
Optimize set_column on uninserted objects
r6921 at Thesaurus (orig r6920): caelum | 2009-07-01 17:40:32 +0200
r5859 at hlagh (orig r6912): caelum | 2009-07-01 06:21:30 -0700
new connected() for dbd::sybase users
r5860 at hlagh (orig r6913): caelum | 2009-07-01 06:25:46 -0700
add a couple of dbd::sybase reconnection tests
r5861 at hlagh (orig r6914): caelum | 2009-07-01 06:35:07 -0700
better connection test
r5862 at hlagh (orig r6915): caelum | 2009-07-01 06:45:05 -0700
use dbh->do for connected instead of prepare_cached
r5863 at hlagh (orig r6916): ribasushi | 2009-07-01 06:55:21 -0700
Segfault
r5864 at hlagh (orig r6917): caelum | 2009-07-01 07:03:22 -0700
use ->do instead of ->prepare_cached in oracle's connected() too
r5865 at hlagh (orig r6918): caelum | 2009-07-01 08:20:52 -0700
fix segfault with old DBD::Sybase
r5866 at hlagh (orig r6919): caelum | 2009-07-01 08:39:18 -0700
move connection tests into _ping()
r6924 at Thesaurus (orig r6923): ijw | 2009-07-01 19:34:32 +0200
Added a test for a resultset to related-resultset join for 0 related records
r6928 at Thesaurus (orig r6927): ijw | 2009-07-01 20:04:16 +0200
Additional tests on prefetch - illustrates the bug with left-join has_many (NULL row returned) and the one that results from the trivial fix (prefetch gives no artist)
r6932 at Thesaurus (orig r6931): ribasushi | 2009-07-02 08:08:33 +0200
Another candidate for somethingawful.com (fix left join-ed count)
r6934 at Thesaurus (orig r6933): ribasushi | 2009-07-02 09:04:13 +0200
Changelog
r6935 at Thesaurus (orig r6934): ribasushi | 2009-07-02 11:23:48 +0200
cleanup
r6936 at Thesaurus (orig r6935): ijw | 2009-07-02 12:41:01 +0200
Check fetched rows == count for related resultsets
r6937 at Thesaurus (orig r6936): ijw | 2009-07-02 12:43:47 +0200
Confirm prefetch doesn't affect main row fetch, and main row fetch works with and without counting
r6938 at Thesaurus (orig r6937): ribasushi | 2009-07-02 12:52:51 +0200
More fail (fix is known but needs work)
r6939 at Thesaurus (orig r6938): ribasushi | 2009-07-02 13:07:22 +0200
And more fail
r6940 at Thesaurus (orig r6939): ribasushi | 2009-07-02 13:16:46 +0200
These tests are in prefetch/count.t
r6941 at Thesaurus (orig r6940): ribasushi | 2009-07-02 13:38:31 +0200
cleanup
r6942 at Thesaurus (orig r6941): ribasushi | 2009-07-02 13:38:49 +0200
Solve more prefetch inflation crap
r6943 at Thesaurus (orig r6942): ribasushi | 2009-07-02 13:47:41 +0200
Make the code readable
r6944 at Thesaurus (orig r6943): ribasushi | 2009-07-02 15:52:35 +0200
Everything works, just need to fix join-path chaining over search_related (to guard against obscure db quirks)
r6946 at Thesaurus (orig r6945): caelum | 2009-07-02 21:06:32 +0200
add sybase reconnect test
r6948 at Thesaurus (orig r6947): ribasushi | 2009-07-02 22:20:21 +0200
Last part of the join handling puzzle
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/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
+ 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/syb_connected:6919
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:6947
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/Changes
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/Changes 2009-07-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/Changes 2009-07-02 20:55:02 UTC (rev 6948)
@@ -1,16 +1,33 @@
Revision history for DBIx::Class
+ - Fixed the has_many prefetch with limit/group deficiency -
+ it is now possible to select "top 5 commenters" while
+ prefetching all their comments
+ - New resultsed method count_rs, returns a ::ResultSetColumn
+ which in turn returns a single count value
+ - Even better support of count with limit
+ - count/all on related left-joined empty resultsets now correctly
+ returns 0/()
- Fixed regression when both page and offset are specified on
a resultset
- Fixed HRI returning too many empty results on multilevel
nonexisting prefetch
- - Fixed the prefetch with limit bug
- - New resultsed method count_rs, returns a ::ResultSetColumn
- which in turn returns a single count value
- make_column_dirty() now overwrites the deflated value with an
inflated one if such exists
- Fixed set_$rel with where restriction deleting rows outside
the restriction
+ - populate() returns the created objects or an arrayref of the
+ create dobjects depending on scalar vs. list context
+ - Fixed find_related on 'single' relationships - the former
+ implementation would overspecify the WHERE condition, reporting
+ no related objects when there in fact is one
+ - SQL::Translator::Parser::DBIx::Class now attaches tables to the
+ central schema object in relationship dependency order
+ - Fixed regression in set_column() preventing sourceless object
+ manipulations
+ - Fixed a bug in search_related doubling a join if the original
+ $rs already joins/prefetches the same relation
+ - Storage::DBI::connected() improvements for Oracle and Sybase
0.08107 2009-06-14 08:21:00 (UTC)
- Fix serialization regression introduced in 0.08103 (affects
@@ -27,8 +44,8 @@
- Update of numeric columns now properly uses != to determine
dirtyness instead of the usual eq
- Fixes to IC::DT tests
- - Fixed exception when undef_if_invalid and timezone are both set on
- an invalid datetime column
+ - Fixed exception when undef_if_invalid and timezone are both set
+ on an invalid datetime column
0.08104 2009-06-10 13:38:00 (UTC)
- order_by now can take \[$sql, @bind] as in
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-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/ResultSet.pm 2009-07-02 20:55:02 UTC (rev 6948)
@@ -957,7 +957,9 @@
sub _construct_object {
my ($self, @row) = @_;
- my $info = $self->_collapse_result($self->{_attrs}{as}, \@row);
+
+ my $info = $self->_collapse_result($self->{_attrs}{as}, \@row)
+ or return ();
my @new = $self->result_class->inflate_result($self->result_source, @$info);
@new = $self->{_attrs}{record_filter}->(@new)
if exists $self->{_attrs}{record_filter};
@@ -967,6 +969,19 @@
sub _collapse_result {
my ($self, $as_proto, $row) = @_;
+ # if the first row that ever came in is totally empty - this means we got
+ # hit by a smooth^Wempty left-joined resultset. Just noop in that case
+ # instead of producing a {}
+ #
+ my $has_def;
+ for (@$row) {
+ if (defined $_) {
+ $has_def++;
+ last;
+ }
+ }
+ return undef unless $has_def;
+
my @copy = @$row;
# 'foo' => [ undef, 'foo' ]
@@ -1227,6 +1242,11 @@
$tmp_attrs->{select} = $rsrc->storage->_count_select ($rsrc, $tmp_attrs);
$tmp_attrs->{as} = 'count';
+ # read the comment on top of the actual function to see what this does
+ $tmp_attrs->{from} = $self->_switch_to_inner_join_if_needed (
+ $tmp_attrs->{from}, $tmp_attrs->{alias}
+ );
+
my $tmp_rs = $rsrc->resultset_class->new($rsrc, $tmp_attrs)->get_column ('count');
return $tmp_rs;
@@ -1254,6 +1274,11 @@
$sub_attrs->{select} = $rsrc->storage->_subq_count_select ($rsrc, $sub_attrs);
+ # read the comment on top of the actual function to see what this does
+ $sub_attrs->{from} = $self->_switch_to_inner_join_if_needed (
+ $sub_attrs->{from}, $sub_attrs->{alias}
+ );
+
$attrs->{from} = [{
count_subq => $rsrc->resultset_class->new ($rsrc, $sub_attrs )->as_query
}];
@@ -1265,6 +1290,77 @@
}
+# The DBIC relationship chaining implementation is pretty simple - every
+# new related_relationship is pushed onto the {from} stack, and the {select}
+# window simply slides further in. This means that when we count somewhere
+# in the middle, we got to make sure that everything in the join chain is an
+# actual inner join, otherwise the count will come back with unpredictable
+# results (a resultset may be generated with _some_ rows regardless of if
+# the relation which the $rs currently selects has rows or not). E.g.
+# $artist_rs->cds->count - normally generates:
+# SELECT COUNT( * ) FROM artist me LEFT JOIN cd cds ON cds.artist = me.artistid
+# which actually returns the number of artists * (number of cds || 1)
+#
+# So what we do here is crawl {from}, determine if the current alias is at
+# the top of the stack, and if not - make sure the chain is inner-joined down
+# to the root.
+#
+sub _switch_to_inner_join_if_needed {
+ my ($self, $from, $alias) = @_;
+
+ return $from if (
+ ref $from ne 'ARRAY'
+ ||
+ ref $from->[0] ne 'HASH'
+ ||
+ ! $from->[0]{-alias}
+ ||
+ $from->[0]{-alias} eq $alias
+ );
+
+ # this would be the case with a subquery - we'll never find
+ # the target as it is not in the parseable part of {from}
+ return $from if @$from == 1;
+
+ my $switch_branch;
+ JOINSCAN:
+ for my $j (@{$from}[1 .. $#$from]) {
+ if ($j->[0]{-alias} eq $alias) {
+ $switch_branch = $j->[0]{-join_path};
+ last JOINSCAN;
+ }
+ }
+
+ # something else went wrong
+ return $from unless $switch_branch;
+
+ # So it looks like we will have to switch some stuff around.
+ # local() is useless here as we will be leaving the scope
+ # anyway, and deep cloning is just too fucking expensive
+ # So replace the inner hashref manually
+ my @new_from = ($from->[0]);
+ my $sw_idx = { map { $_ => 1 } @$switch_branch };
+
+ for my $j (@{$from}[1 .. $#$from]) {
+ my $jalias = $j->[0]{-alias};
+
+ if ($sw_idx->{$jalias}) {
+ my %attrs = %{$j->[0]};
+ delete $attrs{-join_type};
+ push @new_from, [
+ \%attrs,
+ @{$j}[ 1 .. $#$j ],
+ ];
+ }
+ else {
+ push @new_from, $j;
+ }
+ }
+
+ return \@new_from;
+}
+
+
sub _bool {
return 1;
}
@@ -1329,6 +1425,7 @@
}
$self->set_cache(\@obj) if $self->{attrs}{cache};
+
return @obj;
}
@@ -1926,16 +2023,25 @@
# of the attributes supplied
#
# used to determine if a subquery is neccessary
+#
+# supports some virtual attributes:
+# -join
+# This will scan for any joins being present on the resultset.
+# It is not a mere key-search but a deep inspection of {from}
+#
sub _has_resolved_attr {
my ($self, @attr_names) = @_;
my $attrs = $self->_resolved_attrs;
- my $join_check_req;
+ my %extra_checks;
for my $n (@attr_names) {
- ++$join_check_req if $n eq '-join';
+ if (grep { $n eq $_ } (qw/-join/) ) {
+ $extra_checks{$n}++;
+ next;
+ }
my $attr = $attrs->{$n};
@@ -1954,7 +2060,7 @@
# a resolved join is expressed as a multi-level from
return 1 if (
- $join_check_req
+ $extra_checks{-join}
and
ref $attrs->{from} eq 'ARRAY'
and
@@ -2549,6 +2655,11 @@
# in order to properly resolve prefetch aliases (any alias
# with a relation_chain_depth less than the depth of the
# current prefetch is not considered)
+#
+# The increments happen in 1/2s to make it easier to correlate the
+# join depth with the join path. An integer means a relationship
+# specified via a search_related, whereas a fraction means an added
+# join/prefetch via attributes
sub _chain_relationship {
my ($self, $rel) = @_;
my $source = $self->result_source;
@@ -2565,16 +2676,25 @@
}];
my $seen = { %{$attrs->{seen_join} || {} } };
+ my $jpath = ($attrs->{seen_join} && keys %{$attrs->{seen_join}})
+ ? $from->[-1][0]{-join_path}
+ : [];
+
# we need to take the prefetch the attrs into account before we
# ->_resolve_join as otherwise they get lost - captainL
my $merged = $self->_merge_attr( $attrs->{join}, $attrs->{prefetch} );
- my @requested_joins = $source->_resolve_join($merged, $attrs->{alias}, $seen);
+ my @requested_joins = $source->_resolve_join(
+ $merged,
+ $attrs->{alias},
+ $seen,
+ $jpath,
+ );
push @$from, @requested_joins;
- ++$seen->{-relation_chain_depth};
+ $seen->{-relation_chain_depth} += 0.5;
# if $self already had a join/prefetch specified on it, the requested
# $rel might very well be already included. What we do in this case
@@ -2582,19 +2702,36 @@
# the join in question so we could tell it *is* the search_related)
my $already_joined;
+
# we consider the last one thus reverse
for my $j (reverse @requested_joins) {
if ($rel eq $j->[0]{-join_path}[-1]) {
- $j->[0]{-relation_chain_depth}++;
+ $j->[0]{-relation_chain_depth} += 0.5;
$already_joined++;
last;
}
}
+
+# alternative way to scan the entire chain - not backwards compatible
+# for my $j (reverse @$from) {
+# next unless ref $j eq 'ARRAY';
+# if ($j->[0]{-join_path} && $j->[0]{-join_path}[-1] eq $rel) {
+# $j->[0]{-relation_chain_depth} += 0.5;
+# $already_joined++;
+# last;
+# }
+# }
+
unless ($already_joined) {
- push @$from, $source->_resolve_join($rel, $attrs->{alias}, $seen);
+ push @$from, $source->_resolve_join(
+ $rel,
+ $attrs->{alias},
+ $seen,
+ $jpath,
+ );
}
- ++$seen->{-relation_chain_depth};
+ $seen->{-relation_chain_depth} += 0.5;
return ($from,$seen);
}
@@ -2706,7 +2843,13 @@
[
@{ $attrs->{from} },
$source->_resolve_join(
- $join, $alias, { %{ $attrs->{seen_join} || {} } }
+ $join,
+ $alias,
+ { %{ $attrs->{seen_join} || {} } },
+ ($attrs->{seen_join} && keys %{$attrs->{seen_join}})
+ ? $attrs->{from}[-1][0]{-join_path}
+ : []
+ ,
)
];
}
@@ -2759,8 +2902,11 @@
# even though it doesn't make much sense, this is what pre 081xx has
# been doing
if (my $page = delete $attrs->{page}) {
- $attrs->{offset} = ($attrs->{rows} * ($page - 1)) +
- ($attrs->{offset} || 0);
+ $attrs->{offset} =
+ ($attrs->{rows} * ($page - 1))
+ +
+ ($attrs->{offset} || 0)
+ ;
}
return $self->{_attrs} = $attrs;
@@ -2772,13 +2918,21 @@
my $paths = {};
return $paths unless ref $fromspec eq 'ARRAY';
+ my $cur_depth = $seen->{-relation_chain_depth} || 0;
+
+ if (int ($cur_depth) != $cur_depth) {
+ $self->throw_exception ("-relation_chain_depth is not an integer, something went horribly wrong ($cur_depth)");
+ }
+
for my $j (@$fromspec) {
next if ref $j ne 'ARRAY';
- next if $j->[0]{-relation_chain_depth} < ( $seen->{-relation_chain_depth} || 0);
+ next if $j->[0]{-relation_chain_depth} < $cur_depth;
+ my $jpath = $j->[0]{-join_path};
+
my $p = $paths;
- $p = $p->{$_} ||= {} for @{$j->[0]{-join_path}};
+ $p = $p->{$_} ||= {} for @{$jpath}[$cur_depth .. $#$jpath];
push @{$p->{-join_aliases} }, $j->[0]{-alias};
}
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/ResultSource.pm
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/ResultSource.pm 2009-07-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/ResultSource.pm 2009-07-02 20:55:02 UTC (rev 6948)
@@ -893,7 +893,7 @@
}
return unless $f_source; # Can't test rel without f_source
- eval { $self->_resolve_join($rel, 'me', {}) };
+ eval { $self->_resolve_join($rel, 'me', {}, []) };
if ($@) { # If the resolve failed, back out and re-throw the error
delete $rels{$rel}; #
@@ -1087,19 +1087,17 @@
# we need a supplied one, because we do in-place modifications, no returns
$self->throw_exception ('You must supply a seen hashref as the 3rd argument to _resolve_join')
- unless $seen;
+ unless ref $seen eq 'HASH';
- # This isn't quite right, we should actually dive into $seen and reconstruct
- # the entire path (the reference entry point would be the join conditional
- # with depth == current_depth - 1. At this point however nothing depends on
- # having the entire path, transcending related_resultset, so just leave it
- # as is, hairy enough already.
- $jpath ||= [];
+ $self->throw_exception ('You must supply a joinpath arrayref as the 4th argument to _resolve_join')
+ unless ref $jpath eq 'ARRAY';
+ $jpath = [@$jpath];
+
if (ref $join eq 'ARRAY') {
return
map {
- $self->_resolve_join($_, $alias, $seen, [@$jpath], $force_left);
+ $self->_resolve_join($_, $alias, $seen, $jpath, $force_left);
} @$join;
} elsif (ref $join eq 'HASH') {
return
@@ -1341,15 +1339,14 @@
"don't know how to resolve prefetch reftype ".ref($pre));
}
else {
-
my $p = $alias_map;
$p = $p->{$_} for (@$pref_path, $pre);
$self->throw_exception (
- "Unable to resolve prefetch $pre - join alias map does not contain an entry for path "
+ "Unable to resolve prefetch $pre - join alias map does not contain an entry for path: "
. join (' -> ', @$pref_path, $pre)
) if (ref $p->{-join_aliases} ne 'ARRAY' or not @{$p->{-join_aliases}} );
-
+
my $as = shift @{$p->{-join_aliases}};
my $rel_info = $self->relationship_info( $pre );
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Row.pm
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Row.pm 2009-07-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Row.pm 2009-07-02 20:55:02 UTC (rev 6948)
@@ -787,9 +787,12 @@
$self->store_column($column, $new_value);
my $dirty;
- if (defined $old_value xor defined $new_value) {
+ if (!$self->in_storage) { # no point tracking dirtyness on uninserted data
$dirty = 1;
}
+ elsif (defined $old_value xor defined $new_value) {
+ $dirty = 1;
+ }
elsif (not defined $old_value) { # both undef
$dirty = 0;
}
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm 2009-07-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm 2009-07-02 20:55:02 UTC (rev 6948)
@@ -83,36 +83,18 @@
return $id;
}
-=head2 connected
-
-Returns true if we have an open (and working) database connection, false if it is not (yet)
-open (or does not work). (Executes a simple SELECT to make sure it works.)
-
-The reason this is needed is that L<DBD::Oracle>'s ping() does not do a real
-OCIPing but just gets the server version, which doesn't help if someone killed
-your session.
-
-=cut
-
-sub connected {
+sub _ping {
my $self = shift;
- if (not $self->next::method(@_)) {
- return 0;
- }
- else {
- my $dbh = $self->_dbh;
+ my $dbh = $self->_dbh or return 0;
- local $dbh->{RaiseError} = 1;
+ local $dbh->{RaiseError} = 1;
- eval {
- my $ping_sth = $dbh->prepare_cached("select 1 from dual");
- $ping_sth->execute;
- $ping_sth->finish;
- };
+ eval {
+ $dbh->do("select 1 from dual");
+ };
- return $@ ? 0 : 1;
- }
+ return $@ ? 0 : 1;
}
sub _dbh_execute {
Added: DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Sybase/Base.pm
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Sybase/Base.pm (rev 0)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Sybase/Base.pm 2009-07-02 20:55:02 UTC (rev 6948)
@@ -0,0 +1,37 @@
+package # hide from PAUSE
+ DBIx::Class::Storage::DBI::Sybase::Base;
+
+use strict;
+use warnings;
+
+=head1 NAME
+
+DBIx::Class::Storage::DBI::Sybase::Base - Common functionality for drivers using
+DBD::Sybase
+
+=cut
+
+sub _ping {
+ my $self = shift;
+
+ my $dbh = $self->_dbh or return 0;
+
+ local $dbh->{RaiseError} = 1;
+ eval {
+ $dbh->do('select 1');
+ };
+
+ return $@ ? 0 : 1;
+}
+
+1;
+
+=head1 AUTHORS
+
+See L<DBIx::Class/CONTRIBUTORS>.
+
+=head1 LICENSE
+
+You may distribute this code under the same terms as Perl itself.
+
+=cut
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Sybase/Microsoft_SQL_Server.pm
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Sybase/Microsoft_SQL_Server.pm 2009-07-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Sybase/Microsoft_SQL_Server.pm 2009-07-02 20:55:02 UTC (rev 6948)
@@ -2,10 +2,10 @@
use strict;
use warnings;
-
+use mro 'c3';
use base qw/
+ DBIx::Class::Storage::DBI::Sybase::Base
DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server
- DBIx::Class::Storage::DBI::Sybase
/;
1;
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Sybase.pm
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Sybase.pm 2009-07-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI/Sybase.pm 2009-07-02 20:55:02 UTC (rev 6948)
@@ -2,9 +2,12 @@
use strict;
use warnings;
+use mro 'c3';
+use base qw/
+ DBIx::Class::Storage::DBI::Sybase::Base
+ DBIx::Class::Storage::DBI::NoBindVars
+/;
-use base qw/DBIx::Class::Storage::DBI::NoBindVars/;
-
sub _rebless {
my $self = shift;
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-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/lib/DBIx/Class/Storage/DBI.pm 2009-07-02 20:55:02 UTC (rev 6948)
@@ -669,12 +669,20 @@
$self->_verify_pid;
return 0 if !$self->_dbh;
}
- return ($dbh->FETCH('Active') && $dbh->ping);
+ return ($dbh->FETCH('Active') && $self->_ping);
}
return 0;
}
+sub _ping {
+ my $self = shift;
+
+ my $dbh = $self->_dbh or return 0;
+
+ return $dbh->ping;
+}
+
# handle pid changes correctly
# NOTE: assumes $self->_dbh is a valid $dbh
sub _verify_pid {
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/746sybase.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/746sybase.t 2009-07-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/746sybase.t 2009-07-02 20:55:02 UTC (rev 6948)
@@ -2,6 +2,7 @@
use warnings;
use Test::More;
+use Test::Exception;
use lib qw(t/lib);
use DBICTest;
@@ -10,13 +11,21 @@
plan skip_all => 'Set $ENV{DBICTEST_SYBASE_DSN}, _USER and _PASS to run this test'
unless ($dsn && $user);
-plan tests => 12;
+plan tests => 13;
my $schema = DBICTest::Schema->connect($dsn, $user, $pass, {AutoCommit => 1});
+# start disconnected to test reconnection
$schema->storage->ensure_connected;
+$schema->storage->_dbh->disconnect;
+
isa_ok( $schema->storage, 'DBIx::Class::Storage::DBI::Sybase' );
+my $dbh;
+lives_ok (sub {
+ $dbh = $schema->storage->dbh;
+}, 'reconnect works');
+
$schema->storage->dbh_do (sub {
my ($storage, $dbh) = @_;
eval { $dbh->do("DROP TABLE artist") };
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/74mssql.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/74mssql.t 2009-07-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/74mssql.t 2009-07-02 20:55:02 UTC (rev 6948)
@@ -9,6 +9,7 @@
}
use Test::More;
+use Test::Exception;
use lib qw(t/lib);
use DBICTest;
@@ -17,15 +18,22 @@
plan skip_all => 'Set $ENV{DBICTEST_MSSQL_DSN}, _USER and _PASS to run this test'
unless ($dsn);
-plan tests => 6;
+plan tests => 7;
my $schema = DBICTest::Schema->clone;
$schema->connection($dsn, $user, $pass);
-my $dbh = $schema->storage->dbh;
+# start disconnected to test reconnection
+$schema->storage->ensure_connected;
+$schema->storage->_dbh->disconnect;
isa_ok($schema->storage, 'DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server');
+my $dbh;
+lives_ok (sub {
+ $dbh = $schema->storage->dbh;
+}, 'reconnect works');
+
$dbh->do("IF OBJECT_ID('artist', 'U') IS NOT NULL
DROP TABLE artist");
$dbh->do("IF OBJECT_ID('cd', 'U') IS NOT NULL
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/83cache.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/83cache.t 2009-07-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/83cache.t 2009-07-02 20:55:02 UTC (rev 6948)
@@ -8,7 +8,7 @@
my $schema = DBICTest->init_schema();
my $queries;
-$schema->storage->debugcb( sub{ $queries++ } );
+my $debugcb = sub{ $queries++ };
my $sdebug = $schema->storage->debug;
plan tests => 23;
@@ -45,6 +45,7 @@
$queries = 0;
$schema->storage->debug(1);
+$schema->storage->debugcb ($debugcb);
$rs = $schema->resultset('Artist')->search( undef, { cache => 1 } );
while( $artist = $rs->next ) {}
@@ -53,6 +54,7 @@
is( $queries, 1, 'revisiting a row does not issue a query when cache => 1' );
$schema->storage->debug($sdebug);
+$schema->storage->debugcb (undef);
my @a = $schema->resultset("Artist")->search(
{ },
@@ -77,6 +79,7 @@
# start test for prefetch SELECT count
$queries = 0;
$schema->storage->debug(1);
+$schema->storage->debugcb ($debugcb);
$artist = $rs->first;
$rs->reset();
@@ -99,6 +102,7 @@
is($queries, 1, 'only one SQL statement executed');
$schema->storage->debug($sdebug);
+$schema->storage->debugcb (undef);
# make sure related_resultset is deleted after object is updated
$artist->set_column('name', 'New Name');
@@ -130,18 +134,21 @@
# SELECT count for nested has_many prefetch
$queries = 0;
$schema->storage->debug(1);
+$schema->storage->debugcb ($debugcb);
$artist = ($rs->all)[0];
is($queries, 1, 'only one SQL statement executed');
$schema->storage->debug($sdebug);
+$schema->storage->debugcb (undef);
my @objs;
#$artist = $rs->find(1);
$queries = 0;
$schema->storage->debug(1);
+$schema->storage->debugcb ($debugcb);
my $cds = $artist->cds;
my $tags = $cds->next->tags;
@@ -185,4 +192,4 @@
is( $queries, 1, 'only one select statement on find with has_many prefetch on resultset' );
$schema->storage->debug($sdebug);
-
+$schema->storage->debugcb (undef);
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/cdbi/02-Film.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/cdbi/02-Film.t 2009-07-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/cdbi/02-Film.t 2009-07-02 20:55:02 UTC (rev 6948)
@@ -8,8 +8,7 @@
plan (skip_all => 'Class::Trigger and DBIx::ContextualFetch required');
next;
}
- eval "use DBD::SQLite";
- plan $@ ? (skip_all => 'needs DBD::SQLite for testing') : (tests => 98);
+ plan tests => 98;
}
INIT {
@@ -187,17 +186,14 @@
ok(!Film->retrieve('Ishtar'), 'Ishtar no longer there');
{
my $deprecated = 0;
- #local $SIG{__WARN__} = sub { $deprecated++ if $_[0] =~ /deprecated/ };
+ local $SIG{__WARN__} = sub { $deprecated++ if $_[0] =~ /deprecated/ };
ok(
Film->delete(Director => 'Elaine May'),
"In fact, delete all films by Elaine May"
);
cmp_ok(Film->search(Director => 'Elaine May'), '==',
0, "0 Films by Elaine May");
- SKIP: {
- skip "No deprecated warnings from compat layer", 1;
- is $deprecated, 1, "Got a deprecated warning";
- }
+ is $deprecated, 0, "No deprecated warnings from compat layer";
}
};
is $@, '', "No problems with deletes";
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/count/count_rs.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/count/count_rs.t 2009-07-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/count/count_rs.t 2009-07-02 20:55:02 UTC (rev 6948)
@@ -33,7 +33,7 @@
\@bind,
'SELECT COUNT( * )
FROM cd me
- LEFT JOIN track tracks ON tracks.cd = me.cdid
+ JOIN track tracks ON tracks.cd = me.cdid
JOIN cd disc ON disc.cdid = tracks.cd
LEFT JOIN lyrics lyrics ON lyrics.track_id = tracks.trackid
WHERE ( ( position = ? OR position = ? ) )
@@ -51,7 +51,7 @@
FROM (
SELECT tracks.trackid
FROM cd me
- LEFT JOIN track tracks ON tracks.cd = me.cdid
+ JOIN track tracks ON tracks.cd = me.cdid
JOIN cd disc ON disc.cdid = tracks.cd
LEFT JOIN lyrics lyrics ON lyrics.track_id = tracks.trackid
WHERE ( ( position = ? OR position = ? ) )
@@ -85,7 +85,7 @@
FROM (
SELECT cds.cdid
FROM artist me
- LEFT JOIN cd cds ON cds.artist = me.artistid
+ JOIN cd cds ON cds.artist = me.artistid
LEFT JOIN track tracks ON tracks.cd = cds.cdid
JOIN artist artist ON artist.artistid = cds.artist
WHERE tracks.position = ? OR tracks.position = ?
@@ -105,7 +105,7 @@
FROM (
SELECT cds.cdid
FROM artist me
- LEFT JOIN cd cds ON cds.artist = me.artistid
+ JOIN cd cds ON cds.artist = me.artistid
LEFT JOIN track tracks ON tracks.cd = cds.cdid
JOIN artist artist ON artist.artistid = cds.artist
WHERE tracks.position = ? OR tracks.position = ?
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/count/joined.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/count/joined.t 2009-07-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/count/joined.t 2009-07-02 20:55:02 UTC (rev 6948)
@@ -7,7 +7,7 @@
use DBICTest;
-plan tests => 3;
+plan tests => 7;
my $schema = DBICTest->init_schema();
@@ -26,6 +26,12 @@
"Count correct with requested distinct collapse of main table"
);
+# JOIN and LEFT JOIN issues mean that we've seen problems where counted rows and fetched rows are sometimes 1 higher than they should
+# be in the related resultset.
+my $artist=$schema->resultset('Artist')->create({name => 'xxx'});
+is($artist->related_resultset('cds')->count(), 0, "No CDs found for a shiny new artist");
+is(scalar($artist->related_resultset('cds')->all()), 0, "No CDs fetched for a shiny new artist");
-
-
+my $artist_rs = $schema->resultset('Artist')->search({artistid => $artist->id});
+is($artist_rs->related_resultset('cds')->count(), 0, "No CDs counted for a shiny new artist using a resultset search");
+is(scalar($artist_rs->related_resultset('cds')->all), 0, "No CDs fetched for a shiny new artist using a resultset search");
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/count/prefetch.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/count/prefetch.t 2009-07-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/count/prefetch.t 2009-07-02 20:55:02 UTC (rev 6948)
@@ -32,7 +32,7 @@
is_same_sql_bind (
$sql,
\@bind,
- 'SELECT COUNT( * ) FROM (SELECT cds.cdid FROM artist me LEFT JOIN cd cds ON cds.artist = me.artistid LEFT JOIN track tracks ON tracks.cd = cds.cdid JOIN artist artist ON artist.artistid = cds.artist WHERE tracks.position = ? OR tracks.position = ? GROUP BY cds.cdid) count_subq',
+ 'SELECT COUNT( * ) FROM (SELECT cds.cdid FROM artist me JOIN cd cds ON cds.artist = me.artistid LEFT JOIN track tracks ON tracks.cd = cds.cdid JOIN artist artist ON artist.artistid = cds.artist WHERE tracks.position = ? OR tracks.position = ? GROUP BY cds.cdid) count_subq',
[ qw/'1' '2'/ ],
);
}
@@ -57,7 +57,7 @@
is_same_sql_bind (
$sql,
\@bind,
- 'SELECT COUNT( * ) FROM cd me LEFT JOIN track tracks ON tracks.cd = me.cdid JOIN cd disc ON disc.cdid = tracks.cd LEFT JOIN lyrics lyrics ON lyrics.track_id = tracks.trackid WHERE ( ( position = ? OR position = ? ) )',
+ 'SELECT COUNT( * ) FROM cd me JOIN track tracks ON tracks.cd = me.cdid JOIN cd disc ON disc.cdid = tracks.cd LEFT JOIN lyrics lyrics ON lyrics.track_id = tracks.trackid WHERE ( ( position = ? OR position = ? ) )',
[ qw/'1' '2'/ ],
);
}
Modified: DBIx-Class/0.08/branches/unresolvable_prefetch/t/prefetch/count.t
===================================================================
--- DBIx-Class/0.08/branches/unresolvable_prefetch/t/prefetch/count.t 2009-07-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/prefetch/count.t 2009-07-02 20:55:02 UTC (rev 6948)
@@ -4,8 +4,9 @@
use Test::More;
use lib qw(t/lib);
use DBICTest;
+use DBIC::SqlMakerTest;
-plan tests => 5;
+plan tests => 23;
my $schema = DBICTest->init_schema();
@@ -22,3 +23,79 @@
is($cd_rs->search_related('tracks')->count, 15, 'Tracks associated with CDs count (after SELECT()ing)');
is($cd_rs->search_related ('tracks')->all, 15, 'Track objects associated with CDs (after SELECT()ing)');
+
+my $artist = $schema->resultset('Artist')->create({name => 'xxx'});
+
+my $artist_rs = $schema->resultset('Artist')->search(
+ {artistid => $artist->id},
+ {prefetch=>'cds', join => 'twokeys' }
+);
+
+is($artist_rs->count, 1, "New artist found with prefetch turned on");
+is(scalar($artist_rs->all), 1, "New artist fetched with prefetch turned on");
+is($artist_rs->related_resultset('cds')->count, 0, "No CDs counted on a brand new artist");
+is(scalar($artist_rs->related_resultset('cds')->all), 0, "No CDs fetched on a brand new artist (count == fetch)");
+
+# create a cd, and make sure the non-existing join does not skew the count
+$artist->create_related ('cds', { title => 'yyy', year => '1999' });
+is($artist_rs->related_resultset('cds')->count, 1, "1 CDs counted on a brand new artist");
+is(scalar($artist_rs->related_resultset('cds')->all), 1, "1 CDs prefetched on a brand new artist (count == fetch)");
+
+# Really fuck shit up with one more cd and some insanity
+# this doesn't quite work as there are the prefetch gets lost
+# on search_related. This however is too esoteric to fix right
+# now
+
+my $cd2 = $artist->create_related ('cds', {
+ title => 'zzz',
+ year => '1999',
+ tracks => [{ title => 'ping' }, { title => 'pong' }],
+});
+
+my $cds = $cd2->search_related ('artist', {}, { join => 'twokeys' })
+ ->search_related ('cds');
+my $tracks = $cds->search_related ('tracks');
+
+is($tracks->count, 2, "2 Tracks counted on cd via artist via one of the cds");
+is(scalar($tracks->all), 2, "2 Track objects on cd via artist via one of the cds");
+
+is($cds->count, 2, "2 CDs counted on artist via one of the cds");
+is(scalar($cds->all), 2, "2 CD objectson artist via one of the cds");
+
+# make sure the join collapses all the way
+is_same_sql_bind (
+ $tracks->count_rs->as_query,
+ '(
+ SELECT COUNT( * )
+ FROM artist me
+ LEFT JOIN twokeys twokeys ON twokeys.artist = me.artistid
+ JOIN cd cds ON cds.artist = me.artistid
+ JOIN track tracks ON tracks.cd = cds.cdid
+ WHERE ( me.artistid = ? )
+ )',
+ [ [ 'me.artistid' => 4 ] ],
+);
+
+
+TODO: {
+ local $TODO = "Chaining with prefetch is fundamentally broken";
+
+ my $queries;
+ $schema->storage->debugcb ( sub { $queries++ } );
+ $schema->storage->debug (1);
+
+ my $cds = $cd2->search_related ('artist', {}, { prefetch => { cds => 'tracks' }, join => 'twokeys' })
+ ->search_related ('cds');
+
+ my $tracks = $cds->search_related ('tracks');
+
+ is($tracks->count, 2, "2 Tracks counted on cd via artist via one of the cds");
+ is(scalar($tracks->all), 2, "2 Tracks prefetched on cd via artist via one of the cds");
+ is($tracks->count, 2, "Cached 2 Tracks counted on cd via artist via one of the cds");
+
+ is($cds->count, 2, "2 CDs counted on artist via one of the cds");
+ is(scalar($cds->all), 2, "2 CDs prefetched on artist via one of the cds");
+ is($cds->count, 2, "Cached 2 CDs counted on artist via one of the cds");
+
+ is ($queries, 3, '2 counts + 1 prefetch?');
+}
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-02 20:20:21 UTC (rev 6947)
+++ DBIx-Class/0.08/branches/unresolvable_prefetch/t/relationship/core.t 2009-07-02 20:55:02 UTC (rev 6948)
@@ -9,7 +9,7 @@
my $schema = DBICTest->init_schema();
my $sdebug = $schema->storage->debug;
-plan tests => 78;
+plan tests => 79;
# has_a test
my $cd = $schema->resultset("CD")->find(4);
@@ -276,11 +276,11 @@
cmp_ok($searched->count, '==', 2, "Both artist returned from map after adding another condition");
-# check join through cascaded has_many relationships
+# check join through cascaded has_many relationships (also empty has_many rels)
$artist = $schema->resultset("Artist")->find(1);
my $trackset = $artist->cds->search_related('tracks');
-# LEFT join means we also see the trackless additional album...
-cmp_ok($trackset->count, '==', 11, "Correct number of tracks for artist");
+is($trackset->count, 10, "Correct number of tracks for artist");
+is($trackset->all, 10, "Correct number of track objects for artist");
# now see about updating eveything that belongs to artist 2 to artist 3
$artist = $schema->resultset("Artist")->find(2);
More information about the Bast-commits
mailing list