mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-25 15:25:50 +00:00
refactor: remove unused better-sqlite3 dependency
- Remove better-sqlite3 from package.json dependencies - Remove @types/better-sqlite3 from devDependencies - Remove unused hardlink.db query logic in videoService (always uses wcdbService/DLL) - Remove unused hardlink.db query logic in chatService (fallback to filesystem search) - Remove HardlinkState type and hardlinkCache - Simplify code by removing dead optimization paths
This commit is contained in:
@@ -6,7 +6,6 @@ import * as https from 'https'
|
||||
import * as http from 'http'
|
||||
import * as fzstd from 'fzstd'
|
||||
import * as crypto from 'crypto'
|
||||
import Database from 'better-sqlite3'
|
||||
import { app, BrowserWindow } from 'electron'
|
||||
import { ConfigService } from './config'
|
||||
import { wcdbService } from './wcdbService'
|
||||
@@ -18,12 +17,6 @@ import { exportCardDiagnosticsService } from './exportCardDiagnosticsService'
|
||||
import { voiceTranscribeService } from './voiceTranscribeService'
|
||||
import { LRUCache } from '../utils/LRUCache.js'
|
||||
|
||||
type HardlinkState = {
|
||||
db: Database.Database
|
||||
imageTable?: string
|
||||
dirTable?: string
|
||||
}
|
||||
|
||||
export interface ChatSession {
|
||||
username: string
|
||||
type: number
|
||||
@@ -213,7 +206,6 @@ class ChatService {
|
||||
private avatarCache: Map<string, ContactCacheEntry>
|
||||
private readonly avatarCacheTtlMs = 10 * 60 * 1000
|
||||
private readonly defaultV1AesKey = 'cfcd208495d565ef'
|
||||
private hardlinkCache = new Map<string, HardlinkState>()
|
||||
private readonly contactCacheService: ContactCacheService
|
||||
private readonly messageCacheService: MessageCacheService
|
||||
private readonly sessionStatsCacheService: SessionStatsCacheService
|
||||
@@ -4852,13 +4844,6 @@ class ChatService {
|
||||
this.groupMyMessageCountCacheService.clearAll()
|
||||
}
|
||||
|
||||
for (const state of this.hardlinkCache.values()) {
|
||||
try {
|
||||
state.db?.close()
|
||||
} catch { }
|
||||
}
|
||||
this.hardlinkCache.clear()
|
||||
|
||||
if (includeEmojis) {
|
||||
emojiCache.clear()
|
||||
emojiDownloading.clear()
|
||||
@@ -6707,10 +6692,6 @@ class ChatService {
|
||||
|
||||
private async findDatFile(accountDir: string, baseName: string, sessionId?: string): Promise<string | null> {
|
||||
const normalized = this.normalizeDatBase(baseName)
|
||||
if (this.looksLikeMd5(normalized)) {
|
||||
const hardlinkPath = this.resolveHardlinkPath(accountDir, normalized, sessionId)
|
||||
if (hardlinkPath) return hardlinkPath
|
||||
}
|
||||
|
||||
const searchPaths = [
|
||||
join(accountDir, 'FileStorage', 'Image'),
|
||||
@@ -6776,68 +6757,6 @@ class ChatService {
|
||||
return /[._][a-z]$/.test(baseLower)
|
||||
}
|
||||
|
||||
private resolveHardlinkPath(accountDir: string, md5: string, sessionId?: string): string | null {
|
||||
try {
|
||||
const hardlinkPath = join(accountDir, 'hardlink.db')
|
||||
if (!existsSync(hardlinkPath)) return null
|
||||
|
||||
const state = this.getHardlinkState(accountDir, hardlinkPath)
|
||||
if (!state.imageTable) return null
|
||||
|
||||
const row = state.db
|
||||
.prepare(`SELECT dir1, dir2, file_name FROM ${state.imageTable} WHERE md5 = ? LIMIT 1`)
|
||||
.get(md5) as { dir1?: string; dir2?: string; file_name?: string } | undefined
|
||||
|
||||
if (!row) return null
|
||||
const dir1 = row.dir1 as string | undefined
|
||||
const dir2 = row.dir2 as string | undefined
|
||||
const fileName = row.file_name as string | undefined
|
||||
if (!dir1 || !dir2 || !fileName) return null
|
||||
const lowerFileName = fileName.toLowerCase()
|
||||
if (lowerFileName.endsWith('.dat')) {
|
||||
const baseLower = lowerFileName.slice(0, -4)
|
||||
if (!this.hasXVariant(baseLower)) return null
|
||||
}
|
||||
|
||||
let dirName = dir2
|
||||
if (state.dirTable && sessionId) {
|
||||
try {
|
||||
const dirRow = state.db
|
||||
.prepare(`SELECT dir_name FROM ${state.dirTable} WHERE dir_id = ? AND username = ? LIMIT 1`)
|
||||
.get(dir2, sessionId) as { dir_name?: string } | undefined
|
||||
if (dirRow?.dir_name) dirName = dirRow.dir_name as string
|
||||
} catch { }
|
||||
}
|
||||
|
||||
const fullPath = join(accountDir, dir1, dirName, fileName)
|
||||
if (existsSync(fullPath)) return fullPath
|
||||
|
||||
const withDat = `${fullPath}.dat`
|
||||
if (existsSync(withDat)) return withDat
|
||||
} catch { }
|
||||
return null
|
||||
}
|
||||
|
||||
private getHardlinkState(accountDir: string, hardlinkPath: string): HardlinkState {
|
||||
const cached = this.hardlinkCache.get(accountDir)
|
||||
if (cached) return cached
|
||||
|
||||
const db = new Database(hardlinkPath, { readonly: true, fileMustExist: true })
|
||||
const imageRow = db
|
||||
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'image_hardlink_info%' ORDER BY name DESC LIMIT 1")
|
||||
.get() as { name?: string } | undefined
|
||||
const dirRow = db
|
||||
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'dir2id%' LIMIT 1")
|
||||
.get() as { name?: string } | undefined
|
||||
const state: HardlinkState = {
|
||||
db,
|
||||
imageTable: imageRow?.name as string | undefined,
|
||||
dirTable: dirRow?.name as string | undefined
|
||||
}
|
||||
this.hardlinkCache.set(accountDir, state)
|
||||
return state
|
||||
}
|
||||
|
||||
private getDatVersion(data: Buffer): number {
|
||||
if (data.length < 6) return 0
|
||||
const sigV1 = Buffer.from([0x07, 0x08, 0x56, 0x31, 0x08, 0x07])
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import { existsSync, readdirSync, statSync, readFileSync, appendFileSync, mkdirSync } from 'fs'
|
||||
import { app } from 'electron'
|
||||
import { ConfigService } from './config'
|
||||
import Database from 'better-sqlite3'
|
||||
import { wcdbService } from './wcdbService'
|
||||
|
||||
export interface VideoInfo {
|
||||
@@ -71,58 +70,21 @@ class VideoService {
|
||||
|
||||
/**
|
||||
* 从 video_hardlink_info_v4 表查询视频文件名
|
||||
* 优先使用 cachePath 中解密后的 hardlink.db(使用 better-sqlite3)
|
||||
* 如果失败,则尝试使用 wcdbService.execQuery 查询加密的 hardlink.db
|
||||
* 使用 wcdbService.execQuery 查询加密的 hardlink.db
|
||||
*/
|
||||
private async queryVideoFileName(md5: string): Promise<string | undefined> {
|
||||
const cachePath = this.getCachePath()
|
||||
const dbPath = this.getDbPath()
|
||||
const wxid = this.getMyWxid()
|
||||
const cleanedWxid = this.cleanWxid(wxid)
|
||||
|
||||
this.log('queryVideoFileName 开始', { md5, wxid, cleanedWxid, cachePath, dbPath })
|
||||
this.log('queryVideoFileName 开始', { md5, wxid, cleanedWxid, dbPath })
|
||||
|
||||
if (!wxid) {
|
||||
this.log('queryVideoFileName: wxid 为空')
|
||||
return undefined
|
||||
}
|
||||
|
||||
// 方法1:优先在 cachePath 下查找解密后的 hardlink.db
|
||||
if (cachePath) {
|
||||
const cacheDbPaths = [
|
||||
join(cachePath, cleanedWxid, 'hardlink.db'),
|
||||
join(cachePath, wxid, 'hardlink.db'),
|
||||
join(cachePath, 'hardlink.db'),
|
||||
join(cachePath, 'databases', cleanedWxid, 'hardlink.db'),
|
||||
join(cachePath, 'databases', wxid, 'hardlink.db')
|
||||
]
|
||||
|
||||
for (const p of cacheDbPaths) {
|
||||
if (existsSync(p)) {
|
||||
try {
|
||||
this.log('尝试缓存 hardlink.db', { path: p })
|
||||
const db = new Database(p, { readonly: true })
|
||||
const row = db.prepare(`
|
||||
SELECT file_name, md5 FROM video_hardlink_info_v4
|
||||
WHERE md5 = ?
|
||||
LIMIT 1
|
||||
`).get(md5) as { file_name: string; md5: string } | undefined
|
||||
db.close()
|
||||
|
||||
if (row?.file_name) {
|
||||
const realMd5 = row.file_name.replace(/\.[^.]+$/, '')
|
||||
this.log('缓存 hardlink.db 命中', { file_name: row.file_name, realMd5 })
|
||||
return realMd5
|
||||
}
|
||||
this.log('缓存 hardlink.db 未命中', { path: p })
|
||||
} catch (e) {
|
||||
this.log('缓存 hardlink.db 查询失败', { path: p, error: String(e) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 方法2:使用 wcdbService.execQuery 查询加密的 hardlink.db
|
||||
// 使用 wcdbService.execQuery 查询加密的 hardlink.db
|
||||
if (dbPath) {
|
||||
const dbPathLower = dbPath.toLowerCase()
|
||||
const wxidLower = wxid.toLowerCase()
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
"electron:build": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"better-sqlite3": "^12.5.0",
|
||||
"echarts": "^5.5.1",
|
||||
"echarts-for-react": "^3.0.2",
|
||||
"electron-store": "^10.0.0",
|
||||
@@ -46,7 +45,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron/rebuild": "^4.0.2",
|
||||
"@types/better-sqlite3": "^7.6.13",
|
||||
"@types/react": "^19.1.0",
|
||||
"@types/react-dom": "^19.1.0",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
|
||||
Reference in New Issue
Block a user