forked from ProjectWIND/ProjectWIND
添加了数据库api
This commit is contained in:
parent
469e75c1af
commit
c2d9653ba0
@ -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 {
|
func Set(category string, id string, key string, value string) {
|
||||||
return nil
|
// 修改数据
|
||||||
}
|
dataSet(DB, category, id, key, value)
|
||||||
LOG.INFO("Database started successfully.")
|
|
||||||
keepDatabase(&db)
|
|
||||||
return &db
|
|
||||||
}
|
}
|
||||||
|
@ -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可以理解为命名空间
|
||||||
|
5
main.go
5
main.go
@ -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
|
||||||
}
|
}
|
||||||
|
32
utils.go
32
utils.go
@ -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 {}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user