Added by Simon Mundy, last edited by Wil Sinclair on May 14, 2008  (view change)

Labels

 
(None)

Zend Framework: Zend_Db_Table Enhancements Component Proposal

Proposed Component Name Zend_Db_Table Enhancements
Developer Notes http://framework.zend.com/wiki/display/ZFDEV/Zend_Db_Table Enhancements
Proposers Fabien MARTY
Eugene Panaitov
Simon Mundy
Darby Felton, Zend liaison
Revision 0.1 - 14 October 2006: Summary of community feedback on ZF Mailing list. (wiki revision: 7)

Table of Contents

1. Overview

This proposal summarises several requests on the mailing list and the issue tracker to provide enhancements to the Zend_Db_Table component. It is a response to Gavin Vess's request to formalise these enhancements and not meant to override or overlap any existing Db work already being performed. It's been posted here so that more focussed feedback can be given and to ensure these enhancements follow the established procedures for accepting ZF components.

2. References

3. Component Requirements, Constraints, and Acceptance Criteria

  • This component will allow developers to extend the capability of Zend_Db_Table rows and rowsets.
  • It will allow developers to specify a custom class for rowsets / rows in a Zend_Db_Table instance.
  • It will provide better ORM capabilities by allowing the possibility of chained queries and domain logic outside of the Db itself.
  • It will allow Zend_Db_Table_Row objects to be serialized (removing dependency on stored DB connections)
  • It will provide methods to allow custom pre-filtering of data for insertion/updates to the database.
  • It will allow arrays for primary keys (for composite keys on tables)

4. Dependencies on Other Framework Components

  • Zend_Db_Table
  • Zend_Db_Exception

5. Theory of Operation

The component allows developers to override the default class used for rowsets and rows, meaning that result sets for single rows or collections of rows may be instantiated with user-defined classes.

Custom rows can also have hooks to perform user-transformations to data before rows are inserted or updated. The empty _insert() and _update() methods are called before data is committed and operate directly on row data using transformed columns (e.g. if you had camelCaps enabled, you would set $this->clientListId = 3 rather than $this->client_list_id = 3).

To allow rows and rowsets to be serialized (as they can contain domain logic rather than simply hold database values), the database is not stored within the row or rowset instance and is instead accessed by querying an instance of the parent table. A reference to the parent table is provided as a classname so that a row can take advantage of lazy-loading.

Because tables can also have composite keys, the primary key will allow arrays, and this will be enforced during a 'find()' operation - if the primary key is an associative array, all keys must be assigned values in the find() method or an exception will be thrown.

The enforcement of 'camelCaps' and other case transformations will not be set by default, however the option to add these will remain. The method setColumnCase() will create a new column filter for a Zend_Db_Table and all rows/rowsets will inherit this transformation.

6. Milestones / Tasks

  • Milestone 1: Community discussion and initial acceptance by Zend Db team.
  • Milestone 2: Working prototype checked into the incubator.
  • Milestone 3: Unit tests exist, work, and are checked into SVN.
  • Milestone 4: Update existing documentation and use-cases.

7. Class Index

  • Zend_Db_Table
  • Zend_Db_Table_Rowset
  • Zend_Db_Table_Rowset_Abstract
  • Zend_Db_Table_Row
  • Zend_Db_Table_Row_Abstract

8. Use Cases

9. Class Skeletons

Hi,

I wonder if this is the right place for some thoughts to add some joining functionalities to Zend_Db. I just add them here anyway.

a) I would like to suggest to split the current _fetch() method up into two methods like this (stripped off the comments):

Now I could easily add a join in my classes which extend Zend_Db:

b) Nothing to do with joiningh, but I would also like to add a fetchCount() method to Zend_Db_Table to get the number of all records or the number for a specific where clause?

What do you think about these suggestions?

Best Regards,

Ralf

My implementation is:

We need to point to the loadClass function a list of directories where each successor of Zend_Db_Table_Row or Zend_Db_Table_RowSet can be found. I added
protected $_dirs = null;
variable

Unofficial comments ...

This "KISS" style of ORM has been a popular suggestion over the last few months on the mail lists. The team is focused on marching towards a 1.0. Due to time constraints, and the difficulty in obtaining approval for "incubator" with a proposal that is not required for ZF 1.0, I am recommending that this proposal at least be granted lab access to help get more exposure and make it easier for others to test, use, and hopefully improve it.

Posted by Gavin at Nov 13, 2006 20:06

That's great Gavin - I have a version with some updated Zend_Db_Table_xxx components that I could upload immediately. They're working quite well in a production environment but could do with some refactoring to allow caching of table structures, etc. Will publish when (if?) we get the lab account.

Hello.

We need a count method able to retrieve the number of records available in a table that will receive a $where parameter. If a user is filtering the list making a search then is not difficult to recreate pagination on the search results.

Something like:

/**

  • Count the available records that match a search criteria
    *
  • @param string $where
    */
    public function count($where)
    {
    $select = $this->_db->select();
    $select->from($this->_name,'COUNT('.$this->_primary.') AS number');

// the WHERE clause
$where = (array) $where;
foreach ($where as $key => $val) {
if (is_int($key))

Unknown macro: { $select->where($val); }
else
Unknown macro: { $select->where($key, $val); }

}
return $this->_db->fetchRow($select);
}

Zend Feedback
This proposal has been approved for laboratory development. Please continue to work together as a group on this project, discussing ideas together during development, and raise any issues in the ZF fw-db mail list.
Posted by Gavin at Dec 11, 2006 13:29

I'm trying to think why the Zend_Db_Table inherited classes are not singletons or even static. I don't see any reason to instantiate more than one (or even not instantiate at all) a "table".

I think it might be a good idea to use a method instead of a variable to determine what type should be returned by the fetch methods. This would allow you to use the fetch methods with STI (single table inheritance), much like Ruby On Rails polymorphic finds. For example:

Zend_Db_Table.php

Zend_Db_Table_RowSet.php

Example.php

It would probably be a good idea to implement a similar change in Zend_Db_Table::fetchAll() for getting a different type of Zend_Db_Table_RowSet object back as well, though this would not need to be polymorphic based on the return type.

Food for thought.

Quick bug catch:

protected function _determineClassName($data)

Unknown macro: {{/code}

This needs to be public, obviously.

May I ask how's the proposal going? Is there any possibility for the code being accepted and thrown into incubator anytime soon?

Hi Martel - I'll be uploading a set of classes to the Laboratory soon. Nothing yet in the incubator, though - I understand Bill's making a lot of other improvements and they may or may not have a similar implementation.

It looks like this proposal hasn't been active for quite a while. Has it been promoted or abandoned? I'm moving to the archived section. Please reparent to the correct section if the status has changed.

,Wil