添加了数据库api

This commit is contained in:
Thun_Ann 2025-01-23 13:07:44 +08:00
parent 469e75c1af
commit c2d9653ba0
4 changed files with 80 additions and 41 deletions

View File

@ -35,6 +35,7 @@ func newDatabase(id string) Database {
Id: id, Id: id,
Users: make(map[string]User), Users: make(map[string]User),
Groups: make(map[string]Group), Groups: make(map[string]Group),
Global: make(map[string]Global),
} }
return *db return *db
} }
@ -43,7 +44,7 @@ func folderCheck(filename string) {
if _, err := os.Stat(filename); os.IsNotExist(err) { if _, err := os.Stat(filename); os.IsNotExist(err) {
err := os.MkdirAll(filename, 0755) err := os.MkdirAll(filename, 0755)
if err != nil { if err != nil {
LOG.FATAL("[ERROR]Error occurred while create folder: %v", err) LOG.FATAL("[ERROR]Error occured while create folder: %v", err)
} }
} }
} }
@ -55,12 +56,12 @@ func fileCheck(filename string) {
if _, err := os.Stat(filename); os.IsNotExist(err) { if _, err := os.Stat(filename); os.IsNotExist(err) {
file, err := os.Create(filename) file, err := os.Create(filename)
if err != nil { if err != nil {
LOG.FATAL("[ERROR]Error occurred while create file: %v", err) LOG.FATAL("[ERROR]Error occured while create file: %v", err)
} }
defer func(file *os.File) { defer func(file *os.File) {
err := file.Close() err := file.Close()
if err != nil { if err != nil {
LOG.FATAL("[ERROR]Error occurred while close file: %v", err) LOG.FATAL("[ERROR]Error occured while close file: %v", err)
} }
}(file) }(file)
} }
@ -91,7 +92,7 @@ func printContent(file string) (string, error) {
} }
} }
func SaveData(db *Database) error { func saveData(db *Database) error {
// 保存数据到文件 // 保存数据到文件
dataJson, err := json.Marshal(db) dataJson, err := json.Marshal(db)
if err != nil { if err != nil {
@ -104,10 +105,7 @@ func SaveData(db *Database) error {
LOG.ERROR("[ERROR]:Error while create file %s: %v", filename, err) LOG.ERROR("[ERROR]:Error while create file %s: %v", filename, err)
return err return err
} }
err = writeContent(file, string(dataJson)) writeContent(file, string(dataJson))
if err != nil {
return err
}
return nil return nil
} }
@ -130,7 +128,9 @@ func loadData(db *Database) error {
return nil return nil
} }
func DataGet(db *Database, category string, id string, key string) (string, bool) { var DB *Database
func dataGet(db *Database, category string, id string, key string) (string, bool) {
// 查询数据 // 查询数据
switch category { switch category {
case "user": case "user":
@ -172,12 +172,12 @@ func DataGet(db *Database, category string, id string, key string) (string, bool
return "", false return "", false
} }
if global.Data == nil { if global.Data == nil {
LOG.WARN("[WARNING]:Global %s's data is nil", id) LOG.WARN("[WARNING]:Global data of %s is nil", id)
return "", false return "", false
} }
value, ok := global.Data[key] value, ok := global.Data[key]
if !ok { if !ok {
LOG.WARN("[WARNING]:Global %s's data %s not found", id, key) LOG.WARN("[WARNING]:Global data of %s's %s not found", id, key)
return "", false return "", false
} }
return value, true return value, true
@ -187,7 +187,7 @@ func DataGet(db *Database, category string, id string, key string) (string, bool
} }
} }
func DataSet(db *Database, category string, id string, key string, value string) { func dataSet(db *Database, category string, id string, key string, value string) {
// 修改数据 // 修改数据
switch category { switch category {
case "user": case "user":
@ -234,14 +234,24 @@ func DataSet(db *Database, category string, id string, key string, value string)
} }
} }
func keepDatabase(db *Database) { func initializeDatabase() *Database {
// 启动并检查程序
LOG.INFO("Starting database ...")
db := newDatabase("datamap")
loadData(&db)
LOG.INFO("Database started successfully.")
return &db
}
func Start() {
DB = initializeDatabase()
// 创建一个通道用于接收信号 // 创建一个通道用于接收信号
dataChan := make(chan os.Signal, 1) dataChan := make(chan os.Signal, 1)
// 监听指定的信号如SIGINT (Ctrl+C) 和 SIGTERM // 监听指定的信号如SIGINT (Ctrl+C) 和 SIGTERM
signal.Notify(dataChan, syscall.SIGINT, syscall.SIGTERM) signal.Notify(dataChan, syscall.SIGINT, syscall.SIGTERM)
// 定义一个Ticker用于每1小时触发一次保存操作 // 定义一个Ticker用于每1小时触发一次保存操作
saveTicker := time.NewTicker(3600 * time.Second) saveTicker := time.NewTicker(600 * time.Second)
defer saveTicker.Stop() defer saveTicker.Stop()
// 启动一个goroutine等待信号和定时保存 // 启动一个goroutine等待信号和定时保存
@ -251,33 +261,25 @@ func keepDatabase(db *Database) {
case <-dataChan: case <-dataChan:
// 接收到信号,保存数据并退出程序 // 接收到信号,保存数据并退出程序
LOG.INFO("Received signal, saving data and exiting...") LOG.INFO("Received signal, saving data and exiting...")
err := SaveData(db) saveData(DB)
if err != nil {
return
}
os.Exit(0) os.Exit(0)
case <-saveTicker.C: case <-saveTicker.C:
// 定时保存数据 // 定时保存数据
LOG.INFO("Saving data automatically...") LOG.INFO("Saving data automatically...")
err := SaveData(db) saveData(DB)
if err != nil {
return
}
} }
} }
}() }()
select {} // 阻塞主goroutine select {} // 阻塞主goroutine
} }
func Start() *Database { func Get(category string, id string, key string) (string, bool) {
// 启动并检查程序 // 查询数据
LOG.INFO("Starting database ...") return dataGet(DB, category, id, key)
db := newDatabase("datamap")
err := loadData(&db)
if err != nil {
return nil
} }
LOG.INFO("Database started successfully.")
keepDatabase(&db) func Set(category string, id string, key string, value string) {
return &db // 修改数据
dataSet(DB, category, id, key, value)
} }

View File

@ -1,17 +1,19 @@
```go ```go
func Start() *database //启动默认数据库,并且返回数据库指针 func Start() //启动默认数据库
``` ```
该函数用于启动数据库,加载数据,启动自动存储 该函数用于启动数据库,加载数据,启动自动存储
Tips:需要异步启动数据库,否则进程会被阻塞
Tips:需要在启动数据库后等待其初始化建议使用time.Sleep()函数等待至少1秒
```go ```go
func DataGet(database *database, category string, id string, key string) (string,bool) //获取变量,示例用法:// database.DataGet(&db, "user", "1001", "age") 表示查询db数据库中id为1001的用户个人变量age func Get(database *database, category string, id string, key string) (string,bool) //获取变量,示例用法:// database.Get("user", "1001", "age") 表示查询db数据库中id为1001的用户个人变量age
``` ```
该函数用于查询设定的变量 该函数用于查询设定的变量
——database部分请填入&db
——category部分可以填入"user","group","global",分别表示个人变量,群变量,全局变量 ——category部分可以填入"user","group","global",分别表示个人变量,群变量,全局变量
——id为用户id或群id全局变量使用时id可以理解为命名空间 ——id为用户id或群id全局变量使用时id可以理解为命名空间
@ -21,16 +23,14 @@ func DataGet(database *database, category string, id string, key string) (string
返回值类型为string,bool第一个返回值为查询到的变量第二个返回值表示是否返回成功 返回值类型为string,bool第一个返回值为查询到的变量第二个返回值表示是否返回成功
```go ```go
func DataSet(database *database, category string, id string, key string, value string) //修改变量,示例用法: func Set(category string, id string, key string, value string) //修改变量,示例用法:
// database.DataSet(&db, "user", "1001", "age", "18") 表示将db数据库中id为1001的用户个人变量age设置为"18" // database.Set("user", "1001", "age", "18") 表示将db数据库中id为1001的用户个人变量age设置为"18"
// 注意变量目前只支持string类型如果需要储存数据或对象请将它们转化为string类型再进行储存 // 注意变量目前只支持string类型如果需要储存数据或对象请将它们转化为string类型再进行储存
// 该数据库的所有变量将会存放在/data/database/datamap.txt中请不要乱动这个文件 // 该数据库的所有变量将会存放在/data/database/datamap.txt中请不要乱动这个文件
``` ```
该函数用于新建或修改变量 该函数用于新建或修改变量
——database部分请填入&db
——category部分可以填入"user","group","global",分别表示个人变量,群变量,全局变量 ——category部分可以填入"user","group","global",分别表示个人变量,群变量,全局变量
——id为用户id或群id全局变量使用时id可以理解为命名空间 ——id为用户id或群id全局变量使用时id可以理解为命名空间

View File

@ -48,6 +48,11 @@ func main() {
startProtocol() startProtocol()
return return
} }
if cmdArgs[0] == "-d" || cmdArgs[0] == "--database" {
// 连接到数据库
startDatabase()
return
}
fmt.Println("未知命令,请使用-h查看帮助。") fmt.Println("未知命令,请使用-h查看帮助。")
return return
} }

View File

@ -3,6 +3,7 @@ package main
import ( import (
"ProjectWIND/LOG" "ProjectWIND/LOG"
"ProjectWIND/core" "ProjectWIND/core"
"ProjectWIND/database"
"ProjectWIND/typed" "ProjectWIND/typed"
"encoding/json" "encoding/json"
"errors" "errors"
@ -327,3 +328,34 @@ func ReloadApps() {
total, success := core.ReloadApps() total, success := core.ReloadApps()
LOG.INFO("应用重新加载完成,共加载%d个应用成功加载%d个应用。", total, success) LOG.INFO("应用重新加载完成,共加载%d个应用成功加载%d个应用。", total, success)
} }
func startDatabase() {
go database.Start()
time.Sleep(time.Second * 1)
// 读写测试
// for i := 0; i < 10; i++ {
// data, ok := database.Get("user", "test", "test"+fmt.Sprintf("%d", i))
// if !ok {
// LOG.ERROR("Failed to get data from database")
// continue
// }
// LOG.INFO("Get data from database: %v", data)
// time.Sleep(time.Second * 1)
// }
// time.Sleep(time.Second * 1)
// for i := 0; i < 10; i++ {
// database.Set("user", "test", "test"+fmt.Sprintf("%d", i), "test"+fmt.Sprintf("%d", 1000+i))
// time.Sleep(time.Second * 1)
// }
// time.Sleep(time.Second * 1)
// for i := 0; i < 10; i++ {
// data, ok := database.Get("user", "test", "test"+fmt.Sprintf("%d", i))
// if !ok {
// LOG.ERROR("Failed to get data from database")
// continue
// }
// LOG.INFO("Get data from database: %v", data)
// time.Sleep(time.Second * 1)
// }
select {}
}