From: Peter Rabbitson Date: Sun, 14 Feb 2010 10:41:14 +0000 (+0000) Subject: Merge 'trunk' into 'pri_key_refactor' X-Git-Tag: v0.08120~27^2~3 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=commitdiff_plain;h=0777ad33930b2c09258f9752e4e76c27ca75f347;hp=-c Merge 'trunk' into 'pri_key_refactor' r8510@Thesaurus (orig r8497): caelum | 2010-02-01 12:07:13 +0100 throw exception on attempt to insert a blob with DBD::Oracle == 1.23 r8511@Thesaurus (orig r8498): caelum | 2010-02-01 12:12:48 +0100 add RT link for Oracle blob bug in DBD::Oracle == 1.23 r8527@Thesaurus (orig r8514): caelum | 2010-02-02 23:20:17 +0100 r22968@hlagh (orig r8502): caelum | 2010-02-02 05:30:47 -0500 branch to support Sybase SQL Anywhere r22971@hlagh (orig r8505): caelum | 2010-02-02 07:21:13 -0500 ASA last_insert_id and limit support, still needs BLOB support r22972@hlagh (orig r8506): caelum | 2010-02-02 08:33:57 -0500 deref table name if needed, check all columns for identity column not just PK r22973@hlagh (orig r8507): caelum | 2010-02-02 08:48:11 -0500 test blobs, they work, didn't have to do anything r22974@hlagh (orig r8508): caelum | 2010-02-02 09:15:44 -0500 fix stupid identity bug, test empty insert (works), test DTs (not working yet) r22976@hlagh (orig r8510): caelum | 2010-02-02 14:31:00 -0500 rename ::Sybase::ASA to ::SQLAnywhere, per mst r22978@hlagh (orig r8512): caelum | 2010-02-02 17:02:29 -0500 DT inflation now works r22979@hlagh (orig r8513): caelum | 2010-02-02 17:18:06 -0500 minor POD update r8528@Thesaurus (orig r8515): caelum | 2010-02-02 23:23:26 +0100 r22895@hlagh (orig r8473): caelum | 2010-01-30 03:57:26 -0500 branch to fix computed columns in Sybase ASE r22911@hlagh (orig r8489): caelum | 2010-01-31 07:18:33 -0500 empty insert into a Sybase table with computed columns and either data_type => undef or default_value => SCALARREF works now r22912@hlagh (orig r8490): caelum | 2010-01-31 07:39:32 -0500 add POD about computed columns and timestamps for Sybase r22918@hlagh (orig r8496): caelum | 2010-02-01 05:09:07 -0500 update POD about Schema::Loader for Sybase r8531@Thesaurus (orig r8518): ribasushi | 2010-02-02 23:57:27 +0100 r8512@Thesaurus (orig r8499): boghead | 2010-02-01 23:38:13 +0100 - Creating a branch for adding _post_inflate_datetime and _pre_deflate_datetime to InflateColumn::DateTime r8513@Thesaurus (orig r8500): boghead | 2010-02-01 23:42:14 +0100 - Add _post_inflate_datetime and _pre_deflate_datetime to InflateColumn::DateTime to allow for modifying DateTime objects after inflation or before deflation. r8524@Thesaurus (orig r8511): boghead | 2010-02-02 22:59:28 +0100 - Simplify by allowing moving column_info depreciated {extra}{timezone} data to {timezone} (and the same with locale) r8533@Thesaurus (orig r8520): caelum | 2010-02-03 05:19:59 +0100 support for Sybase SQL Anywhere through ODBC r8536@Thesaurus (orig r8523): ribasushi | 2010-02-03 08:27:54 +0100 Changes r8537@Thesaurus (orig r8524): ribasushi | 2010-02-03 08:31:20 +0100 Quote fail r8538@Thesaurus (orig r8525): caelum | 2010-02-03 13:21:37 +0100 test DT inflation for Sybase SQL Anywhere over ODBC too r8539@Thesaurus (orig r8526): caelum | 2010-02-03 17:36:39 +0100 minor code cleanup for SQL Anywhere last_insert_id r8540@Thesaurus (orig r8527): ribasushi | 2010-02-04 11:28:33 +0100 Fix bug reported by tommyt r8548@Thesaurus (orig r8535): ribasushi | 2010-02-04 14:34:45 +0100 Prepare for new SQLA release r8560@Thesaurus (orig r8547): ribasushi | 2010-02-05 08:59:04 +0100 Refactor some evil code r8565@Thesaurus (orig r8552): ribasushi | 2010-02-05 17:00:12 +0100 Looks like RSC is finally (halfway) fixed r8566@Thesaurus (orig r8553): ribasushi | 2010-02-05 17:07:13 +0100 RSC subquery can not include the prefetch r8567@Thesaurus (orig r8554): ribasushi | 2010-02-05 17:10:29 +0100 Fix typo and borked test r8569@Thesaurus (orig r8556): ribasushi | 2010-02-05 17:33:12 +0100 Release 0.08116 r8571@Thesaurus (orig r8558): ribasushi | 2010-02-05 18:01:33 +0100 No idea how I missed all these fails... r8572@Thesaurus (orig r8559): ribasushi | 2010-02-05 18:13:34 +0100 Release 0.08117 r8574@Thesaurus (orig r8561): ribasushi | 2010-02-05 18:51:12 +0100 Try to distinguish trunk from official versions r8580@Thesaurus (orig r8567): gshank | 2010-02-05 22:29:24 +0100 add doc on 'where' attribute r8587@Thesaurus (orig r8574): frew | 2010-02-07 21:07:03 +0100 add as_subselect_rs r8588@Thesaurus (orig r8575): frew | 2010-02-07 21:13:04 +0100 fix longstanding unmentioned bug ("me") r8589@Thesaurus (orig r8576): frew | 2010-02-08 06:17:43 +0100 another example of as_subselect_rs r8590@Thesaurus (orig r8577): frew | 2010-02-08 06:23:58 +0100 fix bug in UTF8Columns r8591@Thesaurus (orig r8578): ribasushi | 2010-02-08 09:31:01 +0100 Extend utf8columns test to trap fixed bug r8592@Thesaurus (orig r8579): ribasushi | 2010-02-08 12:03:23 +0100 Cleanup rel accessor type handling r8593@Thesaurus (orig r8580): ribasushi | 2010-02-08 12:20:47 +0100 Fix some fallout r8595@Thesaurus (orig r8582): ribasushi | 2010-02-08 12:38:19 +0100 Merge some obsolete code cleanup from the prefetch branch r8596@Thesaurus (orig r8583): ribasushi | 2010-02-08 12:42:09 +0100 Merge fix of RT54039 from prefetch branch r8598@Thesaurus (orig r8585): ribasushi | 2010-02-08 12:48:31 +0100 Release 0.08118 r8600@Thesaurus (orig r8587): ribasushi | 2010-02-08 12:52:33 +0100 Bump trunk version r8606@Thesaurus (orig r8593): ribasushi | 2010-02-08 16:16:44 +0100 cheaper lookup r8609@Thesaurus (orig r8596): ribasushi | 2010-02-10 12:40:37 +0100 Consolidate last_insert_id handling with a fallback-attempt on DBI::last_insert_id r8614@Thesaurus (orig r8601): caelum | 2010-02-10 21:29:51 +0100 workaround for Moose bug affecting Replicated storage r8615@Thesaurus (orig r8602): caelum | 2010-02-10 21:40:07 +0100 revert Moose bug workaround, bump Moose dep for Replicated to 0.98 r8616@Thesaurus (orig r8603): caelum | 2010-02-10 22:48:34 +0100 add a couple proxy methods to Replicated so it can run r8628@Thesaurus (orig r8615): caelum | 2010-02-11 11:35:01 +0100 r21090@hlagh (orig r7836): caelum | 2009-11-02 06:40:52 -0500 new branch to fix unhandled methods in Storage::DBI::Replicated r21091@hlagh (orig r7837): caelum | 2009-11-02 06:42:00 -0500 add test to display unhandled methods r21092@hlagh (orig r7838): caelum | 2009-11-02 06:55:34 -0500 minor fix to last committed test r21093@hlagh (orig r7839): caelum | 2009-11-02 09:26:00 -0500 minor test code cleanup r23125@hlagh (orig r8607): caelum | 2010-02-10 19:25:51 -0500 add unimplemented Storage::DBI methods to ::DBI::Replicated r23130@hlagh (orig r8612): ribasushi | 2010-02-11 05:12:48 -0500 Podtesting exclusion r8630@Thesaurus (orig r8617): frew | 2010-02-11 11:45:54 +0100 Changes (from a while ago) r8631@Thesaurus (orig r8618): caelum | 2010-02-11 11:46:58 +0100 savepoints for SQLAnywhere r8640@Thesaurus (orig r8627): ribasushi | 2010-02-11 12:33:19 +0100 r8424@Thesaurus (orig r8411): ribasushi | 2010-01-22 11:19:40 +0100 Chaining POC test r8641@Thesaurus (orig r8628): ribasushi | 2010-02-11 12:34:19 +0100 r8426@Thesaurus (orig r8413): ribasushi | 2010-01-22 11:35:15 +0100 Moev failing regression test away from trunk r8642@Thesaurus (orig r8629): ribasushi | 2010-02-11 12:34:56 +0100 r8643@Thesaurus (orig r8630): ribasushi | 2010-02-11 12:35:03 +0100 r8507@Thesaurus (orig r8494): frew | 2010-02-01 04:33:08 +0100 small refactor to put select/as/+select/+as etc merging in it's own function r8644@Thesaurus (orig r8631): ribasushi | 2010-02-11 12:35:11 +0100 r8514@Thesaurus (orig r8501): frew | 2010-02-02 05:12:29 +0100 revert actual changes from yesterday as per ribasushis advice r8645@Thesaurus (orig r8632): ribasushi | 2010-02-11 12:35:16 +0100 r8522@Thesaurus (orig r8509): frew | 2010-02-02 19:39:33 +0100 delete +stuff if stuff exists r8646@Thesaurus (orig r8633): ribasushi | 2010-02-11 12:35:23 +0100 r8534@Thesaurus (orig r8521): frew | 2010-02-03 06:14:44 +0100 change deletion/overriding to fix t/76 r8647@Thesaurus (orig r8634): ribasushi | 2010-02-11 12:35:30 +0100 r8535@Thesaurus (orig r8522): frew | 2010-02-03 06:57:15 +0100 some basic readability factorings (aka, fewer nested ternaries and long maps) r8648@Thesaurus (orig r8635): ribasushi | 2010-02-11 12:36:01 +0100 r8558@Thesaurus (orig r8545): frew | 2010-02-04 20:32:54 +0100 fix incorrect test in t/76select.t and posit an incorrect solution r8649@Thesaurus (orig r8636): ribasushi | 2010-02-11 12:38:47 +0100 r8650@Thesaurus (orig r8637): ribasushi | 2010-02-11 12:38:57 +0100 r8578@Thesaurus (orig r8565): ribasushi | 2010-02-05 19:11:09 +0100 Should not be needed r8651@Thesaurus (orig r8638): ribasushi | 2010-02-11 12:39:03 +0100 r8579@Thesaurus (orig r8566): ribasushi | 2010-02-05 19:13:24 +0100 SQLA now fixed r8652@Thesaurus (orig r8639): ribasushi | 2010-02-11 12:39:10 +0100 r8624@Thesaurus (orig r8611): ribasushi | 2010-02-11 10:31:08 +0100 MOAR testing r8653@Thesaurus (orig r8640): ribasushi | 2010-02-11 12:39:17 +0100 r8626@Thesaurus (orig r8613): frew | 2010-02-11 11:16:30 +0100 fix bad test r8654@Thesaurus (orig r8641): ribasushi | 2010-02-11 12:39:23 +0100 r8627@Thesaurus (orig r8614): frew | 2010-02-11 11:21:52 +0100 fix t/76, break rsc tests r8655@Thesaurus (orig r8642): ribasushi | 2010-02-11 12:39:30 +0100 r8632@Thesaurus (orig r8619): frew | 2010-02-11 11:53:50 +0100 fix incorrect test r8656@Thesaurus (orig r8643): ribasushi | 2010-02-11 12:39:35 +0100 r8633@Thesaurus (orig r8620): frew | 2010-02-11 11:54:49 +0100 make t/76s and t/88 pass by deleting from the correct attr hash r8657@Thesaurus (orig r8644): ribasushi | 2010-02-11 12:39:40 +0100 r8634@Thesaurus (orig r8621): frew | 2010-02-11 11:55:41 +0100 fix a test due to ordering issues r8658@Thesaurus (orig r8645): ribasushi | 2010-02-11 12:39:45 +0100 r8635@Thesaurus (orig r8622): frew | 2010-02-11 11:58:23 +0100 this is why you run tests before you commit them. r8659@Thesaurus (orig r8646): ribasushi | 2010-02-11 12:39:51 +0100 r8636@Thesaurus (orig r8623): frew | 2010-02-11 12:00:59 +0100 fix another ordering issue r8660@Thesaurus (orig r8647): ribasushi | 2010-02-11 12:39:57 +0100 r8637@Thesaurus (orig r8624): frew | 2010-02-11 12:11:31 +0100 fix for search/select_chains r8661@Thesaurus (orig r8648): ribasushi | 2010-02-11 12:40:03 +0100 r8662@Thesaurus (orig r8649): caelum | 2010-02-11 12:40:07 +0100 test nanosecond precision for SQLAnywhere r8663@Thesaurus (orig r8650): ribasushi | 2010-02-11 12:40:09 +0100 r8639@Thesaurus (orig r8626): ribasushi | 2010-02-11 12:33:03 +0100 Changes and small ommission r8666@Thesaurus (orig r8653): ribasushi | 2010-02-11 18:16:45 +0100 Changes r8674@Thesaurus (orig r8661): ribasushi | 2010-02-12 09:12:45 +0100 Fix moose dep r8680@Thesaurus (orig r8667): dew | 2010-02-12 18:05:11 +0100 Add is_ordered to DBIC::ResultSet r8688@Thesaurus (orig r8675): ribasushi | 2010-02-13 09:36:29 +0100 r8667@Thesaurus (orig r8654): ribasushi | 2010-02-11 18:17:35 +0100 Try a dep-handling idea r8675@Thesaurus (orig r8662): ribasushi | 2010-02-12 12:46:11 +0100 Move optional deps out of the Makefile r8676@Thesaurus (orig r8663): ribasushi | 2010-02-12 13:40:53 +0100 Support methods to verify group dependencies r8677@Thesaurus (orig r8664): ribasushi | 2010-02-12 13:45:18 +0100 Move sqlt dephandling to Optional::Deps r8679@Thesaurus (orig r8666): ribasushi | 2010-02-12 14:03:17 +0100 Move replicated to Opt::Deps r8684@Thesaurus (orig r8671): ribasushi | 2010-02-13 02:47:52 +0100 Auto-POD for Optional Deps r8685@Thesaurus (orig r8672): ribasushi | 2010-02-13 02:53:20 +0100 Privatize the full list method r8686@Thesaurus (orig r8673): ribasushi | 2010-02-13 02:59:51 +0100 Scary warning r8687@Thesaurus (orig r8674): ribasushi | 2010-02-13 09:35:01 +0100 Changes r8691@Thesaurus (orig r8678): ribasushi | 2010-02-13 10:07:15 +0100 Autogen comment for Dependencies.pod r8692@Thesaurus (orig r8679): ribasushi | 2010-02-13 10:11:24 +0100 Ask for newer M::I r8698@Thesaurus (orig r8685): ribasushi | 2010-02-13 11:11:10 +0100 Add author/license to pod r8699@Thesaurus (orig r8686): arcanez | 2010-02-13 13:43:22 +0100 fix typo per nuba on irc r8705@Thesaurus (orig r8692): ribasushi | 2010-02-13 15:15:33 +0100 r8001@Thesaurus (orig r7989): goraxe | 2009-11-30 01:14:47 +0100 Branch for dbicadmin script refactor r8003@Thesaurus (orig r7991): goraxe | 2009-11-30 01:26:39 +0100 add DBIx::Class::Admin r8024@Thesaurus (orig r8012): goraxe | 2009-12-02 22:49:27 +0100 get deployment tests to pass r8025@Thesaurus (orig r8013): goraxe | 2009-12-02 22:50:42 +0100 get deployment tests to pass r8026@Thesaurus (orig r8014): goraxe | 2009-12-02 23:52:40 +0100 all ddl tests now pass r8083@Thesaurus (orig r8071): goraxe | 2009-12-12 17:01:11 +0100 add quite attribute to DBIx::Class admin r8086@Thesaurus (orig r8074): goraxe | 2009-12-12 17:36:58 +0100 add tests for data manipulation ported from 89dbicadmin.t r8088@Thesaurus (orig r8076): goraxe | 2009-12-12 17:38:07 +0100 add sleep 1 to t/admin/02ddl.t so insert into upgrade table does not happen too quickly r8089@Thesaurus (orig r8077): goraxe | 2009-12-12 17:40:33 +0100 update DBIx::Class::Admin data manip functions to pass the test r8095@Thesaurus (orig r8083): goraxe | 2009-12-12 19:36:22 +0100 change passing of preversion to be a parameter r8096@Thesaurus (orig r8084): goraxe | 2009-12-12 19:38:26 +0100 add some pod to DBIx::Class::Admin r8103@Thesaurus (orig r8091): goraxe | 2009-12-12 22:08:55 +0100 some changes to make DBIx::Class::Admin more compatible with dbicadmin interface r8104@Thesaurus (orig r8092): goraxe | 2009-12-12 22:09:39 +0100 commit refactored dbicadmin script and very minor changes to its existing test suite r8107@Thesaurus (orig r8095): goraxe | 2009-12-12 22:34:35 +0100 add compatability for --op for dbicadmin, revert test suite r8127@Thesaurus (orig r8115): goraxe | 2009-12-15 22:14:20 +0100 dep check to end of module r8128@Thesaurus (orig r8116): goraxe | 2009-12-15 23:15:25 +0100 add namespace::autoclean to DBIx::Class::Admin r8129@Thesaurus (orig r8117): goraxe | 2009-12-15 23:16:00 +0100 update test suite to skip if cannot load DBIx::Class::Admin r8130@Thesaurus (orig r8118): goraxe | 2009-12-15 23:18:35 +0100 add deps check for 89dbicadmin.t r8131@Thesaurus (orig r8119): goraxe | 2009-12-15 23:19:01 +0100 include deps for dbicadmin DBIx::Class::Admin to Makefile.PL r8149@Thesaurus (orig r8137): goraxe | 2009-12-17 23:21:50 +0100 use DBICTest::_database over creating a schema object to steal conn info r8338@Thesaurus (orig r8326): goraxe | 2010-01-15 19:00:17 +0100 change white space to not be tabs r8339@Thesaurus (orig r8327): goraxe | 2010-01-15 19:10:42 +0100 remove Module::Load from test suite r8358@Thesaurus (orig r8346): ribasushi | 2010-01-17 17:52:10 +0100 Real detabify r8359@Thesaurus (orig r8347): ribasushi | 2010-01-17 18:01:53 +0100 Fix POD (spacing matters) r8360@Thesaurus (orig r8348): ribasushi | 2010-01-17 21:57:53 +0100 More detabification r8361@Thesaurus (orig r8349): ribasushi | 2010-01-17 22:33:12 +0100 Test cleanup r8362@Thesaurus (orig r8350): ribasushi | 2010-01-17 22:41:11 +0100 More tets cleanup r8363@Thesaurus (orig r8351): ribasushi | 2010-01-17 22:43:57 +0100 And more cleanup r8364@Thesaurus (orig r8352): ribasushi | 2010-01-17 22:51:21 +0100 Disallow mucking with INC r8365@Thesaurus (orig r8353): ribasushi | 2010-01-17 23:23:15 +0100 More cleanup r8366@Thesaurus (orig r8354): ribasushi | 2010-01-17 23:27:49 +0100 Add lib path to ENV so that $^X can see it r8367@Thesaurus (orig r8355): ribasushi | 2010-01-17 23:33:10 +0100 Move script-test r8368@Thesaurus (orig r8356): goraxe | 2010-01-17 23:35:03 +0100 change warns/dies -> carp/throw_exception r8369@Thesaurus (orig r8357): goraxe | 2010-01-17 23:53:54 +0100 add goraxe to contributors r8370@Thesaurus (orig r8358): goraxe | 2010-01-17 23:54:15 +0100 remove comment headers r8404@Thesaurus (orig r8391): caelum | 2010-01-20 20:54:29 +0100 minor fixups r8405@Thesaurus (orig r8392): goraxe | 2010-01-20 21:13:24 +0100 add private types to coerce r8406@Thesaurus (orig r8393): goraxe | 2010-01-20 21:17:19 +0100 remove un-needed coerce from schema_class of type Str r8411@Thesaurus (orig r8398): caelum | 2010-01-21 23:36:25 +0100 minor documentation updates r8436@Thesaurus (orig r8423): caelum | 2010-01-25 02:56:30 +0100 this code never runs anyway r8440@Thesaurus (orig r8427): caelum | 2010-01-26 14:05:53 +0100 prefer JSON::DWIW for barekey support r8693@Thesaurus (orig r8680): ribasushi | 2010-02-13 10:27:18 +0100 dbicadmin dependencies r8694@Thesaurus (orig r8681): ribasushi | 2010-02-13 10:28:04 +0100 Some cleaup, make use of Text::CSV r8695@Thesaurus (orig r8682): ribasushi | 2010-02-13 10:34:19 +0100 We use Try::Tiny in a single spot, not grounds for inlusion in deps r8696@Thesaurus (orig r8683): ribasushi | 2010-02-13 10:37:30 +0100 POD section r8697@Thesaurus (orig r8684): ribasushi | 2010-02-13 11:05:17 +0100 Switch tests to Optional::Deps r8700@Thesaurus (orig r8687): ribasushi | 2010-02-13 14:32:50 +0100 Switch Admin/dbicadmin to Opt::Deps r8702@Thesaurus (orig r8689): ribasushi | 2010-02-13 14:39:24 +0100 JSON dep is needed for Admin.pm itself r8703@Thesaurus (orig r8690): ribasushi | 2010-02-13 15:06:28 +0100 Test fixes r8704@Thesaurus (orig r8691): ribasushi | 2010-02-13 15:13:31 +0100 Changes r8707@Thesaurus (orig r8694): ribasushi | 2010-02-13 16:37:57 +0100 Test for optional deps manager r8710@Thesaurus (orig r8697): caelum | 2010-02-14 05:22:03 +0100 add doc on maximum cursors for SQLAnywhere r8711@Thesaurus (orig r8698): ribasushi | 2010-02-14 09:23:09 +0100 Cleanup dependencies / Admin inheritance r8712@Thesaurus (orig r8699): ribasushi | 2010-02-14 09:28:29 +0100 Some formatting r8715@Thesaurus (orig r8702): ribasushi | 2010-02-14 10:46:51 +0100 This is Moose, so use CMOP --- 0777ad33930b2c09258f9752e4e76c27ca75f347 diff --combined Makefile.PL index 9c550a2,c725626..e747063 --- a/Makefile.PL +++ b/Makefile.PL @@@ -1,135 -1,123 +1,123 @@@ - use inc::Module::Install 0.89; + use inc::Module::Install 0.93; use strict; use warnings; use POSIX (); use 5.008001; - # ****** DO NOT ADD OPTIONAL DEPENDENCIES. EVER. --mst ****** + use FindBin; + use lib "$FindBin::Bin/lib"; + + ### + ### DO NOT ADD OPTIONAL DEPENDENCIES HERE, EVEN AS recommends() + ### All of them should go to DBIx::Class::Optional::Dependencies + ### + name 'DBIx-Class'; perl_version '5.008001'; all_from 'lib/DBIx/Class.pm'; + my $build_requires = { + 'DBD::SQLite' => '1.25', + }; + + my $test_requires = { + 'File::Temp' => '0.22', + 'Test::Builder' => '0.33', + 'Test::Deep' => '0', + 'Test::Exception' => '0', + 'Test::More' => '0.92', + 'Test::Warn' => '0.21', + }; + + my $runtime_requires = { + # Core + 'List::Util' => '0', + 'Scalar::Util' => '0', + 'Storable' => '0', + + # Dependencies + 'Carp::Clan' => '6.0', + 'Class::Accessor::Grouped' => '0.09002', + 'Class::C3::Componentised' => '1.0005', + 'Class::Inspector' => '1.24', + 'Data::Page' => '2.00', + 'DBI' => '1.609', + 'MRO::Compat' => '0.09', + 'Module::Find' => '0.06', + 'Path::Class' => '0.18', + 'Scope::Guard' => '0.03', + 'SQL::Abstract' => '1.61', + 'SQL::Abstract::Limit' => '0.13', + 'Sub::Name' => '0.04', + 'Data::Dumper::Concise' => '1.000', + }; + + # this is so we can order requires alphabetically + # copies are needed for author requires injection + my $reqs = { + build_requires => { %$build_requires }, + requires => { %$runtime_requires }, + test_requires => { %$test_requires }, + }; + + # re-build README and require extra modules for testing if we're in a checkout + if ($Module::Install::AUTHOR) { + + print "Regenerating README\n"; + system('pod2text lib/DBIx/Class.pm > README'); + + if (-f 'MANIFEST') { + print "Removing MANIFEST\n"; + unlink 'MANIFEST'; + } + + print "Regenerating Optional/Dependencies.pod\n"; + require DBIx::Class::Optional::Dependencies; + DBIx::Class::Optional::Dependencies->_gen_pod; + + # FIXME Disabled due to unsolved issues, ask theorbtwo + # require Module::Install::Pod::Inherit; + # PodInherit(); + + warn <<'EOW'; + ****************************************************************************** + ****************************************************************************** + *** *** + *** AUTHOR MODE: all optional test dependencies converted to hard requires *** + *** *** + ****************************************************************************** + ****************************************************************************** + + EOW + + $reqs->{test_requires} = { + %{$reqs->{test_requires}}, + %{DBIx::Class::Optional::Dependencies->_all_optional_requirements}, + }; + } + + # compose final req list, for alphabetical ordering + my %final_req; + for my $rtype (keys %$reqs) { + for my $mod (keys %{$reqs->{$rtype}} ) { + + # sanity check req duplications + if ($final_req{$mod}) { + die "$mod specified as both a '$rtype' and a '$final_req{$mod}[0]'\n"; + } - test_requires 'Test::Builder' => '0.33'; - test_requires 'Test::Deep' => '0'; - test_requires 'Test::Exception' => '0'; - test_requires 'Test::More' => '0.92'; - test_requires 'Test::Warn' => '0.21'; - - test_requires 'File::Temp' => '0.22'; - - - # Core - requires 'List::Util' => '0'; - requires 'Scalar::Util' => '0'; - requires 'Storable' => '0'; - - # Dependencies (keep in alphabetical order) - requires 'Carp::Clan' => '6.0'; - requires 'Class::Accessor::Grouped' => '0.09002'; - requires 'Class::C3::Componentised' => '1.0005'; - requires 'Class::Inspector' => '1.24'; - requires 'Data::Page' => '2.00'; - requires 'DBD::SQLite' => '1.25'; - requires 'DBI' => '1.609'; - requires 'JSON::Any' => '1.18'; - requires 'MRO::Compat' => '0.09'; - requires 'Module::Find' => '0.06'; - requires 'Path::Class' => '0.16'; - requires 'Scope::Guard' => '0.03'; - requires 'SQL::Abstract' => '1.60'; - requires 'SQL::Abstract::Limit' => '0.13'; - requires 'Sub::Name' => '0.04'; - requires 'Data::Dumper::Concise' => '1.000'; - - my %replication_requires = ( - 'Moose', => '0.90', - 'MooseX::Types', => '0.21', - 'namespace::clean' => '0.11', - 'Hash::Merge', => '0.11', - ); - - #************************************************************************# - # Make *ABSOLUTELY SURE* that nothing on this list is a real require, # - # since every module listed in %force_requires_if_author is deleted # - # from the final META.yml (thus will never make it as a CPAN dependency) # - #************************************************************************# - my %force_requires_if_author = ( - %replication_requires, - - # when changing also adjust $DBIx::Class::Storage::DBI::minimum_sqlt_version - 'SQL::Translator' => '0.11002', - - # 'Module::Install::Pod::Inherit' => '0.01', - - # when changing also adjust version in t/02pod.t - 'Test::Pod' => '1.26', - - # when changing also adjust version in t/06notabs.t - # 'Test::NoTabs' => '0.9', - - # when changing also adjust version in t/07eol.t - # 'Test::EOL' => '0.6', - - # when changing also adjust version in t/03podcoverage.t - 'Test::Pod::Coverage' => '1.08', - 'Pod::Coverage' => '0.20', - - # CDBI-compat related - 'DBIx::ContextualFetch' => '0', - 'Class::DBI::Plugin::DeepAbstractSearch' => '0', - 'Class::Trigger' => '0', - 'Time::Piece::MySQL' => '0', - 'Clone' => '0', - 'Date::Simple' => '3.03', - - # t/52cycle.t - 'Test::Memory::Cycle' => '0', - 'Devel::Cycle' => '1.10', - - # t/36datetime.t - # t/60core.t - 'DateTime::Format::SQLite' => '0', - - # t/96_is_deteministic_value.t - 'DateTime::Format::Strptime'=> '0', - - # database-dependent reqs - # - $ENV{DBICTEST_PG_DSN} - ? ( - 'Sys::SigAction' => '0', - 'DBD::Pg' => '2.009002', - 'DateTime::Format::Pg' => '0', - ) : () - , - - $ENV{DBICTEST_MYSQL_DSN} - ? ( - 'DateTime::Format::MySQL' => '0', - ) : () - , - - $ENV{DBICTEST_ORA_DSN} - ? ( - 'DateTime::Format::Oracle' => '0', - ) : () - , - - $ENV{DBICTEST_SYBASE_DSN} - ? ( - 'DateTime::Format::Sybase' => 0, - ) : () - , - ); - #************************************************************************# - # Make ABSOLUTELY SURE that nothing on the list above is a real require, # - # since every module listed in %force_requires_if_author is deleted # - # from the final META.yml (thus will never make it as a CPAN dependency) # - #************************************************************************# + $final_req{$mod} = [ $rtype, $reqs->{$rtype}{$mod}||0 ], + } + } + # actual require + for my $mod (sort keys %final_req) { + my ($rtype, $ver) = @{$final_req{$mod}}; + no strict 'refs'; + $rtype->($mod, $ver); + } install_script (qw| script/dbicadmin @@@ -150,49 -138,26 +138,25 @@@ no_index directory => $_ for (qw lib/DBIx/Class/PK/Auto |); no_index package => $_ for (qw/ DBIx::Class::SQLAHacks DBIx::Class::Storage::DBIHacks /); - # re-build README and require extra modules for testing if we're in a checkout - - if ($Module::Install::AUTHOR) { - warn <<'EOW'; - ****************************************************************************** - ****************************************************************************** - *** *** - *** AUTHOR MODE: all optional test dependencies converted to hard requires *** - *** *** - ****************************************************************************** - ****************************************************************************** - - EOW - - foreach my $module (sort keys %force_requires_if_author) { - build_requires ($module => $force_requires_if_author{$module}); - } - - print "Regenerating README\n"; - system('pod2text lib/DBIx/Class.pm > README'); - - if (-f 'MANIFEST') { - print "Removing MANIFEST\n"; - unlink 'MANIFEST'; - } - - # require Module::Install::Pod::Inherit; - # PodInherit(); - } auto_install(); WriteAll(); + # Re-write META.yml to _exclude_ all forced requires (we do not want to ship this) if ($Module::Install::AUTHOR) { + # FIXME test_requires is not yet part of META + my %original_build_requires = ( %$build_requires, %$test_requires ); + + print "Regenerating META with author requires excluded\n"; Meta->{values}{build_requires} = [ grep - { not exists $force_requires_if_author{$_->[0]} } - ( @{Meta->{values}{build_requires}} ) + { exists $original_build_requires{$_->[0]} } + ( @{Meta->{values}{build_requires}} ) ]; Meta->write; diff --combined lib/DBIx/Class/ResultSet.pm index 1bf30a3,26ee0f7..ef7055e --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@@ -291,10 -291,15 +291,15 @@@ sub search_rs $rows = $self->get_cache; } + # reset the selector list + if (List::Util::first { exists $attrs->{$_} } qw{columns select as}) { + delete @{$our_attrs}{qw{select as columns +select +as +columns include_columns}}; + } + my $new_attrs = { %{$our_attrs}, %{$attrs} }; # merge new attrs into inherited - foreach my $key (qw/join prefetch +select +as bind/) { + foreach my $key (qw/join prefetch +select +as +columns include_columns bind/) { next unless exists $attrs->{$key}; $new_attrs->{$key} = $self->_merge_attr($our_attrs->{$key}, $attrs->{$key}); } @@@ -1256,7 -1261,7 +1261,7 @@@ sub _count_subq_rs # if we multi-prefetch we group_by primary keys only as this is what we would # get out of the rs via ->next/->all. We *DO WANT* to clobber old group_by regardless if ( keys %{$attrs->{collapse}} ) { - $sub_attrs->{group_by} = [ map { "$attrs->{alias}.$_" } ($rsrc->primary_columns) ] + $sub_attrs->{group_by} = [ map { "$attrs->{alias}.$_" } ($rsrc->_pri_cols) ] } $sub_attrs->{select} = $rsrc->storage->_subq_count_select ($rsrc, $sub_attrs); @@@ -1415,7 -1420,7 +1420,7 @@@ sub _rs_update_delete my $attrs = $self->_resolved_attrs_copy; delete $attrs->{$_} for qw/collapse select as/; - $attrs->{columns} = [ map { "$attrs->{alias}.$_" } ($self->result_source->primary_columns) ]; + $attrs->{columns} = [ map { "$attrs->{alias}.$_" } ($self->result_source->_pri_cols) ]; if ($needs_group_by_subq) { # make sure no group_by was supplied, or if there is one - make sure it matches @@@ -2465,6 -2470,23 +2470,23 @@@ sub is_paged return !!$self->{attrs}{page}; } + =head2 is_ordered + + =over 4 + + =item Arguments: none + + =item Return Value: true, if the resultset has been ordered with C. + + =back + + =cut + + sub is_ordered { + my ($self) = @_; + return scalar $self->result_source->storage->_parse_order_by($self->{attrs}{order_by}); + } + =head2 related_resultset =over 4 @@@ -2502,7 -2524,7 +2524,7 @@@ sub related_resultset ->relname_to_table_alias($rel, $join_count); # since this is search_related, and we already slid the select window inwards - # (the select/as attrs were deleted in the beginning), we need to flip all + # (the select/as attrs were deleted in the beginning), we need to flip all # left joins to inner, so we get the expected results # read the comment on top of the actual function to see what this does $attrs->{from} = $rsrc->schema->storage->_straight_join_to_node ($attrs->{from}, $alias); @@@ -2588,6 -2610,68 +2610,68 @@@ sub current_source_alias return ($self->{attrs} || {})->{alias} || 'me'; } + =head2 as_subselect_rs + + =over 4 + + =item Arguments: none + + =item Return Value: $resultset + + =back + + Act as a barrier to SQL symbols. The resultset provided will be made into a + "virtual view" by including it as a subquery within the from clause. From this + point on, any joined tables are inaccessible to ->search on the resultset (as if + it were simply where-filtered without joins). For example: + + my $rs = $schema->resultset('Bar')->search({'x.name' => 'abc'},{ join => 'x' }); + + # 'x' now pollutes the query namespace + + # So the following works as expected + my $ok_rs = $rs->search({'x.other' => 1}); + + # But this doesn't: instead of finding a 'Bar' related to two x rows (abc and + # def) we look for one row with contradictory terms and join in another table + # (aliased 'x_2') which we never use + my $broken_rs = $rs->search({'x.name' => 'def'}); + + my $rs2 = $rs->as_subselect_rs; + + # doesn't work - 'x' is no longer accessible in $rs2, having been sealed away + my $not_joined_rs = $rs2->search({'x.other' => 1}); + + # works as expected: finds a 'table' row related to two x rows (abc and def) + my $correctly_joined_rs = $rs2->search({'x.name' => 'def'}); + + Another example of when one might use this would be to select a subset of + columns in a group by clause: + + my $rs = $schema->resultset('Bar')->search(undef, { + group_by => [qw{ id foo_id baz_id }], + })->as_subselect_rs->search(undef, { + columns => [qw{ id foo_id }] + }); + + In the above example normally columns would have to be equal to the group by, + but because we isolated the group by into a subselect the above works. + + =cut + + sub as_subselect_rs { + my $self = shift; + + return $self->result_source->resultset->search( undef, { + alias => $self->current_source_alias, + from => [{ + $self->current_source_alias => $self->as_query, + -alias => $self->current_source_alias, + -source_handle => $self->result_source->handle, + }] + }); + } + # This code is called by search_related, and makes sure there # is clear separation between the joins before, during, and # after the relationship. This information is needed later @@@ -2715,41 -2799,46 +2799,46 @@@ sub _resolved_attrs # build columns (as long as select isn't set) into a set of as/select hashes unless ( $attrs->{select} ) { - my @cols = ( ref($attrs->{columns}) eq 'ARRAY' ) - ? @{ delete $attrs->{columns}} - : ( - ( delete $attrs->{columns} ) - || - $source->columns - ) - ; - - @colbits = map { - ( ref($_) eq 'HASH' ) - ? $_ - : { - ( - /^\Q${alias}.\E(.+)$/ - ? "$1" - : "$_" - ) - => - ( - /\./ - ? "$_" - : "${alias}.$_" - ) - } - } @cols; + my @cols; + if ( ref $attrs->{columns} eq 'ARRAY' ) { + @cols = @{ delete $attrs->{columns}} + } elsif ( defined $attrs->{columns} ) { + @cols = delete $attrs->{columns} + } else { + @cols = $source->columns + } + + for (@cols) { + if ( ref $_ eq 'HASH' ) { + push @colbits, $_ + } else { + my $key = /^\Q${alias}.\E(.+)$/ + ? "$1" + : "$_"; + my $value = /\./ + ? "$_" + : "${alias}.$_"; + push @colbits, { $key => $value }; + } + } } # add the additional columns on - foreach ( 'include_columns', '+columns' ) { - push @colbits, map { - ( ref($_) eq 'HASH' ) - ? $_ - : { ( split( /\./, $_ ) )[-1] => ( /\./ ? $_ : "${alias}.$_" ) } - } ( ref($attrs->{$_}) eq 'ARRAY' ) ? @{ delete $attrs->{$_} } : delete $attrs->{$_} if ( $attrs->{$_} ); + foreach (qw{include_columns +columns}) { + if ( $attrs->{$_} ) { + my @list = ( ref($attrs->{$_}) eq 'ARRAY' ) + ? @{ delete $attrs->{$_} } + : delete $attrs->{$_}; + for (@list) { + if ( ref($_) eq 'HASH' ) { + push @colbits, $_ + } else { + my $key = ( split /\./, $_ )[-1]; + my $value = ( /\./ ? $_ : "$alias.$_" ); + push @colbits, { $key => $value }; + } + } + } } # start with initial select items @@@ -2758,15 -2847,22 +2847,22 @@@ ( ref $attrs->{select} eq 'ARRAY' ) ? [ @{ $attrs->{select} } ] : [ $attrs->{select} ]; - $attrs->{as} = ( - $attrs->{as} - ? ( - ref $attrs->{as} eq 'ARRAY' - ? [ @{ $attrs->{as} } ] - : [ $attrs->{as} ] + + if ( $attrs->{as} ) { + $attrs->{as} = + ( + ref $attrs->{as} eq 'ARRAY' + ? [ @{ $attrs->{as} } ] + : [ $attrs->{as} ] ) - : [ map { m/^\Q${alias}.\E(.+)$/ ? $1 : $_ } @{ $attrs->{select} } ] - ); + } else { + $attrs->{as} = [ map { + m/^\Q${alias}.\E(.+)$/ + ? $1 + : $_ + } @{ $attrs->{select} } + ] + } } else { @@@ -2776,27 -2872,24 +2872,24 @@@ } # now add colbits to select/as - push( @{ $attrs->{select} }, map { values( %{$_} ) } @colbits ); - push( @{ $attrs->{as} }, map { keys( %{$_} ) } @colbits ); + push @{ $attrs->{select} }, map values %{$_}, @colbits; + push @{ $attrs->{as} }, map keys %{$_}, @colbits; - my $adds; - if ( $adds = delete $attrs->{'+select'} ) { + if ( my $adds = delete $attrs->{'+select'} ) { $adds = [$adds] unless ref $adds eq 'ARRAY'; - push( - @{ $attrs->{select} }, - map { /\./ || ref $_ ? $_ : "${alias}.$_" } @$adds - ); + push @{ $attrs->{select} }, + map { /\./ || ref $_ ? $_ : "$alias.$_" } @$adds; } - if ( $adds = delete $attrs->{'+as'} ) { + if ( my $adds = delete $attrs->{'+as'} ) { $adds = [$adds] unless ref $adds eq 'ARRAY'; - push( @{ $attrs->{as} }, @$adds ); + push @{ $attrs->{as} }, @$adds; } - $attrs->{from} ||= [ { + $attrs->{from} ||= [{ -source_handle => $source->handle, -alias => $self->{attrs}{alias}, $self->{attrs}{alias} => $source->from, - } ]; + }]; if ( $attrs->{join} || $attrs->{prefetch} ) { @@@ -2816,7 -2909,7 +2909,7 @@@ $join, $alias, { %{ $attrs->{seen_join} || {} } }, - ($attrs->{seen_join} && keys %{$attrs->{seen_join}}) + ( $attrs->{seen_join} && keys %{$attrs->{seen_join}}) ? $attrs->{from}[-1][0]{-join_path} : [] , @@@ -2851,14 -2944,10 +2944,10 @@@ my %already_grouped = map { $_ => 1 } (@{$attrs->{group_by}}); my $storage = $self->result_source->schema->storage; - my $sql_maker = $storage->sql_maker; - local $sql_maker->{quote_char}; #disable quoting my $rs_column_list = $storage->_resolve_column_info ($attrs->{from}); - my @chunks = $sql_maker->_order_by_chunks ($attrs->{order_by}); - for my $chunk (map { ref $_ ? @$_ : $_ } (@chunks) ) { - $chunk =~ s/\s+ (?: ASC|DESC ) \s* $//ix; + for my $chunk ($storage->_parse_order_by($attrs->{order_by})) { if ($rs_column_list->{$chunk} && not $already_grouped{$chunk}++) { push @{$attrs->{group_by}}, $chunk; } diff --combined lib/DBIx/Class/ResultSource.pm index 26b01cd,1b9baa8..2794292 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@@ -503,16 -503,6 +503,16 @@@ sub primary_columns return @{shift->_primaries||[]}; } +sub _pri_cols { + my $self = shift; + my @pcols = $self->primary_columns + or $self->throw_exception (sprintf( + 'Operation requires a primary key to be declared on %s via set_primary_key', + ref $self, + )); + return @pcols; +} + =head2 add_unique_constraint =over 4 @@@ -1198,12 -1188,6 +1198,6 @@@ sub _compare_relationship_keys return $found; } - sub resolve_join { - carp 'resolve_join is a private method, stop calling it'; - my $self = shift; - $self->_resolve_join (@_); - } - # Returns the {from} structure used to express JOIN conditions sub _resolve_join { my ($self, $join, $alias, $seen, $jpath, $parent_force_left) = @_; @@@ -1272,7 -1256,11 +1266,11 @@@ : $rel_info->{attrs}{join_type} , -join_path => [@$jpath, { $join => $as } ], - -is_single => (List::Util::first { $rel_info->{attrs}{accessor} eq $_ } (qw/single filter/) ), + -is_single => ( + $rel_info->{attrs}{accessor} + && + List::Util::first { $rel_info->{attrs}{accessor} eq $_ } (qw/single filter/) + ), -alias => $as, -relation_chain_depth => $seen->{-relation_chain_depth} || 0, }, @@@ -1383,77 -1371,6 +1381,6 @@@ sub _resolve_condition } } - # Legacy code, needs to go entirely away (fully replaced by _resolve_prefetch) - sub resolve_prefetch { - carp 'resolve_prefetch is a private method, stop calling it'; - - my ($self, $pre, $alias, $seen, $order, $collapse) = @_; - $seen ||= {}; - if( ref $pre eq 'ARRAY' ) { - return - map { $self->resolve_prefetch( $_, $alias, $seen, $order, $collapse ) } - @$pre; - } - elsif( ref $pre eq 'HASH' ) { - my @ret = - map { - $self->resolve_prefetch($_, $alias, $seen, $order, $collapse), - $self->related_source($_)->resolve_prefetch( - $pre->{$_}, "${alias}.$_", $seen, $order, $collapse) - } keys %$pre; - return @ret; - } - elsif( ref $pre ) { - $self->throw_exception( - "don't know how to resolve prefetch reftype ".ref($pre)); - } - else { - my $count = ++$seen->{$pre}; - my $as = ($count > 1 ? "${pre}_${count}" : $pre); - my $rel_info = $self->relationship_info( $pre ); - $self->throw_exception( $self->name . " has no such relationship '$pre'" ) - unless $rel_info; - my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : ''); - my $rel_source = $self->related_source($pre); - - if (exists $rel_info->{attrs}{accessor} - && $rel_info->{attrs}{accessor} eq 'multi') { - $self->throw_exception( - "Can't prefetch has_many ${pre} (join cond too complex)") - unless ref($rel_info->{cond}) eq 'HASH'; - my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}" - if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots } - keys %{$collapse}) { - my ($last) = ($fail =~ /([^\.]+)$/); - carp ( - "Prefetching multiple has_many rels ${last} and ${pre} " - .(length($as_prefix) - ? "at the same level (${as_prefix}) " - : "at top level " - ) - . 'will explode the number of row objects retrievable via ->next or ->all. ' - . 'Use at your own risk.' - ); - } - #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); } - # values %{$rel_info->{cond}}; - $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ]; - # action at a distance. prepending the '.' allows simpler code - # in ResultSet->_collapse_result - my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); } - keys %{$rel_info->{cond}}; - my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY' - ? @{$rel_info->{attrs}{order_by}} - : (defined $rel_info->{attrs}{order_by} - ? ($rel_info->{attrs}{order_by}) - : ())); - push(@$order, map { "${as}.$_" } (@key, @ord)); - } - - return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] } - $rel_source->columns; - } - } # Accepts one or more relationships for the current source and returns an # array of column names for each of those relationships. Column names are @@@ -1502,8 -1419,7 +1429,7 @@@ sub _resolve_prefetch my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : ''); my $rel_source = $self->related_source($pre); - if (exists $rel_info->{attrs}{accessor} - && $rel_info->{attrs}{accessor} eq 'multi') { + if ($rel_info->{attrs}{accessor} && $rel_info->{attrs}{accessor} eq 'multi') { $self->throw_exception( "Can't prefetch has_many ${pre} (join cond too complex)") unless ref($rel_info->{cond}) eq 'HASH'; @@@ -1530,7 -1446,8 +1456,8 @@@ keys %{$rel_info->{cond}}; my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY' ? @{$rel_info->{attrs}{order_by}} - : (defined $rel_info->{attrs}{order_by} + + : (defined $rel_info->{attrs}{order_by} ? ($rel_info->{attrs}{order_by}) : ())); push(@$order, map { "${as}.$_" } (@key, @ord)); diff --combined lib/DBIx/Class/Storage/DBI.pm index f23795f,0030431..e3d90e8 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@@ -16,11 -16,6 +16,6 @@@ use List::Util() use Data::Dumper::Concise(); use Sub::Name (); - # what version of sqlt do we require if deploy() without a ddl_dir is invoked - # when changing also adjust the corresponding author_require in Makefile.PL - my $minimum_sqlt_version = '0.11002'; - - __PACKAGE__->mk_group_accessors('simple' => qw/_connect_info _dbi_connect_info _dbh _sql_maker _sql_maker_opts _conn_pid _conn_tid transaction_depth _dbh_autocommit _driver_determined savepoints/ @@@ -1606,7 -1601,15 +1601,7 @@@ sub _subq_update_delete my $rsrc = $rs->result_source; # quick check if we got a sane rs on our hands - my @pcols = $rsrc->primary_columns; - unless (@pcols) { - $self->throw_exception ( - sprintf ( - "You must declare primary key(s) on source '%s' (via set_primary_key) in order to update or delete complex resultsets", - $rsrc->source_name || $rsrc->from - ) - ); - } + my @pcols = $rsrc->_pri_cols; my $sel = $rs->_resolved_attrs->{select}; $sel = [ $sel ] unless ref $sel eq 'ARRAY'; @@@ -1659,7 -1662,7 +1654,7 @@@ sub _per_row_update_delete my ($rs, $op, $values) = @_; my $rsrc = $rs->result_source; - my @pcols = $rsrc->primary_columns; + my @pcols = $rsrc->_pri_cols; my $guard = $self->txn_scope_guard; @@@ -1825,7 -1828,7 +1820,7 @@@ sub _select_args && (ref $ident eq 'ARRAY' && @$ident > 1) # indicates a join && - scalar $sql_maker->_order_by_chunks ($attrs->{order_by}) + scalar $self->_parse_order_by ($attrs->{order_by}) ) { # the RNO limit dialect above mangles the SQL such that the join gets lost # wrap a subquery here @@@ -2045,18 -2048,14 +2040,14 @@@ Return the row id of the last insert =cut sub _dbh_last_insert_id { - # All Storage's need to register their own _dbh_last_insert_id - # the old SQLite-based method was highly inappropriate + my ($self, $dbh, $source, $col) = @_; - my $self = shift; - my $class = ref $self; - $self->throw_exception (<last_insert_id (undef, undef, $source->name, $col) }; + + return $id if defined $id; - No _dbh_last_insert_id() method found in $class. - Since the method of obtaining the autoincrement id of the last insert - operation varies greatly between different databases, this method must be - individually implemented for every storage class. - EOE + my $class = ref $self; + $self->throw_exception ("No storage specific _dbh_last_insert_id() method implemented in $class, and the generic DBI::last_insert_id() failed"); } sub last_insert_id { @@@ -2247,8 -2246,9 +2238,9 @@@ sub create_ddl_dir %{$sqltargs || {}} }; - $self->throw_exception("Can't create a ddl file without SQL::Translator: " . $self->_sqlt_version_error) - if !$self->_sqlt_version_ok; + unless (DBIx::Class::Optional::Dependencies->req_ok_for ('deploy')) { + $self->throw_exception("Can't create a ddl file without " . DBIx::Class::Optional::Dependencies->req_missing_for ('deploy') ); + } my $sqlt = SQL::Translator->new( $sqltargs ); @@@ -2390,8 -2390,9 +2382,9 @@@ sub deployment_statements return join('', @rows); } - $self->throw_exception("Can't deploy without either SQL::Translator or a ddl_dir: " . $self->_sqlt_version_error ) - if !$self->_sqlt_version_ok; + unless (DBIx::Class::Optional::Dependencies->req_ok_for ('deploy') ) { + $self->throw_exception("Can't deploy without a ddl_dir or " . DBIx::Class::Optional::Dependencies->req_missing_for ('deploy') ); + } # sources needs to be a parser arg, but for simplicty allow at top level # coming in @@@ -2515,33 -2516,6 +2508,6 @@@ sub lag_behind_master return; } - # SQLT version handling - { - my $_sqlt_version_ok; # private - my $_sqlt_version_error; # private - - sub _sqlt_version_ok { - if (!defined $_sqlt_version_ok) { - eval "use SQL::Translator $minimum_sqlt_version"; - if ($@) { - $_sqlt_version_ok = 0; - $_sqlt_version_error = $@; - } - else { - $_sqlt_version_ok = 1; - } - } - return $_sqlt_version_ok; - } - - sub _sqlt_version_error { - shift->_sqlt_version_ok unless defined $_sqlt_version_ok; - return $_sqlt_version_error; - } - - sub _sqlt_minimum_version { $minimum_sqlt_version }; - } - =head2 relname_to_table_alias =over 4 @@@ -2578,7 -2552,10 +2544,10 @@@ sub DESTROY # some databases need this to stop spewing warnings if (my $dbh = $self->_dbh) { local $@; - eval { $dbh->disconnect }; + eval { + %{ $dbh->{CachedKids} } = (); + $dbh->disconnect; + }; } $self->_dbh(undef); diff --combined lib/DBIx/Class/Storage/DBI/MSSQL.pm index 7896a86,8bd0d45..fedec7f --- a/lib/DBIx/Class/Storage/DBI/MSSQL.pm +++ b/lib/DBIx/Class/Storage/DBI/MSSQL.pm @@@ -3,7 -3,7 +3,7 @@@ package DBIx::Class::Storage::DBI::MSSQ use strict; use warnings; -use base qw/DBIx::Class::Storage::DBI::AmbiguousGlob DBIx::Class::Storage::DBI/; +use base qw/DBIx::Class::Storage::DBI/; use mro 'c3'; use List::Util(); @@@ -190,7 -190,7 +190,7 @@@ sub _select_args_to_query # see if this is an ordered subquery my $attrs = $_[3]; - if ( scalar $self->sql_maker->_order_by_chunks ($attrs->{order_by}) ) { + if ( scalar $self->_parse_order_by ($attrs->{order_by}) ) { $self->throw_exception( 'An ordered subselect encountered - this is not safe! Please see "Ordered Subselects" in DBIx::Class::Storage::DBI::MSSQL ') unless $attrs->{unsafe_subselect_ok}; diff --combined lib/DBIx/Class/Storage/DBI/Sybase/ASE.pm index 91bf586,10cc9c8..e3485ce --- a/lib/DBIx/Class/Storage/DBI/Sybase/ASE.pm +++ b/lib/DBIx/Class/Storage/DBI/Sybase/ASE.pm @@@ -353,10 -353,19 +353,19 @@@ sub insert # check for empty insert # INSERT INTO foo DEFAULT VALUES -- does not work with Sybase - # try to insert explicit 'DEFAULT's instead (except for identity) + # try to insert explicit 'DEFAULT's instead (except for identity, timestamp + # and computed columns) if (not %$to_insert) { for my $col ($source->columns) { next if $col eq $identity_col; + + my $info = $source->column_info($col); + + next if ref $info->{default_value} eq 'SCALAR' + || (exists $info->{data_type} && (not defined $info->{data_type})); + + next if $info->{data_type} && $info->{data_type} =~ /^timestamp\z/i; + $to_insert->{$col} = \'DEFAULT'; } } @@@ -719,9 -728,10 +728,9 @@@ sub _remove_blob_cols_array sub _update_blobs { my ($self, $source, $blob_cols, $where) = @_; - my (@primary_cols) = $source->primary_columns; - - $self->throw_exception('Cannot update TEXT/IMAGE column(s) without a primary key') - unless @primary_cols; + my @primary_cols = eval { $source->_pri_cols }; + $self->throw_exception("Cannot update TEXT/IMAGE column(s): $@") + if $@; # check if we're updating a single row by PK my $pk_cols_in_where = 0; @@@ -753,9 -763,10 +762,9 @@@ sub _insert_blobs my $table = $source->name; my %row = %$row; - my (@primary_cols) = $source->primary_columns; - - $self->throw_exception('Cannot update TEXT/IMAGE column(s) without a primary key') - unless @primary_cols; + my @primary_cols = eval { $source->_pri_cols} ; + $self->throw_exception("Cannot update TEXT/IMAGE column(s): $@") + if $@; $self->throw_exception('Cannot update TEXT/IMAGE column(s) without primary key values') if ((grep { defined $row{$_} } @primary_cols) != @primary_cols); @@@ -933,12 -944,8 +942,8 @@@ sub _svp_rollback =head1 Schema::Loader Support - There is an experimental branch of L that will - allow you to dump a schema from most (if not all) versions of Sybase. - - It is available via subversion from: - - http://dev.catalyst.perl.org/repos/bast/branches/DBIx-Class-Schema-Loader/current/ + As of version C<0.05000>, L should work well with + most (if not all) versions of Sybase ASE. =head1 FreeTDS @@@ -1091,6 -1098,42 +1096,42 @@@ loading your app, if it doesn't match t When inserting IMAGE columns using this method, you'll need to use L as well. + =head1 COMPUTED COLUMNS + + If you have columns such as: + + created_dtm AS getdate() + + represent them in your Result classes as: + + created_dtm => { + data_type => undef, + default_value => \'getdate()', + is_nullable => 0, + } + + The C must exist and must be C. Then empty inserts will work + on tables with such columns. + + =head1 TIMESTAMP COLUMNS + + C columns in Sybase ASE are not really timestamps, see: + L. + + They should be defined in your Result classes as: + + ts => { + data_type => 'timestamp', + is_nullable => 0, + inflate_datetime => 0, + } + + The C< 0>> is necessary if you use + L, and most people do, and still want to + be able to read these values. + + The values will come back as hexadecimal. + =head1 TODO =over