mirror of
https://github.com/injoyai/tdx.git
synced 2025-11-26 21:25:35 +08:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7b6963bd6 | ||
|
|
456a0af9a5 | ||
|
|
84404bcb2c | ||
|
|
716e35122f | ||
|
|
c4866a2f2e |
148
codes.go
148
codes.go
@@ -34,12 +34,6 @@ func NewCodesMysql(c *Client, dsn string) (*Codes, error) {
|
||||
return nil, err
|
||||
}
|
||||
db.SetMapper(core.SameMapper{})
|
||||
if err := db.Sync2(new(CodeModel)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := db.Sync2(new(UpdateModel)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewCodes(c, db)
|
||||
}
|
||||
@@ -62,6 +56,12 @@ func NewCodesSqlite(c *Client, filenames ...string) (*Codes, error) {
|
||||
}
|
||||
db.SetMapper(core.SameMapper{})
|
||||
db.DB().SetMaxOpenConns(1)
|
||||
|
||||
return NewCodes(c, db)
|
||||
}
|
||||
|
||||
func NewCodes(c *Client, db *xorm.Engine) (*Codes, error) {
|
||||
|
||||
if err := db.Sync2(new(CodeModel)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -69,17 +69,13 @@ func NewCodesSqlite(c *Client, filenames ...string) (*Codes, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewCodes(c, db)
|
||||
}
|
||||
|
||||
func NewCodes(c *Client, db *xorm.Engine) (*Codes, error) {
|
||||
|
||||
update := new(UpdateModel)
|
||||
{ //查询或者插入一条数据
|
||||
has, err := db.Get(update)
|
||||
has, err := db.Where("`Key`=?", "codes").Get(update)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
update.Key = "codes"
|
||||
if _, err := db.Insert(update); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -127,83 +123,6 @@ func NewCodes(c *Client, db *xorm.Engine) (*Codes, error) {
|
||||
return cc, cc.Update(true)
|
||||
}
|
||||
|
||||
//func NewCodes(c *Client, filenames ...string) (*Codes, error) {
|
||||
//
|
||||
// //如果没有指定文件名,则使用默认
|
||||
// defaultFilename := filepath.Join(DefaultDatabaseDir, "codes.db")
|
||||
// filename := conv.Default(defaultFilename, filenames...)
|
||||
// filename = conv.Select(filename == "", defaultFilename, filename)
|
||||
//
|
||||
// //如果文件夹不存在就创建
|
||||
// dir, _ := filepath.Split(filename)
|
||||
// _ = os.MkdirAll(dir, 0777)
|
||||
//
|
||||
// //连接数据库
|
||||
// db, err := xorm.NewEngine("sqlite", filename)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// db.SetMapper(core.SameMapper{})
|
||||
// db.DB().SetMaxOpenConns(1)
|
||||
// if err := db.Sync2(new(CodeModel)); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// if err := db.Sync2(new(UpdateModel)); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// update := new(UpdateModel)
|
||||
// { //查询或者插入一条数据
|
||||
// has, err := db.Get(update)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// } else if !has {
|
||||
// if _, err := db.Insert(update); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// cc := &Codes{
|
||||
// Client: c,
|
||||
// db: db,
|
||||
// }
|
||||
//
|
||||
// { //设置定时器,每天早上9点更新数据
|
||||
// task := cron.New(cron.WithSeconds())
|
||||
// task.AddFunc("10 0 9 * * *", func() {
|
||||
// for i := 0; i < 3; i++ {
|
||||
// if err := cc.Update(); err == nil {
|
||||
// return
|
||||
// }
|
||||
// logs.Err(err)
|
||||
// <-time.After(time.Minute * 5)
|
||||
// }
|
||||
// })
|
||||
// task.Start()
|
||||
// }
|
||||
//
|
||||
// { //判断是否更新过,更新过则不更新
|
||||
// now := time.Now()
|
||||
// node := time.Date(now.Year(), now.Month(), now.Day(), 9, 0, 0, 0, time.Local)
|
||||
// updateTime := time.Unix(update.Time, 0)
|
||||
// if now.Sub(node) > 0 {
|
||||
// //当前时间在9点之后,且更新时间在9点之前,需要更新
|
||||
// if updateTime.Sub(node) < 0 {
|
||||
// return cc, cc.Update()
|
||||
// }
|
||||
// } else {
|
||||
// //当前时间在9点之前,且更新时间在上个节点之前
|
||||
// if updateTime.Sub(node.Add(time.Hour*24)) < 0 {
|
||||
// return cc, cc.Update()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //从缓存中加载
|
||||
// return cc, cc.Update(true)
|
||||
//}
|
||||
|
||||
type Codes struct {
|
||||
*Client //客户端
|
||||
db *xorm.Engine //数据库实例
|
||||
@@ -276,7 +195,7 @@ func (this *Codes) Update(byDB ...bool) error {
|
||||
this.list = codes
|
||||
this.exchanges = exchanges
|
||||
//更新时间
|
||||
_, err = this.db.Update(&UpdateModel{Time: time.Now().Unix()})
|
||||
_, err = this.db.Where("`Key`=?", "codes").Update(&UpdateModel{Time: time.Now().Unix()})
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -339,29 +258,52 @@ func (this *Codes) GetCodes(byDatabase bool) ([]*CodeModel, error) {
|
||||
}
|
||||
}
|
||||
|
||||
//4. 插入或者更新数据库
|
||||
err := NewSessionFunc(this.db, func(session *xorm.Session) error {
|
||||
for _, v := range insert {
|
||||
if _, err := session.Insert(v); err != nil {
|
||||
return err
|
||||
switch this.db.Dialect().URI().DBType {
|
||||
case "mysql":
|
||||
// 1️⃣ 清空
|
||||
if _, err := this.db.Exec("TRUNCATE TABLE codes"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data := append(insert, update...)
|
||||
// 2️⃣ 直接批量插入
|
||||
batchSize := 3000 // 8000(2m16s) 5000(43s) 3000(11s) 1000(59s)
|
||||
for i := 0; i < len(data); i += batchSize {
|
||||
end := i + batchSize
|
||||
if end > len(data) {
|
||||
end = len(data)
|
||||
}
|
||||
|
||||
slice := conv.Array(data[i:end])
|
||||
if _, err := this.db.Insert(slice); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
for _, v := range update {
|
||||
if _, err := session.Where("Exchange=? and Code=? ", v.Exchange, v.Code).Cols("Name,LastPrice").Update(v); err != nil {
|
||||
return err
|
||||
case "sqlite3":
|
||||
//4. 插入或者更新数据库
|
||||
err := NewSessionFunc(this.db, func(session *xorm.Session) error {
|
||||
for _, v := range insert {
|
||||
if _, err := session.Insert(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, v := range update {
|
||||
if _, err := session.Where("Exchange=? and Code=? ", v.Exchange, v.Code).Cols("Name,LastPrice").Update(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return list, nil
|
||||
|
||||
}
|
||||
|
||||
type UpdateModel struct {
|
||||
Key string
|
||||
Time int64 //更新时间
|
||||
}
|
||||
|
||||
|
||||
17
example/ManageMysql/main.go
Normal file
17
example/ManageMysql/main.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/injoyai/logs"
|
||||
"github.com/injoyai/tdx"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_, err := tdx.NewManageMysql(&tdx.ManageConfig{
|
||||
Number: 2,
|
||||
CodesFilename: "root:root@tcp(192.168.1.105:3306)/stock?charset=utf8mb4&parseTime=True&loc=Local",
|
||||
WorkdayFileName: "root:root@tcp(192.168.1.105:3306)/stock?charset=utf8mb4&parseTime=True&loc=Local",
|
||||
Dial: nil,
|
||||
})
|
||||
logs.PanicErr(err)
|
||||
logs.Debug("done")
|
||||
}
|
||||
52
manage.go
52
manage.go
@@ -1,6 +1,7 @@
|
||||
package tdx
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/injoyai/ios/client"
|
||||
"github.com/robfig/cron/v3"
|
||||
"time"
|
||||
@@ -10,6 +11,57 @@ const (
|
||||
DefaultDatabaseDir = "./data/database"
|
||||
)
|
||||
|
||||
func NewManageMysql(cfg *ManageConfig, op ...client.Option) (*Manage, error) {
|
||||
//初始化配置
|
||||
if cfg == nil {
|
||||
cfg = &ManageConfig{}
|
||||
}
|
||||
if cfg.CodesFilename == "" {
|
||||
return nil, errors.New("未配置Codes的数据库")
|
||||
}
|
||||
if cfg.WorkdayFileName == "" {
|
||||
return nil, errors.New("未配置Workday的数据库")
|
||||
}
|
||||
if cfg.Dial == nil {
|
||||
cfg.Dial = DialDefault
|
||||
}
|
||||
|
||||
//通用客户端
|
||||
commonClient, err := cfg.Dial(op...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
commonClient.Wait.SetTimeout(time.Second * 5)
|
||||
|
||||
//代码管理
|
||||
codes, err := NewCodesMysql(commonClient, cfg.CodesFilename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//工作日管理
|
||||
workday, err := NewWorkdayMysql(commonClient, cfg.WorkdayFileName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//连接池
|
||||
p, err := NewPool(func() (*Client, error) {
|
||||
return cfg.Dial(op...)
|
||||
}, cfg.Number)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Manage{
|
||||
Pool: p,
|
||||
Config: cfg,
|
||||
Codes: codes,
|
||||
Workday: workday,
|
||||
Cron: cron.New(cron.WithSeconds()),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewManage(cfg *ManageConfig, op ...client.Option) (*Manage, error) {
|
||||
//初始化配置
|
||||
if cfg == nil {
|
||||
|
||||
78
workday.go
78
workday.go
@@ -24,9 +24,6 @@ func NewWorkdayMysql(c *Client, dsn string) (*Workday, error) {
|
||||
return nil, err
|
||||
}
|
||||
db.SetMapper(core.SameMapper{})
|
||||
if err := db.Sync2(new(WorkdayModel)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewWorkday(c, db)
|
||||
}
|
||||
@@ -47,14 +44,15 @@ func NewWorkdaySqlite(c *Client, filenames ...string) (*Workday, error) {
|
||||
}
|
||||
db.SetMapper(core.SameMapper{})
|
||||
db.DB().SetMaxOpenConns(1)
|
||||
if err := db.Sync2(new(WorkdayModel)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewWorkday(c, db)
|
||||
}
|
||||
|
||||
func NewWorkday(c *Client, db *xorm.Engine) (*Workday, error) {
|
||||
if err := db.Sync2(new(WorkdayModel)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
w := &Workday{
|
||||
Client: c,
|
||||
db: db,
|
||||
@@ -76,48 +74,6 @@ func NewWorkday(c *Client, db *xorm.Engine) (*Workday, error) {
|
||||
return w, w.Update()
|
||||
}
|
||||
|
||||
//func NewWorkday(c *Client, filenames ...string) (*Workday, error) {
|
||||
//
|
||||
// defaultFilename := filepath.Join(DefaultDatabaseDir, "workday.db")
|
||||
// filename := conv.Default(defaultFilename, filenames...)
|
||||
//
|
||||
// //如果文件夹不存在就创建
|
||||
// dir, _ := filepath.Split(filename)
|
||||
// _ = os.MkdirAll(dir, 0777)
|
||||
//
|
||||
// //连接数据库
|
||||
// db, err := xorm.NewEngine("sqlite", filename)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// db.SetMapper(core.SameMapper{})
|
||||
// db.DB().SetMaxOpenConns(1)
|
||||
// if err := db.Sync2(new(WorkdayModel)); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// w := &Workday{
|
||||
// Client: c,
|
||||
// db: db,
|
||||
// cache: maps.NewBit(),
|
||||
// }
|
||||
//
|
||||
// //设置定时器,每天早上9点更新数据,8点多获取不到今天的数据
|
||||
// task := cron.New(cron.WithSeconds())
|
||||
// task.AddFunc("0 0 9 * * *", func() {
|
||||
// for i := 0; i < 3; i++ {
|
||||
// if err := w.Update(); err == nil {
|
||||
// return
|
||||
// }
|
||||
// logs.Err(err)
|
||||
// <-time.After(time.Minute * 5)
|
||||
// }
|
||||
// })
|
||||
// task.Start()
|
||||
//
|
||||
// return w, w.Update()
|
||||
//}
|
||||
|
||||
type Workday struct {
|
||||
*Client
|
||||
db *xorm.Engine
|
||||
@@ -148,27 +104,30 @@ func (this *Workday) Update() error {
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
if lastWorkday == nil || lastWorkday.Unix < IntegerDay(now).Unix() {
|
||||
if lastWorkday.Unix < IntegerDay(now).Unix() {
|
||||
resp, err := this.Client.GetIndexDayAll("sh000001")
|
||||
if err != nil {
|
||||
logs.Err(err)
|
||||
return err
|
||||
}
|
||||
|
||||
return NewSessionFunc(this.db, func(session *xorm.Session) error {
|
||||
for _, v := range resp.List {
|
||||
if unix := v.Time.Unix(); unix > lastWorkday.Unix {
|
||||
_, err = session.Insert(&WorkdayModel{Unix: unix, Date: v.Time.Format("20060102"), Is: true})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
this.cache.Set(uint64(unix), true)
|
||||
}
|
||||
inserts := []any(nil)
|
||||
for _, v := range resp.List {
|
||||
if unix := v.Time.Unix(); unix > lastWorkday.Unix {
|
||||
inserts = append(inserts, &WorkdayModel{Unix: unix, Date: v.Time.Format("20060102")})
|
||||
this.cache.Set(uint64(unix), true)
|
||||
}
|
||||
}
|
||||
|
||||
if len(inserts) == 0 {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
_, err = this.db.Insert(inserts)
|
||||
return err
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -222,7 +181,6 @@ type WorkdayModel struct {
|
||||
ID int64 `json:"id"` //主键
|
||||
Unix int64 `json:"unix"` //时间戳
|
||||
Date string `json:"date"` //日期
|
||||
Is bool `json:"is"` //是否是工作日
|
||||
}
|
||||
|
||||
func (this *WorkdayModel) TableName() string {
|
||||
|
||||
Reference in New Issue
Block a user