ZF-5199: Zend_Db_Select should make use of Zend_Db_Table instances in from() and join() clauses

Description

Look at Zend_Db_Table_Select from() method :


public function from($name, $cols = self::SQL_WILDCARD, $schema = null)
{
if ($name instanceof Zend_Db_Table_Abstract) {
            $info = $name->info();
            $name = $info[Zend_Db_Table_Abstract::NAME];
            if (isset($info[Zend_Db_Table_Abstract::SCHEMA])) {
                $schema = $info[Zend_Db_Table_Abstract::SCHEMA];
            }
        }
// ...

That is nice, and I wonder why that has'nt been implemented in Zend_Db_Select class. Same for join() : Why cant we use a Zend_Db_Table instance in it ?

Use case asked :


$db->select()->from($aTable)->join($anotherTable) ...
// $db is a Zend_Db_Adapter_Abstract
// $aTable and $anotherTable are both Zend_Db_Table_Abstract objects

Comments

Why should Zend_Db_Select be aware of anything Zend_Db_Table? Wouldnt this introduce a level of unwanted coupling? Isnt this what Z_D_T_Select is for?

@Ralph Schindler:

Here's why I vote for this issue. I have a table "Foo" for which I have created a subclass of Zend_Db_Table_Abstract called FooTable. I want to select a single value from a single column of "Foo", but Zend_Db_Table does not have a fetchOne() method, whereas Zend_Db_Adapter does. So I use Zend_Db_Adapter for the query. However, I want my FooTable class to completely encapsulate the database table, so that if I decide to change the name of the table from "Foo" to "BetterFoo", I only have to make a change in one place.

Instead of doing this:

$select = $db_adapter->select()->from("Foo", ...); $scalar_val = $db_adapter->fetchOne($select);

I want to do this:

$foo_table = new FooTable(); $select = $db_adapter->select()->from($foo_table, ...); $scalar_val = $db_adapter->fetchOne($select);

Comments welcome!

@Ian:

Not a valid reason for Zend_Db_Select to need extra code to need be aware of Zend_Db_Table.

take a look at the docs here http://framework.zend.com/manual/en/…

You can already retrieve specific columns with Zend_Db_Table_Select:


$table = new MyTable();
$table->select()->from($table, array('my_column'))->fetchRow();

If you really want the same behavior as Zend_Db_Select#fetchOne() (that is, return a single value as a result) then you can do:


$table = new MyTable();
$select = $table->select()->from($table, array('my_column'));
$result = $table->getAdapter()->fetchOne($select);

@Marc Hodgins:

Your second code snippet addresses my concern quite well. I didn't realize you could pass a Zend_Db_Table_Select to Zend_Db_Adapter->fetchOne(). (Of course, now that I look more closely at the API docs, I see that Zend_Db_Table_Select inherits from Zend_Db_Select, so I guess I could have figured this out on my own.)

Thanks for the feedback/lesson. Your (and Ralph's) point about keeping Zend_Db_Select unaware of Zend_Db_Table is a good one, so I'll "unvote" this issue.