database->toArray(); } else { self::$_config = new Zend_Config(['database' => $config]); } if (!array_key_exists('profiler', $config['params'])) { $config['params']['profiler'] = self::$_debug ? new \Qs\Db\Profiler(true) : false; } Qs_Db::$_instance = Zend_Db::factory($config['adapter'], $config['params']); Zend_Db_Table::setDefaultAdapter(Qs_Db::$_instance); } return Qs_Db::$_instance; } public static function isDebug() { return self::$_debug; } public static function setDebug($debug) { self::$_debug = $debug; } 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(); /** @var Zend_Config $additionalDatabases */ 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 getTableAlias($tableName) { if (false !== ($shortName = array_search($tableName, Qs_Db::$_tableNames))) { return $shortName; } if (false === ($idx = strpos($tableName, '_'))) { return $tableName; } $shortName = substr($tableName, $idx + 1); return $shortName ?: false; } public static function filter(Zend_Db_Select $select, array $filter, $alias, $flag = 0) { if (empty($filter)) { return false; } $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(['name' => $tableInfo['tableName'], 'schema' => $tableInfo['schema']]); $metaData = $table->getMetaData(); foreach ($filter as $field => $value) { if (false !== strpos($field, '?')) { $select->where($select->getAdapter()->quoteInto($field, $value)); continue; } if (!array_key_exists($field, $metaData)) { if (($flag & self::FILTER_THROW_UNKNOWN) === self::FILTER_THROW_UNKNOWN) { throw new Exception("'{$field}' is not found in the {$tableInfo['tableName']} table"); } 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); } return true; } /** * 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(); } } elseif (false !== strpos($condition, '?')) { $term = $db->quoteInto($condition, $term); } elseif (is_null($term)) { $term = $condition . ' IS NULL'; } else { $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 [$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 = []; /** @var Qs_Db_Table $table */ $table = (is_string($table)) ? new Qs_Db_Table($table) : $table; if (!$table instanceof Zend_Db_Table) { throw new Qs_Db_Exception('Wrong param "$table"'); } $tableName = $table->getName(); if (!array_key_exists($tableName, $metaDataCache)) { $metaDataCache[$tableName] = $table->info(Zend_Db_Table::METADATA); } $metaData = $metaDataCache[$tableName]; $db = static::getInstance(); $quotedRow = []; 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 = []; foreach ($list as $key => $row) { $quotedList[$key] = static::quoteRow($row, $table); } return $quotedList; } /** * @param int|string $id int - id value, string - id field name * @return int|string */ public static function quoteIdField($id) { return (is_int($id) || ctype_digit($id)) ? (int) $id : static::getInstance()->quoteIdentifier((string) $id); } public static function quoteLike($term, $condition = '%{term}%') { $term = str_replace(['\\', '_', '%'], ['\\\\', '\_', '\%'], $term); $term = str_replace('{term}', $term, $condition); return Qs_Db::getInstance()->quote($term); } /** * @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, ['COUNT(*)']); $select->where(Qs_Db::getWhereSql($where)); return new \Zend_Db_Expr('(' . $select . ')'); } /** * @param $tableAlias * @return Qs_Db_Table */ public static function getTable($tableAlias) { if (!array_key_exists($tableAlias, self::$_tables)) { self::$_tables[$tableAlias] = new Qs_Db_Table($tableAlias); } return self::$_tables[$tableAlias]; } }