Files
BiliDown/internal/util/db.go
T
yw1573 dd8eaef97d refactor: restructure project to standard Go layout
- Reorganize code into cmd/bilidown and internal/ packages
- Rename client/ to web/ for frontend source
- Remove systray dependency for headless web service
- Embed static files into binary using go:embed
- Update import paths to use internal/ prefix
- Update .gitignore with common patterns

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 17:21:49 +08:00

152 lines
3.1 KiB
Go

package util
import (
"database/sql"
"errors"
"fmt"
"log"
"os"
"strings"
"sync"
)
func CreateLog(db *sql.DB, content string) error {
SqliteLock.Lock()
_, err := db.Exec(`INSERT INTO "log" ("content") VALUES (?)`, content)
SqliteLock.Unlock()
return err
}
func GetFields(db *sql.DB, names ...string) (map[string]string, error) {
if len(names) == 0 {
return nil, nil
}
placeholders := make([]string, len(names))
for i := 0; i < len(names); i++ {
placeholders[i] = "?"
}
query := fmt.Sprintf(`SELECT "name", "value" FROM "field" WHERE "name" IN (%s)`, strings.Join(placeholders, ","))
values := make([]interface{}, len(names))
for i := 0; i < len(names); i++ {
values[i] = names[i]
}
SqliteLock.Lock()
row, err := db.Query(query, values...)
SqliteLock.Unlock()
if err != nil {
return nil, err
}
defer row.Close()
var name, value string
fields := make(map[string]string)
for row.Next() {
if err := row.Scan(&name, &value); err != nil {
return nil, err
}
fields[name] = value
}
return fields, nil
}
func SaveFields(db *sql.DB, data [][2]string) error {
if len(data) == 0 {
return nil
}
tx, err := db.Begin()
if err != nil {
return err
}
defer func() {
if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()
stmt, err := tx.Prepare(`INSERT OR REPLACE INTO "field" ("name", "value") VALUES (?, ?)`)
if err != nil {
return err
}
defer stmt.Close()
for _, d := range data {
SqliteLock.Lock()
_, err = stmt.Exec(d[0], d[1])
SqliteLock.Unlock()
if err != nil {
return err
}
}
return nil
}
// GetCurrentFolder 获取数据库中的下载保存路径,如果不存在则将默认路径保存到数据库
func GetCurrentFolder(db *sql.DB) (string, error) {
var folder string
SqliteLock.Lock()
err := db.QueryRow(`SELECT "value" FROM "field" WHERE "name" = 'download_folder'`).Scan(&folder)
SqliteLock.Unlock()
if err != nil && err == sql.ErrNoRows {
folder, err = GetDefaultDownloadFolder()
if err != nil {
return "", err
}
err = os.MkdirAll(folder, os.ModePerm)
if err != nil {
return "", err
}
err = SaveDownloadFolder(db, folder)
if err != nil {
return "", err
}
return folder, nil
}
err = os.MkdirAll(folder, os.ModePerm)
if err != nil {
return "", err
}
return folder, nil
}
// SaveDownloadFolder 保存下载路径,不存在则自动创建
func SaveDownloadFolder(db *sql.DB, downloadFolder string) error {
_, err := os.Stat(downloadFolder)
if err != nil {
if os.IsNotExist(err) {
err = os.MkdirAll(downloadFolder, os.ModePerm)
if err != nil {
return err
}
}
return err
}
SqliteLock.Lock()
_, err = db.Exec(`INSERT OR REPLACE INTO "field" ("name", "value") VALUES ('download_folder', ?)`, downloadFolder)
SqliteLock.Unlock()
return err
}
var SqliteLock sync.Mutex
func MustGetDB(path ...string) *sql.DB {
pathStr := ""
if len(path) == 0 {
pathStr = "./data.db"
} else if len(path) > 1 {
log.Fatalln(errors.New("len(path) <= 1"))
} else {
pathStr = path[0]
}
db, err := sql.Open("sqlite", pathStr)
if err != nil {
log.Fatalln("sql.Open:", err)
}
return db
}