feat: 新增 storage 支持数据持久化

This commit is contained in:
kercylan98 2023-07-19 12:12:30 +08:00
parent 1dcbd0a220
commit f59354db3f
4 changed files with 189 additions and 0 deletions

View File

@ -0,0 +1,49 @@
package storage
// NewGlobalData 创建全局数据
func NewGlobalData[T any](name string, storage GlobalDataStorage[T]) *GlobalData[T] {
data := &GlobalData[T]{
name: name,
data: storage.Load(name),
}
return data
}
// GlobalData 全局数据
type GlobalData[T any] struct {
storage GlobalDataStorage[T] // 存储器
name string // 全局数据名称
data T // 数据
}
// GetName 获取名称
func (slf *GlobalData[T]) GetName() string {
return slf.name
}
// GetData 获取数据
func (slf *GlobalData[T]) GetData() T {
return slf.data
}
// LoadData 加载数据
func (slf *GlobalData[T]) LoadData(storage GlobalDataStorage[T]) *GlobalData[T] {
return LoadGlobalData(slf, storage)
}
// SaveData 保存数据
func (slf *GlobalData[T]) SaveData(storage GlobalDataStorage[T]) *GlobalData[T] {
return SaveGlobalData(slf, storage)
}
// Handle 处理数据
func (slf *GlobalData[T]) Handle(handler func(name string, data T)) *GlobalData[T] {
handler(slf.GetName(), slf.GetData())
return slf
}
// HandleWithCallback 处理数据
func (slf *GlobalData[T]) HandleWithCallback(handler func(name string, data T) error, callback func(err error)) *GlobalData[T] {
callback(handler(slf.GetName(), slf.GetData()))
return slf
}

View File

@ -0,0 +1,22 @@
package storage
// GlobalDataStorage 全局数据存储器接口
type GlobalDataStorage[T any] interface {
// Load 加载全局数据
// - 当全局数据不存在时,应当返回新的全局数据实例
Load(name string) T
// Save 保存全局数据
Save(name string, data T)
}
// LoadGlobalData 加载全局数据
func LoadGlobalData[T any](globalData *GlobalData[T], storage GlobalDataStorage[T]) *GlobalData[T] {
globalData.data = storage.Load(globalData.GetName())
return globalData
}
// SaveGlobalData 保存全局数据
func SaveGlobalData[T any](globalData *GlobalData[T], storage GlobalDataStorage[T]) *GlobalData[T] {
storage.Save(globalData.GetName(), globalData.GetData())
return globalData
}

View File

@ -0,0 +1,58 @@
package storage
import (
"github.com/kercylan98/minotaur/utils/generic"
)
// NewIndexData 创建索引数据
func NewIndexData[I generic.Ordered, T any](name string, storage IndexDataStorage[I, T]) *IndexData[I, T] {
data := &IndexData[I, T]{
name: name,
data: map[I]T{},
}
return data
}
// IndexData 全局数据
type IndexData[I generic.Ordered, T any] struct {
storage GlobalDataStorage[T] // 存储器
name string // 数据组名称
data map[I]T // 数据
}
// GetName 获取名称
func (slf *IndexData[I, T]) GetName() string {
return slf.name
}
// GetData 获取数据
func (slf *IndexData[I, T]) GetData(index I) T {
return slf.data[index]
}
// GetAllData 获取所有数据
func (slf *IndexData[I, T]) GetAllData() map[I]T {
return slf.data
}
// LoadData 加载数据
func (slf *IndexData[I, T]) LoadData(index I, storage IndexDataStorage[I, T]) *IndexData[I, T] {
return LoadIndexData(slf, index, storage)
}
// SaveData 保存数据
func (slf *IndexData[I, T]) SaveData(storage IndexDataStorage[I, T], index I) *IndexData[I, T] {
return SaveIndexData(slf, index, storage)
}
// Handle 处理数据
func (slf *IndexData[I, T]) Handle(index I, handler func(name string, index I, data T)) *IndexData[I, T] {
handler(slf.GetName(), index, slf.GetData(index))
return slf
}
// HandleWithCallback 处理数据
func (slf *IndexData[I, T]) HandleWithCallback(index I, handler func(name string, index I, data T) error, callback func(err error)) *IndexData[I, T] {
callback(handler(slf.GetName(), index, slf.GetData(index)))
return slf
}

View File

@ -0,0 +1,60 @@
package storage
import "github.com/kercylan98/minotaur/utils/generic"
// IndexDataStorage 全局数据存储器接口
type IndexDataStorage[I generic.Ordered, T any] interface {
// Load 加载特定索引数据
// - 通常情况下当数据不存在时,应当返回空指针
Load(name string, index I) T
// LoadAll 加载所有数据
LoadAll(name string) map[I]T
// Save 保存特定索引数据
Save(name string, index I, data T)
// SaveAll 保存所有数据
SaveAll(name string, data map[I]T)
// Delete 删除特定索引数据
Delete(name string, index I)
// DeleteAll 删除所有数据
DeleteAll(name string)
}
// LoadIndexData 加载索引数据
func LoadIndexData[I generic.Ordered, T any](indexData *IndexData[I, T], index I, storage IndexDataStorage[I, T]) *IndexData[I, T] {
indexData.data[index] = storage.Load(indexData.GetName(), index)
return indexData
}
// LoadIndexDataAll 加载所有索引数据
func LoadIndexDataAll[I generic.Ordered, T any](indexData *IndexData[I, T], storage IndexDataStorage[I, T]) *IndexData[I, T] {
indexData.data = storage.LoadAll(indexData.GetName())
return indexData
}
// SaveIndexData 保存索引数据
func SaveIndexData[I generic.Ordered, T any](indexData *IndexData[I, T], index I, storage IndexDataStorage[I, T]) *IndexData[I, T] {
storage.Save(indexData.GetName(), index, indexData.GetData(index))
return indexData
}
// SaveIndexDataALl 保存所有所索引数据
func SaveIndexDataALl[I generic.Ordered, T any](indexData *IndexData[I, T], storage IndexDataStorage[I, T]) *IndexData[I, T] {
storage.SaveAll(indexData.GetName(), indexData.GetAllData())
return indexData
}
// DeleteIndexData 删除索引数据
func DeleteIndexData[I generic.Ordered, T any](indexData *IndexData[I, T], index I, storage IndexDataStorage[I, T]) *IndexData[I, T] {
storage.Delete(indexData.GetName(), index)
delete(indexData.data, index)
return indexData
}
// DeleteIndexDataAll 删除所有索引数据
func DeleteIndexDataAll[I generic.Ordered, T any](indexData *IndexData[I, T], storage IndexDataStorage[I, T]) *IndexData[I, T] {
storage.DeleteAll(indexData.GetName())
for k := range indexData.data {
delete(indexData.data, k)
}
return indexData
}