View Source

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{zone-template-instance:ZFDEV:Zend Proposal Zone Template}

{zone-data:component-name}
Zend_Db_Table Query Enhancements
{zone-data}

{zone-data:proposer-list}
[Simon Mundy|mailto:studio@peptolab.com]
[Darby Felton|mailto:darby@zend.com], Zend liaison
{zone-data}

{zone-data:revision}
0.1 - 1 August 2007: Initial proposal.
{zone-data}

{zone-data:overview}
This proposal aims to provide a more flexible, consistent and lean strategy for modifying queries derived around the Zend_Db_Table component. This includes the fetch/find methods from a Zend_Db_Table object as well as the relationship-based queries performed from a Zend_Db_Table_Row.
{zone-data}

{zone-data:references}
* Zend_Db_Select
* Zend_Db_Table_Row
* Zend_Db_Table_Row_Abstract
* [Existing JIRA issue|http://framework.zend.com/issues/browse/ZF-1674]
{zone-data}

{zone-data:requirements}
Currently the signature for fetchAll follows a ($where, $order, $limit, $offset) approach (similarly for fetchRow) but this does not provide enough flexibility for some more complex requirements (e.g. grouping). Some current methods completely ignore any passed parameters (the magic method relationship queries). It is proposed instead that all fetch/find queries from a Zend_Db_Table/Row provide the capability of supplying a Zend_Db_Select object to modify the query.

* This component *will* retain existing method signatures to provide BC.
* This component *will* allow a Zend_Db_Select object to be used to modify a query.
* This component *will* allow a 'partial' Zend_Db_Table_Row/Rowset to be fetched (will be read-only).
* This component *will* allow individual Zend_Db_Table_Rows to be 'locked' using the readOnly flag.
* This component *will not* allow Zend_Db_Select to perform Joins or to otherwise extend the query outside of the parent table.
{zone-data}

{zone-data:dependencies}
* Zend_Db_Select
* Zend_Db_Table_Abstract
* Zend_Db_Table_Row_Abstract
* Zend_Db_Table_Rowset_Abstract
{zone-data}

{zone-data:operation}
The components will continue to operate when called using the method signature as per release 1.0.1 of the Zend Framework. However the new select object usage will become the preferred method and by release 1.2+ of Zend Framework the deprecated methods will emit an E_NOTICE.

A user-supplied Zend_Db_Select object will not allow modification to the 'from' or any 'join' methods - this is to prevent any errors or conflicts with the Zend_Db_Table schema.
{zone-data}

{zone-data:milestones}
* Milestone 1: [design notes will be published here|http://framework.zend.com/wiki/x/sg]
* Milestone 2: [DONE] Working prototype @ http://framework.zend.com/svn/laboratory/library/Zend/Db/Table
* Milestone 3: Unit tests created.
* Milestone 4: Update existing documentation.
{zone-data}

{zone-data:class-list}
* Zend_Db_Select
* Zend_Db_Table_Abstract
* Zend_Db_Table_Row_Abstract
* Zend_Db_Table_Rowset_Abstract
{zone-data}

{zone-data:use-cases}
||UC-01||
Simple table query
{code}
$table = new MyTable();

// Existing usage (and also continued usage for BC)
$rows = $table->fetchAll('status = "active"', 'submitdate ASC', 20, 0);

// Proposed usage
$rows = $table->fetchAll($table->select()->where('status = ?', 'active')
->order('submitdate ASC')
->limit(20, 0));
$row = $table->find('1234', $table->select()->where('status = ?', 'pending'))
->current();
{code}
||UC-02||
Retrieving related/dependent rows
{code}
$table = new MyTable();
$row = $table->find('1234')->current();

// Find dependent rows
$rows = $row->findDependentRowset('Bugs', 'Engineer', $row->select()->where('status = ?', 'active')
->order('submitdate ASC'));
// alternate usage
$rows = $row->findBugsByEngineer($row->select()->where('status = ?', 'active')
->order('submitdate ASC'));

// Find parent row
$prnt = $row->findParentAccounts($row->select()->where('role = ?', 'in_charge'));
{code}
{zone-data}

{zone-data:skeletons}
The major changes to the class(es) will be the addition of a method to allow retrieval of the Zend_Db_Select object. From a Zend_Db_Table_Row object, for example, it is possible to retrieve via $row->getTable()->getAdapter()->select() but for the sake of readability and leaner code these convenience methods will provide a helpful shortcut.
{code}
Zend_Db_Table_Abstract
{
public function select()
{
return $this->getAdapter()->select();
}
}

Zend_Db_Table_Row_Abstract
{
public function select()
{
return $this->getTable()->getAdapter()->select();
}

public function isReadOnly()
{
return $this->_readOnly;
}

public function setReadOnly($flag)
{
$this->_readOnly = (bool) $flag;
}
}
{code}
The addition of the readOnly flag is to prevent partial Zend_Db_Table_Row objects being saved if they contain fields outside of the table schema (including functions, aliases, etc.)

The other subtle change is to modify the signature of the fetch/find methods to detect a select object. If the deprecated method is used, then these parameters will be added to a new select object and passed to the query. In a later release of the framework, using the deprecated signature will emit an E_NOTICE.
{zone-data}

{zone-template-instance}]]></ac:plain-text-body></ac:macro>