/** * @return string */ protected function _renderFromClauseToString() { /* * If no table specified, use RDBMS-dependent solution * for table-less query. e.g. DUAL in Oracle. */ if (empty($this->_parts[self::FROM])) { $this->_parts[self::FROM] = $this->_getDummyTable(); } $from = array(); foreach ((array) $this->_parts[self::FROM] as $correlationName => $table) { $tmp = ''; if (empty($from)) { /* * Add schema if available */ if (null !== $table['schema']) { $tmp .= $this->_adapter->quoteIdentifier($table['schema'], true) . '.'; } /* * First table is named alone ignoring join information */ $tmp .= $this->_adapter->quoteTableAs($table['tableName'], $correlationName, true); } else { /* * Subsequent tables may have joins */ if (!empty($table['joinType'])) { $tmp .= ' ' . strtoupper($table['joinType']) . ' '; } /* * Add schema if available */ if (null !== $table['schema']) { $tmp .= $this->_adapter->quoteIdentifier($table['schema'], true) . '.'; } $tmp .= $this->_adapter->quoteTableAs($table['tableName'], $correlationName, true); if (!empty($table['joinCondition'])) { $tmp .= ' ON ' . $table['joinCondition']; } } /* * Add the table name and condition add to the list */ $from[] = $tmp; } /* * Add the list of all joins */ if (!empty($from)) { return 'FROM ' . implode("\n", $from); } return null; }
/** * Fetches rows by primary key. The argument specifies one or more primary * key value(s). To find multiple rows by primary key, the argument must * be an array. * * This method accepts a variable number of arguments. If the table has a * multi-column primary key, the number of arguments must be the same as * the number of columns in the primary key. To find multiple rows in a * table with a multi-column primary key, each argument must be an array * with the same number of elements. * * The find() method always returns a Rowset object, even if only one row * was found. * * @param mixed $key The value(s) of the primary keys. * @return Zend_Db_Table_Rowset_Abstract Row(s) matching the criteria. * @throws Zend_Db_Table_Exception */ public function find() { $args = func_get_args(); $keyNames = array_values((array) $this->_primary); if (count($args) < count($keyNames)) { require_once 'Zend/Db/Table/Exception.php'; throw new Zend_Db_Table_Exception("Too few columns for the primary key"); } if (count($args) > count($keyNames)) { require_once 'Zend/Db/Table/Exception.php'; throw new Zend_Db_Table_Exception("Too many columns for the primary key"); } $whereList = array(); $numberTerms = 0; foreach ($args as $keyPosition => $keyValues) { // Coerce the values to an array. // Don't simply typecast to array, because the values // might be Zend_Db_Expr objects. if (!is_array($keyValues)) { $keyValues = array($keyValues); } if ($numberTerms == 0) { $numberTerms = count($keyValues); } else { if (count($keyValues) != $numberTerms) { require_once 'Zend/Db/Table/Exception.php'; throw new Zend_Db_Table_Exception("Missing value(s) for the primary key"); } } for ($i = 0; $i < count($keyValues); ++$i) { if (!isset($whereList[$i])) { $whereList[$i] = array(); } $whereList[$i][$keyPosition] = $keyValues[$i]; } } $whereClause = null; if (count($whereList)) { $whereOrTerms = array(); foreach ($whereList as $keyValueSets) { $whereAndTerms = array(); foreach ($keyValueSets as $keyPosition => $keyValue) { $type = $this->_metadata[$keyNames[$keyPosition]]['DATA_TYPE']; $tableName = $this->_db->quoteTableAs($this->_name, null, true); $columnName = $this->_db->quoteIdentifier($keyNames[$keyPosition], true); $whereAndTerms[] = $this->_db->quoteInto($tableName . '.' . $columnName . ' = ?', $keyValue, $type); } $whereOrTerms[] = '(' . implode(' AND ', $whereAndTerms) . ')'; } $whereClause = '(' . implode(' OR ', $whereOrTerms) . ')'; } return $this->fetchAll($whereClause); }
/** * Fetches rows by primary key. The argument specifies one or more primary * key value(s). To find multiple rows by primary key, the argument must * be an array. * * This method accepts a variable number of arguments. If the table has a * multi-column primary key, the number of arguments must be the same as * the number of columns in the primary key. To find multiple rows in a * table with a multi-column primary key, each argument must be an array * with the same number of elements. * * The find() method always returns a Rowset object, even if only one row * was found. * * @param mixed $key The value(s) of the primary keys. * @return Zend_Db_Table_Rowset_Abstract Row(s) matching the criteria. * @throws Zend_Db_Table_Exception */ public function find() { $this->_setupPrimaryKey(); $args = func_get_args(); $keyNames = array_values((array) $this->_primary); if (count($args) < count($keyNames)) { require_once 'Zend/Db/Table/Exception.php'; throw new Zend_Db_Table_Exception("Too few columns for the primary key"); } if (count($args) > count($keyNames)) { require_once 'Zend/Db/Table/Exception.php'; throw new Zend_Db_Table_Exception("Too many columns for the primary key"); } $whereList = array(); $numberTerms = 0; foreach ($args as $keyPosition => $keyValues) { $keyValuesCount = count($keyValues); // Coerce the values to an array. // Don't simply typecast to array, because the values // might be Zend_Db_Expr objects. if (!is_array($keyValues)) { $keyValues = array($keyValues); } if ($numberTerms == 0) { $numberTerms = $keyValuesCount; } else { if ($keyValuesCount != $numberTerms) { require_once 'Zend/Db/Table/Exception.php'; throw new Zend_Db_Table_Exception("Missing value(s) for the primary key"); } } $keyValues = array_values($keyValues); for ($i = 0; $i < $keyValuesCount; ++$i) { if (!isset($whereList[$i])) { $whereList[$i] = array(); } $whereList[$i][$keyPosition] = $keyValues[$i]; } } $whereClause = null; if (count($whereList)) { $whereOrTerms = array(); $tableName = $this->_db->quoteTableAs($this->_name, null, true); foreach ($whereList as $keyValueSets) { $whereAndTerms = array(); foreach ($keyValueSets as $keyPosition => $keyValue) { $type = $this->_metadata[$keyNames[$keyPosition]]['DATA_TYPE']; $columnName = $this->_db->quoteIdentifier($keyNames[$keyPosition], true); $whereAndTerms[] = $this->_db->quoteInto($tableName . '.' . $columnName . ' = ?', $keyValue, $type); } $whereOrTerms[] = '(' . implode(' AND ', $whereAndTerms) . ')'; } $whereClause = '(' . implode(' OR ', $whereOrTerms) . ')'; } // issue ZF-5775 (empty where clause should return empty rowset) if ($whereClause == null) { $rowsetClass = $this->getRowsetClass(); if (!class_exists($rowsetClass)) { require_once 'Zend/Loader.php'; Zend_Loader::loadClass($rowsetClass); } return new $rowsetClass(array('table' => $this, 'rowClass' => $this->getRowClass(), 'stored' => true)); } return $this->fetchAll($whereClause); }
/** * Return a quoted table name * * @param string $tableName The table name * @param string $correlationName The correlation name OPTIONAL * @return string */ protected function _getQuotedTable($tableName, $correlationName = null) { return $this->_adapter->quoteTableAs($tableName, $correlationName, true); }
/** * Quote a table identifier and alias. * * @param string|array|Zend_Db_Expr $ident The identifier or expression. * @param string $alias An alias for the table. * @param boolean $auto (optional) If true, heed the AUTO_QUOTE_IDENTIFIERS config option. * @return string The quoted identifier and alias. */ public function quoteTableAs($ident, $alias = null, $auto = false) { return $this->_adapter->quoteTableAs($ident, $alias, $auto); }
/** * Converts this object to an SQL SELECT string. * * @todo use $this->_adapter->quoteColumns() for non-PDO adapters * @todo use $this->_adapter->quoteTableNames() for non-PDO adapters * @todo use prepared queries for PDO adapters instead of constructing all the SQL ourselves * like in Adapter/Abstract.php.html:query() * @return string This object as a SELECT string. */ public function __toString() { // initial SELECT [DISTINCT] [FOR UPDATE] $sql = "SELECT"; if ($this->_parts[self::DISTINCT]) { $sql .= " DISTINCT"; } if ($this->_parts[self::FOR_UPDATE]) { $sql .= " FOR UPDATE"; } $sql .= "\n\t"; // add columns if ($this->_parts[self::COLUMNS]) { $columns = array(); foreach ($this->_parts[self::COLUMNS] as $correlationName => $columnList) { foreach ($columnList as $alias => $column) { if (!is_string($alias)) { $alias = null; } if ($column instanceof Zend_Db_Expr) { $columns[] = $this->_adapter->quoteColumnAs($column, $alias); } else { if ($column == '*') { $column = new Zend_Db_Expr('*'); $alias = null; } if (empty($correlationName)) { $columns[] = $this->_adapter->quoteColumnAs($column, $alias); } else { $columns[] = $this->_adapter->quoteColumnAs(array($correlationName, $column), $alias); } } } } $sql .= implode(",\n\t", $columns); } // from these joined tables if ($this->_parts[self::FROM]) { $from = array(); // array_pop() foreach ($this->_parts[self::FROM] as $correlationName => $table) { $tmp = ''; if (empty($from)) { // First table is named alone ignoring join information $tmp .= $this->_adapter->quoteTableAs($table['tableName'], $correlationName); } else { // Subsequent tables may have joins if (!empty($table['joinType'])) { $tmp .= ' ' . strtoupper($table['joinType']) . ' '; } $tmp .= $this->_adapter->quoteTableAs($table['tableName'], $correlationName); if (!empty($table['joinCondition'])) { $tmp .= ' ON ' . $table['joinCondition']; } } // add the table name and condition // add to the list $from[] = $tmp; } // add the list of all joins if (!empty($from)) { $sql .= "\nFROM " . implode("\n", $from); } // with these where conditions if ($this->_parts[self::WHERE]) { $sql .= "\nWHERE\n\t"; $sql .= implode("\n\t", $this->_parts[self::WHERE]); } // grouped by these columns if ($this->_parts[self::GROUP]) { $sql .= "\nGROUP BY\n\t"; $l = array(); foreach ($this->_parts[self::GROUP] as $term) { $l[] = $this->_adapter->quoteIdentifier($term); } $sql .= implode(",\n\t", $l); } // having these conditions if ($this->_parts[self::HAVING]) { $sql .= "\nHAVING\n\t"; $sql .= implode("\n\t", $this->_parts[self::HAVING]); } } // ordered by these columns if ($this->_parts[self::ORDER]) { $sql .= "\nORDER BY\n\t"; $l = array(); foreach ($this->_parts[self::ORDER] as $term) { if (is_array($term)) { $l[] = $this->_adapter->quoteIdentifier($term[0]) . ' ' . $term[1]; } else { $l[] = $this->_adapter->quoteIdentifier($term); } } $sql .= implode(",\n\t", $l); } // determine offset $count = 0; $offset = 0; if (!empty($this->_parts[self::LIMIT_OFFSET])) { $offset = (int) $this->_parts[self::LIMIT_OFFSET]; // this should be reduced to the max integer PHP can support $count = intval(9223372036854775807); } // determine count if (!empty($this->_parts[self::LIMIT_COUNT])) { $count = (int) $this->_parts[self::LIMIT_COUNT]; } // add limits clause if ($count > 0) { $sql .= "\n"; $sql = trim($this->_adapter->limit($sql, $count, $offset)); } return $sql; }