| @@ -170,22 +170,7 @@ else if ($step==2) { | |||
| $query .= $line."\n"; | |||
| $query = str_replace('#@__', $dbprefix, $query); | |||
| if ($dbtype == 'sqlite') { | |||
| $query = preg_replace('/character set (.*?) /i','', $query); | |||
| $query = preg_replace('/unsigned/i','', $query); | |||
| $query = str_replace('TYPE=MyISAM','', $query); | |||
| $query = preg_replace ('/TINYINT\(([\d]+)\)/i','INTEGER', $query); | |||
| $query = preg_replace ('/mediumint\(([\d]+)\)/i','INTEGER', $query); | |||
| $query = preg_replace ('/smallint\(([\d]+)\)/i','INTEGER', $query); | |||
| $query = preg_replace('/int\(([\d]+)\)/i','INTEGER', $query); | |||
| $query = preg_replace('/auto_increment/i','PRIMARY KEY AUTOINCREMENT', $query); | |||
| $query = preg_replace('/,([\t\s ]+)KEY(.*?)MyISAM;/','', $query); | |||
| $query = preg_replace('/,([\t\s ]+)KEY(.*?);/',');', $query); | |||
| $query = preg_replace('/,([\t\s ]+)UNIQUE KEY(.*?);/',');', $query); | |||
| $query = preg_replace('/set\(([^\)]*?)\)/','varchar', $query); | |||
| $query = preg_replace('/enum\(([^\)]*?)\)/','varchar', $query); | |||
| if (preg_match("/PRIMARY KEY AUTOINCREMENT/", $query)) { | |||
| $query = preg_replace('/,([\t\s ]+)PRIMARY KEY([\t\s ]+)\(`([0-9a-zA-Z]+)`\)/i','', $query); | |||
| } | |||
| $query = ConvertMysqlToSqlite($query); | |||
| $db->exec($query); | |||
| } else { | |||
| if (preg_match('#CREATE#i', $query)) { | |||
| @@ -113,8 +113,10 @@ | |||
| $("#dbtype").change(function() { | |||
| if ($(this).val() === 'sqlite') { | |||
| $(".form-group.server").hide(); | |||
| $("#dbpwd").prop("required", false); | |||
| } else { | |||
| $(".form-group.server").show(); | |||
| $("#dbpwd").prop("required", true); | |||
| } | |||
| }); | |||
| </script> | |||
| @@ -365,14 +365,24 @@ function ShowMsg($msg, $gourl, $onlymsg = 0, $limittime = 0) | |||
| */ | |||
| function TableHasField($tablename, $field) | |||
| { | |||
| global $dsql; | |||
| $dsql->GetTableFields($tablename,"tfd"); | |||
| while ($r = $dsql->GetFieldObject("tfd")) { | |||
| if ($r->name === $field) { | |||
| return true; | |||
| global $dsql,$cfg_dbtype; | |||
| if ($cfg_dbtype === 'mysql') { | |||
| $dsql->GetTableFields($tablename,"tfd"); | |||
| while ($r = $dsql->GetFieldObject("tfd")) { | |||
| if ($r->name === $field) { | |||
| return true; | |||
| } | |||
| } | |||
| return false; | |||
| } elseif ($cfg_dbtype === 'sqlite') { | |||
| $k = $dsql->GetTableFields($tablename); | |||
| while ($r = $dsql->GetFieldObject($k)) { | |||
| if ($r->name === $field) { | |||
| return true; | |||
| } | |||
| } | |||
| return false; | |||
| } | |||
| return false; | |||
| } | |||
| function GetSimpleServerSoftware() | |||
| { | |||
| @@ -459,7 +469,7 @@ function GetUpdateSQL() | |||
| $result = array(); | |||
| $query = ''; | |||
| $sql4tmp = "ENGINE=MyISAM DEFAULT CHARSET=".$cfg_db_language; | |||
| $fp = fopen(DEDEROOT.'/install/update.txt','r'); | |||
| $fp = fopen(DEDEDATA.'/admin/update.txt','r'); | |||
| $sqls = array(); | |||
| $current_ver = ''; | |||
| while(!feof($fp)) | |||
| @@ -692,6 +702,108 @@ function DedeSearchAPIURL($action, $parms=array()) | |||
| return $finalUrl; | |||
| } | |||
| function ConvertMysqlToSqlite($mysqlQuery) { | |||
| // 移除 CHARACTER SET 和 COLLATE | |||
| $query = preg_replace('/character set \S+/i', '', $mysqlQuery); | |||
| $query = preg_replace('/collate \S+/i', '', $query); | |||
| // 移除 unsigned 关键字 | |||
| $query = str_replace('unsigned', '', $query); | |||
| // 替换 MySQL 的整数类型为 SQLite 的 INTEGER | |||
| $query = preg_replace('/\b(TINY|SMALL|MEDIUM|BIG)?INT\(\d+\)/i', 'INTEGER', $query); | |||
| // 替换 AUTO_INCREMENT 为 PRIMARY KEY AUTOINCREMENT (仅适用于 INTEGER 类型) | |||
| $query = preg_replace('/\bINTEGER\s+NOT NULL\s+PRIMARY KEY AUTOINCREMENT/i', 'INTEGER PRIMARY KEY AUTOINCREMENT', $query); | |||
| $query = preg_replace('/\bAUTO_INCREMENT\b/i', '', $query); | |||
| // 移除 MySQL 特有的 ENGINE、CHARSET、COLLATE、TYPE 选项 | |||
| $query = preg_replace('/ENGINE=\S+/i', '', $query); | |||
| $query = preg_replace('/DEFAULT CHARSET=\S+/i', '', $query); | |||
| $query = preg_replace('/COLLATE=\S+/i', '', $query); | |||
| $query = preg_replace('/TYPE=MyISAM;/i', '', $query); | |||
| // 移除 COMMENT 语法(SQLite 不支持) | |||
| $query = preg_replace('/COMMENT\s+\'[^\']*\'/i', '', $query); | |||
| // 移除 KEY 和 UNIQUE KEY 定义(SQLite 会自动管理索引),同时处理 USING BTREE | |||
| $query = preg_replace('/,?\s*KEY\s+\S+\s*\([^)]*\)\s*(USING BTREE)?/i', '', $query); | |||
| $query = preg_replace('/,?\s*UNIQUE KEY\s+\S+\s*\([^)]*\)\s*(USING BTREE)?/i', '', $query); | |||
| // 移除不完整的 UNIQUE 定义 | |||
| $query = preg_replace('/,?\s*UNIQUE\s*(?!\()/', '', $query); | |||
| // 替换 ENUM 和 SET 为 TEXT | |||
| $query = preg_replace('/\b(ENUM|SET)\([^)]*\)/i', 'TEXT', $query); | |||
| // 替换 MEDIUMTEXT 为 TEXT | |||
| $query = preg_replace('/\bMEDIUMTEXT\b/i', 'TEXT', $query); | |||
| // 处理 DEFAULT CURRENT_TIMESTAMP | |||
| $query = preg_replace('/DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP/i', 'DEFAULT CURRENT_TIMESTAMP', $query); | |||
| // 处理 DEFAULT 值 | |||
| $query = preg_replace('/DEFAULT\s+\'([^\']+)\'/i', 'DEFAULT "$1"', $query); | |||
| // 处理 PRIMARY KEY 只能用于 INTEGER | |||
| if (preg_match('/PRIMARY KEY \(`(\w+)`\)/', $query, $matches)) { | |||
| $primaryKeyColumn = $matches[1]; | |||
| $query = preg_replace('/,?\s*PRIMARY KEY\s*\(`' . $primaryKeyColumn . '`\)/i', '', $query); | |||
| $query = preg_replace('/(`' . $primaryKeyColumn . '`\s+INTEGER)/i', '$1 PRIMARY KEY', $query); | |||
| } | |||
| // 处理 CONCAT 替换为 SQLite 兼容形式 | |||
| if (preg_match('/CONCAT\(([^)]*?)\)/i', $query, $matches)) { | |||
| $query = preg_replace('/CONCAT\(([^)]*?)\)/i', str_replace(",", "||", $matches[1]), $query); | |||
| $query = str_replace("'||'", "','", $query); | |||
| } | |||
| // 修正 FIND_IN_SET 替换 | |||
| $query = preg_replace("/FIND_IN_SET\('([\w]+)', arc.flag\)>0/i", "(',' || arc.flag || ',') LIKE '%,\\1,%'", $query); | |||
| $query = preg_replace("/FIND_IN_SET\('([\w]+)', arc.flag\)<1/i", "(',' || arc.flag || ',') NOT LIKE '%,\\1,%'", $query); | |||
| // 修正 FIND_IN_SET 替换(允许列名包含点号) | |||
| $query = preg_replace_callback( | |||
| "/FIND_IN_SET\s*\(\s*'([^']+)'\s*,\s*([a-zA-Z0-9_`\.]+)\s*\)/i", | |||
| function ($matches) { | |||
| // 返回 SQLite 兼容的 LIKE 语法 | |||
| return "(',' || " . $matches[2] . " || ',' LIKE '%," . $matches[1] . ",%')"; | |||
| }, | |||
| $query | |||
| ); | |||
| // 替换 FIELD 函数为 CASE 表达式 | |||
| $query = preg_replace_callback( | |||
| '/\bFIELD\s*\(\s*([^,]+)\s*,\s*((?:\'[^\']+\'|`[^`]+`|[^),]+(?:,\s*)?)+)\s*\)/i', | |||
| function ($matches) { | |||
| $field = trim($matches[1]); | |||
| $values = trim($matches[2]); | |||
| // 更精确分割值列表(支持带引号、反引号及无空格分隔的数值) | |||
| preg_match_all('/\'[^\']+\'|`[^`]+`|\d+|\w+/', $values, $valueParts); | |||
| $cases = []; | |||
| $position = 1; | |||
| foreach ($valueParts[0] as $value) { | |||
| $cases[] = "WHEN $field = $value THEN $position"; | |||
| $position++; | |||
| } | |||
| return "(CASE " . implode(' ', $cases) . " ELSE 0 END)"; | |||
| }, | |||
| $query | |||
| ); | |||
| // 新增的转换逻辑 | |||
| $query = preg_replace("/SHOW fields FROM `([\w]+)`/i", "PRAGMA table_info('\\1') ", $query); | |||
| $query = preg_replace("/SHOW CREATE TABLE `([\w]+)`/i", "SELECT 0,sql FROM sqlite_master WHERE name='\\1'; ", $query); | |||
| $query = preg_replace("/Show Tables/i", "SELECT name FROM sqlite_master WHERE type = \"table\"", $query); | |||
| $query = str_replace("\'", "\"", $query); | |||
| $query = str_replace('\t\n', "", $query); | |||
| $query = str_ireplace('rand', 'RANDOM', $query); | |||
| return trim($query); | |||
| } | |||
| //自定义函数接口 | |||
| if (file_exists(DEDEINC.'/extend.func.php')) { | |||
| require_once(DEDEINC.'/extend.func.php'); | |||
| @@ -56,7 +56,7 @@ class DedeSqlite | |||
| var $isInit = false; | |||
| var $pconnect = false; | |||
| var $_fixObject; | |||
| var $_fieldIdx = 1; //这里最好是数组,对应id,但由于用的地方不多,暂时先这样处理 | |||
| var $_fieldIdx = array(); //这里最好是数组,对应id,但由于用的地方不多,暂时先这样处理 | |||
| //用外部定义的变量初始类,并连接数据库 | |||
| function __construct($pconnect = FALSE, $nconnect = FALSE) | |||
| { | |||
| @@ -253,7 +253,7 @@ class DedeSqlite | |||
| CheckSql($this->queryString); | |||
| } | |||
| $t1 = ExecTime(); | |||
| //var_dump($this->queryString); | |||
| // var_dump($this->queryString); | |||
| $this->result[$id] = $this->linkID->query($this->queryString); | |||
| if (!$this->result[$id]) { | |||
| $this->DisplayError("执行SQL错误:{$this->linkID->lastErrorMsg()}"); | |||
| @@ -386,7 +386,7 @@ class DedeSqlite | |||
| return $sqlite_version; | |||
| } | |||
| //获取特定表的信息 | |||
| function GetTableFields($tbname, $id = "me") | |||
| function GetTableFields($tbname) | |||
| { | |||
| global $dsqlite; | |||
| if (!$dsqlite->isInit) { | |||
| @@ -395,29 +395,27 @@ class DedeSqlite | |||
| $prefix = "#@__"; | |||
| $tbname = str_replace($prefix, $GLOBALS['cfg_dbprefix'], $tbname); | |||
| $query = "SELECT * FROM {$tbname} LIMIT 1"; | |||
| $this->result[$id] = $this->linkID->query($query); | |||
| $result = $this->linkID->query($query); | |||
| $key = spl_object_hash($result); | |||
| $this->result[$key] = $result; | |||
| $this->_fieldIdx[$key] = 0; | |||
| return $key ; | |||
| } | |||
| //获取字段详细信息 | |||
| function GetFieldObject($id = "me") | |||
| { | |||
| if (!$this->result[$id]) { | |||
| if (!isset($this->result[$id]) || !$this->result[$id]) { | |||
| return false; | |||
| } | |||
| $cols = $this->result[$id]->numColumns(); | |||
| if ($this->_fieldIdx >= $cols) { | |||
| $this->_fieldIdx = 1; | |||
| if ($this->_fieldIdx[$id] >= $cols) { | |||
| return false; | |||
| } | |||
| for ($i = 1; $i <= $cols; $i++) { | |||
| $field = new stdClass; | |||
| $n = $this->result[$id]->columnName($i); | |||
| $field->name = $n; | |||
| if ($this->_fieldIdx === $i) { | |||
| $this->_fieldIdx++; | |||
| return $field; | |||
| } | |||
| } | |||
| return false; | |||
| $n = $this->result[$id]->columnName($this->_fieldIdx[$id]); | |||
| $field = new stdClass(); | |||
| $field->name = $n; | |||
| $this->_fieldIdx[$id]++; | |||
| return $field; | |||
| } | |||
| //获得查询的总记录数 | |||
| function GetTotalRow($id = "me") | |||
| @@ -460,41 +458,7 @@ class DedeSqlite | |||
| { | |||
| $prefix = "#@__"; | |||
| $sql = str_replace($prefix, $GLOBALS['cfg_dbprefix'], $sql); | |||
| $this->queryString = $sql; | |||
| //$this->queryString = preg_replace("/CONCAT\(',', arc.typeid2, ','\)/i","printf(',%s,', arc.typeid2)",$this->queryString); | |||
| if (preg_match("/CONCAT\(([^\)]*?)\)/i", $this->queryString, $matches)) { | |||
| $this->queryString = preg_replace("/CONCAT\(([^\)]*?)\)/i", str_replace(",", "||", $matches[1]), $this->queryString); | |||
| $this->queryString = str_replace("'||'", "','", $this->queryString); | |||
| } | |||
| $this->queryString = preg_replace("/FIND_IN_SET\('([\w]+)', arc.flag\)>0/i", "(',' || arc.flag || ',') LIKE '%,\\1,%'", $this->queryString); | |||
| $this->queryString = preg_replace("/FIND_IN_SET\('([\w]+)', arc.flag\)<1/i", "(',' || arc.flag || ',') NOT LIKE '%,\\1,%'", $this->queryString); | |||
| if (preg_match("/CREATE TABLE/i", $this->queryString)) { | |||
| $this->queryString = preg_replace("/[\r\n]/", '', $this->queryString); | |||
| $this->queryString = preg_replace('/character set (.*?) /i', '', $this->queryString); | |||
| $this->queryString = preg_replace('/unsigned/i', '', $this->queryString); | |||
| $this->queryString = str_replace('TYPE=MyISAM', '', $this->queryString); | |||
| $this->queryString = preg_replace('/TINYINT\(([\d]+)\)/i', 'INTEGER', $this->queryString); | |||
| $this->queryString = preg_replace('/mediumint\(([\d]+)\)/i', 'INTEGER', $this->queryString); | |||
| $this->queryString = preg_replace('/smallint\(([\d]+)\)/i', 'INTEGER', $this->queryString); | |||
| $this->queryString = preg_replace('/int\(([\d]+)\)/i', 'INTEGER', $this->queryString); | |||
| $this->queryString = preg_replace('/auto_increment/i', 'PRIMARY KEY AUTOINCREMENT', $this->queryString); | |||
| $this->queryString = preg_replace('/, KEY(.*?)MyISAM;/i', '', $this->queryString); | |||
| $this->queryString = preg_replace('/, KEY(.*?);/i', ');', $this->queryString); | |||
| $this->queryString = preg_replace('/, UNIQUE KEY(.*?);/i', ');', $this->queryString); | |||
| $this->queryString = preg_replace('/set\(([^\)]*?)\)/', 'varchar', $this->queryString); | |||
| $this->queryString = preg_replace('/enum\(([^\)]*?)\)/', 'varchar', $this->queryString); | |||
| if (preg_match("/PRIMARY KEY AUTOINCREMENT/", $this->queryString)) { | |||
| $this->queryString = preg_replace('/,([\t\s ]+)PRIMARY KEY \(`([0-9a-zA-Z]+)`\)/i', '', $this->queryString); | |||
| $this->queryString = str_replace(', PRIMARY KEY (`id`)', '', $this->queryString); | |||
| } | |||
| } | |||
| $this->queryString = preg_replace("/SHOW fields FROM `([\w]+)`/i", "PRAGMA table_info('\\1') ", $this->queryString); | |||
| $this->queryString = preg_replace("/SHOW CREATE TABLE .([\w]+)/i", "SELECT 0,sql FROM sqlite_master WHERE name='\\1'; ", $this->queryString); | |||
| //var_dump($this->queryString); | |||
| $this->queryString = preg_replace("/Show Tables/i", "SELECT name FROM sqlite_master WHERE type = \"table\"", $this->queryString); | |||
| $this->queryString = str_replace("\'", "\"", $this->queryString); | |||
| $this->queryString = str_replace('\t\n', "", $this->queryString); | |||
| $this->queryString = str_ireplace('rand', 'RANDOM', $this->queryString); | |||
| $this->queryString = ConvertMysqlToSqlite($sql); | |||
| //var_dump($this->queryString); | |||
| } | |||
| function SetSql($sql) | |||