[Bast-commits] r6119 - in DBIx-Class/0.08/branches/hierarchical-queries: . lib/DBIx lib/DBIx/Class lib/DBIx/Class/CDBICompat lib/DBIx/Class/InflateColumn lib/DBIx/Class/Manual lib/DBIx/Class/Relationship lib/DBIx/Class/ResultClass lib/DBIx/Class/ResultSource lib/DBIx/Class/Schema lib/DBIx/Class/Storage lib/DBIx/Class/Storage/DBI lib/DBIx/Class/Storage/DBI/ODBC lib/SQL/Translator/Parser/DBIx t t/cdbi t/cdbi/testlib t/cdbi/testlib/DBIC t/cdbi/testlib/DBIC/Test t/lib t/lib/DBICTest t/lib/DBICTest/Schema t/lib/DBICTest/Taint t/lib/DBICTest/Taint/Classes t/lib/DBICTest/Taint/Namespaces t/lib/DBICTest/Taint/Namespaces/Result t/prefetch t/resultset t/search

caelum at dev.catalyst.perl.org caelum at dev.catalyst.perl.org
Mon May 4 03:30:19 GMT 2009


Author: caelum
Date: 2009-05-04 03:30:18 +0000 (Mon, 04 May 2009)
New Revision: 6119

Added:
   DBIx-Class/0.08/branches/hierarchical-queries/t/63register_source.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/DBIC/
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/DBIC/Test/
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/DBIC/Test/SQLite.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Schema/EventTZDeprecated.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Taint/
   DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Taint/Classes/
   DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Taint/Classes/Auto.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Taint/Classes/Manual.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Taint/Namespaces/
   DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Taint/Namespaces/Result/
   DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Taint/Namespaces/Result/Test.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/
   DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/attrs_untouched.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/multiple_hasmany.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/pollute_already_joined.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/rows_bug.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/standard.t
Removed:
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Test/
   DBIx-Class/0.08/branches/hierarchical-queries/t/77prefetch.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/98rows_prefetch.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICNGTest/
Modified:
   DBIx-Class/0.08/branches/hierarchical-queries/
   DBIx-Class/0.08/branches/hierarchical-queries/Changes
   DBIx-Class/0.08/branches/hierarchical-queries/MANIFEST.SKIP
   DBIx-Class/0.08/branches/hierarchical-queries/Makefile.PL
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/AbstractSearch.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/ColumnGroups.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/ColumnsAsHash.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Copy.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Iterator.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/NoObjectIndex.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Relationship.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Relationships.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Retrieve.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Componentised.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/DB.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/InflateColumn/DateTime.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/Cookbook.pod
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/FAQ.pod
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/Glossary.pod
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/Reading.pod
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/Troubleshooting.pod
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Relationship/Accessor.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Relationship/BelongsTo.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultClass/HashRefInflator.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSet.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSetColumn.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSource.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSource/View.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSourceHandle.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Row.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Schema.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Schema/Versioned.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI/NoBindVars.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI/ODBC/ACCESS.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI/Replicated.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI/SQLite.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/TxnScopeGuard.pm
   DBIx-Class/0.08/branches/hierarchical-queries/lib/SQL/Translator/Parser/DBIx/Class.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/03podcoverage.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/04dont_break_c3.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/100extra_source.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/19quotes.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/19quotes_newstyle.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/33storage_reconnect.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/39load_namespaces_rt41083.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/54taint.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/63register_class.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/64db.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/66relationship.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/71mysql.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/72pg.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/74mssql.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/76select.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/80unique.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/81transactions.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/89dbicadmin.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/89inflate_datetime.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/91debug.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/93storage_replication.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/95sql_maker.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/95sql_maker_quote.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/99dbic_sqlt_parser.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/01-columns.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/02-Film.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/15-accessor.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/22-deflate_order.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/columns_dont_override_custom_accessors.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/copy.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/multi_column_set.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/set_to_undef.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/set_vs_DateTime.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Actor.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/ActorAlias.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Blurb.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/CDBase.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Director.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Film.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Lazy.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/MyBase.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Order.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/OtherThing.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Thing.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Schema/CD.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Schema/EventTZ.pm
   DBIx-Class/0.08/branches/hierarchical-queries/t/lib/sqlite.sql
   DBIx-Class/0.08/branches/hierarchical-queries/t/resultset/as_query.t
   DBIx-Class/0.08/branches/hierarchical-queries/t/search/subquery.t
Log:
update branch from trunk


Property changes on: DBIx-Class/0.08/branches/hierarchical-queries
___________________________________________________________________
Name: svn:ignore
   - _build
blib
pm_to_blib
Build
Build.bat
Makefile
Makefile.old
inc
README
META.yml
MANIFEST


   + _build
blib
pm_to_blib
Build
Build.bat
Makefile
Makefile.old
inc
README
META.yml
MANIFEST
MANIFEST.bak

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:5635
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:10954
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/file_column:3920
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/multi_stuff:5565
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_sequence:4173
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/parser_fk_index:4485
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/replication_dedux:4600
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/subquery:5617
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:/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: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/file_column:3920
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/multi_stuff:5565
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_sequence:4173
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/parser_fk_index:4485
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/prefetch:5699
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/replication_dedux:4600
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/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/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/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:6113
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/hierarchical-queries/Changes
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/Changes	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/Changes	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,4 +1,35 @@
 Revision history for DBIx::Class
+
+0.08102 2009-04-30 08:29:00 (UTC)
+        - Fixed two subtle bugs when using columns or select/as
+          paired with a join (limited prefetch)
+        - Fixed breakage of cdbi tests (RT#45551)
+        - Some POD improvements
+
+0.08101 2009-04-27 09:45:00 (UTC)
+        - Fix +select, +as, +columns and include_columns being stripped
+          by $rs->get_column
+        - move load_optional_class from DBIx::Class::Componentised to
+          Class::C3::Componentised, bump dependency
+        - register_extra_source() now *really* fixed wrt subclassing
+        - Added missing POD descriptions (RT#45195)
+        - Fix insert() to not store_column() every present object column
+        - Multiple Makefile.PL fixes
+
+0.08100 2009-04-19 11:39:35 (UTC)
+        - Todo out the register_extra_source test until after shipping
+
+0.08099_08 2009-03-30 00:00:00 (UTC)
+        - Fixed taint mode with load_namespaces
+        - Putting IC::DateTime locale, timezone or floating_tz_ok attributes into
+          extra => {} has been deprecated. The new way is to put these things
+          directly into the columns definition
+        - Switched MI code to MRO::Compat
+        - Document db-side default_value caveats
+        - Search_like() now warns to indicate deprecation in 0.09.
+        - TxnScopeGuard left experimental state
+
+0.08099_07 2009-02-27 02:00:00 (UTC)
         - multi-create using find_or_create rather than _related for post-insert
         - fix get_inflated_columns to check has_column_loaded
         - Add DBIC_MULTICREATE_DEBUG env var (undocumented, quasi-internal)
@@ -7,15 +38,17 @@
           - not try and insert things tagged on via new_related unless required
         - Possible to set locale in IC::DateTime extra => {} config
         - Calling the accessor of a belongs_to when the foreign_key
-          was NULL and the row was not stored would unexpectedly fail (groditi)
+          was NULL and the row was not stored would unexpectedly fail 
         - Split sql statements for deploy only if SQLT::Producer returned a scalar
           containing all statements to be executed
         - Add as_query() for ResultSet and ResultSetColumn. This makes subqueries
-          possible. See the Cookbook for details. (robkinyon, michaelr)
+          possible. See the Cookbook for details.
         - Massive rewrite of Ordered to properly handle position constraints and
           to make it more matpath-friendly
         - deploy_statements called ddl_filename with the $version and $dir arguments
-          in the wrong order. (groditi)
+          in the wrong order.
+        - columns/+columns attributes now support { as => select } hahsrefs
+        - support for views both in DBIC and via deploy() in SQLT
 
 0.08099_06 2009-01-23 07:30:00 (UTC)
         - Allow a scalarref to be supplied to the 'from' resultset attribute
@@ -30,19 +63,18 @@
           (http://msdn.microsoft.com/en-us/library/ms190315.aspx)
         - an sqlt_deploy_hook can now be shared between result sources using
           a configurable callback trigger
-        - new order_by => { -desc => 'colname' } syntax supported with
-          SQLA >= 1.50
-        - PG array datatype supported with SQLA >= 1.50
+        - new order_by => { -desc => 'colname' } syntax supported
+        - PG array datatype supported
         - insert should use store_column, not set_column to avoid marking
-          clean just-stored values as dirty. New test for this (groditi)
-        - regression test for source_name (groditi)
+          clean just-stored values as dirty. New test for this 
+        - regression test for source_name 
 
 0.08099_05 2008-10-30 21:30:00 (UTC)
-        - Rewritte of Storage::DBI::connect_info(), extended with an
+        - Rewrite of Storage::DBI::connect_info(), extended with an
           additional argument format type
         - InflateColumn::DateTime: add warning about floating timezone
         - InflateColumn::DateTime: possible to enforce/skip inflation
-        - delete throws exception if passed arguments to prevent drunken mishaps. (purge)
+        - delete throws exception if passed arguments to prevent drunken mishaps.
         - Fix storage to copy scalar conds before regexping to avoid
           trying to modify a constant in odd edge cases
         - Related resultsets on uninserted objects are now empty

Modified: DBIx-Class/0.08/branches/hierarchical-queries/MANIFEST.SKIP
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/MANIFEST.SKIP	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/MANIFEST.SKIP	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,3 +1,6 @@
+^(?!script/|examples/|lib/|inc/|t/|Makefile.PL$|README$|MANIFEST$|Changes$|META.yml$)
+
+
 # Avoid version control files.
 \bRCS\b
 \bCVS\b

Modified: DBIx-Class/0.08/branches/hierarchical-queries/Makefile.PL
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/Makefile.PL	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/Makefile.PL	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,4 +1,4 @@
-use inc::Module::Install 0.67;
+use inc::Module::Install 0.79;
 use strict;
 use warnings;
 use POSIX ();
@@ -9,31 +9,32 @@
 perl_version '5.006001';
 all_from 'lib/DBIx/Class.pm';
 
+# configure_requires so _check_sqlite() below can run
+# remove once test deprecated
+configure_requires 'DBD::SQLite';
+
+requires 'DBD::SQLite'              => 1.23;
 requires 'Data::Page'               => 2.00;
 requires 'Scalar::Util'             => 0;
-requires 'SQL::Abstract'            => 1.49;
+requires 'SQL::Abstract'            => 1.53;
 requires 'SQL::Abstract::Limit'     => 0.13;
-requires 'Class::C3'                => 0.20;
-requires 'Class::C3::Componentised' => 0;
+requires 'Class::C3::Componentised' => 1.0005;
 requires 'Storable'                 => 0;
 requires 'Carp::Clan'               => 0;
 requires 'DBI'                      => 1.40;
 requires 'Module::Find'             => 0;
 requires 'Class::Inspector'         => 0;
-requires 'Class::Accessor::Grouped' => 0.08002;
+requires 'Class::Accessor::Grouped' => 0.08003;
 requires 'JSON::Any'                => 1.17;
 requires 'Scope::Guard'             => 0.03;
 requires 'Path::Class'              => 0;
 requires 'List::Util'               => 1.19;
 requires 'Sub::Name'                => 0.04;
-requires 'namespace::clean'         => 0.09;
+requires 'MRO::Compat'              => 0.09;
 
 # Perl 5.8.0 doesn't have utf8::is_utf8()
 requires 'Encode'                   => 0 if ($] <= 5.008000);  
 
-# configure_requires so the sanity check below can run
-configure_requires 'DBD::SQLite'    => 1.14;
-
 test_requires 'Test::Builder'       => 0.33;
 test_requires 'Test::Warn'          => 0.11;
 test_requires 'Test::Exception'     => 0;
@@ -41,34 +42,54 @@
 
 recommends 'SQL::Translator'        => 0.09004;
 
-install_script 'script/dbicadmin';
+install_script (qw|
+    script/dbicadmin
+|);
 
-tests_recursive 't';
+tests_recursive (qw|
+    t
+|);
 
-# re-build README and require CDBI modules for testing if we're in a checkout
+# re-build README and require extra modules for testing if we're in a checkout
 
 my %force_requires_if_author = (
-  'Test::Pod::Coverage'       => 0,
+  'Test::Pod::Coverage'       => 1.04,
   'SQL::Translator'           => 0.09004,
 
   # CDBI-compat related
   'DBIx::ContextualFetch'     => 0,
+  'Class::DBI::Plugin::DeepAbstractSearch' => 0,
   'Class::Trigger'            => 0,
-  'Time::Piece'               => 0,
+  'Time::Piece::MySQL'        => 0,
   'Clone'                     => 0,
+  'Date::Simple'              => 0,
 
   # t/52cycle.t
   'Test::Memory::Cycle'       => 0,
 
+  # t/60core.t
+  'DateTime::Format::MySQL'   => 0,
+
+  # t/72pg.t
+  $ENV{DBICTEST_PG_DSN}
+    ? ('Sys::SigAction'=> 0)
+    : ()
+  ,
+
   # t/93storage_replication.t
-  'Moose',                    => 0,
-  'MooseX::AttributeHelpers'  => 0.12,
+  'Moose',                        => 0.54,
+  'Moose::Util::TypeConstraints'  => 0.54,
+  'MooseX::AttributeHelpers'      => 0.12,
+  'Class::MOP'                    => 0.63,
+
+  # t/96_is_deteministic_value.t
+  'DateTime::Format::Strptime' => 0,
 );
 
 if ($Module::Install::AUTHOR) {
 
   foreach my $module (keys %force_requires_if_author) {
-    requires ($module => $force_requires_if_author{$module});
+    build_requires ($module => $force_requires_if_author{$module});
   }
 
   system('pod2text lib/DBIx/Class.pm > README');
@@ -76,62 +97,65 @@
 
 auto_provides;
 
+if ($Module::Install::AUTHOR) {
+  warn <<'EOW';
+******************************************************************************
+******************************************************************************
+***                                                                        ***
+*** AUTHOR MODE: all optional test dependencies converted to hard requires ***
+***                                                                        ***
+******************************************************************************
+******************************************************************************
+
+EOW
+}
 auto_install;
 
 # Have all prerequisites, check DBD::SQLite sanity
-if (! $ENV{DBICTEST_NO_SQLITE_CHECK} ) {
+_check_sqlite() if (! $ENV{DBICTEST_NO_SQLITE_CHECK} );
 
-  my $pid = fork();
-  if (not defined $pid) {
-      die "Unable to fork(): $!";
-  }
-  elsif (! $pid) {
+WriteAll();
 
-      # Win32 does not have real fork()s so a segfault will bring
-      # everything down. Warn about it.
-      if ($^O eq 'MSWin32') {
-        print <<'EOW';
+if ($Module::Install::AUTHOR) {
+  # Need to do this _after_ WriteAll else it loses track of them
+  Meta->{values}{build_requires} = [ grep {
+    my $ok = 1;
+    foreach my $module (keys %force_requires_if_author) {
+      if ($_->[0] =~ /$module/) {
+        $ok = 0;
+        last;
+      }
+    }
+    $ok;
+  } @{Meta->{values}{build_requires}} ];
 
-######################################################################
-#                                                                    #
-# A short stress-testing of DBD::SQLite will follow. If you have a   #
-# buggy library this might very well be the last text you will see   #
-# before the installation silently terminates. If this happens it    #
-# would mean that you are running a buggy version of DBD::SQLite     #
-# known to randomly segfault on errors. Even if you have the latest  #
-# CPAN module version, the system sqlite3 dynamic library might have #
-# been compiled against an older buggy sqlite3 dev library (oddly    #
-# DBD::SQLite will prefer the system library against the one bundled #
-# with it). You are strongly advised to resolve this issue before    #
-# proceeding.                                                        #
-#                                                                    #
-# If this happens to you (this text is the last thing you see), and  #
-# you just want to install this module without worrying about the    #
-# tests (which will almost certainly fail) - set the environment     #
-# variable DBICTEST_NO_SQLITE_CHECK to a true value and try again.   #
-#                                                                    #
-######################################################################
+  Meta->{values}{resources} = [ 
+    [ 'MailingList', 'http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class' ],
+    [ 'IRC', 'irc://irc.perl.org/#dbix-class' ],
+    [ 'license', 'http://dev.perl.org/licenses/' ],
+    [ 'repository', 'http://dev.catalyst.perl.org/svnweb/bast/browse/DBIx-Class/' ],
+  ];
+  Meta->write;
+}
 
-EOW
-      }
 
-      require DBI;
-      for (1 .. 100) {
-          my $dbh;
-          $dbh = DBI->connect ('dbi:SQLite::memory:', undef, undef, {
-              AutoCommit => 1,
-              RaiseError => 0,
-              PrintError => 0,
-          })
-              or die "Unable to connect to database: $@";
-          $dbh->do ('CREATE TABLE name_with_no_columns');   # a subtle syntax error
-          $dbh->do ('COMMIT');                              # followed by commit
-          $dbh->disconnect;
-      }
+# This is legacy code. Latest DBD::SQLite developments fixed all known bugs
+# in this area. Remove before some arbitrary next version
+sub _check_sqlite {
 
+  # Win32 does not have real fork()s so a segfault will bring
+  # everything down. Warn about it below, and don't try fork()
+  if ($^O ne 'MSWin32') {
+
+    my $pid = fork();
+    if (not defined $pid) {
+        die "Unable to fork(): $!";
+    }
+    elsif (! $pid) {
+      _torture_sqlite();
       exit 0;
-  }
-  else {
+    }
+    else {
       eval {
           local $SIG{ALRM} = sub { die "timeout\n" };
           alarm 5;
@@ -142,7 +166,7 @@
 
       my $sig = $? & 127;
 
-# make sure process actually dies
+      # make sure process actually dies
       $exception && kill POSIX::SIGKILL(), $pid;
 
       if ($exception || $sig == POSIX::SIGSEGV() || $sig == POSIX::SIGABRT()
@@ -168,39 +192,50 @@
           );
           exit 0 unless ($ans =~ /^y(es)?$/i);
       }
+    }
   }
-}
 
+  else {  # the win32 version
 
-WriteAll();
+    print <<'EOW';
+######################################################################
+#                                                                    #
+# A short stress-testing of DBD::SQLite will follow. If you have a   #
+# buggy library this might very well be the last text you will see   #
+# before the installation silently terminates. If this happens it    #
+# would mean that you are running a buggy version of DBD::SQLite     #
+# known to randomly segfault on errors. Even if you have the latest  #
+# CPAN module version, the system sqlite3 dynamic library might have #
+# been compiled against an older buggy sqlite3 dev library (oddly    #
+# DBD::SQLite will prefer the system library against the one bundled #
+# with it). You are strongly advised to resolve this issue before    #
+# proceeding.                                                        #
+#                                                                    #
+# If this happens to you (this text is the last thing you see), and  #
+# you just want to install this module without worrying about the    #
+# tests (which will almost certainly fail) - set the environment     #
+# variable DBICTEST_NO_SQLITE_CHECK to a true value and try again.   #
+#                                                                    #
+######################################################################
 
+EOW
 
-if ($Module::Install::AUTHOR) {
-  # Need to do this _after_ WriteAll else it looses track of them
-  Meta->{values}{build_requires} = [ grep {
-    my $ok = 1;
-    foreach my $module (keys %force_requires_if_author) {
-      if ($_->[0] =~ /$module/) {
-        $ok = 0;
-        last;
-      }
-    }
-    $ok;
-  } @{Meta->{values}{build_requires}} ];
+    _torture_sqlite();
+  }
+}
 
-  my @scalar_keys = Module::Install::Metadata::Meta_TupleKeys();
-  my $cr = Module::Install::Metadata->can("Meta_TupleKeys");
-  {
-    no warnings 'redefine';
-    *Module::Install::Metadata::Meta_TupleKeys = sub {
-      return $cr->(@_), 'resources';
-    };
+sub _torture_sqlite {
+  require DBI;
+
+  for (1 .. 100) {
+    my $dbh = DBI->connect ('dbi:SQLite::memory:', undef, undef, {
+      AutoCommit => 1,
+      RaiseError => 0,
+      PrintError => 0,
+    }) or die "Unable to connect to database: $@";
+
+    $dbh->do ('CREATE TABLE name_with_no_columns');   # a subtle syntax error
+    $dbh->do ('COMMIT');                              # followed by commit
+    $dbh->disconnect;
   }
-  Meta->{values}{resources} = [ 
-    [ 'MailingList', 'http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class' ],
-    [ 'IRC', 'irc://irc.perl.org/#dbix-class' ],
-    [ 'license', 'http://dev.perl.org/licenses/' ],
-    [ 'repository', 'http://dev.catalyst.perl.org/svnweb/bast/browse/DBIx-Class/' ],
-  ];
-  Meta->write;
 }

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/AbstractSearch.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/AbstractSearch.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/AbstractSearch.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -6,7 +6,7 @@
 
 =head1 NAME
 
-DBIx::Class::CDBICompat::AbstractSearch
+DBIx::Class::CDBICompat::AbstractSearch - Emulates Class::DBI::AbstractSearch
 
 =head1 SYNOPSIS
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/ColumnGroups.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/ColumnGroups.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/ColumnGroups.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -155,7 +155,8 @@
   return map { $class->find_column($_) } @col;
 }
 
-package DBIx::Class::CDBICompat::ColumnGroups::GrouperShim;
+package # hide from PAUSE (should be harmless, no POD no Version)
+    DBIx::Class::CDBICompat::ColumnGroups::GrouperShim;
 
 sub groups_for {
   my ($self, @cols) = @_;
@@ -167,6 +168,5 @@
   }
   return keys %groups;
 }
-    
 
 1;

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/ColumnsAsHash.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/ColumnsAsHash.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/ColumnsAsHash.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -7,7 +7,7 @@
 
 =head1 NAME
 
-DBIx::Class::CDBICompat::ColumnsAsHash
+DBIx::Class::CDBICompat::ColumnsAsHash - Emulates the behavior of Class::DBI where the object can be accessed as a hash of columns.
 
 =head1 SYNOPSIS
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Copy.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Copy.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Copy.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -8,7 +8,7 @@
 
 =head1 NAME
 
-DBIx::Class::CDBICompat::Copy
+DBIx::Class::CDBICompat::Copy - Emulates Class::DBI->copy($new_id)
 
 =head1 SYNOPSIS
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Iterator.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Iterator.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Iterator.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -6,7 +6,7 @@
 
 =head1 NAME
 
-DBIx::Class::CDBICompat::Iterator
+DBIx::Class::CDBICompat::Iterator - Emulates the extra behaviors of the Class::DBI search iterator.
 
 =head1 SYNOPSIS
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/NoObjectIndex.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/NoObjectIndex.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/NoObjectIndex.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -6,7 +6,7 @@
 
 =head1 NAME
 
-DBIx::Class::CDBICompat::NoObjectIndex
+DBIx::Class::CDBICompat::NoObjectIndex - Defines empty methods for object indexing. They do nothing
 
 =head1 SYNOPSIS
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Relationship.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Relationship.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Relationship.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -7,7 +7,7 @@
 
 =head1 NAME
 
-DBIx::Class::CDBICompat::Relationship
+DBIx::Class::CDBICompat::Relationship - Emulate the Class::DBI::Relationship object returned from meta_info()
 
 =head1 DESCRIPTION
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Relationships.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Relationships.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Relationships.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -14,7 +14,7 @@
 
 =head1 NAME
 
-DBIx::Class::CDBICompat::Relationships
+DBIx::Class::CDBICompat::Relationships - Emulate has_a(), has_many(), might_have() and meta_info()
 
 =head1 DESCRIPTION
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Retrieve.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Retrieve.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/CDBICompat/Retrieve.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -50,11 +50,24 @@
 
   $cond =~ s/^\s*WHERE//i;
 
-  if( $cond =~ s/\bLIMIT (\d+)\s*$//i ) {
-      push @rest, { rows => $1 };
+  # Need to parse the SQL clauses after WHERE in reverse
+  # order of appearance.
+
+  my %attrs;
+
+  if( $cond =~ s/\bLIMIT\s+(\d+)\s*$//i ) {
+      $attrs{rows} = $1;
   }
 
-  return $class->search_literal($cond, @rest);
+  if ( $cond =~ s/\bORDER\s+BY\s+(.*)\s*$//i ) {
+      $attrs{order_by} = $1;
+  }
+
+  if( $cond =~ s/\bGROUP\s+BY\s+(.*)\s*$//i ) {
+      $attrs{group_by} = $1;
+  }
+
+  return $class->search_literal($cond, @rest, ( %attrs ? \%attrs : () ) );
 }
 
 sub construct {

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Componentised.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Componentised.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Componentised.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -31,25 +31,4 @@
   $class->next::method($target, @to_inject);
 }
 
-# Returns a true value if the specified class is installed and loaded
-# successfully, throws an exception if the class is found but not loaded
-# successfully, and false if the class is not installed
-sub load_optional_class {
-  my ($class, $f_class) = @_;
-  eval { $class->ensure_class_loaded($f_class) };
-  my $err = $@;   # so we don't lose it
-  if (! $err) {
-    return 1;
-  }
-  else {
-    my $fn = (join ('/', split ('::', $f_class) ) ) . '.pm';
-    if ($err =~ /Can't locate ${fn} in \@INC/ ) {
-      return 0;
-    }
-    else {
-      die $err;
-    }
-  }
-}
-
 1;

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/DB.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/DB.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/DB.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -162,11 +162,12 @@
 sub _maybe_attach_source_to_schema {
   my ($class, $source) = @_;
   if (my $meth = $class->can('schema_instance')) {
-    my $schema = $class->$meth;
-    $schema->register_class($class, $class);
-    my $new_source = $schema->source($class);
-    %$source = %$new_source;
-    $schema->source_registrations->{$class} = $source;
+    if (my $schema = $class->$meth) {
+      $schema->register_class($class, $class);
+      my $new_source = $schema->source($class);
+      %$source = %$new_source;
+      $schema->source_registrations->{$class} = $source;
+    }
   }
 }
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/InflateColumn/DateTime.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/InflateColumn/DateTime.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/InflateColumn/DateTime.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -30,7 +30,7 @@
 If you want to set a specific timezone and locale for that field, use:
 
   __PACKAGE__->add_columns(
-    starts_when => { data_type => 'datetime', extra => { timezone => "America/Chicago", locale => "de_DE" } }
+    starts_when => { data_type => 'datetime', timezone => "America/Chicago", locale => "de_DE" }
   );
 
 If you want to inflate no matter what data_type your column is,
@@ -111,13 +111,20 @@
 
   my $timezone;
   if ( defined $info->{extra}{timezone} ) {
+    warn "Putting timezone into extra => { timezone => '...' } has been deprecated, ".
+         "please put it directly into the columns definition.";
     $timezone = $info->{extra}{timezone};
   }
 
   my $locale;
   if ( defined $info->{extra}{locale} ) {
+    warn "Putting locale into extra => { locale => '...' } has been deprecated, ".
+         "please put it directly into the columns definition.";
     $locale = $info->{extra}{locale};
   }
+  
+  $locale   = $info->{locale}   if defined $info->{locale};
+  $timezone = $info->{timezone} if defined $info->{timezone};
 
   my $undef_if_invalid = $info->{datetime_undef_if_invalid};
 
@@ -137,7 +144,13 @@
     #     closure &G, $info => $H
     #     $H => %E
     #
-    my $floating_tz_ok = $info->{extra}{floating_tz_ok};
+    my $floating_tz_ok;
+    if (defined $info->{extra}{floating_tz_ok}) {
+      warn "Putting floating_tz_ok into extra => { floating_tz_ok => 1 } has been deprecated, ".
+           "please put it directly into the columns definition.";
+      $floating_tz_ok = $info->{extra}{floating_tz_ok};
+    }
+    $floating_tz_ok = $info->{floating_tz_ok} if defined $info->{floating_tz_ok};
 
     $self->inflate_column(
       $column =>
@@ -189,7 +202,7 @@
 result you expect). For example:
 
   __PACKAGE__->add_columns(
-    starts_when => { data_type => 'datetime', extra => { timezone => "America/Chicago" } }
+    starts_when => { data_type => 'datetime', timezone => "America/Chicago" }
   );
 
   my $event = $schema->resultset('EventTZ')->create({
@@ -213,7 +226,7 @@
 =item Suppress the check on per-column basis
 
   __PACKAGE__->add_columns(
-    starts_when => { data_type => 'datetime', extra => { timezone => "America/Chicago", floating_tz_ok => 1 } }
+    starts_when => { data_type => 'datetime', timezone => "America/Chicago", floating_tz_ok => 1 }
   );
 
 =item Suppress the check globally
@@ -222,8 +235,11 @@
 
 =back
 
+Putting extra attributes like timezone, locale or floating_tz_ok into extra => {} has been
+B<DEPRECATED> because this gets you into trouble using L<DBIx::Class::Schema::Versioned>.
+Instead put it directly into the columns definition like in the examples above. If you still
+use the old way you'll see a warning - please fix your code then!
 
-
 =head1 SEE ALSO
 
 =over 4

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/Cookbook.pod
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/Cookbook.pod	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/Cookbook.pod	2009-05-04 03:30:18 UTC (rev 6119)
@@ -19,20 +19,9 @@
 
   return $rs->all(); # all records for page 1
 
-The C<page> attribute does not have to be specified in your search:
+You can get a L<Data::Page> object for the resultset (suitable for use
+in e.g. a template) using the C<pager> method:
 
-  my $rs = $schema->resultset('Artist')->search(
-    undef,
-    {
-      rows => 10,
-    }
-  );
-
-  return $rs->page(1); # DBIx::Class::ResultSet containing first 10 records
-
-In either of the above cases, you can get a L<Data::Page> object for the
-resultset (suitable for use in e.g. a template) using the C<pager> method:
-
   return $rs->pager();
 
 =head2 Complex WHERE clauses
@@ -116,7 +105,7 @@
 Say you want to run a complex custom query on your user data, here's what
 you have to add to your User class:
 
-  package My::Schema::User;
+  package My::Schema::Result::User;
   
   use base qw/DBIx::Class/;
   
@@ -160,10 +149,10 @@
 achieve the same with subclassing the resultset class and defining the
 ResultSource there:
 
-  package My::Schema::UserFriendsComplex;
+  package My::Schema::Result::UserFriendsComplex;
 
-  use My::Schema::User;
-  use base qw/My::Schema::User/;
+  use My::Schema::Result::User;
+  use base qw/My::Schema::Result::User/;
 
   __PACKAGE__->table('dummy');  # currently must be called before anything else
 
@@ -295,7 +284,7 @@
 are in any way unsure about the use of the attributes above (C< join
 >, C< select >, C< as > and C< group_by >).
 
-=head2 Subqueries
+=head2 Subqueries (EXPERIMENTAL)
 
 You can write subqueries relatively easily in DBIC.
 
@@ -343,6 +332,10 @@
        WHERE artistid = me.artistid
       )
 
+=head3 EXPERIMENTAL
+
+Please note that subqueries are considered an experimental feature.
+
 =head2 Predefined searches
 
 You can write your own L<DBIx::Class::ResultSet> class by inheriting from it
@@ -680,7 +673,7 @@
 module.
 
 To make an object stringify itself as a single column, use something
-like this (replace C<foo> with the column/method of your choice):
+like this (replace C<name> with the column/method of your choice):
 
   use overload '""' => sub { shift->name}, fallback => 1;
 
@@ -747,16 +740,16 @@
  
 B<Schema Definition> 
  
-    package DB::Schema; 
+    package My::Schema; 
      
     use base qw/DBIx::Class::Schema/; 
  
-    __PACKAGE__->load_classes(qw/User/); 
+    __PACKAGE__->load_namespaces; 
  
  
 B<Proxy-Class definitions> 
  
-    package DB::Schema::User; 
+    package My::Schema::Result::User; 
      
     use strict; 
     use warnings; 
@@ -791,11 +784,11 @@
     } 
      
      
-    package DB::Schema::User::Admin; 
+    package My::Schema::Result::User::Admin; 
      
     use strict; 
     use warnings; 
-    use base qw/DB::Schema::User/; 
+    use base qw/My::Schema::Result::User/; 
      
     sub hello 
     { 
@@ -813,7 +806,7 @@
  
     use warnings; 
     use strict; 
-    use DB::Schema; 
+    use My::Schema; 
      
     my $user_data = { email    => 'someguy at place.com',  
                       password => 'pass1',  
@@ -823,7 +816,7 @@
                        password => 'pass2',  
                        admin    => 1 }; 
                            
-    my $schema = DB::Schema->connection('dbi:Pg:dbname=test'); 
+    my $schema = My::Schema->connection('dbi:Pg:dbname=test'); 
      
     $schema->resultset('User')->create( $user_data ); 
     $schema->resultset('User')->create( $admin_data ); 
@@ -861,11 +854,16 @@
 
 Wasn't that easy?
 
+Beware, changing the Result class using
+L<DBIx::Class::ResultSet/result_class> will replace any existing class
+completely including any special components loaded using
+load_components, eg L<DBIx::Class::InflateColumn::DateTime>.
+
 =head2 Get raw data for blindingly fast results
 
 If the L<HashRefInflator|DBIx::Class::ResultClass::HashRefInflator> solution
 above is not fast enough for you, you can use a DBIx::Class to return values
-exactly as they come out of the data base with none of the convenience methods
+exactly as they come out of the database with none of the convenience methods
 wrapped round them.
 
 This is used like so:
@@ -876,13 +874,13 @@
   }
 
 You will need to map the array offsets to particular columns (you can
-use the I<select> attribute of C<search()> to force ordering).
+use the L<DBIx::Class::ResultSet/select> attribute of L<DBIx::Class::ResultSet/search> to force ordering).
 
 =head1 RESULTSET OPERATIONS
 
 =head2 Getting Schema from a ResultSet
 
-To get the schema object from a result set, do the following:
+To get the L<DBIx::Class::Schema> object from a ResultSet, do the following:
 
  $rs->result_source->schema
 
@@ -1022,6 +1020,98 @@
   $rs = $user->addresses(); # get all addresses for a user
   $rs = $address->users(); # get all users for an address
 
+=head2 Relationships across DB schemas
+
+Mapping relationships across L<DB schemas|DBIx::Class::Manual::Glossary/DB schema>
+is easy as long as the schemas themselves are all accessible via the same DBI
+connection. In most cases, this means that they are on the same database host
+as each other and your connecting database user has the proper permissions to them.
+
+To accomplish this one only needs to specify the DB schema name in the table
+declaration, like so...
+
+  package MyDatabase::Main::Artist;
+  use base qw/DBIx::Class/;
+  __PACKAGE__->load_components(qw/PK::Auto Core/);
+  
+  __PACKAGE__->table('database1.artist'); # will use "database1.artist" in FROM clause
+  
+  __PACKAGE__->add_columns(qw/ artistid name /);
+  __PACKAGE__->set_primary_key('artistid');
+  __PACKAGE__->has_many('cds' => 'MyDatabase::Main::Cd');
+
+  1;
+
+Whatever string you specify there will be used to build the "FROM" clause in SQL
+queries.
+
+The big drawback to this is you now have DB schema names hardcoded in your
+class files. This becomes especially troublesome if you have multiple instances
+of your application to support a change lifecycle (e.g. DEV, TEST, PROD) and
+the DB schemas are named based on the environment (e.g. database1_dev).
+
+However, one can dynamically "map" to the proper DB schema by overriding the
+L<connection|DBIx::Class::Schama/connection> method in your Schema class and
+building a renaming facility, like so:
+
+  package MyDatabase::Schema;
+  use Moose;
+  
+  extends 'DBIx::Class::Schema';
+  
+  around connection => sub {
+    my ( $inner, $self, $dsn, $username, $pass, $attr ) = ( shift, @_ );
+   
+    my $postfix = delete $attr->{schema_name_postfix};
+    
+    $inner->(@_);
+    
+    if ( $postfix ) {
+        $self->append_db_name($postfix);
+    }
+  };
+
+  sub append_db_name {
+    my ( $self, $postfix ) = @_;
+    
+    my @sources_with_db 
+        = grep 
+            { $_->name =~ /^\w+\./mx } 
+            map 
+                { $self->source($_) } 
+                $self->sources;
+    
+    foreach my $source (@sources_with_db) {
+        my $name = $source->name;
+        $name =~ s{^(\w+)\.}{${1}${postfix}\.}mx;
+        
+        $source->name($name);
+    }
+  }
+
+  1;
+
+By overridding the L<connection|DBIx::Class::Schama/connection>
+method and extracting a custom option from the provided \%attr hashref one can
+then simply iterate over all the Schema's ResultSources, renaming them as
+needed.
+
+To use this facility, simply add or modify the \%attr hashref that is passed to 
+L<connection|DBIx::Class::Schama/connect>, as follows:
+
+  my $schema 
+    = MyDatabase::Schema->connect(
+      $dsn, 
+      $user, 
+      $pass,
+      {
+        schema_name_postfix => '_dev'
+        # ... Other options as desired ... 
+      })
+
+Obviously, one could accomplish even more advanced mapping via a hash map or a
+callback routine.
+
 =head1 TRANSACTIONS
 
 As of version 0.04001, there is improved transaction support in
@@ -1174,6 +1264,18 @@
   while (my @vals = $cursor->next) {
     print $vals[0]."\n";
   }
+
+In case you're going to use this "trick" together with L<DBIx::Class::Schema/deploy> or
+L<DBIx::Class::Schema/create_ddl_dir> a table called "dual" will be created in your
+current schema. This would overlap "sys.dual" and you could not fetch "sysdate" or
+"sequence.nextval" anymore from dual. To avoid this problem, just tell
+L<SQL::Translator> to not create table dual:
+
+    my $sqlt_args = {
+        add_drop_table => 1,
+        parser_args    => { sources => [ grep $_ ne 'Dual', schema->sources ] },
+    };
+    $schema->create_ddl_dir( [qw/Oracle/], undef, './sql', undef, $sqlt_args );
  
 Or use L<DBIx::Class::ResultClass::HashRefInflator>
  
@@ -1219,7 +1321,7 @@
 L<callback system|DBIx::Class::ResultSource/sqlt_deploy_callback> if you wish
 to share a hook between multiple sources):
 
- package My::Schema::Artist;
+ package My::Schema::Result::Artist;
 
  __PACKAGE__->table('artist');
  __PACKAGE__->add_columns(id => { ... }, name => { ... })
@@ -1381,10 +1483,10 @@
 
 =head2 Working with PostgreSQL array types
 
-If your SQL::Abstract version (>= 1.50) supports it, you can assign to
-PostgreSQL array values by passing array references in the C<\%columns>
-(C<\%vals>) hashref of the L<DBIx::Class::ResultSet/create> and
-L<DBIx::Class::Row/update> family of methods:
+You can also assign values to PostgreSQL array columns by passing array
+references in the C<\%columns> (C<\%vals>) hashref of the
+L<DBIx::Class::ResultSet/create> and L<DBIx::Class::Row/update> family of
+methods:
 
   $resultset->create({
     numbers => [1, 2, 3]
@@ -1733,4 +1835,33 @@
 syntax to load the appropriate classes there is not a direct alternative
 avoiding L<Module::Find|Module::Find>.
 
+=head1 MEMORY USAGE
+
+=head2 Cached statements
+
+L<DBIx::Class> normally caches all statements with L<< prepare_cached()|DBI/prepare_cached >>.
+This is normally a good idea, but if too many statements are cached, the database may use too much
+memory and may eventually run out and fail entirely.  If you suspect this may be the case, you may want
+to examine DBI's L<< CachedKids|DBI/CachedKidsCachedKids_(hash_ref) >> hash:
+
+    # print all currently cached prepared statements
+    print for keys %{$schema->storage->dbh->{CachedKids}};
+    # get a count of currently cached prepared statements
+    my $count = scalar keys %{$schema->storage->dbh->{CachedKids}};
+
+If it's appropriate, you can simply clear these statements, automatically deallocating them in the
+database:
+
+    my $kids = $schema->storage->dbh->{CachedKids};
+    delete @{$kids}{keys %$kids} if scalar keys %$kids > 100;
+
+But what you probably want is to expire unused statements and not those that are used frequently.
+You can accomplish this with L<Tie::Cache> or L<Tie::Cache::LRU>:
+
+    use Tie::Cache;
+    use DB::Main;
+    my $schema = DB::Main->connect($dbi_dsn, $user, $pass, {
+        on_connect_do => sub { tie %{shift->_dbh->{CachedKids}}, 'Tie::Cache', 100 },
+    });
+
 =cut

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/FAQ.pod
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/FAQ.pod	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/FAQ.pod	2009-05-04 03:30:18 UTC (rev 6119)
@@ -274,7 +274,7 @@
 
 Or, if you have quoting off:
 
- ->search({ 'YEAR(date_of_birth' => 1979 });
+ ->search({ 'YEAR(date_of_birth)' => 1979 });
 
 =item .. find more help on constructing searches?
 
@@ -353,6 +353,20 @@
 L<DBIx::Class::PK/discard_changes> does just that by re-fetching the row from storage
 using the row's primary key.
 
+=item .. fetch my data a "page" at a time?
+
+Pass the C<rows> and C<page> attributes to your search, eg:
+
+  ->search({}, { rows => 10, page => 1});
+
+=item .. get a count of all rows even when paging?
+
+Call C<pager> on the paged resultset, it will return a L<Data::Page>
+object. Calling C<total_entries> on the pager will return the correct
+total.
+
+C<count> on the resultset will only return the total number in the page.
+
 =back
 
 =head2 Inserting and updating data

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/Glossary.pod
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/Glossary.pod	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/Glossary.pod	2009-05-04 03:30:18 UTC (rev 6119)
@@ -9,6 +9,17 @@
 
 =head1 TERMS
 
+=head2 DB schema
+
+Refers to a single physical schema within an RDBMS. Synonymous with the terms
+'database', for MySQL; and 'schema', for most other RDBMS(s).
+
+In other words, it's the 'xyz' _thing_ you're connecting to when using any of
+the following L<DSN|DBI/connect>(s):
+
+  dbi:DriverName:xyz at hostname:port
+  dbi:DriverName:database=xyz;host=hostname;port=port
+
 =head2 Inflation
 
 The act of turning database row data into objects in

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/Reading.pod
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/Reading.pod	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/Reading.pod	2009-05-04 03:30:18 UTC (rev 6119)
@@ -34,13 +34,18 @@
 
 =item *
 
-Each method starts with a "head2" statement of it's name.
+Each method starts with a "head2" statement of its name.
 
+Just the plain method name, not an example of how to call it, or a link.
+This is to ensure easy linking to method documentation from other POD.
+
 =item *
 
-The header is followed by a one-item list.
+The header is followed by a two-item list. This contains a description
+of the arguments the method is expected to take, and an indication of
+what the method returns.
 
-The single item provides a list of all possible values for the
+The first item provides a list of all possible values for the
 arguments of the method in order, separated by C<, >, preceeded by the
 text "Arguments: "
 
@@ -70,24 +75,60 @@
 
 =item *
 
+%var - A hashref variable (list of key/value pairs) - rarely used in DBIx::Class.
+
+Reading an argument as a hash variable will consume all subsequent
+method arguments, use with caution.
+
+=item *
+
+ at var - An array variable (list of values).
+
+Reading an argument as a array variable will consume all subsequent
+method arguments, use with caution.
+
+=item *
+
 ? - Optional, should be placed after the argument type and name.
 
+  ## Correct
+  \%myhashref|\@myarrayref?
+
+  ## Wrong
+  \%myhashref?|\@myarrayref
+
+Applies to the entire argument.
+
+Optional arguments can be left out of method calls, unless the caller
+needs to pass in any of the following arguments. In which case the
+caller should pass C<undef> in place of the missing argument.
+
 =item *
 
-| - Alternate argument types.
+| - Alternate argument content types. 
 
+At least one of these must be supplied unless the argument is also
+marked optional.
+
 =back
 
-NOTES:
+The second item starts with the text "Return value:". The remainder of
+the line is either the text "undefined", a text describing the result of
+the method, or a variable with a descriptive name.
 
-If several arguments are optional, it is always possible to pass
-C<undef> as one optional argument in order to skip it and provide a
-value for the following ones. This does not need to be indicated in
-the Arguments line, it is assumed.
+  ## Good examples
+  =item Return value: undefined
+  =item Return value: A schema object
+  =item Return value: $classname
 
-The C<?> for optional arguments always applies to the entire argument
-value, not a particular type or argument.
+  ## Bad examples
+  =item Return value: The names
 
+"undefined" means the method does not deliberately return a value, and
+the caller should not use or rely on anything it does return. (Perl
+functions always return something, usually the result of the last code
+statement, if there is no explicit return statement.)
+
 =item *
 
 The argument list is followed by a single paragraph describing what
@@ -98,6 +139,9 @@
 The description paragraph is followed by another list. Each item in
 the list explains one of the possible argument/type combinations.
 
+This list may be omitted if the author feels that the variable names are
+self-explanatory enough to not require it. Use best judgement.
+
 =item *
 
 The argument list is followed by some examples of how to use the

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/Troubleshooting.pod
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/Troubleshooting.pod	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Manual/Troubleshooting.pod	2009-05-04 03:30:18 UTC (rev 6119)
@@ -47,7 +47,7 @@
 
 L<DBI> version 1.50 and L<DBD::Pg> 1.43 are known to work.
 
-=head2 ... Can't locate object method "source_name" via package ...
+=head2 Can't locate object method "source_name" via package
 
 There's likely a syntax error in the table class referred to elsewhere
 in this error message.  In particular make sure that the package

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Relationship/Accessor.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Relationship/Accessor.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Relationship/Accessor.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -31,11 +31,12 @@
           $rel_info->{cond}, $rel, $self
         );
         if ($rel_info->{attrs}->{undef_on_null_fk}){
-          return unless ref($cond) eq 'HASH';
-          return if grep { not defined } values %$cond;
+          return undef unless ref($cond) eq 'HASH';
+          return undef if grep { not defined $_ } values %$cond;
         }
         my $val = $self->find_related($rel, {}, {});
-        return unless $val;
+        return $val unless $val;  # $val instead of undef so that null-objects can go through
+
         return $self->{_relationship_data}{$rel} = $val;
       }
     };

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Relationship/BelongsTo.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Relationship/BelongsTo.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Relationship/BelongsTo.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -79,12 +79,14 @@
   return 1;
 }
 
-=head1 AUTHORS
+# Attempt to remove the POD so it (maybe) falls off the indexer
 
-Alexander Hartmaier <Alexander.Hartmaier at t-systems.at>
+#=head1 AUTHORS
+#
+#Alexander Hartmaier <Alexander.Hartmaier at t-systems.at>
+#
+#Matt S. Trout <mst at shadowcatsystems.co.uk>
+#
+#=cut
 
-Matt S. Trout <mst at shadowcatsystems.co.uk>
-
-=cut
-
 1;

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultClass/HashRefInflator.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultClass/HashRefInflator.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultClass/HashRefInflator.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -5,7 +5,7 @@
 
 =head1 NAME
 
-DBIx::Class::ResultClass::HashRefInflator
+DBIx::Class::ResultClass::HashRefInflator - Get raw hashrefs from a resultset
 
 =head1 SYNOPSIS
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSet.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSet.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSet.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -102,6 +102,21 @@
     });
   }
 
+=head3 Resolving conditions and attributes
+
+When a resultset is chained from another resultset, conditions and
+attributes with the same keys need resolving.
+
+L</join>, L</prefetch>, L</+select>, L</+as> attributes are merged
+into the existing ones from the original resultset.
+
+The L</where>, L</having> attribute, and any search conditions are
+merged with an SQL C<AND> to the existing condition from the original
+resultset.
+
+All other attributes are overridden by any new ones supplied in the
+search attributes.
+
 =head2 Multiple queries
 
 Since a resultset just defines a query, you can do all sorts of
@@ -264,6 +279,11 @@
 sub search_rs {
   my $self = shift;
 
+  # Special-case handling for (undef, undef).
+  if ( @_ == 2 && !defined $_[1] && !defined $_[0] ) {
+    pop(@_); pop(@_);
+  }
+
   my $attrs = {};
   $attrs = pop(@_) if @_ > 1 and ref $_[$#_] eq 'HASH';
   my $our_attrs = { %{$self->{attrs}} };
@@ -373,19 +393,29 @@
 resultset query.
 
 CAVEAT: C<search_literal> is provided for Class::DBI compatibility and should
-only be used in that context. There are known problems using C<search_literal>
-in chained queries; it can result in bind values in the wrong order.  See
-L<DBIx::Class::Manual::Cookbook/Searching> and
+only be used in that context. C<search_literal> is a convenience method. 
+It is equivalent to calling $schema->search(\[]), but if you want to ensure
+columns are bound correctly, use C<search>.
+
+Example of how to use C<search> instead of C<search_literal>
+
+  my @cds = $cd_rs->search_literal('cdid = ? AND (artist = ? OR artist = ?)', (2, 1, 2));
+  my @cds = $cd_rs->search(\[ 'cdid = ? AND (artist = ? OR artist = ?)', [ 'cdid', 2 ], [ 'artist', 1 ], [ 'artist', 2 ] ]);
+
+
+See L<DBIx::Class::Manual::Cookbook/Searching> and 
 L<DBIx::Class::Manual::FAQ/Searching> for searching techniques that do not
 require C<search_literal>.
 
 =cut
 
 sub search_literal {
-  my ($self, $cond, @vals) = @_;
-  my $attrs = (ref $vals[$#vals] eq 'HASH' ? { %{ pop(@vals) } } : {});
-  $attrs->{bind} = [ @{$self->{attrs}{bind}||[]}, @vals ];
-  return $self->search(\$cond, $attrs);
+  my ($self, $sql, @bind) = @_; 
+  my $attr;
+  if ( @bind && ref($bind[-1]) eq 'HASH' ) {
+    $attr = pop @bind;
+  }
+  return $self->search(\[ $sql, map [ __DUMMY__ => $_ ], @bind ], ($attr || () ));
 }
 
 =head2 find
@@ -830,10 +860,24 @@
 
 For more information, see L<DBIx::Class::Manual::Cookbook>.
 
+This method is deprecated and will be removed in 0.09. Use L</search()>
+instead. An example conversion is:
+
+  ->search_like({ foo => 'bar' });
+
+  # Becomes
+
+  ->search({ foo => { like => 'bar' } });
+
 =cut
 
 sub search_like {
   my $class = shift;
+  carp join ("\n",
+    'search_like() is deprecated and will be removed in 0.09.',
+    'Instead use ->search({ x => { -like => "y%" } })',
+    '(note the outer pair of {}s - they are important!)'
+  );
   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
   my $query = ref $_[0] eq 'HASH' ? { %{shift()} }: {@_};
   $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
@@ -1077,6 +1121,11 @@
 C<< result_source->result_class >> - which in most cases is the name of the 
 L<"table"|DBIx::Class::Manual::Glossary/"ResultSource"> class.
 
+Note that changing the result_class will also remove any components
+that were originally loaded in the source class via
+L<DBIx::Class::ResultSource/load_components>. Any overloaded methods
+in the original source class will not run.
+
 =cut
 
 sub result_class {
@@ -1636,6 +1685,9 @@
 Return Value a L<Data::Page> object for the current resultset. Only makes
 sense for queries with a C<page> attribute.
 
+To get the full count of entries for a paged resultset, call
+C<total_entries> on the L<Data::Page> object.
+
 =cut
 
 sub pager {
@@ -1807,7 +1859,7 @@
   return \%unaliased;
 }
 
-=head2 as_query
+=head2 as_query (EXPERIMENTAL)
 
 =over 4
 
@@ -1821,6 +1873,8 @@
 
 This is generally used as the RHS for a subquery.
 
+B<NOTE>: This feature is still experimental.
+
 =cut
 
 sub as_query { return shift->cursor->as_query(@_) }
@@ -2067,6 +2121,63 @@
   return $self->create($cond);
 }
 
+=head2 update_or_new
+
+=over 4
+
+=item Arguments: \%col_values, { key => $unique_constraint }?
+
+=item Return Value: $rowobject
+
+=back
+
+  $resultset->update_or_new({ col => $val, ... });
+
+First, searches for an existing row matching one of the unique constraints
+(including the primary key) on the source of this resultset. If a row is
+found, updates it with the other given column values. Otherwise, instantiate
+a new result object and return it. The object will not be saved into your storage
+until you call L<DBIx::Class::Row/insert> on it.
+
+Takes an optional C<key> attribute to search on a specific unique constraint.
+For example:
+
+  # In your application
+  my $cd = $schema->resultset('CD')->update_or_new(
+    {
+      artist => 'Massive Attack',
+      title  => 'Mezzanine',
+      year   => 1998,
+    },
+    { key => 'cd_artist_title' }
+  );
+
+  if ($cd->in_storage) {
+      # the cd was updated
+  }
+  else {
+      # the cd is not yet in the database, let's insert it
+      $cd->insert;
+  }
+
+See also L</find>, L</find_or_create> and L<find_or_new>.
+
+=cut
+
+sub update_or_new {
+    my $self  = shift;
+    my $attrs = ( @_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {} );
+    my $cond  = ref $_[0] eq 'HASH' ? shift : {@_};
+
+    my $row = $self->find( $cond, $attrs );
+    if ( defined $row ) {
+        $row->update($cond);
+        return $row;
+    }
+
+    return $self->new_result($cond);
+}
+
 =head2 get_cache
 
 =over 4
@@ -2293,12 +2404,20 @@
   # build columns (as long as select isn't set) into a set of as/select hashes
   unless ( $attrs->{select} ) {
       @colbits = map {
-          ( ref($_) eq 'HASH' ) ? $_
-            : {
-              (
-                  /^\Q${alias}.\E(.+)$/ ? $1
-                  : $_
-                ) => ( /\./ ? $_ : "${alias}.$_" )
+          ( ref($_) eq 'HASH' )
+              ? $_
+              : {
+                  (
+                    /^\Q${alias}.\E(.+)$/ 
+                      ? "$1"
+                      : "$_"
+                  )
+                => 
+                  (
+                    /\./ 
+                      ? "$_" 
+                      : "${alias}.$_"
+                  )
             }
       } ( ref($attrs->{columns}) eq 'ARRAY' ) ? @{ delete $attrs->{columns}} : (delete $attrs->{columns} || $source->columns );
   }
@@ -2555,23 +2674,27 @@
 
 =over 4
 
-=item Value: ($order_by | \@order_by)
+=item Value: ( $order_by | \@order_by | \%order_by )
 
 =back
 
-Which column(s) to order the results by. This is currently passed
-through directly to SQL, so you can give e.g. C<year DESC> for a
-descending order on the column `year'.
+Which column(s) to order the results by. If a single column name, or
+an arrayref of names is supplied, the argument is passed through
+directly to SQL. The hashref syntax allows for connection-agnostic
+specification of ordering direction:
 
-Please note that if you have C<quote_char> enabled (see
-L<DBIx::Class::Storage::DBI/connect_info>) you will need to do C<\'year DESC' > to
-specify an order. (The scalar ref causes it to be passed as raw sql to the DB,
-so you will need to manually quote things as appropriate.)
+ For descending order:
 
-If your L<SQL::Abstract> version supports it (>=1.50), you can also use
-C<{-desc => 'year'}>, which takes care of the quoting for you. This is the
-recommended syntax.
+  order_by => { -desc => [qw/col1 col2 col3/] }
 
+ For explicit ascending order:
+
+  order_by => { -asc => 'col' }
+
+The old scalarref syntax (i.e. order_by => \'year DESC') is still
+supported, although you are strongly encouraged to use the hashref
+syntax as outlined above.
+
 =head2 columns
 
 =over 4
@@ -2851,6 +2974,10 @@
 
 If L<rows> attribute is not specified it defualts 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
+C<total_entries> on it.
+
 =head2 rows
 
 =over 4

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSetColumn.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSetColumn.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSetColumn.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -38,7 +38,7 @@
   $class = ref $class if ref $class;
   my $new_parent_rs = $rs->search_rs; # we don't want to mess up the original, so clone it
   my $attrs = $new_parent_rs->_resolved_attrs;
-  $new_parent_rs->{attrs}->{$_} = undef for qw(prefetch include_columns +select +as); # prefetch, include_columns, +select, +as cause additional columns to be fetched
+  $new_parent_rs->{attrs}->{prefetch} = undef; # prefetch cause additional columns to be fetched
 
   # If $column can be found in the 'as' list of the parent resultset, use the
   # corresponding element of its 'select' list (to keep any custom column
@@ -54,7 +54,7 @@
   return $new;
 }
 
-=head2 as_query
+=head2 as_query (EXPERIMENTAL)
 
 =over 4
 
@@ -68,6 +68,8 @@
 
 This is generally used as the RHS for a subquery.
 
+B<NOTE>: This feature is still experimental.
+
 =cut
 
 sub as_query { return shift->_resultset->as_query }

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSource/View.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSource/View.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSource/View.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -46,7 +46,7 @@
 Deploying the view does B<not> translate it between different database
 syntaxes, so be careful what you write in your view SQL.
 
-Virtual views (L</is_virtual> unset or false), are assumed to not
+Virtual views (L</is_virtual> true), are assumed to not
 exist in your database as a real view. The L</view_definition> in this
 case replaces the view name in a FROM clause in a subselect.
 
@@ -54,13 +54,13 @@
 
 =over
 
-=item is_virtual set to true
+=item is_virtual set to false
 
   $schema->resultset('Year2000CDs')->all();
 
   SELECT cdid, artist, title FROM year2000cds me
 
-=item is_virtual set to false
+=item is_virtual set to true
 
   $schema->resultset('Year2000CDs')->all();
 
@@ -115,6 +115,8 @@
 
 Jess Robinson <castaway at desert-island.me.uk>
 
+Wallace Reis <wreis at cpan.org>
+
 =head1 LICENSE
 
 You may distribute this code under the same terms as Perl itself.

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSource.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSource.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSource.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -125,9 +125,13 @@
 =item default_value
 
 Set this to the default value which will be inserted into a column
-by the database. Can contain either a value or a function. This is
-currently only used by L<DBIx::Class::Schema/deploy>.
+by the database. Can contain either a value or a function (use a
+reference to a scalar e.g. C<\'now()'> if you want a function). This
+is currently only used by L<DBIx::Class::Schema/deploy>.
 
+See the note on L<DBIx::Class::Row/new> for more information about possible
+issues related to db-side default values.
+
 =item sequence
 
 Set this on a primary key column to the name of the sequence used to
@@ -1085,12 +1089,16 @@
   $seen ||= {};
   $force_left ||= { force => 0 };
   if (ref $join eq 'ARRAY') {
-    return map { $self->resolve_join($_, $alias, $seen) } @$join;
+    return
+      map {
+        local $force_left->{force} = $force_left->{force};
+        $self->resolve_join($_, $alias, $seen, $force_left);
+      } @$join;
   } elsif (ref $join eq 'HASH') {
     return
       map {
         my $as = ($seen->{$_} ? $_.'_'.($seen->{$_}+1) : $_);
-        local $force_left->{force};
+        local $force_left->{force} = $force_left->{force};
         (
           $self->resolve_join($_, $alias, $seen, $force_left),
           $self->related_source($_)->resolve_join(
@@ -1196,7 +1204,11 @@
         #warn "$self $k $for $v";
         unless ($for->has_column_loaded($v)) {
           if ($for->in_storage) {
-            $self->throw_exception("Column ${v} not loaded on ${for} trying to resolve relationship");
+            $self->throw_exception(
+              "Column ${v} not loaded or not passed to new() prior to insert()"
+                ." on ${for} trying to resolve relationship (maybe you forgot "
+                  ."to call ->reload_from_storage to get defaults from the db)"
+            );
           }
           return $UNRESOLVABLE_CONDITION;
         }

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSourceHandle.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSourceHandle.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/ResultSourceHandle.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -20,7 +20,7 @@
 
 =head1 NAME
 
-DBIx::Class::ResultSourceHandle
+DBIx::Class::ResultSourceHandle - Decouple Rows/ResultSets objects from their Source objects
 
 =head1 DESCRIPTION
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Row.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Row.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Row.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -8,6 +8,10 @@
 use Scalar::Util ();
 use Scope::Guard;
 
+###
+### Internal method
+### Do not use
+###
 BEGIN {
   *MULTICREATE_DEBUG =
     $ENV{DBIC_MULTICREATE_DEBUG}
@@ -73,6 +77,23 @@
 
 For a more involved explanation, see L<DBIx::Class::ResultSet/create>.
 
+Please note that if a value is not passed to new, no value will be sent
+in the SQL INSERT call, and the column will therefore assume whatever
+default value was specified in your database. While DBIC will retrieve the
+value of autoincrement columns, it will never make an explicit database
+trip to retrieve default values assigned by the RDBMS. You can explicitly
+request that all values be fetched back from the database by calling
+L</discard_changes>, or you can supply an explicit C<undef> to columns
+with NULL as the default, and save yourself a SELECT.
+
+ CAVEAT:
+
+ The behavior described above will backfire if you use a foreign key column
+ with a database-defined default. If you call the relationship accessor on
+ an object that doesn't have a set value for the FK column, DBIC will throw
+ an exception, as it has no way of knowing the PK of the related object (if
+ there is one).
+
 =cut
 
 ## It needs to store the new objects somewhere, and call insert on that list later when insert is called on this object. We may need an accessor for these so the user can retrieve them, if just doing ->new().
@@ -960,6 +981,9 @@
 Reblessing can also be done more easily by setting C<result_class> in
 your Result class. See L<DBIx::Class::ResultSource/result_class>.
 
+Different types of results can also be created from a particular
+L<DBIx::Class::ResultSet>, see L<DBIx::Class::ResultSet/result_class>.
+
 =cut
 
 sub inflate_result {
@@ -1005,7 +1029,6 @@
         $fetched = $pre_source->result_class->inflate_result(
                       $pre_source, @{$pre_val});
       }
-      $new->related_resultset($pre)->set_cache([ $fetched ]);
       my $accessor = $source->relationship_info($pre)->{attrs}{accessor};
       $class->throw_exception("No accessor for prefetched $pre")
        unless defined $accessor;
@@ -1016,6 +1039,7 @@
       } else {
        $class->throw_exception("Prefetch not supported with accessor '$accessor'");
       }
+      $new->related_resultset($pre)->set_cache([ $fetched ]);
     }
   }
   return $new;

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Schema/Versioned.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Schema/Versioned.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Schema/Versioned.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -533,7 +533,6 @@
   $db_tr->producer($db);
   my $dbic_tr = SQL::Translator->new;
   $dbic_tr->parser('SQL::Translator::Parser::DBIx::Class');
-  $dbic_tr = $self->storage->configure_sqlt($dbic_tr, $db);
   $dbic_tr->data($self);
   $dbic_tr->producer($db);
 
@@ -614,7 +613,7 @@
 
 =head1 AUTHORS
 
-Jess Robinson <castaway at desert-island.demon.co.uk>
+Jess Robinson <castaway at desert-island.me.uk>
 Luke Saunders <luke at shadowcatsystems.co.uk>
 
 =head1 LICENSE

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Schema.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Schema.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Schema.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -157,6 +157,21 @@
   return $name;
 }
 
+# Finds all modules in the supplied namespace, or if omitted in the
+# namespace of $class. Untaints all findings as they can be assumed
+# to be safe
+sub _findallmod {
+  my $proto = shift;
+  my $ns = shift || ref $proto || $proto;
+
+  my @mods = Module::Find::findallmod($ns);
+
+  # try to untaint module names. mods where this fails
+  # are left alone so we don't have to change the old behavior
+  no locale; # localized \w doesn't untaint expression
+  return map { $_ =~ m/^( (?:\w+::)* \w+ )$/x ? $1 : $_ } @mods;
+}
+
 # returns a hash of $shortname => $fullname for every package
 #  found in the given namespaces ($shortname is with the $fullname's
 #  namespace stripped off)
@@ -168,7 +183,7 @@
     push(
       @results_hash,
       map { (substr($_, length "${namespace}::"), $_) }
-      Module::Find::findallmod($namespace)
+      $class->_findallmod($namespace)
     );
   }
 
@@ -314,7 +329,7 @@
     }
   } else {
     my @comp = map { substr $_, length "${class}::"  }
-                 Module::Find::findallmod($class);
+                 $class->_findallmod;
     $comps_for{$class} = \@comp;
   }
 
@@ -325,13 +340,6 @@
     foreach my $prefix (keys %comps_for) {
       foreach my $comp (@{$comps_for{$prefix}||[]}) {
         my $comp_class = "${prefix}::${comp}";
-        { # try to untaint module name. mods where this fails
-          # are left alone so we don't have to change the old behavior
-          no locale; # localized \w doesn't untaint expression
-          if ( $comp_class =~ m/^( (?:\w+::)* \w+ )$/x ) {
-            $comp_class = $1;
-          }
-        }
         $class->ensure_class_loaded($comp_class);
 
         my $snsub = $comp_class->can('source_name');
@@ -475,6 +483,12 @@
 C<connect> does not. C<connect> wraps it's arguments in an arrayref
 before passing them to C<connect_info>.
 
+=head3 Overloading
+
+C<connect> is a convenience method. It is equivalent to calling
+$schema->clone->connection(@connectinfo). To write your own overloaded
+version, overload L</connection> instead.
+
 =cut
 
 sub connect { shift->clone->connection(@_) }
@@ -603,7 +617,7 @@
   $self->storage->txn_do(@_);
 }
 
-=head2 txn_scope_guard (EXPERIMENTAL)
+=head2 txn_scope_guard
 
 Runs C<txn_scope_guard> on the schema's storage. See 
 L<DBIx::Class::Storage/txn_scope_guard>.
@@ -752,7 +766,10 @@
 data in-place on the Schema class. You should probably be calling
 L</connect> to get a proper Schema object instead.
 
+=head3 Overloading
 
+Overload C<connection> to change the behaviour of C<connect>.
+
 =cut
 
 sub connection {
@@ -990,7 +1007,9 @@
 
 See L<SQL::Translator/METHODS> for a list of values for C<$sqlt_args>. The most
 common value for this would be C<< { add_drop_table => 1, } >> to have the SQL
-produced include a DROP TABLE statement for each table created.
+produced include a DROP TABLE statement for each table created. For quoting
+purposes use C<producer_options> value with C<quote_table_names> and
+C<quote_field_names>.
 
 Additionally, the DBIx::Class parser accepts a C<sources> parameter as a hash 
 ref or an array ref, containing a list of source to deploy. If present, then 
@@ -1248,24 +1267,33 @@
 sub _register_source {
   my ($self, $moniker, $source, $params) = @_;
 
+  my $orig_source = $source;
+
   $source = $source->new({ %$source, source_name => $moniker });
+  $source->schema($self);
+  weaken($source->{schema}) if ref($self);
 
+  my $rs_class = $source->result_class;
+
   my %reg = %{$self->source_registrations};
   $reg{$moniker} = $source;
   $self->source_registrations(\%reg);
 
-  $source->schema($self);
-  weaken($source->{schema}) if ref($self);
   return if ($params->{extra});
+  return unless defined($rs_class) && $rs_class->can('result_source_instance');
 
-  if ($source->result_class) {
-    my %map = %{$self->class_mappings};
-    if (exists $map{$source->result_class}) {
-      warn $source->result_class . ' already has a source, use register_extra_source for additional sources';
-    }
-    $map{$source->result_class} = $moniker;
-    $self->class_mappings(\%map);
+  my %map = %{$self->class_mappings};
+  if (
+    exists $map{$rs_class}
+      and
+    $map{$rs_class} ne $moniker
+      and
+    $rs_class->result_source_instance ne $orig_source
+  ) {
+    carp "$rs_class already has a source, use register_extra_source for additional sources";
   }
+  $map{$rs_class} = $moniker;
+  $self->class_mappings(\%map);
 }
 
 sub _unregister_source {

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI/NoBindVars.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI/NoBindVars.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI/NoBindVars.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -38,6 +38,9 @@
 
 sub _prep_for_execute {
   my $self = shift;
+
+  my ($op, $extra_bind, $ident) = @_;
+
   my ($sql, $bind) = $self->next::method(@_);
 
   # stringify args, quote via $dbh, and manually insert
@@ -46,12 +49,14 @@
   my $new_sql;
 
   foreach my $bound (@$bind) {
-    shift @$bound;
+    my $col = shift @$bound;
+    my $datatype = 'FIXME!!!';
     foreach my $data (@$bound) {
         if(ref $data) {
             $data = ''.$data;
         }
-        $new_sql .= shift(@sql_part) . $self->_dbh->quote($data);
+        $data = $self->_dbh->quote($data);
+        $new_sql .= shift(@sql_part) . $data;
     }
   }
   $new_sql .= join '', @sql_part;

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI/ODBC/ACCESS.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI/ODBC/ACCESS.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI/ODBC/ACCESS.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -2,8 +2,6 @@
 use strict;
 use warnings;
 
-use Data::Dump qw( dump );
-
 use DBI;
 use base qw/DBIx::Class::Storage::DBI/;
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI/Replicated.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI/Replicated.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI/Replicated.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -313,7 +313,6 @@
 
     reload_row
     _prep_for_execute
-    configure_sqlt
     
   /],
 );

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI/SQLite.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI/SQLite.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI/SQLite.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -45,21 +45,6 @@
   return $backupfile;
 }
 
-sub disconnect {
-
-  # As described in this node http://www.perlmonks.org/?node_id=666210
-  # there seems to be no sane way to ->disconnect a SQLite database with
-  # cached statement handles. As per mst we just zap the cache and 
-  # proceed as normal.
-
-  my $self = shift;
-  if ($self->connected) {
-    $self->_dbh->{CachedKids} = {};
-    $self->next::method (@_);
-  }
-}
-
-
 1;
 
 =head1 NAME

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/DBI.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1239,7 +1239,7 @@
 
 sub _dbh_execute {
   my ($self, $dbh, $op, $extra_bind, $ident, $bind_attributes, @args) = @_;
-  
+
   my ($sql, $bind) = $self->_prep_for_execute($op, $extra_bind, $ident, \@args);
 
   $self->_query_start( $sql, @$bind );
@@ -1286,20 +1286,22 @@
   my $ident = $source->from; 
   my $bind_attributes = $self->source_bind_attributes($source);
 
+  my $updated_cols = {};
+
   $self->ensure_connected;
   foreach my $col ( $source->columns ) {
     if ( !defined $to_insert->{$col} ) {
       my $col_info = $source->column_info($col);
 
       if ( $col_info->{auto_nextval} ) {
-        $to_insert->{$col} = $self->_sequence_fetch( 'nextval', $col_info->{sequence} || $self->_dbh_get_autoinc_seq($self->dbh, $source) );
+        $updated_cols->{$col} = $to_insert->{$col} = $self->_sequence_fetch( 'nextval', $col_info->{sequence} || $self->_dbh_get_autoinc_seq($self->dbh, $source) );
       }
     }
   }
 
   $self->_execute('insert' => [], $source, $bind_attributes, $to_insert);
 
-  return $to_insert;
+  return $updated_cols;
 }
 
 ## Still not quite perfect, and EXPERIMENTAL
@@ -1384,14 +1386,6 @@
   my ($self, $ident, $select, $condition, $attrs) = @_;
   my $order = $attrs->{order_by};
 
-  if (ref $condition eq 'SCALAR') {
-    my $unwrap = ${$condition};
-    if ($unwrap =~ s/ORDER BY (.*)$//i) {
-      $order = $1;
-      $condition = \$unwrap;
-    }
-  }
-
   my $for = delete $attrs->{for};
   my $sql_maker = $self->sql_maker;
   $sql_maker->{for} = $for;
@@ -1574,9 +1568,18 @@
 =cut
 
 sub _dbh_last_insert_id {
-    my ($self, $dbh, $source, $col) = @_;
-    # XXX This is a SQLite-ism as a default... is there a DBI-generic way?
-    $dbh->func('last_insert_rowid');
+    # All Storage's need to register their own _dbh_last_insert_id
+    # the old SQLite-based method was highly inappropriate
+
+    my $self = shift;
+    my $class = ref $self;
+    $self->throw_exception (<<EOE);
+
+No _dbh_last_insert_id() method found in $class.
+Since the method of obtaining the autoincrement id of the last insert
+operation varies greatly between different databases, this method must be
+individually implemented for every storage class.
+EOE
 }
 
 sub last_insert_id {
@@ -1659,7 +1662,6 @@
 
   foreach my $db (@$databases) {
     $sqlt->reset();
-    $sqlt = $self->configure_sqlt($sqlt, $db);
     $sqlt->{schema} = $sqlt_schema;
     $sqlt->producer($db);
 
@@ -1705,7 +1707,6 @@
       $t->debug( 0 );
       $t->trace( 0 );
       $t->parser( $db )                       or die $t->error;
-      $t = $self->configure_sqlt($t, $db);
       my $out = $t->translate( $prefilename ) or die $t->error;
       $source_schema = $t->schema;
       unless ( $source_schema->name ) {
@@ -1723,7 +1724,6 @@
       $t->debug( 0 );
       $t->trace( 0 );
       $t->parser( $db )                    or die $t->error;
-      $t = $self->configure_sqlt($t, $db);
       my $out = $t->translate( $filename ) or die $t->error;
       $dest_schema = $t->schema;
       $dest_schema->name( $filename )
@@ -1743,17 +1743,6 @@
   }
 }
 
-sub configure_sqlt() {
-  my $self = shift;
-  my $tr = shift;
-  my $db = shift || $self->sqlt_type;
-  if ($db eq 'PostgreSQL') {
-    $tr->quote_table_names(0);
-    $tr->quote_field_names(0);
-  }
-  return $tr;
-}
-
 =head2 deployment_statements
 
 =over 4

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/TxnScopeGuard.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/TxnScopeGuard.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage/TxnScopeGuard.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,5 +1,4 @@
-package # Hide from pause for now - till we get it working
-  DBIx::Class::Storage::TxnScopeGuard;
+package DBIx::Class::Storage::TxnScopeGuard;
 
 use strict;
 use warnings;
@@ -47,7 +46,7 @@
 
 =head1 NAME
 
-DBIx::Class::Storage::TxnScopeGuard - Experimental
+DBIx::Class::Storage::TxnScopeGuard - Scope-based transaction handling
 
 =head1 SYNOPSIS
 
@@ -70,14 +69,15 @@
 
 =head2 new
 
-Creating an instance of this class will start a new transaction. Expects a
+Creating an instance of this class will start a new transaction (by
+implicitly calling L<DBIx::Class::Storage/txn_begin>. Expects a
 L<DBIx::Class::Storage> object as its only argument.
 
 =head2 commit
 
 Commit the transaction, and stop guarding the scope. If this method is not
-called (i.e. an exception is thrown) and this object goes out of scope then
-the transaction is rolled back.
+called and this object goes out of scope (i.e. an exception is thrown) then
+the transaction is rolled back, via L<DBIx::Class::Storage/txn_rollback>
 
 =cut
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class/Storage.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -299,21 +299,25 @@
 
 =for comment
 
-=head2 txn_scope_guard (EXPERIMENTAL)
+=head2 txn_scope_guard
 
-An alternative way of using transactions to C<txn_do>:
+An alternative way of transaction handling based on
+L<DBIx::Class::Storage::TxnScopeGuard>:
 
- my $txn = $storage->txn_scope_guard;
+ my $txn_guard = $storage->txn_scope_guard;
 
  $row->col1("val1");
  $row->update;
 
- $txn->commit;
+ $txn_guard->commit;
 
-If a exception occurs, the transaction will be rolled back. This is still very
-experiemental, and we are not 100% sure it is working right when nested. The
-onus is on you as the user to make sure you dont forget to call
-$C<$txn->commit>.
+If an exception occurs, or the guard object otherwise leaves the scope
+before C<< $txn_guard->commit >> is called, the transaction will be rolled
+back by an explicit L</txn_rollback> call. In essence this is akin to
+using a L</txn_begin>/L</txn_commit> pair, without having to worry
+about calling L</txn_rollback> at the right places. Note that since there
+is no defined code closure, there will be no retries and other magic upon
+database disconnection. If you need such functionality see L</txn_do>.
 
 =cut
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/DBIx/Class.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -24,7 +24,7 @@
 # i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports
 # brain damage and presumably various other packaging systems too
 
-$VERSION = '0.08099_06';
+$VERSION = '0.08102';
 
 $VERSION = eval $VERSION; # numify for warning-free dev releases
 
@@ -207,6 +207,8 @@
 
 ank: Andres Kievsky
 
+arcanez: Justin Hunter <justin.d.hunter at gmail.com>
+
 ash: Ash Berlin <ash at cpan.org>
 
 bert: Norbert Csongradi <bert at cpan.org>
@@ -219,8 +221,6 @@
 
 caelum: Rafael Kitover <rkitover at cpan.org>
 
-captainL: Luke Saunders <luke.saunders at gmail.com>
-
 castaway: Jess Robinson
 
 claco: Christopher H. Laco
@@ -243,6 +243,10 @@
 
 groditi: Guillermo Roditi <groditi at cpan.org>
 
+ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari at ilmari.org>
+
+jasonmay: Jason May <jason.a.may at gmail.com>
+
 jesper: Jesper Krogh
 
 jgoulah: John Goulah <jgoulah at cpan.org>
@@ -257,6 +261,8 @@
 
 konobi: Scott McWhirter
 
+lukes: Luke Saunders <luke.saunders at gmail.com>
+
 marcus: Marcus Ramberg <mramberg at cpan.org>
 
 mattlaw: Matt Lawrence
@@ -269,6 +275,8 @@
 
 ningu: David Kamholz <dkamholz at cpan.org>
 
+norbi: Norbert Buchmuller <norbi at nix.hu>
+
 Numa: Dan Sully <daniel at cpan.org>
 
 oyse: Øystein Torget <oystein.torget at dnv.com>
@@ -279,6 +287,8 @@
 
 perigrin: Chris Prather <chris at prather.org>
 
+peter: Peter Collingbourne <peter at pcc.me.uk>
+
 phaylon: Robert Sedlacek <phaylon at dunkelheit.at>
 
 plu: Johannes Plunien <plu at cpan.org>
@@ -301,6 +311,8 @@
 
 semifor: Marc Mims <marc at questright.com>
 
+solomon: Jared Johnson <jaredj at nmgi.com>
+
 sszabo: Stephan Szabo <sszabo at bigpanda.com>
 
 teejay : Aaron Trevena <teejay at cpan.org>
@@ -317,10 +329,10 @@
 
 willert: Sebastian Willert <willert at cpan.org>
 
+wreis: Wallace Reis <wreis at cpan.org>
+
 zamolxes: Bogdan Lucaciu <bogdan at wiz.ro>
 
-norbi: Norbert Buchmuller <norbi at nix.hu>
-
 =head1 LICENSE
 
 You may distribute this code under the same terms as Perl itself.

Modified: DBIx-Class/0.08/branches/hierarchical-queries/lib/SQL/Translator/Parser/DBIx/Class.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/lib/SQL/Translator/Parser/DBIx/Class.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/lib/SQL/Translator/Parser/DBIx/Class.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -246,6 +246,8 @@
         if ($source->result_class->can('sqlt_deploy_hook')) {
           $source->result_class->sqlt_deploy_hook($view);
         }
+
+        $source->_invoke_sqlt_deploy_hook($view);
     }
 
     if ($dbicschema->can('sqlt_deploy_hook')) {
@@ -291,14 +293,14 @@
 interrogates the columns, and stuffs it all in an $sqlt_schema object.
 
 It's primary use is in deploying database layouts described as a set
-of L<DBIx::Class> classes, to a database. To do this, see the
-L<DBIx::Class::Schema/deploy> method.
+of L<DBIx::Class> classes, to a database. To do this, see
+L<DBIx::Class::Schema/deploy>.
 
 This can also be achieved by having DBIx::Class export the schema as a
 set of SQL files ready for import into your database, or passed to
 other machines that need to have your application installed but don't
-have SQL::Translator installed. To do this see the
-L<DBIx::Class::Schema/create_ddl_dir> method.
+have SQL::Translator installed. To do this see
+L<DBIx::Class::Schema/create_ddl_dir>.
 
 =head1 SEE ALSO
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/03podcoverage.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/03podcoverage.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/03podcoverage.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -44,6 +44,11 @@
             qw(setup_connection_class)
         ]
     },
+    'DBIx::Class::Storage::DBI::Sybase' => {
+        ignore => [
+            qw/should_quote_data_type/,
+        ]
+    },
     'DBIx::Class::CDBICompat::AccessorMapping'          => { skip => 1 },
     'DBIx::Class::CDBICompat::AbstractSearch' => {
         ignore => [qw(search_where)]

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/04dont_break_c3.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/04dont_break_c3.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/04dont_break_c3.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -4,6 +4,7 @@
 
 use strict;
 use Test::More tests => 2;
+use MRO::Compat;
 
 {
 package AAA;
@@ -26,8 +27,8 @@
 __PACKAGE__->inject_base( __PACKAGE__, 'DBIx::Class::Core' );
 }
 
-eval { Class::C3::calculateMRO('BBB'); };
+eval { mro::get_linear_isa('BBB'); };
 ok (! $@, "Correctly skipped injecting a direct parent of class BBB");
 
-eval { Class::C3::calculateMRO('CCC'); };
+eval { mro::get_linear_isa('CCC'); };
 ok (! $@, "Correctly skipped injecting an indirect parent of class BBB");

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/100extra_source.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/100extra_source.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/100extra_source.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -12,7 +12,7 @@
     use base qw/DBIx::Class::ResultSource::Table/;
 }
 
-plan tests => 3;
+plan tests => 4;
 
 my $schema = DBICTest->init_schema();
 my $artist_source = $schema->source('Artist');
@@ -36,6 +36,12 @@
 }
 
 {
+  my $source = $schema->source('DBICTest::Artist');
+  $schema->register_source($source->source_name, $source);
+  is($warn, '', "re-registering an existing source under the same name causes no errors");
+}
+
+{
   my $new_source_name = 'Artist->preview(artist_preview)';
   $schema->register_source( $new_source_name => $new_source );
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/19quotes.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/19quotes.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/19quotes.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -19,7 +19,7 @@
 use_ok('DBIC::DebugObj');
 my $schema = DBICTest->init_schema();
 
-diag('Testing against ' . join(' ', map { $schema->storage->dbh->get_info($_) } qw/17 18/));
+#diag('Testing against ' . join(' ', map { $schema->storage->dbh->get_info($_) } qw/17 18/));
 
 $schema->storage->sql_maker->quote_char('`');
 $schema->storage->sql_maker->name_sep('.');

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/19quotes_newstyle.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/19quotes_newstyle.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/19quotes_newstyle.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -19,7 +19,7 @@
 
 my $schema = DBICTest->init_schema();
 
-diag('Testing against ' . join(' ', map { $schema->storage->dbh->get_info($_) } qw/17 18/));
+#diag('Testing against ' . join(' ', map { $schema->storage->dbh->get_info($_) } qw/17 18/));
 
 my $dsn = $schema->storage->_dbi_connect_info->[0];
 $schema->connection(

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/33storage_reconnect.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/33storage_reconnect.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/33storage_reconnect.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -21,12 +21,11 @@
 
 # Disconnect the dbh, and be sneaky about it
 # Also test if DBD::SQLite finaly knows how to ->disconnect properly
-TODO: {
-    local $TODO = 'SQLite is evil/braindead. Once this test starts passing, remove the related atrocity from DBIx::Class::Storage::DBI::SQLite';
-    my $w;
-    local $SIG{__WARN__} = sub { $w = shift };
-    $schema->storage->_dbh->disconnect;
-    ok ($w !~ /active statement handles/, 'SQLite can disconnect properly \o/');
+{
+  my $w;
+  local $SIG{__WARN__} = sub { $w = shift };
+  $schema->storage->_dbh->disconnect;
+  ok ($w !~ /active statement handles/, 'SQLite can disconnect properly');
 }
 
 # Try the operation again - What should happen here is:

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/39load_namespaces_rt41083.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/39load_namespaces_rt41083.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/39load_namespaces_rt41083.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -2,41 +2,65 @@
 
 use strict;
 use warnings;
-use Test::More;
 
 use lib 't/lib';
+use Test::More tests => 8;
 
-plan tests => 4;
-
 sub _chk_warning {
-	defined $_[0]? 
-		$_[0] !~ qr/We found ResultSet class '([^']+)' for '([^']+)', but it seems that you had already set '([^']+)' to use '([^']+)' instead/ :
-		1
+  defined $_[0]?
+    $_[0] !~ qr/We found ResultSet class '([^']+)' for '([^']+)', but it seems that you had already set '([^']+)' to use '([^']+)' instead/ :
+    1
 }
 
-my $warnings;
-eval {
+sub _chk_extra_sources_warning {
+  my $p = qr/already has a source, use register_extra_source for additional sources/;
+  defined $_[0]? $_[0] !~ /$p/ : 1;
+}
+
+sub _verify_sources {
+  my @monikers = @_;
+  is_deeply (
+    [ sort DBICNSTest::RtBug41083->sources ],
+    \@monikers,
+    'List of resultsource registrations',
+  );
+}
+
+{
+  my $warnings;
+  eval {
     local $SIG{__WARN__} = sub { $warnings .= shift };
     package DBICNSTest::RtBug41083;
     use base 'DBIx::Class::Schema';
     __PACKAGE__->load_namespaces(
-	result_namespace => 'Schema_A',
-	resultset_namespace => 'ResultSet_A',
-	default_resultset_class => 'ResultSet'
+      result_namespace => 'Schema_A',
+      resultset_namespace => 'ResultSet_A',
+      default_resultset_class => 'ResultSet'
     );
-};
-ok(!$@) or diag $@;
-ok(_chk_warning($warnings), 'expected no complaint');
+  };
 
-eval {
+  ok(!$@) or diag $@;
+  ok(_chk_warning($warnings), 'expected no resultset complaint');
+  ok(_chk_extra_sources_warning($warnings), 'expected no extra sources complaint') or diag($warnings);
+
+  _verify_sources (qw/A A::Sub/);
+}
+
+{
+  my $warnings;
+  eval {
     local $SIG{__WARN__} = sub { $warnings .= shift };
     package DBICNSTest::RtBug41083;
     use base 'DBIx::Class::Schema';
     __PACKAGE__->load_namespaces(
-	result_namespace => 'Schema',
-	resultset_namespace => 'ResultSet',
-	default_resultset_class => 'ResultSet'
+      result_namespace => 'Schema',
+      resultset_namespace => 'ResultSet',
+      default_resultset_class => 'ResultSet'
     );
-};
-ok(!$@) or diag $@;
-ok(_chk_warning($warnings), 'expected no complaint') or diag $warnings;
+  };
+  ok(!$@) or diag $@;
+  ok(_chk_warning($warnings), 'expected no resultset complaint') or diag $warnings;
+  ok(_chk_extra_sources_warning($warnings), 'expected no extra sources complaint') or diag($warnings);
+
+  _verify_sources (qw/A A::Sub Foo Foo::Sub/);
+}

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/54taint.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/54taint.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/54taint.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -5,29 +5,41 @@
 use strict;
 use warnings;
 
-our @plan;
+use Test::More;
+BEGIN { plan tests => 7 }
 
-BEGIN {
-  eval "require Module::Find;";
-  @plan = $@ ? ( skip_all => 'Could not load Module::Find' )
-    : ( tests => 2 );
-}
+package DBICTest::Taint::Classes;
 
-package DBICTest::Plain;
+use Test::More;
+use Test::Exception;
 
-# Use the Plain test class namespace to avoid the need for a
-# new test infrastructure. If invalid classes will be introduced to
-# 't/lib/DBICTest/Plain/' someday, this has to be reworked.
-
 use lib qw(t/lib);
+use base qw/DBIx::Class::Schema/;
 
-use Test::More @plan;
+lives_ok (sub {
+  __PACKAGE__->load_classes(qw/Manual/);
+  ok( __PACKAGE__->source('Manual'), 'The Classes::Manual source has been registered' );
+  __PACKAGE__->_unregister_source (qw/Manual/);
+}, 'Loading classes with explicit load_classes worked in taint mode' );
 
+lives_ok (sub {
+  __PACKAGE__->load_classes();
+  ok( __PACKAGE__->source('Auto'), 'The Classes::Auto source has been registered' );
+  ok( __PACKAGE__->source('Auto'), 'The Classes::Manual source has been re-registered' );
+}, 'Loading classes with Module::Find/load_classes worked in taint mode' );
+
+
+package DBICTest::Taint::Namespaces;
+
+use Test::More;
+use Test::Exception;
+
+use lib qw(t/lib);
 use base qw/DBIx::Class::Schema/;
 
-eval{ __PACKAGE__->load_classes() };
-cmp_ok( $@, 'eq', '',
-        'Loading classes with Module::Find worked in taint mode' );
-ok( __PACKAGE__->source('Test'), 'The Plain::Test source has been registered' );
+lives_ok (sub {
+  __PACKAGE__->load_namespaces();
+  ok( __PACKAGE__->source('Test'), 'The Namespaces::Test source has been registered' );
+}, 'Loading classes with Module::Find/load_namespaces worked in taint mode' );
 
 1;

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/63register_class.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/63register_class.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/63register_class.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,19 +1,14 @@
 use strict;
 use warnings;  
 
-use Test::More tests => 3;
+use Test::More tests => 2;
 use lib qw(t/lib);
 use DBICTest;
 use DBICTest::Schema;
 use DBICTest::Schema::Artist;
 
 DBICTest::Schema::Artist->source_name('MyArtist');
-{
-    my $w;
-    local $SIG{__WARN__} = sub { $w = shift };
-    DBICTest::Schema->register_class('FooA', 'DBICTest::Schema::Artist');
-    like ($w, qr/use register_extra_source/, 'Complain about using register_class on an already-registered class');
-}
+DBICTest::Schema->register_class('FooA', 'DBICTest::Schema::Artist');
 
 my $schema = DBICTest->init_schema();
 

Added: DBIx-Class/0.08/branches/hierarchical-queries/t/63register_source.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/63register_source.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/63register_source.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -0,0 +1,18 @@
+use strict;
+use warnings;
+
+use Test::Exception tests => 1;
+use lib qw(t/lib);
+use DBICTest;
+use DBICTest::Schema;
+use DBIx::Class::ResultSource::Table;
+
+my $schema = DBICTest->init_schema();
+
+my $foo = DBIx::Class::ResultSource::Table->new({ name => "foo" });
+my $bar = DBIx::Class::ResultSource::Table->new({ name => "bar" });
+
+lives_ok {
+    $schema->register_source(foo => $foo);
+    $schema->register_source(bar => $bar);
+} 'multiple classless sources can be registered';

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/64db.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/64db.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/64db.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -64,7 +64,12 @@
       'rank' => {
           'data_type' => 'integer',
           'is_nullable' => 0,
+          'default_value' => '13',
       },
+      'charfield' => {
+          'data_type' => 'char',
+          'is_nullable' => 1,
+      },
     },
     'Correctly retrieve column info (mixed null and non-null columns)'
   );

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/66relationship.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/66relationship.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/66relationship.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -8,7 +8,7 @@
 
 my $schema = DBICTest->init_schema();
 
-plan tests => 70;
+plan tests => 74;
 
 # has_a test
 my $cd = $schema->resultset("CD")->find(4);
@@ -35,10 +35,15 @@
 if ($INC{'DBICTest/HelperRels.pm'}) {
   $artist->add_to_cds({ title => 'Big Flop', year => 2005 });
 } else {
-  $artist->create_related( 'cds', {
+  my $big_flop = $artist->create_related( 'cds', {
       title => 'Big Flop',
       year => 2005,
   } );
+
+ SKIP:{
+    skip "Can't fix right now", 1 if $DBIx::Class::VERSION < 0.09;
+    lives_ok { $big_flop->genre} "Don't throw exception when col is not loaded after insert";
+  };
 }
 
 my $big_flop_cd = ($artist->search_related('cds'))[3];
@@ -284,3 +289,14 @@
 my $rs_overridden = $schema->source('ForceForeign');
 my $relinfo_with_attr = $rs_overridden->relationship_info ('cd_3');
 cmp_ok($relinfo_with_attr->{attrs}{is_foreign_key_constraint}, '==', 0, "is_foreign_key_constraint defined for belongs_to relationships with attr.");
+
+# check that relationships below left join relationships are forced to left joins 
+# when traversing multiple belongs_to
+my $cds = $schema->resultset("CD")->search({ 'me.cdid' => 5 }, { join => { single_track => 'cd' } });
+is($cds->count, 1, "subjoins under left joins force_left (string)");
+
+$cds = $schema->resultset("CD")->search({ 'me.cdid' => 5 }, { join => { single_track => ['cd'] } });
+is($cds->count, 1, "subjoins under left joins force_left (arrayref)");
+
+$cds = $schema->resultset("CD")->search({ 'me.cdid' => 5 }, { join => { single_track => { cd => {} } } });
+is($cds->count, 1, "subjoins under left joins force_left (hashref)");

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/71mysql.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/71mysql.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/71mysql.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -108,7 +108,7 @@
     => 'Created an artist resultset of undef';
     
     TODO: {
-    	$TODO = "need to fix the row count =1 when select * from table where pk IS NULL problem";
+    	local $TODO = "need to fix the row count =1 when select * from table where pk IS NULL problem";
 	    is $artist2_rs->count, 0
 	    => 'got no rows';    	
     }

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/72pg.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/72pg.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/72pg.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -15,10 +15,15 @@
 
   __PACKAGE__->load_components(qw/Core/);
   __PACKAGE__->table('testschema.casecheck');
-  __PACKAGE__->add_columns(qw/id name NAME uc_name/);
+  __PACKAGE__->add_columns(qw/id name NAME uc_name storecolumn/);
   __PACKAGE__->column_info_from_storage(1);
   __PACKAGE__->set_primary_key('id');
 
+  sub store_column {
+    my ($self, $name, $value) = @_;
+    $value = '#'.$value if($name eq "storecolumn");
+    $self->maybe::next::method($name, $value);
+  }
 }
 
 {
@@ -45,7 +50,7 @@
     unless ($dsn && $user);
 
 
-plan tests => 37;
+plan tests => 39;
 
 DBICTest::Schema->load_classes( 'Casecheck', 'ArrayTest' );
 my $schema = DBICTest::Schema->connect($dsn, $user, $pass);
@@ -73,10 +78,17 @@
     $dbh->do("CREATE SEQUENCE pkid1_seq START 1 MAXVALUE 999999 MINVALUE 0");
     $dbh->do("CREATE SEQUENCE pkid2_seq START 10 MAXVALUE 999999 MINVALUE 0");
     $dbh->do("CREATE SEQUENCE nonpkid_seq START 20 MAXVALUE 999999 MINVALUE 0");
-    ok ( $dbh->do('CREATE TABLE testschema.casecheck (id serial PRIMARY KEY, "name" VARCHAR(1), "NAME" VARCHAR(2), "UC_NAME" VARCHAR(3));'), 'Creation of casecheck table');
+    ok ( $dbh->do('CREATE TABLE testschema.casecheck (id serial PRIMARY KEY, "name" VARCHAR(1), "NAME" VARCHAR(2), "UC_NAME" VARCHAR(3), "storecolumn" VARCHAR(10));'), 'Creation of casecheck table');
     ok ( $dbh->do('CREATE TABLE testschema.array_test (id serial PRIMARY KEY, arrayfield INTEGER[]);'), 'Creation of array_test table');
 }
 
+# store_column is called once for create() for non sequence columns
+
+ok(my $storecolumn = $schema->resultset('Casecheck')->create({'storecolumn' => 'a'}));
+
+is($storecolumn->storecolumn, '#a'); # was '##a'
+
+
 # This is in Core now, but it's here just to test that it doesn't break
 $schema->class('Artist')->load_components('PK::Auto');
 
@@ -130,10 +142,7 @@
 is_deeply($type_info, $test_type_info,
           'columns_info_for - column data types');
 
-SKIP: {
-  skip "SQL::Abstract < 1.49 does not pass through arrayrefs", 4
-    if $SQL::Abstract::VERSION < 1.49;
-
+{
   lives_ok {
     $schema->resultset('ArrayTest')->create({
       arrayfield => [1, 2],
@@ -153,7 +162,7 @@
   my $count;
   lives_ok {
     $count = $schema->resultset('ArrayTest')->search({
-      arrayfield => \[ '= ?' => [arrayfield => [3, 4]] ],   #TODO anything less ugly than this?
+      arrayfield => \[ '= ?' => [arrayfield => [3, 4]] ],   #Todo anything less ugly than this?
     })->count;
   } 'comparing arrayref to pg array data does not blow up';
   is($count, 1, 'comparing arrayref to pg array data gives correct result');
@@ -246,20 +255,16 @@
     });
 }
 
-SKIP: {
-  skip "Oracle Auto-PK tests are broken", 16;
-
-  # test auto increment using sequences WITHOUT triggers
-  for (1..5) {
+for (1..5) {
     my $st = $schema->resultset('SequenceTest')->create({ name => 'foo' });
     is($st->pkid1, $_, "Oracle Auto-PK without trigger: First primary key");
     is($st->pkid2, $_ + 9, "Oracle Auto-PK without trigger: Second primary key");
     is($st->nonpkid, $_ + 19, "Oracle Auto-PK without trigger: Non-primary key");
-  }
-  my $st = $schema->resultset('SequenceTest')->create({ name => 'foo', pkid1 => 55 });
-  is($st->pkid1, 55, "Oracle Auto-PK without trigger: First primary key set manually");
 }
+my $st = $schema->resultset('SequenceTest')->create({ name => 'foo', pkid1 => 55 });
+is($st->pkid1, 55, "Oracle Auto-PK without trigger: First primary key set manually");
 
+
 END {
     if($dbh) {
         $dbh->do("DROP TABLE testschema.artist;");
@@ -272,4 +277,3 @@
         $dbh->do("DROP SCHEMA testschema;");
     }
 }
-

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/74mssql.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/74mssql.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/74mssql.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -40,7 +40,7 @@
 
 # Test LIMIT
 for (1..6) {
-    $schema->resultset('Artist')->create( { name => 'Artist ' . $_ } );
+    $schema->resultset('Artist')->create( { name => 'Artist ' . $_, rank => $_ } );
 }
 
 my $it = $schema->resultset('Artist')->search( { },

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/76select.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/76select.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/76select.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -5,10 +5,11 @@
 use Test::Exception;
 use lib qw(t/lib);
 use DBICTest;
+use DBIC::SqlMakerTest;
 
 my $schema = DBICTest->init_schema();
 
-plan tests => 12;
+plan tests => 24;
 
 my $rs = $schema->resultset('CD')->search({},
     {
@@ -28,6 +29,16 @@
 lives_ok(sub { $rs->first->get_column('count') }, 'multiple +select/+as columns, 1st rscolumn present');
 lives_ok(sub { $rs->first->get_column('addedtitle') }, 'multiple +select/+as columns, 2nd rscolumn present');
 
+# Tests a regression in ResultSetColumn wrt +select
+$rs = $schema->resultset('CD')->search(undef,
+    {
+        '+select'   => [ \'COUNT(*) AS year_count' ],
+		order_by => 'year_count'
+	}
+);
+my @counts = $rs->get_column('cdid')->all;
+ok(scalar(@counts), 'got rows from ->all using +select');
+
 $rs = $schema->resultset('CD')->search({},
     {
         '+select'   => [ \ 'COUNT(*)', 'title' ],
@@ -63,3 +74,128 @@
 is ($subsel->next->title, $cds->next->title, 'Second CD title match');
 
 is($schema->resultset('CD')->current_source_alias, "me", '$rs->current_source_alias returns "me"');
+
+
+
+$rs = $schema->resultset('CD')->search({},
+    {
+        'join' => 'artist',
+        'columns' => ['cdid', 'title', 'artist.name'],
+    }
+);
+
+my ($sql, @bind) = @${$rs->as_query};
+is_same_sql_bind (
+  $sql,
+  \@bind,
+  '(SELECT me.cdid, me.title, artist.name FROM cd me  JOIN artist artist ON artist.artistid = me.artist)',
+  [],
+  'Use of columns attribute results in proper sql'
+);
+
+lives_ok(sub {
+  $rs->first->get_column('cdid')
+}, 'columns 1st rscolumn present');
+
+lives_ok(sub {
+  $rs->first->get_column('title')
+}, 'columns 2nd rscolumn present');
+
+lives_ok(sub {
+  $rs->first->artist->get_column('name') 
+}, 'columns 3rd rscolumn present'); 
+
+
+
+$rs = $schema->resultset('CD')->search({},
+    {  
+        'join' => 'artist',
+        '+columns' => ['cdid', 'title', 'artist.name'],
+    }
+);
+
+($sql, @bind) = @${$rs->as_query};
+is_same_sql_bind (
+  $sql,
+  \@bind,
+  '(SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track, me.cdid, me.title, artist.name FROM cd me  JOIN artist artist ON artist.artistid = me.artist)',
+  [],
+  'Use of columns attribute results in proper sql'
+);
+
+lives_ok(sub {
+  $rs->first->get_column('cdid') 
+}, 'columns 1st rscolumn present');
+
+lives_ok(sub {
+  $rs->first->get_column('title')
+}, 'columns 2nd rscolumn present');
+
+lives_ok(sub {
+  $rs->first->artist->get_column('name')
+}, 'columns 3rd rscolumn present');
+
+
+$rs = $schema->resultset('CD')->search({'tracks.position' => { -in => [2] } },
+  {
+    join => 'tracks',
+    columns => [qw/me.cdid me.title/],
+    '+select' => ['tracks.position'],
+    '+as' => ['track_position'],
+
+    # get a hashref of CD1 only (the first with a second track)
+    result_class => 'DBIx::Class::ResultClass::HashRefInflator',
+    order_by => 'cdid',
+    rows => 1,
+  }
+);
+
+is_deeply (
+  $rs->single,
+  {
+    cdid => 1,
+    track_position => 2,
+    title => 'Spoonful of bees',
+  },
+  'limited prefetch via column works on a multi-relationship',
+);
+
+my $sub_rs = $rs->search ({},
+  {
+    columns => [qw/artist tracks.trackid/],    # columns should not be merged but override $rs columns
+    '+select' => ['tracks.title'],
+    '+as' => ['tracks.title'],
+  }
+);
+
+is_deeply (
+  $sub_rs->single,
+  {
+    artist => 1,
+    track_position => 2,
+    tracks =>
+      {
+        trackid => 17,
+        title => 'Apiary',
+      },
+  },
+  'columns/select/as fold properly on sub-searches',
+);
+
+TODO: {
+  local $TODO = "Multi-collapsing still doesn't work right - HRI should be getting an arrayref, not an individual hash";
+  is_deeply (
+    $sub_rs->single,
+    {
+      artist => 1,
+      track_position => 2,
+      tracks => [
+        {
+          trackid => 17,
+          title => 'Apiary',
+        },
+      ],
+    },
+    'columns/select/as fold properly on sub-searches',
+  );
+}

Deleted: DBIx-Class/0.08/branches/hierarchical-queries/t/77prefetch.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/77prefetch.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/77prefetch.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,485 +0,0 @@
-use strict;
-use warnings;  
-
-use Test::More;
-use Test::Exception;
-use lib qw(t/lib);
-use DBICTest;
-use Data::Dumper;
-
-my $schema = DBICTest->init_schema();
-
-my $orig_debug = $schema->storage->debug;
-
-use IO::File;
-
-BEGIN {
-    eval "use DBD::SQLite";
-    plan $@
-        ? ( skip_all => 'needs DBD::SQLite for testing' )
-        : ( tests => 74 );
-}
-
-# figure out if we've got a version of sqlite that is older than 3.2.6, in
-# which case COUNT(DISTINCT()) doesn't work
-my $is_broken_sqlite = 0;
-my ($sqlite_major_ver,$sqlite_minor_ver,$sqlite_patch_ver) =
-    split /\./, $schema->storage->dbh->get_info(18);
-if( $schema->storage->dbh->get_info(17) eq 'SQLite' &&
-    ( ($sqlite_major_ver < 3) ||
-      ($sqlite_major_ver == 3 && $sqlite_minor_ver < 2) ||
-      ($sqlite_major_ver == 3 && $sqlite_minor_ver == 2 && $sqlite_patch_ver < 6) ) ) {
-    $is_broken_sqlite = 1;
-}
-
-# bug in 0.07000 caused attr (join/prefetch) to be modifed by search
-# so we check the search & attr arrays are not modified
-my $search = { 'artist.name' => 'Caterwauler McCrae' };
-my $attr = { prefetch => [ qw/artist liner_notes/ ],
-             order_by => 'me.cdid' };
-my $search_str = Dumper($search);
-my $attr_str = Dumper($attr);
-
-my $rs = $schema->resultset("CD")->search($search, $attr);
-
-is(Dumper($search), $search_str, 'Search hash untouched after search()');
-is(Dumper($attr), $attr_str, 'Attribute hash untouched after search()');
-cmp_ok($rs + 0, '==', 3, 'Correct number of records returned');
-
-# A search() with prefetch seems to pollute an already joined resultset
-# in a way that offsets future joins (adapted from a test case by Debolaz)
-{
-  my ($cd_rs, $attrs);
-
-  # test a real-life case - rs is obtained by an implicit m2m join
-  $cd_rs = $schema->resultset ('Producer')->first->cds;
-  $attrs = Dumper $cd_rs->{attrs};
-
-  $cd_rs->search ({})->all;
-  is (Dumper ($cd_rs->{attrs}), $attrs, 'Resultset attributes preserved after a simple search');
-
-  lives_ok (sub {
-    $cd_rs->search ({'artist.artistid' => 1}, { prefetch => 'artist' })->all;
-    is (Dumper ($cd_rs->{attrs}), $attrs, 'Resultset attributes preserved after search with prefetch');
-  }, 'first prefetching search ok');
-
-  lives_ok (sub {
-    $cd_rs->search ({'artist.artistid' => 1}, { prefetch => 'artist' })->all;
-    is (Dumper ($cd_rs->{attrs}), $attrs, 'Resultset attributes preserved after another search with prefetch')
-  }, 'second prefetching search ok');
-
-
-  # test a regular rs with an empty seen_join injected - it should still work!
-  $cd_rs = $schema->resultset ('CD');
-  $cd_rs->{attrs}{seen_join}  = {};
-  $attrs = Dumper $cd_rs->{attrs};
-
-  $cd_rs->search ({})->all;
-  is (Dumper ($cd_rs->{attrs}), $attrs, 'Resultset attributes preserved after a simple search');
-
-  lives_ok (sub {
-    $cd_rs->search ({'artist.artistid' => 1}, { prefetch => 'artist' })->all;
-    is (Dumper ($cd_rs->{attrs}), $attrs, 'Resultset attributes preserved after search with prefetch');
-  }, 'first prefetching search ok');
-
-  lives_ok (sub {
-    $cd_rs->search ({'artist.artistid' => 1}, { prefetch => 'artist' })->all;
-    is (Dumper ($cd_rs->{attrs}), $attrs, 'Resultset attributes preserved after another search with prefetch')
-  }, 'second prefetching search ok');
-}
-
-
-my $queries = 0;
-$schema->storage->debugcb(sub { $queries++; });
-$schema->storage->debug(1);
-
-my @cd = $rs->all;
-
-is($cd[0]->title, 'Spoonful of bees', 'First record returned ok');
-
-ok(!defined $cd[0]->liner_notes, 'No prefetch for NULL LEFT join');
-
-is($cd[1]->{_relationship_data}{liner_notes}->notes, 'Buy Whiskey!', 'Prefetch for present LEFT JOIN');
-
-is(ref $cd[1]->liner_notes, 'DBICTest::LinerNotes', 'Prefetch returns correct class');
-
-is($cd[2]->{_inflated_column}{artist}->name, 'Caterwauler McCrae', 'Prefetch on parent object ok');
-
-is($queries, 1, 'prefetch ran only 1 select statement');
-
-$schema->storage->debug($orig_debug);
-$schema->storage->debugobj->callback(undef);
-
-# test for partial prefetch via columns attr
-my $cd = $schema->resultset('CD')->find(1,
-    {
-      columns => [qw/title artist artist.name/], 
-      join => { 'artist' => {} }
-    }
-);
-ok(eval { $cd->artist->name eq 'Caterwauler McCrae' }, 'single related column prefetched');
-
-# start test for nested prefetch SELECT count
-$queries = 0;
-$schema->storage->debugcb(sub { $queries++ });
-$schema->storage->debug(1);
-
-$rs = $schema->resultset('Tag')->search(
-  {},
-  {
-    prefetch => { cd => 'artist' }
-  }
-);
-
-my $tag = $rs->first;
-
-is( $tag->cd->title, 'Spoonful of bees', 'step 1 ok for nested prefetch' );
-
-is( $tag->cd->artist->name, 'Caterwauler McCrae', 'step 2 ok for nested prefetch');
-
-# count the SELECTs
-#$selects++ if /SELECT(?!.*WHERE 1=0.*)/;
-is($queries, 1, 'nested prefetch ran exactly 1 select statement (excluding column_info)');
-
-$queries = 0;
-
-is($tag->search_related('cd')->search_related('artist')->first->name,
-   'Caterwauler McCrae',
-   'chained belongs_to->belongs_to search_related ok');
-
-is($queries, 0, 'chained search_related after belontgs_to->belongs_to prefetch ran no queries');
-
-$queries = 0;
-
-$cd = $schema->resultset('CD')->find(1, { prefetch => 'artist' });
-
-is($cd->{_inflated_column}{artist}->name, 'Caterwauler McCrae', 'artist prefetched correctly on find');
-
-is($queries, 1, 'find with prefetch ran exactly 1 select statement (excluding column_info)');
-
-$queries = 0;
-
-$schema->storage->debugcb(sub { $queries++; });
-
-$cd = $schema->resultset('CD')->find(1, { prefetch => { cd_to_producer => 'producer' } });
-
-is($cd->producers->first->name, 'Matt S Trout', 'many_to_many accessor ok');
-
-is($queries, 1, 'many_to_many accessor with nested prefetch ran exactly 1 query');
-
-$queries = 0;
-
-my $producers = $cd->search_related('cd_to_producer')->search_related('producer');
-
-is($producers->first->name, 'Matt S Trout', 'chained many_to_many search_related ok');
-
-is($queries, 0, 'chained search_related after many_to_many prefetch ran no queries');
-
-$schema->storage->debug($orig_debug);
-$schema->storage->debugobj->callback(undef);
-
-$rs = $schema->resultset('Tag')->search(
-  {},
-  {
-    join => { cd => 'artist' },
-    prefetch => { cd => 'artist' }
-  }
-);
-
-cmp_ok( $rs->count, '>=', 0, 'nested prefetch does not duplicate joins' );
-
-my ($artist) = $schema->resultset("Artist")->search({ 'cds.year' => 2001 },
-                 { order_by => 'artistid DESC', join => 'cds' });
-
-is($artist->name, 'Random Boy Band', "Join search by object ok");
-
-my @cds = $schema->resultset("CD")->search({ 'liner_notes.notes' => 'Buy Merch!' },
-                               { join => 'liner_notes' });
-
-cmp_ok(scalar @cds, '==', 1, "Single CD retrieved via might_have");
-
-is($cds[0]->title, "Generic Manufactured Singles", "Correct CD retrieved");
-
-my @artists = $schema->resultset("Artist")->search({ 'tags.tag' => 'Shiny' },
-                                       { join => { 'cds' => 'tags' } });
-
-cmp_ok( @artists, '==', 2, "two-join search ok" );
-
-$rs = $schema->resultset("CD")->search(
-  {},
-  { group_by => [qw/ title me.cdid /] }
-);
-
-SKIP: {
-    skip "SQLite < 3.2.6 doesn't understand COUNT(DISTINCT())", 1
-        if $is_broken_sqlite;
-    cmp_ok( $rs->count, '==', 5, "count() ok after group_by on main pk" );
-}
-
-cmp_ok( scalar $rs->all, '==', 5, "all() returns same count as count() after group_by on main pk" );
-
-$rs = $schema->resultset("CD")->search(
-  {},
-  { join => [qw/ artist /], group_by => [qw/ artist.name /] }
-);
-
-SKIP: {
-    skip "SQLite < 3.2.6 doesn't understand COUNT(DISTINCT())", 1
-        if $is_broken_sqlite;
-    cmp_ok( $rs->count, '==', 3, "count() ok after group_by on related column" );
-}
-
-$rs = $schema->resultset("Artist")->search(
-  {},
-      { join => [qw/ cds /], group_by => [qw/ me.name /], having =>{ 'MAX(cds.cdid)'=> \'< 5' } }
-);
-
-cmp_ok( $rs->all, '==', 2, "results ok after group_by on related column with a having" );
-
-$rs = $rs->search( undef, {  having =>{ 'count(*)'=> \'> 2' }});
-
-cmp_ok( $rs->all, '==', 1, "count() ok after group_by on related column with a having" );
-
-$rs = $schema->resultset("Artist")->search(
-        { 'cds.title' => 'Spoonful of bees',
-          'cds_2.title' => 'Forkful of bees' },
-        { join => [ 'cds', 'cds' ] });
-
-SKIP: {
-    skip "SQLite < 3.2.6 doesn't understand COUNT(DISTINCT())", 1
-        if $is_broken_sqlite;
-    cmp_ok($rs->count, '==', 1, "single artist returned from multi-join");
-}
-
-is($rs->next->name, 'Caterwauler McCrae', "Correct artist returned");
-
-$cd = $schema->resultset('Artist')->first->create_related('cds',
-    {
-    title   => 'Unproduced Single',
-    year    => 2007
-});
-
-my $left_join = $schema->resultset('CD')->search(
-    { 'me.cdid' => $cd->cdid },
-    { prefetch => { cd_to_producer => 'producer' } }
-);
-
-cmp_ok($left_join, '==', 1, 'prefetch with no join record present');
-
-$queries = 0;
-$schema->storage->debugcb(sub { $queries++ });
-$schema->storage->debug(1);
-
-my $tree_like =
-     $schema->resultset('TreeLike')->find(5,
-       { join     => { parent => { parent => 'parent' } },
-         prefetch => { parent => { parent => 'parent' } } });
-
-is($tree_like->name, 'quux', 'Bottom of tree ok');
-$tree_like = $tree_like->parent;
-is($tree_like->name, 'baz', 'First level up ok');
-$tree_like = $tree_like->parent;
-is($tree_like->name, 'bar', 'Second level up ok');
-$tree_like = $tree_like->parent;
-is($tree_like->name, 'foo', 'Third level up ok');
-
-$schema->storage->debug($orig_debug);
-$schema->storage->debugobj->callback(undef);
-
-cmp_ok($queries, '==', 1, 'Only one query run');
-
-$tree_like = $schema->resultset('TreeLike')->search({'me.id' => 2});
-$tree_like = $tree_like->search_related('children')->search_related('children')->search_related('children')->first;
-is($tree_like->name, 'quux', 'Tree search_related ok');
-
-$tree_like = $schema->resultset('TreeLike')->search_related('children',
-    { 'children.id' => 3, 'children_2.id' => 4 },
-    { prefetch => { children => 'children' } }
-  )->first;
-is(eval { $tree_like->children->first->children->first->name }, 'quux',
-   'Tree search_related with prefetch ok');
-
-$tree_like = eval { $schema->resultset('TreeLike')->search(
-    { 'children.id' => 3, 'children_2.id' => 6 }, 
-    { join => [qw/children children/] }
-  )->search_related('children', { 'children_4.id' => 7 }, { prefetch => 'children' }
-  )->first->children->first; };
-is(eval { $tree_like->name }, 'fong', 'Tree with multiple has_many joins ok');
-
-# test that collapsed joins don't get a _2 appended to the alias
-
-my $sql = '';
-$schema->storage->debugcb(sub { $sql = $_[1] });
-$schema->storage->debug(1);
-
-eval {
-  my $row = $schema->resultset('Artist')->search_related('cds', undef, {
-    join => 'tracks',
-    prefetch => 'tracks',
-  })->search_related('tracks')->first;
-};
-
-like( $sql, qr/^SELECT tracks_2\.trackid/, "join not collapsed for search_related" );
-
-$schema->storage->debug($orig_debug);
-$schema->storage->debugobj->callback(undef);
-
-$rs = $schema->resultset('Artist');
-$rs->create({ artistid => 4, name => 'Unknown singer-songwriter' });
-$rs->create({ artistid => 5, name => 'Emo 4ever' });
- at artists = $rs->search(undef, { prefetch => 'cds', order_by => 'artistid' });
-is(scalar @artists, 5, 'has_many prefetch with adjacent empty rows ok');
-
-# -------------
-#
-# Tests for multilevel has_many prefetch
-
-# artist resultsets - with and without prefetch
-my $art_rs = $schema->resultset('Artist');
-my $art_rs_pr = $art_rs->search(
-    {},
-    {
-        join     => [ { cds => ['tracks'] } ],
-        prefetch => [ { cds => ['tracks'] } ],
-        cache    => 1 # last test needs this
-    }
-);
-
-# This test does the same operation twice - once on a
-# set of items fetched from the db with no prefetch of has_many rels
-# The second prefetches 2 levels of has_many
-# We check things are the same by comparing the name or title
-# we build everything into a hash structure and compare the one
-# from each rs to see what differs
-
-sub make_hash_struc {
-    my $rs = shift;
-
-    my $struc = {};
-    foreach my $art ( $rs->all ) {
-        foreach my $cd ( $art->cds ) {
-            foreach my $track ( $cd->tracks ) {
-                $struc->{ $art->name }{ $cd->title }{ $track->title }++;
-            }
-        }
-    }
-    return $struc;
-}
-
-$queries = 0;
-$schema->storage->debugcb(sub { $queries++ });
-$schema->storage->debug(1);
-
-my $prefetch_result = make_hash_struc($art_rs_pr);
-
-is($queries, 1, 'nested prefetch across has_many->has_many ran exactly 1 query');
-
-my $nonpre_result   = make_hash_struc($art_rs);
-
-is_deeply( $prefetch_result, $nonpre_result,
-    'Compare 2 level prefetch result to non-prefetch result' );
-
-$queries = 0;
-
-is($art_rs_pr->search_related('cds')->search_related('tracks')->first->title,
-   'Fowlin',
-   'chained has_many->has_many search_related ok'
-  );
-
-is($queries, 0, 'chained search_related after has_many->has_many prefetch ran no queries');
-
-# once the following TODO is complete, remove the 2 warning tests immediately after the TODO block
-# (the TODO block itself contains tests ensuring that the warns are removed)
-TODO: {
-    local $TODO = 'Prefetch of multiple has_many rels at the same level (currently warn to protect the clueless git)';
-
-    #( 1 -> M + M )
-    my $cd_rs = $schema->resultset('CD')->search ({ 'me.title' => 'Forkful of bees' });
-    my $pr_cd_rs = $cd_rs->search ({}, {
-        prefetch => [qw/tracks tags/],
-    });
-
-    my $tracks_rs = $cd_rs->first->tracks;
-    my $tracks_count = $tracks_rs->count;
-
-    my ($pr_tracks_rs, $pr_tracks_count);
-
-    $queries = 0;
-    $schema->storage->debugcb(sub { $queries++ });
-    $schema->storage->debug(1);
-
-    my $o_mm_warn;
-    {
-        local $SIG{__WARN__} = sub { $o_mm_warn = shift };
-        $pr_tracks_rs = $pr_cd_rs->first->tracks;
-    };
-    $pr_tracks_count = $pr_tracks_rs->count;
-
-    ok(! $o_mm_warn, 'no warning on attempt to prefetch several same level has_many\'s (1 -> M + M)');
-
-    is($queries, 1, 'prefetch one->(has_many,has_many) ran exactly 1 query');
-    is($pr_tracks_count, $tracks_count, 'equal count of prefetched relations over several same level has_many\'s (1 -> M + M)');
-
-    for ($pr_tracks_rs, $tracks_rs) {
-        $_->result_class ('DBIx::Class::ResultClass::HashRefInflator');
-    }
-
-    is_deeply ([$pr_tracks_rs->all], [$tracks_rs->all], 'same structure returned with and without prefetch over several same level has_many\'s (1 -> M + M)');
-
-    #( M -> 1 -> M + M )
-    my $note_rs = $schema->resultset('LinerNotes')->search ({ notes => 'Buy Whiskey!' });
-    my $pr_note_rs = $note_rs->search ({}, {
-        prefetch => {
-            cd => [qw/tags tracks/]
-        },
-    });
-
-    my $tags_rs = $note_rs->first->cd->tags;
-    my $tags_count = $tags_rs->count;
-
-    my ($pr_tags_rs, $pr_tags_count);
-
-    $queries = 0;
-    $schema->storage->debugcb(sub { $queries++ });
-    $schema->storage->debug(1);
-
-    my $m_o_mm_warn;
-    {
-        local $SIG{__WARN__} = sub { $m_o_mm_warn = shift };
-        $pr_tags_rs = $pr_note_rs->first->cd->tags;
-    };
-    $pr_tags_count = $pr_tags_rs->count;
-
-    ok(! $m_o_mm_warn, 'no warning on attempt to prefetch several same level has_many\'s (M -> 1 -> M + M)');
-
-    is($queries, 1, 'prefetch one->(has_many,has_many) ran exactly 1 query');
-
-    is($pr_tags_count, $tags_count, 'equal count of prefetched relations over several same level has_many\'s (M -> 1 -> M + M)');
-
-    for ($pr_tags_rs, $tags_rs) {
-        $_->result_class ('DBIx::Class::ResultClass::HashRefInflator');
-    }
-
-    is_deeply ([$pr_tags_rs->all], [$tags_rs->all], 'same structure returned with and without prefetch over several same level has_many\'s (M -> 1 -> M + M)');
-};
-
-# remove this closure once the TODO above is working
-my $w;
-{
-    local $SIG{__WARN__} = sub { $w = shift };
-
-    my $rs = $schema->resultset('CD')->search ({ 'me.title' => 'Forkful of bees' }, { prefetch => [qw/tracks tags/] });
-    for (qw/all count next first/) {
-        undef $w;
-        my @stuff = $rs->search()->$_;
-        like ($w, qr/will currently disrupt both the functionality of .rs->count\(\), and the amount of objects retrievable via .rs->next\(\)/,
-            "warning on ->$_ attempt prefetching several same level has_manys (1 -> M + M)");
-    }
-    my $rs2 = $schema->resultset('LinerNotes')->search ({ notes => 'Buy Whiskey!' }, { prefetch => { cd => [qw/tags tracks/] } });
-    for (qw/all count next first/) {
-        undef $w;
-        my @stuff = $rs2->search()->$_;
-        like ($w, qr/will currently disrupt both the functionality of .rs->count\(\), and the amount of objects retrievable via .rs->next\(\)/,
-            "warning on ->$_ attempt prefetching several same level has_manys (M -> 1 -> M + M)");
-    }
-}

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/80unique.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/80unique.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/80unique.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -7,7 +7,7 @@
 
 my $schema = DBICTest->init_schema();
 
-plan tests => 45;
+plan tests => 49;
 
 # Check the defined unique constraints
 is_deeply(
@@ -183,3 +183,30 @@
   ok($cd->in_storage, 'find correctly grepped the key across a relationship');
   is($cd->cdid, 1, 'cdid is correct');
 }
+
+# Test update_or_new
+{
+    my $cd1 = $schema->resultset('CD')->update_or_new(
+      {
+        artist => $artistid,
+        title  => "SuperHits $$",
+        year   => 2007,
+      },
+      { key => 'cd_artist_title' }
+    );
+
+    ok(!$cd1->in_storage, 'CD is not in storage yet after update_or_new');
+    $cd1->insert;
+    ok($cd1->in_storage, 'CD got added to strage after update_or_new && insert');
+
+    my $cd2 = $schema->resultset('CD')->update_or_new(
+      {
+        artist => $artistid,
+        title  => "SuperHits $$",
+        year   => 2008,
+      },
+      { key => 'cd_artist_title' }
+    );
+    ok($cd2->in_storage, 'Updating year using update_or_new was successful');
+    is($cd2->id, $cd1->id, 'Got the same CD using update_or_new');
+}
\ No newline at end of file

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/81transactions.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/81transactions.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/81transactions.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -272,7 +272,7 @@
 
   ok(!$artist_rs->find({name => 'Death Cab for Cutie'}), "Artist not created");
 
-  eval {
+  lives_ok (sub {
     my $w;
     local $SIG{__WARN__} = sub { $w = shift };
 
@@ -281,32 +281,27 @@
     outer($schema, 0);
 
     like ($w, qr/A DBIx::Class::Storage::TxnScopeGuard went out of scope without explicit commit or an error/, 'Out of scope warning detected');
-  };
+    ok(!$artist_rs->find({name => 'Death Cab for Cutie'}), "Artist not created");
+  }, 'rollback successful withot exception');
 
-  local $TODO = "Work out how this should work";
-  is($@, "Not sure what we want here, but something", "Rollback okay");
-
-  ok(!$artist_rs->find({name => 'Death Cab for Cutie'}), "Artist not created");
-
   sub outer {
     my ($schema) = @_;
-   
+
     my $guard = $schema->txn_scope_guard;
     $schema->resultset('Artist')->create({
       name => 'Death Cab for Cutie',
     });
     inner(@_);
-    $guard->commit;
   }
 
   sub inner {
     my ($schema, $fatal) = @_;
-    my $guard = $schema->txn_scope_guard;
 
+    my $inner_guard = $schema->txn_scope_guard;
+    is($schema->storage->transaction_depth, 2, "Correct transaction depth");
+
     my $artist = $artist_rs->find({ name => 'Death Cab for Cutie' });
 
-    is($schema->storage->transaction_depth, 2, "Correct transaction depth");
-    undef $@;
     eval {
       $artist->cds->create({ 
         title => 'Plans',
@@ -320,6 +315,7 @@
       die $@;
     }
 
-    # See what happens if we dont $guard->commit;
+    # inner guard should commit without consequences
+    $inner_guard->commit;
   }
 }

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/89dbicadmin.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/89dbicadmin.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/89dbicadmin.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -21,7 +21,6 @@
 
 plan tests => $tests_per_run * @json_backends;
 
-use JSON::Any;
 for my $js (@json_backends) {
 
     eval {JSON::Any->import ($js) };

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/89inflate_datetime.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/89inflate_datetime.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/89inflate_datetime.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -5,12 +5,17 @@
 use lib qw(t/lib);
 use DBICTest;
 
+{
+  local $SIG{__WARN__} = sub { warn @_ if $_[0] !~ /extra \=\> .+? has been deprecated/ };
+  DBICTest::Schema->load_classes('EventTZDeprecated');
+}
+
 my $schema = DBICTest->init_schema();
 
 eval { require DateTime::Format::MySQL };
 plan skip_all => "Need DateTime::Format::MySQL for inflation tests" if $@;
 
-plan tests => 32;
+plan tests => 50;
 
 # inflation test
 my $event = $schema->resultset("Event")->find(1);
@@ -52,75 +57,78 @@
 
 
 # Test "timezone" parameter
-my $event_tz = $schema->resultset('EventTZ')->create({
-    starts_at => DateTime->new(year=>2007, month=>12, day=>31, time_zone => "America/Chicago" ),
-    created_on => DateTime->new(year=>2006, month=>1, day=>31,
-        hour => 13, minute => 34, second => 56, time_zone => "America/New_York" ),
-});
 
-is ($event_tz->starts_at->day_name, "Montag", 'Locale de_DE loaded: day_name');
-is ($event_tz->starts_at->month_name, "Dezember", 'Locale de_DE loaded: month_name');
-is ($event_tz->created_on->day_name, "Tuesday", 'Default locale loaded: day_name');
-is ($event_tz->created_on->month_name, "January", 'Default locale loaded: month_name');
+foreach my $tbl (qw/EventTZ EventTZDeprecated/) {
+  my $event_tz = $schema->resultset($tbl)->create({
+      starts_at => DateTime->new(year=>2007, month=>12, day=>31, time_zone => "America/Chicago" ),
+      created_on => DateTime->new(year=>2006, month=>1, day=>31,
+          hour => 13, minute => 34, second => 56, time_zone => "America/New_York" ),
+  });
 
-my $starts_at = $event_tz->starts_at;
-is("$starts_at", '2007-12-31T00:00:00', 'Correct date/time using timezone');
+  is ($event_tz->starts_at->day_name, "Montag", 'Locale de_DE loaded: day_name');
+  is ($event_tz->starts_at->month_name, "Dezember", 'Locale de_DE loaded: month_name');
+  is ($event_tz->created_on->day_name, "Tuesday", 'Default locale loaded: day_name');
+  is ($event_tz->created_on->month_name, "January", 'Default locale loaded: month_name');
 
-my $created_on = $event_tz->created_on;
-is("$created_on", '2006-01-31T12:34:56', 'Correct timestamp using timezone');
-is($event_tz->created_on->time_zone->name, "America/Chicago", "Correct timezone");
+  my $starts_at = $event_tz->starts_at;
+  is("$starts_at", '2007-12-31T00:00:00', 'Correct date/time using timezone');
 
-my $loaded_event = $schema->resultset('EventTZ')->find( $event_tz->id );
+  my $created_on = $event_tz->created_on;
+  is("$created_on", '2006-01-31T12:34:56', 'Correct timestamp using timezone');
+  is($event_tz->created_on->time_zone->name, "America/Chicago", "Correct timezone");
 
-isa_ok($loaded_event->starts_at, 'DateTime', 'DateTime returned');
-$starts_at = $loaded_event->starts_at;
-is("$starts_at", '2007-12-31T00:00:00', 'Loaded correct date/time using timezone');
-is($starts_at->time_zone->name, 'America/Chicago', 'Correct timezone');
+  my $loaded_event = $schema->resultset($tbl)->find( $event_tz->id );
 
-isa_ok($loaded_event->created_on, 'DateTime', 'DateTime returned');
-$created_on = $loaded_event->created_on;
-is("$created_on", '2006-01-31T12:34:56', 'Loaded correct timestamp using timezone');
-is($created_on->time_zone->name, 'America/Chicago', 'Correct timezone');
+  isa_ok($loaded_event->starts_at, 'DateTime', 'DateTime returned');
+  $starts_at = $loaded_event->starts_at;
+  is("$starts_at", '2007-12-31T00:00:00', 'Loaded correct date/time using timezone');
+  is($starts_at->time_zone->name, 'America/Chicago', 'Correct timezone');
 
-# Test floating timezone warning
-# We expect one warning
-SKIP: {
-    skip "ENV{DBIC_FLOATING_TZ_OK} was set, skipping", 1 if $ENV{DBIC_FLOATING_TZ_OK};
-    local $SIG{__WARN__} = sub {
-        like(
-            shift,
-            qr/You're using a floating timezone, please see the documentation of DBIx::Class::InflateColumn::DateTime for an explanation/,
-            'Floating timezone warning'
-        );
-    };
-    my $event_tz_floating = $schema->resultset('EventTZ')->create({
-        starts_at => DateTime->new(year=>2007, month=>12, day=>31, ),
-        created_on => DateTime->new(year=>2006, month=>1, day=>31,
-            hour => 13, minute => 34, second => 56, ),
-    });
-    delete $SIG{__WARN__};
-};
+  isa_ok($loaded_event->created_on, 'DateTime', 'DateTime returned');
+  $created_on = $loaded_event->created_on;
+  is("$created_on", '2006-01-31T12:34:56', 'Loaded correct timestamp using timezone');
+  is($created_on->time_zone->name, 'America/Chicago', 'Correct timezone');
 
-# This should fail to set
-my $prev_str = "$created_on";
-$loaded_event->update({ created_on => '0000-00-00' });
-is("$created_on", $prev_str, "Don't update invalid dates");
+  # Test floating timezone warning
+  # We expect one warning
+  SKIP: {
+      skip "ENV{DBIC_FLOATING_TZ_OK} was set, skipping", 1 if $ENV{DBIC_FLOATING_TZ_OK};
+      local $SIG{__WARN__} = sub {
+          like(
+              shift,
+              qr/You're using a floating timezone, please see the documentation of DBIx::Class::InflateColumn::DateTime for an explanation/,
+              'Floating timezone warning'
+          );
+      };
+      my $event_tz_floating = $schema->resultset($tbl)->create({
+          starts_at => DateTime->new(year=>2007, month=>12, day=>31, ),
+          created_on => DateTime->new(year=>2006, month=>1, day=>31,
+              hour => 13, minute => 34, second => 56, ),
+      });
+      delete $SIG{__WARN__};
+  };
 
-my $invalid = $schema->resultset('Event')->create({
-    starts_at  => '0000-00-00',
-    created_on => $created_on
-});
+  # This should fail to set
+  my $prev_str = "$created_on";
+  $loaded_event->update({ created_on => '0000-00-00' });
+  is("$created_on", $prev_str, "Don't update invalid dates");
 
-is( $invalid->get_column('starts_at'), '0000-00-00', "Invalid date stored" );
-is( $invalid->starts_at, undef, "Inflate to undef" );
+  my $invalid = $schema->resultset('Event')->create({
+      starts_at  => '0000-00-00',
+      created_on => $created_on
+  });
 
-$invalid->created_on('0000-00-00');
-$invalid->update;
+  is( $invalid->get_column('starts_at'), '0000-00-00', "Invalid date stored" );
+  is( $invalid->starts_at, undef, "Inflate to undef" );
 
-{
-    local $@;
-    eval { $invalid->created_on };
-    like( $@, qr/invalid date format/i, "Invalid date format exception");
+  $invalid->created_on('0000-00-00');
+  $invalid->update;
+
+  {
+      local $@;
+      eval { $invalid->created_on };
+      like( $@, qr/invalid date format/i, "Invalid date format exception");
+  }
 }
 
 ## varchar field using inflate_date => 1

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/91debug.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/91debug.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/91debug.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -57,7 +57,7 @@
     my @cds = $schema->resultset('CD')->search( { artist => 1, cdid => { -between => [ 1, 3 ] }, } );
     is_same_sql_bind(
         $sql, [],
-        "SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track FROM cd me WHERE ( artist = ? AND cdid BETWEEN ? AND ? ): '1', '1', '3'", [],
+        "SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track FROM cd me WHERE ( artist = ? AND (cdid BETWEEN ? AND ?) ): '1', '1', '3'", [],
         'got correct SQL with all bind parameters (debugcb)'
     );
 
@@ -66,7 +66,7 @@
     @cds = $schema->resultset('CD')->search( { artist => 1, cdid => { -between => [ 1, 3 ] }, } );
     is_same_sql_bind(
         $sql, \@bind,
-        "SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track FROM cd me WHERE ( artist = ? AND cdid BETWEEN ? AND ? )", ["'1'", "'1'", "'3'"],
+        "SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track FROM cd me WHERE ( artist = ? AND (cdid BETWEEN ? AND ?) )", ["'1'", "'1'", "'3'"],
         'got correct SQL with all bind parameters (debugobj)'
     );
 }

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/93storage_replication.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/93storage_replication.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/93storage_replication.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -577,12 +577,3 @@
 
 ## Delete the old database files
 $replicated->cleanup;
-
-use Data::Dump qw/dump/;
-#warn dump $replicated->schema->storage->read_handler;
-
-
-
-
-
-

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/95sql_maker.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/95sql_maker.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/95sql_maker.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -20,10 +20,7 @@
 my $sql_maker = $schema->storage->sql_maker;
 
 
-SKIP: {
-  skip "SQL::Abstract < 1.49 does not pass through arrayrefs", 2
-    if $SQL::Abstract::VERSION < 1.49;
-
+{
   my ($sql, @bind) = $sql_maker->insert(
             'lottery',
             {

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/95sql_maker_quote.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/95sql_maker_quote.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/95sql_maker_quote.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -110,10 +110,7 @@
   'scalar ORDER BY okay (multiple values)'
 );
 
-SKIP: {
-  skip "SQL::Abstract < 1.49 does not support hashrefs in order_by", 2
-    if $SQL::Abstract::VERSION < 1.49;
-
+{
   ($sql, @bind) = $sql_maker->select(
             [
               {
@@ -236,10 +233,7 @@
   'quoted table names for UPDATE'
 );
 
-SKIP: {
-  skip "select attr with star does not work in SQL::Abstract < 1.49", 1
-    if $SQL::Abstract::VERSION < 1.49;
-
+{
   ($sql, @bind) = $sql_maker->select(
         [
           {

Deleted: DBIx-Class/0.08/branches/hierarchical-queries/t/98rows_prefetch.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/98rows_prefetch.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/98rows_prefetch.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,42 +0,0 @@
-# Test to ensure we get a consistent result set wether or not we use the
-# prefetch option in combination rows (LIMIT).
-use strict;
-use warnings;
-
-use Test::More;
-use lib qw(t/lib);
-use DBICTest;
-
-plan $@ ? (skip_all => 'needs DBD::SQLite for testing') : (tests => 2);
-
-my $schema = DBICTest->init_schema();
-my $no_prefetch = $schema->resultset('Artist')->search(
-	undef,
-	{ rows => 3 }
-);
-
-my $use_prefetch = $schema->resultset('Artist')->search(
-	undef,
-	{
-		prefetch => 'cds',
-		rows     => 3
-	}
-);
-
-my $no_prefetch_count  = 0;
-my $use_prefetch_count = 0;
-
-is($no_prefetch->count, $use_prefetch->count, '$no_prefetch->count == $use_prefetch->count');
-
-TODO: {
-	local $TODO = "This is a difficult bug to fix, workaround is not to use prefetch with rows";
-	$no_prefetch_count++  while $no_prefetch->next;
-	$use_prefetch_count++ while $use_prefetch->next;
-	is(
-		$no_prefetch_count,
-		$use_prefetch_count,
-		"manual row count confirms consistency"
-		. " (\$no_prefetch_count == $no_prefetch_count, "
-		. " \$use_prefetch_count == $use_prefetch_count)"
-	);
-}

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/99dbic_sqlt_parser.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/99dbic_sqlt_parser.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/99dbic_sqlt_parser.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -7,9 +7,9 @@
 
 
 BEGIN {
-    eval "use DBD::mysql; use SQL::Translator 0.09003;";
+    eval "use SQL::Translator 0.09003;";
     if ($@) {
-        plan skip_all => 'needs DBD::mysql and SQL::Translator 0.09003 for testing';
+        plan skip_all => 'needs SQL::Translator 0.09003 for testing';
     }
 }
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/01-columns.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/01-columns.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/01-columns.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,6 +1,7 @@
 use strict;
 
 use Test::More;
+use lib 't/cdbi/testlib';
 
 BEGIN {
   eval "use DBIx::Class::CDBICompat;";
@@ -13,7 +14,7 @@
 #-----------------------------------------------------------------------
 package State;
 
-use base 'DBIx::Class::Test::SQLite';
+use base 'DBIC::Test::SQLite';
 
 State->table('State');
 State->columns(Essential => qw/Abbreviation Name/);
@@ -39,7 +40,7 @@
 
 package City;
 
-use base 'DBIx::Class::Test::SQLite';
+use base 'DBIC::Test::SQLite';
 
 City->table('City');
 City->columns(All => qw/Name State Population/);
@@ -56,7 +57,7 @@
 
 #-------------------------------------------------------------------------
 package CD;
-use base 'DBIx::Class::Test::SQLite';
+use base 'DBIC::Test::SQLite';
 
 CD->table('CD');
 CD->columns('All' => qw/artist title length/);

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/02-Film.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/02-Film.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/02-Film.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -151,7 +151,7 @@
 
 # Multi-column search
 {
-	my @films = $blrunner->search_like(title => "Bladerunner%", rating => '15');
+	my @films = $blrunner->search (title => { -like => "Bladerunner%"}, rating => '15');
 	is @films, 1, "Only one Bladerunner is a 15";
 }
 
@@ -208,7 +208,7 @@
 is($films[0]->id, $gone->id, ' ... the correct one');
 
 # Find all films which were directed by Bob
- at films = Film->search_like('Director', 'Bob %');
+ at films = Film->search ( { 'Director' => { -like => 'Bob %' } });
 is(scalar @films, 3, ' search_like returns 3 films');
 ok(
 	eq_array(

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/15-accessor.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/15-accessor.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/15-accessor.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -25,6 +25,11 @@
     sub Class::DBI::sheep { ok 0; }
 }
 
+# Install the deprecation warning intercept here for the rest of the 08 dev cycle
+local $SIG{__WARN__} = sub {
+  warn @_ unless (DBIx::Class->VERSION < 0.09 and $_[0] =~ /Query returned more than one row/);
+};
+
 sub Film::mutator_name {
     my ($class, $col) = @_;
     return "set_sheep" if lc $col eq "numexplodingsheep";
@@ -160,9 +165,6 @@
     like $@, qr/film/, "no hasa film";
 
     eval {
-        local $SIG{__WARN__} = sub {
-            warn @_ unless $_[0] =~ /Query returned more than one row/;
-        };
         ok my $f = $ac->movie, "hasa movie";
         isa_ok $f, "Film";
         is $f->id, $bt->id, " - Bad Taste";
@@ -264,5 +266,5 @@
     my $abigail = eval { Film->create({ title => "Abigail's Party" }) };
     like $@, qr/read only/, "Or create new films";
 
-    $sandl->discard_changes;
+    $_->discard_changes for ($naked, $sandl);
 }

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/22-deflate_order.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/22-deflate_order.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/22-deflate_order.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -12,6 +12,7 @@
 eval { require Time::Piece::MySQL };
 plan skip_all => "Need Time::Piece::MySQL for this test" if $@;
 
+use lib 't/cdbi/testlib';
 eval { require 't/cdbi/testlib/Log.pm' };
 plan skip_all => "Need MySQL for this test" if $@;
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/columns_dont_override_custom_accessors.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/columns_dont_override_custom_accessors.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/columns_dont_override_custom_accessors.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,5 +1,6 @@
 use strict;
 use Test::More;
+use lib 't/cdbi/testlib';
 
 BEGIN {
   eval "use DBIx::Class::CDBICompat;";
@@ -10,7 +11,7 @@
 {
     package Thing;
 
-    use base 'DBIx::Class::Test::SQLite';
+    use base 'DBIC::Test::SQLite';
 
     Thing->columns(TEMP => qw[foo bar]);
     Thing->columns(All  => qw[thing_id yarrow flower]);

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/copy.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/copy.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/copy.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -15,7 +15,7 @@
     package # hide from PAUSE 
         MyFilm;
 
-    use base 'DBIx::Class::Test::SQLite';
+    use base 'DBIC::Test::SQLite';
     use strict;
 
     __PACKAGE__->set_table('Movies');

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/multi_column_set.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/multi_column_set.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/multi_column_set.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,5 +1,6 @@
 use strict;
 use Test::More;
+use lib 't/cdbi/testlib';
 
 BEGIN {
   eval "use DBIx::Class::CDBICompat;";
@@ -10,7 +11,7 @@
 {
     package Thing;
 
-    use base 'DBIx::Class::Test::SQLite';
+    use base 'DBIC::Test::SQLite';
 
     Thing->columns(TEMP => qw[foo bar baz]);
     Thing->columns(All  => qw[some real stuff]);

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/set_to_undef.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/set_to_undef.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/set_to_undef.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,5 +1,6 @@
 use strict;
 use Test::More;
+use lib 't/cdbi/testlib';
 
 BEGIN {
   eval "use DBIx::Class::CDBICompat;";
@@ -19,7 +20,7 @@
 {
     package Thing;
 
-    use base 'DBIx::Class::Test::SQLite';
+    use base 'DBIC::Test::SQLite';
 
     Thing->columns(All  => qw[thing_id this that date]);
 }

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/set_vs_DateTime.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/set_vs_DateTime.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/set_vs_DateTime.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,6 +1,7 @@
 use strict;
 use Test::More;
 use Test::Exception;
+use lib 't/cdbi/testlib';
 
 BEGIN {
   eval "use DBIx::Class::CDBICompat;";
@@ -13,7 +14,7 @@
 {
     package Thing;
 
-    use base 'DBIx::Class::Test::SQLite';
+    use base 'DBIC::Test::SQLite';
 
     Thing->columns(All  => qw[thing_id this that date]);
 }

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Actor.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Actor.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Actor.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -4,7 +4,7 @@
 use strict;
 use warnings;
 
-use base 'DBIx::Class::Test::SQLite';
+use base 'DBIC::Test::SQLite';
 
 __PACKAGE__->set_table('Actor');
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/ActorAlias.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/ActorAlias.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/ActorAlias.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -4,7 +4,7 @@
 use strict;
 use warnings;
 
-use base 'DBIx::Class::Test::SQLite';
+use base 'DBIC::Test::SQLite';
 
 __PACKAGE__->set_table( 'ActorAlias' );
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Blurb.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Blurb.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Blurb.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -2,7 +2,7 @@
     Blurb;
 
 use strict;
-use base 'DBIx::Class::Test::SQLite';
+use base 'DBIC::Test::SQLite';
 
 __PACKAGE__->set_table('Blurbs');
 __PACKAGE__->columns('Primary', 'Title');

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/CDBase.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/CDBase.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/CDBase.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -2,6 +2,6 @@
     CDBase;
 
 use strict;
-use base qw(DBIx::Class::Test::SQLite);
+use base qw(DBIC::Test::SQLite);
 
 1;

Added: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/DBIC/Test/SQLite.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/DBIC/Test/SQLite.pm	                        (rev 0)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/DBIC/Test/SQLite.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -0,0 +1,95 @@
+package # hide from PAUSE
+    DBIC::Test::SQLite;
+
+=head1 NAME
+
+DBIx::Class::Test::SQLite - Base class for running Class::DBI tests against DBIx::Class compat layer, shamelessly ripped from Class::DBI::Test::SQLite
+
+=head1 SYNOPSIS
+
+  use base 'DBIx::Class::Test::SQLite';
+
+  __PACKAGE__->set_table('test');
+  __PACKAGE__->columns(All => qw/id name film salary/);
+
+  sub create_sql {
+      return q{
+          id     INTEGER PRIMARY KEY,
+          name   CHAR(40),
+          film   VARCHAR(255),
+          salary INT
+      }
+  }
+    
+=head1 DESCRIPTION
+
+This provides a simple base class for DBIx::Class::CDBICompat tests using
+SQLite.  Each class for the test should inherit from this, provide a
+create_sql() method which returns a string representing the SQL used to
+create the table for the class, and then call set_table() to create the
+table, and tie it to the class.
+
+=cut
+
+use strict;
+use warnings;
+
+use base qw/DBIx::Class/;
+
+__PACKAGE__->load_components(qw/CDBICompat Core DB/);
+
+use File::Temp qw/tempfile/;
+my (undef, $DB) = tempfile();
+END { unlink $DB if -e $DB }
+
+my @DSN = ("dbi:SQLite:dbname=$DB", '', '', { AutoCommit => 1, RaiseError => 1 });
+
+__PACKAGE__->connection(@DSN);
+__PACKAGE__->set_sql(_table_pragma => 'PRAGMA table_info(__TABLE__)');
+__PACKAGE__->set_sql(_create_me    => 'CREATE TABLE __TABLE__ (%s)');
+__PACKAGE__->storage->dbh->do("PRAGMA synchronous = OFF");
+
+=head1 METHODS
+
+=head2 set_table
+
+    __PACKAGE__->set_table('test');
+
+This combines creating the table with the normal DBIx::Class table()
+call.
+
+=cut
+
+sub set_table {
+    my ($class, $table) = @_;
+    $class->table($table);
+    $class->_create_test_table;
+}
+
+sub _create_test_table {
+    my $class = shift;
+    my @vals  = $class->sql__table_pragma->select_row;
+    $class->sql__create_me($class->create_sql)->execute unless @vals;
+}
+
+=head2 create_sql
+
+This is an abstract method you must override.
+
+  sub create_sql {
+      return q{
+          id     INTEGER PRIMARY KEY,
+          name   CHAR(40),
+          film   VARCHAR(255),
+          salary INT
+      }
+  }
+
+This should return, as a text string, the schema for the table represented
+by this class.
+
+=cut
+
+sub create_sql { die "create_sql() not implemented by $_[0]\n" }
+
+1;

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Director.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Director.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Director.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -2,7 +2,7 @@
     Director;
 
 use strict;
-use base 'DBIx::Class::Test::SQLite';
+use base 'DBIC::Test::SQLite';
 
 __PACKAGE__->set_table('Directors');
 __PACKAGE__->columns('All' => qw/ Name Birthday IsInsane /);

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Film.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Film.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Film.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,7 +1,7 @@
 package # hide from PAUSE 
     Film;
 
-use base 'DBIx::Class::Test::SQLite';
+use base 'DBIC::Test::SQLite';
 use strict;
 
 __PACKAGE__->set_table('Movies');

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Lazy.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Lazy.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Lazy.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,7 +1,7 @@
 package # hide from PAUSE 
     Lazy;
 
-use base 'DBIx::Class::Test::SQLite';
+use base 'DBIC::Test::SQLite';
 use strict;
 
 __PACKAGE__->set_table("Lazy");

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/MyBase.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/MyBase.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/MyBase.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -8,9 +8,7 @@
 
 use vars qw/$dbh/;
 
-# temporary, might get switched to the new test framework someday
-my @connect = ("dbi:mysql:test", "", "", { PrintError => 0});
-
+my @connect = (@ENV{map { "DBICTEST_MYSQL_${_}" } qw/DSN USER PASS/}, { PrintError => 0});
 $dbh = DBI->connect(@connect) or die DBI->errstr;
 my @table;
 

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Order.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Order.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Order.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -2,7 +2,7 @@
     Order;
 
 use strict;
-use base 'DBIx::Class::Test::SQLite';
+use base 'DBIC::Test::SQLite';
 
 __PACKAGE__->set_table('orders');
 __PACKAGE__->table_alias('orders');

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/OtherThing.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/OtherThing.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/OtherThing.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,5 +1,5 @@
 package OtherThing;
-use base 'DBIx::Class::Test::SQLite';
+use base 'DBIC::Test::SQLite';
 
 OtherThing->set_table("other_thing");
 OtherThing->columns(All => qw(id));

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Thing.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Thing.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/cdbi/testlib/Thing.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,5 +1,5 @@
 package Thing;
-use base 'DBIx::Class::Test::SQLite';
+use base 'DBIC::Test::SQLite';
 
 Thing->set_table("thing");
 Thing->columns(All => qw(id that_thing));

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Schema/CD.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Schema/CD.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Schema/CD.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -38,7 +38,9 @@
 });
 
 # in case this is a single-cd it promotes a track from another cd
-__PACKAGE__->belongs_to( single_track => 'DBICTest::Schema::Track' );
+__PACKAGE__->belongs_to( single_track => 'DBICTest::Schema::Track', 'single_track', 
+    { join_type => 'left'} 
+);
 
 __PACKAGE__->has_many( tracks => 'DBICTest::Schema::Track' );
 __PACKAGE__->has_many(

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Schema/EventTZ.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Schema/EventTZ.pm	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Schema/EventTZ.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -10,8 +10,8 @@
 
 __PACKAGE__->add_columns(
   id => { data_type => 'integer', is_auto_increment => 1 },
-  starts_at => { data_type => 'datetime', extra => { timezone => "America/Chicago", locale => 'de_DE' } },
-  created_on => { data_type => 'timestamp', extra => { timezone => "America/Chicago", floating_tz_ok => 1 } },
+  starts_at => { data_type => 'datetime', timezone => "America/Chicago", locale => 'de_DE' },
+  created_on => { data_type => 'timestamp', timezone => "America/Chicago", floating_tz_ok => 1 },
 );
 
 __PACKAGE__->set_primary_key('id');

Added: DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Schema/EventTZDeprecated.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Schema/EventTZDeprecated.pm	                        (rev 0)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Schema/EventTZDeprecated.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -0,0 +1,19 @@
+package DBICTest::Schema::EventTZDeprecated;
+
+use strict;
+use warnings;
+use base qw/DBIx::Class::Core/;
+
+__PACKAGE__->load_components(qw/InflateColumn::DateTime/);
+
+__PACKAGE__->table('event');
+
+__PACKAGE__->add_columns(
+  id => { data_type => 'integer', is_auto_increment => 1 },
+  starts_at => { data_type => 'datetime', extra => { timezone => "America/Chicago", locale => 'de_DE' } },
+  created_on => { data_type => 'timestamp', extra => { timezone => "America/Chicago", floating_tz_ok => 1 } },
+);
+
+__PACKAGE__->set_primary_key('id');
+
+1;

Added: DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Taint/Classes/Auto.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Taint/Classes/Auto.pm	                        (rev 0)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Taint/Classes/Auto.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -0,0 +1,7 @@
+package # hide from PAUSE 
+    DBICTest::Taint::Classes::Auto;
+
+use base 'DBIx::Class::Core';
+__PACKAGE__->table('test');
+
+1;

Added: DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Taint/Classes/Manual.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Taint/Classes/Manual.pm	                        (rev 0)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Taint/Classes/Manual.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -0,0 +1,7 @@
+package # hide from PAUSE 
+    DBICTest::Taint::Classes::Manual;
+
+use base 'DBIx::Class::Core';
+__PACKAGE__->table('test');
+
+1;

Added: DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Taint/Namespaces/Result/Test.pm
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Taint/Namespaces/Result/Test.pm	                        (rev 0)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/lib/DBICTest/Taint/Namespaces/Result/Test.pm	2009-05-04 03:30:18 UTC (rev 6119)
@@ -0,0 +1,7 @@
+package # hide from PAUSE 
+    DBICTest::Taint::Namespaces::Result::Test;
+
+use base 'DBIx::Class::Core';
+__PACKAGE__->table('test');
+
+1;

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/lib/sqlite.sql
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/lib/sqlite.sql	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/lib/sqlite.sql	2009-05-04 03:30:18 UTC (rev 6119)
@@ -1,6 +1,6 @@
 -- 
 -- Created by SQL::Translator::Producer::SQLite
--- Created on Sun Feb 22 00:15:06 2009
+-- Created on Thu Apr 30 10:04:57 2009
 -- 
 
 

Added: DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/attrs_untouched.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/attrs_untouched.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/attrs_untouched.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -0,0 +1,46 @@
+use warnings;  
+
+use Test::More;
+use Test::Exception;
+use lib qw(t/lib);
+use DBICTest;
+use Data::Dumper;
+
+my $schema = DBICTest->init_schema();
+
+my $orig_debug = $schema->storage->debug;
+
+use IO::File;
+
+BEGIN {
+    eval "use DBD::SQLite";
+    plan $@
+        ? ( skip_all => 'needs DBD::SQLite for testing' )
+        : ( tests => 3 );
+}
+
+# figure out if we've got a version of sqlite that is older than 3.2.6, in
+# which case COUNT(DISTINCT()) doesn't work
+my $is_broken_sqlite = 0;
+my ($sqlite_major_ver,$sqlite_minor_ver,$sqlite_patch_ver) =
+    split /\./, $schema->storage->dbh->get_info(18);
+if( $schema->storage->dbh->get_info(17) eq 'SQLite' &&
+    ( ($sqlite_major_ver < 3) ||
+      ($sqlite_major_ver == 3 && $sqlite_minor_ver < 2) ||
+      ($sqlite_major_ver == 3 && $sqlite_minor_ver == 2 && $sqlite_patch_ver < 6) ) ) {
+    $is_broken_sqlite = 1;
+}
+
+# bug in 0.07000 caused attr (join/prefetch) to be modifed by search
+# so we check the search & attr arrays are not modified
+my $search = { 'artist.name' => 'Caterwauler McCrae' };
+my $attr = { prefetch => [ qw/artist liner_notes/ ],
+             order_by => 'me.cdid' };
+my $search_str = Dumper($search);
+my $attr_str = Dumper($attr);
+
+my $rs = $schema->resultset("CD")->search($search, $attr);
+
+is(Dumper($search), $search_str, 'Search hash untouched after search()');
+is(Dumper($attr), $attr_str, 'Attribute hash untouched after search()');
+cmp_ok($rs + 0, '==', 3, 'Correct number of records returned');

Added: DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/multiple_hasmany.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/multiple_hasmany.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/multiple_hasmany.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -0,0 +1,172 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use Test::Exception;
+use lib qw(t/lib);
+use DBICTest;
+use Data::Dumper;
+
+my $schema = DBICTest->init_schema();
+
+my $orig_debug = $schema->storage->debug;
+
+use IO::File;
+
+BEGIN {
+    eval "use DBD::SQLite";
+    plan $@
+        ? ( skip_all => 'needs DBD::SQLite for testing' )
+        : ( tests => 16 );
+}
+
+# figure out if we've got a version of sqlite that is older than 3.2.6, in
+# which case COUNT(DISTINCT()) doesn't work
+my $is_broken_sqlite = 0;
+my ($sqlite_major_ver,$sqlite_minor_ver,$sqlite_patch_ver) =
+    split /\./, $schema->storage->dbh->get_info(18);
+if( $schema->storage->dbh->get_info(17) eq 'SQLite' &&
+    ( ($sqlite_major_ver < 3) ||
+      ($sqlite_major_ver == 3 && $sqlite_minor_ver < 2) ||
+      ($sqlite_major_ver == 3 && $sqlite_minor_ver == 2 && $sqlite_patch_ver < 6) ) ) {
+    $is_broken_sqlite = 1;
+}
+
+# once the following TODO is complete, remove the 2 warning tests immediately
+# after the TODO block
+# (the TODO block itself contains tests ensuring that the warns are removed)
+TODO: {
+    local $TODO = 'Prefetch of multiple has_many rels at the same level (currently warn to protect the clueless git)';
+
+    #( 1 -> M + M )
+    my $cd_rs = $schema->resultset('CD')->search ({ 'me.title' => 'Forkful of bees' });
+    my $pr_cd_rs = $cd_rs->search ({}, {
+        prefetch => [qw/tracks tags/],
+    });
+
+    my $tracks_rs = $cd_rs->first->tracks;
+    my $tracks_count = $tracks_rs->count;
+
+    my ($pr_tracks_rs, $pr_tracks_count);
+
+    my $queries = 0;
+    $schema->storage->debugcb(sub { $queries++ });
+    $schema->storage->debug(1);
+
+    my $o_mm_warn;
+    {
+        local $SIG{__WARN__} = sub { $o_mm_warn = shift };
+        $pr_tracks_rs = $pr_cd_rs->first->tracks;
+    };
+    $pr_tracks_count = $pr_tracks_rs->count;
+
+    ok(! $o_mm_warn, 'no warning on attempt to prefetch several same level has_many\'s (1 -> M + M)');
+
+    is($queries, 1, 'prefetch one->(has_many,has_many) ran exactly 1 query');
+    is($pr_tracks_count, $tracks_count, 'equal count of prefetched relations over several same level has_many\'s (1 -> M + M)');
+
+    for ($pr_tracks_rs, $tracks_rs) {
+        $_->result_class ('DBIx::Class::ResultClass::HashRefInflator');
+    }
+
+    is_deeply ([$pr_tracks_rs->all], [$tracks_rs->all], 'same structure returned with and without prefetch over several same level has_many\'s (1 -> M + M)');
+
+    #( M -> 1 -> M + M )
+    my $note_rs = $schema->resultset('LinerNotes')->search ({ notes => 'Buy Whiskey!' });
+    my $pr_note_rs = $note_rs->search ({}, {
+        prefetch => {
+            cd => [qw/tags tracks/]
+        },
+    });
+
+    my $tags_rs = $note_rs->first->cd->tags;
+    my $tags_count = $tags_rs->count;
+
+    my ($pr_tags_rs, $pr_tags_count);
+
+    $queries = 0;
+    $schema->storage->debugcb(sub { $queries++ });
+    $schema->storage->debug(1);
+
+    my $m_o_mm_warn;
+    {
+        local $SIG{__WARN__} = sub { $m_o_mm_warn = shift };
+        $pr_tags_rs = $pr_note_rs->first->cd->tags;
+    };
+    $pr_tags_count = $pr_tags_rs->count;
+
+    ok(! $m_o_mm_warn, 'no warning on attempt to prefetch several same level has_many\'s (M -> 1 -> M + M)');
+
+    is($queries, 1, 'prefetch one->(has_many,has_many) ran exactly 1 query');
+
+    is($pr_tags_count, $tags_count, 'equal count of prefetched relations over several same level has_many\'s (M -> 1 -> M + M)');
+
+    for ($pr_tags_rs, $tags_rs) {
+        $_->result_class ('DBIx::Class::ResultClass::HashRefInflator');
+    }
+
+    is_deeply ([$pr_tags_rs->all], [$tags_rs->all], 'same structure returned with and without prefetch over several same level has_many\'s (M -> 1 -> M + M)');
+}
+
+# remove this closure once the TODO above is working
+my $w;
+{
+    local $SIG{__WARN__} = sub { $w = shift };
+
+    my $rs = $schema->resultset('CD')->search ({ 'me.title' => 'Forkful of bees' }, { prefetch => [qw/tracks tags/] });
+    for (qw/all count next first/) {
+        undef $w;
+        my @stuff = $rs->search()->$_;
+        like ($w, qr/will currently disrupt both the functionality of .rs->count\(\), and the amount of objects retrievable via .rs->next\(\)/,
+            "warning on ->$_ attempt prefetching several same level has_manys (1 -> M + M)");
+    }
+    my $rs2 = $schema->resultset('LinerNotes')->search ({ notes => 'Buy Whiskey!' }, { prefetch => { cd => [qw/tags tracks/] } });
+    for (qw/all count next first/) {
+        undef $w;
+        my @stuff = $rs2->search()->$_;
+        like ($w, qr/will currently disrupt both the functionality of .rs->count\(\), and the amount of objects retrievable via .rs->next\(\)/,
+            "warning on ->$_ attempt prefetching several same level has_manys (M -> 1 -> M + M)");
+    }
+}
+
+__END__
+The solution is to rewrite ResultSet->_collapse_result() and
+ResultSource->resolve_prefetch() to focus on the final results from the collapse
+of the data. Right now, the code doesn't treat the columns from the various
+tables as grouped entities. While there is a concept of hierarchy (so that
+prefetching down relationships does work as expected), there is no idea of what
+the final product should look like and how the various columns in the row would
+play together. So, the actual prefetch datastructure from the search would be
+very useful in working through this problem. We already have access to the PKs
+and sundry for those. So, when collapsing the search result, we know we are
+looking for 1 cd object. We also know we're looking for tracks and tags records
+-independently- of each other. So, we can grab the data for tracks and data for
+tags separately, uniqueing on the PK as appropriate. Then, when we're done with
+the given cd object's datastream, we know we're good. This should work for all
+the various scenarios.
+
+My reccommendation is the row's data is preprocessed first, breaking it up into
+the data for each of the component tables. (This could be done in the single
+table case, too, but probably isn't necessary.) So, starting with something
+like:
+  my $row = {
+    t1.col1 => 1,
+    t1.col2 => 2,
+    t2.col1 => 3,
+    t2.col2 => 4,
+    t3.col1 => 5,
+    t3.col2 => 6,
+  };
+it is massaged to look something like:
+  my $row_massaged = {
+    t1 => { col1 => 1, col2 => 2 },
+    t2 => { col1 => 3, col2 => 4 },
+    t3 => { col1 => 5, col2 => 6 },
+  };
+At this point, find the stuff that's different is easy enough to do and slotting
+things into the right spot is, likewise, pretty straightforward. Instead of
+storing things in a AoH, store them in a HoH keyed on the PKs of the the table,
+then convert to an AoH after all collapsing is done.
+
+This implies that the collapse attribute can probably disappear or, at the
+least, be turned into a boolean (which is how it's used in every other place).

Added: DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/pollute_already_joined.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/pollute_already_joined.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/pollute_already_joined.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -0,0 +1,75 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use Test::Exception;
+use lib qw(t/lib);
+use DBICTest;
+use Data::Dumper;
+
+my $schema = DBICTest->init_schema();
+
+my $orig_debug = $schema->storage->debug;
+
+use IO::File;
+
+BEGIN {
+    eval "use DBD::SQLite";
+    plan $@
+        ? ( skip_all => 'needs DBD::SQLite for testing' )
+        : ( tests => 10 );
+}
+
+# figure out if we've got a version of sqlite that is older than 3.2.6, in
+# which case COUNT(DISTINCT()) doesn't work
+my $is_broken_sqlite = 0;
+my ($sqlite_major_ver,$sqlite_minor_ver,$sqlite_patch_ver) =
+    split /\./, $schema->storage->dbh->get_info(18);
+if( $schema->storage->dbh->get_info(17) eq 'SQLite' &&
+    ( ($sqlite_major_ver < 3) ||
+      ($sqlite_major_ver == 3 && $sqlite_minor_ver < 2) ||
+      ($sqlite_major_ver == 3 && $sqlite_minor_ver == 2 && $sqlite_patch_ver < 6) ) ) {
+    $is_broken_sqlite = 1;
+}
+
+# A search() with prefetch seems to pollute an already joined resultset
+# in a way that offsets future joins (adapted from a test case by Debolaz)
+{
+  my ($cd_rs, $attrs);
+
+  # test a real-life case - rs is obtained by an implicit m2m join
+  $cd_rs = $schema->resultset ('Producer')->first->cds;
+  $attrs = Dumper $cd_rs->{attrs};
+
+  $cd_rs->search ({})->all;
+  is (Dumper ($cd_rs->{attrs}), $attrs, 'Resultset attributes preserved after a simple search');
+
+  lives_ok (sub {
+    $cd_rs->search ({'artist.artistid' => 1}, { prefetch => 'artist' })->all;
+    is (Dumper ($cd_rs->{attrs}), $attrs, 'Resultset attributes preserved after search with prefetch');
+  }, 'first prefetching search ok');
+
+  lives_ok (sub {
+    $cd_rs->search ({'artist.artistid' => 1}, { prefetch => 'artist' })->all;
+    is (Dumper ($cd_rs->{attrs}), $attrs, 'Resultset attributes preserved after another search with prefetch')
+  }, 'second prefetching search ok');
+
+
+  # test a regular rs with an empty seen_join injected - it should still work!
+  $cd_rs = $schema->resultset ('CD');
+  $cd_rs->{attrs}{seen_join}  = {};
+  $attrs = Dumper $cd_rs->{attrs};
+
+  $cd_rs->search ({})->all;
+  is (Dumper ($cd_rs->{attrs}), $attrs, 'Resultset attributes preserved after a simple search');
+
+  lives_ok (sub {
+    $cd_rs->search ({'artist.artistid' => 1}, { prefetch => 'artist' })->all;
+    is (Dumper ($cd_rs->{attrs}), $attrs, 'Resultset attributes preserved after search with prefetch');
+  }, 'first prefetching search ok');
+
+  lives_ok (sub {
+    $cd_rs->search ({'artist.artistid' => 1}, { prefetch => 'artist' })->all;
+    is (Dumper ($cd_rs->{attrs}), $attrs, 'Resultset attributes preserved after another search with prefetch')
+  }, 'second prefetching search ok');
+}

Added: DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/rows_bug.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/rows_bug.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/rows_bug.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -0,0 +1,83 @@
+# Test to ensure we get a consistent result set wether or not we use the
+# prefetch option in combination rows (LIMIT).
+use strict;
+use warnings;
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+plan $@ ? (skip_all => 'needs DBD::SQLite for testing') : (tests => 2);
+
+my $schema = DBICTest->init_schema();
+my $no_prefetch = $schema->resultset('Artist')->search(
+  undef,
+  { rows => 3 }
+);
+
+my $use_prefetch = $schema->resultset('Artist')->search(
+  undef,
+  {
+    prefetch => 'cds',
+    rows     => 3
+  }
+);
+
+my $no_prefetch_count  = 0;
+my $use_prefetch_count = 0;
+
+is($no_prefetch->count, $use_prefetch->count, '$no_prefetch->count == $use_prefetch->count');
+
+TODO: {
+  local $TODO = "This is a difficult bug to fix, workaround is not to use prefetch with rows";
+  $no_prefetch_count++  while $no_prefetch->next;
+  $use_prefetch_count++ while $use_prefetch->next;
+  is(
+    $no_prefetch_count,
+    $use_prefetch_count,
+    "manual row count confirms consistency"
+    . " (\$no_prefetch_count == $no_prefetch_count, "
+    . " \$use_prefetch_count == $use_prefetch_count)"
+  );
+}
+
+__END__
+The fix is to, when using prefetch, take the query and put it into a subquery
+joined to the tables we're prefetching from. This might result in the same
+table being joined once in the main subquery and once in the main query. This
+may actually resolve other, unknown edgecase bugs. It is also the right way
+to do prefetching. Optimizations can come later.
+
+This means that:
+  $foo_rs->search(
+    { ... },
+    {
+      prefetch => 'bar',
+      ...
+    },
+  );
+
+becomes:
+  my $temp = $foo_rs->search(
+    { ... },
+    {
+      join => 'bar',
+      ...
+    },
+  );
+  $foo_rs->storage->schema->resultset('foo')->search(
+    undef,
+    {
+      from => [
+        { me => $temp->as_query },
+      ],
+      prefetch => 'bar',
+    },
+  );
+
+Problem:
+  * The prefetch->join change needs to happen ONLY IF there are conditions
+    that depend on bar being joined.
+  * How will this work when the $rs is further searched on? Those clauses
+    need to be added to the subquery, not the outer one. This is particularly
+    true if rows is added in the attribute later per the Pager.

Added: DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/standard.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/standard.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/prefetch/standard.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -0,0 +1,340 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use Test::Exception;
+use lib qw(t/lib);
+use DBICTest;
+use Data::Dumper;
+
+my $schema = DBICTest->init_schema();
+
+my $orig_debug = $schema->storage->debug;
+
+use IO::File;
+
+BEGIN {
+    eval "use DBD::SQLite";
+    plan $@
+        ? ( skip_all => 'needs DBD::SQLite for testing' )
+        : ( tests => 45 );
+}
+
+# figure out if we've got a version of sqlite that is older than 3.2.6, in
+# which case COUNT(DISTINCT()) doesn't work
+my $is_broken_sqlite = 0;
+my ($sqlite_major_ver,$sqlite_minor_ver,$sqlite_patch_ver) =
+    split /\./, $schema->storage->dbh->get_info(18);
+if( $schema->storage->dbh->get_info(17) eq 'SQLite' &&
+    ( ($sqlite_major_ver < 3) ||
+      ($sqlite_major_ver == 3 && $sqlite_minor_ver < 2) ||
+      ($sqlite_major_ver == 3 && $sqlite_minor_ver == 2 && $sqlite_patch_ver < 6) ) ) {
+    $is_broken_sqlite = 1;
+}
+
+my $queries = 0;
+$schema->storage->debugcb(sub { $queries++; });
+$schema->storage->debug(1);
+
+my $search = { 'artist.name' => 'Caterwauler McCrae' };
+my $attr = { prefetch => [ qw/artist liner_notes/ ],
+             order_by => 'me.cdid' };
+my $search_str = Dumper($search);
+my $attr_str = Dumper($attr);
+
+my $rs = $schema->resultset("CD")->search($search, $attr);
+my @cd = $rs->all;
+
+is($cd[0]->title, 'Spoonful of bees', 'First record returned ok');
+
+ok(!defined $cd[0]->liner_notes, 'No prefetch for NULL LEFT join');
+
+is($cd[1]->{_relationship_data}{liner_notes}->notes, 'Buy Whiskey!', 'Prefetch for present LEFT JOIN');
+
+is(ref $cd[1]->liner_notes, 'DBICTest::LinerNotes', 'Prefetch returns correct class');
+
+is($cd[2]->{_inflated_column}{artist}->name, 'Caterwauler McCrae', 'Prefetch on parent object ok');
+
+is($queries, 1, 'prefetch ran only 1 select statement');
+
+$schema->storage->debug($orig_debug);
+$schema->storage->debugobj->callback(undef);
+
+# test for partial prefetch via columns attr
+my $cd = $schema->resultset('CD')->find(1,
+    {
+      columns => [qw/title artist artist.name/], 
+      join => { 'artist' => {} }
+    }
+);
+ok(eval { $cd->artist->name eq 'Caterwauler McCrae' }, 'single related column prefetched');
+
+# start test for nested prefetch SELECT count
+$queries = 0;
+$schema->storage->debugcb(sub { $queries++ });
+$schema->storage->debug(1);
+
+$rs = $schema->resultset('Tag')->search(
+  {},
+  {
+    prefetch => { cd => 'artist' }
+  }
+);
+
+my $tag = $rs->first;
+
+is( $tag->cd->title, 'Spoonful of bees', 'step 1 ok for nested prefetch' );
+
+is( $tag->cd->artist->name, 'Caterwauler McCrae', 'step 2 ok for nested prefetch');
+
+# count the SELECTs
+#$selects++ if /SELECT(?!.*WHERE 1=0.*)/;
+is($queries, 1, 'nested prefetch ran exactly 1 select statement (excluding column_info)');
+
+$queries = 0;
+
+is($tag->search_related('cd')->search_related('artist')->first->name,
+   'Caterwauler McCrae',
+   'chained belongs_to->belongs_to search_related ok');
+
+is($queries, 0, 'chained search_related after belontgs_to->belongs_to prefetch ran no queries');
+
+$queries = 0;
+
+$cd = $schema->resultset('CD')->find(1, { prefetch => 'artist' });
+
+is($cd->{_inflated_column}{artist}->name, 'Caterwauler McCrae', 'artist prefetched correctly on find');
+
+is($queries, 1, 'find with prefetch ran exactly 1 select statement (excluding column_info)');
+
+$queries = 0;
+
+$schema->storage->debugcb(sub { $queries++; });
+
+$cd = $schema->resultset('CD')->find(1, { prefetch => { cd_to_producer => 'producer' } });
+
+is($cd->producers->first->name, 'Matt S Trout', 'many_to_many accessor ok');
+
+is($queries, 1, 'many_to_many accessor with nested prefetch ran exactly 1 query');
+
+$queries = 0;
+
+my $producers = $cd->search_related('cd_to_producer')->search_related('producer');
+
+is($producers->first->name, 'Matt S Trout', 'chained many_to_many search_related ok');
+
+is($queries, 0, 'chained search_related after many_to_many prefetch ran no queries');
+
+$schema->storage->debug($orig_debug);
+$schema->storage->debugobj->callback(undef);
+
+$rs = $schema->resultset('Tag')->search(
+  {},
+  {
+    join => { cd => 'artist' },
+    prefetch => { cd => 'artist' }
+  }
+);
+
+cmp_ok( $rs->count, '>=', 0, 'nested prefetch does not duplicate joins' );
+
+my ($artist) = $schema->resultset("Artist")->search({ 'cds.year' => 2001 },
+                 { order_by => 'artistid DESC', join => 'cds' });
+
+is($artist->name, 'Random Boy Band', "Join search by object ok");
+
+my @cds = $schema->resultset("CD")->search({ 'liner_notes.notes' => 'Buy Merch!' },
+                               { join => 'liner_notes' });
+
+cmp_ok(scalar @cds, '==', 1, "Single CD retrieved via might_have");
+
+is($cds[0]->title, "Generic Manufactured Singles", "Correct CD retrieved");
+
+my @artists = $schema->resultset("Artist")->search({ 'tags.tag' => 'Shiny' },
+                                       { join => { 'cds' => 'tags' } });
+
+cmp_ok( @artists, '==', 2, "two-join search ok" );
+
+$rs = $schema->resultset("CD")->search(
+  {},
+  { group_by => [qw/ title me.cdid /] }
+);
+
+SKIP: {
+    skip "SQLite < 3.2.6 doesn't understand COUNT(DISTINCT())", 1
+        if $is_broken_sqlite;
+    cmp_ok( $rs->count, '==', 5, "count() ok after group_by on main pk" );
+}
+
+cmp_ok( scalar $rs->all, '==', 5, "all() returns same count as count() after group_by on main pk" );
+
+$rs = $schema->resultset("CD")->search(
+  {},
+  { join => [qw/ artist /], group_by => [qw/ artist.name /] }
+);
+
+SKIP: {
+    skip "SQLite < 3.2.6 doesn't understand COUNT(DISTINCT())", 1
+        if $is_broken_sqlite;
+    cmp_ok( $rs->count, '==', 3, "count() ok after group_by on related column" );
+}
+
+$rs = $schema->resultset("Artist")->search(
+  {},
+      { join => [qw/ cds /], group_by => [qw/ me.name /], having =>{ 'MAX(cds.cdid)'=> \'< 5' } }
+);
+
+cmp_ok( $rs->all, '==', 2, "results ok after group_by on related column with a having" );
+
+$rs = $rs->search( undef, {  having =>{ 'count(*)'=> \'> 2' }});
+
+cmp_ok( $rs->all, '==', 1, "count() ok after group_by on related column with a having" );
+
+$rs = $schema->resultset("Artist")->search(
+        { 'cds.title' => 'Spoonful of bees',
+          'cds_2.title' => 'Forkful of bees' },
+        { join => [ 'cds', 'cds' ] });
+
+SKIP: {
+    skip "SQLite < 3.2.6 doesn't understand COUNT(DISTINCT())", 1
+        if $is_broken_sqlite;
+    cmp_ok($rs->count, '==', 1, "single artist returned from multi-join");
+}
+
+is($rs->next->name, 'Caterwauler McCrae', "Correct artist returned");
+
+$cd = $schema->resultset('Artist')->first->create_related('cds',
+    {
+    title   => 'Unproduced Single',
+    year    => 2007
+});
+
+my $left_join = $schema->resultset('CD')->search(
+    { 'me.cdid' => $cd->cdid },
+    { prefetch => { cd_to_producer => 'producer' } }
+);
+
+cmp_ok($left_join, '==', 1, 'prefetch with no join record present');
+
+$queries = 0;
+$schema->storage->debugcb(sub { $queries++ });
+$schema->storage->debug(1);
+
+my $tree_like =
+     $schema->resultset('TreeLike')->find(5,
+       { join     => { parent => { parent => 'parent' } },
+         prefetch => { parent => { parent => 'parent' } } });
+
+is($tree_like->name, 'quux', 'Bottom of tree ok');
+$tree_like = $tree_like->parent;
+is($tree_like->name, 'baz', 'First level up ok');
+$tree_like = $tree_like->parent;
+is($tree_like->name, 'bar', 'Second level up ok');
+$tree_like = $tree_like->parent;
+is($tree_like->name, 'foo', 'Third level up ok');
+
+$schema->storage->debug($orig_debug);
+$schema->storage->debugobj->callback(undef);
+
+cmp_ok($queries, '==', 1, 'Only one query run');
+
+$tree_like = $schema->resultset('TreeLike')->search({'me.id' => 2});
+$tree_like = $tree_like->search_related('children')->search_related('children')->search_related('children')->first;
+is($tree_like->name, 'quux', 'Tree search_related ok');
+
+$tree_like = $schema->resultset('TreeLike')->search_related('children',
+    { 'children.id' => 3, 'children_2.id' => 4 },
+    { prefetch => { children => 'children' } }
+  )->first;
+is(eval { $tree_like->children->first->children->first->name }, 'quux',
+   'Tree search_related with prefetch ok');
+
+$tree_like = eval { $schema->resultset('TreeLike')->search(
+    { 'children.id' => 3, 'children_2.id' => 6 }, 
+    { join => [qw/children children/] }
+  )->search_related('children', { 'children_4.id' => 7 }, { prefetch => 'children' }
+  )->first->children->first; };
+is(eval { $tree_like->name }, 'fong', 'Tree with multiple has_many joins ok');
+
+# test that collapsed joins don't get a _2 appended to the alias
+
+my $sql = '';
+$schema->storage->debugcb(sub { $sql = $_[1] });
+$schema->storage->debug(1);
+
+eval {
+  my $row = $schema->resultset('Artist')->search_related('cds', undef, {
+    join => 'tracks',
+    prefetch => 'tracks',
+  })->search_related('tracks')->first;
+};
+
+like( $sql, qr/^SELECT tracks_2\.trackid/, "join not collapsed for search_related" );
+
+$schema->storage->debug($orig_debug);
+$schema->storage->debugobj->callback(undef);
+
+$rs = $schema->resultset('Artist');
+$rs->create({ artistid => 4, name => 'Unknown singer-songwriter' });
+$rs->create({ artistid => 5, name => 'Emo 4ever' });
+ at artists = $rs->search(undef, { prefetch => 'cds', order_by => 'artistid' });
+is(scalar @artists, 5, 'has_many prefetch with adjacent empty rows ok');
+
+# -------------
+#
+# Tests for multilevel has_many prefetch
+
+# artist resultsets - with and without prefetch
+my $art_rs = $schema->resultset('Artist');
+my $art_rs_pr = $art_rs->search(
+    {},
+    {
+        join     => [ { cds => ['tracks'] } ],
+        prefetch => [ { cds => ['tracks'] } ],
+        cache    => 1 # last test needs this
+    }
+);
+
+# This test does the same operation twice - once on a
+# set of items fetched from the db with no prefetch of has_many rels
+# The second prefetches 2 levels of has_many
+# We check things are the same by comparing the name or title
+# we build everything into a hash structure and compare the one
+# from each rs to see what differs
+
+sub make_hash_struc {
+    my $rs = shift;
+
+    my $struc = {};
+    foreach my $art ( $rs->all ) {
+        foreach my $cd ( $art->cds ) {
+            foreach my $track ( $cd->tracks ) {
+                $struc->{ $art->name }{ $cd->title }{ $track->title }++;
+            }
+        }
+    }
+    return $struc;
+}
+
+$queries = 0;
+$schema->storage->debugcb(sub { $queries++ });
+$schema->storage->debug(1);
+
+my $prefetch_result = make_hash_struc($art_rs_pr);
+
+is($queries, 1, 'nested prefetch across has_many->has_many ran exactly 1 query');
+
+my $nonpre_result   = make_hash_struc($art_rs);
+
+is_deeply( $prefetch_result, $nonpre_result,
+    'Compare 2 level prefetch result to non-prefetch result' );
+
+$queries = 0;
+
+is($art_rs_pr->search_related('cds')->search_related('tracks')->first->title,
+   'Fowlin',
+   'chained has_many->has_many search_related ok'
+  );
+
+is($queries, 0, 'chained search_related after has_many->has_many prefetch ran no queries');
+

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/resultset/as_query.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/resultset/as_query.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/resultset/as_query.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -7,12 +7,7 @@
 
 use Test::More;
 
-BEGIN {
-    eval "use SQL::Abstract 1.49";
-    plan $@
-        ? ( skip_all => "Needs SQLA 1.49+" )
-        : ( tests => 4 );
-}
+plan ( tests => 4 );
 
 use lib qw(t/lib);
 use DBICTest;

Modified: DBIx-Class/0.08/branches/hierarchical-queries/t/search/subquery.t
===================================================================
--- DBIx-Class/0.08/branches/hierarchical-queries/t/search/subquery.t	2009-05-04 02:03:28 UTC (rev 6118)
+++ DBIx-Class/0.08/branches/hierarchical-queries/t/search/subquery.t	2009-05-04 03:30:18 UTC (rev 6119)
@@ -7,12 +7,7 @@
 
 use Test::More;
 
-BEGIN {
-    eval "use SQL::Abstract 1.49";
-    plan $@
-        ? ( skip_all => "Needs SQLA 1.49+" )
-        : ( tests => 7 );
-}
+plan ( tests => 7 );
 
 use lib qw(t/lib);
 use DBICTest;
@@ -31,7 +26,7 @@
   my ($query, @bind) = @{$$arr};
   is_same_sql_bind(
     $query, \@bind,
-    "SELECT me.cdid,me.artist,me.title,me.year,me.genreid,me.single_track FROM cd me WHERE artist_id IN ( SELECT id FROM artist me LIMIT 1 )",
+    "( SELECT me.cdid,me.artist,me.title,me.year,me.genreid,me.single_track FROM cd me WHERE artist_id IN ( SELECT id FROM artist me LIMIT 1 ) )",
     [],
   );
 }
@@ -50,7 +45,7 @@
   my ($query, @bind) = @{$$arr};
   is_same_sql_bind(
     $query, \@bind,
-    "SELECT (SELECT id FROM cd me LIMIT 1) FROM artist me",
+    "( SELECT (SELECT id FROM cd me LIMIT 1) FROM artist me )",
     [],
   );
 }
@@ -69,7 +64,7 @@
   my ($query, @bind) = @{$$arr};
   is_same_sql_bind(
     $query, \@bind,
-    "SELECT me.artistid, me.name, me.rank, me.charfield, (SELECT id FROM cd me LIMIT 1) FROM artist me",
+    "( SELECT me.artistid, me.name, me.rank, me.charfield, (SELECT id FROM cd me LIMIT 1) FROM artist me )",
     [],
   );
 }
@@ -90,7 +85,7 @@
   my ($query, @bind) = @{$$arr};
   is_same_sql_bind(
     $query, \@bind,
-    "SELECT cd2.cdid, cd2.artist, cd2.title, cd2.year, cd2.genreid, cd2.single_track FROM (SELECT me.cdid,me.artist,me.title,me.year,me.genreid,me.single_track FROM cd me WHERE id > 20) cd2",
+    "( SELECT cd2.cdid, cd2.artist, cd2.title, cd2.year, cd2.genreid, cd2.single_track FROM (SELECT me.cdid,me.artist,me.title,me.year,me.genreid,me.single_track FROM cd me WHERE id > 20) cd2 )",
     [],
   );
 }
@@ -108,7 +103,7 @@
   my ($query, @bind) = @{$$arr};
   is_same_sql_bind(
     $query, \@bind,
-    "SELECT me.artistid, me.name, me.rank, me.charfield FROM artist me JOIN (SELECT me.artist as cds_artist FROM cd me) cds ON me.artistid = cds_artist", []
+    "( SELECT me.artistid, me.name, me.rank, me.charfield FROM artist me JOIN (SELECT me.artist as cds_artist FROM cd me) cds ON me.artistid = cds_artist )", []
   );
 
 
@@ -137,13 +132,14 @@
   my ($query, @bind) = @{$$arr};
   is_same_sql_bind(
     $query, \@bind,
-    "SELECT cd2.cdid, cd2.artist, cd2.title, cd2.year, cd2.genreid, cd2.single_track 
+    "( SELECT cd2.cdid, cd2.artist, cd2.title, cd2.year, cd2.genreid, cd2.single_track 
       FROM 
         (SELECT cd3.cdid,cd3.artist,cd3.title,cd3.year,cd3.genreid,cd3.single_track 
           FROM 
             (SELECT me.cdid,me.artist,me.title,me.year,me.genreid,me.single_track 
               FROM cd me WHERE id < 40) cd3
-          WHERE id > 20) cd2",
+          WHERE id > 20) cd2
+    )",
     [],
   );
 
@@ -162,7 +158,7 @@
   my ($query, @bind) = @{$$arr};
   is_same_sql_bind(
     $query, \@bind,
-    "SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track FROM cd me WHERE year = (SELECT MAX(inner.year) FROM cd inner WHERE artistid = me.artistid)",
+    "( SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track FROM cd me WHERE year = (SELECT MAX(inner.year) FROM cd inner WHERE artistid = me.artistid) )",
     [],
   );
 }




More information about the Bast-commits mailing list