Hi Davey,

I took a good look at your patch for a prototype ActiveRecord
implementation.

You might want to take a look at the implementation currently in branch
"DbTable-09".  I just committed a doc section for it today:
http://framework.zend.com/fisheye/browse/~raw,r=3781/Zend_Framework/bran
ch/DbTable-09/documentation/manual/en/module_specs/Zend_Db_Table-Relatio
nships.xml

The implementation currently in the branch actually shares a lot of
features with your implementation.  Here are some differences (not
necessarily a complete list):

Your implementation:
- find() method returns a Row or Rowset object, depending on whether you
give 1 arg or > 1 arg.
- findAll() and findFirst() methods support Boolean operators for
combining the array of where conditions.
- Supports a single custom Row and Rowset class per ActiveRecord class,
custom Row and Rowset classnames must be based on ActiveRecord
classname.
- Primary keys limited to a single column.
- Supports object vars for searching (how does one reset the object vars
back to an initial state?)
- "Roll back" (i.e. reset) Row members to clean data.
- Supports custom methods in Row per column, for filtering values during
__set().
- Uses inflectors to pluralize/singularize during the table
relationships query methods.

The implementation in the branch:
- The find() method always returns a Rowset object (see ZF-21).  Good
because it's easy to call exists() after find().
- Supports multi-column primary keys.
- No usage of inflectors.
- No object vars for searching.
- Supports any number of custom Row and Rowset classes per Table class.
- Supports queries against related tables, e.g. parent table, dependent
table, many-to-many table.  All queries support multi-column keys.
- Table class supports custom _insert(), _update(), _delete() filtering.
- Table relationship query methods can be either magic or non-magic
(non-magic is useful for tool support).

Your patch has a lot of good ideas, but there are some places where you
and I disagree:
- I don't think the find() method should return two different class
types depending on the arguments.
- I don't care for inflectors, or any manipulation of SQL identifiers.
You get into trouble if your database contains both spellings, e.g. Dog
and Dogs.  Or if the RDBMS uses case-sensitive identifiers, but the
framework is trying to apply camelcasing.  The only safe thing to do is
to use the spelling of SQL identifiers that the RDBMS uses.
- I prefer declaration of metadata, instead of imposing schema
conventions on developers.  There are plenty of frameworks that impose
conventions, which is great for new projects where the developer has the
freedom to design the database schema.  But Zend_Db could gain a very
valuable differentiator if it works with an existing database schema.

Regards,
Bill Karwin

> -----Original Message-----
> From: Davey Shafik [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, March 06, 2007 1:05 AM
> To: Bill Karwin
> Cc: Zend Framework
> Subject: Re: [fw-general] Zend Framework 0.9 code freeze schedule
> 
> Bill,
> 
> Yes, I did look at the proposals. I have also done as promised and
> written a fully fledged ORM :)
> 
> I have attached the files, they will unpack directly in the folder
> they are in, and should be placed
> in incubator/Zend/Db/
> 
> The ORM features as follows:
> 
> * Inflection based config, i.e. class Dogs extends
> Zend_Db_ActiveRecord { } == table "dogs"
> * Advanced "Find" methods:
>       - find($id)
>       - find($id, $id2, $id*)
>       - $obj->id = $id; $obj->find(); $obj->name = "foo";
$obj->find();
>       - findAll(array('column' => 'value'), (AND|OR))
>       - $obj->name = "bar"; $obj->findAll();
>       - findFirst(...) - same as findAll() but only returns a single
row
> * Ability to override _setUp() method to customize table name and PK
> column name (i.e. not inflection/reflection based)
> * Smart save() method will UPDATE or iNSERT as needed.
> * Ability to use 1:1 and 1:MANY relationships
>       - $row->getFoo() = 1:1 using class "Foos"
>       - $row->getAllFoos() = 1:MANY using class "Foos"
> * Ability to filter data when setting on the record, by doing:
>       class Foos_Row extends Zend_Db_ActiveRecord_Row {
>               function name($value)
>               {
>                       return ucwords($value);
>               }
>       }
> 
>       $foos_row_instance->name = "davey shafik"; // will save as
"Davey
> Shafik"
> * Ability to rollback to the original row data, or to last save() call
>       $row->rollback();
> * Duplicate rows using:
>       $duplicate = clone $original;
>       $duplicate->save();
> 
> And all this in just 584 LOC (including comments and whitespace :)
> 
> The only thing I would like to add, is the ability to pre-fetch
> relationships using JOINs by setting
> an option and looking for $this->*_id - then the getFoo() and
> getAllFoos() would just use the already
> fetched data.
> 
> There is an ActiveRecordExample.php in the zip file, and I also
> attached a SQL dump of the DB I'm using
> 
> - Davey

Reply via email to