1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-25 16:58:06 +08:00
This commit is contained in:
shaoying 2019-07-27 12:45:01 +08:00
parent c0c9f26fe2
commit 013b38fb1b
2 changed files with 290 additions and 369 deletions

View File

@ -4,5 +4,5 @@ var version = struct {
host string
self int
}{
"2019-07-27 06:00:22", "mac", 219,
"2019-07-27 12:43:56", "ZYB-20190522USI", 276,
}

View File

@ -1,33 +1,34 @@
package mdb
import (
"contexts/ctx"
"time"
"toolkit"
"database/sql"
_ "github.com/go-sql-driver/mysql"
"github.com/gomodule/redigo/redis"
"contexts/ctx"
"toolkit"
"database/sql"
"encoding/json"
"fmt"
"strings"
"time"
)
type MDB struct {
*sql.DB
conn redis.Conn
*sql.DB
*ctx.Context
}
func (mdb *MDB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
c.Caches = map[string]*ctx.Cache{
"database": &ctx.Cache{Name: "database", Value: m.Confx("database", arg, 0), Help: "数据库"},
"username": &ctx.Cache{Name: "username", Value: m.Confx("username", arg, 1), Help: "账户"},
"username": &ctx.Cache{Name: "username", Value: m.Confx("username", arg, 1), Help: "用户名"},
"password": &ctx.Cache{Name: "password", Value: m.Confx("password", arg, 2), Help: "密码"},
"address": &ctx.Cache{Name: "address", Value: m.Confx("address", arg, 3), Help: "地址"},
"protocol": &ctx.Cache{Name: "protocol(tcp)", Value: m.Confx("protocol", arg, 4), Help: "协议"},
"driver": &ctx.Cache{Name: "driver(mysql)", Value: m.Confx("driver", arg, 5), Help: "驱动"},
"redis": &ctx.Cache{Name: "redis", Value: "", Help: "数据缓存"},
}
c.Configs = map[string]*ctx.Config{
"dbs": &ctx.Config{Name: "dbs", Value: []string{}, Help: "数据库"},
@ -36,18 +37,17 @@ func (mdb *MDB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
"offset": &ctx.Config{Name: "offset", Value: "0", Help: "偏移"},
}
s := new(MDB)
s.Context = c
return s
return &MDB{Context: c}
}
func (mdb *MDB) Begin(m *ctx.Message, arg ...string) ctx.Server {
return mdb
}
func (mdb *MDB) Start(m *ctx.Message, arg ...string) bool {
db, e := sql.Open(m.Cap("driver"), fmt.Sprintf("%s:%s@%s(%s)/%s", m.Cap("username"), m.Cap("password"), m.Cap("protocol"), m.Cap("address"), m.Cap("database")))
m.Assert(e)
mdb.DB = db
if db, e := sql.Open(m.Cap("driver"), fmt.Sprintf("%s:%s@%s(%s)/%s", m.Cap("username"), m.Cap("password"),
m.Cap("protocol"), m.Cap("address"), m.Cap("database"))); m.Assert(e) {
m.Log("info", "mdb open %s", m.Cap("stream", m.Cap("database")))
mdb.DB = db
}
return false
}
func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool {
@ -57,16 +57,19 @@ func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool {
var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
Caches: map[string]*ctx.Cache{
"nsource": &ctx.Cache{Name: "nsource", Value: "0", Help: "已打开数据库的数量"},
"redis": &ctx.Cache{Name: "redis", Value: "", Help: "服务地址"},
},
Configs: map[string]*ctx.Config{
"database": &ctx.Config{Name: "database", Value: "demo", Help: "默认数据库"},
"username": &ctx.Config{Name: "username", Value: "demo", Help: "默认账户"},
"password": &ctx.Config{Name: "password", Value: "demo", Help: "默认密码"},
"address": &ctx.Config{Name: "address", Value: ":6379", Help: "默认地址"},
"protocol": &ctx.Config{Name: "protocol(tcp)", Value: "tcp", Help: "默认协议"},
"address": &ctx.Config{Name: "address", Value: "", Help: "默认地址"},
"driver": &ctx.Config{Name: "driver(mysql)", Value: "mysql", Help: "默认驱动"},
"ktv": &ctx.Config{Name: "ktv", Value: map[string]interface{}{
"conf": map[string]interface{}{"expire": "24h"}, "data": map[string]interface{}{},
}, Help: "缓存数据"},
"temp": &ctx.Config{Name: "temp", Value: map[string]interface{}{}, Help: "缓存数据"},
"temp_view": &ctx.Config{Name: "temp_view", Value: map[string]interface{}{}, Help: "缓存数据"},
"temp_expire": &ctx.Config{Name: "temp_expire(s)", Value: "3000", Help: "缓存数据"},
@ -96,102 +99,11 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
"base": []interface{}{"key", "create_time", "type", "name", "model", "value"},
"full": []interface{}{"key", "create_time", "access_time", "type", "name", "model", "value", "view", "data", "ship"},
}, Help: "数据视图"},
"ktv": &ctx.Config{Name: "ktv", Value: map[string]interface{}{
"conf": map[string]interface{}{"expire": "24h"}, "data": map[string]interface{}{},
}, Help: "缓存数据"},
},
Commands: map[string]*ctx.Command{
"ktv": &ctx.Command{Name: "ktv", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
now := kit.Int(m.Time("stamp"))
m.Confm("ktv", "data", func(key string, value map[string]interface{}) {
m.Push("key", key)
m.Push("expire", kit.Int(value["expire"])-now)
m.Push("value", value["value"])
})
m.Table()
return
}
if len(arg) == 1 {
if m.Confi("ktv", []string{"data", arg[0], "expire"}) < kit.Int(m.Time("stamp")) {
m.Conf("ktv", []string{"data", arg[0]}, "")
}
m.Echo(m.Conf("ktv", []string{"data", arg[0], "value"}))
return
}
m.Confv("ktv", []string{"data", arg[0]}, map[string]interface{}{
"expire": m.Time(kit.Select(m.Conf("ktv", "conf.expire"), arg, 2), "stamp"),
"value": arg[1],
})
m.Echo(arg[1])
return
}},
"redis": &ctx.Command{Name: "redis open address [protocol]", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) {
switch arg[0] {
case "open":
mdb.conn, e = redis.Dial("tcp", m.Cap("redis", arg[1]), redis.DialKeepAlive(time.Second*10))
default:
if mdb.conn == nil {
m.Echo("not open")
break
}
if mdb.conn.Err() != nil {
mdb.conn, e = redis.Dial("tcp", m.Cap("redis"), redis.DialKeepAlive(time.Second*10))
}
args := []interface{}{}
for _, v := range arg[1:] {
args = append(args, v)
}
res, err := mdb.conn.Do(arg[0], args...)
m.Assert(err)
switch val := res.(type) {
case redis.Error:
m.Echo("%v", val)
case []interface{}:
for i, v := range val {
m.Add("append", "index", i)
m.Add("append", "value", v)
}
m.Table()
default:
str := kit.Format(res)
var data interface{}
if json.Unmarshal([]byte(str), &data) == nil {
m.Echo(kit.Formats(data))
} else {
m.Echo(str)
}
}
}
}
return
}},
"open": &ctx.Command{Name: "open [database [username [password [address [protocol [driver]]]]]]",
Help: "打开数据库, database: 数据库名, username: 用户名, password: 密码, address: 服务地址, protocol: 服务协议, driver: 数据库类型",
Form: map[string]int{"dbname": 1, "dbhelp": 1},
Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool {
switch len(arg) {
case 0:
m.Auto("", fmt.Sprintf("database(%s)", m.Conf("database")), "数据库")
case 1:
m.Auto("", fmt.Sprintf("username(%s)", m.Conf("username")), "账号")
case 2:
m.Auto("", fmt.Sprintf("password(%s)", m.Conf("password")), "密码")
case 3:
m.Auto("", fmt.Sprintf("address(%s)", m.Conf("address")), "地址")
case 4:
m.Auto("", fmt.Sprintf("protocol(%s)", m.Conf("protocol")), "协议")
case 5:
m.Auto("", fmt.Sprintf("driver(%s)", m.Conf("driver")), "驱动")
default:
m.Auto("", "[dbname name]", "模块名")
m.Auto("", "[dbhelp help]", "帮助文档")
}
return true
},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
Form: map[string]int{"dbname": 1, "dbhelp": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Start(kit.Select(fmt.Sprintf("db%d", m.Capi("nsource", 1)), m.Option("dbname")),
kit.Select("数据源", m.Option("dbhelp")), arg...)
return
@ -203,16 +115,13 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
which = append(which, v)
}
ret, e := mdb.Exec(arg[0], which...)
m.Assert(e)
id, e := ret.LastInsertId()
m.Assert(e)
n, e := ret.RowsAffected()
m.Assert(e)
if ret, e := mdb.Exec(arg[0], which...); m.Assert(e) {
id, _ := ret.LastInsertId()
n, _ := ret.RowsAffected()
m.Log("info", "last(%s) nrow(%s)", m.Append("last", id), m.Append("nrow", n))
m.Echo("%d", n)
}
}
return
}},
"query": &ctx.Command{Name: "query sql [arg]", Help: "查询数据库, sql: SQL语句, arg: 查询参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
@ -222,12 +131,9 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
which = append(which, v)
}
rows, e := mdb.Query(arg[0], which...)
m.Assert(e)
if rows, e := mdb.Query(arg[0], which...); m.Assert(e) {
defer rows.Close()
cols, e := rows.Columns()
m.Assert(e)
if cols, e := rows.Columns(); m.Assert(e) {
num := len(cols)
for rows.Next() {
@ -239,16 +145,7 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
rows.Scan(ptrs...)
for i, k := range cols {
switch b := vals[i].(type) {
case nil:
m.Add("append", k, "")
case []byte:
m.Add("append", k, string(b))
case int64:
m.Add("append", k, fmt.Sprintf("%d", b))
default:
m.Add("append", k, fmt.Sprintf("%v", b))
}
m.Push(k, vals[i])
}
}
@ -259,21 +156,61 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
}
m.Table()
}
}
}
return
}},
"redis": &ctx.Command{Name: "redis [open address]|[cmd...]", Help: "缓存数据库", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) {
switch arg[0] {
case "open":
if mdb.conn, e = redis.Dial("tcp", m.Cap("redis", arg[1]), redis.DialKeepAlive(time.Second*10)); m.Assert(e) {
m.Log("info", "redis: %v", arg[1])
}
default:
if mdb.conn == nil || mdb.conn.Err() != nil {
if m.Caps("redis") {
m.Cmd("mdb.redis", "open", m.Cap("redis"))
} else {
m.Echo("not open")
break
}
}
args := []interface{}{}
for _, v := range arg[1:] {
args = append(args, v)
}
if res, err := mdb.conn.Do(arg[0], args...); m.Assert(err) {
switch val := res.(type) {
case redis.Error:
m.Echo("%v", val)
case []interface{}:
for i, v := range val {
m.Add("append", "index", i)
m.Add("append", "value", v)
}
m.Table()
default:
var data interface{}
if str := kit.Format(res); json.Unmarshal([]byte(str), &data) == nil {
m.Echo(kit.Formats(data))
} else {
m.Echo(str)
}
}
}
}
}
return
}},
"db": &ctx.Command{Name: "db [which]", Help: "查看或选择数据库",
Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool {
if len(arg) == 0 {
m.Put("option", "bio.cmd", "").Spawn().Cmd("query", "show databases").Table(func(line map[string]string) {
for _, v := range line {
m.Auto(v, "", "")
}
})
}
return true
},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
"db": &ctx.Command{Name: "db [which]", Help: "查看或选择数据库", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
m.Cmdy(".query", "show databases").Table()
return
@ -283,23 +220,7 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
m.Echo(m.Cap("database", arg[0]))
return
}},
"tab": &ctx.Command{Name: "tab [which [field]]", Help: "查看关系表which: 表名, field: 字段名",
Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool {
switch len(arg) {
case 0:
m.Put("option", "bio.cmd", "").Spawn().Cmd("query", "show tables").Table(func(line map[string]string) {
for _, v := range line {
m.Auto(v, "", "")
}
})
case 1:
m.Put("option", "bio.cmd", "").Spawn().Cmd("query", fmt.Sprintf("desc %s", arg[0])).Table(func(line map[string]string) {
m.Auto(line["Field"], line["Type"], line["Default"])
})
}
return true
},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
"tab": &ctx.Command{Name: "tab [which [field]]", Help: "查看关系表which: 表名, field: 字段名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
switch len(arg) {
case 0:
m.Cmdy(".query", "show tables").Table()
@ -311,31 +232,7 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
return
}},
"show": &ctx.Command{Name: "show table fields...", Help: "查询数据, table: 表名, fields: 字段, where: 查询条件, group: 聚合字段, order: 排序字段",
Form: map[string]int{"where": 1, "eq": 2, "like": 2, "in": 2, "begin": 2, "group": 1, "order": 1, "desc": 0, "limit": 1, "offset": 1, "other": -1},
Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool {
if len(arg) == 0 {
m.Put("option", "bio.cmd", "").Spawn().Cmd("query", "show tables").Table(func(line map[string]string) {
for _, v := range line {
m.Auto(v, "", "")
}
})
return true
}
m.Auto("where", "stmt", "条件语句")
m.Auto("eq", "field value", "条件语句")
m.Auto("in", "field value", "条件语句")
m.Auto("like", "field value", "条件语句")
m.Auto("begin", "field value", "条件语句")
m.Auto("group", "field", "聚合")
m.Auto("order", "field", "排序")
m.Auto("desc", "", "降序")
m.Auto("limit", "10", "分页")
m.Auto("offset", "0", "偏移")
m.Auto("other", "stmt", "其它")
return true
},
Form: map[string]int{"where": 1, "eq": 2, "in": 2, "like": 2, "begin": 2, "group": 1, "order": 1, "desc": 0, "limit": 1, "offset": 1, "other": -1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
m.Cmdy(".query", "show tables")
@ -407,17 +304,43 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
values = append(values, fmt.Sprintf("%s='%s'", arg[i], arg[i+1]))
}
stmt := []string{fmt.Sprintf("update %s", arg[0])}
stmt := []string{"update", arg[0]}
stmt = append(stmt, "set", strings.Join(values, ","))
stmt = append(stmt, fmt.Sprintf("where %s", arg[1]))
stmt = append(stmt, "where", arg[1])
m.Cmd(".exec", strings.Join(stmt, " "))
m.Cmdy("show", arg[0], fields, "where", arg[1])
m.Cmdy(".show", arg[0], fields, "where", arg[1])
}
return
}},
"temp": &ctx.Command{Name: "temp [type [meta [data]]] [tid [node|ship|data] [chain... [select ...]]]", Form: map[string]int{"select": -1, "limit": 1}, Help: "缓存数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
"ktv": &ctx.Command{Name: "ktv", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
now := kit.Int(m.Time("stamp"))
m.Confm("ktv", "data", func(key string, value map[string]interface{}) {
m.Push("key", key)
m.Push("expire", kit.Int(value["expire"])-now)
m.Push("value", value["value"])
})
m.Table()
return
}
if len(arg) == 1 {
if m.Confi("ktv", []string{"data", arg[0], "expire"}) < kit.Int(m.Time("stamp")) {
m.Conf("ktv", []string{"data", arg[0]}, "")
}
m.Echo(m.Conf("ktv", []string{"data", arg[0], "value"}))
return
}
m.Confv("ktv", []string{"data", arg[0]}, map[string]interface{}{
"expire": m.Time(kit.Select(m.Conf("ktv", "conf.expire"), arg, 2), "stamp"),
"value": arg[1],
})
m.Echo(arg[1])
return
}},
"temp": &ctx.Command{Name: "temp [type [meta [data]]] [tid [node|ship|data] [chain... [select ...]]]",
Form: map[string]int{"select": -1, "limit": 1}, Help: "缓存数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) > 0 && arg[0] == "check" {
h := ""
for i := 1; i < len(arg)-1; i += 2 {
@ -873,7 +796,5 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
}
func init() {
mdb := &MDB{}
mdb.Context = Index
ctx.Index.Register(Index, mdb)
ctx.Index.Register(Index, &MDB{Context: Index})
}