database->adapter, $config->database->params->toArray()); Zend_Db_Table::setDefaultAdapter(Qs_Db::$_instance); } return Qs_Db::$_instance; } public static function getSelect() { return static::getInstance()->select(); } /** * @static * @return Zend_Config | mixed * @throws Qs_Db_Exception */ public static function getConfig() { if (null === Qs_Db::$_config) { if (!Zend_Registry::isRegistered('config')) { throw new Qs_Db_Exception('config is not registered in Zend_Registry'); } Qs_Db::$_config = Zend_Registry::get('config'); } return Qs_Db::$_config; } public static function getTableName($shortName) { if (!isset(Qs_Db::$_tableNames[$shortName])) { $dbPrefix = explode('_', $shortName); $dbPrefix = reset($dbPrefix); $config = Qs_Db::getConfig(); if (null !== ($additionalDatabases = $config->database->get('additionalDatabases'))) { if (null !== ($database = $additionalDatabases->get($dbPrefix))) { $name = substr($shortName, strlen($dbPrefix) + 1); Qs_Db::$_tableNames[$shortName] = $database->name . '.' . $database->tablePrefix . $name; } else { Qs_Db::$_tableNames[$shortName] = $config->database->params->dbname . '.' . $config->database->tablePrefix . $shortName; } } else { Qs_Db::$_tableNames[$shortName] = $config->database->tablePrefix . $shortName; } } return Qs_Db::$_tableNames[$shortName]; } public static function filter(Zend_Db_Select $select, array $filter, $alias) { if (empty($filter)) { return; } $tableInfo = Qs_Array::get($select->getPart(Zend_Db_Select::FROM), $alias); if (null === $tableInfo) { throw new Qs_Db_Exception( 'Alias "' . $alias . '" not found in select "FROM" part' . print_r($select->getPart(Zend_Db_Select::FROM), true) ); } $table = new Qs_Db_Table(array('name' => $tableInfo['tableName'], 'schema' => $tableInfo['schema'])); $metaData = $table->getMetaData(); foreach ($filter as $field => $value) { if (!array_key_exists($field, $metaData)) { continue; } $_field = $select->getAdapter()->quoteIdentifier($alias . '.' . $field); if (is_null($value)) { $_conditionAndValue = 'IS NULL'; } else { $type = Qs_Db::_getMetaTypeToType(Qs_Array::get($metaData, $field . '[DATA_TYPE]')); $_condition = is_array($value) ? ' IN (?)' : '= ?'; $_conditionAndValue = $select->getAdapter()->quoteInto($_condition, $value, $type); } $select->where($_field . ' ' . $_conditionAndValue); } } /** * Modified version of function Zend_Db_Adapter_Abstract->_whereExpr * * Convert an array, string, or Zend_Db_Expr object * into a string to put in a WHERE clause. * * @param array|string|Zend_Db_Expr $where * @return string */ public static function getWhereSql($where) { if (empty($where)) { return 1; } $db = Qs_Db::getInstance(); $where = (array) $where; foreach ($where as $condition => &$term) { if (is_int($condition)) { if ($term instanceof Zend_Db_Expr) { $term = $term->__toString(); } } else { $condition = (false !== strpos($condition, '?')) ? $condition : $condition . ' = ?'; $term = $db->quoteInto($condition, $term); } $term = '(' . $term . ')'; } $where = implode(' AND ', $where); return $where; } protected static function _getMetaTypeToType($type) { switch (strtolower($type)) { case 'mediumint': // break was intentionally omitted case 'smallint': // break was intentionally omitted case 'tinyint': // break was intentionally omitted case 'bit': // break was intentionally omitted case 'bool': // break was intentionally omitted case 'boolean': // break was intentionally omitted case 'int': $type = Qs_Db::INT_TYPE; break; case 'serial': // break was intentionally omitted case 'bingint': $type = Qs_Db::BIGINT_TYPE; break; case 'decimal': // break was intentionally omitted case 'double': // break was intentionally omitted case 'float': // break was intentionally omitted case 'real': $type = Qs_Db::FLOAT_TYPE; break; default: $type = null; break; } return $type; } public static function getPairExpr($tableAlias, $alias = null) { $pair = static::getPair($tableAlias, $alias); $db = static::getInstance(); return new Zend_Db_Expr($db->quoteIdentifier(current($pair)) . ' AS ' . $db->quoteIdentifier(key($pair))); } public static function getPair($tableAlias, $alias = null) { if (null === $alias) { $alias = $tableAlias; } return array($alias => static::getTableName($tableAlias)); } public static function getField($field, $alias = null) { return ((null === $alias) ? '' : $alias . '.') . $field; } public static function quoteField($field, $alias = null) { return Qs_Db::getInstance()->quoteIdentifier(static::getField($field, $alias)); } public static function getLastQuery() { return Qs_Db::getInstance()->getProfiler()->getLastQueryProfile()->getQuery(); } /** * Method quotes values according to meta data, unknown fields will be removed * @static * @param array $row * @param string|Zend_Db_Table $table Table alias or instance * @return array * @throws Qs_Db_Exception */ public static function quoteRow(array $row, $table) { static $metaDataCache = array(); $table = (is_string($table)) ? new Qs_Db_Table($table) : $table; if (!$table instanceof Zend_Db_Table) { throw new Qs_Db_Exception('Param $table expected to be "Zend_Db_Table" but "' . get_class($table) . '" found'); } $tableName = $table->getName(); if (!array_key_exists($tableName, $metaDataCache)) { $metaDataCache[$tableName] = $table->info(Zend_Db_Table::METADATA); } $metaData = $metaDataCache[$tableName]; $db = static::getInstance(); $quotedRow = array(); foreach ($row as $name => $value) { if (array_key_exists($name, $metaData)) { $colMeta = $metaData[$name]; $quotedRow[$name] = (null === $value && $colMeta['NULLABLE']) ? 'NULL' : $db->quote($value, static::_getMetaTypeToType($colMeta['DATA_TYPE'])); } } return $quotedRow; } /** * Returns quoted list * @static * @param array $list * @param string|Zend_Db_Table $table Table alias or instance * @return array */ public static function quoteList(array $list, $table) { $quotedList = array(); foreach ($list as $key => $row) { $quotedList[$key] = static::quoteRow($row, $table); } return $quotedList; } /** * @static * @param $tableAlias string | array * @return bool|string */ public static function getTableModificationTime($tableAlias) { $tableAlias = (array)$tableAlias; $tables = array_map('Qs_Db::getTableName', $tableAlias); if (empty($tables)) { return false; } $select = self::getSelect(); $select->from('information_schema.tables', array('update_time')); $select->where('`table_schema` = ?', \Qs_Array::get(self::getInstance()->getConfig(), 'dbname')); $select->where('`table_name` IN(?)', $tables); $select->order('update_time DESC'); $select->limit(1); return Qs_Db::getInstance()->fetchOne($select); } public static function quote($value, $type = null) { if (is_string($value)) { $value = self::_escapeMetaChars($value); } elseif (is_array($value)) { foreach ($value as &$val) { $val = self::_escapeMetaChars($val); } } switch ($type) { case self::PERCENT_LEFT: $value = '%' . $value; $type = null; break; case self::PERCENT_RIGHT: $value = $value . '%'; $type = null; break; case self::PERCENT_BOTH: $value = '%' . $value . '%'; $type = null; break; } return Qs_Db::getInstance()->quote($value, $type); } protected static function _escapeMetaChars($value) { return str_replace(array('\\', '%', '_'), array('\\\\', '\%', '\_'), (string) $value); } /** * @param array|string $alias alias | [alias, shortAlias] * @param array|string $where * @return Zend_Db_Expr */ public static function getCountExpr($alias, $where) { $pair = (is_array($alias)) ? Qs_Db::getPair(array_shift($alias), array_shift($alias)) : Qs_Db::getPair($alias); $select = Qs_Db::getSelect(); $select->from($pair, array('COUNT(*)')); $select->where(Qs_Db::getWhereSql($where)); return new \Zend_Db_Expr('(' . $select . ')'); } }