mirror of https://github.com/Wox-launcher/Wox
feat(setting): Refactor settings to use a database-backed store
Refactors the entire settings management system from JSON files to a more robust and scalable SQLite database using GORM. This architectural change lays the foundation for future features like cloud synchronization. Key changes: - Introduces a new `database` package with GORM models for all settings and app data. - Implements a backward-compatible migration system that automatically moves existing users settings from `wox.setting.json` and `wox.app.data.json` to the new `wox.db` file on the first run. - Moves the database location to `userDataDirectory` to align with the projects data storage conventions. - Rewrites the `setting.Manager` to be fully database-driven, replacing all file I/O with GORM operations. - Sacrifices `FavoriteResults` during migration due to the technical limitation of its one-way hash implementation. This resolves the issue of having scattered JSON configuration and provides a centralized, transactional data store.
This commit is contained in:
parent
8bc44b0836
commit
247c970ed2
|
@ -0,0 +1,132 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"wox/common"
|
||||
"wox/util"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
var (
|
||||
db *gorm.DB
|
||||
once sync.Once
|
||||
)
|
||||
|
||||
const dbFileName = "wox.db"
|
||||
|
||||
// Models
|
||||
|
||||
type Setting struct {
|
||||
Key string `gorm:"primaryKey"`
|
||||
Value string
|
||||
}
|
||||
|
||||
type Hotkey struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement"`
|
||||
Hotkey string `gorm:"unique"`
|
||||
Query string
|
||||
IsSilentExecution bool
|
||||
}
|
||||
|
||||
type QueryShortcut struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement"`
|
||||
Shortcut string `gorm:"unique"`
|
||||
Query string
|
||||
}
|
||||
|
||||
type AIProvider struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement"`
|
||||
Name common.ProviderName
|
||||
ApiKey string
|
||||
Host string
|
||||
}
|
||||
|
||||
type QueryHistory struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement"`
|
||||
Query string
|
||||
Timestamp int64
|
||||
}
|
||||
|
||||
type FavoriteResult struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement"`
|
||||
PluginID string `gorm:"uniqueIndex:idx_fav"`
|
||||
Title string `gorm:"uniqueIndex:idx_fav"`
|
||||
Subtitle string `gorm:"uniqueIndex:idx_fav"`
|
||||
}
|
||||
|
||||
type PluginSetting struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement"`
|
||||
PluginID string `gorm:"uniqueIndex:idx_plugin_setting"`
|
||||
Key string `gorm:"uniqueIndex:idx_plugin_setting"`
|
||||
Value string
|
||||
}
|
||||
|
||||
type ActionedResult struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement"`
|
||||
PluginID string
|
||||
Title string
|
||||
Subtitle string
|
||||
Timestamp int64
|
||||
Query string
|
||||
}
|
||||
|
||||
type Oplog struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement"`
|
||||
EntityType string
|
||||
EntityID string
|
||||
Operation string
|
||||
Key string
|
||||
Value string
|
||||
Timestamp int64
|
||||
SyncedToCloud bool `gorm:"default:false"`
|
||||
}
|
||||
|
||||
// Init initializes the database connection and migrates the schema.
|
||||
func Init() error {
|
||||
var err error
|
||||
once.Do(func() {
|
||||
dbPath := filepath.Join(util.GetLocation().GetUserDataDirectory(), dbFileName)
|
||||
|
||||
db, err = gorm.Open(sqlite.Open(dbPath), &gorm.Config{
|
||||
Logger: logger.Default.LogMode(logger.Silent),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to connect to database: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
// AutoMigrate will create tables, columns, and indexes, but not delete them.
|
||||
err = migrateSchema()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to migrate database schema: %w", err)
|
||||
return
|
||||
}
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// GetDB returns the GORM database instance.
|
||||
func GetDB() *gorm.DB {
|
||||
return db
|
||||
}
|
||||
|
||||
// migrateSchema runs GORM's AutoMigrate function.
|
||||
func migrateSchema() error {
|
||||
return db.AutoMigrate(
|
||||
&Setting{},
|
||||
&Hotkey{},
|
||||
&QueryShortcut{},
|
||||
&AIProvider{},
|
||||
&QueryHistory{},
|
||||
&FavoriteResult{},
|
||||
&PluginSetting{},
|
||||
&ActionedResult{},
|
||||
&Oplog{},
|
||||
)
|
||||
}
|
|
@ -27,7 +27,6 @@ require (
|
|||
github.com/olahol/melody v1.2.1
|
||||
github.com/openai/openai-go v0.1.0-beta.6
|
||||
github.com/otiai10/copy v1.14.0
|
||||
|
||||
github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274
|
||||
github.com/robotn/gohook v0.41.0
|
||||
github.com/rs/cors v1.11.1
|
||||
|
@ -65,6 +64,7 @@ require (
|
|||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/invopop/jsonschema v0.12.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
|
@ -93,4 +93,6 @@ require (
|
|||
google.golang.org/protobuf v1.35.1 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gorm.io/driver/sqlite v1.6.0 // indirect
|
||||
gorm.io/gorm v1.30.0 // indirect
|
||||
)
|
||||
|
|
|
@ -50,6 +50,8 @@ github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uO
|
|||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
|
||||
github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
|
@ -232,6 +234,10 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
|||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ=
|
||||
gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8=
|
||||
gorm.io/gorm v1.30.0 h1:qbT5aPv1UH8gI99OsRlvDToLxW5zR7FzS9acZDOZcgs=
|
||||
gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
|
||||
howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM=
|
||||
howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue