$val) { $value[$i] = $db->quote($val, $type); } return implode(', ', $value); } return $db->quote($value, $type); } public static function isError($res) { if (MDB2::isError($res)) { if (defined('DEBUG') && DEBUG) { vdie($res); } else { sendDeveloperEmail($res->getUserInfo()); } return true; } return false; } public static function getTableName($alias) { return DB_PREFIX . $alias; } public static function getPair($fullAlias, $shortAlias = null) { if (null === $shortAlias) { $shortAlias = $fullAlias; } $db = &S_db2::getInstance(); return $db->quoteIdentifier(self::getTableName($fullAlias)) . ' AS ' . $db->quoteIdentifier($shortAlias); } public static function quoteIdentifier($identifier) { $db = &S_db2::getInstance(); if (is_string($identifier)) { $identifier = explode('.', $identifier); } if (is_array($identifier)) { $segments = array(); foreach ($identifier as $segment) { $segments[] = $db->quoteIdentifier($segment); } $quoted = implode('.', $segments); } else { $quoted = $db->quoteIdentifier($identifier); } return $quoted; } public static function filter($filter, $alias = null, $condition = null) { $parts = array(); foreach ($filter as $field => $value) { $parts[] = self::equalCondition($field, $value, $alias); } return implode(' ' . ((null === $condition) ? 'AND': $condition) . ' ', $parts); } public static function equalCondition($field, $value, $alias = null) { $_part = (!empty($alias) ? '`' . $alias . '`.' : '') . '`' . $field . '`'; if (is_array($value)) { $_part .= ' IN (' . Qs_Db::quote($value) . ')'; } elseif (null === $value) { $_part .= ' IS NULL '; } else { $_part .= ' = ' . Qs_Db::quote($value); } return $_part; } public static function describeTable($tableName, $schemaName = null) { $db = &S_db2::getInstance(); if ($schemaName) { $sql = 'DESCRIBE ' . $db->quoteIdentifier("$schemaName.$tableName", true); } else { $sql = 'DESCRIBE ' . $db->quoteIdentifier($tableName, true); } $result = $db->queryAll($sql, null, MDB2_FETCHMODE_ORDERED); $field = 0; $type = 1; $null = 2; $key = 3; $default = 4; $extra = 5; $desc = array(); $i = 1; $p = 1; foreach ($result as $row) { list($length, $scale, $precision, $unsigned, $primary, $primaryPosition, $identity) = array(null, null, null, null, false, null, false); if (preg_match('/unsigned/', $row[$type])) { $unsigned = true; } if (preg_match('/^((?:var)?char)\((\d+)\)/', $row[$type], $matches)) { $row[$type] = $matches[1]; $length = $matches[2]; } else if (preg_match('/^decimal\((\d+),(\d+)\)/', $row[$type], $matches)) { $row[$type] = 'decimal'; $precision = $matches[1]; $scale = $matches[2]; } else if (preg_match('/^float\((\d+),(\d+)\)/', $row[$type], $matches)) { $row[$type] = 'float'; $precision = $matches[1]; $scale = $matches[2]; } else if (preg_match('/^((?:big|medium|small|tiny)?int)\((\d+)\)/', $row[$type], $matches)) { $row[$type] = $matches[1]; // The optional argument of a MySQL int type is not precision // or length; it is only a hint for display width. } if (strtoupper($row[$key]) == 'PRI') { $primary = true; $primaryPosition = $p; if ($row[$extra] == 'auto_increment') { $identity = true; } else { $identity = false; } ++$p; } $desc[Qs_Db::_foldCase($row[$field])] = array( 'SCHEMA_NAME' => null, // @todo 'TABLE_NAME' => Qs_Db::_foldCase($tableName), 'COLUMN_NAME' => Qs_Db::_foldCase($row[$field]), 'COLUMN_POSITION' => $i, 'DATA_TYPE' => $row[$type], 'DEFAULT' => $row[$default], 'NULLABLE' => (bool) ($row[$null] == 'YES'), 'LENGTH' => $length, 'SCALE' => $scale, 'PRECISION' => $precision, 'UNSIGNED' => $unsigned, 'PRIMARY' => $primary, 'PRIMARY_POSITION' => $primaryPosition, 'IDENTITY' => $identity ); ++$i; } return $desc; } protected static function _getTypeFromMetaType($type) { switch ($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; } /** * @param array $row * @param array $meta * @return array */ public static function convertFieldTypesUsingMeta($row, $meta) { $row = array_intersect_key($row, $meta); foreach ($row as $field => $value) { if (null === $value && $meta[$field]['NULLABLE']) { $row[$field] = null; continue; } switch (Qs_Db::_getTypeFromMetaType($meta[$field]['DATA_TYPE'])) { case QS_DB_INT_TYPE: $row[$field] = (int) $value; break; case QS_DB_BIGIINT_TYPE: $row[$field] = (int) $value; break; case QS_DB_FLOAT_TYPE: $row[$field] = (float) $value; break; default: break; } } return $row; } protected static function _foldCase($column) { $db = &S_db2::getInstance(); if ($db->options['field_case'] == CASE_LOWER) { $column = strtolower($column); } else { $column = strtoupper($column); } return $column; } }