[CDBI] DBIx::Class::CDBICompat unofficial alpha

Michael G Schwern schwern at pobox.com
Mon Jun 11 19:04:39 BST 2007


Several moons ago I posted that I was going to be doing some performance work
on Class::DBI.
http://lists.digitalcraftsmen.net/pipermail/classdbi/2007-February/001517.html

People pointed out that DBIx::Class has a lot of the features I needed and has
a CDBICompat library already.  Unfortunately, CDBICompat wasn't a good enough
emulator of CDBI to handle my existing app.  Still, DBIC's features and
performance proved enticing enough to improve CDBICompat.

After a few months of working on it on-and-off its now at a state that it can
handle my large, twisty CDBI app.  Before putting it into production I'd like
others to beat on it with a few sticks, see if they can shake out more
problems.  It currently resides in my local SVK repository but I'll be merging
it into the DBIC repo soon.
http://schwern.org/~schwern/src/DBIx-Class-0.07006_CDBICompat_01.tar.gz

I've attached my log so folks can get a feel for what's been done.

I must say, I'm impressed with the way Class::C3 and its next::method() allows
slicing up modules by feature and how it allows code to use a mix of CDBI and
DBIC behaviors.

There's a pile of new tests in CDBICompat that can be merged back into CDBI.
Also the CDBICompat tests are based on an old test suite and I need to merge
in the latest tests.


Here's the caveats about CDBICompat I've noted.

* You can no longer treat $obj->{column} and $obj->column as synonyms.

Its wrong, but you can get away with $obj->{column} in CDBI if you're sure the
columns have been fleshed out.  People do this to bypass lousy accessor
performance.  This will not work in CDBICompat, DBIC stores columns elsewhere.

This proved to be the single largest and most pervasive incompatibility.  If
anyone can think of a way to detect when $obj->{column} is accessed I'd like
to hear it.  Some sort of tricky self-tie maybe.  I'd also like to know if
anyone has an idea of how it can be emulated.


* The class' table or columns must be declared as early as possible.

CDBI does most of its work just-in-time.  DBIC does its setup early on.
CDBICompat uses table() and columns() to trigger DBIC's setup.  Without it,
nothing works.

A consequence of this is you need to declare a foreign table's table() and
columns() before you try to make a relationship with it.  This means you can't
put your relationship declarations in the same module as your table() and
columns() declarations which I find awkward.

This is the #2 incompatibility from where I stand.  Again, better ideas welcomed.


* insert() is no longer a way to get around an overriden create()

Foo isa CDBI.  Foo::create() exists.  But Foo->insert() calls
Class::DBI->insert.  This is a bug in CDBI that some people exploit to jump
over an overridden create().  It should probably be fixed in CDBI (change
*create = \&insert; to sub create { $self->insert(@_) }.  I fixed it in
CDBICompat and I think it should stay that way.


* $obj = $obj->retrieve($obj->id) will not necessarily give you a fresh
copy of the object.

If you want to clear out the object use $obj->discard_changes().  If your
object has special data and stuff, override discard_changes() to clear that
stuff out, too.

I'm not sure why this is so.  Better ideas welcomed.
-------------- next part --------------
----------------------------------------------------------------------
r31146:  schwern | 2007-06-06 13:43:49 -0700

Update MANIFEST with the new tests

Add maximum/minimum_value_of() to emulate CDBI.
----------------------------------------------------------------------
r31145:  schwern | 2007-06-05 07:19:18 -0700

Turns out it was CDBICompat's discard_changes() causing the problem with
relationships.  It had to clear _relationship_data.

Also figured out how to test it.
----------------------------------------------------------------------
r31144:  schwern | 2007-06-05 06:38:19 -0700

Ensure that _relationship_data is cleared out as part of discard_changes() so
relationships are reloaded from the database.  Unfortuately I don't have a
good test for this.
----------------------------------------------------------------------
r31143:  schwern | 2007-06-04 17:37:01 -0700

Fix the relationship accessor so it doesn't auto-vivify a related row
that doesn't exist.
----------------------------------------------------------------------
r31142:  schwern | 2007-06-04 17:35:44 -0700

find_or_new_related() would fail to recognize that it had found an object
if that object was false in a boolean context (ie. its overloaded).
----------------------------------------------------------------------
r31141:  schwern | 2007-06-03 18:38:25 -0700

Add __IDENTIFIER__ for CDBI compatibility.

Also, fix __ESSENTIAL__ when it has more than one column.
----------------------------------------------------------------------
r31125:  schwern | 2007-05-03 00:15:40 -0700

 r31122 at windhund:  schwern | 2007-05-03 00:05:27 -0700
 0.07006 from CPAN

----------------------------------------------------------------------
r31119:  schwern | 2007-04-13 08:37:23 -0700

Fix the behavior of CDBI iterators properly, with an override.
----------------------------------------------------------------------
r31118:  schwern | 2007-04-13 08:37:05 -0700

Revert the ResultSet boolean hack.

Document and test the overloaded behavior of ResultSet.

Call the overload methods as methods rather than function references so
they can be overriden by subclasses.
----------------------------------------------------------------------
r31117:  schwern | 2007-04-13 08:19:08 -0700

The CDBI iterator returns true/false based on if there's any results.
The DBIC iterator always returns true in boolean context.  I can't
figure out how to change it just in CDBICompat so I have to change DBIC as
a hack for now.
----------------------------------------------------------------------
r31116:  schwern | 2007-04-13 07:53:39 -0700

Objects made via new_result() were not marked as being in_storage() so they
would not look to the database to flesh themselves out.
----------------------------------------------------------------------
r31115:  schwern | 2007-04-11 13:32:12 -0700

Explicitly stringify things before setting to avoid weird overloading
problems of somewhat broken overloading objects.
----------------------------------------------------------------------
r31114:  schwern | 2007-04-11 13:00:30 -0700

CDBI->set() can set multiple values at once.  It can also take temp columns.

GetSet had to be moved after TempColumns in the chain so TempColumns->set()
could remove the temp data from the arguments before DBIC saw it and puked.
----------------------------------------------------------------------
r31113:  schwern | 2007-04-11 12:11:12 -0700

Add new test to MANIFEST
----------------------------------------------------------------------
r31112:  schwern | 2007-04-11 12:10:23 -0700

Fix CDBICompat so that accessor declarations (columns(), has_a()...) don't
override existing methods.
----------------------------------------------------------------------
r27904:  schwern | 2007-04-03 13:25:04 -0700

Add construct() to CDBICompat
----------------------------------------------------------------------
r27903:  schwern | 2007-04-03 13:10:23 -0700

Its perfectly kosher in CDBI to call discard_changes() in DESTROY.  Because
DBIC's discard_changes() reloads the object from the database, and then
throws it out, it causes a DESTROY and an infinite recursion.

Since CDBI has lazy loading there's no need to reload the object.  Just
blow away the changed rows and let the lazy loading fill them back in
again.

As we're not replacing the object any more when we discard it there's no
need to replace it in the live object cache.
----------------------------------------------------------------------
r27902:  schwern | 2007-04-03 13:07:52 -0700

Make sure you can serialize a DBIx::Class object even once it has things
like related_results that might contain CODE refs.
----------------------------------------------------------------------
r27893:  schwern | 2007-04-02 15:25:57 -0700

Needs to call init_schema() or else DBICTest::CD won't be loaded.
----------------------------------------------------------------------
r27892:  schwern | 2007-04-02 13:40:04 -0700

Allow the statement passed to retrieve_from_sql() to contain a simple LIMIT.
----------------------------------------------------------------------
r27868:  schwern | 2007-04-02 09:03:54 -0700

Allow declaring TEMP columns without a table.
----------------------------------------------------------------------
r27867:  schwern | 2007-04-02 08:57:12 -0700

No reason to have these SKIP blocks around anymore.
----------------------------------------------------------------------
r27866:  schwern | 2007-03-28 22:55:34 -0700

In CDBI insert() and create() are synonyms and called as a class method.
In DBIC insert() is an object method and create() a class method.  Fix
the CDBICompat layer so you can call insert() as a class method.
----------------------------------------------------------------------
r27865:  schwern | 2007-03-28 22:44:46 -0700

Add all the new stuff I've added in the MANIFEST.
----------------------------------------------------------------------
r27864:  schwern | 2007-03-20 19:31:10 -0700

Fix the "columns before table" patch so that a subclass inherits the
table name and columns of its parent.
----------------------------------------------------------------------
r27710:  schwern | 2007-03-16 20:07:33 -0700

Forgot to check this in.
----------------------------------------------------------------------
r27709:  schwern | 2007-03-16 19:57:11 -0700

In CDBI if you change the accessor name but not the mutator name the mutator
gets the accessor's name.
----------------------------------------------------------------------
r27708:  schwern | 2007-03-16 19:24:49 -0700

CDBI 3.0.7 decided to change "accessor_name" and "mutator_name" to "accessor_name_for" and "mutator_name_for".  CDBI continues to support the old names.  CDBICompat only supports the old name.
----------------------------------------------------------------------
r27707:  schwern | 2007-03-16 19:24:00 -0700

Add a test to ensure a where + limit works.
----------------------------------------------------------------------
r27701:  schwern | 2007-03-14 19:27:30 -0700

AbstractSearch compatibility layer.
----------------------------------------------------------------------
r27700:  schwern | 2007-03-14 19:20:46 -0700

Fix search so it can accept an offset without a limit.
----------------------------------------------------------------------
r27699:  schwern | 2007-03-14 19:19:50 -0700

Forgot to commit this test.
----------------------------------------------------------------------
r27685:  schwern | 2007-03-13 06:58:33 -0700

Add in the test libraries for the new has_many tests.
----------------------------------------------------------------------
r27684:  schwern | 2007-03-13 06:57:42 -0700

Allow has_many() to infer the foreign key from an existing has_a()
relationship as CDBI can do.
----------------------------------------------------------------------
r27422:  schwern | 2007-02-17 08:21:28 -0800

Increment the version for an alpha release for GSG.
----------------------------------------------------------------------
r27421:  schwern | 2007-02-17 08:21:17 -0800

Fix the CDBICompat so columns can be declared before the table.
----------------------------------------------------------------------
r27420:  schwern | 2007-02-17 05:57:57 -0800

Local copy of DBIx-Class
----------------------------------------------------------------------


More information about the ClassDBI mailing list