[Bast-commits] r6806 - in DBIx-Class/0.08/branches/run_file_against_storage: . lib/DBIx/Class lib/DBIx/Class/InflateColumn lib/DBIx/Class/Manual lib/DBIx/Class/PK/Auto lib/DBIx/Class/Relationship lib/DBIx/Class/ResultClass lib/DBIx/Class/Storage lib/DBIx/Class/Storage/DBI lib/SQL/Translator/Parser/DBIx t t/cdbi/DeepAbstractSearch t/count t/inflate t/lib t/lib/DBICTest/Schema t/multi_create t/prefetch t/relationship

ribasushi at dev.catalyst.perl.org ribasushi at dev.catalyst.perl.org
Sat Jun 27 12:24:52 GMT 2009


Author: ribasushi
Date: 2009-06-27 12:24:52 +0000 (Sat, 27 Jun 2009)
New Revision: 6806

Added:
   DBIx-Class/0.08/branches/run_file_against_storage/t/count/count_rs.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/multi_create/in_memory.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/multi_create/standard.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/multi_create/torture.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/double_prefetch.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/with_limit.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/relationship/update_or_create_multi.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/relationship/update_or_create_single.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/zzzzzzz_sqlite_deadlock.t
Removed:
   DBIx-Class/0.08/branches/run_file_against_storage/t/96multi_create.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/96multi_create_new.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/96multi_create_torture.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/rows_bug.t
Modified:
   DBIx-Class/0.08/branches/run_file_against_storage/
   DBIx-Class/0.08/branches/run_file_against_storage/Changes
   DBIx-Class/0.08/branches/run_file_against_storage/Makefile.PL
   DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/InflateColumn/DateTime.pm
   DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Manual/Cookbook.pod
   DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Manual/Joining.pod
   DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/PK/Auto/Oracle.pm
   DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Relationship/Base.pm
   DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Relationship/ManyToMany.pm
   DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/ResultClass/HashRefInflator.pm
   DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/ResultSet.pm
   DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/ResultSource.pm
   DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Row.pm
   DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Schema.pm
   DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Storage.pm
   DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Storage/DBI.pm
   DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Storage/DBI/mysql.pm
   DBIx-Class/0.08/branches/run_file_against_storage/lib/SQL/Translator/Parser/DBIx/Class.pm
   DBIx-Class/0.08/branches/run_file_against_storage/t/46where_attribute.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/67pager.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/85utf8.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/86sqlt.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/93storage_replication.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/cdbi/DeepAbstractSearch/01_search.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/count/distinct.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/inflate/hri.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/inflate/serialize.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/lib/DBICTest/Schema/ArtistUndirectedMap.pm
   DBIx-Class/0.08/branches/run_file_against_storage/t/lib/DBICTest/Schema/Genre.pm
   DBIx-Class/0.08/branches/run_file_against_storage/t/lib/DBICTest/Schema/TwoKeys.pm
   DBIx-Class/0.08/branches/run_file_against_storage/t/lib/sqlite.sql
   DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/attrs_untouched.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/relationship/core.t
   DBIx-Class/0.08/branches/run_file_against_storage/t/zzzzzzz_perl_perf_bug.t
Log:
 r6671 at Thesaurus (orig r6670):  ribasushi | 2009-06-14 11:00:35 +0200
 Lapse in copy() docs
 r6673 at Thesaurus (orig r6672):  ribasushi | 2009-06-14 11:33:22 +0200
 Forgotten piece of as_query refactor
 r6683 at Thesaurus (orig r6682):  timbunce | 2009-06-15 16:30:21 +0200
 Added note that column inflation is not performed
 
 r6690 at Thesaurus (orig r6689):  timbunce | 2009-06-16 15:06:07 +0200
 Removed wording from txn_do that implies the coderef could be executed more than once.
 
 r6691 at Thesaurus (orig r6690):  timbunce | 2009-06-16 15:14:23 +0200
 Added doc note that txn_commit does not perform an actual storage commit unless 
 there's a DBIx::Class transaction currently in effect
 
 r6692 at Thesaurus (orig r6691):  timbunce | 2009-06-16 15:40:11 +0200
 Reverted doc patch r6689 for now, sadly. I'll open a ticket to explain.
 
 r6694 at Thesaurus (orig r6693):  ribasushi | 2009-06-16 17:22:59 +0200
 Fix possible regression with prefetch select resolution
 r6699 at Thesaurus (orig r6698):  wintrmute | 2009-06-17 10:32:30 +0200
 Replace vague language around whether load_classes/namespaces is preferred,
 with an explanation that load_namespaces() is generally preferred, and explain
 when load_classes is appropriate.
 r6702 at Thesaurus (orig r6701):  caelum | 2009-06-17 19:50:47 +0200
 fix page with offset bug
 r6704 at Thesaurus (orig r6703):  ribasushi | 2009-06-18 08:40:18 +0200
 Cleanup attribute handling - I deal with resolved attributes throughout, no point in complicating things further
 r6705 at Thesaurus (orig r6704):  abraxxa | 2009-06-18 12:30:01 +0200
 added test for nested has_many prefetch without entries
 
 r6707 at Thesaurus (orig r6706):  ribasushi | 2009-06-18 12:43:36 +0200
 HRI fix
 r6708 at Thesaurus (orig r6707):  ribasushi | 2009-06-18 14:05:42 +0200
 wtf
 r6714 at Thesaurus (orig r6713):  caelum | 2009-06-19 01:03:01 +0200
 fix broken link in manual
 r6726 at Thesaurus (orig r6725):  ribasushi | 2009-06-19 17:25:19 +0200
  r6706 at Thesaurus (orig r6705):  ribasushi | 2009-06-18 12:30:08 +0200
  Branch to attempt prefetch with limit fix
  r6709 at Thesaurus (orig r6708):  ribasushi | 2009-06-18 15:54:38 +0200
  This seems to be the prefetch+limit fix - ugly as hell but appears to work
  r6710 at Thesaurus (orig r6709):  ribasushi | 2009-06-18 16:13:31 +0200
  More comments
  r6717 at Thesaurus (orig r6716):  ribasushi | 2009-06-19 15:39:43 +0200
  single() throws with has_many prefetch
  r6718 at Thesaurus (orig r6717):  ribasushi | 2009-06-19 15:40:38 +0200
  Rename test
  r6719 at Thesaurus (orig r6718):  ribasushi | 2009-06-19 15:44:26 +0200
  cleanup svn attrs
  r6720 at Thesaurus (orig r6719):  ash | 2009-06-19 16:31:11 +0200
  Add extra test for prefetch+has_many
  
  r6721 at Thesaurus (orig r6720):  ribasushi | 2009-06-19 16:33:49 +0200
  no need to slice as use_prefetch already has a limit
  r6722 at Thesaurus (orig r6721):  ribasushi | 2009-06-19 16:36:08 +0200
  throw in an extra limit, sophisticate test a bit
  r6723 at Thesaurus (orig r6722):  ribasushi | 2009-06-19 16:36:54 +0200
  Fix the fix
  r6725 at Thesaurus (orig r6724):  ribasushi | 2009-06-19 17:24:23 +0200
  Fix dubious optimization
 
 r6734 at Thesaurus (orig r6733):  ribasushi | 2009-06-20 10:16:02 +0200
 todoify skip
 r6736 at Thesaurus (orig r6735):  ribasushi | 2009-06-20 12:37:52 +0200
 Clarify test
 r6740 at Thesaurus (orig r6739):  ribasushi | 2009-06-20 15:22:06 +0200
 Disambiguate populate() return
 r6743 at Thesaurus (orig r6742):  ribasushi | 2009-06-20 23:30:23 +0200
  r6737 at Thesaurus (orig r6736):  ribasushi | 2009-06-20 12:39:34 +0200
  new branch to streamline count() and introduce count_rs()
  r6738 at Thesaurus (orig r6737):  ribasushi | 2009-06-20 12:44:09 +0200
  Add count_rs, move the code back from DBI - leave only sql specific hooks
  r6739 at Thesaurus (orig r6738):  ribasushi | 2009-06-20 12:54:11 +0200
  Test count_rs
  r6742 at Thesaurus (orig r6741):  ribasushi | 2009-06-20 23:30:10 +0200
  More tests and a really working count_rs
 
 r6753 at Thesaurus (orig r6752):  ribasushi | 2009-06-21 09:00:21 +0200
 Clenaup text
 r6754 at Thesaurus (orig r6753):  ribasushi | 2009-06-21 14:37:56 +0200
 make_column_dirty fix
 r6756 at Thesaurus (orig r6755):  ribasushi | 2009-06-21 23:12:40 +0200
 Fix borked test
 r6764 at Thesaurus (orig r6763):  ribasushi | 2009-06-23 10:33:59 +0200
 Real inheritance ordering for load_namespaces
 r6772 at Thesaurus (orig r6771):  ribasushi | 2009-06-23 16:46:18 +0200
 Move tests around, add extra has_one relationship
 r6773 at Thesaurus (orig r6772):  caelum | 2009-06-23 18:36:22 +0200
 add missing ' to doc
 r6781 at Thesaurus (orig r6780):  ribasushi | 2009-06-24 11:08:02 +0200
 Properly name the relinfo variable
 r6782 at Thesaurus (orig r6781):  ribasushi | 2009-06-24 12:12:49 +0200
 find_related fix for single-type relationships
 r6783 at Thesaurus (orig r6782):  nigel | 2009-06-24 17:28:33 +0200
  r11786 at hex:  nigel | 2009-06-24 16:27:58 +0100
  Fixed set_$rel with where restriction deleting rows outside the restriction
 
 r6784 at Thesaurus (orig r6783):  nigel | 2009-06-24 17:47:31 +0200
  r11788 at hex:  nigel | 2009-06-24 16:47:04 +0100
  Rework of set_$rel patch with less obfuscation
 
 r6789 at Thesaurus (orig r6788):  ribasushi | 2009-06-25 09:19:10 +0200
 Commit test inspired by joel - it seemingly fails on Mac?
 r6790 at Thesaurus (orig r6789):  ribasushi | 2009-06-25 11:04:26 +0200
 Minor cleanups
 r6793 at Thesaurus (orig r6792):  teejay | 2009-06-26 14:43:05 +0200
 normalised artist_id, and plural relationships to plural names making use of alias/relname less ambiguous than relname/tablename being the same, also added a little more info on joining/relationships
 r6794 at Thesaurus (orig r6793):  tomboh | 2009-06-26 15:25:19 +0200
 Documentation fix:
 - timezone is no longer an extra setting
 - fix a typo of 'subsequently'
 
 r6795 at Thesaurus (orig r6794):  gphat | 2009-06-26 16:33:35 +0200
 Fix typo in ResultSet docs
 
 r6803 at Thesaurus (orig r6802):  ribasushi | 2009-06-27 12:39:03 +0200
 Todoified (unsolvable) test from RT#42466
 r6804 at Thesaurus (orig r6803):  ribasushi | 2009-06-27 12:52:26 +0200
 POD patch from RT#46808
 r6805 at Thesaurus (orig r6804):  ribasushi | 2009-06-27 13:59:03 +0200
 Adjust sqlt schema parser to add tables in FK dependency order
 r6806 at Thesaurus (orig r6805):  ribasushi | 2009-06-27 14:08:35 +0200
 Bump author SQLT dependency for early developer testing
 Regenerate SQLite schema with new parser/sqlt
 Use throw_exception in lieu of plain die when possible



Property changes on: DBIx-Class/0.08/branches/run_file_against_storage
___________________________________________________________________
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:11142
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/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_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/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/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:6668
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/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_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/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:6805
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/run_file_against_storage/Changes
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/Changes	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/Changes	2009-06-27 12:24:52 UTC (rev 6806)
@@ -1,5 +1,17 @@
 Revision history for DBIx::Class
 
+        - 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
+
 0.08107 2009-06-14 08:21:00 (UTC)
         - Fix serialization regression introduced in 0.08103 (affects
           Cursor::Cached)

Modified: DBIx-Class/0.08/branches/run_file_against_storage/Makefile.PL
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/Makefile.PL	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/Makefile.PL	2009-06-27 12:24:52 UTC (rev 6806)
@@ -59,7 +59,7 @@
 
 my %force_requires_if_author = (
   'Test::Pod::Coverage'       => 1.04,
-  'SQL::Translator'           => 0.09004,
+  'SQL::Translator'           => 0.09007,
 
   # CDBI-compat related
   'DBIx::ContextualFetch'     => 0,

Modified: DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/InflateColumn/DateTime.pm
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/InflateColumn/DateTime.pm	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/InflateColumn/DateTime.pm	2009-06-27 12:24:52 UTC (rev 6806)
@@ -211,7 +211,7 @@
 
 =head1 USAGE NOTES
 
-If you have a datetime column with the C<timezone> extra setting, and subsenquently 
+If you have a datetime column with an associated C<timezone>, and subsequently
 create/update this column with a DateTime object in the L<DateTime::TimeZone::Floating>
 timezone, you will get a warning (as there is a very good chance this will not have the
 result you expect). For example:

Modified: DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Manual/Cookbook.pod
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Manual/Cookbook.pod	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Manual/Cookbook.pod	2009-06-27 12:24:52 UTC (rev 6806)
@@ -240,7 +240,7 @@
   my $rs = $schema->resultset('Artist')->search(
     {},
     {
-      columns => [ qw/artistid name rank/ ],
+      columns => [ qw/artist_id name rank/ ],
       distinct => 1
     } 
   );
@@ -248,15 +248,15 @@
   my $rs = $schema->resultset('Artist')->search(
     {},
     {
-      columns => [ qw/artistid name rank/ ],
-      group_by => [ qw/artistid name rank/ ],
+      columns => [ qw/artist_id name rank/ ],
+      group_by => [ qw/artist_id name rank/ ],
     }
   );
 
   # Equivalent SQL:
-  # SELECT me.artistid, me.name, me.rank
+  # SELECT me.artist_id, me.name, me.rank
   # FROM artist me
-  # GROUP BY artistid, name, rank
+  # GROUP BY artist_id, name, rank
 
 =head2 SELECT COUNT(DISTINCT colname)
 
@@ -336,7 +336,7 @@
   my $rs = $cdrs->search({
     year => {
       '=' => $cdrs->search(
-        { artistid => { '=' => \'me.artistid' } },
+        { artist_id => { '=' => \'me.artist_id' } },
         { alias => 'inner' }
       )->get_column('year')->max_rs->as_query,
     },
@@ -349,7 +349,7 @@
    WHERE year = (
       SELECT MAX(inner.year)
         FROM cd inner
-       WHERE artistid = me.artistid
+       WHERE artist_id = me.artist_id
       )
 
 =head3 EXPERIMENTAL
@@ -429,15 +429,20 @@
 =head2 Using joins and prefetch
 
 You can use the C<join> attribute to allow searching on, or sorting your
-results by, one or more columns in a related table. To return all CDs matching
-a particular artist name:
+results by, one or more columns in a related table.
 
+This requires that you have defined the L<DBIx::Class::Relationship>. For example :
+
+  My::Schema::CD->has_many( artists => 'My::Schema::Artist', 'artist_id');
+
+To return all CDs matching a particular artist name, you specify the name of the relationship ('artists'):
+
   my $rs = $schema->resultset('CD')->search(
     {
-      'artist.name' => 'Bob Marley'    
+      'artists.name' => 'Bob Marley'    
     },
     {
-      join => 'artist', # join the artist table
+      join => 'artists', # join the artist table
     }
   );
 
@@ -446,16 +451,19 @@
   # JOIN artist ON cd.artist = artist.id
   # WHERE artist.name = 'Bob Marley'
 
+In that example both the join, and the condition use the relationship name rather than the table name
+(see DBIx::Class::Manual::Joining for more details on aliasing ).
+
 If required, you can now sort on any column in the related tables by including
-it in your C<order_by> attribute:
+it in your C<order_by> attribute, (again using the aliased relation name rather than table name) :
 
   my $rs = $schema->resultset('CD')->search(
     {
-      'artist.name' => 'Bob Marley'
+      'artists.name' => 'Bob Marley'
     },
     {
-      join     => 'artist',
-      order_by => [qw/ artist.name /]
+      join     => 'artists',
+      order_by => [qw/ artists.name /]
     }
   );
 
@@ -492,12 +500,12 @@
 
   my $rs = $schema->resultset('CD')->search(
     {
-      'artist.name' => 'Bob Marley'
+      'artists.name' => 'Bob Marley'
     },
     {
-      join     => 'artist',
-      order_by => [qw/ artist.name /],
-      prefetch => 'artist' # return artist data too!
+      join     => 'artists',
+      order_by => [qw/ artists.name /],
+      prefetch => 'artists' # return artist data too!
     }
   );
 
@@ -1100,8 +1108,8 @@
   
   __PACKAGE__->table('database1.artist'); # will use "database1.artist" in FROM clause
   
-  __PACKAGE__->add_columns(qw/ artistid name /);
-  __PACKAGE__->set_primary_key('artistid');
+  __PACKAGE__->add_columns(qw/ artist_id name /);
+  __PACKAGE__->set_primary_key('artist_id');
   __PACKAGE__->has_many('cds' => 'MyDatabase::Main::Cd');
 
   1;

Modified: DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Manual/Joining.pod
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Manual/Joining.pod	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Manual/Joining.pod	2009-06-27 12:24:52 UTC (rev 6806)
@@ -34,7 +34,7 @@
 So, joins are a way of extending simple select statements to include
 fields from other, related, tables. There are various types of joins,
 depending on which combination of the data you wish to retrieve, see
-L<MySQL's doc on JOINs|http://dev.mysql.com/doc/refman/5.0/en/join.html>.
+MySQL's doc on JOINs: L<http://dev.mysql.com/doc/refman/5.0/en/join.html>.
 
 =head1 DEFINING JOINS AND RELATIONSHIPS
 


Property changes on: DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/PK/Auto/Oracle.pm
___________________________________________________________________
Name: svn:keywords
   - Id

Modified: DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Relationship/Base.pm
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Relationship/Base.pm	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Relationship/Base.pm	2009-06-27 12:24:52 UTC (rev 6806)
@@ -176,13 +176,13 @@
   $self->throw_exception("Can't call *_related as class methods")
     unless ref $self;
   my $rel = shift;
-  my $rel_obj = $self->relationship_info($rel);
+  my $rel_info = $self->relationship_info($rel);
   $self->throw_exception( "No such relationship ${rel}" )
-    unless $rel_obj;
+    unless $rel_info;
   
   return $self->{related_resultsets}{$rel} ||= do {
     my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
-    $attrs = { %{$rel_obj->{attrs} || {}}, %$attrs };
+    $attrs = { %{$rel_info->{attrs} || {}}, %$attrs };
 
     $self->throw_exception( "Invalid query: @_" )
       if (@_ > 1 && (@_ % 2 == 1));
@@ -190,7 +190,7 @@
 
     my $source = $self->result_source;
     my $cond = $source->_resolve_condition(
-      $rel_obj->{cond}, $rel, $self
+      $rel_info->{cond}, $rel, $self
     );
     if ($cond eq $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION) {
       my $reverse = $source->reverse_relationship_info($rel);
@@ -390,22 +390,22 @@
 
 sub set_from_related {
   my ($self, $rel, $f_obj) = @_;
-  my $rel_obj = $self->relationship_info($rel);
-  $self->throw_exception( "No such relationship ${rel}" ) unless $rel_obj;
-  my $cond = $rel_obj->{cond};
+  my $rel_info = $self->relationship_info($rel);
+  $self->throw_exception( "No such relationship ${rel}" ) unless $rel_info;
+  my $cond = $rel_info->{cond};
   $self->throw_exception(
     "set_from_related can only handle a hash condition; the ".
     "condition for $rel is of type ".
     (ref $cond ? ref $cond : 'plain scalar')
   ) unless ref $cond eq 'HASH';
   if (defined $f_obj) {
-    my $f_class = $rel_obj->{class};
+    my $f_class = $rel_info->{class};
     $self->throw_exception( "Object $f_obj isn't a ".$f_class )
       unless Scalar::Util::blessed($f_obj) and $f_obj->isa($f_class);
   }
   $self->set_columns(
     $self->result_source->_resolve_condition(
-       $rel_obj->{cond}, $f_obj, $rel));
+       $rel_info->{cond}, $f_obj, $rel));
   return 1;
 }
 

Modified: DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Relationship/ManyToMany.pm
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Relationship/ManyToMany.pm	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Relationship/ManyToMany.pm	2009-06-27 12:24:52 UTC (rev 6806)
@@ -107,7 +107,14 @@
         "{$set_meth} needs a list of objects or hashrefs"
       );
       my @to_set = (ref($_[0]) eq 'ARRAY' ? @{ $_[0] } : @_);
-      $self->search_related($rel, {})->delete;
+      # if there is a where clause in the attributes, ensure we only delete
+      # rows that are within the where restriction
+      if ($rel_attrs && $rel_attrs->{where}) {
+        $self->search_related( $rel, $rel_attrs->{where},{join => $f_rel})->delete;
+      } else {
+        $self->search_related( $rel, {} )->delete;
+      }
+      # add in the set rel objects
       $self->$add_meth($_, ref($_[1]) ? $_[1] : {}) for (@to_set);
     };
 

Modified: DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/ResultClass/HashRefInflator.pm
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/ResultClass/HashRefInflator.pm	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/ResultClass/HashRefInflator.pm	2009-06-27 12:24:52 UTC (rev 6806)
@@ -73,8 +73,15 @@
 
         # if there is at least one defined column consider the resultset real
         # (and not an emtpy has_many rel containing one empty hashref)
+        # an empty arrayref is an empty multi-sub-prefetch - don't consider
+        # those either
         for (values %$hash) {
-            return $hash if defined $_;
+            if (ref $_ eq 'ARRAY') {
+              return $hash if @$_;
+            }
+            elsif (defined $_) {
+              return $hash;
+            }
         }
 
         return undef;
@@ -116,6 +123,12 @@
 HashRefInflator only affects resultsets at inflation time, and prefetch causes
 relations to be inflated when the master C<$artist> row is inflated.
 
+=item *
+
+Column value inflation, e.g., using modules like
+L<DBIx::Class::InflateColumn::DateTime>, is not performed.
+The returned hash contains the raw database values.
+
 =back
 
 =cut

Modified: DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/ResultSet.pm
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/ResultSet.pm	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/ResultSet.pm	2009-06-27 12:24:52 UTC (rev 6806)
@@ -513,6 +513,14 @@
     my $unique_query = $self->_build_unique_query($input_query, \@unique_cols);
     $query = $self->_add_alias($unique_query, $alias);
   }
+  elsif ($self->{attrs}{accessor} and $self->{attrs}{accessor} eq 'single') {
+    # This means that we got here after a merger of relationship conditions
+    # in ::Relationship::Base::search_related (the row method), and furthermore
+    # the relationship is of the 'single' type. This means that the condition
+    # provided by the relationship (already attached to $self) is sufficient,
+    # as there can be only one row in the databse that would satisfy the 
+    # relationship
+  }
   else {
     my @unique_queries = $self->_unique_queries($input_query, $attrs);
     $query = @unique_queries
@@ -521,27 +529,14 @@
   }
 
   # Run the query
-  if (keys %$attrs) {
-    my $rs = $self->search($query, $attrs);
-    if (keys %{$rs->_resolved_attrs->{collapse}}) {
-      my $row = $rs->next;
-      carp "Query returned more than one row" if $rs->next;
-      return $row;
-    }
-    else {
-      return $rs->single;
-    }
+  my $rs = $self->search ($query, $attrs);
+  if (keys %{$rs->_resolved_attrs->{collapse}}) {
+    my $row = $rs->next;
+    carp "Query returned more than one row" if $rs->next;
+    return $row;
   }
   else {
-    if (keys %{$self->_resolved_attrs->{collapse}}) {
-      my $rs = $self->search($query);
-      my $row = $rs->next;
-      carp "Query returned more than one row" if $rs->next;
-      return $row;
-    }
-    else {
-      return $self->single($query);
-    }
+    return $rs->single;
   }
 }
 
@@ -698,10 +693,14 @@
 
   Query returned more than one row
 
-In this case, you should be using L</first> or L</find> instead, or if you really
+In this case, you should be using L</next> or L</find> instead, or if you really
 know what you are doing, use the L</rows> attribute to explicitly limit the size
 of the resultset.
 
+This method will also throw an exception if it is called on a resultset prefetching
+has_many, as such a prefetch implies fetching multiple rows from the database in
+order to assemble the resulting object.
+
 =back
 
 =cut
@@ -714,6 +713,12 @@
 
   my $attrs = $self->_resolved_attrs_copy;
 
+  if (keys %{$attrs->{collapse}}) {
+    $self->throw_exception(
+      'single() can not be used on resultsets prefetching has_many. Use find( \%cond ) or next() instead'
+    );
+  }
+
   if ($where) {
     if (defined $attrs->{where}) {
       $attrs->{where} = {
@@ -1144,17 +1149,122 @@
   return $self->search(@_)->count if @_ and defined $_[0];
   return scalar @{ $self->get_cache } if $self->get_cache;
 
-  my $meth = $self->_has_attr (qw/prefetch collapse distinct group_by/)
-    ? 'count_grouped'
-    : 'count'
-  ;
+  my $attrs = $self->_resolved_attrs_copy;
 
-  my $attrs = $self->_resolved_attrs_copy;
+  # this is a little optimization - it is faster to do the limit
+  # adjustments in software, instead of a subquery
+  my $rows = delete $attrs->{rows};
+  my $offset = delete $attrs->{offset};
+
+  my $crs;
+  if ($self->_has_resolved_attr (qw/collapse group_by/)) {
+    $crs = $self->_count_subq_rs ($attrs);
+  }
+  else {
+    $crs = $self->_count_rs ($attrs);
+  }
+  my $count = $crs->next;
+
+  $count -= $offset if $offset;
+  $count = $rows if $rows and $rows < $count;
+  $count = 0 if ($count < 0);
+
+  return $count;
+}
+
+=head2 count_rs
+
+=over 4
+
+=item Arguments: $cond, \%attrs??
+
+=item Return Value: $count_rs
+
+=back
+
+Same as L</count> but returns a L<DBIx::Class::ResultSetColumn> object.
+This can be very handy for subqueries:
+
+  ->search( { amount => $some_rs->count_rs->as_query } )
+
+As with regular resultsets the SQL query will be executed only after
+the resultset is accessed via L</next> or L</all>. That would return
+the same single value obtainable via L</count>.
+
+=cut
+
+sub count_rs {
+  my $self = shift;
+  return $self->search(@_)->count_rs if @_;
+
+  # this may look like a lack of abstraction (count() does about the same)
+  # but in fact an _rs *must* use a subquery for the limits, as the
+  # software based limiting can not be ported if this $rs is to be used
+  # in a subquery itself (i.e. ->as_query)
+  if ($self->_has_resolved_attr (qw/collapse group_by offset rows/)) {
+    return $self->_count_subq_rs;
+  }
+  else {
+    return $self->_count_rs;
+  }
+}
+
+#
+# returns a ResultSetColumn object tied to the count query
+#
+sub _count_rs {
+  my ($self, $attrs) = @_;
+
   my $rsrc = $self->result_source;
+  $attrs ||= $self->_resolved_attrs;
 
-  return $rsrc->storage->$meth ($rsrc, $attrs);
+  my $tmp_attrs = { %$attrs };
+
+  # take off any limits, record_filter is cdbi, and no point of ordering a count 
+  delete $tmp_attrs->{$_} for (qw/select as rows offset order_by record_filter/);
+
+  # overwrite the selector (supplied by the storage)
+  $tmp_attrs->{select} = $rsrc->storage->_count_select ($rsrc, $tmp_attrs);
+  $tmp_attrs->{as} = 'count';
+
+  my $tmp_rs = $rsrc->resultset_class->new($rsrc, $tmp_attrs)->get_column ('count');
+
+  return $tmp_rs;
 }
 
+#
+# same as above but uses a subquery
+#
+sub _count_subq_rs {
+  my ($self, $attrs) = @_;
+
+  my $rsrc = $self->result_source;
+  $attrs ||= $self->_resolved_attrs_copy;
+
+  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/;
+
+  # 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
+  if ( keys %{$attrs->{collapse}} ) {
+    $sub_attrs->{group_by} = [ map { "$attrs->{alias}.$_" } ($rsrc->primary_columns) ]
+  }
+
+  $sub_attrs->{select} = $rsrc->storage->_subq_count_select ($rsrc, $sub_attrs);
+
+  $attrs->{from} = [{
+    count_subq => $rsrc->resultset_class->new ($rsrc, $sub_attrs )->as_query
+  }];
+
+  # the subquery replaces this
+  delete $attrs->{$_} for qw/where bind collapse group_by having having_bind rows offset/;
+
+  return $self->_count_rs ($attrs);
+}
+
+
 sub _bool {
   return 1;
 }
@@ -1276,15 +1386,15 @@
 
   my $rsrc = $self->result_source;
 
-  my $needs_group_by_subq = $self->_has_attr (qw/prefetch distinct join seen_join group_by/);
-  my $needs_subq = $self->_has_attr (qw/row offset page/);
+  my $needs_group_by_subq = $self->_has_resolved_attr (qw/collapse group_by -join/);
+  my $needs_subq = $self->_has_resolved_attr (qw/row offset/);
 
   if ($needs_group_by_subq or $needs_subq) {
 
     # make a new $rs selecting only the PKs (that's all we really need)
     my $attrs = $self->_resolved_attrs_copy;
 
-    delete $attrs->{$_} for qw/prefetch collapse select +select as +as columns +columns/;
+    delete $attrs->{$_} for qw/collapse select as/;
     $attrs->{columns} = [ map { "$attrs->{alias}.$_" } ($self->result_source->primary_columns) ];
 
     if ($needs_group_by_subq) {
@@ -1504,8 +1614,9 @@
 to insert the data, as this is a faster method.
 
 Otherwise, each set of data is inserted into the database using
-L<DBIx::Class::ResultSet/create>, and a arrayref of the resulting row
-objects is returned.
+L<DBIx::Class::ResultSet/create>, and the resulting objects are
+accumulated into an array. The array itself, or an array reference
+is returned depending on scalar or list context.
 
 Example:  Assuming an Artist Class that has many CDs Classes relating:
 
@@ -1571,7 +1682,7 @@
     foreach my $item (@$data) {
       push(@created, $self->create($item));
     }
-    return @created;
+    return wantarray ? @created : \@created;
   } else {
     my ($first, @rest) = @$data;
 
@@ -1808,14 +1919,14 @@
   return 0;
 }
 
-# _has_attr
+# _has_resolved_attr
 #
 # determines if the resultset defines at least one
 # of the attributes supplied
 #
 # used to determine if a subquery is neccessary
 
-sub _has_attr {
+sub _has_resolved_attr {
   my ($self, @attr_names) = @_;
 
   my $attrs = $self->_resolved_attrs;
@@ -1823,7 +1934,7 @@
   my $join_check_req;
 
   for my $n (@attr_names) {
-    ++$join_check_req if $n =~ /join/;
+    ++$join_check_req if $n eq '-join';
 
     my $attr =  $attrs->{$n};
 
@@ -1840,7 +1951,7 @@
     }
   }
 
-  # a join can be expressed as a multi-level from
+  # a resolved join is expressed as a multi-level from
   return 1 if (
     $join_check_req
       and
@@ -1930,7 +2041,13 @@
 
   my $attrs = $self->_resolved_attrs_copy;
 
-  my ($sqlbind, $bind_attrs) = $self->result_source->storage
+  # For future use:
+  #
+  # in list ctx:
+  # my ($sql, \@bind, \%dbi_bind_attrs) = _select_args_to_query (...)
+  # $sql also has no wrapping parenthesis in list ctx
+  #
+  my $sqlbind = $self->result_source->storage
     ->_select_args_to_query ($attrs->{from}, $attrs->{select}, $attrs->{where}, $attrs);
 
   return $sqlbind;
@@ -2064,7 +2181,7 @@
 =back
 
   $cd->cd_to_producer->find_or_create({ producer => $producer },
-                                      { key => 'primary });
+                                      { key => 'primary' });
 
 Tries to find a record based on its primary key or unique constraints; if none
 is found, creates one and returns that instead.
@@ -2326,12 +2443,12 @@
 
   $self->{related_resultsets} ||= {};
   return $self->{related_resultsets}{$rel} ||= do {
-    my $rel_obj = $self->result_source->relationship_info($rel);
+    my $rel_info = $self->result_source->relationship_info($rel);
 
     $self->throw_exception(
       "search_related: result source '" . $self->result_source->source_name .
         "' has no such relationship $rel")
-      unless $rel_obj;
+      unless $rel_info;
 
     my ($from,$seen) = $self->_resolve_from($rel);
 
@@ -2432,7 +2549,7 @@
 # with a relation_chain_depth less than the depth of the
 # current prefetch is not considered)
 sub _resolve_from {
-  my ($self, $extra_join) = @_;
+  my ($self, $rel) = @_;
   my $source = $self->result_source;
   my $attrs = $self->{attrs};
 
@@ -2456,7 +2573,7 @@
 
   ++$seen->{-relation_chain_depth};
 
-  push @$from, $source->_resolve_join($extra_join, $attrs->{alias}, $seen);
+  push @$from, $source->_resolve_join($rel, $attrs->{alias}, $seen);
 
   ++$seen->{-relation_chain_depth};
 
@@ -2555,22 +2672,24 @@
     $self->{attrs}{alias} => $source->from,
   } ];
 
-  if ( exists $attrs->{join} || exists $attrs->{prefetch} ) {
+  if ( $attrs->{join} || $attrs->{prefetch} ) {
+
+    $self->throw_exception ('join/prefetch can not be used with a literal scalarref {from}')
+      if ref $attrs->{from} ne 'ARRAY';
+
     my $join = delete $attrs->{join} || {};
 
     if ( defined $attrs->{prefetch} ) {
       $join = $self->_merge_attr( $join, $attrs->{prefetch} );
-
     }
 
     $attrs->{from} =    # have to copy here to avoid corrupting the original
       [
-      @{ $attrs->{from} },
-      $source->_resolve_join(
-        $join, $alias, { %{ $attrs->{seen_join} || {} } }
-      )
+        @{ $attrs->{from} },
+        $source->_resolve_join(
+          $join, $alias, { %{ $attrs->{seen_join} || {} } }
+        )
       ];
-
   }
 
   if ( $attrs->{order_by} ) {
@@ -2592,30 +2711,35 @@
   $attrs->{_virtual_order_by} = [ $self->result_source->primary_columns ];
 
 
-  my $collapse = $attrs->{collapse} || {};
+  $attrs->{collapse} ||= {};
   if ( my $prefetch = delete $attrs->{prefetch} ) {
     $prefetch = $self->_merge_attr( {}, $prefetch );
-    my @pre_order;
-    foreach my $p ( ref $prefetch eq 'ARRAY' ? @$prefetch : ($prefetch) ) {
 
-      # bring joins back to level of current class
-      my $join_map = $self->_joinpath_aliases ($attrs->{from}, $attrs->{seen_join});
-      my @prefetch =
-        $source->_resolve_prefetch( $p, $alias, $join_map, \@pre_order, $collapse );
-      push( @{ $attrs->{select} }, map { $_->[0] } @prefetch );
-      push( @{ $attrs->{as} },     map { $_->[1] } @prefetch );
-    }
-    push( @{ $attrs->{order_by} }, @pre_order );
+    my $prefetch_ordering = [];
+
+    my $join_map = $self->_joinpath_aliases ($attrs->{from}, $attrs->{seen_join});
+
+    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 );
+
+    push( @{ $attrs->{order_by} }, @$prefetch_ordering );
+    $attrs->{_collapse_order_by} = \@$prefetch_ordering;
   }
 
+
   if (delete $attrs->{distinct}) {
     $attrs->{group_by} ||= [ grep { !ref($_) || (ref($_) ne 'HASH') } @{$attrs->{select}} ];
   }
 
-  $attrs->{collapse} = $collapse;
-
-  if ( $attrs->{page} and not defined $attrs->{offset} ) {
-    $attrs->{offset} = ( $attrs->{rows} * ( $attrs->{page} - 1 ) );
+  # if both page and offset are specified, produce a combined offset
+  # 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);
   }
 
   return $self->{_attrs} = $attrs;
@@ -3084,7 +3208,7 @@
 identical to creating a non-pages resultset and then calling ->page($page)
 on it.
 
-If L<rows> attribute is not specified it defualts to 10 rows per page.
+If L<rows> attribute is not specified it defaults to 10 rows per page.
 
 When you have a paged resultset, L</count> will only return the number
 of rows in the page. To get the total, use the L</pager> and call

Modified: DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/ResultSource.pm
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/ResultSource.pm	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/ResultSource.pm	2009-06-27 12:24:52 UTC (rev 6806)
@@ -1083,26 +1083,23 @@
 
 # Returns the {from} structure used to express JOIN conditions
 sub _resolve_join {
-  my ($self, $join, $alias, $seen, $force_left, $jpath) = @_;
+  my ($self, $join, $alias, $seen, $jpath, $force_left) = @_;
 
   # 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;
 
-  $force_left ||= { force => 0 };
-
   # 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 ||= [];  
+  $jpath ||= [];
 
   if (ref $join eq 'ARRAY') {
     return
       map {
-        local $force_left->{force} = $force_left->{force};
-        $self->_resolve_join($_, $alias, $seen, $force_left, [@$jpath]);
+        $self->_resolve_join($_, $alias, $seen, [@$jpath], $force_left);
       } @$join;
   } elsif (ref $join eq 'HASH') {
     return
@@ -1110,9 +1107,9 @@
         my $as = ($seen->{$_} ? join ('_', $_, $seen->{$_} + 1) : $_);  # the actual seen value will be incremented below
         local $force_left->{force} = $force_left->{force};
         (
-          $self->_resolve_join($_, $alias, $seen, $force_left, [@$jpath]),
+          $self->_resolve_join($_, $alias, $seen, [@$jpath], $force_left),
           $self->related_source($_)->_resolve_join(
-            $join->{$_}, $as, $seen, $force_left, [@$jpath, $_]
+            $join->{$_}, $as, $seen, [@$jpath, $_], $force_left
           )
         );
       } keys %$join;
@@ -1126,11 +1123,11 @@
     my $rel_info = $self->relationship_info($join);
     $self->throw_exception("No such relationship ${join}") unless $rel_info;
     my $type;
-    if ($force_left->{force}) {
+    if ($force_left) {
       $type = 'left';
     } else {
       $type = $rel_info->{attrs}{join_type} || '';
-      $force_left->{force} = 1 if lc($type) eq 'left';
+      $force_left = 1 if lc($type) eq 'left';
     }
 
     my $rel_src = $self->related_source($join);

Modified: DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Row.pm
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Row.pm	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Row.pm	2009-06-27 12:24:52 UTC (rev 6806)
@@ -710,7 +710,21 @@
 
   $self->throw_exception( "No such column '${column}'" )
     unless exists $self->{_column_data}{$column} || $self->has_column($column);
+
+  # the entire clean/dirty code relieas on exists, not on true/false
+  return 1 if exists $self->{_dirty_columns}{$column};
+
   $self->{_dirty_columns}{$column} = 1;
+
+  # if we are just now making the column dirty, and if there is an inflated
+  # value, force it over the deflated one
+  if (exists $self->{_inflated_column}{$column}) {
+    $self->store_column($column,
+      $self->_deflated_column(
+        $column, $self->{_inflated_column}{$column}
+      )
+    );
+  }
 }
 
 =head2 get_inflated_columns
@@ -911,7 +925,11 @@
 
 Inserts a new row into the database, as a copy of the original
 object. If a hashref of replacement data is supplied, these will take
-precedence over data in the original.
+precedence over data in the original. Also any columns which have
+the L<column info attribute|DBIx::Class::ResultSource/add_columns>
+C<< is_auto_increment => 1 >> are explicitly removed before the copy,
+so that the database can insert its own autoincremented values into
+the new object.
 
 Relationships will be followed by the copy procedure B<only> if the
 relationship specifes a true value for its

Modified: DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Schema.pm
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Schema.pm	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Schema.pm	2009-06-27 12:24:52 UTC (rev 6806)
@@ -7,6 +7,7 @@
 use Carp::Clan qw/^DBIx::Class/;
 use Scalar::Util qw/weaken/;
 use File::Spec;
+use MRO::Compat;
 use Sub::Name ();
 require Module::Find;
 
@@ -239,16 +240,29 @@
     local *Class::C3::reinitialize = sub { };
     use warnings 'redefine';
 
-    # ensure classes are loaded and fetch properly sorted classes
+    # ensure classes are loaded and attached in inheritance order
     $class->ensure_class_loaded($_) foreach(values %results);
-    my @subclass_last = sort { $results{$a}->isa($results{$b}) } keys(%results);
-    
+    my %inh_idx;
+    my @subclass_last = sort {
+
+      ($inh_idx{$a} ||=
+        scalar @{mro::get_linear_isa( $results{$a} )}
+      )
+
+          <=>
+
+      ($inh_idx{$b} ||=
+        scalar @{mro::get_linear_isa( $results{$b} )}
+      )
+
+    } keys(%results);
+
     foreach my $result (@subclass_last) {
       my $result_class = $results{$result};
 
       my $rs_class = delete $resultsets{$result};
       my $rs_set = $class->_ns_get_rsrc_instance ($result_class)->resultset_class;
-      
+
       if($rs_set && $rs_set ne 'DBIx::Class::ResultSet') {
         if($rs_class && $rs_class ne $rs_set) {
           carp "We found ResultSet class '$rs_class' for '$result', but it seems "
@@ -285,8 +299,10 @@
 
 =back
 
-Alternative method to L</load_namespaces> which you should look at
-using if you can.
+L</load_classes> is an alternative method to L</load_namespaces>, both of
+which serve similar purposes, each with different advantages and disadvantages.
+In the general case you should use L</load_namespaces>, unless you need to
+be able to specify that only specific classes are loaded at runtime.
 
 With no arguments, this method uses L<Module::Find> to find all classes under
 the schema's namespace. Otherwise, this method loads the classes you specify
@@ -1109,6 +1125,19 @@
 You may override this method in your schema if you wish to use a different
 format.
 
+ WARNING
+
+ Prior to DBIx::Class version 0.08100 this method had a different signature:
+
+    my $filename = $table->ddl_filename($type, $dir, $version, $preversion)
+
+ In recent versions variables $dir and $version were reversed in order to
+ bring the signature in line with other Schema/Storage methods. If you 
+ really need to maintain backward compatibility, you can do the following
+ in any overriding methods:
+
+    ($dir, $version) = ($version, $dir) if ($DBIx::Class::VERSION < 0.08100);
+
 =cut
 
 sub ddl_filename {

Modified: DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Storage/DBI/mysql.pm
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Storage/DBI/mysql.pm	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Storage/DBI/mysql.pm	2009-06-27 12:24:52 UTC (rev 6806)
@@ -64,10 +64,10 @@
 # primary keys of the main table in the inner query. This hopefully still
 # hits the indexes and keeps mysql happy.
 # (mysql does not care if the SELECT and the GROUP BY match)
-sub _grouped_count_select {
-  my ($self, $source, $rs_args) = @_;
-  my @pcols = map { join '.', $rs_args->{alias}, $_ } ($source->primary_columns);
-  return @pcols ? \@pcols : $rs_args->{group_by};
+sub _subq_count_select {
+  my ($self, $source, $rs_attrs) = @_;
+  my @pcols = map { join '.', $rs_attrs->{alias}, $_ } ($source->primary_columns);
+  return @pcols ? \@pcols : [ 1 ];
 }
 
 1;

Modified: DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Storage/DBI.pm
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Storage/DBI.pm	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Storage/DBI.pm	2009-06-27 12:24:52 UTC (rev 6806)
@@ -1218,26 +1218,22 @@
 
   # my ($sql, $prepared_bind) = $self->_prep_for_execute($op, $bind, $ident, [ $select, $cond, $order, $rows, $offset ]);
   my ($sql, $prepared_bind) = $self->_prep_for_execute($op, $bind, $ident, \@args);
+  $prepared_bind ||= [];
 
-  return \[ "($sql)", @{ $prepared_bind || [] }];
+  return wantarray
+    ? ($sql, $prepared_bind, $bind_attrs)
+    : \[ "($sql)", @$prepared_bind ]
+  ;
 }
 
 sub _select_args {
-  my ($self, $ident, $select, $condition, $attrs) = @_;
+  my ($self, $ident, $select, $where, $attrs) = @_;
 
   my $sql_maker = $self->sql_maker;
-  $sql_maker->{for} = delete $attrs->{for};
+  my $alias2source = $self->_resolve_ident_sources ($ident);
 
-  my $order = { map
-    { $attrs->{$_} ? ( $_ => $attrs->{$_} ) : ()  }
-    (qw/order_by group_by having _virtual_order_by/ )
-  };
-
-
+  # calculate bind_attrs before possible $ident mangling
   my $bind_attrs = {};
-
-  my $alias2source = $self->_resolve_ident_sources ($ident);
-
   for my $alias (keys %$alias2source) {
     my $bindtypes = $self->source_bind_attributes ($alias2source->{$alias}) || {};
     for my $col (keys %$bindtypes) {
@@ -1250,15 +1246,7 @@
     }
   }
 
-  # This would be the point to deflate anything found in $condition
-  # (and leave $attrs->{bind} intact). Problem is - inflators historically
-  # expect a row object. And all we have is a resultsource (it is trivial
-  # to extract deflator coderefs via $alias2source above).
-  #
-  # I don't see a way forward other than changing the way deflators are
-  # invoked, and that's just bad...
-
-  my @args = ('select', $attrs->{bind}, $ident, $bind_attrs, $select, $condition, $order);
+  my @limit;
   if ($attrs->{software_limit} ||
       $sql_maker->_default_limit_syntax eq "GenericSubQ") {
         $attrs->{software_limit} = 1;
@@ -1268,11 +1256,185 @@
 
     # MySQL actually recommends this approach.  I cringe.
     $attrs->{rows} = 2**48 if not defined $attrs->{rows} and defined $attrs->{offset};
-    push @args, $attrs->{rows}, $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};
+    }
   }
-  return @args;
+
+###
+  # This would be the point to deflate anything found in $where
+  # (and leave $attrs->{bind} intact). Problem is - inflators historically
+  # expect a row object. And all we have is a resultsource (it is trivial
+  # to extract deflator coderefs via $alias2source above).
+  #
+  # I don't see a way forward other than changing the way deflators are
+  # invoked, and that's just bad...
+###
+
+  my $order = { map
+    { $attrs->{$_} ? ( $_ => $attrs->{$_} ) : ()  }
+    (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 {
+  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');
+  }
+
+  $self->throw_exception ('Prefetch with limit (rows/offset) is 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/;
+
+  my $alias = $attrs->{alias};
+
+  # create subquery select list
+  my $sub_select = [ grep { $_ =~ /^$alias\./ } @{$attrs->{select}} ];
+
+  # bring over all non-collapse-induced order_by into the inner query (if any)
+  # the outer one will have to keep them all
+  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) ]
+    ];
+  }
+
+  # mangle {from}
+  $from = [ @$from ];
+  my $select_root = shift @$from;
+  my @outer_from = @$from;
+
+  my %inner_joins;
+  my %join_info = map { $_->[0]{-alias} => $_->[0] } (@$from);
+
+  # in complex search_related chains $alias may *not* be 'me'
+  # so always include it in the inner join, and also shift away
+  # from the outer stack, so that the two datasets actually do
+  # meet
+  if ($select_root->{-alias} ne $alias) {
+    $inner_joins{$alias} = 1;
+
+    while (@outer_from && $outer_from[0][0]{-alias} ne $alias) {
+      shift @outer_from;
+    }
+    if (! @outer_from) {
+      $self->throw_exception ("Unable to find '$alias' in the {from} stack, something is wrong");
+    }
+
+    shift @outer_from; # the new subquery will represent this alias, so get rid of it
+  }
+
+
+  # decide which parts of the join will remain on the inside
+  #
+  # this is not a very viable optimisation, but it was written
+  # before I realised this, so might as well remain. We can throw
+  # 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
+  # complex queries some might, and we might make some RDBMS happy.
+  #
+  #
+  # since we do not have introspectable SQLA, we fall back to ugly
+  # scanning of raw SQL for WHERE, and for pieces of ORDER BY
+  # in order to determine what goes into %inner_joins
+  # It may not be very efficient, but it's a reasonable stop-gap
+  {
+    # produce stuff unquoted, so it can be scanned
+    my $sql_maker = $self->sql_maker;
+    local $sql_maker->{quote_char};
+
+    my @order_by = (map
+      { ref $_ ? $_->[0] : $_ }
+      $sql_maker->_order_by_chunks ($sub_attrs->{order_by})
+    );
+
+    my $where_sql = $sql_maker->where ($where);
+
+    # sort needed joins
+    for my $alias (keys %join_info) {
+
+      # any table alias found on a column name in where or order_by
+      # gets included in %inner_joins
+      # Also any parent joins that are needed to reach this particular alias
+      for my $piece ($where_sql, @order_by ) {
+        if ($piece =~ /\b$alias\./) {
+          $inner_joins{$alias} = 1;
+        }
+      }
+    }
+  }
+
+  # scan for non-leaf/non-left joins and mark as needed
+  # also mark all ancestor joins that are needed to reach this particular alias
+  # (e.g.  join => { cds => 'tracks' } - tracks will bring cds too )
+  #
+  # traverse by the size of the -join_path i.e. reverse depth first
+  for my $alias (sort { @{$join_info{$b}{-join_path}} <=> @{$join_info{$a}{-join_path}} } (keys %join_info) ) {
+
+    my $j = $join_info{$alias};
+    $inner_joins{$alias} = 1 if (! $j->{-join_type} || ($j->{-join_type} !~ /^left$/i) );
+
+    if ($inner_joins{$alias}) {
+      $inner_joins{$_} = 1 for (@{$j->{-join_path}});
+    }
+  }
+
+  # construct the inner $from for the subquery
+  my $inner_from = [ $select_root ];
+  for my $j (@$from) {
+    push @$inner_from, $j if $inner_joins{$j->[0]{-alias}};
+  }
+
+  # if a multi-type join was needed in the subquery ("multi" is indicated by
+  # presence in {collapse}) - add a group_by to simulate the collapse in the subq
+
+  for my $alias (keys %inner_joins) {
+
+    # the dot comes from some weirdness in collapse
+    # remove after the rewrite
+    if ($attrs->{collapse}{".$alias"}) {
+      $sub_attrs->{group_by} = $sub_select;
+      last;
+    }
+  }
+
+  # generate the subquery
+  my $subq = $self->_select_args_to_query (
+    $inner_from,
+    $sub_select,
+    $where,
+    $sub_attrs
+  );
+
+  # put it in the new {from}
+  unshift @outer_from, { $alias => $subq };
+
+  # This is totally horrific - the $where ends up in both the inner and outer query
+  # Unfortunately not much can be done until SQLA2 introspection arrives
+  #
+  # OTOH it can be seen as a plus: <ash> (notes that this query would make a DBA cry ;)
+  return (\@outer_from, $select, $where, $attrs);
+}
+
 sub _resolve_ident_sources {
   my ($self, $ident) = @_;
 
@@ -1303,75 +1465,37 @@
   return $alias2source;
 }
 
-sub count {
-  my ($self, $source, $attrs) = @_;
-
-  my $tmp_attrs = { %$attrs };
-
-  # take off any pagers, record_filter is cdbi, and no point of ordering a count
-  delete $tmp_attrs->{$_} for (qw/select as rows offset page order_by record_filter/);
-
-  # overwrite the selector
-  $tmp_attrs->{select} = { count => '*' };
-
-  my $tmp_rs = $source->resultset_class->new($source, $tmp_attrs);
-  my ($count) = $tmp_rs->cursor->next;
-
-  # if the offset/rows attributes are still present, we did not use
-  # a subquery, so we need to make the calculations in software
-  $count -= $attrs->{offset} if $attrs->{offset};
-  $count = $attrs->{rows} if $attrs->{rows} and $attrs->{rows} < $count;
-  $count = 0 if ($count < 0);
-
-  return $count;
+# Returns a counting SELECT for a simple count
+# query. Abstracted so that a storage could override
+# this to { count => 'firstcol' } or whatever makes
+# sense as a performance optimization
+sub _count_select {
+  #my ($self, $source, $rs_attrs) = @_;
+  return { count => '*' };
 }
 
-sub count_grouped {
-  my ($self, $source, $attrs) = @_;
-
-  # copy for the subquery, we need to do some adjustments to it too
-  my $sub_attrs = { %$attrs };
-
-  # these can not go in the subquery, and there is no point of ordering it
-  delete $sub_attrs->{$_} for qw/prefetch collapse 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
-  # simply deleting group_by suffices, as the code below will re-fill it
-  # Note: we check $attrs, as $sub_attrs has collapse deleted
-  if (ref $attrs->{collapse} and keys %{$attrs->{collapse}} ) {
-    delete $sub_attrs->{group_by};
-  }
-
-  $sub_attrs->{group_by} ||= [ map { "$attrs->{alias}.$_" } ($source->primary_columns) ];
-  $sub_attrs->{select} = $self->_grouped_count_select ($source, $sub_attrs);
-
-  $attrs->{from} = [{
-    count_subq => $source->resultset_class->new ($source, $sub_attrs )->as_query
-  }];
-
-  # the subquery replaces this
-  delete $attrs->{$_} for qw/where bind prefetch collapse group_by having having_bind rows offset page pager/;
-
-  return $self->count ($source, $attrs);
-}
-
+# Returns a SELECT which will end up in the subselect
+# There may or may not be a group_by, as the subquery
+# might have been called to accomodate a limit
 #
-# Returns a SELECT to go with a supplied GROUP BY
-# (caled by count_grouped so a group_by is present)
-# Most databases expect them to match, but some
-# choke in various ways.
+# Most databases would be happy with whatever ends up
+# here, but some choke in various ways.
 #
-sub _grouped_count_select {
-  my ($self, $source, $rs_args) = @_;
-  return $rs_args->{group_by};
+sub _subq_count_select {
+  my ($self, $source, $rs_attrs) = @_;
+  return $rs_attrs->{group_by} if $rs_attrs->{group_by};
+
+  my @pcols = map { join '.', $rs_attrs->{alias}, $_ } ($source->primary_columns);
+  return @pcols ? \@pcols : [ 1 ];
 }
 
+
 sub source_bind_attributes {
   my ($self, $source) = @_;
-  
+
   my $bind_attributes;
   foreach my $column ($source->columns) {
-  
+
     my $data_type = $source->column_info($column)->{data_type} || '';
     $bind_attributes->{$column} = $self->bind_attribute_by_data_type($data_type)
      if $data_type;

Modified: DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Storage.pm
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Storage.pm	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/lib/DBIx/Class/Storage.pm	2009-06-27 12:24:52 UTC (rev 6806)
@@ -248,6 +248,9 @@
 
 Issues a commit of the current transaction.
 
+It does I<not> perform an actual storage commit unless there's a DBIx::Class
+transaction currently in effect (i.e. you called L</txn_begin>).
+
 =cut
 
 sub txn_commit { die "Virtual method!" }

Modified: DBIx-Class/0.08/branches/run_file_against_storage/lib/SQL/Translator/Parser/DBIx/Class.pm
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/lib/SQL/Translator/Parser/DBIx/Class.pm	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/lib/SQL/Translator/Parser/DBIx/Class.pm	2009-06-27 12:24:52 UTC (rev 6806)
@@ -14,6 +14,7 @@
 
 use Exporter;
 use SQL::Translator::Utils qw(debug normalize_name);
+use Carp::Clan qw/^SQL::Translator|^DBIx::Class/;
 
 use base qw(Exporter);
 
@@ -34,11 +35,11 @@
     my $dbicschema    = $args->{'DBIx::Class::Schema'} ||  $args->{"DBIx::Schema"} ||$data;
     $dbicschema     ||= $args->{'package'};
     my $limit_sources = $args->{'sources'};
-    
-    die 'No DBIx::Class::Schema' unless ($dbicschema);
+
+    croak 'No DBIx::Class::Schema' unless ($dbicschema);
     if (!ref $dbicschema) {
       eval "use $dbicschema;";
-      die "Can't load $dbicschema ($@)" if($@);
+      croak "Can't load $dbicschema ($@)" if($@);
     }
 
     my $schema      = $tr->schema;
@@ -47,12 +48,11 @@
     $schema->name( ref($dbicschema) . " v" . ($dbicschema->schema_version || '1.x'))
       unless ($schema->name);
 
-    my %seen_tables;
-
     my @monikers = sort $dbicschema->sources;
     if ($limit_sources) {
         my $ref = ref $limit_sources || '';
-        die "'sources' parameter must be an array or hash ref" unless $ref eq 'ARRAY' || ref eq 'HASH';
+        $dbicschema->throw_exception ("'sources' parameter must be an array or hash ref")
+          unless( $ref eq 'ARRAY' || ref eq 'HASH' );
 
         # limit monikers to those specified in 
         my $sources;
@@ -76,21 +76,23 @@
       }
     }
 
+    my %tables;
     foreach my $moniker (sort @table_monikers)
     {
         my $source = $dbicschema->source($moniker);
-        
+        my $table_name = $source->name;
+
         # Skip custom query sources
-        next if ref($source->name);
+        next if ref $table_name;
 
-        # Its possible to have multiple DBIC source using same table
-        next if $seen_tables{$source->name}++;
+        # Its possible to have multiple DBIC sources using the same table
+        next if $tables{$table_name};
 
-        my $table = $schema->add_table(
-                                       name => $source->name,
+        $tables{$table_name}{source} = $source;
+        my $table = $tables{$table_name}{object} = SQL::Translator::Schema::Table->new(
+                                       name => $table_name,
                                        type => 'TABLE',
-                                       ) || die $schema->error;
-        my $colcount = 0;
+                                       );
         foreach my $col ($source->columns)
         {
             # assuming column_info in dbic is the same as DBI (?)
@@ -106,7 +108,8 @@
             if ($colinfo{is_nullable}) {
               $colinfo{default} = '' unless exists $colinfo{default};
             }
-            my $f = $table->add_field(%colinfo) || die $table->error;
+            my $f = $table->add_field(%colinfo)
+              || $dbicschema->throw_exception ($table->error);
         }
         $table->primary_key($source->primary_columns);
 
@@ -125,7 +128,7 @@
         my @rels = $source->relationships();
 
         my %created_FK_rels;
-        
+
         # global add_fk_index set in parser_args
         my $add_fk_index = (exists $args->{add_fk_index} && ($args->{add_fk_index} == 0)) ? 0 : 1;
 
@@ -146,7 +149,7 @@
             my $idx;
             my %other_columns_idx = map {'foreign.'.$_ => ++$idx } $othertable->columns;            
             my @cond = sort { $other_columns_idx{$a} cmp $other_columns_idx{$b} } keys(%{$rel_info->{cond}}); 
-      
+
             # Get the key information, mapping off the foreign/self markers
             my @refkeys = map {/^\w+\.(\w+)$/} @cond;
             my @keys = map {$rel_info->{cond}->{$_} =~ /^\w+\.(\w+)$/} @cond;
@@ -177,7 +180,7 @@
                         $cascade->{$c} = $rel_info->{attrs}{"on_$c"};
                     }
                     else {
-                        warn "SQLT attribute 'on_$c' was supplied for relationship '$moniker/$rel', which does not appear to be a foreign constraint. "
+                        carp "SQLT attribute 'on_$c' was supplied for relationship '$moniker/$rel', which does not appear to be a foreign constraint. "
                             . "If you are sure that SQLT must generate a constraint for this relationship, add 'is_foreign_key_constraint => 1' to the attributes.\n";
                     }
                 }
@@ -195,17 +198,21 @@
                 my $key_test = join("\x00", @keys);
                 next if $created_FK_rels{$rel_table}->{$key_test};
 
-                my $is_deferrable = $rel_info->{attrs}{is_deferrable};
-                
-                # global parser_args add_fk_index param can be overridden on the rel def
-                my $add_fk_index_rel = (exists $rel_info->{attrs}{add_fk_index}) ? $rel_info->{attrs}{add_fk_index} : $add_fk_index;
+                if (scalar(@keys)) {
 
+                  $created_FK_rels{$rel_table}->{$key_test} = 1;
 
-                $created_FK_rels{$rel_table}->{$key_test} = 1;
-                if (scalar(@keys)) {
+                  my $is_deferrable = $rel_info->{attrs}{is_deferrable};
+
+                  # do not consider deferrable constraints and self-references
+                  # for dependency calculations
+                  if (! $is_deferrable and $rel_table ne $table_name) {
+                    $tables{$table_name}{foreign_table_deps}{$rel_table}++;
+                  }
+
                   $table->add_constraint(
                                     type             => 'foreign_key',
-                                    name             => join('_', $table->name, 'fk', @keys),
+                                    name             => join('_', $table_name, 'fk', @keys),
                                     fields           => \@keys,
                                     reference_fields => \@refkeys,
                                     reference_table  => $rel_table,
@@ -213,10 +220,13 @@
                                     on_update        => uc ($cascade->{update} || ''),
                                     (defined $is_deferrable ? ( deferrable => $is_deferrable ) : ()),
                   );
-                    
+
+                  # global parser_args add_fk_index param can be overridden on the rel def
+                  my $add_fk_index_rel = (exists $rel_info->{attrs}{add_fk_index}) ? $rel_info->{attrs}{add_fk_index} : $add_fk_index;
+
                   if ($add_fk_index_rel) {
                       my $index = $table->add_index(
-                                                    name   => join('_', $table->name, 'idx', @keys),
+                                                    name   => join('_', $table_name, 'idx', @keys),
                                                     fields => \@keys,
                                                     type   => 'NORMAL',
                                                     );
@@ -224,31 +234,48 @@
               }
             }
         }
-		
-        $source->_invoke_sqlt_deploy_hook($table);
+
     }
 
+    # attach the tables to the schema in dependency order
+    my $dependencies = {
+      map { $_ => _resolve_deps ($_, \%tables) } (keys %tables)
+    };
+    for my $table (sort
+      {
+        keys %{$dependencies->{$a} || {} } <=> keys %{ $dependencies->{$b} || {} }
+          ||
+        $a cmp $b
+      }
+      (keys %tables)
+    ) {
+      $schema->add_table ($tables{$table}{object});
+      $tables{$table}{source} -> _invoke_sqlt_deploy_hook( $tables{$table}{object} );
+    }
+
+
+    my %views;
     foreach my $moniker (sort @view_monikers)
     {
         my $source = $dbicschema->source($moniker);
+        my $view_name = $source->name;
+
         # Skip custom query sources
-        next if ref($source->name);
+        next if ref $view_name;
 
         # Its possible to have multiple DBIC source using same table
-        next if $seen_tables{$source->name}++;
+        next if $views{$view_name}++;
 
-        my $view = $schema->add_view(
-          name => $source->name,
+        my $view = $schema->add_view (
+          name => $view_name,
           fields => [ $source->columns ],
           $source->view_definition ? ( 'sql' => $source->view_definition ) : ()
-        );
-        if ($source->result_class->can('sqlt_deploy_hook')) {
-          $source->result_class->sqlt_deploy_hook($view);
-        }
+        ) || $dbicschema->throw_exception ($schema->error);
 
         $source->_invoke_sqlt_deploy_hook($view);
     }
 
+
     if ($dbicschema->can('sqlt_deploy_hook')) {
       $dbicschema->sqlt_deploy_hook($schema);
     }
@@ -256,6 +283,41 @@
     return 1;
 }
 
+#
+# Quick and dirty dependency graph calculator
+#
+sub _resolve_deps {
+  my ($table, $tables, $seen) = @_;
+
+  my $ret = {};
+  $seen ||= {};
+
+  # copy and bump all deps by one (so we can reconstruct the chain)
+  my %seen = map { $_ => $seen->{$_} + 1 } (keys %$seen);
+  $seen{$table} = 1;
+
+  for my $dep (keys %{$tables->{$table}{foreign_table_deps}} ) {
+
+    if ($seen->{$dep}) {
+
+      # warn and remove the circular constraint so we don't get flooded with the same warning over and over
+      #carp sprintf ("Circular dependency detected, schema may not be deployable:\n%s\n",
+      #  join (' -> ', (sort { $seen->{$b} <=> $seen->{$a} } (keys %$seen) ), $table, $dep )
+      #);
+      #delete $tables->{$table}{foreign_table_deps}{$dep};
+
+      return {};
+    }
+
+    my $subdeps = _resolve_deps ($dep, $tables, \%seen);
+    $ret->{$_} += $subdeps->{$_} for ( keys %$subdeps );
+
+    ++$ret->{$dep};
+  }
+
+  return $ret;
+}
+
 1;
 
 =head1 NAME

Modified: DBIx-Class/0.08/branches/run_file_against_storage/t/46where_attribute.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/46where_attribute.t	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/46where_attribute.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -7,7 +7,7 @@
 use DBICTest;
 my $schema = DBICTest->init_schema();
 
-plan tests => 16;
+plan tests => 19;
 
 # select from a class with resultset_attributes
 my $resultset = $schema->resultset('BooksInLibrary');
@@ -72,3 +72,14 @@
 if ($@) { print $@ }
 ok( !$@, 'many_to_many add_to_$rel($hash) did not throw');
 is($round_objects->count, $round_count+1, 'many_to_many add_to_$rel($hash) count correct');
+
+# test set_$rel
+$round_count = $round_objects->count();
+$pointy_count = $pointy_objects->count();
+my @all_pointy_objects = $pointy_objects->all;
+# doing a set on pointy objects with its current set should not change any counts
+eval {$collection->set_pointy_objects(\@all_pointy_objects)};
+if ($@) { print $@ }
+ok( !$@, 'many_to_many set_$rel(\@objects) did not throw');
+is($pointy_objects->count, $pointy_count, 'many_to_many set_$rel($hash) count correct');
+is($round_objects->count, $round_count, 'many_to_many set_$rel($hash) other rel count correct');

Modified: DBIx-Class/0.08/branches/run_file_against_storage/t/67pager.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/67pager.t	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/67pager.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -84,3 +84,19 @@
 $schema->default_resultset_attributes({ rows => 5 });
 
 is($p->(), 5, 'default rows is 5');
+
+# test page with offset
+$it = $schema->resultset('CD')->search({}, {
+    rows => 2,
+    page => 2,
+    offset => 1,
+    order_by => 'cdid'
+});
+
+my $row = $schema->resultset('CD')->search({}, {
+    order_by => 'cdid', 
+    offset => 3,
+    rows => 1
+})->single;
+
+is($row->cdid, $it->first->cdid, 'page with offset');

Modified: DBIx-Class/0.08/branches/run_file_against_storage/t/85utf8.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/85utf8.t	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/85utf8.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -16,34 +16,24 @@
     eval 'use utf8; 1' or plan skip_all => 'Need utf8 run this test';
 }
 
-plan tests => 5;
+plan tests => 6;
 
 DBICTest::Schema::CD->load_components('UTF8Columns');
 DBICTest::Schema::CD->utf8_columns('title');
 Class::C3->reinitialize();
 
-my $cd = $schema->resultset('CD')->create( { artist => 1, title => 'øni', year => 'foo' } );
+my $cd = $schema->resultset('CD')->create( { artist => 1, title => 'øni', year => '2048' } );
 my $utf8_char = 'uniuni';
 
-if ($] <= 5.008000) {
 
-    ok( Encode::is_utf8( $cd->title ), 'got title with utf8 flag' );
-    ok( !Encode::is_utf8( $cd->year ), 'got year without utf8 flag' );
+ok( _is_utf8( $cd->title ), 'got title with utf8 flag' );
+ok(! _is_utf8( $cd->year ), 'got year without utf8 flag' );
 
-    Encode::_utf8_on($utf8_char);
-    $cd->title($utf8_char);
-    ok( !Encode::is_utf8( $cd->{_column_data}{title} ), 'store utf8-less chars' );
+_force_utf8($utf8_char);
+$cd->title($utf8_char);
+ok(! _is_utf8( $cd->{_column_data}{title} ), 'store utf8-less chars' );
 
-} else {
 
-    ok( utf8::is_utf8( $cd->title ), 'got title with utf8 flag' );
-    ok( !utf8::is_utf8( $cd->year ), 'got year without utf8 flag' );
-
-    utf8::decode($utf8_char);
-    $cd->title($utf8_char);
-    ok( !utf8::is_utf8( $cd->{_column_data}{title} ), 'store utf8-less chars' );
-}
-
 my $v_utf8 = "\x{219}";
 
 $cd->update ({ title => $v_utf8 });
@@ -53,3 +43,28 @@
 $cd->update ({ title => $v_utf8 });
 $cd->title('something_else');
 ok( $cd->is_column_changed('title'), 'column is dirty after setting to something completely different');
+
+TODO: {
+  local $TODO = 'There is currently no way to propagate aliases to inflate_result()';
+  $cd = $schema->resultset('CD')->find ({ title => $v_utf8 }, { select => 'title', as => 'name' });
+  ok (_is_utf8( $cd->get_column ('name') ), 'utf8 flag propagates via as');
+}
+
+
+sub _force_utf8 {
+  if ($] <= 5.008000) {
+    Encode::_utf8_on ($_[0]);
+  }
+  else {
+    utf8::decode ($_[0]);
+  }
+}
+
+sub _is_utf8 {
+  if ($] <= 5.008000) {
+    return Encode::is_utf8 (shift);
+  }
+  else {
+    return utf8::is_utf8 (shift);
+  }
+}

Modified: DBIx-Class/0.08/branches/run_file_against_storage/t/86sqlt.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/86sqlt.t	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/86sqlt.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -45,7 +45,11 @@
     ok($output, "SQLT produced someoutput")
       or diag($translator->error);
 
-    like ($warn, qr/^SQLT attribute .+? was supplied for relationship/, 'Warn about dubious on_delete/on_update attributes');
+    like (
+      $warn,
+      qr/SQLT attribute .+? was supplied for relationship .+? which does not appear to be a foreign constraint/,
+      'Warn about dubious on_delete/on_update attributes',
+    );
 }
 
 # Note that the constraints listed here are the only ones that are tested -- if
@@ -155,7 +159,7 @@
       'name' => 'artist_undirected_map_fk_id2', 'index_name' => 'artist_undirected_map_idx_id2',
       'selftable' => 'artist_undirected_map', 'foreigntable' => 'artist', 
       'selfcols'  => ['id2'], 'foreigncols' => ['artistid'],
-      on_delete => '', on_update => 'CASCADE', deferrable => 1,
+      on_delete => '', on_update => '', deferrable => 1,
     },
   ],
 

Modified: DBIx-Class/0.08/branches/run_file_against_storage/t/93storage_replication.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/93storage_replication.t	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/93storage_replication.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -361,11 +361,8 @@
 
 ## Check that master_read_weight is honored
 {
-    no warnings 'once';
+    no warnings qw/once redefine/;
 
-    # turn off redefined warning
-    local $SIG{__WARN__} = sub {};
-
     local
     *DBIx::Class::Storage::DBI::Replicated::Balancer::Random::_random_number =
 	sub { 999 };

Deleted: DBIx-Class/0.08/branches/run_file_against_storage/t/96multi_create.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/96multi_create.t	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/96multi_create.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -1,487 +0,0 @@
-use strict;
-use warnings;
-
-use Test::More;
-use Test::Exception;
-use lib qw(t/lib);
-use DBICTest;
-
-plan tests => 93;
-
-my $schema = DBICTest->init_schema();
-
-lives_ok ( sub {
-  my $cd = $schema->resultset('CD')->create({
-    artist => { 
-      name => 'Fred Bloggs' 
-    },
-    title => 'Some CD',
-    year => 1996
-  });
-
-  isa_ok($cd, 'DBICTest::CD', 'Created CD object');
-  isa_ok($cd->artist, 'DBICTest::Artist', 'Created related Artist');
-  is($cd->artist->name, 'Fred Bloggs', 'Artist created correctly');
-}, 'simple create + parent (the stuff $rs belongs_to) ok');
-
-lives_ok ( sub {
-  my $bm_rs = $schema->resultset('Bookmark');
-  my $bookmark = $bm_rs->create({
-    link => {
-      id => 66,
-    },
-  });
-
-  isa_ok($bookmark, 'DBICTest::Bookmark', 'Created Bookrmark object');
-  isa_ok($bookmark->link, 'DBICTest::Link', 'Created related Link');
-  is (
-    $bm_rs->search (
-      { 'link.title' => $bookmark->link->title },
-      { join => 'link' },
-    )->count,
-    1,
-    'Bookmark and link made it to the DB',
-  );
-}, 'simple create where the child and parent have no values, except for an explicit parent pk ok');
-
-lives_ok ( sub {
-  my $artist = $schema->resultset('Artist')->first;
-  my $cd = $artist->create_related (cds => {
-    title => 'Music to code by',
-    year => 2007,
-    tags => [
-      { 'tag' => 'rock' },
-    ],
-  });
-
-  isa_ok($cd, 'DBICTest::CD', 'Created CD');
-  is($cd->title, 'Music to code by', 'CD created correctly');
-  is($cd->tags->count, 1, 'One tag created for CD');
-  is($cd->tags->first->tag, 'rock', 'Tag created correctly');
-
-}, 'create over > 1 levels of has_many create (A => { has_many => { B => has_many => C } } )');
-
-throws_ok (
-  sub {
-    # Create via update - add a new CD <--- THIS SHOULD HAVE NEVER WORKED!
-    $schema->resultset('Artist')->first->update({
-      cds => [
-        { title => 'Yet another CD',
-          year => 2006,
-        },
-      ],
-    });
-  },
-  qr/Recursive update is not supported over relationships of type multi/,
-  'create via update of multi relationships throws an exception'
-);
-
-lives_ok ( sub {
-  my $artist = $schema->resultset('Artist')->first;
-  my $c2p = $schema->resultset('CD_to_Producer')->create ({
-    cd => {
-      artist => $artist,
-      title => 'Bad investment',
-      year => 2008,
-      tracks => [
-        { title => 'Just buy' },
-        { title => 'Why did we do it' },
-        { title => 'Burn baby burn' },
-      ],
-    },
-    producer => {
-      name => 'Lehman Bros.',
-    },
-  });
-
-  isa_ok ($c2p, 'DBICTest::CD_to_Producer', 'Linker object created');
-  my $prod = $schema->resultset ('Producer')->find ({ name => 'Lehman Bros.' });
-  isa_ok ($prod, 'DBICTest::Producer', 'Producer row found');
-  is ($prod->cds->count, 1, 'Producer has one production');
-  my $cd = $prod->cds->first;
-  is ($cd->title, 'Bad investment', 'CD created correctly');
-  is ($cd->tracks->count, 3, 'CD has 3 tracks');
-}, 'Create m2m while originating in the linker table');
-
-
-#CD -> has_many -> Tracks -> might have -> Single -> has_many -> Tracks
-#                                               \
-#                                                \-> has_many \
-#                                                              --> CD2Producer
-#                                                /-> has_many /
-#                                               /
-#                                          Producer
-lives_ok ( sub {
-  my $artist = $schema->resultset('Artist')->first;
-  my $cd = $schema->resultset('CD')->create ({
-    artist => $artist,
-    title => 'Music to code by at night',
-    year => 2008,
-    tracks => [
-      {
-        title => 'Off by one again',
-      },
-      {
-        title => 'The dereferencer',
-        cd_single => {
-          artist => $artist,
-          year => 2008,
-          title => 'Was that a null (Single)',
-          tracks => [
-            { title => 'The dereferencer' },
-            { title => 'The dereferencer II' },
-          ],
-          cd_to_producer => [
-            {
-              producer => {
-                name => 'K&R',
-              }
-            },
-            {
-              producer => {
-                name => 'Don Knuth',
-              }
-            },
-          ]
-        },
-      },
-    ],
-  });
-
-  isa_ok ($cd, 'DBICTest::CD', 'Main CD object created');
-  is ($cd->title, 'Music to code by at night', 'Correct CD title');
-  is ($cd->tracks->count, 2, 'Two tracks on main CD');
-
-  my ($t1, $t2) = $cd->tracks->all;
-  is ($t1->title, 'Off by one again', 'Correct 1st track name');
-  is ($t1->cd_single, undef, 'No single for 1st track');
-  is ($t2->title, 'The dereferencer', 'Correct 2nd track name');
-  isa_ok ($t2->cd_single, 'DBICTest::CD', 'Created a single for 2nd track');
-
-  my $single = $t2->cd_single;
-  is ($single->tracks->count, 2, 'Two tracks on single CD');
-  is ($single->tracks->find ({ position => 1})->title, 'The dereferencer', 'Correct 1st track title');
-  is ($single->tracks->find ({ position => 2})->title, 'The dereferencer II', 'Correct 2nd track title');
-
-  is ($single->cd_to_producer->count, 2, 'Two producers created for the single cd');
-  is_deeply (
-    [ sort map { $_->producer->name } ($single->cd_to_producer->all) ],
-    ['Don Knuth', 'K&R'],
-    'Producers named correctly',
-  );
-}, 'Create over > 1 levels of might_have with multiple has_many and multiple m2m but starting at a has_many level');
-
-#Track -> might have -> Single -> has_many -> Tracks
-#                           \
-#                            \-> has_many \
-#                                          --> CD2Producer
-#                            /-> has_many /
-#                           /
-#                       Producer
-lives_ok ( sub {
-  my $cd = $schema->resultset('CD')->first;
-  my $track = $schema->resultset('Track')->create ({
-    cd => $cd,
-    title => 'Multicreate rocks',
-    cd_single => {
-      artist => $cd->artist,
-      year => 2008,
-      title => 'Disemboweling MultiCreate',
-      tracks => [
-        { title => 'Why does mst write this way' },
-        { title => 'Chainsaw celebration' },
-        { title => 'Purl cleans up' },
-      ],
-      cd_to_producer => [
-        {
-          producer => {
-            name => 'mst',
-          }
-        },
-        {
-          producer => {
-            name => 'castaway',
-          }
-        },
-        {
-          producer => {
-            name => 'theorbtwo',
-          }
-        },
-      ]
-    },
-  });
-
-  isa_ok ($track, 'DBICTest::Track', 'Main Track object created');
-  is ($track->title, 'Multicreate rocks', 'Correct Track title');
-
-  my $single = $track->cd_single;
-  isa_ok ($single, 'DBICTest::CD', 'Created a single with the track');
-  is ($single->tracks->count, 3, '3 tracks on single CD');
-  is ($single->tracks->find ({ position => 1})->title, 'Why does mst write this way', 'Correct 1st track title');
-  is ($single->tracks->find ({ position => 2})->title, 'Chainsaw celebration', 'Correct 2nd track title');
-  is ($single->tracks->find ({ position => 3})->title, 'Purl cleans up', 'Correct 3rd track title');
-
-  is ($single->cd_to_producer->count, 3, '3 producers created for the single cd');
-  is_deeply (
-    [ sort map { $_->producer->name } ($single->cd_to_producer->all) ],
-    ['castaway', 'mst', 'theorbtwo'],
-    'Producers named correctly',
-  );
-}, 'Create over > 1 levels of might_have with multiple has_many and multiple m2m but starting at the might_have directly');
-
-lives_ok ( sub {
-  my $artist = $schema->resultset('Artist')->first;
-  my $cd = $schema->resultset('CD')->create ({
-    artist => $artist,
-    title => 'Music to code by at twilight',
-    year => 2008,
-    artwork => {
-      images => [
-        { name => 'recursive descent' },
-        { name => 'tail packing' },
-      ],
-    },
-  });
-
-  isa_ok ($cd, 'DBICTest::CD', 'Main CD object created');
-  is ($cd->title, 'Music to code by at twilight', 'Correct CD title');
-  isa_ok ($cd->artwork, 'DBICTest::Artwork', 'Artwork created');
-
-  # this test might look weird, but it failed at one point, keep it there
-  my $art_obj = $cd->artwork;
-  ok ($art_obj->has_column_loaded ('cd_id'), 'PK/FK present on artwork object');
-  is ($art_obj->images->count, 2, 'Correct artwork image count via the new object');
-  is_deeply (
-    [ sort $art_obj->images->get_column ('name')->all ],
-    [ 'recursive descent', 'tail packing' ],
-    'Images named correctly in objects',
-  );
-
-  my $artwork = $schema->resultset('Artwork')->search (
-    { 'cd.title' => 'Music to code by at twilight' },
-    { join => 'cd' },
-  )->single;
-
-  is ($artwork->images->count, 2, 'Correct artwork image count via a new search');
-
-  is_deeply (
-    [ sort $artwork->images->get_column ('name')->all ],
-    [ 'recursive descent', 'tail packing' ],
-    'Images named correctly after search',
-  );
-}, 'Test might_have again but with a PK == FK in the middle (obviously not specified)');
-
-lives_ok ( sub {
-  my $cd = $schema->resultset('CD')->first;
-  my $track = $schema->resultset ('Track')->create ({
-    cd => $cd,
-    title => 'Black',
-    lyrics => {
-      lyric_versions => [
-        { text => 'The color black' },
-        { text => 'The colour black' },
-      ],
-    },
-  });
-
-  isa_ok ($track, 'DBICTest::Track', 'Main track object created');
-  is ($track->title, 'Black', 'Correct track title');
-  isa_ok ($track->lyrics, 'DBICTest::Lyrics', 'Lyrics created');
-
-  # this test might look weird, but it was failing at one point, keep it there
-  my $lyric_obj = $track->lyrics;
-  ok ($lyric_obj->has_column_loaded ('lyric_id'), 'PK present on lyric object');
-  ok ($lyric_obj->has_column_loaded ('track_id'), 'FK present on lyric object');
-  is ($lyric_obj->lyric_versions->count, 2, 'Correct lyric versions count via the new object');
-  is_deeply (
-    [ sort $lyric_obj->lyric_versions->get_column ('text')->all ],
-    [ 'The color black', 'The colour black' ],
-    'Lyrics text in objects matches',
-  );
-
-
-  my $lyric = $schema->resultset('Lyrics')->search (
-    { 'track.title' => 'Black' },
-    { join => 'track' },
-  )->single;
-
-  is ($lyric->lyric_versions->count, 2, 'Correct lyric versions count via a new search');
-
-  is_deeply (
-    [ sort $lyric->lyric_versions->get_column ('text')->all ],
-    [ 'The color black', 'The colour black' ],
-    'Lyrics text via search matches',
-  );
-}, 'Test might_have again but with just a PK and FK (neither specified) in the mid-table');
-
-lives_ok ( sub {
-  my $newartist2 = $schema->resultset('Artist')->find_or_create({ 
-    name => 'Fred 3',
-    cds => [
-      { 
-        title => 'Noah Act',
-        year => 2007,
-      },
-    ],
-  });
-  is($newartist2->name, 'Fred 3', 'Created new artist with cds via find_or_create');
-}, 'Nested find_or_create');
-
-lives_ok ( sub {
-  my $artist2 = $schema->resultset('Artist')->create({
-    name => 'Fred 4',
-    cds => [
-      {
-        title => 'Music to code by',
-        year => 2007,
-      },
-    ],
-    cds_unordered => [
-      {
-        title => 'Music to code by',
-        year => 2007,
-      },
-    ]
-  });
-
-  is($artist2->in_storage, 1, 'artist with duplicate rels inserted okay');
-}, 'Multiple same level has_many create');
-
-lives_ok ( sub {
-	my $artist = $schema->resultset('Artist')->first;
-	
-	my $cd_result = $artist->create_related('cds', {
-	
-		title => 'TestOneCD1',
-		year => 2007,
-		tracks => [
-			{ title => 'TrackOne' },
-			{ title => 'TrackTwo' },
-		],
-
-	});
-	
-	isa_ok( $cd_result, 'DBICTest::CD', "Got Good CD Class");
-	ok( $cd_result->title eq "TestOneCD1", "Got Expected Title");
-	
-	my $tracks = $cd_result->tracks;
-	
-	isa_ok( $tracks, 'DBIx::Class::ResultSet', 'Got Expected Tracks ResultSet');
-	
-	foreach my $track ($tracks->all)
-	{
-		isa_ok( $track, 'DBICTest::Track', 'Got Expected Track Class');
-	}
-}, 'First create_related pass');
-
-lives_ok ( sub {
-	my $artist = $schema->resultset('Artist')->first;
-	
-	my $cd_result = $artist->create_related('cds', {
-	
-		title => 'TestOneCD2',
-		year => 2007,
-		tracks => [
-			{ title => 'TrackOne' },
-			{ title => 'TrackTwo' },
-		],
-
-    liner_notes => { notes => 'I can haz liner notes?' },
-
-	});
-	
-	isa_ok( $cd_result, 'DBICTest::CD', "Got Good CD Class");
-	ok( $cd_result->title eq "TestOneCD2", "Got Expected Title");
-  ok( $cd_result->notes eq 'I can haz liner notes?', 'Liner notes');
-	
-	my $tracks = $cd_result->tracks;
-	
-	isa_ok( $tracks, 'DBIx::Class::ResultSet', "Got Expected Tracks ResultSet");
-	
-	foreach my $track ($tracks->all)
-	{
-		isa_ok( $track, 'DBICTest::Track', 'Got Expected Track Class');
-	}
-}, 'second create_related with same arguments');
-
-lives_ok ( sub {
-  my $cdp = $schema->resultset('CD_to_Producer')->create({
-    cd => { artist => 1, title => 'foo', year => 2000 },
-    producer => { name => 'jorge' }
-  });
-  ok($cdp, 'join table record created ok');
-}, 'create of parents of a record linker table');
-
-lives_ok ( sub {
-  my $kurt_cobain = { name => 'Kurt Cobain' };
-
-  my $in_utero = $schema->resultset('CD')->new({
-      title => 'In Utero',
-      year  => 1993
-    });
-
-  $kurt_cobain->{cds} = [ $in_utero ];
-
-
-  $schema->resultset('Artist')->populate([ $kurt_cobain ]); # %)
-  $a = $schema->resultset('Artist')->find({name => 'Kurt Cobain'});
-
-  is($a->name, 'Kurt Cobain', 'Artist insertion ok');
-  is($a->cds && $a->cds->first && $a->cds->first->title, 
-		  'In Utero', 'CD insertion ok');
-}, 'populate');
-
-## Create foreign key col obj including PK
-## See test 20 in 66relationships.t
-lives_ok ( sub {
-  my $new_cd_hashref = { 
-    cdid => 27, 
-    title => 'Boogie Woogie', 
-    year => '2007', 
-    artist => { artistid => 17, name => 'king luke' }
-  };
-
-  my $cd = $schema->resultset("CD")->find(1);
-
-  is($cd->artist->id, 1, 'rel okay');
-
-  my $new_cd = $schema->resultset("CD")->create($new_cd_hashref);
-  is($new_cd->artist->id, 17, 'new id retained okay');
-}, 'Create foreign key col obj including PK');
-
-lives_ok ( sub {
-	$schema->resultset("CD")->create({ 
-              cdid => 28, 
-              title => 'Boogie Wiggle', 
-              year => '2007', 
-              artist => { artistid => 18, name => 'larry' }
-             });
-}, 'new cd created without clash on related artist');
-
-throws_ok ( sub {
-    my $t = $schema->resultset("Track")->new({ cd => { artist => undef } });
-    #$t->cd($t->new_related('cd', { artist => undef } ) );
-    #$t->{_rel_in_storage} = 0;
-    $t->insert;
-}, qr/cd.artist may not be NULL/, "Exception propogated properly");
-
-lives_ok ( sub {
-  $schema->resultset('CD')->create ({
-    artist => {
-      name => 'larry', # should already exist
-    },
-    title => 'Warble Marble',
-    year => '2009',
-    cd_to_producer => [
-      { producer => { name => 'Cowboy Neal' } },
-    ],
-  });
-
-  my $m2m_cd = $schema->resultset('CD')->search ({ title => 'Warble Marble'});
-  is ($m2m_cd->count, 1, 'One CD row created via M2M create');
-  is ($m2m_cd->first->producers->count, 1, 'CD row created with one producer');
-  is ($m2m_cd->first->producers->first->name, 'Cowboy Neal', 'Correct producer row created');
-}, 'Test multi create over many_to_many');
-
-1;

Deleted: DBIx-Class/0.08/branches/run_file_against_storage/t/96multi_create_new.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/96multi_create_new.t	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/96multi_create_new.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -1,74 +0,0 @@
-use strict;
-use warnings;
-
-use Test::More;
-use Test::Exception;
-use lib qw(t/lib);
-use DBICTest;
-
-plan tests => 12;
-
-my $schema = DBICTest->init_schema();
-
-# Test various new() invocations - this is all about backcompat, making 
-# sure that insert() still works as expected by legacy code.
-#
-# What we essentially do is multi-instantiate objects, making sure nothing
-# gets inserted. Then we add some more objects to the mix either via
-# new_related() or by setting an accessor directly (or both) - again
-# expecting no inserts. Then after calling insert() on the starter object
-# we expect everything supplied to new() to get inserted, as well as any
-# relations whose PK's are necessary to complete the objects supplied
-# to new(). All other objects should be insert()able afterwards too.
-
-
-{
-    my $new_artist = $schema->resultset("Artist")->new_result({ 'name' => 'Depeche Mode' });
-    my $new_related_cd = $new_artist->new_related('cds', { 'title' => 'Leave in Silence', 'year' => 1982});
-    eval {
-        $new_artist->insert;
-        $new_related_cd->insert;
-    };
-    is ($@, '', 'Staged insertion successful');
-    ok($new_artist->in_storage, 'artist inserted');
-    ok($new_related_cd->in_storage, 'new_related_cd inserted');
-}
-
-{
-    my $new_artist = $schema->resultset("Artist")->new_result({ 'name' => 'Depeche Mode' });
-    my $new_related_cd = $new_artist->new_related('cds', { 'title' => 'Leave Slightly Noisily', 'year' => 1982});
-    eval {
-        $new_related_cd->insert;
-    };
-    is ($@, '', 'CD insertion survives by finding artist');
-    ok($new_artist->in_storage, 'artist inserted');
-    ok($new_related_cd->in_storage, 'new_related_cd inserted');
-}
-
-{
-    my $new_artist = $schema->resultset("Artist")->new_result({ 'name' => 'Depeche Mode 2: Insertion Boogaloo' });
-    my $new_related_cd = $new_artist->new_related('cds', { 'title' => 'Leave Loudly While Singing Off Key', 'year' => 1982});
-    eval {
-        $new_related_cd->insert;
-    };
-    is ($@, '', 'CD insertion survives by inserting artist');
-    ok($new_artist->in_storage, 'artist inserted');
-    ok($new_related_cd->in_storage, 'new_related_cd inserted');
-}
-
-{
-    my $new_cd = $schema->resultset("CD")->new_result({});
-    my $new_related_artist = $new_cd->new_related('artist', { 'name' => 'Marillion',});
-    lives_ok (
-        sub {
-            $new_related_artist->insert;
-            $new_cd->title( 'Misplaced Childhood' );
-            $new_cd->year ( 1985 );
-            $new_cd->artist( $new_related_artist );  # For exact backward compatibility
-            $new_cd->insert;
-        },
-        'Reversed staged insertion successful'
-    );
-    ok($new_related_artist->in_storage, 'related artist inserted');
-    ok($new_cd->in_storage, 'cd inserted');
-}

Deleted: DBIx-Class/0.08/branches/run_file_against_storage/t/96multi_create_torture.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/96multi_create_torture.t	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/96multi_create_torture.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -1,224 +0,0 @@
-use strict;
-use warnings;
-
-use Test::More;
-use Test::Exception;
-use lib qw(t/lib);
-use DBICTest;
-
-plan tests => 23;
-
-# an insane multicreate 
-# (should work, despite the fact that no one will probably use it this way)
-
-my $schema = DBICTest->init_schema();
-
-# first count how many rows do we initially have
-my $counts;
-$counts->{$_} = $schema->resultset($_)->count for qw/Artist CD Genre Producer Tag/;
-
-# do the crazy create
-eval {
-  $schema->resultset('CD')->create ({
-    artist => {
-      name => 'james',
-    },
-    title => 'Greatest hits 1',
-    year => '2012',
-    genre => {
-      name => '"Greatest" collections',
-    },
-    tags => [
-      { tag => 'A' },
-      { tag => 'B' },
-    ],
-    cd_to_producer => [
-      {
-        producer => {
-          name => 'bob',
-          producer_to_cd => [
-            {
-              cd => { 
-                artist => {
-                  name => 'lars',
-                  cds => [
-                    {
-                      title => 'Greatest hits 2',
-                      year => 2012,
-                      genre => {
-                        name => '"Greatest" collections',
-                      },
-                      tags => [
-                        { tag => 'A' },
-                        { tag => 'B' },
-                      ],
-                      # This cd is created via artist so it doesn't know about producers
-                      cd_to_producer => [
-                        { producer => { name => 'bob' } },
-                        { producer => { name => 'paul' } },
-                        { producer => {
-                          name => 'flemming',
-                          producer_to_cd => [
-                            { cd => {
-                              artist => {
-                                name => 'kirk',
-                                cds => [
-                                  {
-                                    title => 'Greatest hits 3',
-                                    year => 2012,
-                                    genre => {
-                                      name => '"Greatest" collections',
-                                    },
-                                    tags => [
-                                      { tag => 'A' },
-                                      { tag => 'B' },
-                                    ],
-                                  },
-                                  {
-                                    title => 'Greatest hits 4',
-                                    year => 2012,
-                                    genre => {
-                                      name => '"Greatest" collections2',
-                                    },
-                                    tags => [
-                                      { tag => 'A' },
-                                      { tag => 'B' },
-                                    ],
-                                  },
-                                ],
-                              },
-                              title => 'Greatest hits 5',
-                              year => 2013,
-                              genre => {
-                                name => '"Greatest" collections2',
-                              },
-                            }},
-                          ],
-                        }},
-                      ],
-                    },
-                  ],
-                },
-                title => 'Greatest hits 6',
-                year => 2012,
-                genre => {
-                  name => '"Greatest" collections',
-                },
-                tags => [
-                  { tag => 'A' },
-                  { tag => 'B' },
-                ],
-              },
-            },
-            {
-              cd => { 
-                artist => {
-                  name => 'lars',    # should already exist
-                  # even though the artist 'name' is not uniquely constrained
-                  # find_or_create will arguably DWIM 
-                },
-                title => 'Greatest hits 7',
-                year => 2013,
-              },
-            },
-          ],
-        },
-      },
-    ],
-  });
-
-  is ($schema->resultset ('Artist')->count, $counts->{Artist} + 3, '3 new artists created');
-  is ($schema->resultset ('Genre')->count, $counts->{Genre} + 2, '2 additional genres created');
-  is ($schema->resultset ('Producer')->count, $counts->{Producer} + 3, '3 new producer');
-  is ($schema->resultset ('CD')->count, $counts->{CD} + 7, '7 new CDs');
-  is ($schema->resultset ('Tag')->count, $counts->{Tag} + 10, '10 new Tags');
-
-  my $cd_rs = $schema->resultset ('CD')
-    ->search ({ title => { -like => 'Greatest hits %' }}, { order_by => 'title'} );
-  is ($cd_rs->count, 7, '7 greatest hits created');
-
-  my $cds_2012 = $cd_rs->search ({ year => 2012});
-  is ($cds_2012->count, 5, '5 CDs created in 2012');
-
-  is (
-    $cds_2012->search(
-      { 'tags.tag' => { -in => [qw/A B/] } },
-      { join => 'tags', group_by => 'me.cdid' }
-    ),
-    5,
-    'All 10 tags were pairwise distributed between 5 year-2012 CDs'
-  );
-
-  my $paul_prod = $cd_rs->search (
-    { 'producer.name' => 'paul'},
-    { join => { cd_to_producer => 'producer' } }
-  );
-  is ($paul_prod->count, 1, 'Paul had 1 production');
-  my $pauls_cd = $paul_prod->single;
-  is ($pauls_cd->cd_to_producer->count, 3, 'Paul had two co-producers');
-  is (
-    $pauls_cd->search_related ('cd_to_producer',
-      { 'producer.name' => 'flemming'},
-      { join => 'producer' }
-    )->count,
-    1,
-    'The second producer is flemming',
-  );
-
-  my $kirk_cds = $cd_rs->search ({ 'artist.name' => 'kirk' }, { join => 'artist' });
-  is ($kirk_cds, 3, 'Kirk had 3 CDs');
-  is (
-    $kirk_cds->search (
-      { 'cd_to_producer.cd' => { '!=', undef } },
-      { join => 'cd_to_producer' },
-    ),
-    1,
-    'Kirk had a producer only on one cd',
-  );
-
-  my $lars_cds = $cd_rs->search ({ 'artist.name' => 'lars' }, { join => 'artist' });
-  is ($lars_cds->count, 3, 'Lars had 3 CDs');
-  is (
-    $lars_cds->search (
-      { 'cd_to_producer.cd' => undef },
-      { join => 'cd_to_producer' },
-    ),
-    0,
-    'Lars always had a producer',
-  );
-  is (
-    $lars_cds->search_related ('cd_to_producer',
-      { 'producer.name' => 'flemming'},
-      { join => 'producer' }
-    )->count,
-    1,
-    'Lars produced 1 CD with flemming',
-  );
-  is (
-    $lars_cds->search_related ('cd_to_producer',
-      { 'producer.name' => 'bob'},
-      { join => 'producer' }
-    )->count,
-    3,
-    'Lars produced 3 CDs with bob',
-  );
-
-  my $bob_prod = $cd_rs->search (
-    { 'producer.name' => 'bob'},
-    { join => { cd_to_producer => 'producer' } }
-  );
-  is ($bob_prod->count, 4, 'Bob produced a total of 4 CDs');
-  ok ($bob_prod->find ({ title => 'Greatest hits 1'}), '1st Bob production name correct');
-  ok ($bob_prod->find ({ title => 'Greatest hits 6'}), '2nd Bob production name correct');
-  ok ($bob_prod->find ({ title => 'Greatest hits 2'}), '3rd Bob production name correct');
-  ok ($bob_prod->find ({ title => 'Greatest hits 7'}), '4th Bob production name correct');
-
-  is (
-    $bob_prod->search ({ 'artist.name' => 'james' }, { join => 'artist' })->count,
-    1,
-    "Bob produced james' only CD",
-  );
-};
-diag $@ if $@;
-
-1;


Property changes on: DBIx-Class/0.08/branches/run_file_against_storage/t/cdbi/DeepAbstractSearch/01_search.t
___________________________________________________________________
Name: svn:executable
   - *

Added: DBIx-Class/0.08/branches/run_file_against_storage/t/count/count_rs.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/count/count_rs.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/count/count_rs.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -0,0 +1,119 @@
+use strict;
+use warnings;
+
+use lib qw(t/lib);
+
+use Test::More;
+use DBICTest;
+use DBIC::SqlMakerTest;
+use DBIC::DebugObj;
+
+plan tests => 10;
+
+my $schema = DBICTest->init_schema();
+
+# non-collapsing prefetch (no multi prefetches)
+{
+  my $rs = $schema->resultset("CD")
+            ->search_related('tracks',
+                { position => [1,2] },
+                { prefetch => [qw/disc lyrics/], rows => 3, offset => 8 },
+            );
+  is ($rs->all, 2, 'Correct number of objects');
+
+
+  my ($sql, @bind);
+  $schema->storage->debugobj(DBIC::DebugObj->new(\$sql, \@bind));
+  $schema->storage->debug(1);
+
+  is ($rs->count, 2, 'Correct count via count()');
+
+  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 = ? ) )
+    ',
+    [ qw/'1' '2'/ ],
+    'count softlimit applied',
+  );
+
+  my $crs = $rs->count_rs;
+  is ($crs->next, 2, 'Correct count via count_rs()');
+
+  is_same_sql_bind (
+    $crs->as_query,
+    '(SELECT COUNT( * )
+       FROM (
+        SELECT tracks.trackid
+          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 = ? ) )
+        LIMIT 3 OFFSET 8
+       ) count_subq
+    )',
+    [ [ position => 1 ], [ position => 2 ] ],
+    'count_rs db-side limit applied',
+  );
+}
+
+# has_many prefetch with limit
+{
+  my $rs = $schema->resultset("Artist")
+            ->search_related('cds',
+                { 'tracks.position' => [1,2] },
+                { prefetch => [qw/tracks artist/], rows => 3, offset => 4 },
+            );
+  is ($rs->all, 1, 'Correct number of objects');
+
+  my ($sql, @bind);
+  $schema->storage->debugobj(DBIC::DebugObj->new(\$sql, \@bind));
+  $schema->storage->debug(1);
+
+  is ($rs->count, 1, 'Correct count via count()');
+
+  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
+    ',
+    [ qw/'1' '2'/ ],
+    'count softlimit applied',
+  );
+
+  my $crs = $rs->count_rs;
+  is ($crs->next, 1, 'Correct count via count_rs()');
+
+  is_same_sql_bind (
+    $crs->as_query,
+    '(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
+        LIMIT 3 OFFSET 4
+      ) count_subq
+    )',
+    [ [ 'tracks.position' => 1 ], [ 'tracks.position' => 2 ] ],
+    'count_rs db-side limit applied',
+  );
+}

Modified: DBIx-Class/0.08/branches/run_file_against_storage/t/count/distinct.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/count/distinct.t	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/count/distinct.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -11,9 +11,7 @@
 
 my $schema = DBICTest->init_schema();
 
-eval "use DBD::SQLite";
-plan skip_all => 'needs DBD::SQLite for testing' if $@;
-plan tests => 22;
+plan tests => 58;
 
 # The tag Blue is assigned to cds 1 2 3 and 5
 # The tag Cheesy is assigned to cds 2 4 and 5
@@ -23,59 +21,64 @@
 my $rs;
 my $in_rs = $schema->resultset('Tag')->search({ tag => [ 'Blue', 'Cheesy' ] });
 
-$rs = $schema->resultset('Tag')->search({ tag => 'Blue' });
-is($rs->count, 4, 'Count without DISTINCT');
+for my $get_count (
+  sub { shift->count },
+  sub { my $crs = shift->count_rs; isa_ok ($crs, 'DBIx::Class::ResultSetColumn'); $crs->next }
+) {
+  $rs = $schema->resultset('Tag')->search({ tag => 'Blue' });
+  is($get_count->($rs), 4, 'Count without DISTINCT');
 
-$rs = $schema->resultset('Tag')->search({ tag => [ 'Blue', 'Cheesy' ] }, { group_by => 'tag' });
-is($rs->count, 2, 'Count with single column group_by');
+  $rs = $schema->resultset('Tag')->search({ tag => [ 'Blue', 'Cheesy' ] }, { group_by => 'tag' });
+  is($get_count->($rs), 2, 'Count with single column group_by');
 
-$rs = $schema->resultset('Tag')->search({ tag => [ 'Blue', 'Cheesy' ] }, { group_by => 'cd' });
-is($rs->count, 5, 'Count with another single column group_by');
+  $rs = $schema->resultset('Tag')->search({ tag => [ 'Blue', 'Cheesy' ] }, { group_by => 'cd' });
+  is($get_count->($rs), 5, 'Count with another single column group_by');
 
-$rs = $schema->resultset('Tag')->search({ tag => 'Blue' }, { group_by => [ qw/tag cd/ ]});
-is($rs->count, 4, 'Count with multiple column group_by');
+  $rs = $schema->resultset('Tag')->search({ tag => 'Blue' }, { group_by => [ qw/tag cd/ ]});
+  is($get_count->($rs), 4, 'Count with multiple column group_by');
 
-$rs = $schema->resultset('Tag')->search({ tag => 'Blue' }, { distinct => 1 });
-is($rs->count, 4, 'Count with single column distinct');
+  $rs = $schema->resultset('Tag')->search({ tag => 'Blue' }, { distinct => 1 });
+  is($get_count->($rs), 4, 'Count with single column distinct');
 
-$rs = $schema->resultset('Tag')->search({ tag => { -in => $in_rs->get_column('tag')->as_query } });
-is($rs->count, 7, 'Count with IN subquery');
+  $rs = $schema->resultset('Tag')->search({ tag => { -in => $in_rs->get_column('tag')->as_query } });
+  is($get_count->($rs), 7, 'Count with IN subquery');
 
-$rs = $schema->resultset('Tag')->search({ tag => { -in => $in_rs->get_column('tag')->as_query } }, { group_by => 'tag' });
-is($rs->count, 2, 'Count with IN subquery with outside group_by');
+  $rs = $schema->resultset('Tag')->search({ tag => { -in => $in_rs->get_column('tag')->as_query } }, { group_by => 'tag' });
+  is($get_count->($rs), 2, 'Count with IN subquery with outside group_by');
 
-$rs = $schema->resultset('Tag')->search({ tag => { -in => $in_rs->get_column('tag')->as_query } }, { distinct => 1 });
-is($rs->count, 7, 'Count with IN subquery with outside distinct');
+  $rs = $schema->resultset('Tag')->search({ tag => { -in => $in_rs->get_column('tag')->as_query } }, { distinct => 1 });
+  is($get_count->($rs), 7, 'Count with IN subquery with outside distinct');
 
-$rs = $schema->resultset('Tag')->search({ tag => { -in => $in_rs->get_column('tag')->as_query } }, { distinct => 1, select => 'tag' }), 
-is($rs->count, 2, 'Count with IN subquery with outside distinct on a single column');
+  $rs = $schema->resultset('Tag')->search({ tag => { -in => $in_rs->get_column('tag')->as_query } }, { distinct => 1, select => 'tag' }), 
+  is($get_count->($rs), 2, 'Count with IN subquery with outside distinct on a single column');
 
-$rs = $schema->resultset('Tag')->search({ tag => { -in => $in_rs->search({}, { group_by => 'tag' })->get_column('tag')->as_query } });
-is($rs->count, 7, 'Count with IN subquery with single group_by');
+  $rs = $schema->resultset('Tag')->search({ tag => { -in => $in_rs->search({}, { group_by => 'tag' })->get_column('tag')->as_query } });
+  is($get_count->($rs), 7, 'Count with IN subquery with single group_by');
 
-$rs = $schema->resultset('Tag')->search({ tag => { -in => $in_rs->search({}, { group_by => 'cd' })->get_column('tag')->as_query } });
-is($rs->count, 7, 'Count with IN subquery with another single group_by');
+  $rs = $schema->resultset('Tag')->search({ tag => { -in => $in_rs->search({}, { group_by => 'cd' })->get_column('tag')->as_query } });
+  is($get_count->($rs), 7, 'Count with IN subquery with another single group_by');
 
-$rs = $schema->resultset('Tag')->search({ tag => { -in => $in_rs->search({}, { group_by => [ qw/tag cd/ ] })->get_column('tag')->as_query } });
-is($rs->count, 7, 'Count with IN subquery with multiple group_by');
+  $rs = $schema->resultset('Tag')->search({ tag => { -in => $in_rs->search({}, { group_by => [ qw/tag cd/ ] })->get_column('tag')->as_query } });
+  is($get_count->($rs), 7, 'Count with IN subquery with multiple group_by');
 
-$rs = $schema->resultset('Tag')->search({ tag => \"= 'Blue'" });
-is($rs->count, 4, 'Count without DISTINCT, using literal SQL');
+  $rs = $schema->resultset('Tag')->search({ tag => \"= 'Blue'" });
+  is($get_count->($rs), 4, 'Count without DISTINCT, using literal SQL');
 
-$rs = $schema->resultset('Tag')->search({ tag => \" IN ('Blue', 'Cheesy')" }, { group_by => 'tag' });
-is($rs->count, 2, 'Count with literal SQL and single group_by');
+  $rs = $schema->resultset('Tag')->search({ tag => \" IN ('Blue', 'Cheesy')" }, { group_by => 'tag' });
+  is($get_count->($rs), 2, 'Count with literal SQL and single group_by');
 
-$rs = $schema->resultset('Tag')->search({ tag => \" IN ('Blue', 'Cheesy')" }, { group_by => 'cd' });
-is($rs->count, 5, 'Count with literal SQL and another single group_by');
+  $rs = $schema->resultset('Tag')->search({ tag => \" IN ('Blue', 'Cheesy')" }, { group_by => 'cd' });
+  is($get_count->($rs), 5, 'Count with literal SQL and another single group_by');
 
-$rs = $schema->resultset('Tag')->search({ tag => \" IN ('Blue', 'Cheesy')" }, { group_by => [ qw/tag cd/ ] });
-is($rs->count, 7, 'Count with literal SQL and multiple group_by');
+  $rs = $schema->resultset('Tag')->search({ tag => \" IN ('Blue', 'Cheesy')" }, { group_by => [ qw/tag cd/ ] });
+  is($get_count->($rs), 7, 'Count with literal SQL and multiple group_by');
 
-$rs = $schema->resultset('Tag')->search({ tag => 'Blue' }, { '+select' => { max => 'tagid' }, distinct => 1 });
-is($rs->count, 4, 'Count with +select aggreggate');
+  $rs = $schema->resultset('Tag')->search({ tag => 'Blue' }, { '+select' => { max => 'tagid' }, distinct => 1 });
+  is($get_count->($rs), 4, 'Count with +select aggreggate');
 
-$rs = $schema->resultset('Tag')->search({}, { select => 'length(me.tag)', distinct => 1 });
-is($rs->count, 3, 'Count by distinct function result as select literal');
+  $rs = $schema->resultset('Tag')->search({}, { select => 'length(me.tag)', distinct => 1 });
+  is($get_count->($rs), 3, 'Count by distinct function result as select literal');
+}
 
 eval {
   my @warnings;
@@ -90,7 +93,7 @@
 
 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/,
+  qr/select => { distinct => \.\.\. } syntax is not supported for multiple columns/,
   'throw on unsupported syntax'
 );
 

Modified: DBIx-Class/0.08/branches/run_file_against_storage/t/inflate/hri.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/inflate/hri.t	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/inflate/hri.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -6,7 +6,6 @@
 use DBICTest;
 my $schema = DBICTest->init_schema();
 
-
 # Under some versions of SQLite if the $rs is left hanging around it will lock
 # So we create a scope here cos I'm lazy
 {
@@ -124,3 +123,15 @@
 });
 $rs_hashrefinf->result_class('DBIx::Class::ResultClass::HashRefInflator');
 is_deeply [$rs_hashrefinf->all], \@hashrefinf, 'Check query using extended columns syntax';
+
+# check nested prefetching of has_many relationships which return nothing
+my $artist = $schema->resultset ('Artist')->create ({ name => 'unsuccessful artist without CDs'});
+$artist->discard_changes;
+my $rs_artists = $schema->resultset ('Artist')->search ({ 'me.artistid' => $artist->id}, {
+    prefetch => { cds => 'tracks' }, result_class => 'DBIx::Class::ResultClass::HashRefInflator',
+});
+is_deeply(
+  [$rs_artists->all],
+  [{ $artist->get_columns, cds => [] }],
+  'nested has_many prefetch without entries'
+);

Modified: DBIx-Class/0.08/branches/run_file_against_storage/t/inflate/serialize.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/inflate/serialize.t	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/inflate/serialize.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -32,7 +32,7 @@
 
 plan (skip_all => "No suitable serializer found") unless $selected;
 
-plan (tests => 8);
+plan (tests => 11);
 DBICTest::Schema::Serialized->inflate_column( 'serialized',
     { inflate => $selected->{inflater},
       deflate => $selected->{deflater},
@@ -84,3 +84,17 @@
 ok($object->update( { serialized => $struct_array } ), 'arrayref deflation');
 ok($inflated = $object->serialized, 'arrayref inflation');
 is_deeply($inflated, $struct_array, 'inflated array matches original');
+
+
+#===== make sure make_column_dirty ineracts reasonably with inflation
+$object = $rs->first;
+$object->update ({serialized => { x => 'y'}});
+
+$object->serialized->{x} = 'z'; # change state without notifying $object
+ok (!$object->get_dirty_columns, 'no dirty columns yet');
+is_deeply ($object->serialized, { x => 'z' }, 'object data correct');
+
+$object->make_column_dirty('serialized');
+$object->update;
+
+is_deeply ($rs->first->serialized, { x => 'z' }, 'changes made it to the db' );

Modified: DBIx-Class/0.08/branches/run_file_against_storage/t/lib/DBICTest/Schema/ArtistUndirectedMap.pm
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/lib/DBICTest/Schema/ArtistUndirectedMap.pm	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/lib/DBICTest/Schema/ArtistUndirectedMap.pm	2009-06-27 12:24:52 UTC (rev 6806)
@@ -11,7 +11,7 @@
 __PACKAGE__->set_primary_key(qw/id1 id2/);
 
 __PACKAGE__->belongs_to( 'artist1', 'DBICTest::Schema::Artist', 'id1', { on_delete => 'RESTRICT', on_update => 'CASCADE'} );
-__PACKAGE__->belongs_to( 'artist2', 'DBICTest::Schema::Artist', 'id2', { on_delete => undef, on_update => 'CASCADE'} );
+__PACKAGE__->belongs_to( 'artist2', 'DBICTest::Schema::Artist', 'id2', { on_delete => undef, on_update => undef} );
 __PACKAGE__->has_many(
   'mapped_artists', 'DBICTest::Schema::Artist',
   [ {'foreign.artistid' => 'self.id1'}, {'foreign.artistid' => 'self.id2'} ],

Modified: DBIx-Class/0.08/branches/run_file_against_storage/t/lib/DBICTest/Schema/Genre.pm
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/lib/DBICTest/Schema/Genre.pm	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/lib/DBICTest/Schema/Genre.pm	2009-06-27 12:24:52 UTC (rev 6806)
@@ -20,4 +20,6 @@
 
 __PACKAGE__->has_many (cds => 'DBICTest::Schema::CD', 'genreid');
 
+__PACKAGE__->has_one (model_cd => 'DBICTest::Schema::CD', 'genreid');
+
 1;


Property changes on: DBIx-Class/0.08/branches/run_file_against_storage/t/lib/DBICTest/Schema/TwoKeys.pm
___________________________________________________________________
Name: svn:executable
   - *

Modified: DBIx-Class/0.08/branches/run_file_against_storage/t/lib/sqlite.sql
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/lib/sqlite.sql	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/lib/sqlite.sql	2009-06-27 12:24:52 UTC (rev 6806)
@@ -1,6 +1,6 @@
 -- 
 -- Created by SQL::Translator::Producer::SQLite
--- Created on Thu May 28 10:10:00 2009
+-- Created on Sat Jun 27 14:02:39 2009
 -- 
 
 
@@ -17,41 +17,6 @@
 );
 
 --
--- Table: artist_undirected_map
---
-CREATE TABLE artist_undirected_map (
-  id1 integer NOT NULL,
-  id2 integer NOT NULL,
-  PRIMARY KEY (id1, id2)
-);
-
-CREATE INDEX artist_undirected_map_idx_id1_ ON artist_undirected_map (id1);
-
-CREATE INDEX artist_undirected_map_idx_id2_ ON artist_undirected_map (id2);
-
---
--- Table: cd_artwork
---
-CREATE TABLE cd_artwork (
-  cd_id INTEGER PRIMARY KEY NOT NULL
-);
-
-CREATE INDEX cd_artwork_idx_cd_id_cd_artwor ON cd_artwork (cd_id);
-
---
--- Table: artwork_to_artist
---
-CREATE TABLE artwork_to_artist (
-  artwork_cd_id integer NOT NULL,
-  artist_id integer NOT NULL,
-  PRIMARY KEY (artwork_cd_id, artist_id)
-);
-
-CREATE INDEX artwork_to_artist_idx_artist_id_artwork_to_arti ON artwork_to_artist (artist_id);
-
-CREATE INDEX artwork_to_artist_idx_artwork_cd_id_artwork_to_ ON artwork_to_artist (artwork_cd_id);
-
---
 -- Table: bindtype_test
 --
 CREATE TABLE bindtype_test (
@@ -62,63 +27,6 @@
 );
 
 --
--- Table: bookmark
---
-CREATE TABLE bookmark (
-  id INTEGER PRIMARY KEY NOT NULL,
-  link integer NOT NULL
-);
-
-CREATE INDEX bookmark_idx_link_bookmark ON bookmark (link);
-
---
--- Table: books
---
-CREATE TABLE books (
-  id INTEGER PRIMARY KEY NOT NULL,
-  source varchar(100) NOT NULL,
-  owner integer NOT NULL,
-  title varchar(100) NOT NULL,
-  price integer
-);
-
-CREATE INDEX books_idx_owner_books ON books (owner);
-
---
--- Table: cd
---
-CREATE TABLE cd (
-  cdid INTEGER PRIMARY KEY NOT NULL,
-  artist integer NOT NULL,
-  title varchar(100) NOT NULL,
-  year varchar(100) NOT NULL,
-  genreid integer,
-  single_track integer
-);
-
-CREATE INDEX cd_idx_artist_cd ON cd (artist);
-
-CREATE INDEX cd_idx_genreid_cd ON cd (genreid);
-
-CREATE INDEX cd_idx_single_track_cd ON cd (single_track);
-
-CREATE UNIQUE INDEX cd_artist_title_cd ON cd (artist, title);
-
---
--- Table: cd_to_producer
---
-CREATE TABLE cd_to_producer (
-  cd integer NOT NULL,
-  producer integer NOT NULL,
-  attribute integer,
-  PRIMARY KEY (cd, producer)
-);
-
-CREATE INDEX cd_to_producer_idx_cd_cd_to_pr ON cd_to_producer (cd);
-
-CREATE INDEX cd_to_producer_idx_producer_cd ON cd_to_producer (producer);
-
---
 -- Table: collection
 --
 CREATE TABLE collection (
@@ -127,19 +35,6 @@
 );
 
 --
--- Table: collection_object
---
-CREATE TABLE collection_object (
-  collection integer NOT NULL,
-  object integer NOT NULL,
-  PRIMARY KEY (collection, object)
-);
-
-CREATE INDEX collection_object_idx_collection_collection_obj ON collection_object (collection);
-
-CREATE INDEX collection_object_idx_object_c ON collection_object (object);
-
---
 -- Table: employee
 --
 CREATE TABLE employee (
@@ -180,16 +75,6 @@
 );
 
 --
--- Table: forceforeign
---
-CREATE TABLE forceforeign (
-  artist INTEGER PRIMARY KEY NOT NULL,
-  cd integer NOT NULL
-);
-
-CREATE INDEX forceforeign_idx_artist_forcef ON forceforeign (artist);
-
---
 -- Table: fourkeys
 --
 CREATE TABLE fourkeys (
@@ -203,25 +88,6 @@
 );
 
 --
--- Table: fourkeys_to_twokeys
---
-CREATE TABLE fourkeys_to_twokeys (
-  f_foo integer NOT NULL,
-  f_bar integer NOT NULL,
-  f_hello integer NOT NULL,
-  f_goodbye integer NOT NULL,
-  t_artist integer NOT NULL,
-  t_cd integer NOT NULL,
-  autopilot character NOT NULL,
-  pilot_sequence integer,
-  PRIMARY KEY (f_foo, f_bar, f_hello, f_goodbye, t_artist, t_cd)
-);
-
-CREATE INDEX fourkeys_to_twokeys_idx_f_foo_f_bar_f_hello_f_goodbye_ ON fourkeys_to_twokeys (f_foo, f_bar, f_hello, f_goodbye);
-
-CREATE INDEX fourkeys_to_twokeys_idx_t_artist_t_cd_fourkeys_to ON fourkeys_to_twokeys (t_artist, t_cd);
-
---
 -- Table: genre
 --
 CREATE TABLE genre (
@@ -229,31 +95,9 @@
   name varchar(100) NOT NULL
 );
 
-CREATE UNIQUE INDEX genre_name_genre ON genre (name);
+CREATE UNIQUE INDEX genre_name ON genre (name);
 
 --
--- Table: images
---
-CREATE TABLE images (
-  id INTEGER PRIMARY KEY NOT NULL,
-  artwork_id integer NOT NULL,
-  name varchar(100) NOT NULL,
-  data blob
-);
-
-CREATE INDEX images_idx_artwork_id_images ON images (artwork_id);
-
---
--- Table: liner_notes
---
-CREATE TABLE liner_notes (
-  liner_id INTEGER PRIMARY KEY NOT NULL,
-  notes varchar(100) NOT NULL
-);
-
-CREATE INDEX liner_notes_idx_liner_id_liner ON liner_notes (liner_id);
-
---
 -- Table: link
 --
 CREATE TABLE link (
@@ -263,27 +107,6 @@
 );
 
 --
--- Table: lyric_versions
---
-CREATE TABLE lyric_versions (
-  id INTEGER PRIMARY KEY NOT NULL,
-  lyric_id integer NOT NULL,
-  text varchar(100) NOT NULL
-);
-
-CREATE INDEX lyric_versions_idx_lyric_id_ly ON lyric_versions (lyric_id);
-
---
--- Table: lyrics
---
-CREATE TABLE lyrics (
-  lyric_id INTEGER PRIMARY KEY NOT NULL,
-  track_id integer NOT NULL
-);
-
-CREATE INDEX lyrics_idx_track_id_lyrics ON lyrics (track_id);
-
---
 -- Table: noprimarykey
 --
 CREATE TABLE noprimarykey (
@@ -292,7 +115,7 @@
   baz integer NOT NULL
 );
 
-CREATE UNIQUE INDEX foo_bar_noprimarykey ON noprimarykey (foo, bar);
+CREATE UNIQUE INDEX foo_bar ON noprimarykey (foo, bar);
 
 --
 -- Table: onekey
@@ -319,7 +142,7 @@
   name varchar(100) NOT NULL
 );
 
-CREATE UNIQUE INDEX prod_name_producer ON producer (name);
+CREATE UNIQUE INDEX prod_name ON producer (name);
 
 --
 -- Table: self_ref
@@ -330,19 +153,6 @@
 );
 
 --
--- Table: self_ref_alias
---
-CREATE TABLE self_ref_alias (
-  self_ref integer NOT NULL,
-  alias integer NOT NULL,
-  PRIMARY KEY (self_ref, alias)
-);
-
-CREATE INDEX self_ref_alias_idx_alias_self_ ON self_ref_alias (alias);
-
-CREATE INDEX self_ref_alias_idx_self_ref_se ON self_ref_alias (self_ref);
-
---
 -- Table: sequence_test
 --
 CREATE TABLE sequence_test (
@@ -362,17 +172,101 @@
 );
 
 --
--- Table: tags
+-- Table: treelike
 --
-CREATE TABLE tags (
-  tagid INTEGER PRIMARY KEY NOT NULL,
-  cd integer NOT NULL,
-  tag varchar(100) NOT NULL
+CREATE TABLE treelike (
+  id INTEGER PRIMARY KEY NOT NULL,
+  parent integer,
+  name varchar(100) NOT NULL
 );
 
-CREATE INDEX tags_idx_cd_tags ON tags (cd);
+CREATE INDEX treelike_idx_parent ON treelike (parent);
 
 --
+-- Table: twokeytreelike
+--
+CREATE TABLE twokeytreelike (
+  id1 integer NOT NULL,
+  id2 integer NOT NULL,
+  parent1 integer NOT NULL,
+  parent2 integer NOT NULL,
+  name varchar(100) NOT NULL,
+  PRIMARY KEY (id1, id2)
+);
+
+CREATE INDEX twokeytreelike_idx_parent1_parent2 ON twokeytreelike (parent1, parent2);
+
+CREATE UNIQUE INDEX tktlnameunique ON twokeytreelike (name);
+
+--
+-- Table: typed_object
+--
+CREATE TABLE typed_object (
+  objectid INTEGER PRIMARY KEY NOT NULL,
+  type varchar(100) NOT NULL,
+  value varchar(100) NOT NULL
+);
+
+--
+-- Table: artist_undirected_map
+--
+CREATE TABLE artist_undirected_map (
+  id1 integer NOT NULL,
+  id2 integer NOT NULL,
+  PRIMARY KEY (id1, id2)
+);
+
+CREATE INDEX artist_undirected_map_idx_id1 ON artist_undirected_map (id1);
+
+CREATE INDEX artist_undirected_map_idx_id2 ON artist_undirected_map (id2);
+
+--
+-- Table: bookmark
+--
+CREATE TABLE bookmark (
+  id INTEGER PRIMARY KEY NOT NULL,
+  link integer NOT NULL
+);
+
+CREATE INDEX bookmark_idx_link ON bookmark (link);
+
+--
+-- Table: books
+--
+CREATE TABLE books (
+  id INTEGER PRIMARY KEY NOT NULL,
+  source varchar(100) NOT NULL,
+  owner integer NOT NULL,
+  title varchar(100) NOT NULL,
+  price integer
+);
+
+CREATE INDEX books_idx_owner ON books (owner);
+
+--
+-- Table: forceforeign
+--
+CREATE TABLE forceforeign (
+  artist INTEGER PRIMARY KEY NOT NULL,
+  cd integer NOT NULL
+);
+
+CREATE INDEX forceforeign_idx_artist ON forceforeign (artist);
+
+--
+-- Table: self_ref_alias
+--
+CREATE TABLE self_ref_alias (
+  self_ref integer NOT NULL,
+  alias integer NOT NULL,
+  PRIMARY KEY (self_ref, alias)
+);
+
+CREATE INDEX self_ref_alias_idx_alias ON self_ref_alias (alias);
+
+CREATE INDEX self_ref_alias_idx_self_ref ON self_ref_alias (self_ref);
+
+--
 -- Table: track
 --
 CREATE TABLE track (
@@ -384,40 +278,123 @@
   last_updated_at datetime
 );
 
-CREATE INDEX track_idx_cd_track ON track (cd);
+CREATE INDEX track_idx_cd ON track (cd);
 
-CREATE UNIQUE INDEX track_cd_position_track ON track (cd, position);
+CREATE UNIQUE INDEX track_cd_position ON track (cd, position);
 
-CREATE UNIQUE INDEX track_cd_title_track ON track (cd, title);
+CREATE UNIQUE INDEX track_cd_title ON track (cd, title);
 
 --
--- Table: treelike
+-- Table: cd
 --
-CREATE TABLE treelike (
+CREATE TABLE cd (
+  cdid INTEGER PRIMARY KEY NOT NULL,
+  artist integer NOT NULL,
+  title varchar(100) NOT NULL,
+  year varchar(100) NOT NULL,
+  genreid integer,
+  single_track integer
+);
+
+CREATE INDEX cd_idx_artist ON cd (artist);
+
+CREATE INDEX cd_idx_genreid ON cd (genreid);
+
+CREATE INDEX cd_idx_single_track ON cd (single_track);
+
+CREATE UNIQUE INDEX cd_artist_title ON cd (artist, title);
+
+--
+-- Table: collection_object
+--
+CREATE TABLE collection_object (
+  collection integer NOT NULL,
+  object integer NOT NULL,
+  PRIMARY KEY (collection, object)
+);
+
+CREATE INDEX collection_object_idx_collection ON collection_object (collection);
+
+CREATE INDEX collection_object_idx_object ON collection_object (object);
+
+--
+-- Table: lyrics
+--
+CREATE TABLE lyrics (
+  lyric_id INTEGER PRIMARY KEY NOT NULL,
+  track_id integer NOT NULL
+);
+
+CREATE INDEX lyrics_idx_track_id ON lyrics (track_id);
+
+--
+-- Table: cd_artwork
+--
+CREATE TABLE cd_artwork (
+  cd_id INTEGER PRIMARY KEY NOT NULL
+);
+
+CREATE INDEX cd_artwork_idx_cd_id ON cd_artwork (cd_id);
+
+--
+-- Table: liner_notes
+--
+CREATE TABLE liner_notes (
+  liner_id INTEGER PRIMARY KEY NOT NULL,
+  notes varchar(100) NOT NULL
+);
+
+CREATE INDEX liner_notes_idx_liner_id ON liner_notes (liner_id);
+
+--
+-- Table: lyric_versions
+--
+CREATE TABLE lyric_versions (
   id INTEGER PRIMARY KEY NOT NULL,
-  parent integer,
-  name varchar(100) NOT NULL
+  lyric_id integer NOT NULL,
+  text varchar(100) NOT NULL
 );
 
-CREATE INDEX treelike_idx_parent_treelike ON treelike (parent);
+CREATE INDEX lyric_versions_idx_lyric_id ON lyric_versions (lyric_id);
 
 --
--- Table: twokeytreelike
+-- Table: tags
 --
-CREATE TABLE twokeytreelike (
-  id1 integer NOT NULL,
-  id2 integer NOT NULL,
-  parent1 integer NOT NULL,
-  parent2 integer NOT NULL,
-  name varchar(100) NOT NULL,
-  PRIMARY KEY (id1, id2)
+CREATE TABLE tags (
+  tagid INTEGER PRIMARY KEY NOT NULL,
+  cd integer NOT NULL,
+  tag varchar(100) NOT NULL
 );
 
-CREATE INDEX twokeytreelike_idx_parent1_parent2_twokeytre ON twokeytreelike (parent1, parent2);
+CREATE INDEX tags_idx_cd ON tags (cd);
 
-CREATE UNIQUE INDEX tktlnameunique_twokeytreelike ON twokeytreelike (name);
+--
+-- Table: cd_to_producer
+--
+CREATE TABLE cd_to_producer (
+  cd integer NOT NULL,
+  producer integer NOT NULL,
+  attribute integer,
+  PRIMARY KEY (cd, producer)
+);
 
+CREATE INDEX cd_to_producer_idx_cd ON cd_to_producer (cd);
+
+CREATE INDEX cd_to_producer_idx_producer ON cd_to_producer (producer);
+
 --
+-- Table: images
+--
+CREATE TABLE images (
+  id INTEGER PRIMARY KEY NOT NULL,
+  artwork_id integer NOT NULL,
+  name varchar(100) NOT NULL,
+  data blob
+);
+
+CREATE INDEX images_idx_artwork_id ON images (artwork_id);
+
+--
 -- Table: twokeys
 --
 CREATE TABLE twokeys (
@@ -426,18 +403,41 @@
   PRIMARY KEY (artist, cd)
 );
 
-CREATE INDEX twokeys_idx_artist_twokeys ON twokeys (artist);
+CREATE INDEX twokeys_idx_artist ON twokeys (artist);
 
 --
--- Table: typed_object
+-- Table: artwork_to_artist
 --
-CREATE TABLE typed_object (
-  objectid INTEGER PRIMARY KEY NOT NULL,
-  type varchar(100) NOT NULL,
-  value varchar(100) NOT NULL
+CREATE TABLE artwork_to_artist (
+  artwork_cd_id integer NOT NULL,
+  artist_id integer NOT NULL,
+  PRIMARY KEY (artwork_cd_id, artist_id)
 );
 
+CREATE INDEX artwork_to_artist_idx_artist_id ON artwork_to_artist (artist_id);
+
+CREATE INDEX artwork_to_artist_idx_artwork_cd_id ON artwork_to_artist (artwork_cd_id);
+
 --
+-- Table: fourkeys_to_twokeys
+--
+CREATE TABLE fourkeys_to_twokeys (
+  f_foo integer NOT NULL,
+  f_bar integer NOT NULL,
+  f_hello integer NOT NULL,
+  f_goodbye integer NOT NULL,
+  t_artist integer NOT NULL,
+  t_cd integer NOT NULL,
+  autopilot character NOT NULL,
+  pilot_sequence integer,
+  PRIMARY KEY (f_foo, f_bar, f_hello, f_goodbye, t_artist, t_cd)
+);
+
+CREATE INDEX fourkeys_to_twokeys_idx_f_foo_f_bar_f_hello_f_goodbye ON fourkeys_to_twokeys (f_foo, f_bar, f_hello, f_goodbye);
+
+CREATE INDEX fourkeys_to_twokeys_idx_t_artist_t_cd ON fourkeys_to_twokeys (t_artist, t_cd);
+
+--
 -- View: year2000cds
 --
 CREATE VIEW year2000cds AS

Copied: DBIx-Class/0.08/branches/run_file_against_storage/t/multi_create/in_memory.t (from rev 6548, DBIx-Class/0.08/branches/run_file_against_storage/t/96multi_create_new.t)
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/multi_create/in_memory.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/multi_create/in_memory.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -0,0 +1,74 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Exception;
+use lib qw(t/lib);
+use DBICTest;
+
+plan tests => 12;
+
+my $schema = DBICTest->init_schema();
+
+# Test various new() invocations - this is all about backcompat, making 
+# sure that insert() still works as expected by legacy code.
+#
+# What we essentially do is multi-instantiate objects, making sure nothing
+# gets inserted. Then we add some more objects to the mix either via
+# new_related() or by setting an accessor directly (or both) - again
+# expecting no inserts. Then after calling insert() on the starter object
+# we expect everything supplied to new() to get inserted, as well as any
+# relations whose PK's are necessary to complete the objects supplied
+# to new(). All other objects should be insert()able afterwards too.
+
+
+{
+    my $new_artist = $schema->resultset("Artist")->new_result({ 'name' => 'Depeche Mode' });
+    my $new_related_cd = $new_artist->new_related('cds', { 'title' => 'Leave in Silence', 'year' => 1982});
+    eval {
+        $new_artist->insert;
+        $new_related_cd->insert;
+    };
+    is ($@, '', 'Staged insertion successful');
+    ok($new_artist->in_storage, 'artist inserted');
+    ok($new_related_cd->in_storage, 'new_related_cd inserted');
+}
+
+{
+    my $new_artist = $schema->resultset("Artist")->new_result({ 'name' => 'Depeche Mode' });
+    my $new_related_cd = $new_artist->new_related('cds', { 'title' => 'Leave Slightly Noisily', 'year' => 1982});
+    eval {
+        $new_related_cd->insert;
+    };
+    is ($@, '', 'CD insertion survives by finding artist');
+    ok($new_artist->in_storage, 'artist inserted');
+    ok($new_related_cd->in_storage, 'new_related_cd inserted');
+}
+
+{
+    my $new_artist = $schema->resultset("Artist")->new_result({ 'name' => 'Depeche Mode 2: Insertion Boogaloo' });
+    my $new_related_cd = $new_artist->new_related('cds', { 'title' => 'Leave Loudly While Singing Off Key', 'year' => 1982});
+    eval {
+        $new_related_cd->insert;
+    };
+    is ($@, '', 'CD insertion survives by inserting artist');
+    ok($new_artist->in_storage, 'artist inserted');
+    ok($new_related_cd->in_storage, 'new_related_cd inserted');
+}
+
+{
+    my $new_cd = $schema->resultset("CD")->new_result({});
+    my $new_related_artist = $new_cd->new_related('artist', { 'name' => 'Marillion',});
+    lives_ok (
+        sub {
+            $new_related_artist->insert;
+            $new_cd->title( 'Misplaced Childhood' );
+            $new_cd->year ( 1985 );
+            $new_cd->artist( $new_related_artist );  # For exact backward compatibility
+            $new_cd->insert;
+        },
+        'Reversed staged insertion successful'
+    );
+    ok($new_related_artist->in_storage, 'related artist inserted');
+    ok($new_cd->in_storage, 'cd inserted');
+}

Copied: DBIx-Class/0.08/branches/run_file_against_storage/t/multi_create/standard.t (from rev 6548, DBIx-Class/0.08/branches/run_file_against_storage/t/96multi_create.t)
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/multi_create/standard.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/multi_create/standard.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -0,0 +1,487 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Exception;
+use lib qw(t/lib);
+use DBICTest;
+
+plan tests => 93;
+
+my $schema = DBICTest->init_schema();
+
+lives_ok ( sub {
+  my $cd = $schema->resultset('CD')->create({
+    artist => { 
+      name => 'Fred Bloggs' 
+    },
+    title => 'Some CD',
+    year => 1996
+  });
+
+  isa_ok($cd, 'DBICTest::CD', 'Created CD object');
+  isa_ok($cd->artist, 'DBICTest::Artist', 'Created related Artist');
+  is($cd->artist->name, 'Fred Bloggs', 'Artist created correctly');
+}, 'simple create + parent (the stuff $rs belongs_to) ok');
+
+lives_ok ( sub {
+  my $bm_rs = $schema->resultset('Bookmark');
+  my $bookmark = $bm_rs->create({
+    link => {
+      id => 66,
+    },
+  });
+
+  isa_ok($bookmark, 'DBICTest::Bookmark', 'Created Bookrmark object');
+  isa_ok($bookmark->link, 'DBICTest::Link', 'Created related Link');
+  is (
+    $bm_rs->search (
+      { 'link.title' => $bookmark->link->title },
+      { join => 'link' },
+    )->count,
+    1,
+    'Bookmark and link made it to the DB',
+  );
+}, 'simple create where the child and parent have no values, except for an explicit parent pk ok');
+
+lives_ok ( sub {
+  my $artist = $schema->resultset('Artist')->first;
+  my $cd = $artist->create_related (cds => {
+    title => 'Music to code by',
+    year => 2007,
+    tags => [
+      { 'tag' => 'rock' },
+    ],
+  });
+
+  isa_ok($cd, 'DBICTest::CD', 'Created CD');
+  is($cd->title, 'Music to code by', 'CD created correctly');
+  is($cd->tags->count, 1, 'One tag created for CD');
+  is($cd->tags->first->tag, 'rock', 'Tag created correctly');
+
+}, 'create over > 1 levels of has_many create (A => { has_many => { B => has_many => C } } )');
+
+throws_ok (
+  sub {
+    # Create via update - add a new CD <--- THIS SHOULD HAVE NEVER WORKED!
+    $schema->resultset('Artist')->first->update({
+      cds => [
+        { title => 'Yet another CD',
+          year => 2006,
+        },
+      ],
+    });
+  },
+  qr/Recursive update is not supported over relationships of type multi/,
+  'create via update of multi relationships throws an exception'
+);
+
+lives_ok ( sub {
+  my $artist = $schema->resultset('Artist')->first;
+  my $c2p = $schema->resultset('CD_to_Producer')->create ({
+    cd => {
+      artist => $artist,
+      title => 'Bad investment',
+      year => 2008,
+      tracks => [
+        { title => 'Just buy' },
+        { title => 'Why did we do it' },
+        { title => 'Burn baby burn' },
+      ],
+    },
+    producer => {
+      name => 'Lehman Bros.',
+    },
+  });
+
+  isa_ok ($c2p, 'DBICTest::CD_to_Producer', 'Linker object created');
+  my $prod = $schema->resultset ('Producer')->find ({ name => 'Lehman Bros.' });
+  isa_ok ($prod, 'DBICTest::Producer', 'Producer row found');
+  is ($prod->cds->count, 1, 'Producer has one production');
+  my $cd = $prod->cds->first;
+  is ($cd->title, 'Bad investment', 'CD created correctly');
+  is ($cd->tracks->count, 3, 'CD has 3 tracks');
+}, 'Create m2m while originating in the linker table');
+
+
+#CD -> has_many -> Tracks -> might have -> Single -> has_many -> Tracks
+#                                               \
+#                                                \-> has_many \
+#                                                              --> CD2Producer
+#                                                /-> has_many /
+#                                               /
+#                                          Producer
+lives_ok ( sub {
+  my $artist = $schema->resultset('Artist')->first;
+  my $cd = $schema->resultset('CD')->create ({
+    artist => $artist,
+    title => 'Music to code by at night',
+    year => 2008,
+    tracks => [
+      {
+        title => 'Off by one again',
+      },
+      {
+        title => 'The dereferencer',
+        cd_single => {
+          artist => $artist,
+          year => 2008,
+          title => 'Was that a null (Single)',
+          tracks => [
+            { title => 'The dereferencer' },
+            { title => 'The dereferencer II' },
+          ],
+          cd_to_producer => [
+            {
+              producer => {
+                name => 'K&R',
+              }
+            },
+            {
+              producer => {
+                name => 'Don Knuth',
+              }
+            },
+          ]
+        },
+      },
+    ],
+  });
+
+  isa_ok ($cd, 'DBICTest::CD', 'Main CD object created');
+  is ($cd->title, 'Music to code by at night', 'Correct CD title');
+  is ($cd->tracks->count, 2, 'Two tracks on main CD');
+
+  my ($t1, $t2) = $cd->tracks->all;
+  is ($t1->title, 'Off by one again', 'Correct 1st track name');
+  is ($t1->cd_single, undef, 'No single for 1st track');
+  is ($t2->title, 'The dereferencer', 'Correct 2nd track name');
+  isa_ok ($t2->cd_single, 'DBICTest::CD', 'Created a single for 2nd track');
+
+  my $single = $t2->cd_single;
+  is ($single->tracks->count, 2, 'Two tracks on single CD');
+  is ($single->tracks->find ({ position => 1})->title, 'The dereferencer', 'Correct 1st track title');
+  is ($single->tracks->find ({ position => 2})->title, 'The dereferencer II', 'Correct 2nd track title');
+
+  is ($single->cd_to_producer->count, 2, 'Two producers created for the single cd');
+  is_deeply (
+    [ sort map { $_->producer->name } ($single->cd_to_producer->all) ],
+    ['Don Knuth', 'K&R'],
+    'Producers named correctly',
+  );
+}, 'Create over > 1 levels of might_have with multiple has_many and multiple m2m but starting at a has_many level');
+
+#Track -> might have -> Single -> has_many -> Tracks
+#                           \
+#                            \-> has_many \
+#                                          --> CD2Producer
+#                            /-> has_many /
+#                           /
+#                       Producer
+lives_ok ( sub {
+  my $cd = $schema->resultset('CD')->first;
+  my $track = $schema->resultset('Track')->create ({
+    cd => $cd,
+    title => 'Multicreate rocks',
+    cd_single => {
+      artist => $cd->artist,
+      year => 2008,
+      title => 'Disemboweling MultiCreate',
+      tracks => [
+        { title => 'Why does mst write this way' },
+        { title => 'Chainsaw celebration' },
+        { title => 'Purl cleans up' },
+      ],
+      cd_to_producer => [
+        {
+          producer => {
+            name => 'mst',
+          }
+        },
+        {
+          producer => {
+            name => 'castaway',
+          }
+        },
+        {
+          producer => {
+            name => 'theorbtwo',
+          }
+        },
+      ]
+    },
+  });
+
+  isa_ok ($track, 'DBICTest::Track', 'Main Track object created');
+  is ($track->title, 'Multicreate rocks', 'Correct Track title');
+
+  my $single = $track->cd_single;
+  isa_ok ($single, 'DBICTest::CD', 'Created a single with the track');
+  is ($single->tracks->count, 3, '3 tracks on single CD');
+  is ($single->tracks->find ({ position => 1})->title, 'Why does mst write this way', 'Correct 1st track title');
+  is ($single->tracks->find ({ position => 2})->title, 'Chainsaw celebration', 'Correct 2nd track title');
+  is ($single->tracks->find ({ position => 3})->title, 'Purl cleans up', 'Correct 3rd track title');
+
+  is ($single->cd_to_producer->count, 3, '3 producers created for the single cd');
+  is_deeply (
+    [ sort map { $_->producer->name } ($single->cd_to_producer->all) ],
+    ['castaway', 'mst', 'theorbtwo'],
+    'Producers named correctly',
+  );
+}, 'Create over > 1 levels of might_have with multiple has_many and multiple m2m but starting at the might_have directly');
+
+lives_ok ( sub {
+  my $artist = $schema->resultset('Artist')->first;
+  my $cd = $schema->resultset('CD')->create ({
+    artist => $artist,
+    title => 'Music to code by at twilight',
+    year => 2008,
+    artwork => {
+      images => [
+        { name => 'recursive descent' },
+        { name => 'tail packing' },
+      ],
+    },
+  });
+
+  isa_ok ($cd, 'DBICTest::CD', 'Main CD object created');
+  is ($cd->title, 'Music to code by at twilight', 'Correct CD title');
+  isa_ok ($cd->artwork, 'DBICTest::Artwork', 'Artwork created');
+
+  # this test might look weird, but it failed at one point, keep it there
+  my $art_obj = $cd->artwork;
+  ok ($art_obj->has_column_loaded ('cd_id'), 'PK/FK present on artwork object');
+  is ($art_obj->images->count, 2, 'Correct artwork image count via the new object');
+  is_deeply (
+    [ sort $art_obj->images->get_column ('name')->all ],
+    [ 'recursive descent', 'tail packing' ],
+    'Images named correctly in objects',
+  );
+
+  my $artwork = $schema->resultset('Artwork')->search (
+    { 'cd.title' => 'Music to code by at twilight' },
+    { join => 'cd' },
+  )->single;
+
+  is ($artwork->images->count, 2, 'Correct artwork image count via a new search');
+
+  is_deeply (
+    [ sort $artwork->images->get_column ('name')->all ],
+    [ 'recursive descent', 'tail packing' ],
+    'Images named correctly after search',
+  );
+}, 'Test might_have again but with a PK == FK in the middle (obviously not specified)');
+
+lives_ok ( sub {
+  my $cd = $schema->resultset('CD')->first;
+  my $track = $schema->resultset ('Track')->create ({
+    cd => $cd,
+    title => 'Black',
+    lyrics => {
+      lyric_versions => [
+        { text => 'The color black' },
+        { text => 'The colour black' },
+      ],
+    },
+  });
+
+  isa_ok ($track, 'DBICTest::Track', 'Main track object created');
+  is ($track->title, 'Black', 'Correct track title');
+  isa_ok ($track->lyrics, 'DBICTest::Lyrics', 'Lyrics created');
+
+  # this test might look weird, but it was failing at one point, keep it there
+  my $lyric_obj = $track->lyrics;
+  ok ($lyric_obj->has_column_loaded ('lyric_id'), 'PK present on lyric object');
+  ok ($lyric_obj->has_column_loaded ('track_id'), 'FK present on lyric object');
+  is ($lyric_obj->lyric_versions->count, 2, 'Correct lyric versions count via the new object');
+  is_deeply (
+    [ sort $lyric_obj->lyric_versions->get_column ('text')->all ],
+    [ 'The color black', 'The colour black' ],
+    'Lyrics text in objects matches',
+  );
+
+
+  my $lyric = $schema->resultset('Lyrics')->search (
+    { 'track.title' => 'Black' },
+    { join => 'track' },
+  )->single;
+
+  is ($lyric->lyric_versions->count, 2, 'Correct lyric versions count via a new search');
+
+  is_deeply (
+    [ sort $lyric->lyric_versions->get_column ('text')->all ],
+    [ 'The color black', 'The colour black' ],
+    'Lyrics text via search matches',
+  );
+}, 'Test might_have again but with just a PK and FK (neither specified) in the mid-table');
+
+lives_ok ( sub {
+  my $newartist2 = $schema->resultset('Artist')->find_or_create({ 
+    name => 'Fred 3',
+    cds => [
+      { 
+        title => 'Noah Act',
+        year => 2007,
+      },
+    ],
+  });
+  is($newartist2->name, 'Fred 3', 'Created new artist with cds via find_or_create');
+}, 'Nested find_or_create');
+
+lives_ok ( sub {
+  my $artist2 = $schema->resultset('Artist')->create({
+    name => 'Fred 4',
+    cds => [
+      {
+        title => 'Music to code by',
+        year => 2007,
+      },
+    ],
+    cds_unordered => [
+      {
+        title => 'Music to code by',
+        year => 2007,
+      },
+    ]
+  });
+
+  is($artist2->in_storage, 1, 'artist with duplicate rels inserted okay');
+}, 'Multiple same level has_many create');
+
+lives_ok ( sub {
+	my $artist = $schema->resultset('Artist')->first;
+	
+	my $cd_result = $artist->create_related('cds', {
+	
+		title => 'TestOneCD1',
+		year => 2007,
+		tracks => [
+			{ title => 'TrackOne' },
+			{ title => 'TrackTwo' },
+		],
+
+	});
+	
+	isa_ok( $cd_result, 'DBICTest::CD', "Got Good CD Class");
+	ok( $cd_result->title eq "TestOneCD1", "Got Expected Title");
+	
+	my $tracks = $cd_result->tracks;
+	
+	isa_ok( $tracks, 'DBIx::Class::ResultSet', 'Got Expected Tracks ResultSet');
+	
+	foreach my $track ($tracks->all)
+	{
+		isa_ok( $track, 'DBICTest::Track', 'Got Expected Track Class');
+	}
+}, 'First create_related pass');
+
+lives_ok ( sub {
+	my $artist = $schema->resultset('Artist')->first;
+	
+	my $cd_result = $artist->create_related('cds', {
+	
+		title => 'TestOneCD2',
+		year => 2007,
+		tracks => [
+			{ title => 'TrackOne' },
+			{ title => 'TrackTwo' },
+		],
+
+    liner_notes => { notes => 'I can haz liner notes?' },
+
+	});
+	
+	isa_ok( $cd_result, 'DBICTest::CD', "Got Good CD Class");
+	ok( $cd_result->title eq "TestOneCD2", "Got Expected Title");
+  ok( $cd_result->notes eq 'I can haz liner notes?', 'Liner notes');
+	
+	my $tracks = $cd_result->tracks;
+	
+	isa_ok( $tracks, 'DBIx::Class::ResultSet', "Got Expected Tracks ResultSet");
+	
+	foreach my $track ($tracks->all)
+	{
+		isa_ok( $track, 'DBICTest::Track', 'Got Expected Track Class');
+	}
+}, 'second create_related with same arguments');
+
+lives_ok ( sub {
+  my $cdp = $schema->resultset('CD_to_Producer')->create({
+    cd => { artist => 1, title => 'foo', year => 2000 },
+    producer => { name => 'jorge' }
+  });
+  ok($cdp, 'join table record created ok');
+}, 'create of parents of a record linker table');
+
+lives_ok ( sub {
+  my $kurt_cobain = { name => 'Kurt Cobain' };
+
+  my $in_utero = $schema->resultset('CD')->new({
+      title => 'In Utero',
+      year  => 1993
+    });
+
+  $kurt_cobain->{cds} = [ $in_utero ];
+
+
+  $schema->resultset('Artist')->populate([ $kurt_cobain ]); # %)
+  $a = $schema->resultset('Artist')->find({name => 'Kurt Cobain'});
+
+  is($a->name, 'Kurt Cobain', 'Artist insertion ok');
+  is($a->cds && $a->cds->first && $a->cds->first->title, 
+		  'In Utero', 'CD insertion ok');
+}, 'populate');
+
+## Create foreign key col obj including PK
+## See test 20 in 66relationships.t
+lives_ok ( sub {
+  my $new_cd_hashref = { 
+    cdid => 27, 
+    title => 'Boogie Woogie', 
+    year => '2007', 
+    artist => { artistid => 17, name => 'king luke' }
+  };
+
+  my $cd = $schema->resultset("CD")->find(1);
+
+  is($cd->artist->id, 1, 'rel okay');
+
+  my $new_cd = $schema->resultset("CD")->create($new_cd_hashref);
+  is($new_cd->artist->id, 17, 'new id retained okay');
+}, 'Create foreign key col obj including PK');
+
+lives_ok ( sub {
+	$schema->resultset("CD")->create({ 
+              cdid => 28, 
+              title => 'Boogie Wiggle', 
+              year => '2007', 
+              artist => { artistid => 18, name => 'larry' }
+             });
+}, 'new cd created without clash on related artist');
+
+throws_ok ( sub {
+    my $t = $schema->resultset("Track")->new({ cd => { artist => undef } });
+    #$t->cd($t->new_related('cd', { artist => undef } ) );
+    #$t->{_rel_in_storage} = 0;
+    $t->insert;
+}, qr/cd.artist may not be NULL/, "Exception propogated properly");
+
+lives_ok ( sub {
+  $schema->resultset('CD')->create ({
+    artist => {
+      name => 'larry', # should already exist
+    },
+    title => 'Warble Marble',
+    year => '2009',
+    cd_to_producer => [
+      { producer => { name => 'Cowboy Neal' } },
+    ],
+  });
+
+  my $m2m_cd = $schema->resultset('CD')->search ({ title => 'Warble Marble'});
+  is ($m2m_cd->count, 1, 'One CD row created via M2M create');
+  is ($m2m_cd->first->producers->count, 1, 'CD row created with one producer');
+  is ($m2m_cd->first->producers->first->name, 'Cowboy Neal', 'Correct producer row created');
+}, 'Test multi create over many_to_many');
+
+1;

Copied: DBIx-Class/0.08/branches/run_file_against_storage/t/multi_create/torture.t (from rev 6548, DBIx-Class/0.08/branches/run_file_against_storage/t/96multi_create_torture.t)
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/multi_create/torture.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/multi_create/torture.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -0,0 +1,228 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Exception;
+use lib qw(t/lib);
+use DBICTest;
+
+plan tests => 23;
+
+# an insane multicreate 
+# (should work, despite the fact that no one will probably use it this way)
+
+my $schema = DBICTest->init_schema();
+
+# first count how many rows do we initially have
+my $counts;
+$counts->{$_} = $schema->resultset($_)->count for qw/Artist CD Genre Producer Tag/;
+
+# do the crazy create
+eval {
+  $schema->resultset('CD')->create ({
+    artist => {
+      name => 'james',
+    },
+    title => 'Greatest hits 1',
+    year => '2012',
+    genre => {
+      name => '"Greatest" collections',
+    },
+    tags => [
+      { tag => 'A' },
+      { tag => 'B' },
+    ],
+    cd_to_producer => [
+      {
+        producer => {
+          name => 'bob',
+          producer_to_cd => [
+            {
+              cd => { 
+                artist => {
+                  name => 'lars',
+                  cds => [
+                    {
+                      title => 'Greatest hits 2',
+                      year => 2012,
+                      genre => {
+                        name => '"Greatest" collections',
+                      },
+                      tags => [
+                        { tag => 'A' },
+                        { tag => 'B' },
+                      ],
+                      # This cd is created via artist so it doesn't know about producers
+                      cd_to_producer => [
+                        { producer => { name => 'bob' } },
+                        { producer => { name => 'paul' } },
+                        { producer => {
+                          name => 'flemming',
+                          producer_to_cd => [
+                            { cd => {
+                              artist => {
+                                name => 'kirk',
+                                cds => [
+                                  {
+                                    title => 'Greatest hits 3',
+                                    year => 2012,
+                                    genre => {
+                                      name => '"Greatest" collections',
+                                    },
+                                    tags => [
+                                      { tag => 'A' },
+                                      { tag => 'B' },
+                                    ],
+                                  },
+                                  {
+                                    title => 'Greatest hits 4',
+                                    year => 2012,
+                                    genre => {
+                                      name => '"Greatest" collections2',
+                                    },
+                                    tags => [
+                                      { tag => 'A' },
+                                      { tag => 'B' },
+                                    ],
+                                  },
+                                ],
+                              },
+                              title => 'Greatest hits 5',
+                              year => 2013,
+                              genre => {
+                                name => '"Greatest" collections2',
+                              },
+                            }},
+                          ],
+                        }},
+                      ],
+                    },
+                  ],
+                },
+                title => 'Greatest hits 6',
+                year => 2012,
+                genre => {
+                  name => '"Greatest" collections',
+                },
+                tags => [
+                  { tag => 'A' },
+                  { tag => 'B' },
+                ],
+              },
+            },
+            {
+              cd => { 
+                artist => {
+                  name => 'lars',    # should already exist
+                  # even though the artist 'name' is not uniquely constrained
+                  # find_or_create will arguably DWIM 
+                },
+                title => 'Greatest hits 7',
+                year => 2013,
+              },
+            },
+          ],
+        },
+      },
+    ],
+  });
+
+  is ($schema->resultset ('Artist')->count, $counts->{Artist} + 3, '3 new artists created');
+  is ($schema->resultset ('Genre')->count, $counts->{Genre} + 2, '2 additional genres created');
+  is ($schema->resultset ('Producer')->count, $counts->{Producer} + 3, '3 new producer');
+  is ($schema->resultset ('CD')->count, $counts->{CD} + 7, '7 new CDs');
+  is ($schema->resultset ('Tag')->count, $counts->{Tag} + 10, '10 new Tags');
+
+  my $cd_rs = $schema->resultset ('CD')
+    ->search ({ title => { -like => 'Greatest hits %' }}, { order_by => 'title'} );
+  is ($cd_rs->count, 7, '7 greatest hits created');
+
+  my $cds_2012 = $cd_rs->search ({ year => 2012});
+  is ($cds_2012->count, 5, '5 CDs created in 2012');
+
+  is (
+    $cds_2012->search(
+      { 'tags.tag' => { -in => [qw/A B/] } },
+      {
+        join => 'tags',
+        group_by => 'me.cdid',
+        having => 'count(me.cdid) = 2',
+      }
+    ),
+    5,
+    'All 10 tags were pairwise distributed between 5 year-2012 CDs'
+  );
+
+  my $paul_prod = $cd_rs->search (
+    { 'producer.name' => 'paul'},
+    { join => { cd_to_producer => 'producer' } }
+  );
+  is ($paul_prod->count, 1, 'Paul had 1 production');
+  my $pauls_cd = $paul_prod->single;
+  is ($pauls_cd->cd_to_producer->count, 3, 'Paul had two co-producers');
+  is (
+    $pauls_cd->search_related ('cd_to_producer',
+      { 'producer.name' => 'flemming'},
+      { join => 'producer' }
+    )->count,
+    1,
+    'The second producer is flemming',
+  );
+
+  my $kirk_cds = $cd_rs->search ({ 'artist.name' => 'kirk' }, { join => 'artist' });
+  is ($kirk_cds, 3, 'Kirk had 3 CDs');
+  is (
+    $kirk_cds->search (
+      { 'cd_to_producer.cd' => { '!=', undef } },
+      { join => 'cd_to_producer' },
+    ),
+    1,
+    'Kirk had a producer only on one cd',
+  );
+
+  my $lars_cds = $cd_rs->search ({ 'artist.name' => 'lars' }, { join => 'artist' });
+  is ($lars_cds->count, 3, 'Lars had 3 CDs');
+  is (
+    $lars_cds->search (
+      { 'cd_to_producer.cd' => undef },
+      { join => 'cd_to_producer' },
+    ),
+    0,
+    'Lars always had a producer',
+  );
+  is (
+    $lars_cds->search_related ('cd_to_producer',
+      { 'producer.name' => 'flemming'},
+      { join => 'producer' }
+    )->count,
+    1,
+    'Lars produced 1 CD with flemming',
+  );
+  is (
+    $lars_cds->search_related ('cd_to_producer',
+      { 'producer.name' => 'bob'},
+      { join => 'producer' }
+    )->count,
+    3,
+    'Lars produced 3 CDs with bob',
+  );
+
+  my $bob_prod = $cd_rs->search (
+    { 'producer.name' => 'bob'},
+    { join => { cd_to_producer => 'producer' } }
+  );
+  is ($bob_prod->count, 4, 'Bob produced a total of 4 CDs');
+  ok ($bob_prod->find ({ title => 'Greatest hits 1'}), '1st Bob production name correct');
+  ok ($bob_prod->find ({ title => 'Greatest hits 6'}), '2nd Bob production name correct');
+  ok ($bob_prod->find ({ title => 'Greatest hits 2'}), '3rd Bob production name correct');
+  ok ($bob_prod->find ({ title => 'Greatest hits 7'}), '4th Bob production name correct');
+
+  is (
+    $bob_prod->search ({ 'artist.name' => 'james' }, { join => 'artist' })->count,
+    1,
+    "Bob produced james' only CD",
+  );
+};
+diag $@ if $@;
+
+1;

Modified: DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/attrs_untouched.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/attrs_untouched.t	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/attrs_untouched.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -8,17 +8,8 @@
 
 my $schema = DBICTest->init_schema();
 
-my $orig_debug = $schema->storage->debug;
+plan tests => 3;
 
-use IO::File;
-
-BEGIN {
-    eval "use DBD::SQLite";
-    plan $@
-        ? ( skip_all => 'needs DBD::SQLite for testing' )
-        : ( tests => 3 );
-}
-
 # bug in 0.07000 caused attr (join/prefetch) to be modifed by search
 # so we check the search & attr arrays are not modified
 my $search = { 'artist.name' => 'Caterwauler McCrae' };

Added: DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/double_prefetch.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/double_prefetch.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/double_prefetch.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -0,0 +1,35 @@
+use warnings;  
+
+use Test::More;
+use Test::Exception;
+use lib qw(t/lib);
+use DBIC::SqlMakerTest;
+use DBICTest;
+
+my $schema = DBICTest->init_schema();
+
+plan tests => 1;
+
+# While this is a rather GIGO case, make sure it behaves as pre-103,
+# as it may result in hard-to-track bugs
+my $cds = $schema->resultset('Artist')
+            ->search_related ('cds')
+              ->search ({}, {
+                  prefetch => [ 'single_track', { single_track => 'cd' } ],
+                });
+
+is_same_sql(
+  ${$cds->as_query}->[0],
+  '(
+    SELECT
+      cds.cdid, cds.artist, cds.title, cds.year, cds.genreid, cds.single_track,
+      single_track.trackid, single_track.cd, single_track.position, single_track.title, single_track.last_updated_on, single_track.last_updated_at,
+      single_track_2.trackid, single_track_2.cd, single_track_2.position, single_track_2.title, single_track_2.last_updated_on, single_track_2.last_updated_at,
+      cd.cdid, cd.artist, cd.title, cd.year, cd.genreid, cd.single_track
+    FROM artist me
+      LEFT JOIN cd cds ON cds.artist = me.artistid
+      LEFT JOIN track single_track ON single_track.trackid = cds.single_track
+      LEFT JOIN track single_track_2 ON single_track_2.trackid = cds.single_track
+      LEFT JOIN cd cd ON cd.cdid = single_track_2.cd
+  )',
+);

Deleted: DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/rows_bug.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/rows_bug.t	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/rows_bug.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -1,68 +0,0 @@
-# Test to ensure we get a consistent result set wether or not we use the
-# prefetch option in combination rows (LIMIT).
-use strict;
-use warnings;
-
-use Test::More;
-use lib qw(t/lib);
-use DBICTest;
-
-plan skip_all => 'fix pending';
-#plan tests => 4;
-
-my $schema = DBICTest->init_schema();
-my $no_prefetch = $schema->resultset('Artist')->search(
-  undef,
-  { rows => 3 }
-);
-
-my $use_prefetch = $schema->resultset('Artist')->search(
-  undef,
-  {
-    prefetch => 'cds',
-    rows     => 3
-  }
-);
-
-is($no_prefetch->count, $use_prefetch->count, '$no_prefetch->count == $use_prefetch->count');
-is(
-  scalar ($no_prefetch->all),
-  scalar ($use_prefetch->all),
-  "Amount of returned rows is right"
-);
-
-
-
-my $artist_many_cds = $schema->resultset('Artist')->search ( {}, {
-  join => 'cds',
-  group_by => 'me.artistid',
-  having => \ 'count(cds.cdid) > 1',
-})->first;
-
-
-$no_prefetch = $schema->resultset('Artist')->search(
-  { artistid => $artist_many_cds->id },
-  { rows => 1 }
-);
-
-$use_prefetch = $schema->resultset('Artist')->search(
-  { artistid => $artist_many_cds->id },
-  {
-    prefetch => 'cds',
-    rows     => 1
-  }
-);
-
-my $prefetch_artist = $use_prefetch->first;
-my $normal_artist = $no_prefetch->first;
-
-is(
-  $prefetch_artist->cds->count,
-  $normal_artist->cds->count,
-  "Count of child rel with prefetch + rows => 1 is right"
-);
-is (
-  scalar ($prefetch_artist->cds->all),
-  scalar ($normal_artist->cds->all),
-  "Amount of child rel rows with prefetch + rows => 1 is right"
-);

Copied: DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/with_limit.t (from rev 6583, DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/rows_bug.t)
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/with_limit.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/prefetch/with_limit.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -0,0 +1,92 @@
+# Test to ensure we get a consistent result set wether or not we use the
+# prefetch option in combination rows (LIMIT).
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Exception;
+use lib qw(t/lib);
+use DBICTest;
+
+plan tests => 9;
+
+my $schema = DBICTest->init_schema();
+
+
+my $no_prefetch = $schema->resultset('Artist')->search(
+  [   # search deliberately contrived
+    { 'artwork.cd_id' => undef },
+    { 'tracks.title' => { '!=' => 'blah-blah-1234568' }}
+  ],
+  { rows => 3, join => { cds => [qw/artwork tracks/] },
+ }
+);
+
+my $use_prefetch = $no_prefetch->search(
+  {},
+  {
+    prefetch => 'cds',
+    order_by => { -desc => 'name' },
+  }
+);
+
+is($no_prefetch->count, $use_prefetch->count, '$no_prefetch->count == $use_prefetch->count');
+is(
+  scalar ($no_prefetch->all),
+  scalar ($use_prefetch->all),
+  "Amount of returned rows is right"
+);
+
+my $artist_many_cds = $schema->resultset('Artist')->search ( {}, {
+  join => 'cds',
+  group_by => 'me.artistid',
+  having => \ 'count(cds.cdid) > 1',
+})->first;
+
+
+$no_prefetch = $schema->resultset('Artist')->search(
+  { artistid => $artist_many_cds->id },
+  { rows => 1 }
+);
+
+$use_prefetch = $no_prefetch->search ({}, { prefetch => 'cds' });
+
+my $normal_artist = $no_prefetch->single;
+my $prefetch_artist = $use_prefetch->find({ name => $artist_many_cds->name });
+my $prefetch2_artist = $use_prefetch->first;
+
+is(
+  $prefetch_artist->cds->count,
+  $normal_artist->cds->count,
+  "Count of child rel with prefetch + rows => 1 is right (find)"
+);
+is(
+  $prefetch2_artist->cds->count,
+  $normal_artist->cds->count,
+  "Count of child rel with prefetch + rows => 1 is right (first)"
+);
+
+is (
+  scalar ($prefetch_artist->cds->all),
+  scalar ($normal_artist->cds->all),
+  "Amount of child rel rows with prefetch + rows => 1 is right (find)"
+);
+is (
+  scalar ($prefetch2_artist->cds->all),
+  scalar ($normal_artist->cds->all),
+  "Amount of child rel rows with prefetch + rows => 1 is right (first)"
+);
+
+throws_ok (
+  sub { $use_prefetch->single },
+  qr/resultsets prefetching has_many/,
+  'single() with multiprefetch is illegal',
+);
+
+my $artist = $use_prefetch->search({'cds.title' => $artist_many_cds->cds->first->title })->next;
+is($artist->cds->count, 1, "count on search limiting prefetched has_many");
+
+# try with double limit
+my $artist2 = $use_prefetch->search({'cds.title' => { '!=' => $artist_many_cds->cds->first->title } })->slice (0,0)->next;
+is($artist2->cds->count, 2, "count on search limiting prefetched has_many");
+

Modified: DBIx-Class/0.08/branches/run_file_against_storage/t/relationship/core.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/relationship/core.t	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/relationship/core.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -40,8 +40,8 @@
       year => 2005,
   } );
 
- SKIP:{
-    skip "Can't fix right now", 1 if $DBIx::Class::VERSION < 0.09;
+ TODO: {
+    local $TODO = "Can't fix right now" if $DBIx::Class::VERSION < 0.09;
     lives_ok { $big_flop->genre} "Don't throw exception when col is not loaded after insert";
   };
 }

Added: DBIx-Class/0.08/branches/run_file_against_storage/t/relationship/update_or_create_multi.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/relationship/update_or_create_multi.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/relationship/update_or_create_multi.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -0,0 +1,88 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Exception;
+use lib qw(t/lib);
+use DBICTest;
+use DBIC::SqlMakerTest;
+
+my $schema = DBICTest->init_schema();
+
+#plan tests => 4;
+plan 'no_plan';
+
+my $artist = $schema->resultset ('Artist')->first;
+
+my $genre = $schema->resultset ('Genre')
+            ->create ({ name => 'par excellence' });
+
+is ($genre->search_related( 'cds' )->count, 0, 'No cds yet');
+
+# expect a create
+$genre->update_or_create_related ('cds', {
+  artist => $artist,
+  year => 2009,
+  title => 'the best thing since sliced bread',
+});
+
+# verify cd was inserted ok
+is ($genre->search_related( 'cds' )->count, 1, 'One cd');
+my $cd = $genre->find_related ('cds', {});
+is_deeply (
+  { map { $_, $cd->get_column ($_) } qw/artist year title/ },
+  {
+    artist => $artist->id,
+    year => 2009,
+    title => 'the best thing since sliced bread',
+  },
+  'CD created correctly',
+);
+
+# expect a year update on the only related row
+# (non-qunique column + unique column as disambiguator)
+$genre->update_or_create_related ('cds', {
+  year => 2010,
+  title => 'the best thing since sliced bread',
+});
+
+# re-fetch the cd, verify update
+is ($genre->search_related( 'cds' )->count, 1, 'Still one cd');
+$cd = $genre->find_related ('cds', {});
+is_deeply (
+  { map { $_, $cd->get_column ($_) } qw/artist year title/ },
+  {
+    artist => $artist->id,
+    year => 2010,
+    title => 'the best thing since sliced bread',
+  },
+  'CD year column updated correctly',
+);
+
+
+# expect a create, after a failed search using *only* the
+# *current* relationship and the unique column constraints
+# (so no year)
+my @sql;
+$schema->storage->debugcb(sub { push @sql, $_[1] });
+$schema->storage->debug (1);
+
+$genre->update_or_create_related ('cds', {
+  title => 'the best thing since vertical toasters',
+  artist => $artist,
+  year => 2012,
+});
+
+$schema->storage->debugcb(undef);
+
+is_same_sql (
+  $sql[0],
+  'SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track
+    FROM cd me 
+    WHERE ( me.artist = ? AND me.title = ? AND me.genreid = ? )
+  ',
+  'expected select issued',
+);
+
+# a has_many search without a unique constraint makes no sense
+# but I am not sure what to test for - leaving open

Added: DBIx-Class/0.08/branches/run_file_against_storage/t/relationship/update_or_create_single.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/relationship/update_or_create_single.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/relationship/update_or_create_single.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -0,0 +1,100 @@
+use strict;
+use warnings;
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+my $schema = DBICTest->init_schema();
+
+#plan tests => 4;
+plan 'no_plan';
+
+my $artist = $schema->resultset ('Artist')->first;
+
+my $genre = $schema->resultset ('Genre')
+            ->create ({ name => 'par excellence' });
+
+is ($genre->search_related( 'model_cd' )->count, 0, 'No cds yet');
+
+# expect a create
+$genre->update_or_create_related ('model_cd', {
+  artist => $artist,
+  year => 2009,
+  title => 'the best thing since sliced bread',
+});
+
+# verify cd was inserted ok
+is ($genre->search_related( 'model_cd' )->count, 1, 'One cd');
+my $cd = $genre->find_related ('model_cd', {});
+is_deeply (
+  { map { $_, $cd->get_column ($_) } qw/artist year title/ },
+  {
+    artist => $artist->id,
+    year => 2009,
+    title => 'the best thing since sliced bread',
+  },
+  'CD created correctly',
+);
+
+# expect a year update on the only related row
+# (non-qunique column + unique column as disambiguator)
+$genre->update_or_create_related ('model_cd', {
+  year => 2010,
+  title => 'the best thing since sliced bread',
+});
+
+# re-fetch the cd, verify update
+is ($genre->search_related( 'model_cd' )->count, 1, 'Still one cd');
+$cd = $genre->find_related ('model_cd', {});
+is_deeply (
+  { map { $_, $cd->get_column ($_) } qw/artist year title/ },
+  {
+    artist => $artist->id,
+    year => 2010,
+    title => 'the best thing since sliced bread',
+  },
+  'CD year column updated correctly',
+);
+
+
+# expect an update of the only related row
+# (update a unique column)
+$genre->update_or_create_related ('model_cd', {
+  title => 'the best thing since vertical toasters',
+});
+
+# re-fetch the cd, verify update
+is ($genre->search_related( 'model_cd' )->count, 1, 'Still one cd');
+$cd = $genre->find_related ('model_cd', {});
+is_deeply (
+  { map { $_, $cd->get_column ($_) } qw/artist year title/ },
+  {
+    artist => $artist->id,
+    year => 2010,
+    title => 'the best thing since vertical toasters',
+  },
+  'CD title column updated correctly',
+);
+
+
+# expect a year update on the only related row
+# (non-qunique column only)
+$genre->update_or_create_related ('model_cd', {
+  year => 2011,
+});
+
+# re-fetch the cd, verify update
+is ($genre->search_related( 'model_cd' )->count, 1, 'Still one cd');
+$cd = $genre->find_related ('model_cd', {});
+is_deeply (
+  { map { $_, $cd->get_column ($_) } qw/artist year title/ },
+  {
+    artist => $artist->id,
+    year => 2011,
+    title => 'the best thing since vertical toasters',
+  },
+  'CD year column updated correctly without a disambiguator',
+);
+
+

Modified: DBIx-Class/0.08/branches/run_file_against_storage/t/zzzzzzz_perl_perf_bug.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/zzzzzzz_perl_perf_bug.t	2009-06-27 12:08:35 UTC (rev 6805)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/zzzzzzz_perl_perf_bug.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -68,7 +68,7 @@
     "in the Troubleshooting POD documentation entitled\n",
     "'Perl Performance Issues on Red Hat Systems'\n",
     "As this is an extremely serious condition, the only way to skip\n",
-    "over this test is to --force the installation, or to edit the test\n",
+    "over this test is to --force the installation, or to look in the test\n",
     "file " . __FILE__ . "\n",
   );
 
@@ -115,7 +115,7 @@
         "Please read the section in the Troubleshooting POD documentation\n",
         "entitled 'Perl Performance Issues on Red Hat Systems'\n",
         "As this is an extremely serious condition, the only way to skip\n",
-        "over this test is to --force the installation, or to edit the test\n",
+        "over this test is to --force the installation, or to look in the test\n",
         "file " . __FILE__ . "\n",
       );
 }

Added: DBIx-Class/0.08/branches/run_file_against_storage/t/zzzzzzz_sqlite_deadlock.t
===================================================================
--- DBIx-Class/0.08/branches/run_file_against_storage/t/zzzzzzz_sqlite_deadlock.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/run_file_against_storage/t/zzzzzzz_sqlite_deadlock.t	2009-06-27 12:24:52 UTC (rev 6806)
@@ -0,0 +1,35 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Exception;
+use lib 't/lib';
+
+use File::Temp ();
+use DBICTest;
+use DBICTest::Schema;
+
+plan tests => 2;
+my $wait_for = 10;  # how many seconds to wait
+
+for my $close (0,1) {
+
+  my $tmp = File::Temp->new( UNLINK => 1, TMPDIR => 1, SUFFIX => '.sqlite' );
+  my $tmp_fn = $tmp->filename;
+  close $tmp if $close;
+
+  local $SIG{ALRM} = sub { die sprintf (
+    "Timeout of %d seconds reached (tempfile still open: %s)",
+    $wait_for, $close ? 'No' : 'Yes'
+  )};
+
+  alarm $wait_for;
+
+  lives_ok (sub {
+    my $schema = DBICTest::Schema->connect ("DBI:SQLite:$tmp_fn");
+    DBICTest->deploy_schema ($schema);
+    DBICTest->populate_schema ($schema);
+  });
+
+  alarm 0;
+}




More information about the Bast-commits mailing list