From c2d9653ba00aa26fa24f3e9f47afe1204d715e13 Mon Sep 17 00:00:00 2001 From: Thun_Ann <2865813065@qq.com> Date: Thu, 23 Jan 2025 13:07:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/database.go | 68 ++++++++++++++------------- database/数据库0.1 使用文档.md | 16 +++---- main.go | 5 ++ utils.go | 32 +++++++++++++ 4 files changed, 80 insertions(+), 41 deletions(-) diff --git a/database/database.go b/database/database.go index 38567ec..3fa97e2 100644 --- a/database/database.go +++ b/database/database.go @@ -35,6 +35,7 @@ func newDatabase(id string) Database { Id: id, Users: make(map[string]User), Groups: make(map[string]Group), + Global: make(map[string]Global), } return *db } @@ -43,7 +44,7 @@ func folderCheck(filename string) { if _, err := os.Stat(filename); os.IsNotExist(err) { err := os.MkdirAll(filename, 0755) 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) { file, err := os.Create(filename) 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) { err := file.Close() if err != nil { - LOG.FATAL("[ERROR]Error occurred while close file: %v", err) + LOG.FATAL("[ERROR]Error occured while close file: %v", err) } }(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) if err != nil { @@ -104,10 +105,7 @@ func SaveData(db *Database) error { LOG.ERROR("[ERROR]:Error while create file %s: %v", filename, err) return err } - err = writeContent(file, string(dataJson)) - if err != nil { - return err - } + writeContent(file, string(dataJson)) return nil } @@ -130,7 +128,9 @@ func loadData(db *Database) error { 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 { case "user": @@ -172,12 +172,12 @@ func DataGet(db *Database, category string, id string, key string) (string, bool return "", false } 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 } value, ok := global.Data[key] 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 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 { 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) // 监听指定的信号,如SIGINT (Ctrl+C) 和 SIGTERM signal.Notify(dataChan, syscall.SIGINT, syscall.SIGTERM) // 定义一个Ticker用于每1小时触发一次保存操作 - saveTicker := time.NewTicker(3600 * time.Second) + saveTicker := time.NewTicker(600 * time.Second) defer saveTicker.Stop() // 启动一个goroutine等待信号和定时保存 @@ -251,33 +261,25 @@ func keepDatabase(db *Database) { case <-dataChan: // 接收到信号,保存数据并退出程序 LOG.INFO("Received signal, saving data and exiting...") - err := SaveData(db) - if err != nil { - return - } + saveData(DB) os.Exit(0) case <-saveTicker.C: // 定时保存数据 LOG.INFO("Saving data automatically...") - err := SaveData(db) - if err != nil { - return - } + saveData(DB) } } }() + select {} // 阻塞主goroutine } -func Start() *Database { - // 启动并检查程序 - LOG.INFO("Starting database ...") - db := newDatabase("datamap") - err := loadData(&db) - if err != nil { - return nil - } - LOG.INFO("Database started successfully.") - keepDatabase(&db) - return &db +func Get(category string, id string, key string) (string, bool) { + // 查询数据 + return dataGet(DB, category, id, key) +} + +func Set(category string, id string, key string, value string) { + // 修改数据 + dataSet(DB, category, id, key, value) } diff --git a/database/数据库0.1 使用文档.md b/database/数据库0.1 使用文档.md index 567a5e9..9a0e865 100644 --- a/database/数据库0.1 使用文档.md +++ b/database/数据库0.1 使用文档.md @@ -1,17 +1,19 @@ ```go -func Start() *database //启动默认数据库,并且返回数据库指针 +func Start() //启动默认数据库 ``` 该函数用于启动数据库,加载数据,启动自动存储 +Tips:需要异步启动数据库,否则进程会被阻塞 + +Tips:需要在启动数据库后等待其初始化,建议使用time.Sleep()函数等待至少1秒 + ```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",分别表示个人变量,群变量,全局变量 ——id为用户id或群id,全局变量使用时,id可以理解为命名空间 @@ -21,16 +23,14 @@ func DataGet(database *database, category string, id string, key string) (string 返回值类型为string,bool,第一个返回值为查询到的变量,第二个返回值表示是否返回成功 ```go -func DataSet(database *database, category string, id string, key string, value string) //修改变量,示例用法: -// database.DataSet(&db, "user", "1001", "age", "18") 表示将db数据库中id为1001的用户个人变量age设置为"18" +func Set(category string, id string, key string, value string) //修改变量,示例用法: +// database.Set("user", "1001", "age", "18") 表示将db数据库中id为1001的用户个人变量age设置为"18" // 注意:变量目前只支持string类型,如果需要储存数据或对象,请将它们转化为string类型再进行储存 // 该数据库的所有变量将会存放在/data/database/datamap.txt中,请不要乱动这个文件 ``` 该函数用于新建或修改变量 -——database部分请填入&db - ——category部分可以填入"user","group","global",分别表示个人变量,群变量,全局变量 ——id为用户id或群id,全局变量使用时,id可以理解为命名空间 diff --git a/main.go b/main.go index 494604e..6ba8769 100644 --- a/main.go +++ b/main.go @@ -48,6 +48,11 @@ func main() { startProtocol() return } + if cmdArgs[0] == "-d" || cmdArgs[0] == "--database" { + // 连接到数据库 + startDatabase() + return + } fmt.Println("未知命令,请使用-h查看帮助。") return } diff --git a/utils.go b/utils.go index 7bcaafb..1f623d0 100644 --- a/utils.go +++ b/utils.go @@ -3,6 +3,7 @@ package main import ( "ProjectWIND/LOG" "ProjectWIND/core" + "ProjectWIND/database" "ProjectWIND/typed" "encoding/json" "errors" @@ -327,3 +328,34 @@ func ReloadApps() { total, success := core.ReloadApps() 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 {} +}