Skip to content

Commit

Permalink
fix: 修改Table为Model,优化部分数据库请求逻辑,修正ban_info的错误请求逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
PaienNate committed Oct 26, 2024
1 parent 6acbc42 commit 4a87586
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 72 deletions.
40 changes: 17 additions & 23 deletions dice/model/attrs_new.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package model

import (
"errors"
"fmt"
"time"

"github.com/tidwall/gjson"
Expand Down Expand Up @@ -46,7 +47,7 @@ type AttributesItemModel struct {
}

// 兼容旧版本数据库
func (AttributesItemModel) TableName() string {
func (*AttributesItemModel) TableName() string {
return "attrs"
}

Expand All @@ -65,7 +66,7 @@ type PlatformMappingModel struct {
func AttrsGetById(db *gorm.DB, id string) (*AttributesItemModel, error) {
// 这里必须使用AttributesItemModel结构体,如果你定义一个只有ID属性的结构体去接收,居然能接收到值,这样就会豹错
var item AttributesItemModel
err := db.Table("attrs").
err := db.Model(&AttributesItemModel{}).
Select("id, data, COALESCE(attrs_type, '') as attrs_type, binding_sheet_id, name, owner_id, sheet_type, is_hidden, created_at, updated_at").
Where("id = ?", id).
Limit(1).
Expand All @@ -80,7 +81,7 @@ func AttrsGetById(db *gorm.DB, id string) (*AttributesItemModel, error) {
func AttrsGetBindingSheetIdByGroupId(db *gorm.DB, id string) (string, error) {
// 这里必须使用AttributesItemModel结构体,如果你定义一个只有ID属性的结构体去接收,居然能接收到值,这样就会豹错
var item AttributesItemModel
err := db.Table("attrs").
err := db.Model(&AttributesItemModel{}).
Select("binding_sheet_id").
Where("id = ?", id).
Limit(1).
Expand All @@ -92,10 +93,10 @@ func AttrsGetBindingSheetIdByGroupId(db *gorm.DB, id string) (string, error) {
}

func AttrsGetIdByUidAndName(db *gorm.DB, userId string, name string) (string, error) {
// 这里必须使用AttributesItemModel结构体,如果你定义一个只有ID属性的结构体去接收,居然能接收到值,这样就会豹错
// 这里必须使用AttributesItemModel结构体
// 如果你定义一个只有ID属性的结构体去接收,居然有概率能接收到值,这样就会和之前的行为不一致了
var item AttributesItemModel
// 使用 GORM 查询 attrs 表,选择 id 字段
err := db.Table("attrs").
err := db.Model(&AttributesItemModel{}).
Select("id").
Where("owner_id = ? AND name = ?", userId, name).
Limit(1).
Expand All @@ -109,13 +110,9 @@ func AttrsGetIdByUidAndName(db *gorm.DB, userId string, name string) (string, er

func AttrsPutById(db *gorm.DB, id string, data []byte, name, sheetType string) error {
now := time.Now().Unix() // 获取当前时间
// 定义用于查询的条件
conditions := map[string]any{
"id": id,
}
// 这里的原本逻辑是:第一次全量创建,第二次修改部分属性
// 所以使用了Attrs和Assign配合使用
if err := db.
if err := db.Where("id = ?", id).
Attrs(map[string]any{
// 第一次全量建表
"id": id,
Expand All @@ -135,7 +132,7 @@ func AttrsPutById(db *gorm.DB, id string, data []byte, name, sheetType string) e
"updated_at": now,
"name": name,
"sheet_type": sheetType,
}).FirstOrCreate(&AttributesItemModel{}, conditions).Error; err != nil {
}).FirstOrCreate(&AttributesItemModel{}).Error; err != nil {
return err // 返回错误
}
return nil // 操作成功,返回 nil
Expand All @@ -154,7 +151,7 @@ func AttrsCharGetBindingList(db *gorm.DB, id string) ([]string, error) {
var lst []string

// 使用 GORM 查询绑定的 id 列表
if err := db.Table("attrs").
if err := db.Model(&AttributesItemModel{}).
Select("id").
Where("binding_sheet_id = ?", id).
Find(&lst).Error; err != nil {
Expand Down Expand Up @@ -216,18 +213,13 @@ func AttrsBindCharacter(db *gorm.DB, charId string, id string) error {
return err
}

// 定义用于查询的条件
conditions := map[string]any{
"id": id,
}
// 原本代码为:
// _, _ = db.Exec(`insert into attrs (id, data, is_hidden, binding_sheet_id, created_at, updated_at)
// values ($1, $3, true, '', $2, $2)`, id, time.Now().Unix(), json)
//
// ret, err := db.Exec(`update attrs set binding_sheet_id = $1 where id = $2`, charId, id)

// 使用 FirstOrCreate,定义初始值和更新值
result := tx.
result := tx.Where("id = ?", id).
// 按照木落的原版代码,应该是这么个逻辑:查不到的时候能正确执行,查到了就不执行了,所以用Attrs而不是Assign
Attrs(map[string]any{
"id": id,
Expand All @@ -244,7 +236,7 @@ func AttrsBindCharacter(db *gorm.DB, charId string, id string) error {
Assign(map[string]any{
"binding_sheet_id": charId,
}).
FirstOrCreate(&AttributesItemModel{}, conditions)
FirstOrCreate(&AttributesItemModel{})
if result.Error != nil {
tx.Rollback() // 返回错误时回滚
return result.Error
Expand Down Expand Up @@ -277,11 +269,13 @@ func AttrsGetCharacterListByUserId(db *gorm.DB, userId string) ([]*AttributesIte
BindingGroupNum int64 `gorm:"column:binding_group_num"` // 映射 COUNT(a.id)
}
var tempResultList []AttrResult

// 由于是复杂查询,无法直接使用Models,又为了防止以后attrs表名称修改,故不使用Table而是用TableName替换
model := AttributesItemModel{}
tableName := model.TableName()
// 此处使用了JOIN来避免子查询,数据库一般对JOIN有使用索引的优化,所以有性能提升,但是我没有实际测试过性能差距。
err := db.Table("attrs AS t1").
err := db.Table(fmt.Sprintf("%s AS t1", tableName)).
Select("t1.id, t1.name, t1.sheet_type, COUNT(a.id) AS binding_group_num").
Joins("LEFT JOIN attrs AS a ON a.binding_sheet_id = t1.id").
Joins(fmt.Sprintf("LEFT JOIN %s AS a ON a.binding_sheet_id = t1.id", tableName)).
Where("t1.owner_id = ? AND t1.is_hidden IS FALSE", userId).
Group("t1.id, t1.name, t1.sheet_type").
// Pinenutn:此处我根据创建时间对创建的卡进行排序,不知道是否有意义?
Expand Down
38 changes: 20 additions & 18 deletions dice/model/ban.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package model

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

// BanInfo 模型
// GORM STRUCT
type BanInfo struct {
ID string `gorm:"primaryKey"`
BanUpdatedAt int `gorm:"index:idx_ban_info_ban_updated_at"`
UpdatedAt int `gorm:"index:idx_ban_info_updated_at"`
Data []byte // 使用[]byte表示BLOB类型
ID string `gorm:"primaryKey;column:id"` // 主键列
BanUpdatedAt int `gorm:"index:idx_ban_info_ban_updated_at;column:ban_updated_at"` // BanUpdatedAt 列
UpdatedAt int `gorm:"index:idx_ban_info_updated_at;column:updated_at"` // UpdatedAt 列
Data []byte `gorm:"column:data"` // BLOB 类型
}

func (BanInfo) TableName() string {
func (*BanInfo) TableName() string {
return "ban_info"
}

Expand All @@ -22,21 +25,20 @@ func BanItemDel(db *gorm.DB, id string) error {
return result.Error // 返回错误
}

// BanItemSave 保存或替换禁用项
// BanItemSave 保存或替换禁用项 这里的[]byte也是json反序列化产物
func BanItemSave(db *gorm.DB, id string, updatedAt int64, banUpdatedAt int64, data []byte) error {
// 定义用于查找的条件
conditions := map[string]any{
"id": id,
}

// 使用 FirstOrCreate 查找或创建新的禁用项
if err := db.Attrs(map[string]any{
"ban_updated_at": int(banUpdatedAt), // 只在创建时设置的字段
// 使用 FirstOrCreate ,这里显然,第一次初始化的时候替换ID,而剩余的时候只换ID以外的数据
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(), // 禁用项数据
}).
Assign(map[string]any{
"updated_at": int(updatedAt), // 更新时覆盖的字段
"data": data, // 禁用项数据
}).FirstOrCreate(&BanInfo{}, conditions).Error; err != nil {
"updated_at": int(updatedAt),
"ban_updated_at": int(banUpdatedAt), // 只在创建时设置的字段
"data": gjson.ParseBytes(data).String(), // 禁用项数据
}).FirstOrCreate(&BanInfo{}).Error; err != nil {
return err // 返回错误
}

Expand Down
9 changes: 5 additions & 4 deletions dice/model/db_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@
package model

import (
"fmt"

"github.com/glebarez/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)

// _SQLiteDBInit 初始化 SQLite 数据库连接
// 非CGO的另一个替代品使用了WASM方案:https://github.com/ncruces/go-sqlite3/tree/main/gormlite
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
}
Expand All @@ -29,10 +31,9 @@ func _SQLiteDBInit(path string, useWAL bool) (*gorm.DB, error) {
if useWAL {
err = db.Exec("PRAGMA journal_mode=WAL").Error
if err != nil {
panic(err)
return nil, err
}
}
fmt.Println(db)
return db, err
}

Expand Down
7 changes: 4 additions & 3 deletions dice/model/db_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"runtime"
"sync"

log "sealdice-core/utils/kratos"
"sealdice-core/utils/spinner"
)

Expand Down Expand Up @@ -82,12 +83,12 @@ func DBVacuum() {
}
}()
if err != nil {
fmt.Printf("清理 %q 时出现错误:%v", path, err)
log.Errorf("清理 %q 时出现错误:%v", path, err)
return
}
err = vacuumDB.Exec("VACUUM;").Error
if err != nil {
fmt.Printf("清理 %q 时出现错误:%v", path, err)
log.Errorf("清理 %q 时出现错误:%v", path, err)
}
}

Expand All @@ -97,5 +98,5 @@ func DBVacuum() {

wg.Wait()

fmt.Println("\n数据库整理完成")
log.Infof("\n数据库整理完成")
}
5 changes: 3 additions & 2 deletions dice/model/endpoint_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (e *EndpointInfo) Query(db *gorm.DB) error {
return errors.New("db is nil")
}

err := db.Table("endpoint_info").
err := db.Model(&EndpointInfo{}).
Where("user_id = ?", e.UserID).
Select("cmd_num", "cmd_last_time", "online_time", "updated_at").
Scan(&e).Error
Expand All @@ -54,7 +54,8 @@ func (e *EndpointInfo) Save(db *gorm.DB) error {

// 直接使用 Save 函数
// Save 会根据主键(user_id)进行插入或更新
err := db.Table("endpoint_info").Save(&e).Error
// 以我的理解,这里不会写入CmdNum=0,所以可以安心认为Save是可用的,不用转换成FirstOrCreate
err := db.Model(&EndpointInfo{}).Save(&e).Error
if err != nil {
return err
}
Expand Down
5 changes: 4 additions & 1 deletion dice/model/gormcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,11 @@ func GetBuntCacheDB(db *gorm.DB) (*gorm.DB, error) {
if err != nil {
return nil, err
}
// Easer参数:使用ServantGo任务执行与合并库
// ServantGo提供了一种简单且惯用的方法来合并同时运行的相同类型的任务。
// 可以先尝试一下easer=true是否可以加速
cachesPlugin := &caches.Caches{Conf: &caches.Config{
Easer: false,
Easer: true,
Cacher: &buntDBCacher{
db: open,
},
Expand Down
11 changes: 6 additions & 5 deletions dice/model/group_info.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package model

import (
"fmt"
"time"

"golang.org/x/time/rate"
"gorm.io/gorm"

ds "github.com/sealdice/dicescript"

log "sealdice-core/utils/kratos"
)

// GroupInfo 模型
Expand All @@ -32,7 +33,7 @@ func GroupInfoListGet(db *gorm.DB, callback func(id string, updatedAt int64, dat
}

// 使用 GORM 查询 group_info 表中的 id, updated_at, data 列
err := db.Table("group_info").Select("id, updated_at, data").Find(&results).Error
err := db.Model(&GroupInfo{}).Select("id, updated_at, data").Find(&results).Error
if err != nil {
// 如果查询发生错误,返回错误信息
return err
Expand Down Expand Up @@ -116,7 +117,7 @@ func GroupPlayerNumGet(db *gorm.DB, groupID string) (int64, error) {
// 使用 GORM 的 Table 方法指定表名进行查询
// db.Table("表名").Where("条件").Count(&count) 是通用的 GORM 用法
// 将 group_id 作为查询条件
err := db.Table("group_player_info").Where("group_id = ?", groupID).Count(&count).Error
err := db.Model(&GroupPlayerInfoBase{}).Where("group_id = ?", groupID).Count(&count).Error
if err != nil {
// 如果查询出现错误,返回错误信息
return 0, err
Expand All @@ -132,14 +133,14 @@ func GroupPlayerInfoGet(db *gorm.DB, groupID string, playerID string) *GroupPlay

// 使用 GORM 查询数据并绑定到结构体中
// db.Table("表名").Where("条件").First(&ret) 查询一条数据并映射到结构体
err := db.Table("group_player_info").
err := db.Model(&GroupPlayerInfoBase{}).
Where("group_id = ? AND user_id = ?", groupID, playerID).
Select("name, last_command_time, auto_set_name_template, dice_side_num").
Scan(&ret).Error

// 如果查询发生错误,打印错误并返回 nil
if err != nil {
fmt.Printf("error getting group player info: %s", err.Error())
log.Errorf("error getting group player info: %s", err.Error())
return nil
}

Expand Down
Loading

0 comments on commit 4a87586

Please sign in to comment.