修复数据库迁移脚本,优化关键词表结构

This commit is contained in:
wood chen 2024-09-28 15:31:37 +08:00
parent a093f712f8
commit 20594715d2
2 changed files with 64 additions and 72 deletions

View File

@ -43,17 +43,28 @@ func NewDatabase() (*Database, error) {
func (d *Database) createTables() error { func (d *Database) createTables() error {
queries := []string{ queries := []string{
`CREATE TABLE IF NOT EXISTS keywords `CREATE TABLE IF NOT EXISTS keywords (
(id INTEGER PRIMARY KEY, keyword TEXT UNIQUE, is_link BOOLEAN, is_auto_added BOOLEAN, added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)`, id INTEGER PRIMARY KEY,
keyword TEXT UNIQUE,
is_link BOOLEAN DEFAULT FALSE,
is_auto_added BOOLEAN DEFAULT FALSE,
added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)`,
`CREATE INDEX IF NOT EXISTS idx_keyword ON keywords(keyword)`, `CREATE INDEX IF NOT EXISTS idx_keyword ON keywords(keyword)`,
`CREATE INDEX IF NOT EXISTS idx_added_at ON keywords(added_at)`, `CREATE INDEX IF NOT EXISTS idx_added_at ON keywords(added_at)`,
`CREATE INDEX IF NOT EXISTS idx_is_link ON keywords(is_link)`, `CREATE TABLE IF NOT EXISTS whitelist (
`CREATE INDEX IF NOT EXISTS idx_is_auto_added ON keywords(is_auto_added)`, id INTEGER PRIMARY KEY,
`CREATE TABLE IF NOT EXISTS whitelist domain TEXT UNIQUE
(id INTEGER PRIMARY KEY, domain TEXT UNIQUE)`, )`,
`CREATE INDEX IF NOT EXISTS idx_domain ON whitelist(domain)`, `CREATE INDEX IF NOT EXISTS idx_domain ON whitelist(domain)`,
`CREATE TABLE IF NOT EXISTS prompt_replies `CREATE TABLE IF NOT EXISTS prompt_replies (
(prompt TEXT PRIMARY KEY, reply TEXT NOT NULL)`, prompt TEXT PRIMARY KEY,
reply TEXT NOT NULL
)`,
`CREATE TABLE IF NOT EXISTS config (
key TEXT PRIMARY KEY,
value TEXT
)`,
} }
for _, query := range queries { for _, query := range queries {
@ -358,87 +369,62 @@ func (d *Database) MigrateExistingKeywords() error {
return nil // 迁移已经完成,无需再次执行 return nil // 迁移已经完成,无需再次执行
} }
// 开始事务 // 检查旧表是否存在
tx, err := d.db.Begin() var tableExists bool
if err != nil { err = d.db.QueryRow("SELECT name FROM sqlite_master WHERE type='table' AND name='keywords'").Scan(&tableExists)
if err != nil && err != sql.ErrNoRows {
return err return err
} }
defer tx.Rollback()
// 获取所有现有的关键词 if tableExists {
rows, err := tx.Query("SELECT keyword FROM keywords") // 检查 added_at 列是否存在
if err != nil { var columnExists bool
return err err = d.db.QueryRow("SELECT 1 FROM pragma_table_info('keywords') WHERE name='added_at'").Scan(&columnExists)
} if err != nil && err != sql.ErrNoRows {
defer rows.Close()
// 准备插入语句
stmt, err := tx.Prepare("INSERT INTO keywords (keyword, is_link, is_auto_added) VALUES (?, ?, ?)")
if err != nil {
return err
}
defer stmt.Close()
// 迁移现有关键词
for rows.Next() {
var keyword string
if err := rows.Scan(&keyword); err != nil {
return err return err
} }
// 这里我们假设所有现有的关键词都是手动添加的非链接关键词 if !columnExists {
_, err = stmt.Exec(keyword, false, false) // 如果 added_at 列不存在,添加它
if err != nil { _, err = d.db.Exec("ALTER TABLE keywords ADD COLUMN added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
if err != nil {
return err
}
}
// 检查 is_link 和 is_auto_added 列是否存在
err = d.db.QueryRow("SELECT 1 FROM pragma_table_info('keywords') WHERE name='is_link'").Scan(&columnExists)
if err != nil && err != sql.ErrNoRows {
return err return err
} }
}
// 删除旧的关键词表 if !columnExists {
_, err = tx.Exec("DROP TABLE IF EXISTS old_keywords") // 如果 is_link 列不存在,添加它
if err != nil { _, err = d.db.Exec("ALTER TABLE keywords ADD COLUMN is_link BOOLEAN DEFAULT FALSE")
return err if err != nil {
} return err
}
}
// 重命名现有的关键词表 err = d.db.QueryRow("SELECT 1 FROM pragma_table_info('keywords') WHERE name='is_auto_added'").Scan(&columnExists)
_, err = tx.Exec("ALTER TABLE keywords RENAME TO old_keywords") if err != nil && err != sql.ErrNoRows {
if err != nil { return err
return err }
}
// 创建新的关键词表 if !columnExists {
_, err = tx.Exec(`CREATE TABLE keywords ( // 如果 is_auto_added 列不存在,添加它
id INTEGER PRIMARY KEY, _, err = d.db.Exec("ALTER TABLE keywords ADD COLUMN is_auto_added BOOLEAN DEFAULT FALSE")
keyword TEXT UNIQUE, if err != nil {
is_link BOOLEAN, return err
is_auto_added BOOLEAN, }
added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP }
)`)
if err != nil {
return err
}
// 将数据从旧表复制到新表
_, err = tx.Exec("INSERT INTO keywords SELECT id, keyword, is_link, is_auto_added, added_at FROM old_keywords")
if err != nil {
return err
}
// 删除旧表
_, err = tx.Exec("DROP TABLE old_keywords")
if err != nil {
return err
} }
// 更新配置,标记迁移已完成 // 更新配置,标记迁移已完成
_, err = tx.Exec("INSERT OR REPLACE INTO config (key, value) VALUES ('keywords_migrated', 'true')") _, err = d.db.Exec("INSERT OR REPLACE INTO config (key, value) VALUES ('keywords_migrated', 'true')")
if err != nil { if err != nil {
return err return err
} }
// 提交事务
if err := tx.Commit(); err != nil {
return err
}
return nil return nil
} }

View File

@ -45,6 +45,12 @@ func Init() error {
return fmt.Errorf("初始化数据库失败: %v", err) return fmt.Errorf("初始化数据库失败: %v", err)
} }
// 确保表已创建
err = DB.createTables()
if err != nil {
return fmt.Errorf("创建数据库表失败: %v", err)
}
// 执行数据迁移 // 执行数据迁移
err = DB.MigrateExistingKeywords() err = DB.MigrateExistingKeywords()
if err != nil { if err != nil {