Skip to content

Commit

Permalink
feat(db): 多数据源支持和部分修正 (#1166)
Browse files Browse the repository at this point in the history
Co-authored-by: bugtower100 <[email protected]>
Co-authored-by: fy <[email protected]>
  • Loading branch information
3 people authored Dec 29, 2024
1 parent fb44c24 commit 230748f
Show file tree
Hide file tree
Showing 26 changed files with 889 additions and 481 deletions.
8 changes: 8 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# DB_TYPE=mysql
# DB_DSN="root:root@tcp(127.0.0.1:3306)/nokoti?charset=utf8mb4&parseTime=True&loc=Local"

# DB_TYPE=postgres
# DB_DSN="postgres://postgres:pinenut666@localhost:5432/nokoti?sslmode=disable"
# SQLITE IS DIFFERENT
DB_TYPE=sqlite
# DATA_DIR="./data/default"
7 changes: 6 additions & 1 deletion dice/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2521,7 +2521,12 @@ func (d *Dice) Save(isAuto bool) {
if groupInfo.Players != nil {
groupInfo.Players.Range(func(key string, value *GroupPlayerInfo) bool {
if value.UpdatedAtTime != 0 {
_ = model.GroupPlayerInfoSave(d.DBData, groupInfo.GroupID, key, (*model.GroupPlayerInfoBase)(value))
// 解离数据库层的操作到调用处,设置对应的信息
now := int(time.Now().Unix())
value.UserID = key
value.GroupID = groupInfo.GroupID
value.UpdatedAt = now // 更新当前时间为 UpdatedAt
_ = model.GroupPlayerInfoSave(d.DBData, (*model.GroupPlayerInfoBase)(value))
value.UpdatedAtTime = 0
}
return true
Expand Down
2 changes: 1 addition & 1 deletion dice/dice.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ func (d *Dice) Init() {
d.CocExtraRules = map[int]*CocRuleInfo{}

var err error
d.DBData, d.DBLogs, err = model.SQLiteDBInit(d.BaseConfig.DataDir)
d.DBData, d.DBLogs, err = model.DatabaseInit()
if err != nil {
d.Logger.Errorf("Failed to init database: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion dice/dice_censor.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ type CensorManager struct {
}

func (d *Dice) NewCensorManager() {
db, err := model.SQLiteCensorDBInit(d.BaseConfig.DataDir)
db, err := model.CensorDBInit()
if err != nil {
panic(err)
}
Expand Down
41 changes: 0 additions & 41 deletions dice/model/attr.go

This file was deleted.

11 changes: 4 additions & 7 deletions dice/model/attrs_new.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"time"

"github.com/tidwall/gjson"
"gorm.io/gorm"

"sealdice-core/utils"
Expand Down Expand Up @@ -119,10 +118,8 @@ func AttrsPutById(db *gorm.DB, id string, data []byte, name, sheetType string) e
Attrs(map[string]any{
// 第一次全量建表
"id": id,
// 如果想在[]bytes里输入值,注意传参的时候不能给any传[]bytes,否则会无法读取,同时还没有豹错,浪费大量时间。
// 这里为了兼容,不使用gob的序列化方法处理结构体(同时,也不知道序列化方法是否可用)
// TODO: 是否在这里string(data)更快更合理?
"data": gjson.ParseBytes(data).String(),
// 使用BYTE规避无法插入的问题
"data": BYTE(data),
"is_hidden": true,
"binding_sheet_id": "",
"name": name,
Expand All @@ -132,7 +129,7 @@ func AttrsPutById(db *gorm.DB, id string, data []byte, name, sheetType string) e
}).
// 如果是更新的情况,更新下面这部分,则需要被更新的为:
Assign(map[string]any{
"data": gjson.ParseBytes(data).String(),
"data": BYTE(data),
"updated_at": now,
"name": name,
"sheet_type": sheetType,
Expand Down Expand Up @@ -229,7 +226,7 @@ func AttrsBindCharacter(db *gorm.DB, charId string, id string) error {
"id": id,
// 如果想在[]bytes里输入值,注意传参的时候不能给any传[]bytes,否则会无法读取,同时还没有豹错,浪费大量时间。
// 这里为了兼容,不使用gob的序列化方法处理结构体(同时,也不知道序列化方法是否可用)
"data": gjson.ParseBytes(json).String(),
"data": BYTE(json),
"is_hidden": true,
// 如果插入成功,原版代码接下来更新这个值,那么现在就是等价的
"binding_sheet_id": charId,
Expand Down
10 changes: 4 additions & 6 deletions dice/model/ban.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package model

import (
"github.com/tidwall/gjson"
"gorm.io/gorm"
)

Expand Down Expand Up @@ -31,17 +30,16 @@ func BanItemSave(db *gorm.DB, id string, updatedAt int64, banUpdatedAt int64, da
if err := db.Where("id = ?", id).Attrs(map[string]any{
"id": id,
"updated_at": int(updatedAt),
"ban_updated_at": int(banUpdatedAt), // 只在创建时设置的字段
"data": gjson.ParseBytes(data).String(), // 禁用项数据
"ban_updated_at": int(banUpdatedAt), // 只在创建时设置的字段
"data": BYTE(data), // 禁用项数据
}).
Assign(map[string]any{
"updated_at": int(updatedAt),
"ban_updated_at": int(banUpdatedAt), // 只在创建时设置的字段
"data": gjson.ParseBytes(data).String(), // 禁用项数据
"ban_updated_at": int(banUpdatedAt), // 只在创建时设置的字段
"data": BYTE(data), // 禁用项数据
}).FirstOrCreate(&BanInfo{}).Error; err != nil {
return err // 返回错误
}

return nil // 操作成功,返回 nil
}

Expand Down
7 changes: 7 additions & 0 deletions dice/model/const.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package model

const (
SQLITE = "sqlite"
MYSQL = "mysql"
POSTGRESQL = "postgres"
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package model
package cache

import (
"context"
Expand Down
36 changes: 36 additions & 0 deletions dice/model/database/mysql.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package database

import (
"log"
"os"
"time"

"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"

"sealdice-core/dice/model/database/cache"
)

func MySQLDBInit(dsn string) (*gorm.DB, error) {
// 构建 MySQL DSN (Data Source Name)
// 使用 GORM 连接 MySQL
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
logger.Config{
SlowThreshold: time.Second, // 慢 SQL 阈值
LogLevel: logger.Info, // 记录所有SQL操作
Colorful: true, // 是否启用彩色打印
},
)})
if err != nil {
return nil, err
}
// 存疑,MYSQL是否需要使用缓存
cacheDB, err := cache.GetBuntCacheDB(db)
if err != nil {
return nil, err
}
// 返回数据库连接
return cacheDB, nil
}
41 changes: 41 additions & 0 deletions dice/model/database/pgsql.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package database

import (
"log"
"os"
"time"

"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"

"sealdice-core/dice/model/database/cache"
)

func PostgresDBInit(dsn string) (*gorm.DB, error) {
// 构建 PostgreSQL DSN (Data Source Name)

// 使用 GORM 连接 PostgreSQL
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
Logger: logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
logger.Config{
SlowThreshold: time.Second, // 慢 SQL 阈值
LogLevel: logger.Info, // 记录所有SQL操作
Colorful: true, // 是否启用彩色打印
},
),
})
if err != nil {
return nil, err
}

// GetBuntCacheDB 逻辑保持不变
cacheDB, err := cache.GetBuntCacheDB(db)
if err != nil {
return nil, err
}

// 返回数据库连接
return cacheDB, nil
}
38 changes: 38 additions & 0 deletions dice/model/database/sqlite.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//go:build !cgo
// +build !cgo

package database

import (
"github.com/glebarez/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"

"sealdice-core/dice/model/database/cache"
)

func SQLiteDBInit(path string, useWAL bool) (*gorm.DB, error) {
db, err := gorm.Open(sqlite.Open(path), &gorm.Config{
// 注意,这里虽然是Info,但实际上打印就变成了Debug.
Logger: logger.Default.LogMode(logger.Info),
})
// https://github.com/glebarez/sqlite/issues/52 尚未遇见问题,可以先考虑不使用
// sqlDB, _ := db.DB()
// sqlDB.SetMaxOpenConns(1)
if err != nil {
return nil, err
}
// Enable Cache Mode
db, err = cache.GetBuntCacheDB(db)
if err != nil {
return nil, err
}
// enable WAL mode
if useWAL {
err = db.Exec("PRAGMA journal_mode=WAL").Error
if err != nil {
return nil, err
}
}
return db, err
}
36 changes: 36 additions & 0 deletions dice/model/database/sqlite_cgo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//go:build cgo
// +build cgo

package database

import (
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"

"sealdice-core/dice/model/database/cache"
)

func SQLiteDBInit(path string, useWAL bool) (*gorm.DB, error) {
open, err := gorm.Open(sqlite.Open(path), &gorm.Config{
// 注意,这里虽然是Info,但实际上打印就变成了Debug.
Logger: logger.Default.LogMode(logger.Info),
})
if err != nil {
return nil, err
}
// Enable Cache Mode
open, err = cache.GetBuntCacheDB(open)
if err != nil {
return nil, err
}
// enable WAL mode
if useWAL {
err = open.Exec("PRAGMA journal_mode=WAL").Error
if err != nil {
panic(err)
}
}

return open, err
}
Loading

0 comments on commit 230748f

Please sign in to comment.