[Jifty-commit] r2888 - in Jifty-DBI/trunk: lib/Jifty lib/Jifty/DBI lib/Jifty/DBI/Class lib/Jifty/DBI/Record t

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Sat Mar 3 11:41:09 EST 2007


Author: jesse
Date: Sat Mar  3 11:41:08 2007
New Revision: 2888

Added:
   Jifty-DBI/trunk/lib/Jifty/DBI/Class/
   Jifty-DBI/trunk/lib/Jifty/DBI/Class/Trigger.pm
   Jifty-DBI/trunk/lib/Jifty/DBI/Record/Plugin.pm
   Jifty-DBI/trunk/t/15types.t
   Jifty-DBI/trunk/t/16inheritance.t
Modified:
   Jifty-DBI/trunk/   (props changed)
   Jifty-DBI/trunk/Changes
   Jifty-DBI/trunk/MANIFEST
   Jifty-DBI/trunk/META.yml
   Jifty-DBI/trunk/Makefile.PL
   Jifty-DBI/trunk/SIGNATURE
   Jifty-DBI/trunk/lib/Jifty/DBI.pm
   Jifty-DBI/trunk/lib/Jifty/DBI/Collection.pm
   Jifty-DBI/trunk/lib/Jifty/DBI/Column.pm
   Jifty-DBI/trunk/lib/Jifty/DBI/Record.pm
   Jifty-DBI/trunk/lib/Jifty/DBI/Schema.pm
   Jifty-DBI/trunk/t/01records.t
   Jifty-DBI/trunk/t/02records_object.t
   Jifty-DBI/trunk/t/11schema_records.t
   Jifty-DBI/trunk/t/12prefetch.t
   Jifty-DBI/trunk/t/testmodels.pl

Log:
* Merge down from the Object::Declare branch



r47396 at pinglin (orig r2567):  clkao | 2007-01-26 07:43:23 +0000
 branch for OD-ify jifty::dbi.
 r47399 at pinglin (orig r2570):  audreyt | 2007-01-26 11:27:28 +0000
 * Completely finish porting Jifty::DBI::Schema to use Object::Declare. 
   Visible differences are:
   
     - "refers App::Class" is now an alias for "refers_to App::Class".
 
     - In refers/refers_to it is no longer neccessary to load App::Class
       beforehand; therefore circular references can now be expressed.
 
     - "length is 30" is now invalid; a compile-time exception will be
       raised that tells the user to use "maxlength id 40" instead.
 
 r47424 at pinglin (orig r2595):  audreyt | 2007-01-26 13:32:46 +0000
 * This be 0.39_999.
 
 - Improved error message for "length is 42":
 
  Due to an incompatible API change, the "length" field in
  Jifty::DBI columns has been renamed to "max_length":
  
      column foo =>
          length is 10;       # NOT VALID 
 
  Please write this instead:
  
      column foo =>
          max_length is 10    # VALID
 
 - Calling 'column' within a schema class is an error:
  
     package TestApp::Address::Schema;
     column address => ...;        # NOT VALID
 
   Please write this instead:
 
     package TestApp::Address;
     use Jifty::DBI::Schema;
     use Jifty::DBI::Record schema {
         column address => ...;    # VALID
     };
 
 
 r47425 at pinglin (orig r2596):  audreyt | 2007-01-26 13:36:12 +0000
 * Remove wrong use of SimpleTrace
 r47426 at pinglin (orig r2597):  audreyt | 2007-01-26 13:42:47 +0000
 * Fix warning in die sighandler
 r47427 at pinglin (orig r2598):  audreyt | 2007-01-26 13:44:36 +0000
 * try again...
 r47428 at pinglin (orig r2599):  audreyt | 2007-01-26 13:52:53 +0000
 * Another try at warning avoidance.
 r47430 at pinglin (orig r2601):  audreyt | 2007-01-26 14:11:44 +0000
 * render_as
 r47443 at pinglin (orig r2614):  clkao | 2007-01-27 00:35:04 +0000
 First draft of bundled type support.
 r47447 at pinglin (orig r2618):  jesse | 2007-01-27 02:44:52 +0000
 * Add back support for 'since' and 'until'
 r47448 at pinglin (orig r2619):  audreyt | 2007-01-27 03:06:13 +0000
 * Jifty::DBI::Schema - Proper support for since/until
 r47451 at pinglin (orig r2622):  audreyt | 2007-01-27 03:32:29 +0000
 * Remove the "until '123'" support that was never working anyway.  It's now
   spelled as "till '123'".
 r47455 at pinglin (orig r2626):  audreyt | 2007-01-27 04:09:12 +0000
 * Jifty::DBI::Column - Remove ->until in OD branch
 r47460 at pinglin (orig r2631):  audreyt | 2007-01-27 04:41:14 +0000
 * Fix "refers_to" bug when cloning virtual columns with column name matching /_id$/.
 r47461 at pinglin (orig r2632):  audreyt | 2007-01-27 04:41:32 +0000
 * Fix mismerge.
 r47465 at pinglin (orig r2636):  audreyt | 2007-01-27 05:11:26 +0000
 * Jifty::DBI::Schema - refers_to handling assumes UNIVERSAL::require(),
   so while it should be largely okay to rely on it being supplied by an
   earlier use of ::Record, still it's better to use() it first.
 r47468 at pinglin (orig r2639):  clkao | 2007-01-27 05:39:08 +0000
 tests for inherited models.
 r47495 at pinglin (orig r2666):  audreyt | 2007-01-27 13:07:41 +0000
 * Jifty::DBI::Schema - Rescind "refers Foo::Bar" support as it's not English.
 r47496 at pinglin (orig r2667):  audreyt | 2007-01-27 13:17:04 +0000
 * Add new synonym "references" for "refers_to" as it has no underscores.
 r48581 at pinglin (orig r2853):  jesse | 2007-02-27 20:35:24 +0000
  r48579 at 123:  jesse | 2007-02-27 15:31:36 -0500
   * Fix 'literal' support in the Object::Declare branch of Jifty
 
 r48587 at pinglin (orig r2858):  jesse | 2007-02-28 02:58:04 +0000
  r48582 at pinglin:  jesse | 2007-02-27 21:57:40 -0500
  * Initial stab at a mixin-based Jifty::DBI::Record plugin system.
 
 r48590 at pinglin (orig r2860):  jesse | 2007-02-28 03:28:56 +0000
  r48588 at pinglin:  jesse | 2007-02-27 22:28:37 -0500
  * Blow the methods into the _right_ class
 
 r48619 at pinglin (orig r2872):  jesse | 2007-02-28 20:18:49 +0000
  r48599 at pinglin:  jesse | 2007-02-28 14:24:49 -0500
   * plugins can now export subs
 
 r50704 at pinglin (orig r2880):  jesse | 2007-03-02 00:45:20 +0000
  r50701 at pinglin:  jesse | 2007-03-01 19:44:22 -0500
  * Initial refactoring to introduce callbacks for plugins
 
 r52914 at pinglin (orig r2883):  falcone | 2007-03-03 05:19:37 +0000
  r17051 at ketch:  falcone | 2007-03-03 00:18:35 -0500
  * add missing Class::Trigger dependancy
 
 r52915 at pinglin (orig r2884):  falcone | 2007-03-03 05:20:08 +0000
  r17052 at ketch:  falcone | 2007-03-03 00:18:49 -0500
  * fix table name so test pass on PG
 
 r52948 at pinglin (orig r2886):  jesse | 2007-03-03 16:29:38 +0000
  r52891 at pinglin:  jesse | 2007-03-02 18:51:05 +0000
   * extracting methods for calling validation and Class::Trigger support
 
 r52950 at pinglin (orig r2887):  jesse | 2007-03-03 16:38:15 +0000
  r52944 at pinglin:  jesse | 2007-03-03 12:26:36 +0000
  * Added intial support for plugins to register triggers
  
  r52945 at pinglin:  jesse | 2007-03-03 12:29:38 +0000
   * can not call a method name as the method. "oops"
  r52947 at pinglin:  jesse | 2007-03-03 16:21:49 +0000
   * canonicalizers work
 


Modified: Jifty-DBI/trunk/Changes
==============================================================================
--- Jifty-DBI/trunk/Changes	(original)
+++ Jifty-DBI/trunk/Changes	Sat Mar  3 11:41:08 2007
@@ -1,5 +1,44 @@
 Revision history for Perl extension Jifty::DBI.
 
+0.39_9999 Fri Jan 26 21:30:48 CST 2007
+
+- Removed unneccessary use of Devel::SimpleTrace.
+
+0.39_999 Fri Jan 26 21:30:48 CST 2007
+
+- Improved error message for "length is 42":
+
+ Due to an incompatible API change, the "length" field in
+ Jifty::DBI columns has been renamed to "max_length":
+ 
+     column foo =>
+         length is 10;       # NOT VALID 
+
+ Please write this instead:
+ 
+     column foo =>
+         max_length is 10    # VALID
+
+- Calling 'column' within a schema class is an error:
+ 
+    package TestApp::Address::Schema;
+    column address => ...;        # NOT VALID
+
+  Please write this instead:
+
+    package TestApp::Address;
+    use Jifty::DBI::Schema;
+    use Jifty::DBI::Record schema {
+        column address => ...;    # VALID
+    };
+
+
+0.39_99 Fri Jan 26 19:57:48 CST 2007
+
+- INCOMPATIBLE API CHANGE: "length is 42" must be written as "max_length is 42" instead.
+- Switch to Object::Declare for schema declaration, fixing many annoyances such as the inability for two modules to refer to each other in their columns.
+- "refers Foo::Bar", a new alias to "refers_to Foo::Bar".
+
 0.34 Sun Jan 28 21:28:00 CST 2007
 
 - Added a method to the schema generator to output the SQL for a single column

Modified: Jifty-DBI/trunk/MANIFEST
==============================================================================
--- Jifty-DBI/trunk/MANIFEST	(original)
+++ Jifty-DBI/trunk/MANIFEST	Sat Mar  3 11:41:08 2007
@@ -74,6 +74,8 @@
 t/12prefetch.t
 t/13collection.t
 t/14handle-pg.t
+t/15types.t
+t/16inheritance.t
 t/pod.t
 t/testmodels.pl
 t/utils.pl

Modified: Jifty-DBI/trunk/META.yml
==============================================================================
--- Jifty-DBI/trunk/META.yml	(original)
+++ Jifty-DBI/trunk/META.yml	Sat Mar  3 11:41:08 2007
@@ -29,6 +29,7 @@
   Encode: 2.1
   Exporter::Lite: 0
   Lingua::EN::Inflect: 0
+  Object::Declare: 0.22
   UNIVERSAL::require: 0
   perl: 5.8.3
-version: 0.32
+version: 0.39_9999

Modified: Jifty-DBI/trunk/Makefile.PL
==============================================================================
--- Jifty-DBI/trunk/Makefile.PL	(original)
+++ Jifty-DBI/trunk/Makefile.PL	Sat Mar  3 11:41:08 2007
@@ -17,8 +17,10 @@
 requires('Encode'  => 2.10);
 requires('Exporter::Lite');
 requires('Lingua::EN::Inflect');
+requires('Object::Declare' => 0.22);
 requires('UNIVERSAL::require');
 requires('version');
+#requires('Class::Trigger');
 build_requires('Test::More' => 0.52);
 build_requires('DBD::SQLite');
 no_index directory => 'ex';

Modified: Jifty-DBI/trunk/SIGNATURE
==============================================================================
--- Jifty-DBI/trunk/SIGNATURE	(original)
+++ Jifty-DBI/trunk/SIGNATURE	Sat Mar  3 11:41:08 2007
@@ -14,10 +14,10 @@
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
-SHA1 691871afc059ed0de2321403a2caffa4e51edafd Changes
+SHA1 6cdd320e5387932cd7b6305d5b5068ac31cef0cb Changes
 SHA1 3bf592c9da2a5718e9be45c822f200bea821746b MANIFEST
-SHA1 9552c4f2bb3380b27b092c527a7bce6dc22288e8 META.yml
-SHA1 38715641f85f55e5597415ab4d53e6c28ef8193f Makefile.PL
+SHA1 59ce3857a0aa37277227ea09964d213bbb3bfd29 META.yml
+SHA1 45d5f1856267d73c7a4a21f8f584b15cfd1bae9b Makefile.PL
 SHA1 d0943ab047f543c92405564ab77ba008052544e6 README
 SHA1 82d6ac3f6def48558d09f8b6e3b53ed4194d8c81 ROADMAP
 SHA1 9d304f35438f847863969f6a069598379f5a9db2 debian/README
@@ -29,22 +29,22 @@
 SHA1 584c0f6cdebcbf760dfca8413c94783586120214 ex/Example/Model/Address.pm
 SHA1 7cea1a5289f79c2a87837924a83feb583f6e8890 ex/Example/Model/Employee.pm
 SHA1 a9d62e4f5b43b2f78066172a4771238ee7df6339 ex/create_tables.pl
-SHA1 0bb5ddbe64424d40536acdee2f09e853ab39087d inc/Module/AutoInstall.pm
-SHA1 e7688055bf405375921ea837273d8bdc68803efb inc/Module/Install.pm
-SHA1 4fad9a959426996f62d0e4e972cf09e3a0cf8c0c inc/Module/Install/AutoInstall.pm
-SHA1 e5b3215acb96829f2142dcfce736c1b6484fbc08 inc/Module/Install/Base.pm
-SHA1 07c44e137098675ea35a5d537df1e4af098382d9 inc/Module/Install/Can.pm
-SHA1 8f691f8e451ba687551fa836e8d75c4d514241e5 inc/Module/Install/Fetch.pm
-SHA1 0db6efc5925b96e1ea3b8bc46c3ecdb14660ae82 inc/Module/Install/Include.pm
-SHA1 81b798c6ca71d1b665a470fb49d32105084ac389 inc/Module/Install/Makefile.pm
-SHA1 c8c9737da19baa15ffa7d9d5037913f64b592189 inc/Module/Install/Metadata.pm
-SHA1 b97304e2a5c405d950eeaa4afd09c6b5507571c3 inc/Module/Install/Win32.pm
-SHA1 73a588d58f7ad0a6a9ed0ea80c48fa12f234a02c inc/Module/Install/WriteAll.pm
-SHA1 69d5c825abea1a2b8f7f3e60d0eb1b75fcdd8a9f lib/Jifty/DBI.pm
-SHA1 8c257d0dfcd1f5e033a96cc51413150a72456b91 lib/Jifty/DBI/Collection.pm
+SHA1 603bb9de29fb8cba7f13409c546750972eff645d inc/Module/AutoInstall.pm
+SHA1 9b2f9d83bcf77860f53a0c07c90a4a59ad9f5df1 inc/Module/Install.pm
+SHA1 ad955f51ad2c40d4ba35395c27f5ed899a80bf7a inc/Module/Install/AutoInstall.pm
+SHA1 abe32855d75ab13747cf65765af9947b7a8c3057 inc/Module/Install/Base.pm
+SHA1 95b81d1e91bd634467bf633571eff4420e9c04eb inc/Module/Install/Can.pm
+SHA1 1fe98c63cf9d7271c8cb4183ba230f152df69e26 inc/Module/Install/Fetch.pm
+SHA1 0606a8b02a420600bc3e2b65ab82f70266784926 inc/Module/Install/Include.pm
+SHA1 aa4a3d87cedc972e3dc0d5d156809624e6db9416 inc/Module/Install/Makefile.pm
+SHA1 f1d4e1bbcb40bb269f36e6dc011b3ca25d3829b7 inc/Module/Install/Metadata.pm
+SHA1 0c2118868ef82ac517eb6d9c3bd93e6eb9bbf83e inc/Module/Install/Win32.pm
+SHA1 e827d6d43771032fa3df35c0ad5e5698d0e54cda inc/Module/Install/WriteAll.pm
+SHA1 83f0a75d698ab7ab174f42bb19e346b23fb4ba5e lib/Jifty/DBI.pm
+SHA1 b9ad69976fe3438c0528057fe972bb5741824af6 lib/Jifty/DBI/Collection.pm
 SHA1 ecfae7430da875a856113e0c233daa0e31073000 lib/Jifty/DBI/Collection/Union.pm
 SHA1 07115934091da72e0025c9c754714fc0ceedbef5 lib/Jifty/DBI/Collection/Unique.pm
-SHA1 1d4155a6de62daf7b1f962383ba46ee0ca80d472 lib/Jifty/DBI/Column.pm
+SHA1 ef9a50bac5f2dfa90936c5d155d1be82b7f4dced lib/Jifty/DBI/Column.pm
 SHA1 a2c16702f3467a220e9ba96ac5e086cc2e7779d1 lib/Jifty/DBI/Filter.pm
 SHA1 87192bf64a224cbea78770f4209ecae9981f3f5c lib/Jifty/DBI/Filter/Date.pm
 SHA1 e7d1ddfa3a55f69680d8637071b53d516ad0fc7d lib/Jifty/DBI/Filter/DateTime.pm
@@ -65,15 +65,15 @@
 SHA1 e6041a34c3044ed8b9691a5629ecf146fed95257 lib/Jifty/DBI/Handle/mysql.pm
 SHA1 f2cc4fcce79c9a88a023d4e6bd96c2089eef1ced lib/Jifty/DBI/Handle/mysqlPP.pm
 SHA1 0e975f9ec5480ca09025c592c06d484058e637df lib/Jifty/DBI/HasFilters.pm
-SHA1 9d7334483b81d1d1141dea136f80be1b873d4fbe lib/Jifty/DBI/Record.pm
+SHA1 da3d76a58bdb72d26fff9717b4e29a3e058d4641 lib/Jifty/DBI/Record.pm
 SHA1 eb7085a11cc38f6a1e4b0256b43e590730666b29 lib/Jifty/DBI/Record/Cachable.pm
 SHA1 91bf502236779f5e3aa04f6c7cabdcffc413ab81 lib/Jifty/DBI/Record/Memcached.pm
-SHA1 16f7dd62bb43ba4a04474bc925ef029a55b69c63 lib/Jifty/DBI/Schema.pm
-SHA1 48e330236bad9a33e1b054570584b8deaa43e4c1 lib/Jifty/DBI/SchemaGenerator.pm
+SHA1 6bdf9f32e1555c08d47e06782428b151b37b28ad lib/Jifty/DBI/Schema.pm
+SHA1 3a967c8385ad5e8ecb76b0c6374cfa2a092dffe3 lib/Jifty/DBI/SchemaGenerator.pm
 SHA1 32834b7c4cf5a8d131382fccc8db341be8768291 t/00.load.t
 SHA1 9aa7fed2b2409faa4c71d2a45db210721f47403e t/01-version_checks.t
 SHA1 13c9fe3eeec0d000a7c86ea2474e30186cbc37e2 t/01basics.t
-SHA1 a9e9d590df1042ed21f8ab18fe720f1ef3d4f9cd t/01records.t
+SHA1 5acefb1e751c4a21e38ceb9fa37063c07d2d37dc t/01records.t
 SHA1 b1d9bb663d106e6874c0c454d64819e6b67d56d2 t/01searches.t
 SHA1 933ebc7f0cfcaf03a2092a7c8271f98b2385f785 t/02-column_constraints.t
 SHA1 70fbf72948bdd7cabcfcf128d8f51365abb33e9c t/02records_cachable.t
@@ -85,8 +85,8 @@
 SHA1 f0f6ce9d48f419de6ac6154684f9065f32e30ddd t/06filter_truncate.t
 SHA1 2e9777a47e3a920d063bfbf9d56375c67c5b89c5 t/06filter_utf8.t
 SHA1 824e48c66d2e18120b377934177745680785525b t/10schema.t
-SHA1 44291153e6f73ecd6d3f465c06bd0477943ae025 t/11schema_records.t
-SHA1 c071b919b08fd107eb86eecc511f61d7c9cbb61a t/12prefetch.t
+SHA1 423461800861653032758627a82465426968da8e t/11schema_records.t
+SHA1 7356c3470a6b493e061df45bd75dd23bf574dd5a t/12prefetch.t
 SHA1 a93e0ee622b2291f797887f663f33c30fc7339f6 t/13collection.t
 SHA1 f057b643275b0370ae18d47b3a1b394791c850d6 t/14handle-pg.t
 SHA1 e9c6a5881fc60173fbc8d479c1afd2ce3b43bef1 t/pod.t
@@ -95,7 +95,7 @@
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.3 (GNU/Linux)
 
-iD8DBQFFvKUPEi9d9xCOQEYRAh+VAJ9k3HuIBC1f5B1RCEpeoHqXvnOZLwCbB4d+
-3y5B6i/kNM+jYHX5KbU6TlU=
-=xCos
+iD8DBQFFugMLtLPdNzw1AaARAke3AKCaJeRcBcCuOf5DEFLK+q9JgVaa7gCdFeH5
+zofu7nWSY/r9+A4aXHcIhfQ=
+=3gHU
 -----END PGP SIGNATURE-----

Modified: Jifty-DBI/trunk/lib/Jifty/DBI.pm
==============================================================================
--- Jifty-DBI/trunk/lib/Jifty/DBI.pm	(original)
+++ Jifty-DBI/trunk/lib/Jifty/DBI.pm	Sat Mar  3 11:41:08 2007
@@ -2,7 +2,7 @@
 use warnings;
 use strict;
 
-$Jifty::DBI::VERSION = '0.34';
+$Jifty::DBI::VERSION = '0.39_9999';
 
 =head1 NAME
 

Added: Jifty-DBI/trunk/lib/Jifty/DBI/Class/Trigger.pm
==============================================================================
--- (empty file)
+++ Jifty-DBI/trunk/lib/Jifty/DBI/Class/Trigger.pm	Sat Mar  3 11:41:08 2007
@@ -0,0 +1,365 @@
+package Jifty::DBI::Class::Trigger;
+
+use strict;
+use vars qw($VERSION);
+$VERSION = "0.11_01";
+
+use Carp ();
+
+my (%Triggers, %TriggerPoints);
+
+sub import {
+    my $class = shift;
+    my $pkg = caller(0);
+
+    $TriggerPoints{$pkg} = { map { $_ => 1 } @_ } if @_;
+
+    # export mixin methods
+    no strict 'refs';
+    my @methods = qw(add_trigger call_trigger last_trigger_results);
+    *{"$pkg\::$_"} = \&{$_} for @methods;
+}
+
+sub add_trigger {
+    my $proto = shift;
+
+    my $triggers = __fetch_triggers($proto);
+
+    if (ref($_[1]) eq 'CODE') { 
+
+    while (my($when, $code) = splice @_, 0, 2) {
+        __validate_triggerpoint($proto, $when);
+        Carp::croak('add_trigger() needs coderef') unless ref($code) eq 'CODE';
+        push @{$triggers->{$when}}, [$code, undef];
+    }
+    }
+    elsif (grep {'name'} @_) {
+        my %args = ( name => undef, callback => undef, abortable => undef, @_);
+        my $when= $args{'name'};
+        my $code = $args{'callback'};
+        my $abortable = $args{'abortable'};
+        __validate_triggerpoint($proto, $when);
+        Carp::croak('add_trigger() needs coderef') unless ref($code) eq 'CODE';
+        push @{$triggers->{$when}}, [$code, $abortable];
+
+
+    } else {
+        Carp::croak('add_trigger() needs coderef');
+
+    }
+    1;
+}
+
+
+sub last_trigger_results {
+    my $self = shift;
+    my $result_store = ref($self) ? $self : ${Jifty::DBI::Class::Trigger::_trigger_results}->{$self};
+    return $result_store->{'_class_trigger_results'};
+}
+
+sub call_trigger {
+    my $self = shift;
+    my $when = shift;
+
+    my @return;
+
+    my $result_store = ref($self) ? $self : ${Jifty::DBI::Class::Trigger::_trigger_results}->{$self};
+
+    $result_store->{'_class_trigger_results'} = [];
+
+    if (my @triggers = __fetch_all_triggers($self, $when)) { # any triggers?
+        for (@triggers) {
+              my @return = $_->[0]->($self, @_);
+                push @{$result_store->{'_class_trigger_results'}}, \@return;
+                return undef if ($_->[1] and not $return[0]); # only abort on false values.
+         
+    }
+    }
+    else {
+        # if validation is enabled we can only add valid trigger points
+        # so we only need to check in call_trigger() if there's no
+        # trigger with the requested name.
+        __validate_triggerpoint($self, $when);
+    }
+
+    return scalar @{$result_store->{'_class_trigger_results'}};
+}
+
+sub __fetch_all_triggers {
+    my ($obj, $when, $list, $order) = @_;
+    my $class = ref $obj || $obj;
+    my $return;
+    unless ($list) {
+        # Absence of the $list parameter conditions the creation of
+        # the unrolled list of triggers. These keep track of the unique
+        # set of triggers being collected for each class and the order
+        # in which to return them (based on hierarchy; base class
+        # triggers are returned ahead of descendant class triggers).
+        $list = {};
+        $order = [];
+        $return = 1;
+    }
+    no strict 'refs';
+    my @classes = @{$class . '::ISA'};
+    push @classes, $class;
+    foreach my $c (@classes) {
+        next if $list->{$c};
+        if (UNIVERSAL::can($c, 'call_trigger')) {
+            $list->{$c} = [];
+            __fetch_all_triggers($c, $when, $list, $order)
+                unless $c eq $class;
+            if (defined $when && $Triggers{$c}{$when}) {
+                push @$order, $c;
+                $list->{$c} = $Triggers{$c}{$when};
+            }
+        }
+    }
+    if ($return) {
+        my @triggers;
+        foreach my $class (@$order) {
+            push @triggers, @{ $list->{$class} };
+        }
+        if (ref $obj && defined $when) {
+            my $obj_triggers = $obj->{__triggers}{$when};
+            push @triggers, @$obj_triggers if $obj_triggers;
+        }
+        return @triggers;
+    }
+}
+
+sub __validate_triggerpoint {
+    return unless my $points = $TriggerPoints{ref $_[0] || $_[0]};
+    my ($self, $when) = @_;
+    Carp::croak("$when is not valid triggerpoint for ".(ref($self) ? ref($self) : $self))
+        unless $points->{$when};
+}
+
+sub __fetch_triggers {
+    my ($obj, $proto) = @_;
+    # check object based triggers first
+    return ref $obj ? $obj->{__triggers} ||= {} : $Triggers{$obj} ||= {};
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Jifty::DBI::Class::Trigger - Mixin to add / call inheritable triggers
+
+=head1 WARNING
+
+This Module is a TEMPORARY FORK of Class::Trigger. It will be replaced
+upon the release of new features in Class::Trigger that we depend on.
+
+ALL BUGS IN THIS MODULE ARE THE FAULT OF Jifty's DEVELOPERS AND NOT
+Class::Trigger's DEVELOPERS. UNDER NO CIRCUMSTANCES SHOULD BUGS
+BE REPORTED TO CLASS::TRIGGER'S DEVELOPERS.  
+
+=head1 SYNOPSIS
+
+  package Foo;
+  use Jifty::DBI::Class::Trigger;
+
+  sub foo {
+      my $self = shift;
+      $self->call_trigger('before_foo');
+      # some code ...
+      $self->call_trigger('middle_of_foo');
+      # some code ...
+      $self->call_trigger('after_foo');
+  }
+
+  package main;
+  Foo->add_trigger(before_foo => \&sub1);
+  Foo->add_trigger(after_foo => \&sub2);
+
+  my $foo = Foo->new;
+  $foo->foo;            # then sub1, sub2 called
+
+  # triggers are inheritable
+  package Bar;
+  use base qw(Foo);
+
+  Bar->add_trigger(before_foo => \&sub);
+
+  # triggers can be object based
+  $foo->add_trigger(after_foo => \&sub3);
+  $foo->foo;            # sub3 would appply only to this object
+
+=head1 DESCRIPTION
+
+Jifty::DBI::Class::Trigger is a mixin class to add / call triggers (or hooks)
+that get called at some points you specify.
+
+=head1 METHODS
+
+By using this module, your class is capable of following methods.
+
+=over 4
+
+=item add_trigger
+
+  Foo->add_trigger($triggerpoint => $sub);
+  $foo->add_trigger($triggerpoint => $sub);
+
+
+  Foo->add_trigger( name => $triggerpoint,
+                    callback => sub {return undef},
+                    abortable => 1); 
+
+  # no further triggers will be called. Undef will be returned.
+
+
+Adds triggers for trigger point. You can have any number of triggers
+for each point. Each coderef will be passed a reference to the calling object, 
+as well as arguments passed in via L<call_trigger>. Return values will be
+captured in I<list context>.
+
+If add_trigger is called with named parameters and the C<abortable>
+parameter is passed a true value, a false return value from trigger
+code will stop processing of this trigger point and return a C<false>
+value to the calling code.
+
+If C<add_trigger> is called without the C<abortable> flag, return
+values will be captured by call_trigger, but failures will be ignored.
+
+If C<add_trigger> is called as object method, whole current trigger
+table will be copied onto the object and the new trigger added to
+that. (The object must be implemented as hash.)
+
+  my $foo = Foo->new;
+
+  # this trigger ($sub_foo) would apply only to $foo object
+  $foo->add_trigger($triggerpoint => $sub_foo);
+  $foo->foo;
+
+  # And not to another $bar object
+  my $bar = Foo->new;
+  $bar->foo;
+
+=item call_trigger
+
+  $foo->call_trigger($triggerpoint, @args);
+
+Calls triggers for trigger point, which were added via C<add_trigger>
+method. Each triggers will be passed a copy of the object as the first argument.
+Remaining arguments passed to C<call_trigger> will be passed on to each trigger.
+Triggers are invoked in the same order they were defined.
+
+If there are no C<abortable> triggers or no C<abortable> trigger point returns 
+a false value, C<call_trigger> will return the number of triggers processed.
+
+
+If an C<abortable> trigger returns a false value, call trigger will stop execution
+of the trigger point and return undef.
+
+=item last_trigger_results
+
+    my @results = @{ $foo->last_trigger_results };
+
+Returns a reference to an array of the return values of all triggers called
+for the last trigger point. Results are ordered in the same order the triggers
+were run.
+
+
+=back
+
+=head1 TRIGGER POINTS
+
+By default you can make any number of trigger points, but if you want
+to declare names of trigger points explicitly, you can do it via
+C<import>.
+
+  package Foo;
+  use Jifty::DBI::Class::Trigger qw(foo bar baz);
+
+  package main;
+  Foo->add_trigger(foo  => \&sub1); # okay
+  Foo->add_trigger(hoge => \&sub2); # exception
+
+=head1 FAQ
+
+B<Acknowledgement:> Thanks to everyone at POOP mailing-list
+(http://poop.sourceforge.net/).
+
+=over 4
+
+=item Q.
+
+This module lets me add subs to be run before/after a specific
+subroutine is run.  Yes?
+
+=item A.
+
+You put various call_trigger() method in your class.  Then your class
+users can call add_trigger() method to add subs to be run in points
+just you specify (exactly where you put call_trigger()).
+
+=item Q.
+
+Are you aware of the perl-aspects project and the Aspect module?  Very
+similar to Jifty::DBI::Class::Trigger by the look of it, but its not nearly as
+explicit.  Its not necessary for foo() to actually say "triggers go
+*here*", you just add them.
+
+=item A.
+
+Yep ;)
+
+But the difference with Aspect would be that Jifty::DBI::Class::Trigger is so
+simple that it's easy to learn, and doesn't require 5.6 or over.
+
+=item Q.
+
+How does this compare to Sub::Versive, or Hook::LexWrap?
+
+=item A.
+
+Very similar. But the difference with Jifty::DBI::Class::Trigger would be the
+explicitness of trigger points.
+
+In addition, you can put hooks in any point, rather than pre or post
+of a method.
+
+=item Q.
+
+It looks interesting, but I just can't think of a practical example of
+its use...
+
+=item A.
+
+(by Tony Bowden)
+
+I originally added code like this to Class::DBI to cope with one
+particular case: auto-upkeep of full-text search indices.
+
+So I added functionality in Class::DBI to be able to trigger an
+arbitary subroutine every time something happened - then it was a
+simple matter of setting up triggers on INSERT and UPDATE to reindex
+that row, and on DELETE to remove that index row.
+
+See L<Class::DBI::mysql::FullTextSearch> and its source code to see it
+in action.
+
+=back
+
+=head1 AUTHOR
+
+IMPORTANT: DO NOT REPORT BUGS TO THE AUTHORS MENTIONED BELOW. PLEASE 
+REPORT THEM TO JIFTY-DEVEL at LISTS.BESTPRACTICAL.COM. PLEASE SEE THE WARNING
+ABOVE
+
+Original idea by Tony Bowden E<lt>tony at kasei.comE<gt> in Class::DBI.
+
+Code by Tatsuhiko Miyagawa E<lt>miyagawa at bulknews.netE<gt>.
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Class::DBI>
+
+=cut
+

Modified: Jifty-DBI/trunk/lib/Jifty/DBI/Collection.pm
==============================================================================
--- Jifty-DBI/trunk/lib/Jifty/DBI/Collection.pm	(original)
+++ Jifty-DBI/trunk/lib/Jifty/DBI/Collection.pm	Sat Mar  3 11:41:08 2007
@@ -1754,17 +1754,6 @@
     return $self->{table};
 }
 
-=head2 refers_to
-
-Private convenience method needed for the declarative schema generation.
-
-=cut
-
-sub refers_to {
-    my $class = shift;
-    return ( Jifty::DBI::Schema::Trait->new( refers_to => $class ), @_ );
-}
-
 =head2 clone
 
 Returns copy of the current object with all search restrictions.

Modified: Jifty-DBI/trunk/lib/Jifty/DBI/Column.pm
==============================================================================
--- Jifty-DBI/trunk/lib/Jifty/DBI/Column.pm	(original)
+++ Jifty-DBI/trunk/lib/Jifty/DBI/Column.pm	Sat Mar  3 11:41:08 2007
@@ -77,17 +77,8 @@
 *read  = \&readable;
 *write = \&writable;
 
-sub length {
-    Carp::carp('$column->length is deprecated; use $column->max_length instead');
-    my $self = shift;
-    $self->max_length(@_);
-}
-
-sub until {
-    Carp::carp('$column->until is deprecated; use $column->till instead');
-    my $self = shift;
-    $self->till(@_);
-}
+sub length { Carp::croak('$column->length is no longer supported; use $column->max_length instead') }
+sub until { Carp::croak('$column->until is no longer supported; use $column->till instead') }
 
 =head2 active
 

Modified: Jifty-DBI/trunk/lib/Jifty/DBI/Record.pm
==============================================================================
--- Jifty-DBI/trunk/lib/Jifty/DBI/Record.pm	(original)
+++ Jifty-DBI/trunk/lib/Jifty/DBI/Record.pm	Sat Mar  3 11:41:08 2007
@@ -7,6 +7,8 @@
 use Lingua::EN::Inflect ();
 use Jifty::DBI::Column  ();
 use UNIVERSAL::require  ();
+use Jifty::DBI::Class::Trigger; # exports by default
+
 
 use base qw/
     Class::Data::Inheritable
@@ -142,7 +144,6 @@
     my $self        = shift;
     my $column_name = shift;
     my $attribute   = lc( shift || '' );
-
     my $col = $self->column($column_name);
     return undef unless ( $col and $col->can($attribute) );
     return $col->$attribute();
@@ -188,6 +189,7 @@
         $column->readable(1);
         $column->type('serial');
         $column->mandatory(1);
+
         $self->_init_methods_for_column($column);
     }
 
@@ -444,8 +446,7 @@
 sub column {
     my $self = shift;
     my $name = lc( shift || '' );
-    my $col = $self->COLUMNS;
-
+    my $col = $self->_columns_hashref;
     return undef unless $col && exists $col->{$name};
     return $col->{$name};
 
@@ -467,7 +468,7 @@
                 <=> ( ( $a->type || '' ) eq 'serial' ) )
                 or ( ($a->sort_order || 0) <=> ($b->sort_order || 0))
                 or ( $a->name cmp $b->name )
-            } grep { $_->active } values %{ $self->COLUMNS || {} }
+            } grep { $_->active } values %{ $self->_columns_hashref }
 	])}
 }
 
@@ -489,9 +490,16 @@
                 <=> ( ( $a->type || '' ) eq 'serial' ) )
                 or ( ($a->sort_order || 0) <=> ($b->sort_order || 0))
                 or ( $a->name cmp $b->name )
-            } values %{ $self->COLUMNS || {} }
+            } values %{ $self->_columns_hashref || {} }
+}
+
+sub _columns_hashref {
+    my $self = shift;
+
+      return ($self->COLUMNS||{});
 }
 
+
 # sub {{{ readable_attributes
 
 =head2 readable_attributes
@@ -602,8 +610,8 @@
     my $column = shift;
 
     my $value = $self->__value( $column => @_ );
-    my $method = $self->can("after_$column");
-    $method->( $self, \$value ) if $method;
+    $self->_run_callback( name => "after_".$column,
+                          args => \$value);
     return $value;
 }
 
@@ -690,23 +698,18 @@
         @_
     );
 
-    my $method = "before_set_" . $args{column};
-    if ( $self->can($method) ) {
-        my $before_set_ret = $self->$method( \%args );
-        return $before_set_ret
-            unless ($before_set_ret);
-    }
 
-    my $ok = $self->__set(%args);
+    my $ok = $self->_run_callback( name => "before_set_" . $args{column},
+                           args => \%args);
+    return $ok if( not defined $ok);
 
-    return $ok unless $ok;
+    $ok = $self->__set(%args);
+    return $ok if not $ok;
 
-    $method = "after_set_" . $args{column};
-    if( $self->can($method) ) {
         # Fetch the value back to make sure we have the actual value
         my $value = $self->_value($args{column});
-        $self->$method({column => $args{column}, value => $value});
-    }
+        my $after_set_ret = $self->_run_callback( name => "after_set_" . $args{column}, args => 
+        {column => $args{column}, value => $value});
 
     return $ok;
 }
@@ -1042,14 +1045,15 @@
 
 
 
-    if ( $self->can('before_create') ) {
-        my $before_ret = $self->before_create( \%attribs );
-        return ($before_ret) unless ($before_ret);
-    }
+    my $ok = $self->_run_callback( name => "before_create", args => \%attribs);
+    return $ok if ( not defined $ok);
 
     my $ret = $self->__create(%attribs);
 
-    $self->after_create( \$ret ) if $self->can('after_create');
+    $ok = $self->_run_callback( name => "after_create",
+                           args => \$ret);
+    return $ok if (not defined $ok);
+    
     if ($class) {
         $self->load_by_cols(id => $ret);
         return ($self);
@@ -1143,12 +1147,13 @@
 
 sub delete {
     my $self = shift;
-    if ( $self->can('before_delete') ) {
-        my $before_ret = $self->before_delete();
-        return $before_ret unless ($before_ret);
-    }
+    my $before_ret = $self->_run_callback( name => 'before_delete' );
+    return $before_ret unless (defined $before_ret);
     my $ret = $self->__delete;
-    $self->after_delete( \$ret ) if $self->can('after_delete');
+
+    my $after_ret
+        = $self->_run_callback( name => 'after_delete', args => \$ret );
+    return $after_ret unless (defined $after_ret);
     return ($ret);
 
 }
@@ -1250,11 +1255,6 @@
 
 =cut
 
-sub refers_to {
-    my $class = shift;
-    return ( Jifty::DBI::Schema::Trait->new(refers_to => $class), @_ );
-}
-
 sub _filters {
     my $self = shift;
     my %args = ( direction => 'input', column => undef, @_ );
@@ -1341,6 +1341,90 @@
     }
 }
 
+
+=head2 run_canonicalization_for_column
+
+=cut
+
+sub run_canonicalization_for_column {
+    my $self = shift;
+    my %args = ( column => undef,
+                 value => undef,
+                 @_);
+
+    my ($ret,$value_ref) = $self->_run_callback ( name => "canonicalize_".$args{'column'}, args => $args{'value'});
+    return unless defined $ret;
+    return ( exists $value_ref->[-1]->[0] ? $value_ref->[-1]->[0] : $args{'value'});
+}
+
+sub has_canonicalizer_for_column {
+    my $self = shift;
+    my $key = shift;
+        my $method = "canonicalize_$key";
+     if( $self->can($method) ) {
+         return 1;
+     } else {
+         return undef;
+     }
+}
+
+
+=head2 run_canonicalization_for_column
+
+=cut
+
+sub run_validation_for_column {
+    my $self = shift;
+    my %args = (
+        column => undef,
+        value  => undef,
+        @_
+    );
+    my $key    = $args{'column'};
+    my $attr   = $args{'value'};
+
+
+    my ($ret, $results)  = $self->_run_callback( name => "validate_".$key, args => $attr );
+
+    if (defined $ret) {
+        return ( 1, 'Validation ok' );
+    }
+    else {
+        return @{$results->[-1]};
+    }
+    
+}
+
+sub has_validator_for_column {
+    my $self = shift;
+    my $key  = shift;
+    if ( $self->can( "validate_" . $key ) ) {
+        return 1;
+    } else {
+        return undef;
+    }
+}
+
+
+sub _run_callback {
+    my $self = shift;
+    my %args = (
+        name => undef,
+        args => undef,
+        @_
+    );
+
+    my $ret;
+    my $method = $args{'name'};
+    my @results;
+    if ( my $func = $self->can($method) ) {
+   @results =  $func->($self, $args{args} );
+        return(wantarray  ?  (undef, [@results]) : undef) unless $results[0];
+    }
+    $ret =  $self->call_trigger( $args{'name'} => $args{args} );
+    return (wantarray ? ($ret, [[@results],@{$self->last_trigger_results}]) : $ret);
+}
+
 1;
 
 __END__

Added: Jifty-DBI/trunk/lib/Jifty/DBI/Record/Plugin.pm
==============================================================================
--- (empty file)
+++ Jifty-DBI/trunk/lib/Jifty/DBI/Record/Plugin.pm	Sat Mar  3 11:41:08 2007
@@ -0,0 +1,26 @@
+package Jifty::DBI::Record::Plugin;
+
+use warnings;
+use strict;
+
+
+use base qw/Exporter/;
+
+
+sub import {
+    my $self = shift;
+    my $caller = caller;
+    for ($self->columns) {
+            $caller->COLUMNS->{$_->name} = $_ ;
+            $caller->_init_methods_for_column($_);
+    }
+    $self->export_to_level(1,undef);
+    
+    if (my $triggers =  $self->can('register_triggers') ) {
+        $triggers->($caller)
+    }
+}
+
+
+
+1;

Modified: Jifty-DBI/trunk/lib/Jifty/DBI/Schema.pm
==============================================================================
--- Jifty-DBI/trunk/lib/Jifty/DBI/Schema.pm	(original)
+++ Jifty-DBI/trunk/lib/Jifty/DBI/Schema.pm	Sat Mar  3 11:41:08 2007
@@ -41,13 +41,128 @@
 =cut
 
 use Carp qw/croak carp/;
-use Exporter::Lite;
-our @EXPORT
-    = qw(column type default literal validator autocompleted immutable unreadable max_length length distinct mandatory not_null sort_order valid_values label hints render_as render since till input_filters output_filters filters virtual is as by are on schema indexed valid order);
+use Scalar::Defer;
+use base qw(Class::Data::Inheritable);
+__PACKAGE__->mk_classdata('TYPES' => {});
+
+use Object::Declare (
+    mapping => {
+        column => sub { Jifty::DBI::Column->new({@_}) } ,
+    },
+    aliases => {
+        default_value => 'default',
+        available   => 'available_values',
+        valid       => 'valid_values',
+        render      => 'render_as',
+        order       => 'sort_order',
+        filters     => 'input_filters',
+    },
+    copula  => {
+        is          => sub { return @_ if $#_;
+                             my $typehandler = __PACKAGE__->TYPES->{$_[0]};
+                             # XXX: when we have a type name
+                             # convention, give a warning when it
+                             # looks like a type name but not found
+                             return ($_[0] => 1) unless $typehandler;
+                             return $typehandler->();
+			 },
+        are         => '',
+        as          => '',
+        ajax        => 'ajax_',
+        refers_to   => sub { refers_to => @_ },
+        references  => sub { refers_to => @_ },
+    },
+);
+use Class::Data::Inheritable;
+use UNIVERSAL::require ();
+
+our @EXPORT = qw( defer lazy column schema by render_as since till literal);
+
+sub by ($) { @_ }
+sub render_as ($) { render as @_ }
+sub since ($) { since is @_ }
+sub till ($) { till is @_ }
+
+sub literal($) {
+    my $value = shift;
+    return \$value;
+}
 
 our $SCHEMA;
 our $SORT_ORDERS = {};
 
+use Exporter::Lite ();
+# TODO - This "sub import" is strictly here to catch the deprecated "length is 40".
+#        Once the deprecation cycle is over we should take this away and rever to
+#        "use Exporter::Lite" in the line above.
+my $old_sig_die;
+
+sub import {
+    no warnings qw( uninitialized numeric );
+    $old_sig_die ||= $SIG{__DIE__};
+    $SIG{__DIE__} = \&filter_die unless $SIG{__DIE__} and $SIG{__DIE__} == \&filter_die;
+    goto &Exporter::Lite::import;
+}
+
+sub filter_die {
+    # Calling it by hand means we restore the old sighandler.
+    $SIG{__DIE__} = $old_sig_die;
+    if ($_[0] =~ /near "is (\d+)"/) {
+        carp @_, << ".";
+
+*********************************************************
+
+ Due to an incompatible API change, the "length" field in
+ Jifty::DBI columns has been renamed to "max_length":
+ 
+     column foo =>
+         length is $1;       # NOT VALID 
+
+ Please write this instead:
+ 
+     column foo =>
+         max_length is $1    # VALID
+
+ Sorry for the inconvenience.
+
+**********************************************************
+
+
+.
+        exit 1;
+    }
+    elsif ($_[0] =~ /Undefined subroutine &Jifty::DBI::Schema::column|Can't locate object method "type" via package "(?:is|are)"/) {
+        my $from = (caller)[0];
+        $from =~ s/::Schema$//;
+        my $base = $INC{'Jifty/Record.pm'} ? "Jifty::Record" : "Jifty::DBI::Record";
+
+        no strict 'refs';
+        carp @_, << ".";
+*********************************************************
+
+ Calling 'column' within a schema class is an error:
+ 
+    package $from\::Schema;
+    column foo => ...;        # NOT VALID
+
+ Please write this instead:
+
+    package $from;
+    use Jifty::DBI::Schema;
+    use @{[(${"$from\::ISA"} || [$base])->[0] || $base]} schema {
+        column foo => ...;    # VALID
+    };
+
+ Sorry for the inconvenience.
+
+*********************************************************
+.
+    }
+
+    die @_;
+}
+
+
 =head1 FUNCTIONS
 
 All these functions are exported.  However, if you use the C<schema> helper function,
@@ -68,38 +183,79 @@
 
 sub schema (&) {
     my $code = shift;
-
-    my $from = (caller)[0];
+    my $from = caller;
 
     my $new_code = sub {
-        $code->();
-
-        # Unimport all our symbols from the calling package.
-        foreach my $sym (@EXPORT) {
-            no strict 'refs';
-            undef *{"$from\::$sym"}
-                if \&{"$from\::$sym"} == \&$sym;
-        }
+	no warnings 'redefine';
+	local *_ = sub { my $args = \@_; defer { _(@$args) } };
+	$from->_init_columns;
+
+	my @columns = &declare($code);
+
+	# Unimport all our symbols from the calling package.
+	foreach my $sym (@EXPORT) {
+	    no strict 'refs';
+	    undef *{"$from\::$sym"}
+		if \&{"$from\::$sym"} == \&$sym;
+	}
+
+	foreach my $column (@columns) {
+	    next if !ref($column);
+	    _init_column($column);
+	}
 
         $from->_init_methods_for_columns;
     };
 
-    return('-base' => $new_code);
+    return ('-base' => $new_code);
 }
 
-=head2 column
+use Hash::Merge ();
+
+no warnings 'uninitialized';
+use constant MERGE_PARAM_BEHAVIOUR => {
+    SCALAR => {
+            SCALAR => sub { CORE::length($_[1]) ? $_[1] : $_[0] },
+            ARRAY  => sub { [ @{$_[1]} ] },
+            HASH   => sub { $_[1] } },
+    ARRAY => {
+            SCALAR => sub { CORE::length($_[1]) ? $_[1] : $_[0] },
+            ARRAY  => sub { [ @{$_[1]} ] },
+            HASH   => sub { $_[1] } },
+    HASH => {
+            SCALAR => sub { CORE::length($_[1]) ? $_[1] : $_[0] },
+            ARRAY  => sub { [ @{$_[1]} ] },
+            HASH   => sub { Hash::Merge::_merge_hashes( $_[0], $_[1] ) } }
+};
+
+=head2 merge_params HASHREF HASHREF
+
+Takes two hashrefs. Merges them together and returns the merged hashref.
+
+    - Empty fields in subclasses don't override nonempty fields in superclass anymore.
+    - Arrays don't merge; e.g. if parent class's valid_values is [1,2,3,4], and
+      subclass's valid_values() is [1,2], they don't somehow become [1,2,3,4,1,2].
+
+BUG: This should either be a private routine or factored out into Jifty::Util
 
-Set forth the description of a column in the data store.
 
-Note: If the column uses 'refers_to' to reference another class then you 
-should not name the column ending in '_id' as it has special meaning.
 
 =cut
 
-sub column {
-    my $name = lc(shift);
+sub merge_params {
+    my $prev_behaviour = Hash::Merge::get_behavior();
+    Hash::Merge::specify_behavior( MERGE_PARAM_BEHAVIOUR, "merge_params" );
+    my $rv = Hash::Merge::merge(@_);
+    Hash::Merge::set_behavior( $prev_behaviour );
+    return $rv;
+}
+
 
-    my $from = (caller)[0];
+sub _init_column {
+    my $column = shift;
+    my $name   = $column->name;
+
+    my $from = (caller(2))[0];
     if ($from =~ s/::Schema$// && $from !~ /Script/) {
         no strict 'refs';
 
@@ -132,23 +288,23 @@
     croak "Illegal column definition for column $name in $from"
       if grep {not UNIVERSAL::isa($_, "Jifty::DBI::Schema::Trait")} @_;
 
-    $from->_init_columns;
-
+    $column->readable(!(delete $column->{unreadable}));
+    $column->writable(!(delete $column->{immutable}));
 
-    my @args = (
-        ! unreadable(),
-        ! immutable(),
-        ! virtual(),
-        type(''),
-        @_
-    );
+    # XXX: deprecated
+    $column->mandatory(1) if delete $column->{not_null};
 
-    my $column = Jifty::DBI::Column->new( { name => $name } );
     $column->sort_order($SORT_ORDERS->{$from}++);
 
-    $_->apply($column) for @args;
+    $column->input_filters($column->{input_filters} || []);
+    $column->output_filters($column->{output_filters} || []);
 
     if ( my $refclass = $column->refers_to ) {
+        if (ref($refclass) eq 'ARRAY') {
+            $column->by($refclass->[1]);
+            $column->refers_to($refclass = $refclass->[0]);
+        }
+
         $refclass->require();
         $column->type('integer') unless ( $column->type );
 
@@ -157,15 +313,14 @@
                 my $aliased_as = $1;
                 my $virtual_column = $from->add_column($aliased_as);
 
-                # XXX FIXME I think the next line is wrong, but things
-                # explode without it -- mostly because we unique-key
-                # on name instead of some conbination of name and
-                # alias_for_column in a couple places
-                $virtual_column->name( $name );
-                $virtual_column->aliased_as($aliased_as);
-                $_->apply($virtual_column) for @args;
+                # Clone ourselves into the virtual column
+                %$virtual_column = %$column;
+
                 $column->refers_to(undef);
+
+                $virtual_column->aliased_as($aliased_as);
                 $virtual_column->alias_for_column($name);
+
                 $from->_init_methods_for_column($virtual_column);
             }
             $column->by('id') unless $column->by;
@@ -188,19 +343,26 @@
     # through the &schema wrapper, so we defer initialization here
     # to not upset column names such as "label" and "type".
     # (We may not *have* a caller(1) if the user is executing a .pm file.)
-    my $caller1 = caller(1);
-    return if defined $caller1 && $caller1 eq __PACKAGE__;
+}
 
-    $from->_init_methods_for_column($column)
+sub register_types {
+    my $class = shift;
+    while (my ($type, $sub) = splice(@_, 0, 2)) {
+        $class->TYPES->{$type} = $sub;
+    }
 }
 
-=head2 refers_to
+1;
+
+__END__
+
+=head2 references
 
 Indicates that the column references an object or a collection of objects in another
 class.  You may refer to either a class that inherits from Jifty::Record by a primary
 key in that class or to a class that inherits from Jifty::Collection.
 
-Correct usage is C<refers_to Application::Model::OtherClass by 'column_name'>, where
+Correct usage is C<references Application::Model::OtherClass by 'column_name'>, where
 Application::Model::OtherClass is a valid Jifty model and C<'column_name'> is
 a column containing unique values in OtherClass.  You can omit C<by 'column_name'> and
 the column name 'id' will be used.
@@ -213,7 +375,11 @@
 
 For columns referring to Jifty::Records you can access the actual value of the column
 instead of the object reference by appending '_id' to the column name.  As a result,
-you may not end any column name which uses 'refers_to' using '_id'.
+you may not end any column name which uses 'references' using '_id'.
+
+=head2 refers_to
+
+Synonym for C<references>.
 
 =cut
 
@@ -230,59 +396,28 @@
 databases.  For example blobs have different names between
 mysql and postgres.
 
-=cut
-
-sub type {
-    _list( type => @_ );
-}
-
 =head2 default
 
 Give a default value for the column.  Correct usage is C<default is
 'foo'>.
 
-=cut
-
-sub default {
-    _list( default => @_ );
-}
-
 =head2 literal
 
 Used for default values, to connote that they should not be quoted
 before being supplied as the default value for the column.  Correct
 usage is C<default is literal 'now()'>.
 
-=cut
-
-sub literal($) {
-    my $value = shift;
-    return \$value;
-}
-
 =head2 validator
 
 Defines a subroutine which returns a true value only for valid values
 this column can have.  Correct usage is C<validator is \&foo>.
 
-=cut
-
-sub validator {
-    _list( validator => @_ );
-}
-
 =head2 immutable
 
 States that this column is not writable.  This is useful for
 properties that are set at creation time but not modifiable
 thereafter, like 'created by'.  Correct usage is C<is immutable>.
 
-=cut
-
-sub immutable {
-    _item( writable => 0, @_ );
-}
-
 =head2 unreadable
 
 States that this column is not directly readable by the application
@@ -290,93 +425,29 @@
 the like.  The data is still accessible via C<< $record->_value('') >>.
 Correct usage is C<is unreadable>.
 
-=cut
-
-sub unreadable {
-    _item( readable => 0, @_ );
-}
-
 =head2 max_length
 
-Sets a maximum length to store in the database; values longer than
+Sets a maximum max_length to store in the database; values longer than
 this are truncated before being inserted into the database, using
 L<Jifty::DBI::Filter::Truncate>.  Note that this is in B<bytes>, not
 B<characters>.  Correct usage is C<max_length is 42>.
 
-=cut
-
-sub max_length {
-    _list( max_length => @_ );
-}
-
-=head2 length
-
-DEPRECATED alias for C<max_length>.  Do not use; this will go away in the
-next version.
-
-=cut
-
-sub length {
-    no strict 'refs';
-    carp << "." unless caller()->{_seen_length_warning}++;
-
-*********************************************************
-
- Due to an incompatible API change, the "length" field in
- Jifty::DBI columns has been renamed to "max_length":
- 
-     column foo =>
-         length is $_[0];       # NOT VALID 
-
- Please write this instead:
- 
-     column foo =>
-         max_length is $_[0]    # VALID
-
- Sorry for the inconvenience.
-
-**********************************************************
-
-
-.
-    _list( max_length => @_ );
-}
-
 
 =head2 mandatory
 
 Mark as a required column.  May be used for generating user
 interfaces.  Correct usage is C<is mandatory>.
 
-=cut
-
-sub mandatory {
-    _item( mandatory => 1, @_ );
-}
-
 =head2 not_null
 
 Same as L</mandatory>.  This is deprecated.  Currect usage would be
 C<is not_null>.
 
-=cut
-
-sub not_null {
-    carp "'is not_null' is deprecated in favor of 'is mandatory'";
-    _item( mandatory => 1, @_ );
-}
-
 =head2 autocompleted
 
 Mark as an autocompleted column.  May be used for generating user
 interfaces.  Correct usage is C<is autocompleted>.
 
-=cut
-
-sub autocompleted {
-    _item( autocompleted => 1, @_ );
-}
-
 =head2 distinct
 
 Declares that a column should only have distinct values.  This
@@ -386,56 +457,26 @@
 columns implemented in L<DBIx::DBSchema> at this time.  
 Correct usage is C<is distinct>.
 
-=cut
-
-sub distinct {
-    _item( distinct => 1, @_ );
-}
-
 =head2 virtual
 
 Declares that a column is not backed by an actual column in the
 database, but is instead computed on-the-fly.
 
-=cut
-
-sub virtual {
-    _item( virtual => 1, @_ );
-}
-
-
 =head2 sort_order
 
 Declares an integer sort value for this column. By default, Jifty will sort
 columns in the order they are defined.
 
-=cut
-
-sub sort_order {
-    _item ( sort_order => (shift @_ || 0));
-}
-
 =head2 order
 
 Alias for C<sort_order>.
 
-=cut
-
-sub order { sort_order(@_) }
-
-
 =head2 input_filters
 
 Sets a list of input filters on the data.  Correct usage is
 C<input_filters are 'Jifty::DBI::Filter::DateTime'>.  See
 L<Jifty::DBI::Filter>.
 
-=cut
-
-sub input_filters {
-    _list( input_filters => @_ );
-}
-
 =head2 output_filters
 
 Sets a list of output filters on the data.  Correct usage is
@@ -443,12 +484,6 @@
 L<Jifty::DBI::Filter>.  You usually don't need to set this, as the
 output filters default to the input filters in reverse order.
 
-=cut
-
-sub output_filters {
-    _list( output_filters => @_ );
-}
-
 =head2 filters
 
 Sets a list of filters on the data.  These are applied when reading
@@ -457,23 +492,11 @@
 actuality, this is the exact same as L</input_filters>, since output
 filters default to the input filters, reversed.
 
-=cut
-
-sub filters {
-    _list( input_filters => @_ );
-}
-
 =head2 since
 
 What application version this column was last changed.  Correct usage
 is C<since '0.1.5'>.
 
-=cut
-
-sub since {
-    _list( since => @_ );
-}
-
 =head2 till
 
 The version after this column was supported. The column is not available in
@@ -502,45 +525,21 @@
   { display => 'Blue', value => 'blue' },
   { display => 'Red', value => 'red' }
 
-=cut
-
-sub valid_values {
-    _list( valid_values => @_ );
-}
-
 =head2 valid
 
 Alias for C<valid_values>.
 
-=cut
-
-sub valid {
-    _list( valid_values => @_ );
-}
-
 =head2 label
 
 Designates a human-readable label for the column, for use in user
 interfaces.  Correct usage is C<label is 'Your foo value'>.
 
-=cut
-
-sub label {
-    _list( label => @_ );
-}
-
 =head2 hints
 
 A sentence or two to display in long-form user interfaces about what
 might go in this column.  Correct usage is C<hints is 'Used by the
 frobnicator to do strange things'>.
 
-=cut
-
-sub hints {
-    _list( hints => @_ );
-}
-
 =head2 render_as
 
 Used in user interface generation to know how to render the column.
@@ -584,108 +583,15 @@
 If these don't meet your needs, you can write your own subclass of
 L<Jifty::Web::Form::Field>. See the documentation for that module.
 
-=cut
-
-sub render_as {
-    _list( render_as => @_ );
-}
-
 =head2 render
 
 Alias for C<render_as>.
 
-=cut
-
-sub render {
-    _list( render_as => @_ );
-}
-
 =head2 indexed
 
 An index will be built on this column
 Correct usage is C<is indexed>
 
-=cut
-
-sub indexed {
-    _list( indexed => 1, @_ );
-}
-
-=head2 by
-
-Helper method to improve readability.
-
-=cut
-
-sub by {
-    _list( by => @_ );
-}
-
-=head2 is
-
-Helper method to improve readability.
-
-=cut
-
-sub is {
-    my $thing = shift;
-    ref $thing eq "ARRAY" ? ( @{$thing}, @_ ) : ($thing, @_);
-}
-
-=head2 as
-
-Helper method to improve readability.
-
-=cut
-
-sub as {
-    my $thing = shift;
-    ref $thing eq "ARRAY" ? ( @{$thing}, @_ ) : ($thing, @_);
-}
-
-=head2 are
-
-Helper method to improve readability.
-
-=cut
-
-sub are {
-    my $ref = [];
-    push @{$ref}, shift @_ while @_ and not UNIVERSAL::isa($_[0], "Jifty::DBI::Schema::Trait");
-    return( $ref, @_ );
-}
-
-=head2 on
-
-Helper method to improve readability.
-
-=cut
-
-sub on {
-    _list( self => shift );
-}
-
-sub _list {
-    defined wantarray
-        or croak("Cannot add traits in void context -- check for misspelled preceding comma as a semicolon or missing use statements for models you refer_to.");
-
-    wantarray
-        or croak("Cannot call list traits in scalar context -- check for unneccessary 'is'");
-    _trait(@_);
-}
-
-sub _item {
-    defined wantarray
-        or croak("Cannot add traits in void context -- check for misspelled preceding comma as a semicolon");
-
-    _trait(@_);
-}
-
-sub _trait {
-    my @trait;
-    push @trait, shift @_ while @_ and not UNIVERSAL::isa($_[0], "Jifty::DBI::Schema::Trait");
-    return wantarray ? (Jifty::DBI::Schema::Trait->new(@trait), @_) : Jifty::DBI::Schema::Trait->new(@trait);
-}
 
 =head1 EXAMPLE
 
@@ -702,32 +608,4 @@
 
 =cut
 
-package Jifty::DBI::Schema::Trait;
-
-use overload "!" => \&negation;
-use Carp qw/croak/;
-
-sub new {
-    my $class = shift;
-    return bless [@_], $class;
-}
-
-sub apply {
-    my $self = shift;
-    my ($column) = @_;
-
-    my ($method, $argument) = @{$self};
-
-    croak("Illegal Jifty::DBI::Schema property '$method'")
-      unless $column->can($method);
-
-    $column->$method($argument);
-}
-
-sub negation {
-    my $self = shift;
-    my ($trait, @rest) = @{$self};
-    return (ref $self)->new($trait, map {not $_} @rest);
-}
-
 1;

Modified: Jifty-DBI/trunk/t/01records.t
==============================================================================
--- Jifty-DBI/trunk/t/01records.t	(original)
+++ Jifty-DBI/trunk/t/01records.t	Sat Mar  3 11:41:08 2007
@@ -38,7 +38,6 @@
         is( $rec->_accessible('id' => 'write'), 0, 'id is not accessible for write' );
         is( $rec->_accessible('id'), undef, "any column is not accessible in undefined mode" );
         is( $rec->_accessible('unexpected_column' => 'read'), undef, "column doesn't exist and can't be accessible for read" );
-
         is_deeply( [sort($rec->readable_attributes)], [sort qw(address employee_id id name phone)], 'readable attributes' );
         is_deeply( [sort($rec->writable_attributes)], [sort qw(address employee_id name phone)], 'writable attributes' );
 
@@ -290,7 +289,7 @@
   type is 'varchar(14)';
 
 column phone =>
-  type is 'varchar(18)',
+  type is 'varchar(18)';
 
 column address =>
   type is 'varchar(50)',

Modified: Jifty-DBI/trunk/t/02records_object.t
==============================================================================
--- Jifty-DBI/trunk/t/02records_object.t	(original)
+++ Jifty-DBI/trunk/t/02records_object.t	Sat Mar  3 11:41:08 2007
@@ -119,7 +119,7 @@
 BEGIN {
     use Jifty::DBI::Schema;
     use Jifty::DBI::Record schema {
-    column employee => refers_to TestApp::Employee;
+    column employee => references TestApp::Employee;
     column phone    => type is 'varchar(18)';
     }
 }

Modified: Jifty-DBI/trunk/t/11schema_records.t
==============================================================================
--- Jifty-DBI/trunk/t/11schema_records.t	(original)
+++ Jifty-DBI/trunk/t/11schema_records.t	Sat Mar  3 11:41:08 2007
@@ -266,7 +266,7 @@
     use Jifty::DBI::Schema;
     use Jifty::DBI::Record schema {
     column name => type is 'varchar';
-    column phones => refers_to TestApp::PhoneCollection by 'employee';
+    column phones => references TestApp::PhoneCollection by 'employee';
     }
 }
 
@@ -282,7 +282,7 @@
 BEGIN {
     use Jifty::DBI::Schema;
     use Jifty::DBI::Record schema {;
-    column employee => refers_to TestApp::Employee;
+    column employee => refers_to TestApp::Employee; # "refers_to" is the old synonym to "references"
     column phone    => type is 'varchar';
     }
 }

Modified: Jifty-DBI/trunk/t/12prefetch.t
==============================================================================
--- Jifty-DBI/trunk/t/12prefetch.t	(original)
+++ Jifty-DBI/trunk/t/12prefetch.t	Sat Mar  3 11:41:08 2007
@@ -183,8 +183,8 @@
 BEGIN {
     use Jifty::DBI::Schema;
     use Jifty::DBI::Record schema {
-    column name => type 'varchar';
-    column phones => refers_to TestApp::PhoneCollection by 'employee';
+    column name => type is 'varchar';
+    column phones => references TestApp::PhoneCollection by 'employee';
     }
 }
 
@@ -194,8 +194,8 @@
 BEGIN {
     use Jifty::DBI::Schema;
     use Jifty::DBI::Record schema {
-    column employee => refers_to TestApp::Employee;
-    column phone    => type 'varchar';
+    column employee => references TestApp::Employee;
+    column phone    => type is 'varchar';
     }
 }
 

Added: Jifty-DBI/trunk/t/15types.t
==============================================================================
--- (empty file)
+++ Jifty-DBI/trunk/t/15types.t	Sat Mar  3 11:41:08 2007
@@ -0,0 +1,133 @@
+#!/usr/bin/env perl -w
+
+use strict;
+
+use Test::More;
+BEGIN { require "t/utils.pl" }
+our (@available_drivers);
+
+use constant TESTS_PER_DRIVER => 16;
+
+my $total = scalar(@available_drivers) * TESTS_PER_DRIVER;
+plan tests => $total;
+
+use DateTime ();
+
+foreach my $d ( @available_drivers ) {
+SKIP: {
+        unless( has_schema( 'TestApp::User', $d ) ) {
+                skip "No schema for '$d' driver", TESTS_PER_DRIVER;
+        }
+        unless( should_test( $d ) ) {
+                skip "ENV is not defined for driver '$d'", TESTS_PER_DRIVER;
+        }
+        diag("start testing with '$d' handle") if $ENV{TEST_VERBOSE};
+
+        my $handle = get_handle( $d );
+        connect_handle( $handle );
+        isa_ok($handle->dbh, 'DBI::db');
+
+        {my $ret = init_schema( 'TestApp::User', $handle );
+        isa_ok($ret,'DBI::st', "Inserted the schema. got a statement handle back" );}
+
+        my $rec = TestApp::User->new( handle => $handle );
+        isa_ok($rec, 'Jifty::DBI::Record');
+
+        my $now = time;
+        my $today = DateTime->from_epoch( epoch => $now )->truncate( to => 'day' )->epoch;
+        my $min_of_day = DateTime->from_epoch( epoch => $now )->truncate( to => 'minute' );
+        my $dt = DateTime->from_epoch( epoch => $now );
+        my ($id) = $rec->create( created => $dt, event_on => $dt, event_stops => $min_of_day );
+        ok($id, "Successfuly created ticket");
+        ok($rec->load($id), "Loaded the record");
+        is($rec->id, $id, "The record has its id");
+        isa_ok($rec->created, 'DateTime' );
+        is( $rec->created->epoch, $now, "Correct value");
+        isa_ok($rec->event_on, 'DateTime' );
+        is( $rec->event_on->epoch, $today, "Correct value");
+        isa_ok($rec->event_stops, 'DateTime' );
+        is( $rec->event_stops->minute, $min_of_day->minute, "Correct value");
+        is( $rec->event_stops->hour, $min_of_day->hour, "Correct value");
+
+        # undef/NULL
+        $rec->set_created;
+        is($rec->created, undef, "Set undef value" );
+
+        # from string
+        require POSIX;
+        $rec->set_created( POSIX::strftime( "%Y-%m-%d %H:%M:%S", gmtime($now) ) );
+        isa_ok($rec->created, 'DateTime' );
+        is( $rec->created->epoch, $now, "Correct value");
+
+        cleanup_schema( 'TestApp', $handle );
+        disconnect_handle( $handle );
+}
+}
+
+package TestApp::User;
+use base qw/Jifty::DBI::Record/;
+
+1;
+
+sub schema_sqlite {
+
+<<EOF;
+CREATE table users (
+        id integer primary key,
+        created datetime,
+        event_on date,
+        event_stops time
+)
+EOF
+
+}
+
+sub schema_mysql {
+
+<<EOF;
+CREATE TEMPORARY table users (
+        id integer auto_increment primary key,
+        created datetime,
+        event_on date,
+        event_stops time
+)
+EOF
+
+}
+
+sub schema_pg {
+
+<<EOF;
+CREATE TEMPORARY table users (
+        id serial primary key,
+        created timestamp,
+        event_on date,
+        event_stops time
+)
+EOF
+
+}
+
+BEGIN {
+use Jifty::DBI::Schema;
+Jifty::DBI::Schema->register_types(
+    Date =>
+        sub { type is 'date', input_filters are qw/Jifty::DBI::Filter::Date/ },
+    Time =>
+        sub { type is 'time', input_filters are qw/Jifty::DBI::Filter::Time/ },
+    DateTime => sub {
+        type is 'datetime',
+        input_filters are qw/Jifty::DBI::Filter::DateTime/
+    }
+);
+}
+
+use Jifty::DBI::Record schema {
+    column created     => is DateTime;
+    column event_on    => is Date;
+    column event_stops => is Time;
+};
+
+
+1;
+

Added: Jifty-DBI/trunk/t/16inheritance.t
==============================================================================
--- (empty file)
+++ Jifty-DBI/trunk/t/16inheritance.t	Sat Mar  3 11:41:08 2007
@@ -0,0 +1,185 @@
+#!/usr/bin/env perl -w
+
+use strict;
+
+use Test::More;
+BEGIN { require "t/utils.pl" }
+our (@available_drivers);
+
+use constant TESTS_PER_DRIVER => 17;
+
+my $total = scalar(@available_drivers) * TESTS_PER_DRIVER;
+plan tests => $total;
+
+use DateTime ();
+
+foreach my $d ( @available_drivers ) {
+SKIP: {
+        unless( has_schema( 'TestApp::CrazyUser', $d ) ) {
+                skip "No schema for '$d' driver", TESTS_PER_DRIVER;
+        }
+        unless( should_test( $d ) ) {
+                skip "ENV is not defined for driver '$d'", TESTS_PER_DRIVER;
+        }
+        diag("start testing with '$d' handle") if $ENV{TEST_VERBOSE};
+
+        my $handle = get_handle( $d );
+        connect_handle( $handle );
+        isa_ok($handle->dbh, 'DBI::db');
+
+        {my $ret = init_schema( 'TestApp::User', $handle );
+        isa_ok($ret,'DBI::st', "Inserted the schema. got a statement handle back" );}
+        {my $ret = init_schema( 'TestApp::CrazyUser', $handle );
+        isa_ok($ret,'DBI::st', "Inserted the schema. got a statement handle back" );}
+        my $rec = TestApp::CrazyUser->new( handle => $handle );
+        isa_ok($rec, 'Jifty::DBI::Record');
+
+        my $now = time;
+        my $today = DateTime->from_epoch( epoch => $now )->truncate( to => 'day' )->epoch;
+        my $min_of_day = DateTime->from_epoch( epoch => $now )->truncate( to => 'minute' );
+        my $dt = DateTime->from_epoch( epoch => $now );
+        my ($id) = $rec->create( created => $dt, event_on => $dt, event_stops => $min_of_day );
+        ok($id, "Successfuly created ticket");
+        ok($rec->load($id), "Loaded the record");
+        is($rec->id, $id, "The record has its id");
+        isa_ok($rec->created, 'DateTime' );
+        is( $rec->created->epoch, $now, "Correct value");
+        isa_ok($rec->event_on, 'DateTime' );
+        is( $rec->event_on->epoch, $today, "Correct value");
+        isa_ok($rec->event_stops, 'DateTime' );
+        is( $rec->event_stops->minute, $min_of_day->minute, "Correct value");
+        is( $rec->event_stops->hour, $min_of_day->hour, "Correct value");
+
+        # undef/NULL
+        $rec->set_created;
+        is($rec->created, undef, "Set undef value" );
+
+        # from string
+        require POSIX;
+        $rec->set_created( POSIX::strftime( "%Y-%m-%d %H:%M:%S", gmtime($now) ) );
+        isa_ok($rec->created, 'DateTime' );
+        is( $rec->created->epoch, $now, "Correct value");
+
+        cleanup_schema( 'TestApp', $handle );
+        disconnect_handle( $handle );
+}
+}
+
+package TestApp::User;
+use base qw/Jifty::DBI::Record/;
+
+1;
+
+sub schema_sqlite {
+
+<<EOF;
+CREATE table users (
+        id integer primary key,
+        created datetime,
+        event_on date,
+        event_stops time
+)
+EOF
+
+}
+
+sub schema_mysql {
+
+<<EOF;
+CREATE TEMPORARY table users (
+        id integer auto_increment primary key,
+        created datetime,
+        event_on date,
+        event_stops time
+)
+EOF
+
+}
+
+sub schema_pg {
+
+<<EOF;
+CREATE TEMPORARY table users (
+        id serial primary key,
+        created timestamp,
+        event_on date,
+        event_stops time
+)
+EOF
+
+}
+
+BEGIN {
+use Jifty::DBI::Schema;
+Jifty::DBI::Schema->register_types(
+    Date =>
+        sub { type is 'date', input_filters are qw/Jifty::DBI::Filter::Date/ },
+    Time =>
+        sub { type is 'time', input_filters are qw/Jifty::DBI::Filter::Time/ },
+    DateTime => sub {
+        type is 'datetime',
+        input_filters are qw/Jifty::DBI::Filter::DateTime/
+    }
+);
+}
+
+use Jifty::DBI::Record schema {
+    column created     => is DateTime;
+    column event_on    => is Date;
+    column event_stops => is Time;
+};
+
+package TestApp::CrazyUser;
+BEGIN {
+our @ISA =qw(TestApp::User);
+}
+use Jifty::DBI::Schema;
+use Jifty::DBI::Record schema {
+    column craziness => type is 'text';
+#    column event_on  => is mandatory;
+};
+
+sub schema_sqlite {
+
+<<EOF;
+CREATE table crazy_users (
+        id integer primary key,
+        craziness varchar(16),
+        created datetime,
+        event_on date,
+        event_stops time
+)
+EOF
+
+}
+
+sub schema_mysql {
+
+<<EOF;
+CREATE TEMPORARY table crazy_users (
+        id integer auto_increment primary key,
+        created datetime,
+        event_on date,
+        event_stops time
+)
+EOF
+
+}
+
+sub schema_pg {
+
+<<EOF;
+CREATE TEMPORARY table crazy_users (
+        id serial primary key,
+        craziness varchar(16),
+        created timestamp,
+        event_on date,
+        event_stops time
+)
+EOF
+
+}
+
+
+1;
+

Modified: Jifty-DBI/trunk/t/testmodels.pl
==============================================================================
--- Jifty-DBI/trunk/t/testmodels.pl	(original)
+++ Jifty-DBI/trunk/t/testmodels.pl	Sat Mar  3 11:41:08 2007
@@ -44,7 +44,7 @@
 use Jifty::DBI::Record schema {
 
 column employee_id =>
-  refers_to Sample::Employee;
+  references Sample::Employee;
 
 column name =>
   type is 'varchar',


More information about the Jifty-commit mailing list