[Bast-commits] r5585 - in DBIx-Class/0.08/branches/views: .
lib/DBIx lib/DBIx/Class lib/DBIx/Class/Manual
lib/DBIx/Class/Relationship lib/DBIx/Class/Storage
lib/DBIx/Class/Storage/DBI lib/DBIx/Class/Storage/DBI/Oracle
lib/DBIx/Class/Storage/DBI/Replicated t t/96multi_create
t/lib t/lib/DBIC t/lib/DBICNSTest t/lib/DBICNSTest/RtBug41083
t/lib/DBICNSTest/RtBug41083/ResultSet
t/lib/DBICNSTest/RtBug41083/ResultSet_A
t/lib/DBICNSTest/RtBug41083/Schema
t/lib/DBICNSTest/RtBug41083/Schema/Foo
t/lib/DBICNSTest/RtBug41083/Schema_A
t/lib/DBICNSTest/RtBug41083/Schema_A/A t/lib/DBICTest
t/lib/DBICTest/Schema t/resultset t/search
matthewt at dev.catalyst.perl.org
matthewt at dev.catalyst.perl.org
Fri Feb 20 07:54:30 GMT 2009
Author: matthewt
Date: 2009-02-20 07:54:30 +0000 (Fri, 20 Feb 2009)
New Revision: 5585
Added:
DBIx-Class/0.08/branches/views/t/39load_namespaces_rt41083.t
DBIx-Class/0.08/branches/views/t/96multi_create/
DBIx-Class/0.08/branches/views/t/96multi_create/cd_single.t
DBIx-Class/0.08/branches/views/t/96multi_create_new.t
DBIx-Class/0.08/branches/views/t/96multi_create_torture.t
DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/
DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/ResultSet.pm
DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/ResultSet/
DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/ResultSet/Foo.pm
DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/ResultSet_A/
DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/ResultSet_A/A.pm
DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema/
DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema/Foo.pm
DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema/Foo/
DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema/Foo/Sub.pm
DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema_A/
DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema_A/A.pm
DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema_A/A/
DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema_A/A/Sub.pm
DBIx-Class/0.08/branches/views/t/lib/DBICTest/Schema/Artwork_to_Artist.pm
DBIx-Class/0.08/branches/views/t/resultset/
DBIx-Class/0.08/branches/views/t/resultset/as_query.t
DBIx-Class/0.08/branches/views/t/search/
DBIx-Class/0.08/branches/views/t/search/subquery.t
Modified:
DBIx-Class/0.08/branches/views/
DBIx-Class/0.08/branches/views/Changes
DBIx-Class/0.08/branches/views/Makefile.PL
DBIx-Class/0.08/branches/views/lib/DBIx/Class.pm
DBIx-Class/0.08/branches/views/lib/DBIx/Class/Manual/Cookbook.pod
DBIx-Class/0.08/branches/views/lib/DBIx/Class/Manual/FAQ.pod
DBIx-Class/0.08/branches/views/lib/DBIx/Class/Relationship/Accessor.pm
DBIx-Class/0.08/branches/views/lib/DBIx/Class/Relationship/Base.pm
DBIx-Class/0.08/branches/views/lib/DBIx/Class/ResultSet.pm
DBIx-Class/0.08/branches/views/lib/DBIx/Class/ResultSetColumn.pm
DBIx-Class/0.08/branches/views/lib/DBIx/Class/Row.pm
DBIx-Class/0.08/branches/views/lib/DBIx/Class/Schema.pm
DBIx-Class/0.08/branches/views/lib/DBIx/Class/Storage/DBI.pm
DBIx-Class/0.08/branches/views/lib/DBIx/Class/Storage/DBI/Cursor.pm
DBIx-Class/0.08/branches/views/lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm
DBIx-Class/0.08/branches/views/lib/DBIx/Class/Storage/DBI/Replicated/Pool.pm
DBIx-Class/0.08/branches/views/t/03podcoverage.t
DBIx-Class/0.08/branches/views/t/66relationship.t
DBIx-Class/0.08/branches/views/t/72pg.t
DBIx-Class/0.08/branches/views/t/73oracle.t
DBIx-Class/0.08/branches/views/t/76joins.t
DBIx-Class/0.08/branches/views/t/81transactions.t
DBIx-Class/0.08/branches/views/t/86sqlt.t
DBIx-Class/0.08/branches/views/t/96multi_create.t
DBIx-Class/0.08/branches/views/t/bindtype_columns.t
DBIx-Class/0.08/branches/views/t/lib/DBIC/SqlMakerTest.pm
DBIx-Class/0.08/branches/views/t/lib/DBICTest/Schema.pm
DBIx-Class/0.08/branches/views/t/lib/DBICTest/Schema/Artist.pm
DBIx-Class/0.08/branches/views/t/lib/DBICTest/Schema/Artwork.pm
DBIx-Class/0.08/branches/views/t/lib/sqlite.sql
Log:
r27793 at agaton (orig r5454): nigel | 2009-02-11 15:07:28 +0000
r10743 at hex: nigel | 2009-02-11 15:07:05 +0000
Documentation update on startup speed
r27797 at agaton (orig r5458): groditi | 2009-02-12 01:49:26 +0000
fixed bug for undef_on_null_fk edge case
r27802 at agaton (orig r5463): nigel | 2009-02-12 14:27:38 +0000
r10772 at hex: nigel | 2009-02-12 14:27:22 +0000
Made update() on a rs that includes joins complain in the same way that delete() does. Added tests for both update and delete checks.
r27803 at agaton (orig r5464): plu | 2009-02-13 10:27:36 +0000
Refactored and re-added r5041: Split sql statements for deploy only if SQLT::Producer returned a scalar containing all statements to be executed
r27804 at agaton (orig r5465): caelum | 2009-02-13 10:40:55 +0000
Some fixes for Oracle edge cases
r27805 at agaton (orig r5466): ribasushi | 2009-02-13 10:45:46 +0000
Some forgotten tests
r27806 at agaton (orig r5467): caelum | 2009-02-13 11:29:37 +0000
Throw exception on invalidated session if in a transaction.
r27810 at agaton (orig r5471): ribasushi | 2009-02-15 00:44:02 +0000
Make 81transactions.t DBIC_TRACE friendly
r27811 at agaton (orig r5472): ribasushi | 2009-02-15 00:45:44 +0000
A dbh_do statement executed with bind values will confuse the hell out of DBIC running in DBIC_TRACE=1 mode - stop sending TMI to _query_[start|end] from within dbh_do/_do_query
r27813 at agaton (orig r5474): plu | 2009-02-15 14:20:25 +0000
RT#38251: DBIx::Class::Storage::DBI::Oracle::Generic does not handle fully-qualified table names
r27818 at agaton (orig r5479): caelum | 2009-02-15 23:30:00 +0000
Improved connected logic for Oracle storage
r27819 at agaton (orig r5480): caelum | 2009-02-16 00:20:27 +0000
sorry, I fucked up the indentation...
r27820 at agaton (orig r5481): ribasushi | 2009-02-16 08:48:49 +0000
Some cleanups of oracle patch
r27828 at agaton (orig r5489): robkinyon | 2009-02-16 21:27:49 +0000
Added a bit of explanation to resultsets to cut down on the repeated questions in #dbix-class
r27830 at agaton (orig r5491): robkinyon | 2009-02-16 22:09:12 +0000
r5378 at rkinyon-lt-osx (orig r5377): robkinyon | 2009-01-29 15:58:53 -0500
Branch for subquery support
r5443 at rkinyon-lt-osx (orig r5442): robkinyon | 2009-02-10 15:10:10 -0500
Added as_query to ResultSet with a couple tests
r5444 at rkinyon-lt-osx (orig r5443): robkinyon | 2009-02-10 15:23:27 -0500
Added as_query() support to ResultSetColumn
r5446 at rkinyon-lt-osx (orig r5445): robkinyon | 2009-02-10 17:53:48 -0500
Switched to use is_same_sql_bind() per ribasushi's suggestion
r5453 at rkinyon-lt-osx (orig r5452): robkinyon | 2009-02-11 09:45:23 -0500
check in bombing test for subquery-with-as_query
r5458 at rkinyon-lt-osx (orig r5457): robkinyon | 2009-02-11 11:24:11 -0500
Checking in failing test
r5470 at rkinyon-lt-osx (orig r5469): robkinyon | 2009-02-13 14:43:12 -0500
Added as_sql and as_subselect as wrappers around as_query
r5471 at rkinyon-lt-osx (orig r5470): robkinyon | 2009-02-13 14:56:40 -0500
Added a passing test for initial simple subqueries
r5479 at rkinyon-lt-osx (orig r5478): robkinyon | 2009-02-15 11:23:46 -0500
Subqueries are done
r27838 at agaton (orig r5499): norbi | 2009-02-17 20:09:40 +0000
r5616 at vger: mendel | 2009-02-17 20:39:09 +0100
* Fixed to make it work with [colname => value] bind value format of SQLA.
r27839 at agaton (orig r5500): norbi | 2009-02-17 20:09:47 +0000
r5621 at vger: mendel | 2009-02-17 21:09:08 +0100
* Updated POD for using PostgreSQL arrays because of the \[$sql, @bind] bind value format change of SQLA.
r27840 at agaton (orig r5501): norbi | 2009-02-17 20:44:19 +0000
r5624 at vger: mendel | 2009-02-17 21:11:58 +0100
* Fixed the initial DROP TABLE statement (used to drop the wrong table).
r27841 at agaton (orig r5502): norbi | 2009-02-17 20:44:26 +0000
r5625 at vger: mendel | 2009-02-17 21:43:54 +0100
* Fixed the bug with omitting 'FOR UPDATE'/'FOR SHARED' (introduced from the 'subquery' branch, made 72pg.t fail).
r27842 at agaton (orig r5503): norbi | 2009-02-17 20:56:09 +0000
r5628 at vger: mendel | 2009-02-17 21:55:54 +0100
* Added the missing POD of a sub.
r27843 at agaton (orig r5504): norbi | 2009-02-17 21:08:05 +0000
r5630 at vger: mendel | 2009-02-17 22:07:56 +0100
* Fixed the bug in the test that made it fail in the END block even if all tests were SKIPped.
r27844 at agaton (orig r5505): castaway | 2009-02-17 21:22:05 +0000
Add multiple database/schema FAQs
r27845 at agaton (orig r5506): norbi | 2009-02-17 21:22:57 +0000
r5632 at vger: mendel | 2009-02-17 22:22:50 +0100
* Added new test subs (is_same_sql, is_same_bind) and new predicate sub (eq_sql_bind) to DBIC::SqlMakerTest (SQL::Abstract::Test has these, so made them available here, too).
r27846 at agaton (orig r5507): caelum | 2009-02-17 21:58:34 +0000
minor Oracle changes
r27847 at agaton (orig r5508): caelum | 2009-02-17 22:39:59 +0000
changed WriteAll; to WriteAll(); in Makefile.PL because of some sort of installation weirdness in some places
r27848 at agaton (orig r5509): caelum | 2009-02-17 22:52:28 +0000
changed DBD::SQLite from a test_requires to a configure_requires
r27849 at agaton (orig r5510): norbi | 2009-02-17 23:09:49 +0000
r5635 at vger: mendel | 2009-02-18 00:09:36 +0100
* Added new TODO tests for bind attributes (for ->select, ->update, ->delete).
r27860 at agaton (orig r5521): jnapiorkowski | 2009-02-18 19:35:19 +0000
I guess ensure_connected does not have a return value... so I cannot use it. Fix for replication issue where replicants always get marked as unavailable even when there is no problem with them
r27864 at agaton (orig r5525): robkinyon | 2009-02-18 19:59:26 +0000
r5515 at rkinyon-lt-osx (orig r5514): robkinyon | 2009-02-17 21:37:09 -0500
Moved the actual subquery test to a new subquery testfile
r5516 at rkinyon-lt-osx (orig r5515): robkinyon | 2009-02-17 21:50:16 -0500
Added TODO tests for +select and from with as_query
r5517 at rkinyon-lt-osx (orig r5516): robkinyon | 2009-02-17 22:06:02 -0500
The tests are truly failing tests
r5518 at rkinyon-lt-osx (orig r5517): robkinyon | 2009-02-18 11:52:42 -0500
as_query now provides its own parens
r5519 at rkinyon-lt-osx (orig r5518): robkinyon | 2009-02-18 14:10:51 -0500
Alias properly checks ->{attrs}{alias}
r5520 at rkinyon-lt-osx (orig r5519): robkinyon | 2009-02-18 14:13:27 -0500
Fixed a test expectation so the right failure is reported
r5521 at rkinyon-lt-osx (orig r5520): robkinyon | 2009-02-18 14:19:28 -0500
Marked tests as TODO for later
r5523 at rkinyon-lt-osx (orig r5522): robkinyon | 2009-02-18 14:54:31 -0500
Added my name
r5524 at rkinyon-lt-osx (orig r5523): robkinyon | 2009-02-18 14:58:21 -0500
Added some more POD in the Cookbook for correlated subqueries
r27865 at agaton (orig r5526): castaway | 2009-02-18 21:52:02 +0000
Improved docs/description lots
r27875 at agaton (orig r5536): robkinyon | 2009-02-20 03:11:07 +0000
r5529 at rkinyon-lt-osx (orig r5528): michaelr | 2009-02-18 21:24:44 -0500
added another TODO test for a nested from =>
r5536 at rkinyon-lt-osx (orig r5535): robkinyon | 2009-02-19 22:07:24 -0500
Fixed failing test
r27878 at agaton (orig r5539): jmmills | 2009-02-20 03:27:41 +0000
Modfied isa() check in set_from_related() to use class name returned from relationship_info() rather than class() accessor on object. This fixes an issue when using with Catalyst::Model::DBIC::Schema.
r27882 at agaton (orig r5543): caelum | 2009-02-20 03:57:18 +0000
added timeout to sqlite health check because some buggy versions of sqlite just hang
r27888 at agaton (orig r5549): matthewt | 2009-02-20 04:31:50 +0000
r27529 at agaton (orig r5341): ribasushi | 2009-01-24 18:28:29 +0000
small refactor
r27889 at agaton (orig r5550): matthewt | 2009-02-20 04:34:55 +0000
r27530 at agaton (orig r5342): ribasushi | 2009-01-24 18:39:02 +0000
merge from branches/multicreate
r27890 at agaton (orig r5551): matthewt | 2009-02-20 04:35:02 +0000
r27531 at agaton (orig r5343): ribasushi | 2009-01-24 18:44:08 +0000
that's it
r27891 at agaton (orig r5552): matthewt | 2009-02-20 04:35:07 +0000
r27538 at agaton (orig r5350): matthewt | 2009-01-25 22:27:59 +0000
extract test
r27892 at agaton (orig r5553): matthewt | 2009-02-20 04:35:14 +0000
r27748 at agaton (orig r5409): groditi | 2009-02-04 21:23:06 +0000
adding failing test to make sure insert doesnt call set_column
r27893 at agaton (orig r5554): matthewt | 2009-02-20 04:35:19 +0000
r27749 at agaton (orig r5410): groditi | 2009-02-04 22:19:45 +0000
use store_column instead of set_column on insert
r27895 at agaton (orig r5556): matthewt | 2009-02-20 04:35:25 +0000
r27750 at agaton (orig r5411): groditi | 2009-02-05 02:35:41 +0000
adding regression test for source_name
r27896 at agaton (orig r5557): matthewt | 2009-02-20 04:35:35 +0000
r27769 at agaton (orig r5430): ribasushi | 2009-02-09 09:37:34 +0000
Remove bogus test:
mst: r5411 is groditi testing a fixed bug.
r27897 at agaton (orig r5558): matthewt | 2009-02-20 04:36:11 +0000
r27898 at agaton (orig r5559): matthewt | 2009-02-20 04:36:18 +0000
r27872 at agaton (orig r5533): matthewt | 2009-02-20 02:22:47 +0000
add DBIC_MULTICREATE_DEBUG, fix one bug with column values not being transferred
r27899 at agaton (orig r5560): matthewt | 2009-02-20 04:36:45 +0000
r27877 at agaton (orig r5538): robkinyon | 2009-02-20 03:18:05 +0000
Fixed some tests so they're now passing (things like bad plans and pod-coverage)
r27901 at agaton (orig r5562): robkinyon | 2009-02-20 04:37:12 +0000
r5547 at rkinyon-lt-osx (orig r5546): robkinyon | 2009-02-19 23:29:39 -0500
Added qualifiers as to when as_query will work
r27902 at agaton (orig r5563): robkinyon | 2009-02-20 04:41:44 +0000
Fixed syntax error
r27905 at agaton (orig r5566): matthewt | 2009-02-20 04:42:42 +0000
r27879 at agaton (orig r5540): robkinyon | 2009-02-20 03:30:17 +0000
fixed a few more test situations
r27906 at agaton (orig r5567): matthewt | 2009-02-20 04:42:54 +0000
r27883 at agaton (orig r5544): matthewt | 2009-02-20 04:09:04 +0000
prevent objects implicitly passed via new_related having insertion cascaded to them unless we have to
r27907 at agaton (orig r5568): matthewt | 2009-02-20 04:43:04 +0000
r27884 at agaton (orig r5545): matthewt | 2009-02-20 04:26:22 +0000
verify non-staged insertion as well
r27908 at agaton (orig r5569): matthewt | 2009-02-20 04:43:22 +0000
r27911 at agaton (orig r5572): matthewt | 2009-02-20 04:50:50 +0000
changes update for mc fixes
r27914 at agaton (orig r5575): robkinyon | 2009-02-20 04:54:26 +0000
r5565 at rkinyon-lt-osx (orig r5564): michaelr | 2009-02-19 23:42:15 -0500
fixed from => subquery test. added from => nested subquery test
r5571 at rkinyon-lt-osx (orig r5570): michaelr | 2009-02-19 23:49:06 -0500
added support for from => $rs->as_query
r5572 at rkinyon-lt-osx (orig r5571): robkinyon | 2009-02-19 23:50:06 -0500
Update Changes
r5574 at rkinyon-lt-osx (orig r5573): robkinyon | 2009-02-19 23:53:34 -0500
Added depedency guards
r27915 at agaton (orig r5576): jmmills | 2009-02-20 06:42:38 +0000
r6230 at ofelia (orig r5167): jmmills | 2008-11-20 04:45:48 -0800
Test written.
Currently fails.
r27916 at agaton (orig r5577): jmmills | 2009-02-20 06:42:56 +0000
r6232 at ofelia (orig r5169): jmmills | 2008-11-20 07:29:29 -0800
Added weird passes/failes test
r27917 at agaton (orig r5578): jmmills | 2009-02-20 06:43:11 +0000
r6233 at ofelia (orig r5170): jmmills | 2008-11-20 07:30:48 -0800
cleaned out unneeded test packages
r27918 at agaton (orig r5579): jmmills | 2009-02-20 06:43:28 +0000
r6277 at ofelia (orig r5252): jmmills | 2008-12-16 22:13:07 -0800
A simple fix to the warning generated by a sub-classed proxy - Please verify.
r27919 at agaton (orig r5580): jmmills | 2009-02-20 06:43:42 +0000
r6401 at ofelia (orig r5436): jmmills | 2009-02-09 16:23:28 -0800
Modified fix - removed %done tracking and replaced with a more elegant and proper isa() sorting.
The core issue with this bug was that sub classes resultset class would be set before the related parent|super class
was to have it's resultset class. This would cause problems since sub-classes inherit resultset classes from it's parent.
Fix is simple, sort the source classes via sub-class last.
r27920 at agaton (orig r5581): jmmills | 2009-02-20 06:45:44 +0000
r6402 at ofelia (orig r5437): jmmills | 2009-02-09 21:30:07 -0800
Merged trunk in to rt_bug_t41083 branch via svk merge.
r27921 at agaton (orig r5582): caelum | 2009-02-20 07:03:02 +0000
check a couple more signals during sqlite health check
r27922 at agaton (orig r5583): matthewt | 2009-02-20 07:07:46 +0000
revert previous revision
Property changes on: DBIx-Class/0.08/branches/views
___________________________________________________________________
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:5420
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
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/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/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/versioned_enhancements:4125
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/versioning:4578
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: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_trunk:10772
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/complex_join_rels:4589
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/file_column:3920
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/multi_stuff:5565
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/on_disconnect_do:3694
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/oracle_sequence:4173
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/parser_fk_index:4485
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/replication_dedux:4600
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/rt_bug_41083:5437
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/savepoints:4223
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/sqla_1.50_compat:5321
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/storage-ms-access:4142
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/subquery:5574
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/trunk:5583
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/views/Changes
===================================================================
--- DBIx-Class/0.08/branches/views/Changes 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/Changes 2009-02-20 07:54:30 UTC (rev 5585)
@@ -1,5 +1,15 @@
Revision history for DBIx::Class
+ - Add DBIC_MULTICREATE_DEBUG env var (undocumented, quasi-internal)
+ - Fix up multi-create to:
+ - correctly propagate columns loaded during multi-insert of rels
+ - 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)
+ - Split sql statements for deploy only if SQLT::Producer returned a scalar
+ containing all statements to be executed
+ - Add as_query() for ResultSet and ResultSetColumn. This makes subqueries
+ possible. See the Cookbook for details. (robkinyon, michaelr)
0.08099_06 2009-01-23 07:30:00 (UTC)
- Allow a scalarref to be supplied to the 'from' resultset attribute
@@ -19,6 +29,7 @@
- PG array datatype supported with SQLA >= 1.50
- 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)
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/views/Makefile.PL
===================================================================
--- DBIx-Class/0.08/branches/views/Makefile.PL 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/Makefile.PL 2009-02-20 07:54:30 UTC (rev 5585)
@@ -1,6 +1,7 @@
use inc::Module::Install 0.67;
use strict;
use warnings;
+use POSIX ();
use 5.006001; # delete this line if you want to send patches for earlier.
@@ -25,11 +26,13 @@
requires 'Path::Class' => 0;
requires 'List::Util' => 1.19;
requires 'Sub::Name' => 0.04;
+requires 'namespace::clean' => 0.09;
# Perl 5.8.0 doesn't have utf8::is_utf8()
requires 'Encode' => 0 if ($] <= 5.008000);
-test_requires 'DBD::SQLite' => 1.14;
+configure_requires 'DBD::SQLite' => 1.14;
+
test_requires 'Test::Builder' => 0.33;
test_requires 'Test::Warn' => 0.11;
test_requires 'Test::Exception' => 0;
@@ -117,9 +120,15 @@
exit 0;
}
else {
- wait();
+ eval {
+ local $SIG{ALRM} = sub { die "timeout\n" };
+ alarm 5;
+ wait();
+ alarm 0;
+ };
my $sig = $? & 127;
- if ($sig == 11) {
+ if ($@ || $sig == POSIX::SIGSEGV() || $sig == POSIX::SIGABRT()
+ || $sig == 7) {
warn (<<EOE);
############################### WARNING #################################
@@ -145,7 +154,7 @@
}
-WriteAll;
+WriteAll();
if ($Module::Install::AUTHOR) {
Modified: DBIx-Class/0.08/branches/views/lib/DBIx/Class/Manual/Cookbook.pod
===================================================================
--- DBIx-Class/0.08/branches/views/lib/DBIx/Class/Manual/Cookbook.pod 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/lib/DBIx/Class/Manual/Cookbook.pod 2009-02-20 07:54:30 UTC (rev 5585)
@@ -295,6 +295,55 @@
are in any way unsure about the use of the attributes above (C< join
>, C< select >, C< as > and C< group_by >).
+=head2 Subqueries
+
+You can write subqueries relatively easily in DBIC.
+
+ my $inside_rs = $schema->resultset('Artist')->search({
+ name => [ 'Billy Joel', 'Brittany Spears' ],
+ });
+
+ my $rs = $schema->resultset('CD')->search({
+ artist_id => { 'IN' => $inside_rs->get_column('id')->as_query },
+ });
+
+The usual operators ( =, !=, IN, NOT IN, etc) are supported.
+
+B<NOTE>: You have to explicitly use '=' when doing an equality comparison.
+The following will B<not> work:
+
+ my $rs = $schema->resultset('CD')->search({
+ artist_id => $inside_rs->get_column('id')->as_query,
+ });
+
+=head3 Correlated subqueries
+
+ my $cdrs = $schema->resultset('CD');
+ my $rs = $cdrs->search({
+ year => {
+ '=' => $cdrs->search(
+ { artistid => { '=' => \'me.artistid' } },
+ { alias => 'inner' }
+ )->get_column('year')->max_rs->as_query,
+ },
+ });
+
+That creates the following SQL:
+
+ 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
+ )
+
+=head2 Where subqueries will work
+
+Currently, subqueries will B<only> work in the where-clause of a search. In
+other words, in the first hashref of a search() method. Work is being done
+to make them work as part of the second hashref (from, select, +select, etc).
+
=head2 Predefined searches
You can write your own L<DBIx::Class::ResultSet> class by inheriting from it
@@ -812,7 +861,7 @@
my $hash_ref = $rs->find(1);
Wasn't that easy?
-
+
=head2 Get raw data for blindingly fast results
If the L<HashRefInflator|DBIx::Class::ResultClass::HashRefInflator> solution
@@ -1358,12 +1407,16 @@
$resultset->search(
{
- numbers => \[ '= ?', [1, 2, 3] ]
+ numbers => \[ '= ?', [numbers => [1, 2, 3]] ]
}
);
See L<SQL::Abstract/array_datatypes> and L<SQL::Abstract/Literal SQL with
-placeholders and bind values (subqueries)> for more explanation.
+placeholders and bind values (subqueries)> for more explanation. Note that
+L<DBIx::Class> sets L<SQL::Abstract/bindtype> to C<columns>, so you must pass
+the bind values (the C<[1, 2, 3]> arrayref in the above example) wrapped in
+arrayrefs together with the column name, like this: C<< [column_name => value]
+>>.
=head1 BOOTSTRAPPING/MIGRATING
@@ -1618,5 +1671,67 @@
statement and dig down to see if certain parameters cause aberrant behavior.
You might want to check out L<DBIx::Class::QueryLog> as well.
+=head1 STARTUP SPEED
+L<DBIx::Class|DBIx::Class> programs can have a significant startup delay
+as the ORM loads all the relevant classes. This section examines
+techniques for reducing the startup delay.
+
+These tips are are listed in order of decreasing effectiveness - so the
+first tip, if applicable, should have the greatest effect on your
+application.
+
+=head2 Statically Define Your Schema
+
+If you are using
+L<DBIx::Class::Schema::Loader|DBIx::Class::Schema::Loader> to build the
+classes dynamically based on the database schema then there will be a
+significant startup delay.
+
+For production use a statically defined schema (which can be generated
+using L<DBIx::Class::Schema::Loader|DBIx::Class::Schema::Loader> to dump
+the database schema once - see
+L<make_schema_at|DBIx::Class::Schema::Loader/make_schema_at> and
+L<dump_directory|DBIx::Class::Schema::Loader/dump_directory> for more
+details on creating static schemas from a database).
+
+=head2 Move Common Startup into a Base Class
+
+Typically L<DBIx::Class> result classes start off with
+
+ use base qw/DBIx::Class/;
+ __PACKAGE__->load_components(qw/InflateColumn::DateTime Core/);
+
+If this preamble is moved into a common base class:-
+
+ package MyDBICbase;
+
+ use base qw/DBIx::Class/;
+ __PACKAGE__->load_components(qw/InflateColumn::DateTime Core/);
+ 1;
+
+and each result class then uses this as a base:-
+
+ use base qw/MyDBICbase/;
+
+then the load_components is only performed once, which can result in a
+considerable startup speedup for schemas with many classes.
+
+=head2 Explicitly List Schema Result Classes
+
+The schema class will normally contain
+
+ __PACKAGE__->load_classes();
+
+to load the result classes. This will use L<Module::Find|Module::Find>
+to find and load the appropriate modules. Explicitly defining the
+classes you wish to load will remove the overhead of
+L<Module::Find|Module::Find> and the related directory operations:-
+
+ __PACKAGE__->load_classes(qw/ CD Artist Track /);
+
+If you are instead using the L<load_namespaces|DBIx::Class::Schema/load_namespaces>
+syntax to load the appropriate classes there is not a direct alternative
+avoiding L<Module::Find|Module::Find>.
+
=cut
Modified: DBIx-Class/0.08/branches/views/lib/DBIx/Class/Manual/FAQ.pod
===================================================================
--- DBIx-Class/0.08/branches/views/lib/DBIx/Class/Manual/FAQ.pod 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/lib/DBIx/Class/Manual/FAQ.pod 2009-02-20 07:54:30 UTC (rev 5585)
@@ -68,7 +68,25 @@
be alarmed if the error from incorrect connection details happens a
lot later.
+=item .. use DBIx::Class across multiple databases?
+If your database server allows you to run querys across multiple
+databases at once, then so can DBIx::Class. All you need to do is make
+sure you write the database name as part of the
+L<DBIx::Class::ResultSource/table> call. Eg:
+
+ __PACKAGE__->table('mydb.mytablename');
+
+And load all the Result classes for both / all databases using one
+L<DBIx::Class::Schema/load_namespaces> call.
+
+=item .. use DBIx::Class across PostgreSQL/DB2/Oracle schemas?
+
+Add the name of the schema to the L<DBIx::Class::ResultSource/table>
+as part of the name, and make sure you give the one user you are going
+to connect with rights to read/write all the schemas/tables as
+necessary.
+
=back
=head2 Relationships
@@ -497,6 +515,16 @@
$resultset->set_primary_key(@column);
+=item How do I make my program start faster?
+
+Look at the tips in L<DBIx::Class::Manual::Cookbook/"STARTUP SPEED">
+
+=item How do I reduce the overhead of database queries?
+
+You can reduce the overhead of object creation within L<DBIx::Class>
+using the tips in L<DBIx::Class::Manual::Cookbook/"Skip row object creation for faster results">
+and L<DBIx::Class::Manual::Cookbook/"Get raw data for blindingly fast results">
+
=back
=head2 Notes for CDBI users
Modified: DBIx-Class/0.08/branches/views/lib/DBIx/Class/Relationship/Accessor.pm
===================================================================
--- DBIx-Class/0.08/branches/views/lib/DBIx/Class/Relationship/Accessor.pm 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/lib/DBIx/Class/Relationship/Accessor.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -31,6 +31,7 @@
$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;
}
my $val = $self->find_related($rel, {}, {});
Modified: DBIx-Class/0.08/branches/views/lib/DBIx/Class/Relationship/Base.pm
===================================================================
--- DBIx-Class/0.08/branches/views/lib/DBIx/Class/Relationship/Base.pm 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/lib/DBIx/Class/Relationship/Base.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -399,7 +399,7 @@
(ref $cond ? ref $cond : 'plain scalar')
) unless ref $cond eq 'HASH';
if (defined $f_obj) {
- my $f_class = $self->result_source->schema->class($rel_obj->{class});
+ my $f_class = $rel_obj->{class};
$self->throw_exception( "Object $f_obj isn't a ".$f_class )
unless Scalar::Util::blessed($f_obj) and $f_obj->isa($f_class);
}
Modified: DBIx-Class/0.08/branches/views/lib/DBIx/Class/ResultSet.pm
===================================================================
--- DBIx-Class/0.08/branches/views/lib/DBIx/Class/ResultSet.pm 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/lib/DBIx/Class/ResultSet.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -19,39 +19,123 @@
=head1 NAME
-DBIx::Class::ResultSet - Responsible for fetching and creating resultset.
+DBIx::Class::ResultSet - Represents a query used for fetching a set of results.
=head1 SYNOPSIS
- my $rs = $schema->resultset('User')->search({ registered => 1 });
- my @rows = $schema->resultset('CD')->search({ year => 2005 })->all();
+ my $users_rs = $schema->resultset('User');
+ my $registered_users_rs = $schema->resultset('User')->search({ registered => 1 });
+ my @cds_in_2005 = $schema->resultset('CD')->search({ year => 2005 })->all();
=head1 DESCRIPTION
-The resultset is also known as an iterator. It is responsible for handling
-queries that may return an arbitrary number of rows, e.g. via L</search>
-or a C<has_many> relationship.
+A ResultSet is an object which stores a set of conditions representing
+a query. It is the backbone of DBIx::Class (i.e. the really
+important/useful bit).
-In the examples below, the following table classes are used:
+No SQL is executed on the database when a ResultSet is created, it
+just stores all the conditions needed to create the query.
- package MyApp::Schema::Artist;
- use base qw/DBIx::Class/;
- __PACKAGE__->load_components(qw/Core/);
- __PACKAGE__->table('artist');
- __PACKAGE__->add_columns(qw/artistid name/);
- __PACKAGE__->set_primary_key('artistid');
- __PACKAGE__->has_many(cds => 'MyApp::Schema::CD');
- 1;
+A basic ResultSet representing the data of an entire table is returned
+by calling C<resultset> on a L<DBIx::Class::Schema> and passing in a
+L<Source|DBIx::Class::Manual::Glossary/Source> name.
- package MyApp::Schema::CD;
- use base qw/DBIx::Class/;
- __PACKAGE__->load_components(qw/Core/);
- __PACKAGE__->table('cd');
- __PACKAGE__->add_columns(qw/cdid artist title year/);
- __PACKAGE__->set_primary_key('cdid');
- __PACKAGE__->belongs_to(artist => 'MyApp::Schema::Artist');
- 1;
+ my $users_rs = $schema->resultset('User');
+A new ResultSet is returned from calling L</search> on an existing
+ResultSet. The new one will contain all the conditions of the
+original, plus any new conditions added in the C<search> call.
+
+A ResultSet is also an iterator. L</next> is used to return all the
+L<DBIx::Class::Row>s the ResultSet represents.
+
+The query that the ResultSet represents is B<only> executed against
+the database when these methods are called:
+
+=over
+
+=item L</find>
+
+=item L</next>
+
+=item L</all>
+
+=item L</count>
+
+=item L</single>
+
+=item L</first>
+
+=back
+
+=head1 EXAMPLES
+
+=head2 Chaining resultsets
+
+Let's say you've got a query that needs to be run to return some data
+to the user. But, you have an authorization system in place that
+prevents certain users from seeing certain information. So, you want
+to construct the basic query in one method, but add constraints to it in
+another.
+
+ sub get_data {
+ my $self = shift;
+ my $request = $self->get_request; # Get a request object somehow.
+ my $schema = $self->get_schema; # Get the DBIC schema object somehow.
+
+ my $cd_rs = $schema->resultset('CD')->search({
+ title => $request->param('title'),
+ year => $request->param('year'),
+ });
+
+ $self->apply_security_policy( $cd_rs );
+
+ return $cd_rs->all();
+ }
+
+ sub apply_security_policy {
+ my $self = shift;
+ my ($rs) = @_;
+
+ return $rs->search({
+ subversive => 0,
+ });
+ }
+
+=head2 Multiple queries
+
+Since a resultset just defines a query, you can do all sorts of
+things with it with the same object.
+
+ # Don't hit the DB yet.
+ my $cd_rs = $schema->resultset('CD')->search({
+ title => 'something',
+ year => 2009,
+ });
+
+ # Each of these hits the DB individually.
+ my $count = $cd_rs->count;
+ my $most_recent = $cd_rs->get_column('date_released')->max();
+ my @records = $cd_rs->all;
+
+And it's not just limited to SELECT statements.
+
+ $cd_rs->delete();
+
+This is even cooler:
+
+ $cd_rs->create({ artist => 'Fred' });
+
+Which is the same as:
+
+ $schema->resultset('CD')->create({
+ title => 'something',
+ year => 2009,
+ artist => 'Fred'
+ });
+
+See: L</search>, L</count>, L</get_column>, L</all>, L</create>.
+
=head1 OVERLOADING
If a resultset is used in a numeric context it returns the L</count>.
@@ -1269,6 +1353,11 @@
$self->throw_exception("Values for update must be a hash")
unless ref $values eq 'HASH';
+ carp( 'WARNING! Currently $rs->update() does not generate proper SQL'
+ . ' on joined resultsets, and may affect rows well outside of the'
+ . ' contents of $rs. Use at your own risk' )
+ if ( $self->{attrs}{seen_join} );
+
my $cond = $self->_cond_for_update_delete;
return $self->result_source->storage->update(
@@ -1612,6 +1701,7 @@
&& $self->{cond} eq $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION
) {
%new = %{$self->{attrs}{related_objects}};
+ $new{-from_resultset} = [ keys %new ] if keys %new;
} else {
$self->throw_exception(
"Can't abstract implicit construct, condition not a hash"
@@ -1717,6 +1807,24 @@
return \%unaliased;
}
+=head2 as_query
+
+=over 4
+
+=item Arguments: none
+
+=item Return Value: \[ $sql, @bind ]
+
+=back
+
+Returns the SQL query and bind vars associated with the invocant.
+
+This is generally used as the RHS for a subquery.
+
+=cut
+
+sub as_query { return shift->cursor->as_query(@_) }
+
=head2 find_or_new
=over 4
@@ -2217,7 +2325,7 @@
push(@{$attrs->{as}}, @$adds);
}
- $attrs->{from} ||= [ { 'me' => $source->from } ];
+ $attrs->{from} ||= [ { $self->{attrs}{alias} => $source->from } ];
if (exists $attrs->{join} || exists $attrs->{prefetch}) {
my $join = delete $attrs->{join} || {};
Modified: DBIx-Class/0.08/branches/views/lib/DBIx/Class/ResultSetColumn.pm
===================================================================
--- DBIx-Class/0.08/branches/views/lib/DBIx/Class/ResultSetColumn.pm 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/lib/DBIx/Class/ResultSetColumn.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -54,6 +54,24 @@
return $new;
}
+=head2 as_query
+
+=over 4
+
+=item Arguments: none
+
+=item Return Value: \[ $sql, @bind ]
+
+=back
+
+Returns the SQL query and bind vars associated with the invocant.
+
+This is generally used as the RHS for a subquery.
+
+=cut
+
+sub as_query { return shift->_resultset->as_query }
+
=head2 next
=over 4
@@ -168,6 +186,24 @@
return shift->func('MIN');
}
+=head2 min_rs
+
+=over 4
+
+=item Arguments: none
+
+=item Return Value: $resultset
+
+=back
+
+ my $rs = $year_col->min_rs();
+
+Wrapper for ->func_rs for function MIN().
+
+=cut
+
+sub min_rs { return shift->func_rs('MIN') }
+
=head2 max
=over 4
@@ -189,6 +225,24 @@
return shift->func('MAX');
}
+=head2 max_rs
+
+=over 4
+
+=item Arguments: none
+
+=item Return Value: $resultset
+
+=back
+
+ my $rs = $year_col->max_rs();
+
+Wrapper for ->func_rs for function MAX().
+
+=cut
+
+sub max_rs { return shift->func_rs('MAX') }
+
=head2 sum
=over 4
@@ -210,6 +264,24 @@
return shift->func('SUM');
}
+=head2 sum_rs
+
+=over 4
+
+=item Arguments: none
+
+=item Return Value: $resultset
+
+=back
+
+ my $rs = $year_col->sum_rs();
+
+Wrapper for ->func_rs for function SUM().
+
+=cut
+
+sub sum_rs { return shift->func_rs('SUM') }
+
=head2 func
=over 4
@@ -232,7 +304,7 @@
sub func {
my ($self,$function) = @_;
- my $cursor = $self->{_parent_resultset}->search(undef, {select => {$function => $self->{_select}}, as => [$self->{_as}]})->cursor;
+ my $cursor = $self->func_rs($function)->cursor;
if( wantarray ) {
return map { $_->[ 0 ] } $cursor->all;
@@ -241,6 +313,30 @@
return ( $cursor->next )[ 0 ];
}
+=head2 func_rs
+
+=over 4
+
+=item Arguments: $function
+
+=item Return Value: $resultset
+
+=back
+
+Creates the resultset that C<func()> uses to run its query.
+
+=cut
+
+sub func_rs {
+ my ($self,$function) = @_;
+ return $self->{_parent_resultset}->search(
+ undef, {
+ select => {$function => $self->{_select}},
+ as => [$self->{_as}],
+ },
+ );
+}
+
=head2 throw_exception
See L<DBIx::Class::Schema/throw_exception> for details.
@@ -278,7 +374,6 @@
);
}
-
1;
=head1 AUTHORS
Modified: DBIx-Class/0.08/branches/views/lib/DBIx/Class/Row.pm
===================================================================
--- DBIx-Class/0.08/branches/views/lib/DBIx/Class/Row.pm 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/lib/DBIx/Class/Row.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -8,6 +8,13 @@
use Scalar::Util ();
use Scope::Guard;
+BEGIN {
+ *MULTICREATE_DEBUG =
+ $ENV{DBIC_MULTICREATE_DEBUG}
+ ? sub () { 1 }
+ : sub () { 0 };
+}
+
__PACKAGE__->mk_group_accessors('simple' => qw/_source_handle/);
=head1 NAME
@@ -124,6 +131,10 @@
$new->result_source($source);
}
+ if (my $related = delete $attrs->{-from_resultset}) {
+ @{$new->{_ignore_at_insert}={}}{@$related} = ();
+ }
+
if ($attrs) {
$new->throw_exception("attrs must be a hashref")
unless ref($attrs) eq 'HASH';
@@ -145,24 +156,38 @@
$rel_obj = $new->__new_related_find_or_new_helper($key, $rel_obj);
}
- $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage);
+ if ($rel_obj->in_storage) {
+ $new->set_from_related($key, $rel_obj);
+ } else {
+ $new->{_rel_in_storage} = 0;
+ MULTICREATE_DEBUG and warn "MC $new uninserted $key $rel_obj\n";
+ }
- $new->set_from_related($key, $rel_obj) if $rel_obj->in_storage;
$related->{$key} = $rel_obj;
next;
} elsif ($info && $info->{attrs}{accessor}
&& $info->{attrs}{accessor} eq 'multi'
&& ref $attrs->{$key} eq 'ARRAY') {
my $others = delete $attrs->{$key};
- foreach my $rel_obj (@$others) {
+ my $total = @$others;
+ my @objects;
+ foreach my $idx (0 .. $#$others) {
+ my $rel_obj = $others->[$idx];
if(!Scalar::Util::blessed($rel_obj)) {
$rel_obj = $new->__new_related_find_or_new_helper($key, $rel_obj);
}
- $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage);
+ if ($rel_obj->in_storage) {
+ $new->set_from_related($key, $rel_obj);
+ } else {
+ $new->{_rel_in_storage} = 0;
+ MULTICREATE_DEBUG and
+ warn "MC $new uninserted $key $rel_obj (${\($idx+1)} of $total)\n";
+ }
$new->set_from_related($key, $rel_obj) if $rel_obj->in_storage;
+ push(@objects, $rel_obj);
}
- $related->{$key} = $others;
+ $related->{$key} = \@objects;
next;
} elsif ($info && $info->{attrs}{accessor}
&& $info->{attrs}{accessor} eq 'filter')
@@ -172,7 +197,10 @@
if(!Scalar::Util::blessed($rel_obj)) {
$rel_obj = $new->__new_related_find_or_new_helper($key, $rel_obj);
}
- $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage);
+ unless ($rel_obj->in_storage) {
+ $new->{_rel_in_storage} = 0;
+ MULTICREATE_DEBUG and warn "MC $new uninserted $key $rel_obj";
+ }
$inflated->{$key} = $rel_obj;
next;
} elsif ($class->has_column($key)
@@ -256,12 +284,18 @@
$relname, { $rel_obj->get_columns }
);
+ MULTICREATE_DEBUG and warn "MC $self pre-inserting $relname $rel_obj\n";
+
$rel_obj->insert();
$self->set_from_related($relname, $rel_obj);
delete $related_stuff{$relname};
}
}
+ MULTICREATE_DEBUG and do {
+ no warnings 'uninitialized';
+ warn "MC $self inserting (".join(', ', $self->get_columns).")\n";
+ };
my $updated_cols = $source->storage->insert($source, { $self->get_columns });
foreach my $col (keys %$updated_cols) {
$self->store_column($col, $updated_cols->{$col});
@@ -276,7 +310,7 @@
if (@auto_pri) {
#$self->throw_exception( "More than one possible key found for auto-inc on ".ref $self )
# if defined $too_many;
-
+ MULTICREATE_DEBUG and warn "MC $self fetching missing PKs ".join(', ', @auto_pri)."\n";
my $storage = $self->result_source->storage;
$self->throw_exception( "Missing primary key but Storage doesn't support last_insert_id" )
unless $storage->can('last_insert_id');
@@ -284,13 +318,15 @@
$self->throw_exception( "Can't get last insert id" )
unless (@ids == @auto_pri);
$self->store_column($auto_pri[$_] => $ids[$_]) for 0 .. $#ids;
+#use Data::Dumper; warn Dumper($self);
}
+
$self->{_dirty_columns} = {};
$self->{related_resultsets} = {};
if(!$self->{_rel_in_storage}) {
- ## Now do the has_many rels, that need $selfs ID.
+ ## Now do the relationships that need our ID (has_many etc.)
foreach my $relname (keys %related_stuff) {
my $rel_obj = $related_stuff{$relname};
my @cands;
@@ -306,13 +342,22 @@
$obj->set_from_related($_, $self) for keys %$reverse;
my $them = { %{$obj->{_relationship_data} || {} }, $obj->get_inflated_columns };
if ($self->__their_pk_needs_us($relname, $them)) {
- $obj = $self->find_or_create_related($relname, $them);
+ if (exists $self->{_ignore_at_insert}{$relname}) {
+ MULTICREATE_DEBUG and warn "MC $self skipping post-insert on $relname";
+ } else {
+ MULTICREATE_DEBUG and warn "MC $self re-creating $relname $obj";
+ my $re = $self->find_or_create_related($relname, $them);
+ %{$obj} = %{$re};
+ MULTICREATE_DEBUG and warn "MC $self new $relname $obj";
+ }
} else {
+ MULTICREATE_DEBUG and warn "MC $self post-inserting $obj";
$obj->insert();
}
}
}
}
+ delete $self->{_ignore_at_insert};
$rollback_guard->commit;
}
Modified: DBIx-Class/0.08/branches/views/lib/DBIx/Class/Schema.pm
===================================================================
--- DBIx-Class/0.08/branches/views/lib/DBIx/Class/Schema.pm 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/lib/DBIx/Class/Schema.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -208,12 +208,16 @@
local *Class::C3::reinitialize = sub { };
use warnings 'redefine';
- foreach my $result (keys %results) {
+ # ensure classes are loaded and fetch properly sorted classes
+ $class->ensure_class_loaded($_) foreach(values %results);
+ my @subclass_last = sort { $results{$a}->isa($results{$b}) } keys(%results);
+
+ foreach my $result (@subclass_last) {
my $result_class = $results{$result};
- $class->ensure_class_loaded($result_class);
my $rs_class = delete $resultsets{$result};
my $rs_set = $result_class->resultset_class;
+
if($rs_set && $rs_set ne 'DBIx::Class::ResultSet') {
if($rs_class && $rs_class ne $rs_set) {
warn "We found ResultSet class '$rs_class' for '$result', but it seems "
Modified: DBIx-Class/0.08/branches/views/lib/DBIx/Class/Storage/DBI/Cursor.pm
===================================================================
--- DBIx-Class/0.08/branches/views/lib/DBIx/Class/Storage/DBI/Cursor.pm 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/lib/DBIx/Class/Storage/DBI/Cursor.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -49,6 +49,32 @@
return bless ($new, $class);
}
+=head2 as_query
+
+=over 4
+
+=item Arguments: none
+
+=item Return Value: \[ $sql, @bind ]
+
+=back
+
+Returns the SQL statement and bind vars associated with the invocant.
+
+=cut
+
+sub as_query {
+ my $self = shift;
+
+ my $storage = $self->{storage};
+ my $sql_maker = $storage->sql_maker;
+ local $sql_maker->{for};
+
+ my @args = $storage->_select_args(@{$self->{args}});
+ my ($sql, $bind) = $storage->_prep_for_execute(@args[0 .. 2], [@args[4 .. $#args]]);
+ return \[ "($sql)", @$bind ];
+}
+
=head2 next
=over 4
Modified: DBIx-Class/0.08/branches/views/lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm
===================================================================
--- DBIx-Class/0.08/branches/views/lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -55,8 +55,23 @@
# trigger_body is a LONG
$dbh->{LongReadLen} = 64 * 1024 if ($dbh->{LongReadLen} < 64 * 1024);
- my $sth = $dbh->prepare($sql);
- $sth->execute( uc($source->name) );
+ my $sth;
+
+ # check for fully-qualified name (eg. SCHEMA.TABLENAME)
+ if ( my ( $schema, $table ) = $source->name =~ /(\w+)\.(\w+)/ ) {
+ $sql = q{
+ SELECT trigger_body FROM ALL_TRIGGERS t
+ WHERE t.owner = ? AND t.table_name = ?
+ AND t.triggering_event = 'INSERT'
+ AND t.status = 'ENABLED'
+ };
+ $sth = $dbh->prepare($sql);
+ $sth->execute( uc($schema), uc($table) );
+ }
+ else {
+ $sth = $dbh->prepare($sql);
+ $sth->execute( uc( $source->name ) );
+ }
while (my ($insert_trigger) = $sth->fetchrow_array) {
return uc($1) if $insert_trigger =~ m!(\w+)\.nextval!i; # col name goes here???
}
@@ -69,6 +84,72 @@
return $id;
}
+=head2 connected
+
+Returns true if we have an open (and working) database connection, false if it is not (yet)
+open (or does not work). (Executes a simple SELECT to make sure it works.)
+
+The reason this is needed is that L<DBD::Oracle>'s ping() does not do a real
+OCIPing but just gets the server version, which doesn't help if someone killed
+your session.
+
+=cut
+
+sub connected {
+ my $self = shift;
+
+ if (not $self->SUPER::connected(@_)) {
+ return 0;
+ }
+ else {
+ my $dbh = $self->_dbh;
+
+ local $dbh->{RaiseError} = 1;
+
+ eval {
+ my $ping_sth = $dbh->prepare_cached("select 1 from dual");
+ $ping_sth->execute;
+ $ping_sth->finish;
+ };
+
+ return $@ ? 0 : 1;
+ }
+}
+
+sub _dbh_execute {
+ my $self = shift;
+ my ($dbh, $op, $extra_bind, $ident, $bind_attributes, @args) = @_;
+
+ my $wantarray = wantarray;
+
+ my (@res, $exception, $retried);
+
+ RETRY: {
+ do {
+ eval {
+ if ($wantarray) {
+ @res = $self->SUPER::_dbh_execute(@_);
+ } else {
+ $res[0] = $self->SUPER::_dbh_execute(@_);
+ }
+ };
+ $exception = $@;
+ if ($exception =~ /ORA-01003/) {
+ # ORA-01003: no statement parsed (someone changed the table somehow,
+ # invalidating your cursor.)
+ my ($sql, $bind) = $self->_prep_for_execute($op, $extra_bind, $ident, \@args);
+ delete $dbh->{CachedKids}{$sql};
+ } else {
+ last RETRY;
+ }
+ } while (not $retried++);
+ }
+
+ $self->throw_exception($exception) if $exception;
+
+ wantarray ? @res : $res[0]
+}
+
=head2 get_autoinc_seq
Returns the sequence name for an autoincrement column
Modified: DBIx-Class/0.08/branches/views/lib/DBIx/Class/Storage/DBI/Replicated/Pool.pm
===================================================================
--- DBIx-Class/0.08/branches/views/lib/DBIx/Class/Storage/DBI/Replicated/Pool.pm 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/lib/DBIx/Class/Storage/DBI/Replicated/Pool.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -187,17 +187,19 @@
sub _safely_ensure_connected {
my ($self, $replicant, @args) = @_;
- my $return; eval {
- $return = $replicant->ensure_connected(@args);
- }; if ($@) {
+ eval {
+ $replicant->ensure_connected(@args);
+ };
+ if ($@) {
$replicant
- ->debugobj
- ->print(
- sprintf( "Exception trying to ->ensure_connected for replicant %s, error is %s",
- $self->_dbi_connect_info->[0], $@)
+ ->debugobj
+ ->print(
+ sprintf( "Exception trying to ->ensure_connected for replicant %s, error is %s",
+ $replicant->_dbi_connect_info->[0], $@)
);
+ return;
}
- return $return;
+ return 1;
}
=head2 connected_replicants
Modified: DBIx-Class/0.08/branches/views/lib/DBIx/Class/Storage/DBI.pm
===================================================================
--- DBIx-Class/0.08/branches/views/lib/DBIx/Class/Storage/DBI.pm 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/lib/DBIx/Class/Storage/DBI.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -259,10 +259,20 @@
return join('', @sqlf);
}
+sub _bind_to_sql {
+ my $self = shift;
+ my $arr = shift;
+ my $sql = shift @$$arr;
+ $sql =~ s/\?/$self->_quote((shift @$$arr)->[1])/eg;
+ return $sql
+}
+
sub _make_as {
my ($self, $from) = @_;
- return join(' ', map { (ref $_ eq 'SCALAR' ? $$_ : $self->_quote($_)) }
- reverse each %{$self->_skip_options($from)});
+ return join(' ', map { (ref $_ eq 'SCALAR' ? $$_
+ : ref $_ eq 'REF' ? $self->_bind_to_sql($_)
+ : $self->_quote($_))
+ } reverse each %{$self->_skip_options($from)});
}
sub _skip_options {
@@ -952,10 +962,18 @@
$self->_do_query($_) foreach @$action;
}
else {
- my @to_run = (ref $action eq 'ARRAY') ? (@$action) : ($action);
- $self->_query_start(@to_run);
- $self->_dbh->do(@to_run);
- $self->_query_end(@to_run);
+ # Most debuggers expect ($sql, @bind), so we need to exclude
+ # the attribute hash which is the second argument to $dbh->do
+ # furthermore the bind values are usually to be presented
+ # as named arrayref pairs, so wrap those here too
+ my @do_args = (ref $action eq 'ARRAY') ? (@$action) : ($action);
+ my $sql = shift @do_args;
+ my $attrs = shift @do_args;
+ my @bind = map { [ undef, $_ ] } @do_args;
+
+ $self->_query_start($sql, @bind);
+ $self->_dbh->do($sql, $attrs, @do_args);
+ $self->_query_end($sql, @bind);
}
return $self;
@@ -1165,11 +1183,15 @@
sub _prep_for_execute {
my ($self, $op, $extra_bind, $ident, $args) = @_;
+ if( blessed($ident) && $ident->isa("DBIx::Class::ResultSource") ) {
+ $ident = $ident->from();
+ }
+
my ($sql, @bind) = $self->sql_maker->$op($ident, @$args);
+
unshift(@bind,
map { ref $_ eq 'ARRAY' ? $_ : [ '!!dummy', $_ ] } @$extra_bind)
if $extra_bind;
-
return ($sql, \@bind);
}
@@ -1211,10 +1233,6 @@
sub _dbh_execute {
my ($self, $dbh, $op, $extra_bind, $ident, $bind_attributes, @args) = @_;
- if( blessed($ident) && $ident->isa("DBIx::Class::ResultSource") ) {
- $ident = $ident->from();
- }
-
my ($sql, $bind) = $self->_prep_for_execute($op, $extra_bind, $ident, \@args);
$self->_query_start( $sql, @$bind );
@@ -1349,6 +1367,13 @@
}
sub _select {
+ my $self = shift;
+ my $sql_maker = $self->sql_maker;
+ local $sql_maker->{for};
+ return $self->_execute($self->_select_args(@_));
+}
+
+sub _select_args {
my ($self, $ident, $select, $condition, $attrs) = @_;
my $order = $attrs->{order_by};
@@ -1362,7 +1387,7 @@
my $for = delete $attrs->{for};
my $sql_maker = $self->sql_maker;
- local $sql_maker->{for} = $for;
+ $sql_maker->{for} = $for;
if (exists $attrs->{group_by} || $attrs->{having}) {
$order = {
@@ -1385,7 +1410,7 @@
push @args, $attrs->{rows}, $attrs->{offset};
}
- return $self->_execute(@args);
+ return @args;
}
sub source_bind_attributes {
@@ -1775,24 +1800,34 @@
sub deploy {
my ($self, $schema, $type, $sqltargs, $dir) = @_;
- foreach my $statement ( $self->deployment_statements($schema, $type, undef, $dir, { no_comments => 1, %{ $sqltargs || {} } } ) ) {
- foreach my $line ( split(";\n", $statement)) {
- next if($line =~ /^--/);
- next if(!$line);
-# next if($line =~ /^DROP/m);
- next if($line =~ /^BEGIN TRANSACTION/m);
- next if($line =~ /^COMMIT/m);
- next if $line =~ /^\s+$/; # skip whitespace only
- $self->_query_start($line);
- eval {
- $self->dbh->do($line); # shouldn't be using ->dbh ?
- };
- if ($@) {
- warn qq{$@ (running "${line}")};
- }
- $self->_query_end($line);
+ my $deploy = sub {
+ my $line = shift;
+ return if($line =~ /^--/);
+ return if(!$line);
+ # next if($line =~ /^DROP/m);
+ return if($line =~ /^BEGIN TRANSACTION/m);
+ return if($line =~ /^COMMIT/m);
+ return if $line =~ /^\s+$/; # skip whitespace only
+ $self->_query_start($line);
+ eval {
+ $self->dbh->do($line); # shouldn't be using ->dbh ?
+ };
+ if ($@) {
+ warn qq{$@ (running "${line}")};
}
+ $self->_query_end($line);
+ };
+ my @statements = $self->deployment_statements($schema, $type, undef, $dir, { no_comments => 1, %{ $sqltargs || {} } } );
+ if (@statements > 1) {
+ foreach my $statement (@statements) {
+ $deploy->( $statement );
+ }
}
+ elsif (@statements == 1) {
+ foreach my $line ( split(";\n", $statements[0])) {
+ $deploy->( $line );
+ }
+ }
}
=head2 datetime_parser
Modified: DBIx-Class/0.08/branches/views/lib/DBIx/Class.pm
===================================================================
--- DBIx-Class/0.08/branches/views/lib/DBIx/Class.pm 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/lib/DBIx/Class.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -291,6 +291,8 @@
rjbs: Ricardo Signes <rjbs at cpan.org>
+robkinyon: Rob Kinyon <rkinyon at cpan.org>
+
sc_: Just Another Perl Hacker
scotty: Scotty Allen <scotty at scottyallen.com>
Modified: DBIx-Class/0.08/branches/views/t/03podcoverage.t
===================================================================
--- DBIx-Class/0.08/branches/views/t/03podcoverage.t 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/t/03podcoverage.t 2009-02-20 07:54:30 UTC (rev 5585)
@@ -29,6 +29,11 @@
mk_classaccessor/
]
},
+ 'DBIx::Class::Row' => {
+ ignore => [
+ qw( MULTICREATE_DEBUG )
+ ],
+ },
'DBIx::Class::Storage' => {
ignore => [
qw(cursor)
Added: DBIx-Class/0.08/branches/views/t/39load_namespaces_rt41083.t
===================================================================
--- DBIx-Class/0.08/branches/views/t/39load_namespaces_rt41083.t (rev 0)
+++ DBIx-Class/0.08/branches/views/t/39load_namespaces_rt41083.t 2009-02-20 07:54:30 UTC (rev 5585)
@@ -0,0 +1,42 @@
+#!/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/views/t/66relationship.t
===================================================================
--- DBIx-Class/0.08/branches/views/t/66relationship.t 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/t/66relationship.t 2009-02-20 07:54:30 UTC (rev 5585)
@@ -8,7 +8,7 @@
my $schema = DBICTest->init_schema();
-plan tests => 74;
+plan tests => 69;
# has_a test
my $cd = $schema->resultset("CD")->find(4);
@@ -228,7 +228,10 @@
$undef_artist_cd->related_resultset('artist')->new({name => 'foo'});
};
is( $@, '', "Object created on a resultset related to not yet inserted object");
-
+lives_ok{
+ $schema->resultset('Artwork')->new_result({})->cd;
+} 'undef_on_null_fk does not choke on empty conds';
+
my $def_artist_cd = $schema->resultset("CD")->new_result({ 'title' => 'badgers', 'year' => 2007, artist => undef });
is($def_artist_cd->has_column_loaded('artist'), 1, 'FK loaded');
is($def_artist_cd->search_related('artist')->count, 0, 'closed search on null FK');
@@ -265,33 +268,6 @@
cmp_ok($artist->cds->count, '==', 0, "Correct new #cds for artist");
cmp_ok($nartist->cds->count, '==', 2, "Correct new #cds for artist");
-my $new_artist = $schema->resultset("Artist")->new_result({ 'name' => 'Depeche Mode' });
-my $new_related_cd = $new_artist->new_related('cds', { 'title' => 'Leave in Silence', 'year' => 1982});
-eval {
- $new_artist->insert;
- $new_related_cd->insert;
-};
-is ($@, '', 'Staged insertion successful');
-ok($new_artist->in_storage, 'artist inserted');
-ok($new_related_cd->in_storage, 'new_related_cd inserted');
-
-TODO: {
-local $TODO = "TODOify for multicreate branch";
-my $new_cd = $schema->resultset("CD")->new_result({});
-my $new_related_artist = $new_cd->new_related('artist', { 'name' => 'Marillion',});
-lives_ok (
- sub {
- $new_related_artist->insert;
- $new_cd->title( 'Misplaced Childhood' );
- $new_cd->year ( 1985 );
-# $new_cd->artist( $new_related_artist ); # For exact backward compatibility # not sure what this means
- $new_cd->insert;
- },
- 'Reversed staged insertion successful'
-);
-ok($new_related_artist->in_storage, 'related artist inserted');
-ok($new_cd->in_storage, 'cd inserted');
-
# check if is_foreign_key_constraint attr is set
my $rs_normal = $schema->source('Track');
my $relinfo = $rs_normal->relationship_info ('cd');
@@ -300,4 +276,3 @@
my $rs_overridden = $schema->source('ForceForeign');
my $relinfo_with_attr = $rs_overridden->relationship_info ('cd_3');
cmp_ok($relinfo_with_attr->{attrs}{is_foreign_key_constraint}, '==', 0, "is_foreign_key_constraint defined for belongs_to relationships with attr.");
-}
Modified: DBIx-Class/0.08/branches/views/t/72pg.t
===================================================================
--- DBIx-Class/0.08/branches/views/t/72pg.t 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/t/72pg.t 2009-02-20 07:54:30 UTC (rev 5585)
@@ -153,7 +153,7 @@
my $count;
lives_ok {
$count = $schema->resultset('ArrayTest')->search({
- arrayfield => \[ '= ?' => [3, 4] ], #TODO anything less ugly than this?
+ arrayfield => \[ '= ?' => [arrayfield => [3, 4]] ], #TODO anything less ugly than this?
})->count;
} 'comparing arrayref to pg array data does not blow up';
is($count, 1, 'comparing arrayref to pg array data gives correct result');
Modified: DBIx-Class/0.08/branches/views/t/73oracle.t
===================================================================
--- DBIx-Class/0.08/branches/views/t/73oracle.t 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/t/73oracle.t 2009-02-20 07:54:30 UTC (rev 5585)
@@ -1,3 +1,30 @@
+{
+ package # hide from PAUSE
+ DBICTest::Schema::ArtistFQN;
+
+ use base 'DBIx::Class::Core';
+
+ __PACKAGE__->table(
+ defined $ENV{DBICTEST_ORA_USER}
+ ? $ENV{DBICTEST_ORA_USER} . '.artist'
+ : 'artist'
+ );
+ __PACKAGE__->add_columns(
+ 'artistid' => {
+ data_type => 'integer',
+ is_auto_increment => 1,
+ },
+ 'name' => {
+ data_type => 'varchar',
+ size => 100,
+ is_nullable => 1,
+ },
+ );
+ __PACKAGE__->set_primary_key('artistid');
+
+ 1;
+}
+
use strict;
use warnings;
@@ -12,8 +39,9 @@
' as well as following sequences: \'pkid1_seq\', \'pkid2_seq\' and \'nonpkid_seq\''
unless ($dsn && $user && $pass);
-plan tests => 23;
+plan tests => 24;
+DBICTest::Schema->load_classes('ArtistFQN');
my $schema = DBICTest::Schema->connect($dsn, $user, $pass);
my $dbh = $schema->storage->dbh;
@@ -62,6 +90,10 @@
my $new = $schema->resultset('Artist')->create({ name => 'foo' });
is($new->artistid, 1, "Oracle Auto-PK worked");
+# test again with fully-qualified table name
+$new = $schema->resultset('ArtistFQN')->create( { name => 'bar' } );
+is( $new->artistid, 2, "Oracle Auto-PK worked with fully-qualified tablename" );
+
# test join with row count ambiguity
my $cd = $schema->resultset('CD')->create({ cdid => 1, artist => 1, title => 'EP C', year => '2003' });
my $track = $schema->resultset('Track')->create({ trackid => 1, cd => 1, position => 1, title => 'Track1' });
@@ -90,7 +122,7 @@
}
my $it = $schema->resultset('Artist')->search( {},
{ rows => 3,
- offset => 2,
+ offset => 3,
order_by => 'artistid' }
);
is( $it->count, 3, "LIMIT count ok" );
@@ -117,7 +149,7 @@
# clean up our mess
END {
- if($dbh) {
+ if($schema && ($dbh = $schema->storage->dbh)) {
$dbh->do("DROP SEQUENCE artist_seq");
$dbh->do("DROP SEQUENCE pkid1_seq");
$dbh->do("DROP SEQUENCE pkid2_seq");
Modified: DBIx-Class/0.08/branches/views/t/76joins.t
===================================================================
--- DBIx-Class/0.08/branches/views/t/76joins.t 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/t/76joins.t 2009-02-20 07:54:30 UTC (rev 5585)
@@ -17,7 +17,7 @@
eval "use DBD::SQLite";
plan $@
? ( skip_all => 'needs DBD::SQLite for testing' )
- : ( tests => 16 );
+ : ( tests => 18 );
}
# figure out if we've got a version of sqlite that is older than 3.2.6, in
@@ -179,3 +179,28 @@
is($rs->first->name, 'We Are Goth', 'Correct record returned');
+# test for warnings on delete of joined resultset
+$rs = $schema->resultset("CD")->search(
+ { 'artist.name' => 'Caterwauler McCrae' },
+ { join => [qw/artist/]}
+);
+my $tst_delete_warning;
+eval {
+ local $SIG{__WARN__} = sub { $tst_delete_warning = shift };
+ $rs->delete();
+};
+
+ok( ($@ || $tst_delete_warning), 'fail/warning on attempt to delete a join-ed resultset');
+
+# test for warnings on update of joined resultset
+$rs = $schema->resultset("CD")->search(
+ { 'artist.name' => 'Random Boy Band' },
+ { join => [qw/artist/]}
+);
+my $tst_update_warning;
+eval {
+ local $SIG{__WARN__} = sub { $tst_update_warning = shift };
+ $rs->update({ 'artist' => 1 });
+};
+
+ok( ($@ || $tst_update_warning), 'fail/warning on attempt to update a join-ed resultset');
Modified: DBIx-Class/0.08/branches/views/t/81transactions.t
===================================================================
--- DBIx-Class/0.08/branches/views/t/81transactions.t 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/t/81transactions.t 2009-02-20 07:54:30 UTC (rev 5585)
@@ -260,7 +260,7 @@
});
$guard->commit;
- } qr/No such column made_up_column .*? at .*?81transactions.t line \d+/, "Error propogated okay";
+ } qr/No such column made_up_column .*? at .*?81transactions.t line \d+/s, "Error propogated okay";
ok(!$artist_rs->find({name => 'Death Cab for Cutie'}), "Artist not created");
Modified: DBIx-Class/0.08/branches/views/t/86sqlt.t
===================================================================
--- DBIx-Class/0.08/branches/views/t/86sqlt.t 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/t/86sqlt.t 2009-02-20 07:54:30 UTC (rev 5585)
@@ -10,7 +10,7 @@
my $schema = DBICTest->init_schema;
-plan tests => 132;
+plan tests => 133;
my $translator = SQL::Translator->new(
parser_args => {
@@ -29,7 +29,7 @@
$schema->source('Track')->sqlt_deploy_callback(sub {
my ($self, $sqlt_table) = @_;
- if ($sqlt_table->schema->translator->producer_type =~ /SQLite$/ ) {
+ if ($schema->storage->sqlt_type eq 'SQLite' ) {
$sqlt_table->add_index( name => 'track_title', fields => ['title'] )
or die $sqlt_table->error;
}
@@ -282,6 +282,18 @@
# the 'dummy' table
ok( !defined($tschema->get_table('dummy')), "Dummy table was removed by hook");
+# Test that the Artist resultsource sqlt_deploy_hook was called okay and added
+# an index
+SKIP: {
+ skip ('Artist sqlt_deploy_hook is only called with an SQLite backend', 1)
+ if $schema->storage->sqlt_type ne 'SQLite';
+
+ ok( ( grep
+ { $_->name eq 'artist_name_hookidx' }
+ $tschema->get_table('artist')->get_indices
+ ), 'sqlt_deploy_hook fired within a resultsource');
+}
+
# Test that nonexistent constraints are not found
my $constraint = get_constraint('FOREIGN KEY', 'cd', ['title'], 'cd', ['year']);
ok( !defined($constraint), 'nonexistent FOREIGN KEY constraint not found' );
Added: DBIx-Class/0.08/branches/views/t/96multi_create/cd_single.t
===================================================================
--- DBIx-Class/0.08/branches/views/t/96multi_create/cd_single.t (rev 0)
+++ DBIx-Class/0.08/branches/views/t/96multi_create/cd_single.t 2009-02-20 07:54:30 UTC (rev 5585)
@@ -0,0 +1,35 @@
+use strict;
+use warnings;
+
+use Test::More qw(no_plan);
+use Test::Exception;
+use lib qw(t/lib);
+use DBICTest;
+
+my $schema = DBICTest->init_schema();
+
+eval {
+ my $cd = $schema->resultset('CD')->first;
+ my $track = $schema->resultset('Track')->new_result({
+ cd => $cd,
+ position => 77, # some day me might test this with Ordered
+ title => 'Multicreate rocks',
+ cd_single => {
+ artist => $cd->artist,
+ year => 2008,
+ title => 'Disemboweling MultiCreate',
+ },
+ });
+
+ isa_ok ($track, 'DBICTest::Track', 'Main Track object created');
+
+ $track->insert;
+
+ ok(1, 'created track');
+
+ is($track->title, 'Multicreate rocks', 'Correct Track title');
+
+ my $single = $track->cd_single;
+
+ ok($single->cdid, 'Got cdid');
+};
Modified: DBIx-Class/0.08/branches/views/t/96multi_create.t
===================================================================
--- DBIx-Class/0.08/branches/views/t/96multi_create.t 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/t/96multi_create.t 2009-02-20 07:54:30 UTC (rev 5585)
@@ -6,11 +6,11 @@
use lib qw(t/lib);
use DBICTest;
-plan tests => 89;
+plan tests => 77;
my $schema = DBICTest->init_schema();
-# simple create + parent (the stuff $rs belongs_to)
+diag '* simple create + parent (the stuff $rs belongs_to)';
eval {
my $cd = $schema->resultset('CD')->create({
artist => {
@@ -26,8 +26,7 @@
};
diag $@ if $@;
-# same as above but the child and parent have no values,
-# except for an explicit parent pk
+diag '* same as above but the child and parent have no values, except for an explicit parent pk';
eval {
my $bm_rs = $schema->resultset('Bookmark');
my $bookmark = $bm_rs->create({
@@ -49,7 +48,7 @@
};
diag $@ if $@;
-# create over > 1 levels of has_many create (A => { has_many => { B => has_many => C } } )
+diag '* create over > 1 levels of has_many create (A => { has_many => { B => has_many => C } } )';
eval {
my $artist = $schema->resultset('Artist')->first;
my $cd = $artist->create_related (cds => {
@@ -83,7 +82,7 @@
'create via update of multi relationships throws an exception'
);
-# Create m2m while originating in the linker table
+diag '* Create m2m while originating in the linker table';
eval {
my $artist = $schema->resultset('Artist')->first;
my $c2p = $schema->resultset('CD_to_Producer')->create ({
@@ -113,7 +112,19 @@
};
diag $@ if $@;
-# create over > 1 levels of might_have (A => { might_have => { B => has_many => C } } )
+diag (<<'DG');
+* Create over > 1 levels of might_have with multiple has_many and multiple m2m
+but starting at a has_many level
+
+CD -> has_many -> Tracks -> might have -> Single -> has_many -> Tracks
+ \
+ \-> has_many \
+ --> CD2Producer
+ /-> has_many /
+ /
+ Producer
+DG
+
eval {
my $artist = $schema->resultset('Artist')->first;
my $cd = $schema->resultset('CD')->create ({
@@ -122,7 +133,7 @@
year => 2008,
tracks => [
{
- position => 1,
+ position => 1, # some day me might test this with Ordered
title => 'Off by one again',
},
{
@@ -141,7 +152,12 @@
producer => {
name => 'K&R',
}
- }
+ },
+ {
+ producer => {
+ name => 'Don Knuth',
+ }
+ },
]
},
},
@@ -163,15 +179,83 @@
is ($single->tracks->find ({ position => 1})->title, 'The dereferencer', 'Correct 1st track title');
is ($single->tracks->find ({ position => 2})->title, 'The dereferencer II', 'Correct 2nd track title');
- is ($single->cd_to_producer->count, 1, 'One producer created with the single cd');
- is ($single->cd_to_producer->first->producer->name, 'K&R', 'Producer name correct');
+ is ($single->cd_to_producer->count, 2, 'Two producers created for the single cd');
+ is_deeply (
+ [ sort map { $_->producer->name } ($single->cd_to_producer->all) ],
+ ['Don Knuth', 'K&R'],
+ 'Producers named correctly',
+ );
};
diag $@ if $@;
-TODO: {
-local $TODO = "Todoify for multicreate branch";
-# test might_have again but with a PK == FK in the middle (obviously not specified)
+diag (<<'DG');
+* Same as above but starting at the might_have directly
+
+Track -> might have -> Single -> has_many -> Tracks
+ \
+ \-> has_many \
+ --> CD2Producer
+ /-> has_many /
+ /
+ Producer
+DG
+
eval {
+ my $cd = $schema->resultset('CD')->first;
+ my $track = $schema->resultset('Track')->create ({
+ cd => $cd,
+ position => 77, # some day me might test this with Ordered
+ title => 'Multicreate rocks',
+ cd_single => {
+ artist => $cd->artist,
+ year => 2008,
+ title => 'Disemboweling MultiCreate',
+ tracks => [
+ { title => 'Why does mst write this way', position => 1 },
+ { title => 'Chainsaw celebration', position => 2 },
+ { title => 'Purl cleans up', position => 3 },
+ ],
+ cd_to_producer => [
+ {
+ producer => {
+ name => 'mst',
+ }
+ },
+ {
+ producer => {
+ name => 'castaway',
+ }
+ },
+ {
+ producer => {
+ name => 'theorbtwo',
+ }
+ },
+ ]
+ },
+ });
+
+ isa_ok ($track, 'DBICTest::Track', 'Main Track object created');
+ is ($track->title, 'Multicreate rocks', 'Correct Track title');
+
+ my $single = $track->cd_single;
+ isa_ok ($single, 'DBICTest::CD', 'Created a single with the track');
+ is ($single->tracks->count, 3, '3 tracks on single CD');
+ is ($single->tracks->find ({ position => 1})->title, 'Why does mst write this way', 'Correct 1st track title');
+ is ($single->tracks->find ({ position => 2})->title, 'Chainsaw celebration', 'Correct 2nd track title');
+ is ($single->tracks->find ({ position => 3})->title, 'Purl cleans up', 'Correct 3rd track title');
+
+ is ($single->cd_to_producer->count, 3, '3 producers created for the single cd');
+ is_deeply (
+ [ sort map { $_->producer->name } ($single->cd_to_producer->all) ],
+ ['castaway', 'mst', 'theorbtwo'],
+ 'Producers named correctly',
+ );
+};
+diag $@ if $@;
+
+diag '* Test might_have again but with a PK == FK in the middle (obviously not specified)';
+eval {
my $artist = $schema->resultset('Artist')->first;
my $cd = $schema->resultset('CD')->create ({
artist => $artist,
@@ -199,7 +283,6 @@
'Images named correctly in objects',
);
-
my $artwork = $schema->resultset('Artwork')->search (
{ 'cd.title' => 'Music to code by at twilight' },
{ join => 'cd' },
@@ -215,7 +298,7 @@
};
diag $@ if $@;
-# test might_have again but with just a PK and FK (neither specified) in the mid-table
+diag '* Test might_have again but with just a PK and FK (neither specified) in the mid-table';
eval {
my $cd = $schema->resultset('CD')->first;
my $track = $schema->resultset ('Track')->create ({
@@ -260,10 +343,60 @@
);
};
diag $@ if $@;
-}
-# nested find_or_create
+diag (<<'DG');
+* Test a multilevel might-have with a PK == FK in the might_have/has_many table
+
+CD -> might have -> Artwork
+ \
+ \-> has_many \
+ --> Artwork_to_Artist
+ /-> has_many /
+ /
+ Artist
+DG
+
eval {
+ my $someartist = $schema->resultset('Artist')->first;
+ my $cd = $schema->resultset('CD')->create ({
+ artist => $someartist,
+ title => 'Music to code by until the cows come home',
+ year => 2008,
+ artwork => {
+ artwork_to_artist => [
+ { artist => { name => 'cowboy joe' } },
+ { artist => { name => 'billy the kid' } },
+ ],
+ },
+ });
+
+ isa_ok ($cd, 'DBICTest::CD', 'Main CD object created');
+ is ($cd->title, 'Music to code by until the cows come home', 'Correct CD title');
+
+ my $art_obj = $cd->artwork;
+ ok ($art_obj->has_column_loaded ('cd_id'), 'PK/FK present on artwork object');
+ is ($art_obj->artists->count, 2, 'Correct artwork creator count via the new object');
+ is_deeply (
+ [ sort $art_obj->artists->get_column ('name')->all ],
+ [ 'billy the kid', 'cowboy joe' ],
+ 'Artists named correctly when queried via object',
+ );
+
+ my $artwork = $schema->resultset('Artwork')->search (
+ { 'cd.title' => 'Music to code by until the cows come home' },
+ { join => 'cd' },
+ )->single;
+ is ($artwork->artists->count, 2, 'Correct artwork creator count via a new search');
+ is_deeply (
+ [ sort $artwork->artists->get_column ('name')->all ],
+ [ 'billy the kid', 'cowboy joe' ],
+ 'Artists named correctly queried via a new search',
+ );
+};
+diag $@ if $@;
+
+diag '* Nested find_or_create';
+eval {
my $newartist2 = $schema->resultset('Artist')->find_or_create({
name => 'Fred 3',
cds => [
@@ -277,7 +410,7 @@
};
diag $@ if $@;
-# multiple same level has_many create
+diag '* Multiple same level has_many create';
eval {
my $artist2 = $schema->resultset('Artist')->create({
name => 'Fred 4',
@@ -299,7 +432,7 @@
};
diag $@ if $@;
-# first create_related pass
+diag '* First create_related pass';
eval {
my $artist = $schema->resultset('Artist')->first;
@@ -333,7 +466,7 @@
};
diag $@ if $@;
-# second create_related with same arguments
+diag '* second create_related with same arguments';
eval {
my $artist = $schema->resultset('Artist')->first;
@@ -370,7 +503,7 @@
};
diag $@ if $@;
-# create of parents of a record linker table
+diag '* create of parents of a record linker table';
eval {
my $cdp = $schema->resultset('CD_to_Producer')->create({
cd => { artist => 1, title => 'foo', year => 2000 },
@@ -380,7 +513,6 @@
};
diag $@ if $@;
-#SPECIAL_CASE
eval {
my $kurt_cobain = { name => 'Kurt Cobain' };
@@ -401,7 +533,8 @@
};
diag $@ if $@;
-#SPECIAL_CASE2
+=pod
+# This test case has been moved to t/96multi_create/cd_single.t
eval {
my $pink_floyd = { name => 'Pink Floyd' };
@@ -417,7 +550,9 @@
is($a->cds && $a->cds->first->title, 'The Wall', 'CD insertion ok');
};
diag $@ if $@;
+=cut
+diag '* Create foreign key col obj including PK (See test 20 in 66relationships.t)';
## Create foreign key col obj including PK
## See test 20 in 66relationships.t
eval {
@@ -447,7 +582,7 @@
};
is($@, '', 'new cd created without clash on related artist');
-# Make sure exceptions from errors in created rels propogate
+diag '* Make sure exceptions from errors in created rels propogate';
eval {
my $t = $schema->resultset("Track")->new({ cd => { artist => undef } });
#$t->cd($t->new_related('cd', { artist => undef } ) );
@@ -456,7 +591,7 @@
};
like($@, qr/cd.artist may not be NULL/, "Exception propogated properly");
-# Test multi create over many_to_many
+diag '* Test multi create over many_to_many';
eval {
$schema->resultset('CD')->create ({
artist => {
@@ -475,217 +610,4 @@
is ($m2m_cd->first->producers->first->name, 'Cowboy Neal', 'Correct producer row created');
};
-# and some insane multicreate
-# (should work, despite the fact that no one will probably use it this way)
-
-# first count how many rows do we initially have
-my $counts;
-$counts->{$_} = $schema->resultset($_)->count for qw/Artist CD Genre Producer Tag/;
-
-# do the crazy create
-eval {
- $schema->resultset('CD')->create ({
- artist => {
- name => 'james',
- },
- title => 'Greatest hits 1',
- year => '2012',
- genre => {
- name => '"Greatest" collections',
- },
- tags => [
- { tag => 'A' },
- { tag => 'B' },
- ],
- cd_to_producer => [
- {
- producer => {
- name => 'bob',
- producer_to_cd => [
- {
- cd => {
- artist => {
- name => 'lars',
- cds => [
- {
- title => 'Greatest hits 2',
- year => 2012,
- genre => {
- name => '"Greatest" collections',
- },
- tags => [
- { tag => 'A' },
- { tag => 'B' },
- ],
- # This cd is created via artist so it doesn't know about producers
- cd_to_producer => [
- # if we specify 'bob' here things bomb
- # as the producer attached to Greatest Hits 1 is
- # already created, but not yet inserted.
- # Maybe this can be fixed, but things are hairy
- # enough already.
- #
- #{ producer => { name => 'bob' } },
- { producer => { name => 'paul' } },
- { producer => {
- name => 'flemming',
- producer_to_cd => [
- { cd => {
- artist => {
- name => 'kirk',
- cds => [
- {
- title => 'Greatest hits 3',
- year => 2012,
- genre => {
- name => '"Greatest" collections',
- },
- tags => [
- { tag => 'A' },
- { tag => 'B' },
- ],
- },
- {
- title => 'Greatest hits 4',
- year => 2012,
- genre => {
- name => '"Greatest" collections2',
- },
- tags => [
- { tag => 'A' },
- { tag => 'B' },
- ],
- },
- ],
- },
- title => 'Greatest hits 5',
- year => 2013,
- genre => {
- name => '"Greatest" collections2',
- },
- }},
- ],
- }},
- ],
- },
- ],
- },
- title => 'Greatest hits 6',
- year => 2012,
- genre => {
- name => '"Greatest" collections',
- },
- tags => [
- { tag => 'A' },
- { tag => 'B' },
- ],
- },
- },
- {
- cd => {
- artist => {
- name => 'lars', # should already exist
- # even though the artist 'name' is not uniquely constrained
- # find_or_create will arguably DWIM
- },
- title => 'Greatest hits 7',
- year => 2013,
- },
- },
- ],
- },
- },
- ],
- });
-
- is ($schema->resultset ('Artist')->count, $counts->{Artist} + 3, '3 new artists created');
- is ($schema->resultset ('Genre')->count, $counts->{Genre} + 2, '2 additional genres created');
- is ($schema->resultset ('Producer')->count, $counts->{Producer} + 3, '3 new producer');
- is ($schema->resultset ('CD')->count, $counts->{CD} + 7, '7 new CDs');
- is ($schema->resultset ('Tag')->count, $counts->{Tag} + 10, '10 new Tags');
-
- my $cd_rs = $schema->resultset ('CD')
- ->search ({ title => { -like => 'Greatest hits %' }}, { order_by => 'title'} );
- is ($cd_rs->count, 7, '7 greatest hits created');
-
- my $cds_2012 = $cd_rs->search ({ year => 2012});
- is ($cds_2012->count, 5, '5 CDs created in 2012');
-
- is (
- $cds_2012->search(
- { 'tags.tag' => { -in => [qw/A B/] } },
- { join => 'tags', group_by => 'me.cdid' }
- ),
- 5,
- 'All 10 tags were pairwise distributed between 5 year-2012 CDs'
- );
-
- my $paul_prod = $cd_rs->search (
- { 'producer.name' => 'paul'},
- { join => { cd_to_producer => 'producer' } }
- );
- is ($paul_prod->count, 1, 'Paul had 1 production');
- my $pauls_cd = $paul_prod->single;
- is ($pauls_cd->cd_to_producer->count, 2, 'Paul had one co-producer');
- is (
- $pauls_cd->search_related ('cd_to_producer',
- { 'producer.name' => 'flemming'},
- { join => 'producer' }
- )->count,
- 1,
- 'The second producer is flemming',
- );
-
- my $kirk_cds = $cd_rs->search ({ 'artist.name' => 'kirk' }, { join => 'artist' });
- is ($kirk_cds, 3, 'Kirk had 3 CDs');
- is (
- $kirk_cds->search (
- { 'cd_to_producer.cd' => { '!=', undef } },
- { join => 'cd_to_producer' },
- ),
- 1,
- 'Kirk had a producer only on one cd',
- );
-
- my $lars_cds = $cd_rs->search ({ 'artist.name' => 'lars' }, { join => 'artist' });
- is ($lars_cds->count, 3, 'Lars had 3 CDs');
- is (
- $lars_cds->search (
- { 'cd_to_producer.cd' => undef },
- { join => 'cd_to_producer' },
- ),
- 0,
- 'Lars always had a producer',
- );
- is (
- $lars_cds->search_related ('cd_to_producer',
- { 'producer.name' => 'flemming'},
- { join => 'producer' }
- )->count,
- 1,
- 'Lars produced 1 CD with flemming',
- );
- is (
- $lars_cds->search_related ('cd_to_producer',
- { 'producer.name' => 'bob'},
- { join => 'producer' }
- )->count,
- 2,
- 'Lars produced 2 CDs with bob',
- );
-
- my $bob_prod = $cd_rs->search (
- { 'producer.name' => 'bob'},
- { join => { cd_to_producer => 'producer' } }
- );
- is ($bob_prod->count, 3, 'Bob produced a total of 3 CDs');
-
- is (
- $bob_prod->search ({ 'artist.name' => 'james' }, { join => 'artist' })->count,
- 1,
- "Bob produced james' only CD",
- );
-};
-diag $@ if $@;
-
1;
Added: DBIx-Class/0.08/branches/views/t/96multi_create_new.t
===================================================================
--- DBIx-Class/0.08/branches/views/t/96multi_create_new.t (rev 0)
+++ DBIx-Class/0.08/branches/views/t/96multi_create_new.t 2009-02-20 07:54:30 UTC (rev 5585)
@@ -0,0 +1,63 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Exception;
+use lib qw(t/lib);
+use DBICTest;
+
+plan tests => 9;
+
+my $schema = DBICTest->init_schema();
+
+# Test various new() invocations - this is all about backcompat, making
+# sure that insert() still works as expected by legacy code.
+#
+# What we essentially do is multi-instantiate objects, making sure nothing
+# gets inserted. Then we add some more objects to the mix either via
+# new_related() or by setting an accessor directly (or both) - again
+# expecting no inserts. Then after calling insert() on the starter object
+# we expect everything supplied to new() to get inserted, as well as any
+# relations whose PK's are necessary to complete the objects supplied
+# to new(). All other objects should be insert()able afterwards too.
+
+
+{
+ my $new_artist = $schema->resultset("Artist")->new_result({ 'name' => 'Depeche Mode' });
+ my $new_related_cd = $new_artist->new_related('cds', { 'title' => 'Leave in Silence', 'year' => 1982});
+ eval {
+ $new_artist->insert;
+ $new_related_cd->insert;
+ };
+ is ($@, '', 'Staged insertion successful');
+ ok($new_artist->in_storage, 'artist inserted');
+ ok($new_related_cd->in_storage, 'new_related_cd inserted');
+}
+
+{
+ my $new_artist = $schema->resultset("Artist")->new_result({ 'name' => 'Depeche Mode' });
+ my $new_related_cd = $new_artist->new_related('cds', { 'title' => 'Leave in Silence', 'year' => 1982});
+ eval {
+ $new_related_cd->insert;
+ };
+ is ($@, '', 'CD insertion survives by inserting artist');
+ ok($new_artist->in_storage, 'artist inserted');
+ ok($new_related_cd->in_storage, 'new_related_cd inserted');
+}
+
+{
+ my $new_cd = $schema->resultset("CD")->new_result({});
+ my $new_related_artist = $new_cd->new_related('artist', { 'name' => 'Marillion',});
+ lives_ok (
+ sub {
+ $new_related_artist->insert;
+ $new_cd->title( 'Misplaced Childhood' );
+ $new_cd->year ( 1985 );
+ $new_cd->artist( $new_related_artist ); # For exact backward compatibility
+ $new_cd->insert;
+ },
+ 'Reversed staged insertion successful'
+ );
+ ok($new_related_artist->in_storage, 'related artist inserted');
+ ok($new_cd->in_storage, 'cd inserted');
+}
Added: DBIx-Class/0.08/branches/views/t/96multi_create_torture.t
===================================================================
--- DBIx-Class/0.08/branches/views/t/96multi_create_torture.t (rev 0)
+++ DBIx-Class/0.08/branches/views/t/96multi_create_torture.t 2009-02-20 07:54:30 UTC (rev 5585)
@@ -0,0 +1,226 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Exception;
+use lib qw(t/lib);
+use DBICTest;
+
+plan tests => 19;
+
+# an insane multicreate
+# (should work, despite the fact that no one will probably use it this way)
+
+my $schema = DBICTest->init_schema();
+
+# first count how many rows do we initially have
+my $counts;
+$counts->{$_} = $schema->resultset($_)->count for qw/Artist CD Genre Producer Tag/;
+
+# do the crazy create
+eval {
+ $schema->resultset('CD')->create ({
+ artist => {
+ name => 'james',
+ },
+ title => 'Greatest hits 1',
+ year => '2012',
+ genre => {
+ name => '"Greatest" collections',
+ },
+ tags => [
+ { tag => 'A' },
+ { tag => 'B' },
+ ],
+ cd_to_producer => [
+ {
+ producer => {
+ name => 'bob',
+ producer_to_cd => [
+ {
+ cd => {
+ artist => {
+ name => 'lars',
+ cds => [
+ {
+ title => 'Greatest hits 2',
+ year => 2012,
+ genre => {
+ name => '"Greatest" collections',
+ },
+ tags => [
+ { tag => 'A' },
+ { tag => 'B' },
+ ],
+ # This cd is created via artist so it doesn't know about producers
+ cd_to_producer => [
+ # if we specify 'bob' here things bomb
+ # as the producer attached to Greatest Hits 1 is
+ # already created, but not yet inserted.
+ # Maybe this can be fixed, but things are hairy
+ # enough already.
+ #
+ #{ producer => { name => 'bob' } },
+ { producer => { name => 'paul' } },
+ { producer => {
+ name => 'flemming',
+ producer_to_cd => [
+ { cd => {
+ artist => {
+ name => 'kirk',
+ cds => [
+ {
+ title => 'Greatest hits 3',
+ year => 2012,
+ genre => {
+ name => '"Greatest" collections',
+ },
+ tags => [
+ { tag => 'A' },
+ { tag => 'B' },
+ ],
+ },
+ {
+ title => 'Greatest hits 4',
+ year => 2012,
+ genre => {
+ name => '"Greatest" collections2',
+ },
+ tags => [
+ { tag => 'A' },
+ { tag => 'B' },
+ ],
+ },
+ ],
+ },
+ title => 'Greatest hits 5',
+ year => 2013,
+ genre => {
+ name => '"Greatest" collections2',
+ },
+ }},
+ ],
+ }},
+ ],
+ },
+ ],
+ },
+ title => 'Greatest hits 6',
+ year => 2012,
+ genre => {
+ name => '"Greatest" collections',
+ },
+ tags => [
+ { tag => 'A' },
+ { tag => 'B' },
+ ],
+ },
+ },
+ {
+ cd => {
+ artist => {
+ name => 'lars', # should already exist
+ # even though the artist 'name' is not uniquely constrained
+ # find_or_create will arguably DWIM
+ },
+ title => 'Greatest hits 7',
+ year => 2013,
+ },
+ },
+ ],
+ },
+ },
+ ],
+ });
+
+ is ($schema->resultset ('Artist')->count, $counts->{Artist} + 3, '3 new artists created');
+ is ($schema->resultset ('Genre')->count, $counts->{Genre} + 2, '2 additional genres created');
+ is ($schema->resultset ('Producer')->count, $counts->{Producer} + 3, '3 new producer');
+ is ($schema->resultset ('CD')->count, $counts->{CD} + 7, '7 new CDs');
+ is ($schema->resultset ('Tag')->count, $counts->{Tag} + 10, '10 new Tags');
+
+ my $cd_rs = $schema->resultset ('CD')
+ ->search ({ title => { -like => 'Greatest hits %' }}, { order_by => 'title'} );
+ is ($cd_rs->count, 7, '7 greatest hits created');
+
+ my $cds_2012 = $cd_rs->search ({ year => 2012});
+ is ($cds_2012->count, 5, '5 CDs created in 2012');
+
+ is (
+ $cds_2012->search(
+ { 'tags.tag' => { -in => [qw/A B/] } },
+ { join => 'tags', group_by => 'me.cdid' }
+ ),
+ 5,
+ 'All 10 tags were pairwise distributed between 5 year-2012 CDs'
+ );
+
+ my $paul_prod = $cd_rs->search (
+ { 'producer.name' => 'paul'},
+ { join => { cd_to_producer => 'producer' } }
+ );
+ is ($paul_prod->count, 1, 'Paul had 1 production');
+ my $pauls_cd = $paul_prod->single;
+ is ($pauls_cd->cd_to_producer->count, 2, 'Paul had one co-producer');
+ is (
+ $pauls_cd->search_related ('cd_to_producer',
+ { 'producer.name' => 'flemming'},
+ { join => 'producer' }
+ )->count,
+ 1,
+ 'The second producer is flemming',
+ );
+
+ my $kirk_cds = $cd_rs->search ({ 'artist.name' => 'kirk' }, { join => 'artist' });
+ is ($kirk_cds, 3, 'Kirk had 3 CDs');
+ is (
+ $kirk_cds->search (
+ { 'cd_to_producer.cd' => { '!=', undef } },
+ { join => 'cd_to_producer' },
+ ),
+ 1,
+ 'Kirk had a producer only on one cd',
+ );
+
+ my $lars_cds = $cd_rs->search ({ 'artist.name' => 'lars' }, { join => 'artist' });
+ is ($lars_cds->count, 3, 'Lars had 3 CDs');
+ is (
+ $lars_cds->search (
+ { 'cd_to_producer.cd' => undef },
+ { join => 'cd_to_producer' },
+ ),
+ 0,
+ 'Lars always had a producer',
+ );
+ is (
+ $lars_cds->search_related ('cd_to_producer',
+ { 'producer.name' => 'flemming'},
+ { join => 'producer' }
+ )->count,
+ 1,
+ 'Lars produced 1 CD with flemming',
+ );
+ is (
+ $lars_cds->search_related ('cd_to_producer',
+ { 'producer.name' => 'bob'},
+ { join => 'producer' }
+ )->count,
+ 2,
+ 'Lars produced 2 CDs with bob',
+ );
+
+ my $bob_prod = $cd_rs->search (
+ { 'producer.name' => 'bob'},
+ { join => { cd_to_producer => 'producer' } }
+ );
+ is ($bob_prod->count, 3, 'Bob produced a total of 3 CDs');
+
+ is (
+ $bob_prod->search ({ 'artist.name' => 'james' }, { join => 'artist' })->count,
+ 1,
+ "Bob produced james' only CD",
+ );
+};
+diag $@ if $@;
+
+1;
Modified: DBIx-Class/0.08/branches/views/t/bindtype_columns.t
===================================================================
--- DBIx-Class/0.08/branches/views/t/bindtype_columns.t 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/t/bindtype_columns.t 2009-02-20 07:54:30 UTC (rev 5585)
@@ -10,7 +10,7 @@
plan skip_all => 'Set $ENV{DBICTEST_PG_DSN}, _USER and _PASS to run this test'
unless ($dsn && $dbuser);
-plan tests => 3;
+plan tests => 6;
my $schema = DBICTest::Schema->connection($dsn, $dbuser, $dbpass, { AutoCommit => 1 });
@@ -18,7 +18,7 @@
{
local $SIG{__WARN__} = sub {};
- $dbh->do('DROP TABLE IF EXISTS artist');
+ $dbh->do('DROP TABLE IF EXISTS bindtype_test');
# the blob/clob are for reference only, will be useful when we switch to SQLT and can test Oracle along the way
$dbh->do(qq[
@@ -32,19 +32,57 @@
],{ RaiseError => 1, PrintError => 1 });
}
-# test primary key handling
-my $big_long_string = 'abcd' x 250000;
+my $big_long_string = "\x00\x01\x02 abcd" x 125000;
-my $new = $schema->resultset('BindType')->create({ bytea => $big_long_string });
+my $new;
+# test inserting a row
+{
+ $new = $schema->resultset('BindType')->create({ bytea => $big_long_string });
-ok($new->id, "Created a bytea row");
-is($new->bytea, $big_long_string, "Set the blob correctly.");
+ ok($new->id, "Created a bytea row");
+ is($new->bytea, $big_long_string, "Set the blob correctly.");
+}
-my $rs = $schema->resultset('BindType')->find({ id => $new->id });
+# test retrieval of the bytea column
+{
+ my $row = $schema->resultset('BindType')->find({ id => $new->id });
+ is($row->get_column('bytea'), $big_long_string, "Created the blob correctly.");
+}
-is($rs->get_column('bytea'), $big_long_string, "Created the blob correctly.");
+TODO: {
+ local $TODO =
+ 'Passing bind attributes to $sth->bind_param() should be implemented (it only works in $storage->insert ATM)';
-$dbh->do("DROP TABLE bindtype_test");
+ my $rs = $schema->resultset('BindType')->search({ bytea => $big_long_string });
+ # search on the bytea column (select)
+ {
+ my $row = $rs->first;
+ is($row ? $row->id : undef, $new->id, "Found the row searching on the bytea column.");
+ }
+ # search on the bytea column (update)
+ {
+ my $new_big_long_string = $big_long_string . "2";
+ $schema->txn_do(sub {
+ $rs->update({ bytea => $new_big_long_string });
+ my $row = $schema->resultset('BindType')->find({ id => $new->id });
+ is($row ? $row->get_column('bytea') : undef, $new_big_long_string,
+ "Updated the row correctly (searching on the bytea column)."
+ );
+ $schema->txn_rollback;
+ });
+ }
+ # search on the bytea column (delete)
+ {
+ $schema->txn_do(sub {
+ $rs->delete;
+ my $row = $schema->resultset('BindType')->find({ id => $new->id });
+ is($row, undef, "Deleted the row correctly (searching on the bytea column).");
+ $schema->txn_rollback;
+ });
+ }
+}
+
+$dbh->do("DROP TABLE bindtype_test");
Modified: DBIx-Class/0.08/branches/views/t/lib/DBIC/SqlMakerTest.pm
===================================================================
--- DBIx-Class/0.08/branches/views/t/lib/DBIC/SqlMakerTest.pm 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/t/lib/DBIC/SqlMakerTest.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -7,8 +7,11 @@
our @EXPORT = qw/
&is_same_sql_bind
+ &is_same_sql
+ &is_same_bind
&eq_sql
&eq_bind
+ &eq_sql_bind
/;
@@ -39,19 +42,59 @@
$tb->ok($same_sql && $same_bind, $msg);
if (!$same_sql) {
- $tb->diag("SQL expressions differ\n"
- . " got: $sql1\n"
- . "expected: $sql2\n"
- );
+ _sql_differ_diag($sql1, $sql2);
}
if (!$same_bind) {
- $tb->diag("BIND values differ\n"
- . " got: " . Dumper($bind_ref1)
- . "expected: " . Dumper($bind_ref2)
- );
+ _bind_differ_diag($bind_ref1, $bind_ref2);
}
}
+ sub is_same_sql
+ {
+ my ($sql1, $sql2, $msg) = @_;
+
+ my $same_sql = eq_sql($sql1, $sql2);
+
+ $tb->ok($same_sql, $msg);
+
+ if (!$same_sql) {
+ _sql_differ_diag($sql1, $sql2);
+ }
+ }
+
+ sub is_same_bind
+ {
+ my ($bind_ref1, $bind_ref2, $msg) = @_;
+
+ my $same_bind = eq_bind($bind_ref1, $bind_ref2);
+
+ $tb->ok($same_bind, $msg);
+
+ if (!$same_bind) {
+ _bind_differ_diag($bind_ref1, $bind_ref2);
+ }
+ }
+
+ sub _sql_differ_diag
+ {
+ my ($sql1, $sql2) = @_;
+
+ $tb->diag("SQL expressions differ\n"
+ . " got: $sql1\n"
+ . "expected: $sql2\n"
+ );
+ }
+
+ sub _bind_differ_diag
+ {
+ my ($bind_ref1, $bind_ref2) = @_;
+
+ $tb->diag("BIND values differ\n"
+ . " got: " . Dumper($bind_ref1)
+ . "expected: " . Dumper($bind_ref2)
+ );
+ }
+
sub eq_sql
{
my ($left, $right) = @_;
@@ -68,6 +111,13 @@
return eq_deeply($bind_ref1, $bind_ref2);
}
+
+ sub eq_sql_bind
+ {
+ my ($sql1, $bind_ref1, $sql2, $bind_ref2) = @_;
+
+ return eq_sql($sql1, $sql2) && eq_bind($bind_ref1, $bind_ref2);
+ }
}
eval "use SQL::Abstract::Test;";
@@ -75,14 +125,20 @@
# SQL::Abstract::Test available
*is_same_sql_bind = \&SQL::Abstract::Test::is_same_sql_bind;
+ *is_same_sql = \&SQL::Abstract::Test::is_same_sql;
+ *is_same_bind = \&SQL::Abstract::Test::is_same_bind;
*eq_sql = \&SQL::Abstract::Test::eq_sql;
*eq_bind = \&SQL::Abstract::Test::eq_bind;
+ *eq_sql_bind = \&SQL::Abstract::Test::eq_sql_bind;
} else {
# old SQL::Abstract
*is_same_sql_bind = \&DBIC::SqlMakerTest::SQLATest::is_same_sql_bind;
+ *is_same_sql = \&DBIC::SqlMakerTest::SQLATest::is_same_sql;
+ *is_same_bind = \&DBIC::SqlMakerTest::SQLATest::is_same_bind;
*eq_sql = \&DBIC::SqlMakerTest::SQLATest::eq_sql;
*eq_bind = \&DBIC::SqlMakerTest::SQLATest::eq_bind;
+ *eq_sql_bind = \&DBIC::SqlMakerTest::SQLATest::eq_sql_bind;
}
@@ -131,6 +187,28 @@
Compares given and expected pairs of C<($sql, \@bind)>, and calls
L<Test::Builder/ok> on the result, with C<$test_msg> as message.
+=head2 is_same_sql
+
+ is_same_sql(
+ $given_sql,
+ $expected_sql,
+ $test_msg
+ );
+
+Compares given and expected SQL statement, and calls L<Test::Builder/ok> on the
+result, with C<$test_msg> as message.
+
+=head2 is_same_bind
+
+ is_same_bind(
+ \@given_bind,
+ \@expected_bind,
+ $test_msg
+ );
+
+Compares given and expected bind value lists, and calls L<Test::Builder/ok> on
+the result, with C<$test_msg> as message.
+
=head2 eq_sql
my $is_same = eq_sql($given_sql, $expected_sql);
@@ -143,7 +221,17 @@
Compares two lists of bind values. Returns true IFF their values are the same.
+=head2 eq_sql_bind
+ my $is_same = eq_sql_bind(
+ $given_sql, \@given_bind,
+ $expected_sql, \@expected_bind
+ );
+
+Compares the two SQL statements and the two lists of bind values. Returns true
+IFF they are equivalent and the bind values are the same.
+
+
=head1 SEE ALSO
L<SQL::Abstract::Test>, L<Test::More>, L<Test::Builder>.
Added: DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/ResultSet/Foo.pm
===================================================================
--- DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/ResultSet/Foo.pm (rev 0)
+++ DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/ResultSet/Foo.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -0,0 +1,8 @@
+package DBICNSTest::RtBug41083::ResultSet::Foo;
+use strict;
+use warnings;
+use base 'DBICNSTest::RtBug41083::ResultSet';
+
+sub fooBar { 1; }
+
+1;
Added: DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/ResultSet.pm
===================================================================
--- DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/ResultSet.pm (rev 0)
+++ DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/ResultSet.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -0,0 +1,5 @@
+package DBICNSTest::RtBug41083::ResultSet;
+use strict;
+use warnings;
+use base 'DBIx::Class::ResultSet';
+1;
Added: DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/ResultSet_A/A.pm
===================================================================
--- DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/ResultSet_A/A.pm (rev 0)
+++ DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/ResultSet_A/A.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -0,0 +1,7 @@
+package DBICNSTest::RtBug41083::ResultSet_A::A;
+use strict;
+use warnings;
+use base 'DBICNSTest::RtBug41083::ResultSet';
+
+sub fooBar { 1; }
+1;
Added: DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema/Foo/Sub.pm
===================================================================
--- DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema/Foo/Sub.pm (rev 0)
+++ DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema/Foo/Sub.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -0,0 +1,5 @@
+package DBICNSTest::RtBug41083::Schema::Foo::Sub;
+use strict;
+use warnings;
+use base 'DBICNSTest::RtBug41083::Schema::Foo';
+1;
Added: DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema/Foo.pm
===================================================================
--- DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema/Foo.pm (rev 0)
+++ DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema/Foo.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -0,0 +1,8 @@
+package DBICNSTest::RtBug41083::Schema::Foo;
+use strict;
+use warnings;
+use base 'DBIx::Class';
+__PACKAGE__->load_components('Core');
+__PACKAGE__->table('foo');
+__PACKAGE__->add_columns('foo');
+1;
Added: DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema_A/A/Sub.pm
===================================================================
--- DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema_A/A/Sub.pm (rev 0)
+++ DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema_A/A/Sub.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -0,0 +1,5 @@
+package DBICNSTest::RtBug41083::Schema_A::A::Sub;
+use strict;
+use warnings;
+use base 'DBICNSTest::RtBug41083::Schema_A::A';
+1;
Added: DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema_A/A.pm
===================================================================
--- DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema_A/A.pm (rev 0)
+++ DBIx-Class/0.08/branches/views/t/lib/DBICNSTest/RtBug41083/Schema_A/A.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -0,0 +1,8 @@
+package DBICNSTest::RtBug41083::Schema_A::A;
+use strict;
+use warnings;
+use base 'DBIx::Class';
+__PACKAGE__->load_components('Core');
+__PACKAGE__->table('a');
+__PACKAGE__->add_columns('a');
+1;
Modified: DBIx-Class/0.08/branches/views/t/lib/DBICTest/Schema/Artist.pm
===================================================================
--- DBIx-Class/0.08/branches/views/t/lib/DBICTest/Schema/Artist.pm 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/t/lib/DBICTest/Schema/Artist.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -53,12 +53,17 @@
{ cascade_copy => 0 } # this would *so* not make sense
);
+__PACKAGE__->has_many(
+ artist_to_artwork => 'DBICTest::Schema::Artwork_to_Artist' => 'artist_id'
+);
+__PACKAGE__->many_to_many('artworks', 'artist_to_artwork', 'artwork');
+
+
sub sqlt_deploy_hook {
my ($self, $sqlt_table) = @_;
-
if ($sqlt_table->schema->translator->producer_type =~ /SQLite$/ ) {
- $sqlt_table->add_index( name => 'artist_name', fields => ['name'] )
+ $sqlt_table->add_index( name => 'artist_name_hookidx', fields => ['name'] )
or die $sqlt_table->error;
}
}
Modified: DBIx-Class/0.08/branches/views/t/lib/DBICTest/Schema/Artwork.pm
===================================================================
--- DBIx-Class/0.08/branches/views/t/lib/DBICTest/Schema/Artwork.pm 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/t/lib/DBICTest/Schema/Artwork.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -1,4 +1,4 @@
-package # hide from PAUSE
+package # hide from PAUSE
DBICTest::Schema::Artwork;
use base qw/DBIx::Class::Core/;
@@ -13,4 +13,7 @@
__PACKAGE__->belongs_to('cd', 'DBICTest::Schema::CD', 'cd_id');
__PACKAGE__->has_many('images', 'DBICTest::Schema::Image', 'artwork_id');
+__PACKAGE__->has_many('artwork_to_artist', 'DBICTest::Schema::Artwork_to_Artist', 'artwork_cd_id');
+__PACKAGE__->many_to_many('artists', 'artwork_to_artist', 'artist');
+
1;
Added: DBIx-Class/0.08/branches/views/t/lib/DBICTest/Schema/Artwork_to_Artist.pm
===================================================================
--- DBIx-Class/0.08/branches/views/t/lib/DBICTest/Schema/Artwork_to_Artist.pm (rev 0)
+++ DBIx-Class/0.08/branches/views/t/lib/DBICTest/Schema/Artwork_to_Artist.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -0,0 +1,21 @@
+package # hide from PAUSE
+ DBICTest::Schema::Artwork_to_Artist;
+
+use base qw/DBIx::Class::Core/;
+
+__PACKAGE__->table('artwork_to_artist');
+__PACKAGE__->add_columns(
+ 'artwork_cd_id' => {
+ data_type => 'integer',
+ is_foreign_key => 1,
+ },
+ 'artist_id' => {
+ data_type => 'integer',
+ is_foreign_key => 1,
+ },
+);
+__PACKAGE__->set_primary_key(qw/artwork_cd_id artist_id/);
+__PACKAGE__->belongs_to('artwork', 'DBICTest::Schema::Artwork', 'artwork_cd_id');
+__PACKAGE__->belongs_to('artist', 'DBICTest::Schema::Artist', 'artist_id');
+
+1;
Modified: DBIx-Class/0.08/branches/views/t/lib/DBICTest/Schema.pm
===================================================================
--- DBIx-Class/0.08/branches/views/t/lib/DBICTest/Schema.pm 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/t/lib/DBICTest/Schema.pm 2009-02-20 07:54:30 UTC (rev 5585)
@@ -24,6 +24,7 @@
{ 'DBICTest::Schema' => [qw/
LinerNotes
Artwork
+ Artwork_to_Artist
Image
Lyrics
LyricVersion
Modified: DBIx-Class/0.08/branches/views/t/lib/sqlite.sql
===================================================================
--- DBIx-Class/0.08/branches/views/t/lib/sqlite.sql 2009-02-20 07:16:53 UTC (rev 5584)
+++ DBIx-Class/0.08/branches/views/t/lib/sqlite.sql 2009-02-20 07:54:30 UTC (rev 5585)
@@ -1,6 +1,6 @@
--
-- Created by SQL::Translator::Producer::SQLite
--- Created on Thu Feb 19 22:09:32 2009
+-- Created on Sat Jan 24 19:42:15 2009
--
@@ -39,6 +39,18 @@
CREATE INDEX cd_artwork_idx_cd_id_cd_artwor ON cd_artwork (cd_id);
--
+-- Table: artwork_to_artist
+--
+CREATE TABLE artwork_to_artist (
+ artwork_cd_id integer NOT NULL,
+ artist_id integer NOT NULL,
+ PRIMARY KEY (artwork_cd_id, artist_id)
+);
+
+CREATE INDEX artwork_to_artist_idx_artist_id_artwork_to_arti ON artwork_to_artist (artist_id);
+CREATE INDEX artwork_to_artist_idx_artwork_cd_id_artwork_to_ ON artwork_to_artist (artwork_cd_id);
+
+--
-- Table: bindtype_test
--
CREATE TABLE bindtype_test (
Added: DBIx-Class/0.08/branches/views/t/resultset/as_query.t
===================================================================
--- DBIx-Class/0.08/branches/views/t/resultset/as_query.t (rev 0)
+++ DBIx-Class/0.08/branches/views/t/resultset/as_query.t 2009-02-20 07:54:30 UTC (rev 5585)
@@ -0,0 +1,74 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings FATAL => 'all';
+
+use Data::Dumper;
+
+use Test::More;
+
+BEGIN {
+ eval "use SQL::Abstract 1.49";
+ plan $@
+ ? ( skip_all => "Needs SQLA 1.49+" )
+ : ( tests => 4 );
+}
+
+use lib qw(t/lib);
+use DBICTest;
+use DBIC::SqlMakerTest;
+
+my $schema = DBICTest->init_schema();
+my $art_rs = $schema->resultset('Artist');
+my $cdrs = $schema->resultset('CD');
+
+{
+ my $arr = $art_rs->as_query;
+ my ($query, @bind) = @{$$arr};
+
+ is_same_sql_bind(
+ $query, \@bind,
+ "(SELECT me.artistid, me.name, me.rank, me.charfield FROM artist me)", [],
+ );
+}
+
+$art_rs = $art_rs->search({ name => 'Billy Joel' });
+
+{
+ my $arr = $art_rs->as_query;
+ my ($query, @bind) = @{$$arr};
+
+ is_same_sql_bind(
+ $query, \@bind,
+ "(SELECT me.artistid, me.name, me.rank, me.charfield FROM artist me WHERE ( name = ? ))",
+ [ [ name => 'Billy Joel' ] ],
+ );
+}
+
+$art_rs = $art_rs->search({ rank => 2 });
+
+{
+ my $arr = $art_rs->as_query;
+ my ($query, @bind) = @{$$arr};
+
+ is_same_sql_bind(
+ $query, \@bind,
+ "(SELECT me.artistid, me.name, me.rank, me.charfield FROM artist me WHERE ( ( ( rank = ? ) AND ( name = ? ) ) ) )",
+ [ [ rank => 2 ], [ name => 'Billy Joel' ] ],
+ );
+}
+
+my $rscol = $art_rs->get_column( 'charfield' );
+
+{
+ my $arr = $rscol->as_query;
+ my ($query, @bind) = @{$$arr};
+
+ is_same_sql_bind(
+ $query, \@bind,
+ "(SELECT me.charfield FROM artist me WHERE ( ( ( rank = ? ) AND ( name = ? ) ) ) )",
+ [ [ rank => 2 ], [ name => 'Billy Joel' ] ],
+ );
+}
+
+__END__
Added: DBIx-Class/0.08/branches/views/t/search/subquery.t
===================================================================
--- DBIx-Class/0.08/branches/views/t/search/subquery.t (rev 0)
+++ DBIx-Class/0.08/branches/views/t/search/subquery.t 2009-02-20 07:54:30 UTC (rev 5585)
@@ -0,0 +1,155 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings FATAL => 'all';
+
+use Data::Dumper;
+
+use Test::More;
+
+BEGIN {
+ eval "use SQL::Abstract 1.49";
+ plan $@
+ ? ( skip_all => "Needs SQLA 1.49+" )
+ : ( tests => 6 );
+}
+
+use lib qw(t/lib);
+use DBICTest;
+use DBIC::SqlMakerTest;
+
+my $schema = DBICTest->init_schema();
+my $art_rs = $schema->resultset('Artist');
+my $cdrs = $schema->resultset('CD');
+
+{
+ my $cdrs2 = $cdrs->search({
+ artist_id => { 'in' => $art_rs->search({}, { rows => 1 })->get_column( 'id' )->as_query },
+ });
+
+ my $arr = $cdrs2->as_query;
+ 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 )",
+ [],
+ );
+}
+
+TODO: {
+ local $TODO = "'+select' doesn't work with as_query yet.";
+ my $rs = $art_rs->search(
+ {},
+ {
+ '+select' => [
+ $cdrs->search({}, { rows => 1 })->get_column('id')->as_query,
+ ],
+ '+as' => [
+ 'cdid',
+ ],
+ },
+ );
+
+ my $arr = $rs->as_query;
+ my ($query, @bind) = @{$$arr};
+ is_same_sql_bind(
+ $query, \@bind,
+ "SELECT me.artistid, me.name, me.rank, me.charfield, (SELECT id FROM cds LIMIT 1) AS cdid FROM artist me",
+ [],
+ );
+}
+
+# simple from
+{
+ my $rs = $cdrs->search(
+ {},
+ {
+ alias => 'cd2',
+ from => [
+ { cd2 => $cdrs->search({ id => { '>' => 20 } })->as_query },
+ ],
+ },
+ );
+
+ my $arr = $rs->as_query;
+ 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",
+ [],
+ );
+}
+
+# nested from
+{
+ my $art_rs2 = $schema->resultset('Artist')->search({},
+ {
+ from => [ { 'me' => 'artist' },
+ [ { 'cds' => $cdrs->search({},{ 'select' => [\'me.artist as cds_artist' ]})->as_query },
+ { 'me.artistid' => 'cds_artist' } ] ]
+ });
+
+ my $arr = $art_rs2->as_query;
+ 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", []
+ );
+
+
+}
+
+# nested subquery in from
+{
+ my $rs = $cdrs->search(
+ {},
+ {
+ alias => 'cd2',
+ from => [
+ { cd2 => $cdrs->search(
+ { id => { '>' => 20 } },
+ {
+ alias => 'cd3',
+ from => [
+ { cd3 => $cdrs->search( { id => { '<' => 40 } } )->as_query }
+ ],
+ }, )->as_query },
+ ],
+ },
+ );
+
+ my $arr = $rs->as_query;
+ 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 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",
+ [],
+ );
+
+}
+
+{
+ my $rs = $cdrs->search({
+ year => {
+ '=' => $cdrs->search(
+ { artistid => { '=' => \'me.artistid' } },
+ { alias => 'inner' }
+ )->get_column('year')->max_rs->as_query,
+ },
+ });
+ my $arr = $rs->as_query;
+ 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)",
+ [],
+ );
+}
+
+__END__
More information about the Bast-commits
mailing list