[Jifty-commit] r5614 - in Jifty-DBI/branches/tisql: . inc/Module inc/Module/Install lib/Jifty lib/Jifty/DBI lib/Jifty/DBI/Filter t

Jifty commits jifty-commit at lists.jifty.org
Wed Jul 30 16:33:17 EDT 2008


Author: ruz
Date: Wed Jul 30 16:33:00 2008
New Revision: 5614

Added:
   Jifty-DBI/branches/tisql/lib/Jifty/DBI/Filter/Boolean.pm
   Jifty-DBI/branches/tisql/lib/Jifty/DBI/Filter/URI.pm
   Jifty-DBI/branches/tisql/t/06filter_boolean.t
Modified:
   Jifty-DBI/branches/tisql/   (props changed)
   Jifty-DBI/branches/tisql/Changes
   Jifty-DBI/branches/tisql/MANIFEST
   Jifty-DBI/branches/tisql/META.yml
   Jifty-DBI/branches/tisql/Makefile.PL
   Jifty-DBI/branches/tisql/SIGNATURE
   Jifty-DBI/branches/tisql/inc/Module/Install.pm
   Jifty-DBI/branches/tisql/inc/Module/Install/AutoInstall.pm
   Jifty-DBI/branches/tisql/inc/Module/Install/Base.pm
   Jifty-DBI/branches/tisql/inc/Module/Install/Can.pm
   Jifty-DBI/branches/tisql/inc/Module/Install/Fetch.pm
   Jifty-DBI/branches/tisql/inc/Module/Install/Include.pm
   Jifty-DBI/branches/tisql/inc/Module/Install/Makefile.pm
   Jifty-DBI/branches/tisql/inc/Module/Install/Metadata.pm
   Jifty-DBI/branches/tisql/inc/Module/Install/Win32.pm
   Jifty-DBI/branches/tisql/inc/Module/Install/WriteAll.pm
   Jifty-DBI/branches/tisql/lib/Jifty/DBI.pm
   Jifty-DBI/branches/tisql/lib/Jifty/DBI/Collection.pm
   Jifty-DBI/branches/tisql/lib/Jifty/DBI/Column.pm
   Jifty-DBI/branches/tisql/lib/Jifty/DBI/Filter.pm
   Jifty-DBI/branches/tisql/lib/Jifty/DBI/Filter/DateTime.pm
   Jifty-DBI/branches/tisql/lib/Jifty/DBI/Handle.pm
   Jifty-DBI/branches/tisql/lib/Jifty/DBI/Handle/Pg.pm
   Jifty-DBI/branches/tisql/lib/Jifty/DBI/Handle/SQLite.pm
   Jifty-DBI/branches/tisql/lib/Jifty/DBI/Record.pm
   Jifty-DBI/branches/tisql/lib/Jifty/DBI/Schema.pm
   Jifty-DBI/branches/tisql/lib/Jifty/DBI/SchemaGenerator.pm
   Jifty-DBI/branches/tisql/t/02-column_constraints.t
   Jifty-DBI/branches/tisql/t/06filter.t
   Jifty-DBI/branches/tisql/t/13collection.t

Log:
 r5596 at ruslan-zakirovs-computer:  ruz | 2008-07-27 10:46:07 +0400
 sync from trunk
  r5062 at ruslan-zakirovs-computer (orig r5061):  alexmv | 2008-02-07 00:22:57 +0300
   r27524 at zoq-fot-pik:  chmrr | 2008-02-06 16:22:10 -0500
    * Fix collections in bool context
  
  r5064 at ruslan-zakirovs-computer (orig r5063):  alexmv | 2008-02-07 02:17:12 +0300
   r27527 at zoq-fot-pik:  chmrr | 2008-02-06 18:16:58 -0500
    * Return self, not true, in boolean context
  
  r5085 at ruslan-zakirovs-computer (orig r5084):  jesse | 2008-02-09 07:58:53 +0300
   r27529 at 31b:  jesse | 2008-02-08 17:40:52 -0500
   * Quiet down defaults for an annoying regex match in current DBIx::DBSChema
  
  r5086 at ruslan-zakirovs-computer (orig r5085):  jesse | 2008-02-09 07:59:10 +0300
   r27530 at 31b:  jesse | 2008-02-08 17:42:39 -0500
   * defaulting to a not-null string
  
  r5087 at ruslan-zakirovs-computer (orig r5086):  jesse | 2008-02-09 08:03:13 +0300
   r27535 at 31b:  jesse | 2008-02-08 23:53:22 -0500
   * fixing our lower() behaviour on non-text columns when we were being stupid
   * better passing in the class of a joined table when using ->new_alias
  
  r5176 at ruslan-zakirovs-computer (orig r5175):  sartak | 2008-02-29 06:46:13 +0300
   r52247 at onn:  sartak | 2008-02-28 22:45:56 -0500
   Have filters receive the database handle
  
  r5177 at ruslan-zakirovs-computer (orig r5176):  sartak | 2008-02-29 06:48:08 +0300
   r52255 at onn:  sartak | 2008-02-28 22:48:03 -0500
   Add "is boolean" support for not-braindead booleans.
  
  r5178 at ruslan-zakirovs-computer (orig r5177):  sartak | 2008-02-29 07:10:47 +0300
   r52257 at onn:  sartak | 2008-02-28 23:10:41 -0500
   Complain if the encoded/decoded value doesn't return one of _is_true or _is_false.
  
  r5179 at ruslan-zakirovs-computer (orig r5178):  sartak | 2008-02-29 08:30:47 +0300
   r52259 at onn:  sartak | 2008-02-29 00:30:30 -0500
   Add a new column attribute, encode_select. This will apply filters on load_by_cols and limit. Have Boolean use encode_select.
  
  r5180 at ruslan-zakirovs-computer (orig r5179):  sartak | 2008-02-29 09:40:06 +0300
   r52261 at onn:  sartak | 2008-02-29 01:38:30 -0500
   Apply filters on default values for attributes
   Rename encode_select to decode_select (I always get the two confused)
   Force undefined boolean attributes to be false, for sanity reasons
  
  r5184 at ruslan-zakirovs-computer (orig r5183):  sartak | 2008-03-01 04:03:01 +0300
   r52274 at onn:  sartak | 2008-02-29 19:52:42 -0500
   Move the alias and column handling in ->limit up sooner so we have a column object as soon as possible
  
  r5185 at ruslan-zakirovs-computer (orig r5184):  sartak | 2008-03-01 04:03:17 +0300
   r52275 at onn:  sartak | 2008-02-29 20:02:51 -0500
   encode and decode were swapped :|
   Some test fixes. DBD::Pg has a damn "DWIM" option for booleans that caused failures
  
  r5186 at ruslan-zakirovs-computer (orig r5185):  sartak | 2008-03-01 04:13:01 +0300
   r52278 at onn:  sartak | 2008-02-29 20:11:49 -0500
   Fix final test failure: toggle pg_bool_tf before making the query
  
  r5187 at ruslan-zakirovs-computer (orig r5186):  sartak | 2008-03-01 04:13:13 +0300
   r52279 at onn:  sartak | 2008-02-29 20:12:51 -0500
   Rename decode_select to encode_on_select
  
  r5209 at ruslan-zakirovs-computer (orig r5208):  sartak | 2008-03-11 04:45:16 +0300
   r52485 at onn:  sartak | 2008-03-10 21:45:09 -0400
   Jifty::DBI::Filter::URI
  
  r5210 at ruslan-zakirovs-computer (orig r5209):  sartak | 2008-03-11 05:20:09 +0300
   r52487 at onn:  sartak | 2008-03-10 22:20:04 -0400
   Get rid of an unbalanced vim-fold
  
  r5212 at ruslan-zakirovs-computer (orig r5211):  sartak | 2008-03-11 16:14:45 +0300
   r52489 at onn:  sartak | 2008-03-11 09:14:39 -0400
   Catch some expected warnings with (new dependency on) Test::Warn
  
  r5228 at ruslan-zakirovs-computer (orig r5227):  alexmv | 2008-03-17 21:39:05 +0300
   r28569 at kohr-ah:  chmrr | 2008-03-17 14:38:49 -0400
    * Fixes for NULL boolean columns
    * Booleans get canonicalizers, so perl-level gets canonical values,
      not just the DB.
    * Canonicalization fixes
  
  r5251 at ruslan-zakirovs-computer (orig r5250):  alexmv | 2008-04-01 22:31:42 +0400
   r28949 at kohr-ah:  chmrr | 2008-04-01 14:31:29 -0400
    * Note that booleans render as checkboxes
  
  r5252 at ruslan-zakirovs-computer (orig r5251):  alexmv | 2008-04-01 22:32:56 +0400
   r28951 at kohr-ah:  chmrr | 2008-04-01 14:32:46 -0400
    * Revert paging fix which isn't quite ready yet
  
  r5258 at ruslan-zakirovs-computer (orig r5257):  dpavlin | 2008-04-05 12:23:29 +0400
  call _init_hander for all columns
  r5263 at ruslan-zakirovs-computer (orig r5262):  sartak | 2008-04-08 06:23:36 +0400
   r53612 at onn:  sartak | 2008-04-07 22:22:53 -0400
   Changes for 0.49
  
  r5264 at ruslan-zakirovs-computer (orig r5263):  sartak | 2008-04-08 06:39:05 +0400
   r53614 at onn:  sartak | 2008-04-07 22:38:43 -0400
   Update MANIFEST, SIGNATURE, META.yml, and inc
  
  r5265 at ruslan-zakirovs-computer (orig r5264):  sartak | 2008-04-08 06:54:36 +0400
   r53616 at onn:  sartak | 2008-04-07 22:52:12 -0400
   Add a list of the major changes in this new version
  
  r5266 at ruslan-zakirovs-computer (orig r5265):  sartak | 2008-04-08 06:54:38 +0400
   r53617 at onn:  sartak | 2008-04-07 22:54:15 -0400
   Update SIGNATURE, release 0.49
  
  r5310 at ruslan-zakirovs-computer (orig r5309):  sartak | 2008-04-16 00:05:52 +0400
   r54086 at onn:  sartak | 2008-04-15 16:05:14 -0400
   Avoid undef warnings by defaulting current_page and per_page in set_page_info
  
  r5311 at ruslan-zakirovs-computer (orig r5310):  sartak | 2008-04-16 00:07:23 +0400
   r54089 at onn:  sartak | 2008-04-15 16:07:03 -0400
   Scratch that set_page_info fix, we do want to warn about this
  
  r5322 at ruslan-zakirovs-computer (orig r5321):  yves | 2008-04-17 16:25:25 +0400
  minor pod improvement for debian lintian
  
  r5345 at ruslan-zakirovs-computer (orig r5344):  sartak | 2008-04-30 01:10:04 +0400
   r54660 at onn:  sartak | 2008-04-29 17:09:51 -0400
   Update copyright year to 2008
  
  r5493 at ruslan-zakirovs-computer (orig r5484):  jasonmay | 2008-05-25 07:33:30 +0400
   r10232 at culex:  jasonmay | 2008-05-24 23:30:43 -0400
   collections can now clear_order_by
  
  r5494 at ruslan-zakirovs-computer (orig r5485):  audreyt | 2008-05-25 10:13:14 +0400
  * Jifty::DBI::Handle::SQLite - LOWER() in SQLite is expensive;
    it's easier just put COLLATE NOCASE on the column side.
  r5495 at ruslan-zakirovs-computer (orig r5486):  trs | 2008-05-27 21:20:34 +0400
   r35216 at zot:  tom | 2008-05-27 13:19:57 -0400
   _formatter is *inheritable* class data.  If it happens to get set by the DateTime filter before getting set by one of its subclasses (the Date and Time filters), than it is stuck on the DateTime _formatter setting because the subclasses don't override it.  There are a couple solutions, the simplest being to check the value of _strptime and update/override _formatter if it is different, which is what I've done here.  (This may not be the most optimized solution.)
  
  r5496 at ruslan-zakirovs-computer (orig r5487):  sartak | 2008-05-28 18:42:04 +0400
   r61122 at onn:  sartak | 2008-05-28 10:41:44 -0400
   Bump to 1.14 which gives us collate nocase
  
  r5497 at ruslan-zakirovs-computer (orig r5488):  sartak | 2008-05-28 18:50:06 +0400
   r61124 at onn:  sartak | 2008-05-28 10:49:27 -0400
   requires('perl' => '5.8.3') confuses M:I. the "correct" incantation is perl_version('5.8.3')
  
  r5498 at ruslan-zakirovs-computer (orig r5489):  trs | 2008-06-02 21:06:37 +0400
   r35364 at zot:  tom | 2008-06-02 13:06:29 -0400
   Require Time::Duration::Parse 0.06 to win us decimal durations like 1.5h
  
  r5499 at ruslan-zakirovs-computer (orig r5490):  trs | 2008-06-02 21:11:24 +0400
   r35366 at zot:  tom | 2008-06-02 13:11:16 -0400
   Bump the version for dependency purposes
  
  r5503 at ruslan-zakirovs-computer (orig r5491):  alexmv | 2008-06-06 00:31:57 +0400
   r32615 at kohr-ah:  chmrr | 2008-06-05 16:31:30 -0400
    * Add the ability to unload columns and prefetched values
  
  r5536 at ruslan-zakirovs-computer (orig r5524):  trs | 2008-06-24 22:18:55 +0400
   r36447 at zot:  tom | 2008-06-24 14:18:22 -0400
   Use $args{'collection'}->limit instead of $self->Jifty::DBI::Collection::limit so we don't break
  
  r5545 at ruslan-zakirovs-computer (orig r5533):  sterling | 2008-06-27 07:10:40 +0400
   r5923 at shanenka-lt-osx:  shanenka | 2008-06-26 22:10:17 -0500
   Adding an example of open_paren/close_paren and limit subclause.
  
  r5546 at ruslan-zakirovs-computer (orig r5534):  sterling | 2008-06-27 17:50:00 +0400
   r5925 at shanenka-lt-osx:  shanenka | 2008-06-27 08:49:36 -0500
   Added documentation for "IS" on limit().
  
  r5551 at ruslan-zakirovs-computer (orig r5539):  trs | 2008-06-30 22:55:32 +0400
   r36668 at zot:  tom | 2008-06-30 14:55:06 -0400
   Bump version so we can depend on it elsewhere
  
  r5552 at ruslan-zakirovs-computer (orig r5540):  sartak | 2008-07-03 07:13:37 +0400
   r63647 at onn:  sartak | 2008-07-02 23:13:24 -0400
   On rollback, flush the record cache
  
 


Modified: Jifty-DBI/branches/tisql/Changes
==============================================================================
--- Jifty-DBI/branches/tisql/Changes	(original)
+++ Jifty-DBI/branches/tisql/Changes	Wed Jul 30 16:33:00 2008
@@ -1,5 +1,96 @@
 Revision history for Perl extension Jifty::DBI.
 
+0.49 Mon Apr 07 22:16:48 EST 2008
+- Major changes:
+   * "is boolean" support for cross-database booleans
+   * New filters: Duration, URI
+   * column attribute encode_select for filtering columns on load_by_cols, etc
+   * <$collection> and @$collection support
+   * Protected and private fields, for Jifty's automatic action introspection
+   * ping/reconnect on error
+   * Memory leak, unnecessary query, and transaction fixes
+
+- All changes:
+   * call _init_hander for all columns
+   * Revert paging fix which isn't quite ready yet
+   * Note that booleans render as checkboxes
+   * Fixes for NULL boolean columns
+   * Booleans get canonicalizers, so perl-level gets canonical values, not just
+     the DB.
+   * Canonicalization fixes
+   * Catch some expected warnings with (new dependency on) Test::Warn
+   * Get rid of an unbalanced vim-fold
+   * Jifty::DBI::Filter::URI
+   * Rename decode_select to encode_on_select
+   * Fix final test failure: toggle pg_bool_tf before making the query
+   * encode and decode were swapped :|
+   * Some test fixes. DBD::Pg has a damn "DWIM" option for booleans that caused
+     failures
+   * Move the alias and column handling in ->limit up sooner so we have a
+     column object as soon as possible
+   * Apply filters on default values for attributes
+   * Rename encode_select to decode_select (I always get the two confused)
+   * Force undefined boolean attributes to be false, for sanity reasons
+   * Add a new column attribute, encode_select. This will apply filters on
+     load_by_cols and limit. Have Boolean use encode_select.
+   * Complain if the encoded/decoded value doesn't return one of _is_true or
+     _is_false.
+   * Add "is boolean" support for not-braindead booleans.
+   * Have filters receive the database handle
+   * fixing our lower() behaviour on non-text columns when we were being stupid
+   * better passing in the class of a joined table when using ->new_alias
+   * defaulting to a not-null string
+   * Quiet down defaults for an annoying regex match in current DBIx::DBSChema
+   * Return self, not true, in boolean context
+   * Fix collections in bool context
+   * Pass all data to logging hook so they can do more interesting things with
+     them immediately
+   * micro-optimization of _filters which is called quite often
+   * Add <$collection> and @$collection syntax sugar that simply calls
+     $collection->next and $collection->items_array_ref behind the scenes.
+   * Tiny POD tweak so t/pod-coverage.t passes.
+   * Jifty::DBI::Handle - When "begin_transaction", "commit" and "rollback"
+     did not succeed, the internal $TRANSDEPTH should be left unchanged.
+     (Otherwise, a failed ->commit will cause future transactions to never
+     really take place.)
+   * Add a documentation meta-attribute, for Jifty
+   * Debian packaging for 0.48
+   * Bump for added properties
+   * Protected and private fields, for Jifty's automatic action introspection
+   * Added the ping/reconnect on error as suggested by Jesse.
+   * Fix typo
+   * Upgrade dep to 0.05 now that the hh:mm(:ss) parsing code is in it
+   * Better error checking
+   * No need to duplicate order_by's logic, just call thrash explicitly and
+     call add_order_by
+   * Add Collection->add_order_by, which refines ordering, instead of thrashing
+     it
+   * Get rid of reference to deprecated method
+   * Don't try to encode/decode empty values
+   * Handle hh:mm(:ss)? within other duration strings so that "1d 2:30" works
+   * More tests for the duration filter (to test different input formats and
+     check the raw DB value)
+   * Fix version
+   * Handle hh:mm:ss in the duration filter as input and output a more concise
+     format
+   * dd missing dependancies with Class::Trigger in debian packaging for use of
+     alone package libjifty-dbi-perl
+   * Add optional dependencies on Time::Duration(::Parse) in Makefile.PL
+   * Add a duration filter which uses Time::Duration and Time::Duration::Parse.
+     Stores durations as seconds in the database and converts them to English
+     strings for output.
+   * Revert mistaken change
+   * UNIVERSAL::require has a memory leak, fixed by 0.11
+   * Allow starts_with and ends_with in addition to STARTSWITH and ENDSWITH
+   * We were leaking the collection on set_page_info. Yuck! We need some way to
+     find these Scalar::Defer leaks
+   * Be more careful about initializing values we're using
+   * Fix a mismerge in 4642
+   * By not reaching inside the pager object, we save on some useless forced
+     SQL queries
+   * Be a bit cleverer about not always doing a count before doing a select
+     (The previous behaviour was pathalogical)
+
 0.48 Thu Nov 29 16:28:11 EST 2007
 
    * User and password values are excluded from the DSN in a more proper fashion

Modified: Jifty-DBI/branches/tisql/MANIFEST
==============================================================================
--- Jifty-DBI/branches/tisql/MANIFEST	(original)
+++ Jifty-DBI/branches/tisql/MANIFEST	Wed Jul 30 16:33:00 2008
@@ -26,6 +26,7 @@
 lib/Jifty/DBI/Column.pm
 lib/Jifty/DBI/Filter.pm
 lib/Jifty/DBI/Filter/base64.pm
+lib/Jifty/DBI/Filter/Boolean.pm
 lib/Jifty/DBI/Filter/Date.pm
 lib/Jifty/DBI/Filter/DateTime.pm
 lib/Jifty/DBI/Filter/Duration.pm
@@ -33,6 +34,7 @@
 lib/Jifty/DBI/Filter/Storable.pm
 lib/Jifty/DBI/Filter/Time.pm
 lib/Jifty/DBI/Filter/Truncate.pm
+lib/Jifty/DBI/Filter/URI.pm
 lib/Jifty/DBI/Filter/utf8.pm
 lib/Jifty/DBI/Filter/YAML.pm
 lib/Jifty/DBI/Handle.pm
@@ -69,6 +71,7 @@
 t/03rebless.t
 t/04memcached.t
 t/06filter.t
+t/06filter_boolean.t
 t/06filter_datetime.t
 t/06filter_duration.t
 t/06filter_storable.t

Modified: Jifty-DBI/branches/tisql/META.yml
==============================================================================
--- Jifty-DBI/branches/tisql/META.yml	(original)
+++ Jifty-DBI/branches/tisql/META.yml	Wed Jul 30 16:33:00 2008
@@ -1,9 +1,11 @@
 --- 
+author: ~
 build_requires: 
   DBD::SQLite: 0
   Test::More: 0.52
+  Test::Warn: 0.1
 distribution_type: module
-generated_by: Module::Install version 0.67
+generated_by: Module::Install version 0.68
 license: perl
 meta-spec: 
   url: http://module-build.sourceforge.net/META-spec-v1.3.html
@@ -33,8 +35,8 @@
   Lingua::EN::Inflect: 0
   Object::Declare: 0.22
   Scalar::Defer: 0.1
-  UNIVERSAL::require: 0
+  UNIVERSAL::require: 0.11
   YAML::Syck: 0
   perl: 5.8.3
   version: 0
-version: 0.46
+version: 0.49

Modified: Jifty-DBI/branches/tisql/Makefile.PL
==============================================================================
--- Jifty-DBI/branches/tisql/Makefile.PL	(original)
+++ Jifty-DBI/branches/tisql/Makefile.PL	Wed Jul 30 16:33:00 2008
@@ -1,8 +1,8 @@
 use inc::Module::Install;
-requires( perl => '5.8.3');
 name ('Jifty-DBI');
 license ('perl');
 version_from('lib/Jifty/DBI.pm');
+perl_version('5.8.3');
 requires('Cache::Simple::TimedExpiry' => '0.21');
 requires('Class::Accessor::Fast' => 0);
 requires('Class::Data::Inheritable');
@@ -25,7 +25,8 @@
 requires('version');
 #requires('Class::Trigger');
 build_requires('Test::More' => 0.52);
-build_requires('DBD::SQLite');
+build_requires('Test::Warn' => 0.10);
+build_requires('DBD::SQLite' => 1.14);
 no_index directory => 'ex';
 features( 
     'Memcached support' => [
@@ -39,7 +40,11 @@
     'Duration filter' => [
         -default => 1,
         'Time::Duration' => '',
-        'Time::Duration::Parse' => '0.05',
+        'Time::Duration::Parse' => '0.06',
+    ],
+    'URI filter' => [
+        -default => 1,
+        'URI' => '',
     ],
 );
 auto_install();

Modified: Jifty-DBI/branches/tisql/SIGNATURE
==============================================================================
--- Jifty-DBI/branches/tisql/SIGNATURE	(original)
+++ Jifty-DBI/branches/tisql/SIGNATURE	Wed Jul 30 16:33:00 2008
@@ -14,76 +14,81 @@
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
-SHA1 3334928687400b465f3a892a9658e48084c6c646 Changes
-SHA1 f559ca6ef0bd30360aad7c77fb6d4251158f87ed MANIFEST
-SHA1 f489b63d4c48d37e3f60388dbac1e2ef9a571999 META.yml
-SHA1 1e748530883277156c87f2ec864746ee8780d745 Makefile.PL
+SHA1 a1e90ada944f4f566a22eb278ddf514153053c81 Changes
+SHA1 d44e458dea3e9f8afe04fead6857c9360d232af8 MANIFEST
+SHA1 819374d4317fb068696f1f6e1bc1f1e3868d9fa6 META.yml
+SHA1 13801def329494f8f119a2659f71b710f9d13aa3 Makefile.PL
 SHA1 ae8407c841f230c353f683bd5c257815aed9b9f0 README
 SHA1 82d6ac3f6def48558d09f8b6e3b53ed4194d8c81 ROADMAP
 SHA1 9d304f35438f847863969f6a069598379f5a9db2 debian/README
-SHA1 603ce50bde12c6a3a91f28742ffd8a9d3917ec79 debian/changelog
+SHA1 00b43188583b43d0c5f953a9b4be027a1f61404b debian/changelog
 SHA1 5d9474c0309b7ca09a182d888f73b37a8fe1362c debian/compat
-SHA1 9cfaec0ba99948cbb812aa1d00005e90f55861b3 debian/control
+SHA1 585fdbb668c1537387d855eb894bc5c987c024d8 debian/control
 SHA1 c1085db4f95bd6e7e7470ccab55f8adba10d5024 debian/rules
 SHA1 c28087e498978a1a314dfcaa584844703f31ac8c doc/notes/on_intuitive_schema_definitions
 SHA1 584c0f6cdebcbf760dfca8413c94783586120214 ex/Example/Model/Address.pm
 SHA1 7cea1a5289f79c2a87837924a83feb583f6e8890 ex/Example/Model/Employee.pm
 SHA1 a9d62e4f5b43b2f78066172a4771238ee7df6339 ex/create_tables.pl
 SHA1 603bb9de29fb8cba7f13409c546750972eff645d inc/Module/AutoInstall.pm
-SHA1 78edb89a439463e44c33a72bbee84c54d0dc8aaf inc/Module/Install.pm
-SHA1 ae32c02b539901de91f06366ce9bdbb7a7bd040b inc/Module/Install/AutoInstall.pm
-SHA1 8ea4e37df83fd0c1c050be5c8da75545c3828d9b inc/Module/Install/Base.pm
-SHA1 1da6031583c32f0d1ec073b8376102fc51427dcc inc/Module/Install/Can.pm
-SHA1 b779375b90c16af2f31f38a1dd2b5df223c7f2fb inc/Module/Install/Fetch.pm
-SHA1 6bf0d0d100b94d1a2ce64d010c8813dec26ac480 inc/Module/Install/Include.pm
-SHA1 2054450e1e9c1dd8056362bf4a64ae70d5d71476 inc/Module/Install/Makefile.pm
-SHA1 5d6189b2cad15cf9932a28faafd55130c8247e83 inc/Module/Install/Metadata.pm
-SHA1 02af973fae2ac3531fa6b704574b2b8cb2a08148 inc/Module/Install/Win32.pm
-SHA1 3a2eab96e91cca8d99938cda7791759ae9d97b3a inc/Module/Install/WriteAll.pm
-SHA1 22e3f05e9262cc24a497f98efc3a92e0420bbffa lib/Jifty/DBI.pm
-SHA1 23294906d6424ae747d284ba03d6b7b71113405e lib/Jifty/DBI/Collection.pm
+SHA1 7e2cfa1b9efe0d502ee57717649c90ba4bd28ba9 inc/Module/Install.pm
+SHA1 182a0df45b65151afdc2be0b7246a2d02d0f0567 inc/Module/Install/AutoInstall.pm
+SHA1 6e1392d80a0f239eecd5664f7f21f922cedb9329 inc/Module/Install/Base.pm
+SHA1 f69417fe831d9cc22a78f00a617afadceade4d81 inc/Module/Install/Can.pm
+SHA1 c61d02895330310048bf388881b5e2e064031561 inc/Module/Install/Fetch.pm
+SHA1 4933b00c3a646da8d223c6957f94552bbd62f8c6 inc/Module/Install/Include.pm
+SHA1 54fcbed19232ec959bb17cfb4410599afc7f0779 inc/Module/Install/Makefile.pm
+SHA1 7d3be9b158e37b2b2c22084740099955623b1d56 inc/Module/Install/Metadata.pm
+SHA1 0a8b66180229ba2f9deaea1fedd0aacf7a7ace6b inc/Module/Install/Win32.pm
+SHA1 d3352eb33fe43a5f3ead513f645224fe34d73bc9 inc/Module/Install/WriteAll.pm
+SHA1 d995b8919444a5245c506495b96aab104f7b8166 lib/Jifty/DBI.pm
+SHA1 09eb4ebb041498d7e8077eed0f013fefb2cc1606 lib/Jifty/DBI/Collection.pm
 SHA1 639ef9c81f03fb084b312a5f9a6f6a3ff63b36b7 lib/Jifty/DBI/Collection/Union.pm
 SHA1 bcba77fd2bacf0475aea1de97f57365c8de92ca6 lib/Jifty/DBI/Collection/Unique.pm
-SHA1 049ce7a6d91bf5ae0dcfa5c3f50dfd6a682f8e70 lib/Jifty/DBI/Column.pm
-SHA1 faf43ec59f8ebd094a1bdfc92eda92053d511e97 lib/Jifty/DBI/Filter.pm
+SHA1 0e6346b30448482f0265221325de4b209dcc13fb lib/Jifty/DBI/Column.pm
+SHA1 cdce125423fb907a12e888a60522cb5d03cda5c0 lib/Jifty/DBI/Filter.pm
+SHA1 e030c3ef5c723ba6dce2e3fc23afecf2a6dfe260 lib/Jifty/DBI/Filter/Boolean.pm
 SHA1 87192bf64a224cbea78770f4209ecae9981f3f5c lib/Jifty/DBI/Filter/Date.pm
 SHA1 70ffc9da2f13fc1aabd652169ba5a08b292ba678 lib/Jifty/DBI/Filter/DateTime.pm
+SHA1 561ee05d174cb1a40be59cd1ef271b6a6c458d27 lib/Jifty/DBI/Filter/Duration.pm
 SHA1 79649ca3fb9f8aa9d2fdda00d6d7c7c99fe4092f lib/Jifty/DBI/Filter/SaltHash.pm
 SHA1 45ff3c7d2c03136acf98b74c659e2fe8c734d929 lib/Jifty/DBI/Filter/Storable.pm
 SHA1 13837e1f389b4e2e60e8b2395b327604ec7e25b6 lib/Jifty/DBI/Filter/Time.pm
 SHA1 83b92752da73eb8a88546509b4affaf57754ea66 lib/Jifty/DBI/Filter/Truncate.pm
+SHA1 6dcb8ad9a3b858bdb76fe62ddf1f483701e1f918 lib/Jifty/DBI/Filter/URI.pm
 SHA1 67ffe7188a1f529d7594f4fa3803bcbe15ba6485 lib/Jifty/DBI/Filter/YAML.pm
 SHA1 9a6fd17e677321904436fefec4d434e17a4685b1 lib/Jifty/DBI/Filter/base64.pm
 SHA1 deb33fa7b35f3542aac3e2d7fb4b5d3070dc3917 lib/Jifty/DBI/Filter/utf8.pm
-SHA1 759b75ddc720d400f610b2a460019eca902b8ae8 lib/Jifty/DBI/Handle.pm
+SHA1 fdc47b3260594e60500125246b6f8a8f92ea142a lib/Jifty/DBI/Handle.pm
 SHA1 bcc7c456e1c4d0dddd5564f03c8bb03a6c7e261f lib/Jifty/DBI/Handle/Informix.pm
 SHA1 338116a45f8eb6bfca5e76e8d3be78fb61fffe81 lib/Jifty/DBI/Handle/ODBC.pm
 SHA1 960fd0b63f3de11924c5d47a3c0c6d1db105ed5b lib/Jifty/DBI/Handle/Oracle.pm
-SHA1 2b64b747d072c67a510e79685cc08bebaf0a1402 lib/Jifty/DBI/Handle/Pg.pm
+SHA1 88573513df75869a536443e4a34006477577df9f lib/Jifty/DBI/Handle/Pg.pm
 SHA1 860b373ddb0d0a1d001f20c721d9dffe003e2517 lib/Jifty/DBI/Handle/SQLite.pm
 SHA1 bba2314c20fcc3ef71cc69090f1cd6bd515cd9b4 lib/Jifty/DBI/Handle/Sybase.pm
 SHA1 e6041a34c3044ed8b9691a5629ecf146fed95257 lib/Jifty/DBI/Handle/mysql.pm
 SHA1 f2cc4fcce79c9a88a023d4e6bd96c2089eef1ced lib/Jifty/DBI/Handle/mysqlPP.pm
 SHA1 0e975f9ec5480ca09025c592c06d484058e637df lib/Jifty/DBI/HasFilters.pm
-SHA1 61579d4fb19bab8d89471ec1dc6afea0e86394e2 lib/Jifty/DBI/Record.pm
+SHA1 954c6673811421607d8780038934f39b7700fb84 lib/Jifty/DBI/Record.pm
 SHA1 1c8b4adcd312024a3408a52d3b2ef288c2084603 lib/Jifty/DBI/Record/Cachable.pm
-SHA1 f4ec61cd857cb1cead8c9c5551047dc78734b73a lib/Jifty/DBI/Record/Memcached.pm
+SHA1 526ea0d42808425435c21ffb0bc4b92c636a6176 lib/Jifty/DBI/Record/Memcached.pm
 SHA1 6a70dc2a6fd6a5d77502d391ac2630d91a681c1a lib/Jifty/DBI/Record/Plugin.pm
-SHA1 08c285edcd05698b982c082f50da82fde02e4d31 lib/Jifty/DBI/Schema.pm
-SHA1 5594fb70d330523a9e6c7b5a1d2ea2f968be2615 lib/Jifty/DBI/SchemaGenerator.pm
+SHA1 95c3151c475f1ffea7ce33ced9166d601c5ecdfe lib/Jifty/DBI/Schema.pm
+SHA1 36a88a3bec092873e86ca2f1cf7edbdb5b358a53 lib/Jifty/DBI/SchemaGenerator.pm
 SHA1 32834b7c4cf5a8d131382fccc8db341be8768291 t/00.load.t
 SHA1 9aa7fed2b2409faa4c71d2a45db210721f47403e t/01-version_checks.t
 SHA1 13c9fe3eeec0d000a7c86ea2474e30186cbc37e2 t/01basics.t
 SHA1 018309dfc89440dc670cccf6138e3d4679465b47 t/01records.t
 SHA1 7574130aa1dc5338b6efcd0f04eca3f6dc4b2696 t/01searches.t
-SHA1 933ebc7f0cfcaf03a2092a7c8271f98b2385f785 t/02-column_constraints.t
+SHA1 df97ee4e5bcb4ef0663dcc1a8db86dc66e8d9206 t/02-column_constraints.t
 SHA1 90a5b9c663002e3c43a00b7f9a04d6ec2787500e t/02records_cachable.t
 SHA1 33642a61fd4b5a88436a82c6dd0fef359ba74a2b t/02records_object.t
 SHA1 369d71ca9ec0f00116ac6be24e017f592ac9cc45 t/02searches_joins.t
 SHA1 f1f330dd8b4144e3437aba1455053903306bd0bc t/03rebless.t
 SHA1 62c42d8458d73898f47f1b72d757239747321ef5 t/04memcached.t
-SHA1 a2d00943d47d52d3ad92efe67a52a9b8e1522903 t/06filter.t
+SHA1 f0371e275879019e2abe732bbb5626d0d05049a0 t/06filter.t
+SHA1 bfb0f7133ce399738b2afe6e9e716134289acaa6 t/06filter_boolean.t
 SHA1 8d464426f2c5b0ab5ecc5a0a0331e5f77669c2dc t/06filter_datetime.t
+SHA1 172f655a7fdb4771e6e8b3aee45e93b1264a5567 t/06filter_duration.t
 SHA1 1c0727c29fb58462710e4578a237d557b8453a07 t/06filter_storable.t
 SHA1 f0f6ce9d48f419de6ac6154684f9065f32e30ddd t/06filter_truncate.t
 SHA1 2e9777a47e3a920d063bfbf9d56375c67c5b89c5 t/06filter_utf8.t
@@ -91,13 +96,14 @@
 SHA1 64c3722f5b34feafc87113257079721c174f3f96 t/10schema.t
 SHA1 0f4655f0a4e558ac31df7b7fdf17c9b110f934da t/11schema_records.t
 SHA1 22a083137927a8635b02931e40f80c60220ec3a7 t/12prefetch.t
-SHA1 a93e0ee622b2291f797887f663f33c30fc7339f6 t/13collection.t
+SHA1 063586c498fdc7fc90519f1d1a3e37838d637104 t/13collection.t
 SHA1 41b7fbaf031d103a4f2066f177cc3bee84ab0458 t/14handle-pg.t
 SHA1 4f41229caa246bf6ebb369010deb0c1eb8809666 t/15types.t
 SHA1 5958e59e29d29fbf3862b5d3471472cbd82d191e t/16inheritance.t
 SHA1 c7004285662f16abca274918f86d17ea43fe8c90 t/17virtualtypes.t
 SHA1 cc7d6dd9889837143074729d30030ddabcfa6b9e t/18triggers.t
 SHA1 54b7727b49111162703581d13dd47dfe276fbe9a t/19reference.t
+SHA1 72a16ddfc2642564023448450f3475ae5abf6d86 t/20overload.t
 SHA1 5b3f8373687f89ccf3faf2dfbda9663137a8c078 t/case_sensitivity.t
 SHA1 1dd9675b0a9a59fdcd300f5d92297f0ecf4f03e4 t/metadata.t
 SHA1 59c44900b1cb957d262f96363ceff21b46e0d598 t/pod-coverage.t
@@ -107,7 +113,7 @@
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.7 (Darwin)
 
-iD8DBQFHTzB0sxfQtHhyRPoRAtM9AJ9Cy4J75ED7ppZVxRT/Ar2wPvuLwwCgj8h3
-XrFbmqQ0xgMosHiFK7ieL6U=
-=S/Zy
+iD8DBQFH+t3rsxfQtHhyRPoRAlcOAJkBmvOV+Fc/7t5ULT/HPwXwlGgCzQCeJBy7
+6UTu17Js7YWoKbUQ6XpP8j8=
+=cQ9D
 -----END PGP SIGNATURE-----

Modified: Jifty-DBI/branches/tisql/inc/Module/Install.pm
==============================================================================
--- Jifty-DBI/branches/tisql/inc/Module/Install.pm	(original)
+++ Jifty-DBI/branches/tisql/inc/Module/Install.pm	Wed Jul 30 16:33:00 2008
@@ -28,7 +28,7 @@
     # This is not enforced yet, but will be some time in the next few
     # releases once we can make sure it won't clash with custom
     # Module::Install extensions.
-    $VERSION = '0.67';
+    $VERSION = '0.68';
 }
 
 # Whether or not inc::Module::Install is actually loaded, the

Modified: Jifty-DBI/branches/tisql/inc/Module/Install/AutoInstall.pm
==============================================================================
--- Jifty-DBI/branches/tisql/inc/Module/Install/AutoInstall.pm	(original)
+++ Jifty-DBI/branches/tisql/inc/Module/Install/AutoInstall.pm	Wed Jul 30 16:33:00 2008
@@ -6,7 +6,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.67';
+	$VERSION = '0.68';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }

Modified: Jifty-DBI/branches/tisql/inc/Module/Install/Base.pm
==============================================================================
--- Jifty-DBI/branches/tisql/inc/Module/Install/Base.pm	(original)
+++ Jifty-DBI/branches/tisql/inc/Module/Install/Base.pm	Wed Jul 30 16:33:00 2008
@@ -1,7 +1,7 @@
 #line 1
 package Module::Install::Base;
 
-$VERSION = '0.67';
+$VERSION = '0.68';
 
 # Suspend handler for "redefined" warnings
 BEGIN {

Modified: Jifty-DBI/branches/tisql/inc/Module/Install/Can.pm
==============================================================================
--- Jifty-DBI/branches/tisql/inc/Module/Install/Can.pm	(original)
+++ Jifty-DBI/branches/tisql/inc/Module/Install/Can.pm	Wed Jul 30 16:33:00 2008
@@ -11,7 +11,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.67';
+	$VERSION = '0.68';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }

Modified: Jifty-DBI/branches/tisql/inc/Module/Install/Fetch.pm
==============================================================================
--- Jifty-DBI/branches/tisql/inc/Module/Install/Fetch.pm	(original)
+++ Jifty-DBI/branches/tisql/inc/Module/Install/Fetch.pm	Wed Jul 30 16:33:00 2008
@@ -6,7 +6,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.67';
+	$VERSION = '0.68';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }

Modified: Jifty-DBI/branches/tisql/inc/Module/Install/Include.pm
==============================================================================
--- Jifty-DBI/branches/tisql/inc/Module/Install/Include.pm	(original)
+++ Jifty-DBI/branches/tisql/inc/Module/Install/Include.pm	Wed Jul 30 16:33:00 2008
@@ -6,7 +6,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.67';
+	$VERSION = '0.68';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }

Modified: Jifty-DBI/branches/tisql/inc/Module/Install/Makefile.pm
==============================================================================
--- Jifty-DBI/branches/tisql/inc/Module/Install/Makefile.pm	(original)
+++ Jifty-DBI/branches/tisql/inc/Module/Install/Makefile.pm	Wed Jul 30 16:33:00 2008
@@ -7,7 +7,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.67';
+	$VERSION = '0.68';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }

Modified: Jifty-DBI/branches/tisql/inc/Module/Install/Metadata.pm
==============================================================================
--- Jifty-DBI/branches/tisql/inc/Module/Install/Metadata.pm	(original)
+++ Jifty-DBI/branches/tisql/inc/Module/Install/Metadata.pm	Wed Jul 30 16:33:00 2008
@@ -6,7 +6,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.67';
+	$VERSION = '0.68';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }

Modified: Jifty-DBI/branches/tisql/inc/Module/Install/Win32.pm
==============================================================================
--- Jifty-DBI/branches/tisql/inc/Module/Install/Win32.pm	(original)
+++ Jifty-DBI/branches/tisql/inc/Module/Install/Win32.pm	Wed Jul 30 16:33:00 2008
@@ -6,7 +6,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.67';
+	$VERSION = '0.68';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }

Modified: Jifty-DBI/branches/tisql/inc/Module/Install/WriteAll.pm
==============================================================================
--- Jifty-DBI/branches/tisql/inc/Module/Install/WriteAll.pm	(original)
+++ Jifty-DBI/branches/tisql/inc/Module/Install/WriteAll.pm	Wed Jul 30 16:33:00 2008
@@ -6,7 +6,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.67';
+	$VERSION = '0.68';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }

Modified: Jifty-DBI/branches/tisql/lib/Jifty/DBI.pm
==============================================================================
--- Jifty-DBI/branches/tisql/lib/Jifty/DBI.pm	(original)
+++ Jifty-DBI/branches/tisql/lib/Jifty/DBI.pm	Wed Jul 30 16:33:00 2008
@@ -2,7 +2,7 @@
 use warnings;
 use strict;
 
-$Jifty::DBI::VERSION = '0.49';
+$Jifty::DBI::VERSION = '0.52';
 
 =head1 NAME
 
@@ -205,7 +205,7 @@
 
 =head1 LICENSE
 
-Jifty::DBI is Copyright 2005-2007 Best Practical Solutions, LLC.
+Jifty::DBI is Copyright 2005-2008 Best Practical Solutions, LLC.
 Jifty::DBI is distributed under the same terms as Perl itself.
 
 =cut

Modified: Jifty-DBI/branches/tisql/lib/Jifty/DBI/Collection.pm
==============================================================================
--- Jifty-DBI/branches/tisql/lib/Jifty/DBI/Collection.pm	(original)
+++ Jifty-DBI/branches/tisql/lib/Jifty/DBI/Collection.pm	Wed Jul 30 16:33:00 2008
@@ -7,6 +7,7 @@
 use overload (
     '@{}'       => \&items_array_ref,
     '<>'        => \&next,
+    bool        => sub {shift},
     fallback    => 1
 );
 
@@ -769,11 +770,11 @@
                 = $classname->new( $self->_new_collection_args )->new_item;
             my $right_alias = $self->new_alias($item);
             $self->join(
-                type    => 'left',
-                alias1  => $last_alias,
-                column1 => 'id',
-                alias2  => $right_alias,
-                column2 => $column->by || 'id',
+                type        => 'left',
+                alias1      => $last_alias,
+                column1     => 'id',
+                alias2      => $right_alias,
+                column2     => $column->by || 'id',
                 is_distinct => 1,
             );
             $last_alias = $right_alias;
@@ -781,11 +782,11 @@
             my $item        = $classname->new( $self->_new_record_args );
             my $right_alias = $self->new_alias($item);
             $self->join(
-                type    => 'left',
-                alias1  => $last_alias,
-                column1 => $name,
-                alias2  => $right_alias,
-                column2 => $column->by || 'id',
+                type        => 'left',
+                alias1      => $last_alias,
+                column1     => $name,
+                alias2      => $right_alias,
+                column2     => $column->by || 'id',
                 is_distinct => 1,
             );
             $last_alias = $right_alias;
@@ -858,7 +859,7 @@
 
 sub do_search {
     my $self = shift;
-    return              if $self->derived;
+    return if $self->derived;
     $self->_do_search() if $self->{'must_redo_search'};
 
 }
@@ -1149,6 +1150,12 @@
 IN matches a column within a set of values.  The value specified in the limit
 should be an array reference of values.
 
+=item "IS"
+
+=item "IS NOT"
+
+This is useful for when you wish to match columns that contain NULL (or ones that don't). Use this operator and a value of "NULL".
+
 =back
 
 =item escape
@@ -1190,6 +1197,59 @@
 
     return if $self->derived;
 
+    #If we're performing a left join, we really want the alias to be the
+    #left join criterion.
+
+    if (   ( defined $args{'leftjoin'} )
+        && ( not defined $args{'alias'} ) )
+    {
+        $args{'alias'} = $args{'leftjoin'};
+    }
+
+    # {{{ if there's no alias set, we need to set it
+
+    unless ( defined $args{'alias'} ) {
+
+        #if the table we're looking at is the same as the main table
+        if ( $args{'table'} eq $self->table ) {
+
+            # TODO this code assumes no self joins on that table.
+            # if someone can name a case where we'd want to do that,
+            # I'll change it.
+
+            $args{'alias'} = 'main';
+        }
+
+        else {
+            $args{'alias'} = $self->new_alias( $args{'table'} );
+        }
+    }
+
+    # }}}
+
+    # Set this to the name of the column and the alias, unless we've been
+    # handed a subclause name
+
+    my $qualified_column
+        = $args{'alias'}
+        ? $args{'alias'} . "." . $args{'column'}
+        : $args{'column'};
+    my $clause_id = $args{'subclause'} || $qualified_column;
+
+    # XXX: when is column_obj undefined?
+    my $class
+        = $self->{joins}{ $args{alias} }
+        && $self->{joins}{ $args{alias} }{class}
+        ? $self->{joins}{ $args{alias} }{class}
+        ->new( $self->_new_collection_args )
+        : $self;
+    my $column_obj = $class->new_item()->column( $args{column} );
+
+    $self->record_class->new(handle => $self->_handle)->_apply_input_filters(
+        column    => $column_obj,
+        value_ref => \$args{'value'},
+    ) if $column_obj && $column_obj->encode_on_select;
+
     # make passing in an object DTRT
     my $value_ref = ref( $args{value} );
     if ($value_ref) {
@@ -1242,45 +1302,6 @@
         $args{'escape'} = 'ESCAPE ' . $self->_quote_value( $args{escape} );
     }
 
-    #If we're performing a left join, we really want the alias to be the
-    #left join criterion.
-
-    if (   ( defined $args{'leftjoin'} )
-        && ( not defined $args{'alias'} ) )
-    {
-        $args{'alias'} = $args{'leftjoin'};
-    }
-
-    # {{{ if there's no alias set, we need to set it
-
-    unless ( defined $args{'alias'} ) {
-
-        #if the table we're looking at is the same as the main table
-        if ( $args{'table'} eq $self->table ) {
-
-            # TODO this code assumes no self joins on that table.
-            # if someone can name a case where we'd want to do that,
-            # I'll change it.
-
-            $args{'alias'} = 'main';
-        }
-
-        else {
-            $args{'alias'} = $self->new_alias( $args{'table'} );
-        }
-    }
-
-    # }}}
-
-    # Set this to the name of the column and the alias, unless we've been
-    # handed a subclause name
-
-    my $qualified_column
-        = $args{'alias'}
-        ? $args{'alias'} . "." . $args{'column'}
-        : $args{'column'};
-    my $clause_id = $args{'subclause'} || $qualified_column;
-
     # If we're trying to get a leftjoin restriction, lets set
     # $restriction to point there. otherwise, lets construct normally
 
@@ -1295,11 +1316,6 @@
 
     # If it's a new value or we're overwriting this sort of restriction,
 
-    # XXX: when is column_obj undefined?
-    my $class = $self->{joins}{$args{alias}} && $self->{joins}{$args{alias}}{class} 
-      ? $self->{joins}{$args{alias}}{class}->new($self->_new_collection_args)
-      : $self;
-    my $column_obj = $class->new_item()->column( $args{column} );
     my $case_sensitive = $column_obj ? $column_obj->case_sensitive : 0;
     $case_sensitive = $args{'case_sensitive'}
         if defined $args{'case_sensitive'};
@@ -1309,8 +1325,8 @@
         && !$case_sensitive )
     {
 
-        # don't worry about case for numeric columns_in_db
-        if ( defined $column_obj ? $column_obj->is_string : 1 ) {
+# don't worry about case for numeric columns_in_db - only be case insensitive when we KNOW it's a blob
+        if ( defined $column_obj ? $column_obj->is_string : 0 ) {
             ( $qualified_column, $args{'operator'}, $args{'value'} )
                 = $self->_handle->_make_clause_case_insensitive(
                 $qualified_column, $args{'operator'}, $args{'value'} );
@@ -1363,6 +1379,35 @@
 will probably change in the near future, but its presence allows for
 arbitrarily complex queries.
 
+Here's an example, to construct a SQL WHERE clause roughly equivalent to (depending on your SQL dialect):
+
+  parent = 12 AND task_type = 'action' 
+      AND (status = 'open' 
+          OR (status = 'done' 
+              AND completed_on >= '2008-06-26 11:39:22'))
+
+You can use sub-clauses and C<open_paren> and C<close_paren> as follows:
+
+  $col->limit( column => 'parent', value => 12 );
+  $col->limit( column => 'task_type', value => 'action' );
+
+  $col->open_paren("my_clause");
+
+  $col->limit( subclause => "my_clause", column => 'status', value => 'open' );
+
+  $col->open_paren("my_clause");
+
+  $col->limit( subclause => "my_clause", column => 'status', 
+      value => 'done', entry_aggregator => 'OR' );
+  $col->limit( subclause => "my_clause", column => 'completed_on',
+      operator => '>=', value => '2008-06-26 11:39:22' );
+
+  $col->close_paren("my_clause");
+
+  $col->close_paren("my_clause");
+
+Where the C<"my_clause"> can be any name you choose.
+
 =cut
 
 sub open_paren {
@@ -1437,7 +1482,9 @@
             unless ( ref $entry ) {
                 $result .= ' ' . $entry . ' ';
             } else {
-                $result .= join ' ', grep { defined } @{$entry}{qw(column operator value escape)};
+                $result .= join ' ',
+                    grep {defined}
+                    @{$entry}{qw(column operator value escape)};
             }
         }
         $result .= ')';
@@ -1544,6 +1591,18 @@
     return ( $self->{'order_by'} || [] );
 }
 
+=head2 clear_order_by
+
+Clears whatever would normally get set in the ORDER BY clause.
+
+=cut
+
+sub clear_order_by {
+    my $self = shift;
+
+    $self->{'order_by'} = [];
+}
+
 =head2 _order_clause
 
 returns the ORDER BY clause for the search.
@@ -1686,9 +1745,10 @@
     my $self = shift;
     my $refers_to = shift || die "Missing parameter";
     my $table;
-
+    my $class = undef;
     if ( $refers_to->can('table') ) {
         $table = $refers_to->table;
+        $class = $refers_to;
     } else {
         $table = $refers_to;
     }
@@ -1696,9 +1756,10 @@
     my $alias = $self->_get_alias($table);
 
     $self->{'joins'}{$alias} = {
-        alias        => $alias,
-        table        => $table,
-        type         => 'CROSS',
+        alias => $alias,
+        table => $table,
+        type  => 'CROSS',
+        ( $class ? ( class => $class ) : () ),
         alias_string => " CROSS JOIN $table $alias ",
     };
 
@@ -1794,9 +1855,10 @@
         ->current_page( $args{'current_page'} );
 
     $self->rows_per_page( $args{'per_page'} );
-    # We're not using $pager->first because it automatically does a count_all 
+
+    # We're not using $pager->first because it automatically does a count_all
     # to correctly return '0' for empty collections
-    $self->first_row(($args{'current_page'} - 1) * $args{'per_page'} + 1);
+    $self->first_row( ( $args{'current_page'} - 1 ) * $args{'per_page'} + 1 );
 
 }
 

Modified: Jifty-DBI/branches/tisql/lib/Jifty/DBI/Column.pm
==============================================================================
--- Jifty-DBI/branches/tisql/lib/Jifty/DBI/Column.pm	(original)
+++ Jifty-DBI/branches/tisql/lib/Jifty/DBI/Column.pm	Wed Jul 30 16:33:00 2008
@@ -30,6 +30,7 @@
     case_sensitive
     private
     protected
+    encode_on_select
     /;
 
 # these actually live in the attributes hash
@@ -59,7 +60,7 @@
 
 =head1 NAME
 
-Jifty::DBI::Column
+Jifty::DBI::Column - Encapsulate's a single column in a Jifty::DBI::Record table
 
 =head1 DESCRIPTION
 

Modified: Jifty-DBI/branches/tisql/lib/Jifty/DBI/Filter.pm
==============================================================================
--- Jifty-DBI/branches/tisql/lib/Jifty/DBI/Filter.pm	(original)
+++ Jifty-DBI/branches/tisql/lib/Jifty/DBI/Filter.pm	Wed Jul 30 16:33:00 2008
@@ -4,7 +4,7 @@
 package Jifty::DBI::Filter;
 use base 'Class::Accessor::Fast';
 
-__PACKAGE__->mk_accessors(qw(record column value_ref));
+__PACKAGE__->mk_accessors(qw(record column value_ref handle));
 
 =head1 NAME
 
@@ -52,7 +52,7 @@
 
 =head2 new
 
-Takes two arguments in a parameter hash:
+Takes three arguments in a parameter hash:
 
 =over
 
@@ -67,6 +67,11 @@
 A L<Jifty::DBI::Column> object, whatever sort of column we're working
 with here.
 
+=item handle
+
+A L<Jifty::DBI::Handle> object, because some filters (ie
+L<Jifty::DBI::Filter::Boolean>) depend on what database system is being used.
+
 =back
 
 =cut
@@ -76,6 +81,7 @@
     my %args  = (
         column    => undef,
         value_ref => undef,
+        handle    => undef,
         @_
     );
     my $self = {};

Added: Jifty-DBI/branches/tisql/lib/Jifty/DBI/Filter/Boolean.pm
==============================================================================
--- (empty file)
+++ Jifty-DBI/branches/tisql/lib/Jifty/DBI/Filter/Boolean.pm	Wed Jul 30 16:33:00 2008
@@ -0,0 +1,101 @@
+package Jifty::DBI::Filter::Boolean;
+
+use warnings;
+use strict;
+
+use base 'Jifty::DBI::Filter';
+
+use constant TRUE_VALUES  => qw(1 t true y yes TRUE);
+use constant FALSE_VALUES => ('', qw(0 f false n no FALSE));
+
+sub _is_true {
+    my $self = shift;
+    my $value = shift;
+
+    no warnings 'uninitialized';
+
+    for ($self->TRUE_VALUES, map { "'$_'" } $self->TRUE_VALUES) {
+        return 1 if $value eq $_;
+    }
+
+    return 0;
+}
+
+sub _is_false {
+    my $self = shift;
+    my $value = shift;
+
+    return 1 if not defined $value;
+
+    for ($self->FALSE_VALUES, map { "'$_'" } $self->FALSE_VALUES) {
+        return 1 if $value eq $_;
+    }
+
+    return 0;
+}
+
+=head1 NAME
+
+Jifty::DBI::Filter::Boolean - Encodes booleans
+
+=head1 DESCRIPTION
+
+=head2 decode
+
+Transform the value into 1 or 0 so Perl's concept of the boolean's value agrees
+with the database's concept of the boolean's value. (For example, 't' and 'f'
+might be used -- 'f' is true in Perl)
+
+=cut
+
+sub decode {
+    my $self = shift;
+    my $value_ref = $self->value_ref;
+
+    return unless defined $$value_ref;
+
+    if ($self->_is_true($$value_ref)) {
+        $$value_ref = 1;
+    }
+    elsif ($self->_is_false($$value_ref)) {
+        $$value_ref = 0;
+    }
+    else {
+        $self->handle->log("The value '$$value_ref' does not look like a boolean. Defaulting to false.");
+        $$value_ref = 0;
+    }
+}
+
+=head2 encode
+
+Transform the value to the canonical true or false value as expected by the
+database.
+
+=cut
+
+sub encode {
+    my $self = shift;
+    my $value_ref = $self->value_ref;
+
+    return unless defined $$value_ref or $self->column->mandatory;
+    return if uc $$value_ref eq "NULL" and not $self->column->mandatory;
+
+    if ($self->_is_true($$value_ref)) {
+        $$value_ref = $self->handle->canonical_true;
+    }
+    elsif ($self->_is_false($$value_ref)) {
+        $$value_ref = $self->handle->canonical_false;
+    }
+    else {
+        $self->handle->log("The value '$$value_ref' does not look like a boolean. Defaulting to false.");
+        $$value_ref = $self->handle->canonical_false;
+    }
+}
+
+=head1 SEE ALSO
+
+L<Jifty::DBI::Filter>
+
+=cut
+
+1;

Modified: Jifty-DBI/branches/tisql/lib/Jifty/DBI/Filter/DateTime.pm
==============================================================================
--- Jifty-DBI/branches/tisql/lib/Jifty/DBI/Filter/DateTime.pm	(original)
+++ Jifty-DBI/branches/tisql/lib/Jifty/DBI/Filter/DateTime.pm	Wed Jul 30 16:33:00 2008
@@ -41,7 +41,9 @@
 __PACKAGE__->mk_classdata("_formatter");
 sub formatter {
     my $self = shift;
-    unless ($self->_formatter) {
+    if ( not $self->_formatter
+          or $self->_formatter->pattern ne $self->_strptime )
+    {
          $self->_formatter(DateTime::Format::Strptime->new(pattern => $self->_strptime));
     }
     return $self->_formatter;

Added: Jifty-DBI/branches/tisql/lib/Jifty/DBI/Filter/URI.pm
==============================================================================
--- (empty file)
+++ Jifty-DBI/branches/tisql/lib/Jifty/DBI/Filter/URI.pm	Wed Jul 30 16:33:00 2008
@@ -0,0 +1,55 @@
+#!/usr/bin/env perl
+package Jifty::DBI::Filter::URI;
+use strict;
+use warnings;
+
+use base 'Jifty::DBI::Filter';
+use URI;
+
+=head1 NAME
+
+Jifty::DBI::Filter::URI - Encodes uniform resource identifiers
+
+=head1 DESCRIPTION
+
+=head2 encode
+
+If the value is a L<URI>, encode it to its string
+form. Otherwise, do nothing.
+
+=cut
+
+sub encode {
+    my $self = shift;
+
+    my $value_ref = $self->value_ref;
+    return unless ref $$value_ref and $$value_ref->isa('URI');
+
+    $$value_ref = $$value_ref->as_string;
+    return 1;
+}
+
+=head2 decode
+
+If value is defined, then decode it using
+L<URI/as_string>, otherwise do nothing.
+
+=cut
+
+sub decode {
+    my $self = shift;
+
+    my $value_ref = $self->value_ref;
+    return unless defined $$value_ref and length $$value_ref;
+
+    $$value_ref = URI->new($$value_ref);
+}
+
+=head1 SEE ALSO
+
+L<Jifty::DBI::Filter>, L<URI>
+
+=cut
+
+1;
+

Modified: Jifty-DBI/branches/tisql/lib/Jifty/DBI/Handle.pm
==============================================================================
--- Jifty-DBI/branches/tisql/lib/Jifty/DBI/Handle.pm	(original)
+++ Jifty-DBI/branches/tisql/lib/Jifty/DBI/Handle.pm	Wed Jul 30 16:33:00 2008
@@ -88,6 +88,7 @@
         user       => undef,
         password   => undef,
         requiressl => undef,
+        extra      => {},
         @_
     );
 
@@ -109,7 +110,7 @@
     if ( ( !$self->dbh ) || ( !$self->dbh->ping ) || ( $self->dsn ne $dsn ) )
     {
         my $handle
-            = DBI->connect( $self->dsn, $args{'user'}, $args{'password'} )
+            = DBI->connect( $self->dsn, $args{'user'}, $args{'password'}, $args{'extra'} )
             || Carp::croak "Connect Failed $DBI::errstr\n";
 
 #databases do case conversion on the name of columns returned.
@@ -196,6 +197,7 @@
 
     delete $args{'user'};
     delete $args{'password'};
+    delete $args{'extra'};
 
     $self->{'dsn'} = "dbi:$driver:"
         . CORE::join( ';',
@@ -794,6 +796,10 @@
 #unless ($TRANSDEPTH) {Carp::confess("Attempted to rollback a transaction with none in progress")};
     if ($force) {
         $TRANSDEPTH = 0;
+
+        Jifty::DBI::Record->flush_cache
+            if Jifty::DBI::Record->can('flush_cache');
+
         return ( $dbh->rollback );
     }
 
@@ -808,7 +814,10 @@
         return $TRANSDEPTH;
     }
 
-    my $rv = $self->dbh->rollback;
+    Jifty::DBI::Record->flush_cache
+        if Jifty::DBI::Record->can('flush_cache');
+
+    my $rv = $dbh->rollback;
     if ($rv) {
         $TRANSDEPTH--;
     }
@@ -932,7 +941,7 @@
                 @args{qw/alias1 alias2/}   = @args{qw/alias2 alias1/};
                 @args{qw/column1 column2/} = @args{qw/column2 column1/};
 
-                return $self->Jifty::DBI::Collection::limit(
+                return $args{'collection'}->limit(
                     entry_aggregator => 'AND',
                     @_,
                     quote_value => 0,
@@ -1101,7 +1110,7 @@
         # left joins on the left side so later we'll get 1 AND x expression
         # which equal to x, so we just skip it
         next if $join->{'type'} eq 'LEFT';
-        next unless $join->{'depends_on'} eq $args{'alias'};
+        next unless $join->{'depends_on'} && ($join->{'depends_on'} eq $args{'alias'});
 
         my @tmp = map { ( '(', @$_, ')', $join->{'entry_aggregator'} ) }
             values %{ $join->{'criteria'} };
@@ -1258,6 +1267,28 @@
 
 }
 
+=head2 canonical_true
+
+This returns the canonical true value for this database. For example, in SQLite
+it is 1 but in Postgres it is 't'.
+
+The default is 1.
+
+=cut
+
+sub canonical_true { 1 }
+
+=head2 canonical_false
+
+This returns the canonical false value for this database. For example, in SQLite
+it is 0 but in Postgres it is 'f'.
+
+The default is 0.
+
+=cut
+
+sub canonical_false { 0 }
+
 =head2 DESTROY
 
 When we get rid of the L<Jifty::DBI::Handle>, we need to disconnect

Modified: Jifty-DBI/branches/tisql/lib/Jifty/DBI/Handle/Pg.pm
==============================================================================
--- Jifty-DBI/branches/tisql/lib/Jifty/DBI/Handle/Pg.pm	(original)
+++ Jifty-DBI/branches/tisql/lib/Jifty/DBI/Handle/Pg.pm	Wed Jul 30 16:33:00 2008
@@ -236,6 +236,22 @@
     }
 }
 
+=head2 canonical_true
+
+The canonical true value in Postgres is 't'.
+
+=cut
+
+sub canonical_true { 't' }
+
+=head2 canonical_false
+
+The canonical false value in Postgres is 'f'.
+
+=cut
+
+sub canonical_false { 'f' }
+
 1;
 
 __END__

Modified: Jifty-DBI/branches/tisql/lib/Jifty/DBI/Handle/SQLite.pm
==============================================================================
--- Jifty-DBI/branches/tisql/lib/Jifty/DBI/Handle/SQLite.pm	(original)
+++ Jifty-DBI/branches/tisql/lib/Jifty/DBI/Handle/SQLite.pm	Wed Jul 30 16:33:00 2008
@@ -90,6 +90,15 @@
 
 }
 
+sub _make_clause_case_insensitive {
+    my $self     = shift;
+    my $column   = shift;
+    my $operator = shift;
+    my $value    = shift;
+    return("$column COLLATE NOCASE", $operator, $value);
+}
+
+
 1;
 
 __END__

Modified: Jifty-DBI/branches/tisql/lib/Jifty/DBI/Record.pm
==============================================================================
--- Jifty-DBI/branches/tisql/lib/Jifty/DBI/Record.pm	(original)
+++ Jifty-DBI/branches/tisql/lib/Jifty/DBI/Record.pm	Wed Jul 30 16:33:00 2008
@@ -599,8 +599,6 @@
     return ( $self->COLUMNS || {} );
 }
 
-# sub {{{ readable_attributes
-
 =head2 readable_attributes
 
 Returns a list this table's readable columns
@@ -1068,6 +1066,11 @@
                 $value = $value->id;
             }
 
+            $self->_apply_input_filters(
+                column    => $column_obj,
+                value_ref => \$value,
+            ) if $column_obj->encode_on_select;
+
             # if the handle is in a case_sensitive world and we need to make
             # a case-insensitive query
             if ( $self->_handle->case_sensitive && $value ) {
@@ -1363,13 +1366,17 @@
             and not ref $column->default )
         {
             $attribs{ $column->name } = $column->default;
+
+            $self->_apply_input_filters(
+                column    => $column,
+                value_ref => \$attribs{ $column->name },
+            );
         }
 
         if (    not defined $attribs{ $column->name }
             and $column->mandatory
             and $column->type ne "serial" )
         {
-
             # Enforce "mandatory"
             Carp::carp "Did not supply value for mandatory column "
                 . $column->name;
@@ -1569,6 +1576,7 @@
             record    => $self,
             column    => $args{'column'},
             value_ref => $args{'value_ref'},
+            handle    => $self->_handle,
         );
 
         # XXX TODO error proof this
@@ -1625,7 +1633,8 @@
 
     my ( $ret, $value_ref ) = $self->_run_callback(
         name => "canonicalize_" . $args{'column'},
-        args => $args{'value'}
+        args => $args{'value'},
+        short_circuit => 0,
     );
     return unless defined $ret;
     return (
@@ -1647,6 +1656,8 @@
     my $method = "canonicalize_$key";
     if ( $self->can($method) ) {
         return 1;
+    } elsif ( Class::Trigger::__fetch_all_triggers($self, $method) ) {
+        return 1;
     } else {
         return undef;
     }
@@ -1688,7 +1699,10 @@
 sub has_validator_for_column {
     my $self = shift;
     my $key  = shift;
-    if ( $self->can( "validate_" . $key ) ) {
+    my $method = "validate_$key";
+    if ( $self->can( $method ) ) {
+        return 1;
+    } elsif ( Class::Trigger::__fetch_all_triggers($self, $method) ) {
         return 1;
     } else {
         return undef;
@@ -1700,6 +1714,7 @@
     my %args = (
         name => undef,
         args => undef,
+        short_circuit => 1,
         @_
     );
 
@@ -1709,7 +1724,7 @@
     if ( my $func = $self->can($method) ) {
         @results = $func->( $self, $args{args} );
         return ( wantarray ? ( undef, [ [@results] ] ) : undef )
-            unless $results[0];
+            if $args{short_circuit} and not $results[0];
     }
     $ret = $self->call_trigger( $args{'name'} => $args{args} );
     return (
@@ -1719,6 +1734,19 @@
     );
 }
 
+=head2 unload_value COLUMN
+
+Purges the cached value of COLUMN from the object, forcing it to be
+fetched from the database next time it is queried.
+
+=cut
+
+sub unload_value {
+    my $self = shift;
+    my $column = shift;
+    delete $self->{$_}{$column} for qw/values fetched decoded _prefetched/;
+}
+
 1;
 
 __END__

Modified: Jifty-DBI/branches/tisql/lib/Jifty/DBI/Schema.pm
==============================================================================
--- Jifty-DBI/branches/tisql/lib/Jifty/DBI/Schema.pm	(original)
+++ Jifty-DBI/branches/tisql/lib/Jifty/DBI/Schema.pm	Wed Jul 30 16:33:00 2008
@@ -378,12 +378,14 @@
         } else {
             warn "Error in $from: $refclass neither Record nor Collection. Perhaps it couldn't be loaded?";
         }
-    } elsif (my $handler = $column->attributes->{_init_handler}) {
-        $handler->($column, $from);
     } else {
         $column->type('varchar(255)') unless $column->type;
     }
 
+    if (my $handler = $column->attributes->{_init_handler}) {
+        $handler->($column, $from);
+    }
+
     $from->COLUMNS->{$name} = $column;
 
     # Heuristics: If we are called through Jifty::DBI::Schema, 
@@ -404,6 +406,28 @@
     }
 }
 
+__PACKAGE__->register_types(
+    boolean => sub {
+        encode_on_select is 1,
+        type is 'boolean',
+        filters are qw(Jifty::DBI::Filter::Boolean),
+        default is 'false',
+        render_as 'Checkbox',
+        _init_handler is sub {
+            my ($column, $from) = @_;
+            no strict 'refs';
+            Class::Trigger::add_trigger($from, name => "canonicalize_" . $column->name, callback => sub {
+                my ($self,$value) = @_;
+                $self->_apply_output_filters(
+                    column    => $column,
+                    value_ref => \$value,
+                );
+                return $value;
+            });
+        },
+    },
+);
+
 1;
 
 __END__

Modified: Jifty-DBI/branches/tisql/lib/Jifty/DBI/SchemaGenerator.pm
==============================================================================
--- Jifty-DBI/branches/tisql/lib/Jifty/DBI/SchemaGenerator.pm	(original)
+++ Jifty-DBI/branches/tisql/lib/Jifty/DBI/SchemaGenerator.pm	Wed Jul 30 16:33:00 2008
@@ -282,7 +282,7 @@
             {   name     => $column->name,
                 type     => $column->type,
                 null     => $column->mandatory ? 0 : 1,
-                default  => $column->default,
+                default  => $column->default ||'',
             }
             );
 

Modified: Jifty-DBI/branches/tisql/t/02-column_constraints.t
==============================================================================
--- Jifty-DBI/branches/tisql/t/02-column_constraints.t	(original)
+++ Jifty-DBI/branches/tisql/t/02-column_constraints.t	Wed Jul 30 16:33:00 2008
@@ -5,11 +5,12 @@
 use warnings;
 use File::Spec;
 use Test::More;# import => [qw(isa_ok skip plan)];
+use Test::Warn;
 
 BEGIN { require "t/utils.pl" }
 our (@available_drivers);
 
-use constant TESTS_PER_DRIVER => 7;
+use constant TESTS_PER_DRIVER => 9;
 
 my $total = scalar(@available_drivers) * TESTS_PER_DRIVER;
 plan tests => $total;
@@ -37,13 +38,21 @@
         ok($e_id, "Got an id for the new employee");
 
         # Test 'is mandatory'
-        $e_id = $emp->create( employee_num => '456' );
+        warning_like {
+            $e_id = $emp->create( employee_num => '456' );
+        } qr/^Did not supply value for mandatory column name/;
+
         ok(!$e_id, "Did not get an id for second new employee, good");
 
         # Test 'is distinct'
         $e_id = $emp->create( name => 'Foo', employee_num => '456' );
         ok($e_id, "Was able to create a second record successfully");
-        my $e_id2 = $emp->create( name => 'Bar', employee_num => '123' );
+        my $e_id2;
+
+        warning_like {
+            $e_id2 = $emp->create( name => 'Bar', employee_num => '123' );
+        } qr/^TestApp::Employee=HASH\(\w+\) failed a 'is_distinct' check for employee_num on 123/;
+
         ok(!$e_id2, "is_distinct prevents us from creating another record");
         my $obj = TestApp::Employee->new( handle => $handle );
         $obj->load( $e_id );

Modified: Jifty-DBI/branches/tisql/t/06filter.t
==============================================================================
--- Jifty-DBI/branches/tisql/t/06filter.t	(original)
+++ Jifty-DBI/branches/tisql/t/06filter.t	Wed Jul 30 16:33:00 2008
@@ -4,7 +4,7 @@
 
 use Test::More;
 BEGIN { require "t/utils.pl" }
-plan tests => 6;
+plan tests => 7;
 # test for Jifty::DBI::Filter class only
 # create new t/06filter_*.t files for specific filters
 
@@ -14,6 +14,7 @@
 isa_ok( $filter, 'Jifty::DBI::Filter' );
 is( $filter->column, undef, "empty column value" );
 is( $filter->value_ref, undef, "empty value reference" );
+is( $filter->handle, undef, "empty handle" );
 
 $filter->column( 'my column' );
 is( $filter->column, 'my column', "successfuly set column" );

Added: Jifty-DBI/branches/tisql/t/06filter_boolean.t
==============================================================================
--- (empty file)
+++ Jifty-DBI/branches/tisql/t/06filter_boolean.t	Wed Jul 30 16:33:00 2008
@@ -0,0 +1,181 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+use Test::More;
+BEGIN { require "t/utils.pl" }
+our (@available_drivers);
+
+use constant TESTS_PER_DRIVER => 136;
+
+my $total = scalar(@available_drivers) * TESTS_PER_DRIVER;
+plan tests => $total;
+
+my @true  = qw/1 t true y yes TRUE/;
+my @false = qw/0 f false n no FALSE/;
+
+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', 'init schema');
+    }
+
+    my @values = (
+        ( map { [$_, 'true']  } @true  ),
+        ( map { [$_, 'false'] } @false ),
+    );
+
+    for my $value ( @values, [undef, 'false'] ) {
+        my ($input, $bool) = @$value;
+
+        my $rec = TestApp::User->new( handle => $handle );
+        isa_ok($rec, 'Jifty::DBI::Record');
+
+        my ($id) = $rec->create( defined($input) ? (my_data => $input) : () );
+        ok($id, 'created record');
+        ok($rec->load($id), 'loaded record');
+        is($rec->id, $id, 'record id matches');
+
+        is($rec->my_data, $bool eq 'true' ? 1 : 0, 'Perl agrees with the expected boolean value');
+
+        if ($d eq 'Pg') {
+            # this option tells DBD::Pg to keep booleans as 't' and 'f' and not
+            # map them to 1 and 0
+            $handle->dbh->{pg_bool_tf} = 1;
+        }
+
+        my $sth = $handle->simple_query("SELECT my_data FROM users WHERE id = $id");
+        my ($got) = $sth->fetchrow_array;
+
+        my $method = "canonical_$bool";
+        is( $got, $handle->$method, "my_data bool match for " . (defined($input) ? $input : 'undef') . " ($bool)" );
+
+        if ($d eq 'Pg') {
+            $handle->dbh->{pg_bool_tf} = 0;
+        }
+
+        # undef/NULL
+        $rec->set_my_data;
+        is($rec->my_data, undef, 'set undef value');
+
+        $rec->set_my_data($input);
+        ok($bool eq 'true' ? $rec->my_data : !$rec->my_data, 'Perl agrees with the expected boolean value');
+    }
+
+    for my $value ( @values ) {
+        my ($input, $bool) = @$value;
+        my $rec = TestApp::User->new( handle => $handle );
+        $rec->load_by_cols(
+            my_data => $input,
+        );
+        ok($rec->id, "loaded a record by boolean value '$input'");
+
+        my $col = TestApp::UserCollection->new( handle => $handle );
+        $col->limit(
+            column => 'my_data',
+            value  => $input,
+        );
+        if ($col->count) {
+            ok($bool eq 'true' ? $col->first->my_data : !$col->first->my_data, 'Perl agrees with the expected boolean value');
+        }
+        else {
+            fail("Got no results from limit");
+        }
+    }
+
+    # Test undef for boolean columns marked mandatory
+    my $rec = TestApp::User->new( handle => $handle );
+    my ($id) = $rec->create();
+    ok($id, 'created record');
+    ok($rec->load($id), 'loaded record');
+    is($rec->id, $id, 'record id matches');
+    is($rec->other_data, 0, 'default mandatory column is false, not undef');
+
+    $rec->set_other_data(1);
+    is($rec->other_data, 1, 'mandatory column is now true');
+    
+    $rec->set_other_data(undef);
+    is($rec->other_data, 0, 'mandatory column set to undef is now false, not undef');
+
+    cleanup_schema('TestApp', $handle);
+    disconnect_handle($handle);
+}
+}
+
+package TestApp::User;
+use base qw/ Jifty::DBI::Record /;
+
+sub schema_sqlite {
+
+<<EOF;
+CREATE table users (
+    id integer primary key,
+    my_data boolean,
+    other_data boolean not null
+)
+EOF
+
+}
+
+sub schema_mysql {
+
+<<EOF;
+CREATE TEMPORARY table users (
+    id integer auto_increment primary key,
+    my_data boolean,
+    other_data boolean not null
+)
+EOF
+
+}
+
+sub schema_pg {
+
+<<EOF;
+CREATE TEMPORARY table users (
+    id serial primary key,
+    my_data boolean,
+    other_data boolean not null
+)
+EOF
+
+}
+
+BEGIN {
+    use Jifty::DBI::Schema;
+
+    use Jifty::DBI::Record schema {
+    column my_data =>
+        is boolean;
+
+    column other_data =>
+        is boolean,
+        is mandatory;
+    }
+}
+
+package TestApp::UserCollection;
+
+use base qw/Jifty::DBI::Collection/;
+
+sub _init {
+    my $self = shift;
+    $self->SUPER::_init(@_);
+    $self->table('users');
+}
+

Modified: Jifty-DBI/branches/tisql/t/13collection.t
==============================================================================
--- Jifty-DBI/branches/tisql/t/13collection.t	(original)
+++ Jifty-DBI/branches/tisql/t/13collection.t	Wed Jul 30 16:33:00 2008
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 7;
+use Test::More tests => 8;
 
 my $package;
 BEGIN { 
@@ -123,3 +123,5 @@
    ' ORDER BY ab.msg_id DESC, main.yaks ASC ',
    "add_order_by works when passing a list-as-hash directly";
 
+$obj->clear_order_by;
+is($obj->_order_clause, '', "clear_order_by works");


More information about the Jifty-commit mailing list