[Bast-commits] r6850 - in DBIx-Class/0.08/branches/mssql_top_fixes: . lib/DBIx/Class lib/DBIx/Class/InflateColumn lib/DBIx/Class/Manual lib/DBIx/Class/Relationship lib/SQL/Translator/Parser/DBIx t t/inflate t/lib t/lib/DBICTest/Schema t/multi_create t/relationship

ribasushi at dev.catalyst.perl.org ribasushi at dev.catalyst.perl.org
Mon Jun 29 20:21:24 GMT 2009


Author: ribasushi
Date: 2009-06-29 20:21:24 +0000 (Mon, 29 Jun 2009)
New Revision: 6850

Added:
   DBIx-Class/0.08/branches/mssql_top_fixes/t/multi_create/in_memory.t
   DBIx-Class/0.08/branches/mssql_top_fixes/t/multi_create/standard.t
   DBIx-Class/0.08/branches/mssql_top_fixes/t/multi_create/torture.t
   DBIx-Class/0.08/branches/mssql_top_fixes/t/relationship/update_or_create_multi.t
   DBIx-Class/0.08/branches/mssql_top_fixes/t/relationship/update_or_create_single.t
   DBIx-Class/0.08/branches/mssql_top_fixes/t/zzzzzzz_sqlite_deadlock.t
Removed:
   DBIx-Class/0.08/branches/mssql_top_fixes/t/96multi_create.t
   DBIx-Class/0.08/branches/mssql_top_fixes/t/96multi_create_new.t
   DBIx-Class/0.08/branches/mssql_top_fixes/t/96multi_create_torture.t
Modified:
   DBIx-Class/0.08/branches/mssql_top_fixes/
   DBIx-Class/0.08/branches/mssql_top_fixes/Changes
   DBIx-Class/0.08/branches/mssql_top_fixes/Makefile.PL
   DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/InflateColumn/DateTime.pm
   DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Manual/Cookbook.pod
   DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Ordered.pm
   DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Relationship/Base.pm
   DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Relationship/ManyToMany.pm
   DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/ResultSet.pm
   DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/ResultSource.pm
   DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Row.pm
   DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Schema.pm
   DBIx-Class/0.08/branches/mssql_top_fixes/lib/SQL/Translator/Parser/DBIx/Class.pm
   DBIx-Class/0.08/branches/mssql_top_fixes/t/46where_attribute.t
   DBIx-Class/0.08/branches/mssql_top_fixes/t/85utf8.t
   DBIx-Class/0.08/branches/mssql_top_fixes/t/86sqlt.t
   DBIx-Class/0.08/branches/mssql_top_fixes/t/inflate/serialize.t
   DBIx-Class/0.08/branches/mssql_top_fixes/t/lib/DBICTest/Schema/ArtistUndirectedMap.pm
   DBIx-Class/0.08/branches/mssql_top_fixes/t/lib/DBICTest/Schema/Genre.pm
   DBIx-Class/0.08/branches/mssql_top_fixes/t/lib/sqlite.sql
   DBIx-Class/0.08/branches/mssql_top_fixes/t/multi_create/m2m.t
   DBIx-Class/0.08/branches/mssql_top_fixes/t/zzzzzzz_perl_perf_bug.t
Log:
 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
 r6813 at Thesaurus (orig r6812):  castaway | 2009-06-28 06:11:08 +0200
 Tests for grouping with prefetch
 
 r6820 at Thesaurus (orig r6819):  ribasushi | 2009-06-28 13:00:03 +0200
 The prefetch+group_by is a complex problem - branch
 r6844 at Thesaurus (orig r6843):  abraxxa | 2009-06-29 11:02:17 +0200
 fixed typo in test
 
 r6848 at Thesaurus (orig r6847):  ribasushi | 2009-06-29 19:09:00 +0200
 Minor Ordered optimization (don't use count)



Property changes on: DBIx-Class/0.08/branches/mssql_top_fixes
___________________________________________________________________
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/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:6742
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:6847
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/mssql_top_fixes/Changes
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/Changes	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/Changes	2009-06-29 20:21:24 UTC (rev 6850)
@@ -6,7 +6,11 @@
           nonexisting prefetch
         - Fixed the prefetch with limit bug
         - New resultsed method count_rs, returns a ::ResultSetColumn
-          returning a single count value
+          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

Modified: DBIx-Class/0.08/branches/mssql_top_fixes/Makefile.PL
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/Makefile.PL	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/Makefile.PL	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/lib/DBIx/Class/InflateColumn/DateTime.pm
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/InflateColumn/DateTime.pm	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/InflateColumn/DateTime.pm	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/lib/DBIx/Class/Manual/Cookbook.pod
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Manual/Cookbook.pod	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Manual/Cookbook.pod	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/lib/DBIx/Class/Ordered.pm
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Ordered.pm	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Ordered.pm	2009-06-29 20:21:24 UTC (rev 6850)
@@ -272,14 +272,14 @@
     return defined $lsib ? $lsib : 0;
 }
 
-# an optimised method to get the last sibling position without inflating a row object
-sub _last_sibling_pos {
+# an optimized method to get the last sibling position value without inflating a row object
+sub _last_sibling_posval {
     my $self = shift;
     my $position_column = $self->position_column;
 
     my $cursor = $self->next_siblings->search(
         {},
-        { rows => 1, order_by => { '-desc' => $position_column }, columns => $position_column },
+        { rows => 1, order_by => { '-desc' => $position_column }, select => $position_column },
     )->cursor;
 
     my ($pos) = $cursor->next;
@@ -313,7 +313,7 @@
 
 sub move_next {
     my $self = shift;
-    return 0 unless $self->next_siblings->count;
+    return 0 unless defined $self->_last_sibling_posval;  # quick way to check for no more siblings
     return $self->move_to ($self->_position + 1);
 }
 
@@ -341,7 +341,11 @@
 
 sub move_last {
     my $self = shift;
-    return $self->move_to( $self->_group_rs->count );
+    my $last_posval = $self->_last_sibling_posval;
+
+    return 0 unless defined $last_posval;
+
+    return $self->move_to( $self->_position_from_value ($last_posval) );
 }
 
 =head2 move_to
@@ -436,18 +440,21 @@
         $self->move_last;
 
         $self->set_inflated_columns({ %$to_group, $position_column => undef });
-        my $new_group_count = $self->_group_rs->count;
+        my $new_group_last_posval = $self->_last_sibling_posval;
+        my $new_group_last_position = $self->_position_from_value (
+          $new_group_last_posval
+        );
 
-        if ( not defined($to_position) or $to_position > $new_group_count) {
+        if ( not defined($to_position) or $to_position > $new_group_last_position) {
             $self->set_column(
-                $position_column => $new_group_count
-                    ? $self->_next_position_value ( $self->_last_sibling_pos )
+                $position_column => $new_group_last_position
+                    ? $self->_next_position_value ( $new_group_last_posval )
                     : $self->_initial_position_value
             );
         }
         else {
             my $bumped_pos_val = $self->_position_value ($to_position);
-            my @between = ($to_position, $new_group_count);
+            my @between = ($to_position, $new_group_last_position);
             $self->_shift_siblings (1, @between);   #shift right
             $self->set_column( $position_column => $bumped_pos_val );
         }
@@ -473,10 +480,10 @@
     my $position_column = $self->position_column;
 
     unless ($self->get_column($position_column)) {
-        my $lsib_pos = $self->_last_sibling_pos;
+        my $lsib_posval = $self->_last_sibling_posval;
         $self->set_column(
-            $position_column => (defined $lsib_pos
-                ? $self->_next_position_value ( $lsib_pos )
+            $position_column => (defined $lsib_posval
+                ? $self->_next_position_value ( $lsib_posval )
                 : $self->_initial_position_value
             )
         );
@@ -616,6 +623,27 @@
     return $self->get_column ($self->position_column);
 }
 
+=head2 _position_from_value
+
+  my $num_pos = $item->_position_of_value ( $pos_value )
+
+Returns the B<absolute numeric position> of an object with a B<position
+value> set to C<$pos_value>. By default simply returns C<$pos_value>.
+
+=cut
+sub _position_from_value {
+    my ($self, $val) = @_;
+
+    return 0 unless defined $val;
+
+#    #the right way to do this
+#    return $self -> _group_rs
+#                 -> search({ $self->position_column => { '<=', $val } })
+#                 -> count
+
+    return $val;
+}
+
 =head2 _position_value
 
   my $pos_value = $item->_position_value ( $pos )

Modified: DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Relationship/Base.pm
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Relationship/Base.pm	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Relationship/Base.pm	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/lib/DBIx/Class/Relationship/ManyToMany.pm
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Relationship/ManyToMany.pm	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Relationship/ManyToMany.pm	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/lib/DBIx/Class/ResultSet.pm
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/ResultSet.pm	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/ResultSet.pm	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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;
   }
 }
 
@@ -2189,7 +2184,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.
@@ -2451,12 +2446,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);
 
@@ -2557,7 +2552,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};
 
@@ -2581,7 +2576,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};
 
@@ -3218,7 +3213,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/mssql_top_fixes/lib/DBIx/Class/ResultSource.pm
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/ResultSource.pm	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/ResultSource.pm	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/lib/DBIx/Class/Row.pm
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Row.pm	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Row.pm	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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

Modified: DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Schema.pm
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Schema.pm	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/lib/DBIx/Class/Schema.pm	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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 "
@@ -1111,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/mssql_top_fixes/lib/SQL/Translator/Parser/DBIx/Class.pm
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/lib/SQL/Translator/Parser/DBIx/Class.pm	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/lib/SQL/Translator/Parser/DBIx/Class.pm	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/t/46where_attribute.t
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/46where_attribute.t	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/46where_attribute.t	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/t/85utf8.t
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/85utf8.t	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/85utf8.t	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/t/86sqlt.t
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/86sqlt.t	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/86sqlt.t	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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,
     },
   ],
 

Deleted: DBIx-Class/0.08/branches/mssql_top_fixes/t/96multi_create.t
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/96multi_create.t	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/96multi_create.t	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/t/96multi_create_new.t
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/96multi_create_new.t	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/96multi_create_new.t	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/t/96multi_create_torture.t
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/96multi_create_torture.t	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/96multi_create_torture.t	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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;

Modified: DBIx-Class/0.08/branches/mssql_top_fixes/t/inflate/serialize.t
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/inflate/serialize.t	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/inflate/serialize.t	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/t/lib/DBICTest/Schema/ArtistUndirectedMap.pm
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/lib/DBICTest/Schema/ArtistUndirectedMap.pm	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/lib/DBICTest/Schema/ArtistUndirectedMap.pm	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/t/lib/DBICTest/Schema/Genre.pm
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/lib/DBICTest/Schema/Genre.pm	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/lib/DBICTest/Schema/Genre.pm	2009-06-29 20:21:24 UTC (rev 6850)
@@ -20,4 +20,6 @@
 
 __PACKAGE__->has_many (cds => 'DBICTest::Schema::CD', 'genreid');
 
+__PACKAGE__->has_one (model_cd => 'DBICTest::Schema::CD', 'genreid');
+
 1;

Modified: DBIx-Class/0.08/branches/mssql_top_fixes/t/lib/sqlite.sql
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/lib/sqlite.sql	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/lib/sqlite.sql	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/t/multi_create/in_memory.t (from rev 6553, DBIx-Class/0.08/branches/mssql_top_fixes/t/96multi_create_new.t)
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/multi_create/in_memory.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/multi_create/in_memory.t	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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');
+}

Modified: DBIx-Class/0.08/branches/mssql_top_fixes/t/multi_create/m2m.t
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/multi_create/m2m.t	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/multi_create/m2m.t	2009-06-29 20:21:24 UTC (rev 6850)
@@ -23,7 +23,7 @@
 
   my $cd2 = $schema->resultset('CD')->search ( { cdid => { '!=', $cd->cdid } }, {rows => 1} )->single;  # retrieve a cd different from the first
   $cd2->add_to_producers ({name => 'new m2m producer'});                                                # attach to an existing producer
-  ok ($cd2->producers->find ({name => 'new m2m producer'}), 'Exsiting producer attached to existing cd');
+  ok ($cd2->producers->find ({name => 'new m2m producer'}), 'Existing producer attached to existing cd');
 
 }, 'Test far-end find_or_create over many_to_many');
 

Copied: DBIx-Class/0.08/branches/mssql_top_fixes/t/multi_create/standard.t (from rev 6553, DBIx-Class/0.08/branches/mssql_top_fixes/t/96multi_create.t)
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/multi_create/standard.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/multi_create/standard.t	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/t/multi_create/torture.t (from rev 6553, DBIx-Class/0.08/branches/mssql_top_fixes/t/96multi_create_torture.t)
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/multi_create/torture.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/multi_create/torture.t	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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;

Added: DBIx-Class/0.08/branches/mssql_top_fixes/t/relationship/update_or_create_multi.t
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/relationship/update_or_create_multi.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/relationship/update_or_create_multi.t	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/t/relationship/update_or_create_single.t
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/relationship/update_or_create_single.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/relationship/update_or_create_single.t	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/t/zzzzzzz_perl_perf_bug.t
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/zzzzzzz_perl_perf_bug.t	2009-06-29 20:07:43 UTC (rev 6849)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/zzzzzzz_perl_perf_bug.t	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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/mssql_top_fixes/t/zzzzzzz_sqlite_deadlock.t
===================================================================
--- DBIx-Class/0.08/branches/mssql_top_fixes/t/zzzzzzz_sqlite_deadlock.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/mssql_top_fixes/t/zzzzzzz_sqlite_deadlock.t	2009-06-29 20:21:24 UTC (rev 6850)
@@ -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