[Bast-commits] r5844 - in DBIx-Class/0.08/branches/multi_stuff: . lib/DBIx lib/DBIx/Class lib/DBIx/Class/CDBICompat lib/DBIx/Class/InflateColumn lib/DBIx/Class/Manual lib/DBIx/Class/Relationship 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/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

ribasushi at dev.catalyst.perl.org ribasushi at dev.catalyst.perl.org
Sun Mar 29 15:38:47 BST 2009


Author: ribasushi
Date: 2009-03-29 15:38:46 +0100 (Sun, 29 Mar 2009)
New Revision: 5844

Added:
   DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Schema/EventTZDeprecated.pm
   DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Taint/
   DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Taint/Classes/
   DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Taint/Classes/Auto.pm
   DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Taint/Classes/Manual.pm
   DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Taint/Namespaces/
   DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Taint/Namespaces/Result/
   DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Taint/Namespaces/Result/Test.pm
   DBIx-Class/0.08/branches/multi_stuff/t/prefetch/
   DBIx-Class/0.08/branches/multi_stuff/t/prefetch/attrs_untouched.t
   DBIx-Class/0.08/branches/multi_stuff/t/prefetch/multiple_hasmany.t
   DBIx-Class/0.08/branches/multi_stuff/t/prefetch/pollute_already_joined.t
   DBIx-Class/0.08/branches/multi_stuff/t/prefetch/rows_bug.t
   DBIx-Class/0.08/branches/multi_stuff/t/prefetch/standard.t
Removed:
   DBIx-Class/0.08/branches/multi_stuff/t/39load_namespaces_rt41083.t
   DBIx-Class/0.08/branches/multi_stuff/t/77prefetch.t
   DBIx-Class/0.08/branches/multi_stuff/t/98rows_prefetch.t
   DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICNGTest/
Modified:
   DBIx-Class/0.08/branches/multi_stuff/
   DBIx-Class/0.08/branches/multi_stuff/Changes
   DBIx-Class/0.08/branches/multi_stuff/Makefile.PL
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class.pm
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/CDBICompat/Retrieve.pm
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/InflateColumn/DateTime.pm
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Manual/Cookbook.pod
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Manual/FAQ.pod
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Manual/Reading.pod
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Relationship/Accessor.pm
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/ResultSet.pm
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/ResultSetColumn.pm
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/ResultSource.pm
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/ResultSource/View.pm
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Row.pm
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Schema.pm
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Schema/Versioned.pm
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Storage/DBI.pm
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Storage/DBI/NoBindVars.pm
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Storage/DBI/ODBC/ACCESS.pm
   DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Storage/DBI/Replicated.pm
   DBIx-Class/0.08/branches/multi_stuff/lib/SQL/Translator/Parser/DBIx/Class.pm
   DBIx-Class/0.08/branches/multi_stuff/t/03podcoverage.t
   DBIx-Class/0.08/branches/multi_stuff/t/04dont_break_c3.t
   DBIx-Class/0.08/branches/multi_stuff/t/33storage_reconnect.t
   DBIx-Class/0.08/branches/multi_stuff/t/54taint.t
   DBIx-Class/0.08/branches/multi_stuff/t/66relationship.t
   DBIx-Class/0.08/branches/multi_stuff/t/72pg.t
   DBIx-Class/0.08/branches/multi_stuff/t/74mssql.t
   DBIx-Class/0.08/branches/multi_stuff/t/89inflate_datetime.t
   DBIx-Class/0.08/branches/multi_stuff/t/91debug.t
   DBIx-Class/0.08/branches/multi_stuff/t/93storage_replication.t
   DBIx-Class/0.08/branches/multi_stuff/t/95sql_maker.t
   DBIx-Class/0.08/branches/multi_stuff/t/95sql_maker_quote.t
   DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Schema/EventTZ.pm
   DBIx-Class/0.08/branches/multi_stuff/t/resultset/as_query.t
   DBIx-Class/0.08/branches/multi_stuff/t/search/subquery.t
Log:
 r5654 at Thesaurus (orig r5653):  ribasushi | 2009-02-27 01:00:46 +0100
  r583 at Thesaurus (orig r4766):  matthewt | 2008-08-24 17:29:27 +0200
  first cut at vairable bind vars for sybase
 
 r5655 at Thesaurus (orig r5654):  ribasushi | 2009-02-27 01:00:53 +0100
 
 r5656 at Thesaurus (orig r5655):  ribasushi | 2009-02-27 01:18:15 +0100
 Reinstate examples after botched merge
 r5658 at Thesaurus (orig r5657):  ribasushi | 2009-02-27 01:32:29 +0100
 Allow sqlt_deploy_hook on views
 r5661 at Thesaurus (orig r5660):  ribasushi | 2009-02-27 02:03:03 +0100
 A couple more makefile prereqs
 r5662 at Thesaurus (orig r5661):  ribasushi | 2009-02-27 02:06:55 +0100
 Throw away namespace::clean dependency
 r5663 at Thesaurus (orig r5662):  ribasushi | 2009-02-27 02:24:37 +0100
 Fix some should_quote_data_type problems
 r5664 at Thesaurus (orig r5663):  ribasushi | 2009-02-27 02:43:18 +0100
 We already depend on latest SQLA - remove all references to >= 1.50 - it will only add to the confusion
 r5666 at Thesaurus (orig r5665):  ribasushi | 2009-02-27 02:59:29 +0100
 Dev-Release 0.08099_07
 r5676 at Thesaurus (orig r5675):  ribasushi | 2009-03-03 10:30:15 +0100
 Rewrite t/54taint.t to properly test load_namespaces()
 r5677 at Thesaurus (orig r5676):  ribasushi | 2009-03-03 10:44:52 +0100
 Extend untainting of findallmod() to load_namespaces as well as load_classes
 r5681 at Thesaurus (orig r5680):  ribasushi | 2009-03-03 22:43:48 +0100
 Clarify sybase/nobindvars problem (should have never merged in the 1st place)
 r5682 at Thesaurus (orig r5681):  ribasushi | 2009-03-03 23:21:29 +0100
 Backout entire sybase/nobindvars/noquote changeset - not ready yet
 r5684 at Thesaurus (orig r5683):  ribasushi | 2009-03-03 23:32:50 +0100
 Put code back into branch (and fix trunk snafu)
 r5686 at Thesaurus (orig r5685):  robkinyon | 2009-03-05 19:17:48 +0100
 Added experimental tag to as_query and subqueries in general
 r5691 at Thesaurus (orig r5690):  robkinyon | 2009-03-06 16:43:40 +0100
  r5672 at rkinyon-lt-osx (orig r5671):  robkinyon | 2009-02-28 22:46:19 -0500
  Added comment to describe the proposed fix in the test
 
 r5692 at Thesaurus (orig r5691):  robkinyon | 2009-03-06 16:43:50 +0100
  r5673 at rkinyon-lt-osx (orig r5672):  robkinyon | 2009-03-01 00:13:38 -0500
  Added more notes to the bottom of the failing testcase
 
 r5693 at Thesaurus (orig r5692):  robkinyon | 2009-03-06 16:44:24 +0100
  r5687 at rkinyon-lt-osx (orig r5686):  robkinyon | 2009-03-06 09:57:38 -0500
  Added solution, though no fix
 
 r5694 at Thesaurus (orig r5693):  robkinyon | 2009-03-06 16:44:34 +0100
  r5688 at rkinyon-lt-osx (orig r5687):  robkinyon | 2009-03-06 10:25:34 -0500
  Intermezzo checkin
 
 r5695 at Thesaurus (orig r5694):  robkinyon | 2009-03-06 16:44:58 +0100
  r5689 at rkinyon-lt-osx (orig r5688):  robkinyon | 2009-03-06 10:30:08 -0500
  Broke up the prefetch tests into their own directory
 
 r5696 at Thesaurus (orig r5695):  robkinyon | 2009-03-06 18:55:52 +0100
 Changed how the EXPERIMENTAL tag for subqueries and as_query is noted
 r5697 at Thesaurus (orig r5696):  ribasushi | 2009-03-06 18:56:54 +0100
 Remove erroneously merged file
 r5701 at Thesaurus (orig r5700):  robkinyon | 2009-03-06 20:57:07 +0100
  r5698 at rkinyon-lt-osx (orig r5697):  robkinyon | 2009-03-06 14:55:57 -0500
  Added solution for prefetch + hasmany bug
  r5700 at rkinyon-lt-osx (orig r5699):  robkinyon | 2009-03-06 14:56:50 -0500
  Fixed documentation for test
 
 r5702 at Thesaurus (orig r5701):  robkinyon | 2009-03-06 22:18:09 +0100
 Added a little more verbiage to explain how collapsing from HRI-form should happen
 r5719 at Thesaurus (orig r5718):  ribasushi | 2009-03-09 13:22:54 +0100
 Disable reconnect test except fpor when AUTHORS is set
 r5720 at Thesaurus (orig r5719):  ribasushi | 2009-03-09 13:23:12 +0100
 One more cdbi-compat author req
 r5721 at Thesaurus (orig r5720):  ribasushi | 2009-03-09 13:42:12 +0100
 Use homegrown AUTHOR detection
 r5722 at Thesaurus (orig r5721):  ribasushi | 2009-03-09 17:29:30 +0100
 Strip bogus Data::Dump requires
 r5728 at Thesaurus (orig r5727):  groditi | 2009-03-09 23:33:50 +0100
 remove (groditi) instances
 r5733 at Thesaurus (orig r5732):  wreis | 2009-03-11 01:56:06 +0100
 fixed View's doc | added me to contributors list
 r5734 at Thesaurus (orig r5733):  ribasushi | 2009-03-11 07:57:05 +0100
 Moose-related test hierarchy not removed at r4326
 r5735 at Thesaurus (orig r5734):  ribasushi | 2009-03-11 10:43:40 +0100
 Allow accessors type single to return defined but false objects (needed for null-pattern style components)
 r5736 at Thesaurus (orig r5735):  ribasushi | 2009-03-11 11:03:06 +0100
 Replace the fallback _dbh_last_insert_id with an explicit exception.
 Currently all known Storage::DBI engines provide their own _dbh_last_insert_id, except for Storage::DBI::Sybase, for which the old sqlite-ish fallback doesn't work anyway: http://rt.cpan.org/Public/Bug/Display.html?id=40265
 r5737 at Thesaurus (orig r5736):  wreis | 2009-03-11 20:25:25 +0100
 removed configure_sqlt method
 r5738 at Thesaurus (orig r5737):  ribasushi | 2009-03-12 00:23:18 +0100
 Properly returb undef/null on single rewlationship accessor
 r5744 at Thesaurus (orig r5743):  matthewt | 2009-03-12 19:35:16 +0100
 warning in author mode to avoid confusing the easily confused
 r5745 at Thesaurus (orig r5744):  castaway | 2009-03-12 21:24:55 +0100
 Document how to overload connect/connection
 
 r5746 at Thesaurus (orig r5745):  castaway | 2009-03-12 21:36:41 +0100
 Add docs in various places to point out how to get the total count of rows for a paged resultset
 
 r5747 at Thesaurus (orig r5746):  castaway | 2009-03-12 23:33:42 +0100
 Add doc on how conditions and attrs are merged when chaining.
 
 r5748 at Thesaurus (orig r5747):  ribasushi | 2009-03-13 00:30:26 +0100
 Move author warning in front of auto_install
 r5754 at Thesaurus (orig r5753):  jmmills | 2009-03-13 13:32:35 +0100
 Added test for source sub-class register_extra_sources warning.
 Sub-classes should not generate this warning - bug via non-inhertiance sorting via register_source.
 
 r5759 at Thesaurus (orig r5758):  arcanez | 2009-03-15 17:14:56 +0100
 update Makefile.PL to require latest C3, C3::Componentised, MRO::Compat
 r5761 at Thesaurus (orig r5760):  arcanez | 2009-03-16 20:53:34 +0100
  * change search_literal to use \[] when passing into search (help with binding order)
  * provide documentation on how to use search instead of search_literal
 
 
 r5762 at Thesaurus (orig r5761):  plu | 2009-03-17 16:31:08 +0100
 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
 r5764 at Thesaurus (orig r5763):  ribasushi | 2009-03-18 00:57:49 +0100
 Basic binary op logic FAIL
 r5769 at Thesaurus (orig r5768):  rafl | 2009-03-18 20:02:07 +0100
 Use MRO::Compat instead of Class::C3 directly.
 r5770 at Thesaurus (orig r5769):  rafl | 2009-03-18 20:02:23 +0100
 Depend on the latest C3::Componentised so we use mro:: on 5.10 and Class::C3 on 5.8.
 r5773 at Thesaurus (orig r5772):  robkinyon | 2009-03-19 18:05:00 +0100
 Special-case handling for (undef,undef) passed to search_rs()
 r5777 at Thesaurus (orig r5776):  robkinyon | 2009-03-19 21:35:37 +0100
 Moved some SQL parsing of ORDER BY from _select_args() to retrieve_from_sql() where it belongs
 r5779 at Thesaurus (orig r5778):  robkinyon | 2009-03-19 21:52:54 +0100
 Commit another fix for arcanez to test
 r5780 at Thesaurus (orig r5779):  robkinyon | 2009-03-19 22:07:06 +0100
 Commit another fix for arcanez to test
 r5785 at Thesaurus (orig r5784):  wdh | 2009-03-20 16:23:40 +0100
 clarify need for scalarref when using db functions with 'default_value' attribute
 r5787 at Thesaurus (orig r5786):  solomon | 2009-03-20 22:41:49 +0100
 Add cookbook entry for dealing with runaway prepared statement cache
 r5792 at Thesaurus (orig r5791):  groditi | 2009-03-22 02:10:30 +0100
 adding test for exception if nullable rel call is not explicitly defined as undef on insert
 r5793 at Thesaurus (orig r5792):  ribasushi | 2009-03-22 22:09:22 +0100
 New SQLA::Test handles () differences *much* better, thus fixing the tests
 r5804 at Thesaurus (orig r5803):  groditi | 2009-03-23 19:16:41 +0100
 skip test doc issue relating to db-side defaults
 r5809 at Thesaurus (orig r5808):  jmmills | 2009-03-24 08:49:54 +0100
 Fixed _register_source to not produce 'register_extra_source' warnings
 when "registering class" isa (or is a sub-class) source class.
 This is not exactly an elegant fix as I had to pass a hash key (as _to_register via $params) with the original source class instance; I was not able to determine inheritance via the result_source_instance (ResultSource::Table) object.
  
 r5816 at Thesaurus (orig r5815):  robkinyon | 2009-03-26 02:09:55 +0100
 Deprecated search_like()
 r5817 at Thesaurus (orig r5816):  lukes | 2009-03-26 10:13:18 +0100
 changed my nick in contribs section
 r5820 at Thesaurus (orig r5819):  castaway | 2009-03-26 14:54:09 +0100
 Improved  metapod docs
 
 r5823 at Thesaurus (orig r5822):  nigel | 2009-03-27 13:21:14 +0100
  r11142 at hex:  nigel | 2009-03-27 12:20:55 +0000
  Removed Cookbook section on pagers that stated page attribute was not required.
  [Since the pager throws an exception if the pager attribute is not specified, 
  this was completely wrong]
 
 r5824 at Thesaurus (orig r5823):  norbi | 2009-03-27 13:30:00 +0100
  r5969 at vger:  mendel | 2009-03-27 13:29:24 +0100
   * Fixed the alphabetical order of the contributors list (that I screwed up, sorry).
 
 r5831 at Thesaurus (orig r5830):  ribasushi | 2009-03-28 22:46:34 +0100
 Bump SQLA and CAG dependencies
 r5832 at Thesaurus (orig r5831):  ribasushi | 2009-03-28 23:05:35 +0100
 Clarify DBIC behavior wrt RDBMS default values
 r5833 at Thesaurus (orig r5832):  ribasushi | 2009-03-29 10:31:47 +0200
 detabify
 r5836 at Thesaurus (orig r5835):  ribasushi | 2009-03-29 10:49:32 +0200
 detabify
 r5837 at Thesaurus (orig r5836):  ribasushi | 2009-03-29 12:06:02 +0200
 Revert r5808 - this is NOT a bug, the warning IS correct
 r5838 at Thesaurus (orig r5837):  ribasushi | 2009-03-29 12:18:19 +0200
 Adjust parenthesis to pass with latest SQLA
 r5839 at Thesaurus (orig r5838):  ribasushi | 2009-03-29 12:22:49 +0200
 Remove failing test before branching



Property changes on: DBIx-Class/0.08/branches/multi_stuff
___________________________________________________________________
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/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:/DBIx-Class/0.08/trunk:5648
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/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/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:5838
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/multi_stuff/Changes
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/Changes	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/Changes	2009-03-29 14:38:46 UTC (rev 5844)
@@ -1,4 +1,9 @@
 Revision history for DBIx::Class
+
+0.08099_07 2009-02-27 02:00:00 (UTC)
+        - 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
         - 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,7 +12,7 @@
           - 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
@@ -15,7 +20,14 @@
         - 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
+        - test for not dying if a column isn't loaded after insert and a rel using
+          it is called. (eg ->new({ name => 'foo'})->bar if bar uses bar_id)
+          - Currently skipped. Changed exception to have a more detailed message
+          - Document the known issue and a possible work around.
+        - search_like() now warns to indicate deprecation in 0.09. (robkinyon)
 
 0.08099_06 2009-01-23 07:30:00 (UTC)
         - Allow a scalarref to be supplied to the 'from' resultset attribute
@@ -30,12 +42,11 @@
           (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

Modified: DBIx-Class/0.08/branches/multi_stuff/Makefile.PL
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/Makefile.PL	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/Makefile.PL	2009-03-29 14:38:46 UTC (rev 5844)
@@ -11,22 +11,22 @@
 
 requires 'Data::Page'               => 2.00;
 requires 'Scalar::Util'             => 0;
-requires 'SQL::Abstract'            => 1.49;
+requires 'SQL::Abstract'            => 1.51;
 requires 'SQL::Abstract::Limit'     => 0.13;
-requires 'Class::C3'                => 0.20;
-requires 'Class::C3::Componentised' => 0;
+requires 'MRO::Compat'              => 0;
+requires 'Class::C3::Componentised' => 1.0004;
 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);  
@@ -45,14 +45,15 @@
 
 tests_recursive '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,
   'Clone'                     => 0,
@@ -60,9 +61,15 @@
   # t/52cycle.t
   'Test::Memory::Cycle'       => 0,
 
+  # t/60core.t
+  'DateTime::Format::MySQL'   => 0,
+
   # t/93storage_replication.t
   'Moose',                    => 0,
   'MooseX::AttributeHelpers'  => 0.12,
+
+  # t/96_is_deteministic_value.t
+  'DateTime::Format::Strptime' => 0,
 );
 
 if ($Module::Install::AUTHOR) {
@@ -76,6 +83,18 @@
 
 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
@@ -204,3 +223,4 @@
   ];
   Meta->write;
 }
+

Modified: DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/CDBICompat/Retrieve.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/CDBICompat/Retrieve.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/CDBICompat/Retrieve.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/lib/DBIx/Class/InflateColumn/DateTime.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/InflateColumn/DateTime.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/InflateColumn/DateTime.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/lib/DBIx/Class/Manual/Cookbook.pod
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Manual/Cookbook.pod	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Manual/Cookbook.pod	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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
@@ -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
@@ -1381,10 +1374,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 +1726,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/multi_stuff/lib/DBIx/Class/Manual/FAQ.pod
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Manual/FAQ.pod	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Manual/FAQ.pod	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/lib/DBIx/Class/Manual/Reading.pod
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Manual/Reading.pod	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Manual/Reading.pod	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/lib/DBIx/Class/Relationship/Accessor.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Relationship/Accessor.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Relationship/Accessor.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/lib/DBIx/Class/ResultSet.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/ResultSet.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/ResultSet.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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,20 @@
 
 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 "search_like() is deprecated and will be removed in 0.09. Use search() instead.";
   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
   my $query = ref $_[0] eq 'HASH' ? { %{shift()} }: {@_};
   $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
@@ -1636,6 +1676,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 +1850,7 @@
   return \%unaliased;
 }
 
-=head2 as_query
+=head2 as_query (EXPERIMENTAL)
 
 =over 4
 
@@ -1821,6 +1864,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(@_) }
@@ -2555,23 +2600,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 +2900,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/multi_stuff/lib/DBIx/Class/ResultSetColumn.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/ResultSetColumn.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/ResultSetColumn.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/lib/DBIx/Class/ResultSource/View.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/ResultSource/View.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/ResultSource/View.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/lib/DBIx/Class/ResultSource.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/ResultSource.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/ResultSource.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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
@@ -1196,7 +1200,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/multi_stuff/lib/DBIx/Class/Row.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Row.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Row.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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().

Modified: DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Schema/Versioned.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Schema/Versioned.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Schema/Versioned.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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);
 

Modified: DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Schema.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Schema.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Schema.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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(@_) }
@@ -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 

Modified: DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Storage/DBI/NoBindVars.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Storage/DBI/NoBindVars.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Storage/DBI/NoBindVars.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/lib/DBIx/Class/Storage/DBI/ODBC/ACCESS.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Storage/DBI/ODBC/ACCESS.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Storage/DBI/ODBC/ACCESS.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/lib/DBIx/Class/Storage/DBI/Replicated.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Storage/DBI/Replicated.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Storage/DBI/Replicated.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -313,7 +313,6 @@
 
     reload_row
     _prep_for_execute
-    configure_sqlt
     
   /],
 );

Modified: DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Storage/DBI.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Storage/DBI.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class/Storage/DBI.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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 );
@@ -1384,14 +1384,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;
@@ -1565,9 +1557,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 {
@@ -1650,7 +1651,6 @@
 
   foreach my $db (@$databases) {
     $sqlt->reset();
-    $sqlt = $self->configure_sqlt($sqlt, $db);
     $sqlt->{schema} = $sqlt_schema;
     $sqlt->producer($db);
 
@@ -1696,7 +1696,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 ) {
@@ -1714,7 +1713,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 )
@@ -1734,17 +1732,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/multi_stuff/lib/DBIx/Class.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/DBIx/Class.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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.08099_07';
 
 $VERSION = eval $VERSION; # numify for warning-free dev releases
 
@@ -219,8 +219,6 @@
 
 caelum: Rafael Kitover <rkitover at cpan.org>
 
-captainL: Luke Saunders <luke.saunders at gmail.com>
-
 castaway: Jess Robinson
 
 claco: Christopher H. Laco
@@ -257,6 +255,8 @@
 
 konobi: Scott McWhirter
 
+lukes: Luke Saunders <luke.saunders at gmail.com>
+
 marcus: Marcus Ramberg <mramberg at cpan.org>
 
 mattlaw: Matt Lawrence
@@ -269,6 +269,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>
@@ -301,6 +303,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 +321,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/multi_stuff/lib/SQL/Translator/Parser/DBIx/Class.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/lib/SQL/Translator/Parser/DBIx/Class.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/lib/SQL/Translator/Parser/DBIx/Class.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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')) {

Modified: DBIx-Class/0.08/branches/multi_stuff/t/03podcoverage.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/03podcoverage.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/03podcoverage.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/t/04dont_break_c3.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/04dont_break_c3.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/04dont_break_c3.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/t/33storage_reconnect.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/33storage_reconnect.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/33storage_reconnect.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -7,8 +7,18 @@
 use lib qw(t/lib);
 use DBICTest;
 
-plan tests => 6;
+# equivalent of $Module::Install::AUTHOR
+my $author = (
+  ( not  -d './inc' )
+    or
+  ( -e ($^O eq 'VMS' ? './inc/_author' : './inc/.author') )
+);
 
+plan $author
+  ? (tests => 6)
+  : (skip_all => 'Test temporarily disabled due to a widespread buggy SQLite version')
+;
+
 my $db_orig = "$FindBin::Bin/var/DBIxClass.db";
 my $db_tmp  = "$db_orig.tmp";
 

Deleted: DBIx-Class/0.08/branches/multi_stuff/t/39load_namespaces_rt41083.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/39load_namespaces_rt41083.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/39load_namespaces_rt41083.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -1,42 +0,0 @@
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-use Test::More;
-
-use lib 't/lib';
-
-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
-}
-
-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'
-    );
-};
-ok(!$@) or diag $@;
-ok(_chk_warning($warnings), 'expected no complaint');
-
-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'
-    );
-};
-ok(!$@) or diag $@;
-ok(_chk_warning($warnings), 'expected no complaint') or diag $warnings;

Modified: DBIx-Class/0.08/branches/multi_stuff/t/54taint.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/54taint.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/54taint.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/t/66relationship.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/66relationship.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/66relationship.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -8,7 +8,7 @@
 
 my $schema = DBICTest->init_schema();
 
-plan tests => 70;
+plan tests => 71;
 
 # 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 unless $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];

Modified: DBIx-Class/0.08/branches/multi_stuff/t/72pg.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/72pg.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/72pg.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -130,10 +130,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],

Modified: DBIx-Class/0.08/branches/multi_stuff/t/74mssql.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/74mssql.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/74mssql.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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( { },

Deleted: DBIx-Class/0.08/branches/multi_stuff/t/77prefetch.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/77prefetch.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/77prefetch.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/t/89inflate_datetime.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/89inflate_datetime.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/89inflate_datetime.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -5,12 +5,14 @@
 use lib qw(t/lib);
 use DBICTest;
 
+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 +54,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/multi_stuff/t/91debug.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/91debug.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/91debug.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/t/93storage_replication.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/93storage_replication.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/93storage_replication.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/t/95sql_maker.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/95sql_maker.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/95sql_maker.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/t/95sql_maker_quote.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/95sql_maker_quote.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/95sql_maker_quote.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/t/98rows_prefetch.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/98rows_prefetch.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/98rows_prefetch.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/t/lib/DBICTest/Schema/EventTZ.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Schema/EventTZ.pm	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Schema/EventTZ.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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');

Copied: DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Schema/EventTZDeprecated.pm (from rev 5529, DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Schema/EventTZ.pm)
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Schema/EventTZDeprecated.pm	                        (rev 0)
+++ DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Schema/EventTZDeprecated.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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;

Copied: DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Taint (from rev 5335, DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Plain)

Added: DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Taint/Classes/Auto.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Taint/Classes/Auto.pm	                        (rev 0)
+++ DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Taint/Classes/Auto.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/t/lib/DBICTest/Taint/Classes/Manual.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Taint/Classes/Manual.pm	                        (rev 0)
+++ DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Taint/Classes/Manual.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/t/lib/DBICTest/Taint/Namespaces/Result/Test.pm
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Taint/Namespaces/Result/Test.pm	                        (rev 0)
+++ DBIx-Class/0.08/branches/multi_stuff/t/lib/DBICTest/Taint/Namespaces/Result/Test.pm	2009-03-29 14:38:46 UTC (rev 5844)
@@ -0,0 +1,7 @@
+package # hide from PAUSE 
+    DBICTest::Taint::Namespaces::Result::Test;
+
+use base 'DBIx::Class::Core';
+__PACKAGE__->table('test');
+
+1;

Added: DBIx-Class/0.08/branches/multi_stuff/t/prefetch/attrs_untouched.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/prefetch/attrs_untouched.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/multi_stuff/t/prefetch/attrs_untouched.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/t/prefetch/multiple_hasmany.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/prefetch/multiple_hasmany.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/multi_stuff/t/prefetch/multiple_hasmany.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/t/prefetch/pollute_already_joined.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/prefetch/pollute_already_joined.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/multi_stuff/t/prefetch/pollute_already_joined.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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');
+}

Copied: DBIx-Class/0.08/branches/multi_stuff/t/prefetch/rows_bug.t (from rev 5335, DBIx-Class/0.08/branches/multi_stuff/t/98rows_prefetch.t)
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/prefetch/rows_bug.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/multi_stuff/t/prefetch/rows_bug.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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.

Copied: DBIx-Class/0.08/branches/multi_stuff/t/prefetch/standard.t (from rev 5652, DBIx-Class/0.08/branches/multi_stuff/t/77prefetch.t)
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/prefetch/standard.t	                        (rev 0)
+++ DBIx-Class/0.08/branches/multi_stuff/t/prefetch/standard.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/t/resultset/as_query.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/resultset/as_query.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/resultset/as_query.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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/multi_stuff/t/search/subquery.t
===================================================================
--- DBIx-Class/0.08/branches/multi_stuff/t/search/subquery.t	2009-03-29 11:02:43 UTC (rev 5843)
+++ DBIx-Class/0.08/branches/multi_stuff/t/search/subquery.t	2009-03-29 14:38:46 UTC (rev 5844)
@@ -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