This commit is contained in:
2023-05-17 11:35:28 +08:00
parent d9af4978c6
commit 66828b2c23
4 changed files with 138 additions and 14 deletions
+130 -10
View File
@@ -1,29 +1,149 @@
package remind
import (
"b612.me/sdk/candy/when"
"b612.me/stardb"
"b612.me/startimer"
"errors"
"sync"
"time"
)
type Remind struct {
db stardb.StarDB
tasks map[string]RemindTask
mu sync.Mutex
callBack func(remind RemindTask)
db *stardb.StarDB
tasks map[int]RemindTask
mu sync.RWMutex
callback func(remind RemindTask)
}
type RemindTask struct {
ID int `db:"id"`
Origin string `db:"text"`
timer startimer.StarTimer
Key string `db:"key"`
Msg []byte `db:"msg"`
ID int `db:"id"`
Origin string `db:"text"`
timer *startimer.StarTimer
TmrInfo string `db:"code"`
Key string `db:"key"`
Msg []byte `db:"msg"`
}
func getCreateSql() []string {
return []string{
"CREATE TABLE IF NOT EXISTS remind(id INTEGER PRIMARY KEY AUTOINCREMENT,key VARCHAR(64),text TEXT,msg BLOB)",
"CREATE TABLE IF NOT EXISTS remind(id INTEGER PRIMARY KEY AUTOINCREMENT,key VARCHAR(64),code TEXT,text TEXT,msg BLOB)",
"CREATE INDEX IF NOT EXISTS key_idx ON remind (key)",
}
}
func NewRemind(db *stardb.StarDB, callback func(task RemindTask)) (*Remind, error) {
if db == nil || db.Db == nil {
return nil, errors.New("Invalid hanlder of database")
}
if err := db.Ping(); err != nil {
return nil, err
}
for _, sql := range getCreateSql() {
_, err := db.Exec(sql)
if err != nil {
return nil, err
}
}
return innerLoadDB(db, callback)
}
func innerLoadDB(db *stardb.StarDB, callback func(task RemindTask)) (*Remind, error) {
var rem = Remind{
db: db,
mu: sync.RWMutex{},
callback: callback,
}
var res []RemindTask
data, err := db.Query("select * from remind")
if err != nil {
return nil, err
}
err = data.Orm(&res)
if err != nil {
return nil, err
}
if len(res) != 0 {
rem.tasks = make(map[int]RemindTask, len(res))
for _, task := range res {
tmr := startimer.NewTimer(time.Now())
err = tmr.ImportRepeats(task.TmrInfo)
if err != nil {
return nil, err
}
task.timer = &tmr
task.timer.AddTask(func() {
rem.callbackFn(task)
})
err = task.timer.Run()
if err != nil {
return nil, err
}
rem.tasks[task.ID] = task
}
}
return &rem, nil
}
func (t RemindTask) GetTimer() startimer.StarTimer {
return *t.timer
}
func (r *Remind) callbackFn(task RemindTask) {
r.callback(task)
}
func (r *Remind) AddTask(taskStr, key string, msg []byte) (RemindTask, error) {
tmr, err := when.WhenWithPeriod(taskStr)
if err != nil {
return RemindTask{}, err
}
exp, err := tmr.ExportRepeats()
if err != nil {
return RemindTask{}, err
}
var rmt = RemindTask{
Origin: taskStr,
TmrInfo: exp,
Key: key,
Msg: msg,
timer: &tmr,
}
rmt.timer.AddTask(func() {
r.callbackFn(rmt)
})
res, err := r.db.Insert(rmt, "remind", "id")
if err != nil {
return RemindTask{}, err
}
id, err := res.LastInsertId()
if err != nil {
return RemindTask{}, err
}
rmt.ID = int(id)
r.mu.Lock()
r.tasks[rmt.ID] = rmt
r.mu.Unlock()
rmt.timer.Run()
return rmt, nil
}
func (r *Remind) DeleteTask(id int) error {
r.mu.RLock()
data, ok := r.tasks[id]
r.mu.RUnlock()
if !ok {
return errors.New("no such id")
}
r.mu.Lock()
defer r.mu.Unlock()
err := data.timer.Stop()
if err != nil {
return err
}
_, err = r.db.Exec("delete from remind where id=?", id)
if err != nil {
return err
}
delete(r.tasks, id)
return nil
}