From 99819643dd2c6a16d812b24664ec6dbf22bcb190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A5=81=E5=AE=81?= Date: Tue, 27 May 2014 10:44:14 +0800 Subject: [PATCH] fix #249 fix #250 --- var/Typecho/Common.php | 45 +++++++++++++++++++++++ var/Typecho/Db/Adapter/Pdo/SQLite.php | 32 +++++++++++++++- var/Typecho/Db/Adapter/SQLite.php | 53 +++++---------------------- 3 files changed, 86 insertions(+), 44 deletions(-) diff --git a/var/Typecho/Common.php b/var/Typecho/Common.php index d378f684..b9fe8364 100644 --- a/var/Typecho/Common.php +++ b/var/Typecho/Common.php @@ -987,6 +987,51 @@ EOF; return rtrim($prefix, '/') . '/' . str_replace('//', '/', ltrim($path, '/')); } + /** + * 过滤字段名 + * + * @access private + * @param mixed $result + * @return array + */ + public static function filterSQLite2ColumnName($result) + { + /** 如果结果为空,直接返回 */ + if (empty($result)) { + return $result; + } + + $tResult = array(); + + /** 遍历数组 */ + foreach ($result as $key => $val) { + /** 按点分隔 */ + if (false !== ($pos = strpos($key, '.'))) { + $key = substr($key, $pos + 1); + } + + $tResult[trim($key, '"')] = $val; + } + + return $tResult; + } + + /** + * 处理sqlite2的distinct count + * + * @param $sql + * @return string + */ + public static function filterSQLite2CountQuery($sql) + { + if (preg_match("/SELECT\s+COUNT\(DISTINCT\s+([^\)]+)\)\s+(AS\s+[^\s]+)?\s*FROM\s+(.+)/is", $sql, $matches)) { + return 'SELECT COUNT(' . $matches[1] . ') ' . $matches[2] . ' FROM SELECT DISTINCT ' + . $matches[1] . ' FROM ' . $matches[3]; + } + + return $sql; + } + /** * 获取图片 * diff --git a/var/Typecho/Db/Adapter/Pdo/SQLite.php b/var/Typecho/Db/Adapter/Pdo/SQLite.php index 108d14d5..b1f5c70e 100644 --- a/var/Typecho/Db/Adapter/Pdo/SQLite.php +++ b/var/Typecho/Db/Adapter/Pdo/SQLite.php @@ -15,6 +15,11 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; */ class Typecho_Db_Adapter_Pdo_SQLite extends Typecho_Db_Adapter_Pdo { + /** + * @var sqlite version 2.x + */ + private $_isSQLite2 = false; + /** * 判断适配器是否可用 * @@ -36,9 +41,28 @@ class Typecho_Db_Adapter_Pdo_SQLite extends Typecho_Db_Adapter_Pdo public function init(Typecho_Config $config) { $pdo = new PDO("sqlite:{$config->file}"); + $this->_isSQLite2 = version_compare($pdo->getAttribute(PDO::ATTR_SERVER_VERSION), '3.0.0', '<'); return $pdo; } + /** + * @param resource $resource + * @return array + */ + public function fetch($resource) + { + return Typecho_Common::filterSQLite2ColumnName(parent::fetch($resource)); + } + + /** + * @param resource $resource + * @return object + */ + public function fetchObject($resource) + { + return (object) $this->fetch($resource); + } + /** * 对象引号过滤 * @@ -70,7 +94,13 @@ class Typecho_Db_Adapter_Pdo_SQLite extends Typecho_Db_Adapter_Pdo $sql['limit'] = (0 == strlen($sql['limit'])) ? NULL : ' LIMIT ' . $sql['limit']; $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset']; - return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] . + $query = 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] . $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; + + if ($this->_isSQLite2) { + $query = Typecho_Common::filterSQLite2CountQuery($query); + } + + return $query; } } diff --git a/var/Typecho/Db/Adapter/SQLite.php b/var/Typecho/Db/Adapter/SQLite.php index 123aa2ab..53781914 100644 --- a/var/Typecho/Db/Adapter/SQLite.php +++ b/var/Typecho/Db/Adapter/SQLite.php @@ -34,40 +34,6 @@ class Typecho_Db_Adapter_SQLite implements Typecho_Db_Adapter return function_exists('sqlite_open'); } - /** - * 过滤字段名 - * - * @access private - * @param mixed $result - * @return array - */ - private function filterColumnName($result) - { - /** 如果结果为空,直接返回 */ - if (!$result) { - return $result; - } - - $tResult = array(); - - /** 遍历数组 */ - foreach ($result as $key => $val) { - /** 按点分隔 */ - if (false !== ($pos = strpos($key, '.'))) { - $key = substr($key, $pos + 1); - } - - /** 按引号分割 */ - if (false === ($pos = strpos($key, '"'))) { - $tResult[$key] = $val; - } else { - $tResult[substr($key, $pos + 1, -1)] = $val; - } - } - - return $tResult; - } - /** * 数据库连接函数 * @@ -88,11 +54,12 @@ class Typecho_Db_Adapter_SQLite implements Typecho_Db_Adapter /** * 执行数据库查询 * - * @param string $sql 查询字符串 - * @param mixed $handle 连接对象 - * @param boolean $op 查询读写开关 - * @throws Typecho_Db_Exception - * @return resource + * @param string $query + * @param mixed $handle + * @param int $op + * @param null $action + * @return resource|SQLiteResult + * @throws Typecho_Db_Query_Exception */ public function query($query, $handle, $op = Typecho_Db::READ, $action = NULL) { @@ -113,7 +80,7 @@ class Typecho_Db_Adapter_SQLite implements Typecho_Db_Adapter */ public function fetch($resource) { - return $this->filterColumnName(sqlite_fetch_array($resource, SQLITE_ASSOC)); + return Typecho_Common::filterSQLite2ColumnName(sqlite_fetch_array($resource, SQLITE_ASSOC)); } /** @@ -124,7 +91,7 @@ class Typecho_Db_Adapter_SQLite implements Typecho_Db_Adapter */ public function fetchObject($resource) { - return (object) $this->filterColumnName(sqlite_fetch_array($resource, SQLITE_ASSOC)); + return (object) $this->fetch($resource); } /** @@ -169,8 +136,8 @@ class Typecho_Db_Adapter_SQLite implements Typecho_Db_Adapter $sql['limit'] = (0 == strlen($sql['limit'])) ? NULL : ' LIMIT ' . $sql['limit']; $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset']; - return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] . - $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; + return Typecho_Common::filterSQLite2CountQuery('SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] . + $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset']); } /**