Bill,

First off, thank you for such a detailed comparison, this is great!!

I'll go through your list and say what I would like to bring to Zend_Db_ActiveRecord, and maybe we can move some of your work over and therefore have the name people expect
and provide a good implementation :)

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().

I agree on the Row Vs Rowset, I never *really* liked it :)

- Supports multi-column primary keys.

Honestly, I've never used this, so I missed this from AR, would love to see it moved in

- No usage of inflectors.

We could allow both?

- No object vars for searching.

I could easily add a cleanup method, or perhaps you could pass a Row with the
vars to find() ? I think both would be good :)

- Supports any number of custom Row and Rowset classes per Table class.

Great, I'd like to see this, but automated use of ARClass_Row(Set) would be
great too

- Supports queries against related tables, e.g. parent table, dependent
table, many-to-many table.  All queries support multi-column keys.

Obvously needs adding

- Table class supports custom _insert(), _update(), _delete() filtering.

I'm not sure what this would be used for, but lets bring it over :)

- Table relationship query methods can be either magic or non-magic
(non-magic is useful for tool support).

This would be good too


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.

Agreed

- I don't care for inflectors, or any manipulation of SQL identifiers.

The use is minimal, lets remove it :)

- 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.

I already have plans for this, and I agree, it should be possible to *easily*
wrap AR around an existing table that doesn't conform to our "norm", and
as I mentioned elsewhere, the way I would like to do this, is aliasing, that
allows your tables to have a consistent AR API regardless of the actual
schema beneath.

This is very important to me, actually, that the AR whilst it has a lot of
voodoo, should be easily overridden internally, and still provide
the same API when used.

- Davey


On Mar 7, 2007, at 4:13 AM, Bill Karwin wrote:

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