'use strict'; // ============================================ // 蜂鸟Pro SQLite Utils - 反混淆版本 // ============================================ Object.defineProperty(exports, "__esModule", { value: true }); const child_process = require('child_process'); const util = require('util'); const fs = require('fs'); const path = require('path'); const os = require('os'); const execAsync = util.promisify(child_process.exec); /** * 转义 SQL 字符串中的单引号 */ function escapeSqlString(value) { if (value === null || value === undefined) { return ''; } return String(value).replace(/'/g, "''"); } /** * 执行 SQLite 命令 */ async function execSqlite(dbPath, sql) { const isWindows = process.platform === 'win32'; try { if (isWindows) { // Windows: 直接使用 sqlite3 命令 const escapedSql = sql.replace(/"/g, '\\"'); const command = `sqlite3 "${dbPath}" "${escapedSql}"`; const { stdout, stderr } = await execAsync(command, { encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 }); if (stderr && !stderr.includes('-- Loading')) { console.warn('[SQLite] stderr:', stderr); } return stdout.trim(); } else { // Unix/Mac: 使用临时文件避免命令行转义问题 const tmpFile = path.join(os.tmpdir(), 'cursor_sql_' + Date.now() + '.sql'); fs.writeFileSync(tmpFile, sql, 'utf-8'); try { const command = `sqlite3 "${dbPath}" < "${tmpFile}"`; const { stdout, stderr } = await execAsync(command, { encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024, shell: '/bin/bash' }); if (stderr && !stderr.includes('-- Loading')) { console.warn('[SQLite] stderr:', stderr); } return stdout.trim(); } finally { try { fs.unlinkSync(tmpFile); } catch (e) { // 忽略删除临时文件失败 } } } } catch (error) { // 检查是否是 sqlite3 不存在的错误 if (error.code === 'ENOENT' || error.message?.includes('not found') || error.message?.includes('not recognized')) { throw new Error('sqlite3 命令未找到,请确保已安装 sqlite3'); } throw error; } } /** * 从 SQLite 数据库读取值 */ async function sqliteGet(dbPath, key) { if (!fs.existsSync(dbPath)) { console.warn('[SQLite] 数据库文件不存在:', dbPath); return null; } try { const sql = `SELECT value FROM ItemTable WHERE key = '${escapeSqlString(key)}';`; const result = await execSqlite(dbPath, sql); return result || null; } catch (error) { console.error('[SQLite] 读取失败:', error); return null; } } exports.sqliteGet = sqliteGet; /** * 向 SQLite 数据库写入值 */ async function sqliteSet(dbPath, key, value) { if (!fs.existsSync(dbPath)) { console.warn('[SQLite] 数据库文件不存在:', dbPath); return false; } try { const sql = `INSERT OR REPLACE INTO ItemTable (key, value) VALUES ('${escapeSqlString(key)}', '${escapeSqlString(value)}');`; await execSqlite(dbPath, sql); return true; } catch (error) { console.error('[SQLite] 写入失败:', error); return false; } } exports.sqliteSet = sqliteSet; /** * 批量写入 SQLite 数据库 */ async function sqliteSetBatch(dbPath, entries) { if (!fs.existsSync(dbPath)) { console.warn('[SQLite] 数据库文件不存在:', dbPath); return false; } if (entries.length === 0) { return true; } try { const statements = entries.map(([key, value]) => `INSERT OR REPLACE INTO ItemTable (key, value) VALUES ('${escapeSqlString(key)}', '${escapeSqlString(value)}');` ); const sql = 'BEGIN; ' + statements.join(' ') + ' COMMIT;'; await execSqlite(dbPath, sql); return true; } catch (error) { console.error('[SQLite] 批量写入失败:', error); return false; } } exports.sqliteSetBatch = sqliteSetBatch; /** * 批量读取 SQLite 数据库 */ async function sqliteGetBatch(dbPath, keys) { const result = new Map(); if (!fs.existsSync(dbPath)) { console.warn('[SQLite] 数据库文件不存在:', dbPath); keys.forEach(key => result.set(key, null)); return result; } try { for (const key of keys) { const value = await sqliteGet(dbPath, key); result.set(key, value); } return result; } catch (error) { console.error('[SQLite] 批量读取失败:', error); keys.forEach(key => result.set(key, null)); return result; } } exports.sqliteGetBatch = sqliteGetBatch;