package database import ( "database/sql" "fmt" "os" "path/filepath" _ "modernc.org/sqlite" ) // DB 数据库实例 type DB struct { *sql.DB } // InitDB 初始化数据库 func InitDB(dbPath string) (*DB, error) { // 确保数据库目录存在 dbDir := filepath.Dir(dbPath) if err := os.MkdirAll(dbDir, 0755); err != nil { return nil, fmt.Errorf("创建数据库目录失败: %v", err) } // 打开数据库连接(使用modernc.org/sqlite驱动) db, err := sql.Open("sqlite", dbPath) if err != nil { return nil, fmt.Errorf("打开数据库失败: %v", err) } // 测试连接 if err := db.Ping(); err != nil { return nil, fmt.Errorf("数据库连接测试失败: %v", err) } // 创建表 if err := createTables(db); err != nil { return nil, fmt.Errorf("创建数据表失败: %v", err) } fmt.Println("✅ 数据库初始化成功:", dbPath) return &DB{db}, nil } // createTables 创建数据表 func createTables(db *sql.DB) error { // 公众号表 officialAccountTable := ` CREATE TABLE IF NOT EXISTS official_accounts ( id INTEGER PRIMARY KEY AUTOINCREMENT, biz TEXT NOT NULL UNIQUE, nickname TEXT NOT NULL, homepage TEXT, description TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX IF NOT EXISTS idx_biz ON official_accounts(biz); CREATE INDEX IF NOT EXISTS idx_nickname ON official_accounts(nickname); ` // 文章表 articleTable := ` CREATE TABLE IF NOT EXISTS articles ( id INTEGER PRIMARY KEY AUTOINCREMENT, official_id INTEGER NOT NULL, title TEXT NOT NULL, author TEXT, link TEXT UNIQUE, publish_time TEXT, create_time TEXT, comment_id TEXT, read_num INTEGER DEFAULT 0, like_num INTEGER DEFAULT 0, share_num INTEGER DEFAULT 0, content_preview TEXT, paragraph_count INTEGER DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (official_id) REFERENCES official_accounts(id) ); CREATE INDEX IF NOT EXISTS idx_official_id ON articles(official_id); CREATE INDEX IF NOT EXISTS idx_title ON articles(title); CREATE INDEX IF NOT EXISTS idx_publish_time ON articles(publish_time); CREATE INDEX IF NOT EXISTS idx_link ON articles(link); ` // 文章内容表 articleContentTable := ` CREATE TABLE IF NOT EXISTS article_contents ( id INTEGER PRIMARY KEY AUTOINCREMENT, article_id INTEGER NOT NULL UNIQUE, html_content TEXT, text_content TEXT, paragraphs TEXT, images TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (article_id) REFERENCES articles(id) ON DELETE CASCADE ); CREATE INDEX IF NOT EXISTS idx_article_id ON article_contents(article_id); ` // 执行创建表语句 tables := []string{officialAccountTable, articleTable, articleContentTable} for _, table := range tables { if _, err := db.Exec(table); err != nil { return err } } return nil } // Close 关闭数据库连接 func (db *DB) Close() error { return db.DB.Close() }