mirror of
https://shylinux.com/x/ContextOS
synced 2025-04-25 16:58:06 +08:00
opt mdb
Change-Id: I359a53b2521bc0e92d079bc37a57e62c990458b9
This commit is contained in:
parent
5a0ac5646e
commit
108155dd31
@ -9,7 +9,7 @@ import (
|
||||
"toolkit"
|
||||
)
|
||||
|
||||
func sysinfo(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
func sysinfo(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
sys := &syscall.Sysinfo_t{}
|
||||
syscall.Sysinfo(sys)
|
||||
|
||||
@ -34,4 +34,5 @@ func sysinfo(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
m.Append("fper", fmt.Sprintf("%d%%", fs.Ffree*100/fs.Files))
|
||||
|
||||
m.Table()
|
||||
return
|
||||
}
|
||||
|
@ -103,12 +103,6 @@ func (c *Context) Begin(m *Message, arg ...string) *Context {
|
||||
m.source.sessions = append(m.source.sessions, m)
|
||||
c.exit = make(chan bool, 3)
|
||||
|
||||
switch v := m.Gdb("context", "begin", c.Name).(type) {
|
||||
case string:
|
||||
kit.Log("error", "fuck %v", v)
|
||||
case nil:
|
||||
}
|
||||
|
||||
m.Log("begin", "%d context %v %v", m.Capi("ncontext", 1), m.Meta["detail"], m.Meta["option"])
|
||||
for k, x := range c.Configs {
|
||||
if x.Hand != nil {
|
||||
@ -134,12 +128,6 @@ func (c *Context) Start(m *Message, arg ...string) bool {
|
||||
c.requests = append(c.requests, m)
|
||||
m.source.sessions = append(m.source.sessions, m)
|
||||
|
||||
switch v := m.Gdb("context", "start", c.Name).(type) {
|
||||
case string:
|
||||
kit.Log("error", "fuck %v", v)
|
||||
case nil:
|
||||
}
|
||||
|
||||
if m.Hand = true; m.Cap("status") == "start" {
|
||||
return true
|
||||
}
|
||||
@ -589,7 +577,7 @@ func (m *Message) Has(key ...string) bool {
|
||||
return false
|
||||
}
|
||||
func (m *Message) CopyTo(msg *Message, arg ...string) *Message {
|
||||
msg.Copy(m, arg...)
|
||||
msg.Copy(m, "append").Copy(m, "result")
|
||||
return m
|
||||
}
|
||||
func (m *Message) Copy(msg *Message, arg ...string) *Message {
|
||||
@ -1332,7 +1320,7 @@ func (m *Message) Free(cbs ...func(msg *Message) (done bool)) *Message {
|
||||
}
|
||||
|
||||
func (m *Message) Cmdy(args ...interface{}) *Message {
|
||||
m.Cmd(args...).CopyTo(m)
|
||||
m.Cmd(args...).CopyTo(m, "append").CopyTo(m, "result")
|
||||
return m
|
||||
}
|
||||
func (m *Message) Cmdx(args ...interface{}) string {
|
||||
@ -1353,6 +1341,7 @@ func (m *Message) Cmd(args ...interface{}) *Message {
|
||||
key, arg := m.Meta["detail"][0], m.Meta["detail"][1:]
|
||||
|
||||
m = m.Match(key, true, func(m *Message, s *Context, c *Context, key string) bool {
|
||||
m.Hand = false
|
||||
if x, ok := c.Commands[key]; ok && x.Hand != nil {
|
||||
m.TryCatch(m, true, func(m *Message) {
|
||||
m.Log("cmd", "%s %s %v %v", c.Name, key, arg, m.Meta["option"])
|
||||
@ -1467,10 +1456,11 @@ func (m *Message) Confx(key string, args ...interface{}) string {
|
||||
switch arg := args[0].(type) {
|
||||
case []string:
|
||||
if len(args) > 1 {
|
||||
value, args = kit.Select(value, arg, args[1]), args[1:]
|
||||
value = kit.Select(value, arg, args[1])
|
||||
} else {
|
||||
value = kit.Select(value, arg)
|
||||
}
|
||||
args = args[1:]
|
||||
case map[string]interface{}:
|
||||
value = kit.Select(value, kit.Format(arg[key]))
|
||||
case string:
|
||||
|
@ -125,7 +125,8 @@ var Index = &ctx.Context{Name: "log", Help: "日志中心",
|
||||
"trace": map[string]interface{}{"value": map[string]interface{}{"file": "error.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[32m", "color_end": "\033[0m"}},
|
||||
"debug": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}},
|
||||
"search": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}},
|
||||
"cbs": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}}},
|
||||
"call": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}},
|
||||
"back": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}},
|
||||
|
||||
"bench": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}}},
|
||||
"begin": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
|
||||
@ -139,8 +140,8 @@ var Index = &ctx.Context{Name: "log", Help: "日志中心",
|
||||
"cmd": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
|
||||
},
|
||||
"aaa": map[string]interface{}{
|
||||
// "auth": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
|
||||
// "hash": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
|
||||
"auth": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
|
||||
"hash": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
|
||||
},
|
||||
},
|
||||
}, Help: "日志输出配置"},
|
||||
|
@ -2,12 +2,13 @@ package mdb
|
||||
|
||||
import (
|
||||
"contexts/ctx"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"strings"
|
||||
"toolkit"
|
||||
|
||||
"database/sql"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type MDB struct {
|
||||
@ -17,24 +18,18 @@ type MDB struct {
|
||||
|
||||
func (mdb *MDB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
|
||||
c.Caches = map[string]*ctx.Cache{
|
||||
"database": &ctx.Cache{Name: "数据库", Value: m.Confx("database", arg, 0), Help: "数据库"},
|
||||
"username": &ctx.Cache{Name: "账户", Value: m.Confx("username", arg, 1), Help: "账户"},
|
||||
"password": &ctx.Cache{Name: "密码", Value: m.Confx("password", arg, 2), Help: "密码"},
|
||||
"address": &ctx.Cache{Name: "服务地址", Value: m.Confx("address", arg, 3), Help: "服务地址"},
|
||||
"protocol": &ctx.Cache{Name: "服务协议(tcp)", Value: m.Confx("protocol", arg, 4), Help: "服务协议"},
|
||||
"driver": &ctx.Cache{Name: "数据库驱动(mysql)", Value: m.Confx("driver", arg, 5), Help: "数据库驱动"},
|
||||
"database": &ctx.Cache{Name: "database", Value: m.Confx("database", arg, 0), 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: "驱动"},
|
||||
}
|
||||
c.Configs = map[string]*ctx.Config{
|
||||
"dbs": &ctx.Config{Name: "dbs", Value: []string{}, Help: "关系表"},
|
||||
"tables": &ctx.Config{Name: "dbs", Value: []string{}, Help: "关系表"},
|
||||
"table": &ctx.Config{Name: "关系表", Value: "0", Help: "关系表"},
|
||||
"field": &ctx.Config{Name: "字段名", Value: "", Help: "字段名"},
|
||||
"where": &ctx.Config{Name: "条件", Value: "", Help: "条件"},
|
||||
"group": &ctx.Config{Name: "聚合", Value: "", Help: "聚合"},
|
||||
"order": &ctx.Config{Name: "排序", Value: "", Help: "排序"},
|
||||
"limit": &ctx.Config{Name: "分页", Value: "10", Help: "分页"},
|
||||
"offset": &ctx.Config{Name: "偏移", Value: "0", Help: "偏移"},
|
||||
"parse": &ctx.Config{Name: "解析", Value: "", Help: "解析"},
|
||||
"dbs": &ctx.Config{Name: "dbs", Value: []string{}, Help: "数据库"},
|
||||
"tabs": &ctx.Config{Name: "tabs", Value: []string{}, Help: "关系表"},
|
||||
"limit": &ctx.Config{Name: "limit", Value: "10", Help: "分页"},
|
||||
"offset": &ctx.Config{Name: "offset", Value: "0", Help: "偏移"},
|
||||
}
|
||||
|
||||
s := new(MDB)
|
||||
@ -45,35 +40,30 @@ 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")))
|
||||
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
|
||||
m.Log("info", "mdb open %s", m.Cap("database"))
|
||||
m.Log("info", "mdb open %s", m.Cap("stream", m.Cap("database")))
|
||||
return false
|
||||
}
|
||||
func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool {
|
||||
switch mdb.Context {
|
||||
case m.Target():
|
||||
case m.Source():
|
||||
if mdb.DB != nil {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
|
||||
Caches: map[string]*ctx.Cache{
|
||||
"nsource": &ctx.Cache{Name: "数据源数量", Value: "0", Help: "已打开数据库的数量"},
|
||||
"nsource": &ctx.Cache{Name: "nsource", Value: "0", Help: "已打开数据库的数量"},
|
||||
},
|
||||
Configs: map[string]*ctx.Config{
|
||||
"database": &ctx.Config{Name: "默认数据库", Value: "demo", Help: "默认数据库"},
|
||||
"username": &ctx.Config{Name: "默认用户名", Value: "demo", Help: "默认用户名"},
|
||||
"password": &ctx.Config{Name: "默认密码", Value: "demo", Help: "默认密码"},
|
||||
"protocol": &ctx.Config{Name: "默认协议", Value: "tcp", Help: "默认协议"},
|
||||
"address": &ctx.Config{Name: "默认地址", Value: "", Help: "默认地址"},
|
||||
"driver": &ctx.Config{Name: "数据库驱动(mysql)", Value: "mysql", Help: "数据库驱动"},
|
||||
|
||||
"csv_col_sep": &ctx.Config{Name: "字段分隔符", Value: "\t", Help: "字段分隔符"},
|
||||
"csv_row_sep": &ctx.Config{Name: "记录分隔符", Value: "\n", Help: "记录分隔符"},
|
||||
"database": &ctx.Config{Name: "database", Value: "demo", Help: "默认数据库"},
|
||||
"username": &ctx.Config{Name: "username", Value: "demo", Help: "默认账户"},
|
||||
"password": &ctx.Config{Name: "password", Value: "demo", 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: "默认驱动"},
|
||||
|
||||
"temp": &ctx.Config{Name: "temp", Value: map[string]interface{}{}, Help: "缓存数据"},
|
||||
"temp_view": &ctx.Config{Name: "temp_view", Value: map[string]interface{}{}, Help: "缓存数据"},
|
||||
@ -212,18 +202,31 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
|
||||
}},
|
||||
|
||||
"open": &ctx.Command{Name: "open [database [username [password [address [protocol [driver]]]]]]",
|
||||
Help: "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) {
|
||||
dbname := fmt.Sprintf("db%d", m.Capi("nsource", 1))
|
||||
dbhelp := "数据源"
|
||||
if m.Has("dbname") {
|
||||
dbname = m.Option("dbname")
|
||||
}
|
||||
if m.Has("dbhelp") {
|
||||
dbname = m.Option("dbhelp")
|
||||
}
|
||||
m.Start(dbname, dbhelp, arg...)
|
||||
m.Start(kit.Select(fmt.Sprintf("db%d", m.Capi("nsource", 1)), m.Option("dbname")),
|
||||
kit.Select("数据源", m.Option("dbhelp")), arg...)
|
||||
return
|
||||
}},
|
||||
"exec": &ctx.Command{Name: "exec sql [arg]", Help: "操作数据库, sql: SQL语句, arg: 操作参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
@ -287,215 +290,176 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
|
||||
} else {
|
||||
m.Log("info", "rows(0) cols(0)")
|
||||
}
|
||||
}
|
||||
return
|
||||
}},
|
||||
"db": &ctx.Command{Name: "db [which]", 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) && mdb.DB != nil {
|
||||
if len(arg) == 0 {
|
||||
msg := m.Spawn().Cmd("query", "show databases")
|
||||
dbs := []string{}
|
||||
for i, v := range msg.Meta[msg.Meta["append"][0]] {
|
||||
dbs = append(dbs, v)
|
||||
m.Echo("%d: %s\n", i, v)
|
||||
}
|
||||
m.Target().Configs["dbs"].Value = dbs
|
||||
return
|
||||
}
|
||||
|
||||
db := m.Confv("dbs", arg[0]).(string)
|
||||
m.Assert(m.Spawn().Cmd("exec", fmt.Sprintf("use %s", db)))
|
||||
m.Echo(m.Cap("database", db))
|
||||
}
|
||||
return
|
||||
}},
|
||||
"tab": &ctx.Command{Name: "tab[which [field]]", Help: "查看关系表信息,which: 表名, field: 字段名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if _, ok := m.Target().Server.(*MDB); m.Assert(ok) {
|
||||
if len(arg) == 0 {
|
||||
msg := m.Spawn().Cmd("query", "show tables")
|
||||
tables := []string{}
|
||||
for i, v := range msg.Meta[msg.Meta["append"][0]] {
|
||||
tables = append(tables, v)
|
||||
m.Echo("%d: %s\n", i, v)
|
||||
}
|
||||
m.Target().Configs["tables"].Value = tables
|
||||
return
|
||||
}
|
||||
|
||||
table := arg[0]
|
||||
switch v := m.Confv("tables", arg[0]).(type) {
|
||||
case string:
|
||||
table = v
|
||||
}
|
||||
|
||||
msg := m.Spawn().Cmd("query", fmt.Sprintf("desc %s", table))
|
||||
m.Copy(msg, "append")
|
||||
m.Table()
|
||||
}
|
||||
return
|
||||
}},
|
||||
"show": &ctx.Command{Name: "show table fields...",
|
||||
Help: "查询数据库, table: 表名, fields: 字段, where: 查询条件, group: 聚合字段, order: 排序字段",
|
||||
Form: map[string]int{"like": 2, "eq": 2, "where": 1, "group": 1, "desc": 0, "order": 1, "limit": 1, "offset": 1, "other": -1,
|
||||
"extra_field": 2, "extra_fields": 1, "extra_format": 1, "trans_field": 1, "trans_map": 2},
|
||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if _, ok := m.Target().Server.(*MDB); m.Assert(ok) {
|
||||
if len(arg) == 0 {
|
||||
msg := m.Spawn().Cmd("query", "show tables")
|
||||
for _, v := range msg.Meta[msg.Meta["append"][0]] {
|
||||
m.Add("append", "table", v)
|
||||
|
||||
"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", "auto_cmd", "").Spawn().Cmd("query", "show databases").Table(func(line map[string]string) {
|
||||
for _, v := range line {
|
||||
m.Auto(v, "", "")
|
||||
}
|
||||
m.Table()
|
||||
return
|
||||
}
|
||||
|
||||
table := m.Confx("table", arg, 0)
|
||||
if v := m.Confv("tables", table); v != nil {
|
||||
table = v.(string)
|
||||
}
|
||||
|
||||
fields := []string{"*"}
|
||||
if len(arg) > 1 {
|
||||
fields = arg[1:]
|
||||
} else if m.Confs("field") {
|
||||
fields = []string{m.Conf("field")}
|
||||
}
|
||||
field := strings.Join(fields, ",")
|
||||
|
||||
eq := []string{}
|
||||
for i := 0; i < len(m.Meta["eq"]); i += 2 {
|
||||
eq = append(eq, fmt.Sprintf(" %s='%s' ", m.Meta["eq"][i], m.Meta["eq"][i+1]))
|
||||
}
|
||||
|
||||
if len(eq) > 0 {
|
||||
if m.Options("where") {
|
||||
m.Option("where", m.Option("where")+" and "+strings.Join(eq, "and"))
|
||||
} else {
|
||||
m.Option("where", strings.Join(eq, "and"))
|
||||
}
|
||||
}
|
||||
|
||||
begin := []string{}
|
||||
for i := 0; i < len(m.Meta["begin"]); i += 2 {
|
||||
begin = append(begin, fmt.Sprintf(" %s like '%s%%' ", m.Meta["begin"][i], m.Meta["begin"][i+1]))
|
||||
}
|
||||
|
||||
if len(begin) > 0 {
|
||||
if m.Options("where") {
|
||||
m.Option("where", m.Option("where")+" and "+strings.Join(begin, "and"))
|
||||
} else {
|
||||
m.Option("where", strings.Join(begin, "and"))
|
||||
}
|
||||
}
|
||||
|
||||
where := m.Confx("where", m.Option("where"), "where %s")
|
||||
group := m.Confx("group", m.Option("group"), "group by %s")
|
||||
order := m.Confx("order", m.Option("order"), "order by %s")
|
||||
if m.Has("desc") {
|
||||
order = order + " desc"
|
||||
}
|
||||
limit := m.Confx("limit", m.Option("limit"), "limit %s")
|
||||
offset := m.Confx("offset", m.Option("offset"), "offset %s")
|
||||
|
||||
other := m.Meta["other"]
|
||||
for i, v := range other {
|
||||
if len(v) > 1 {
|
||||
switch v[0] {
|
||||
case '$':
|
||||
other[i] = m.Cap(v[1:])
|
||||
case '@':
|
||||
other[i] = m.Conf(v[1:])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
msg := m.Spawn().Cmd("query", fmt.Sprintf("select %s from %s %s %s %s %s %s", field, table, where, group, order, limit, offset), other)
|
||||
m.Copy(msg, "append")
|
||||
|
||||
m.Target().Configs["template_value"] = &ctx.Config{}
|
||||
if m.Has("extra_field") && len(m.Meta[m.Option("extra_field")]) > 0 {
|
||||
format := "%v"
|
||||
if m.Has("extra_format") {
|
||||
format = m.Option("extra_format")
|
||||
}
|
||||
for i := 0; i < len(m.Meta[m.Option("extra_field")]); i++ {
|
||||
json.Unmarshal([]byte(m.Meta[m.Option("extra_field")][i]), &m.Target().Configs["template_value"].Value)
|
||||
if m.Meta["extra_field"][1] != "" {
|
||||
m.Target().Configs["template_value"].Value = m.Confv("template_value", m.Meta["extra_field"][1])
|
||||
}
|
||||
fields = strings.Split(m.Option("extra_fields"), " ")
|
||||
switch v := m.Confv("template_value").(type) {
|
||||
case map[string]interface{}:
|
||||
for _, k := range fields {
|
||||
if k == "" {
|
||||
continue
|
||||
}
|
||||
if val, ok := v[k]; ok {
|
||||
m.Add("append", k, fmt.Sprintf(format, val))
|
||||
} else {
|
||||
m.Add("append", k, fmt.Sprintf(format, ""))
|
||||
}
|
||||
}
|
||||
m.Meta[m.Option("extra_field")][i] = ""
|
||||
case float64:
|
||||
m.Meta[m.Option("extra_field")][i] = fmt.Sprintf(format, int(v))
|
||||
case nil:
|
||||
m.Meta[m.Option("extra_field")][i] = ""
|
||||
default:
|
||||
m.Meta[m.Option("extra_field")][i] = fmt.Sprintf(format, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if m.Has("trans_field") {
|
||||
trans := map[string]string{}
|
||||
for i := 0; i < len(m.Meta["trans_map"]); i += 2 {
|
||||
trans[m.Meta["trans_map"][i]] = m.Meta["trans_map"][i+1]
|
||||
}
|
||||
for i := 0; i < len(m.Meta[m.Option("trans_field")]); i++ {
|
||||
if t, ok := trans[m.Meta[m.Option("trans_field")][i]]; ok {
|
||||
m.Meta[m.Option("trans_field")][i] = t
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ncol := len(msg.Meta["append"])
|
||||
nrow := len(msg.Meta[msg.Meta["append"][0]])
|
||||
|
||||
m.Echo("data: %dx%d ", nrow, ncol)
|
||||
m.Echo(table).Echo(" %s %s %s %s %s %v\n", where, group, order, limit, offset, m.Meta["other"])
|
||||
|
||||
m.Table(func(maps map[string]string, lists []string, line int) bool {
|
||||
for i, v := range lists {
|
||||
m.Echo(v)
|
||||
if i < len(lists)-1 {
|
||||
m.Echo(m.Conf("csv_col_sep"))
|
||||
}
|
||||
}
|
||||
m.Echo(m.Conf("csv_row_sep"))
|
||||
return true
|
||||
})
|
||||
}
|
||||
return true
|
||||
},
|
||||
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
|
||||
}
|
||||
|
||||
m.Assert(m.Cmdy("exec", fmt.Sprintf("use %s", arg[0])))
|
||||
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", "auto_cmd", "").Spawn().Cmd("query", "show tables").Table(func(line map[string]string) {
|
||||
for _, v := range line {
|
||||
m.Auto(v, "", "")
|
||||
}
|
||||
})
|
||||
case 1:
|
||||
m.Put("option", "auto_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) {
|
||||
switch len(arg) {
|
||||
case 0:
|
||||
m.Cmdy(".query", "show tables").Table()
|
||||
case 1:
|
||||
m.Cmdy(".query", fmt.Sprintf("desc %s", arg[0])).Table()
|
||||
case 2:
|
||||
m.Cmdy(".query", fmt.Sprintf("desc %s", arg[0])).Cmd("select", "Field", arg[1]).CopyTo(m)
|
||||
}
|
||||
return
|
||||
}},
|
||||
"set": &ctx.Command{Name: "set table [field value] where condition", Help: "查看或选择数据库信息", Form: map[string]int{"where": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) && mdb.DB != nil {
|
||||
sql := []string{"update", arg[0], "set"}
|
||||
fields := []string{}
|
||||
for i := 1; i < len(arg)-1; i += 2 {
|
||||
sql = append(sql, fmt.Sprintf("%s='%s'", arg[i], arg[i+1]))
|
||||
fields = append(fields, arg[i])
|
||||
if i < len(arg)-2 {
|
||||
sql = append(sql, ",")
|
||||
}
|
||||
"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", "auto_cmd", "").Spawn().Cmd("query", "show tables").Table(func(line map[string]string) {
|
||||
for _, v := range line {
|
||||
m.Auto(v, "", "")
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
sql = append(sql, fmt.Sprintf("where %s", m.Option("where")))
|
||||
m.Spawn().Cmd("exec", strings.Join(sql, " "))
|
||||
msg := m.Spawn().Cmd("show", arg[0], fields, "where", m.Option("where"))
|
||||
m.Copy(msg, "result").Copy(msg, "append")
|
||||
}
|
||||
return
|
||||
}},
|
||||
|
||||
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
|
||||
},
|
||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Cmdy(".query", "show tables")
|
||||
return
|
||||
}
|
||||
|
||||
stmt := []string{
|
||||
fmt.Sprintf("select %s", kit.Select("*", strings.Join(arg[1:], ","))),
|
||||
fmt.Sprintf("from %s", arg[0]),
|
||||
}
|
||||
|
||||
where := []string{}
|
||||
if m.Has("where") {
|
||||
where = append(where, m.Option("where"))
|
||||
}
|
||||
for i := 0; i < len(m.Meta["eq"]); i += 2 {
|
||||
where = append(where, fmt.Sprintf("%s='%s'", m.Meta["eq"][i], m.Meta["eq"][i+1]))
|
||||
}
|
||||
for i := 0; i < len(m.Meta["in"]); i += 2 {
|
||||
where = append(where, fmt.Sprintf("%s in (%s)", m.Meta["in"][i], m.Meta["in"][i+1]))
|
||||
}
|
||||
for i := 0; i < len(m.Meta["like"]); i += 2 {
|
||||
where = append(where, fmt.Sprintf("%s like '%s'", m.Meta["like"][i], m.Meta["like"][i+1]))
|
||||
}
|
||||
for i := 0; i < len(m.Meta["begin"]); i += 2 {
|
||||
where = append(where, fmt.Sprintf("%s like '%s%%'", m.Meta["begin"][i], m.Meta["begin"][i+1]))
|
||||
}
|
||||
if len(where) > 0 {
|
||||
stmt = append(stmt, "where", strings.Join(where, " and "))
|
||||
}
|
||||
|
||||
if m.Has("group") {
|
||||
stmt = append(stmt, fmt.Sprintf("group by %s", m.Option("group")))
|
||||
}
|
||||
if m.Has("order") {
|
||||
stmt = append(stmt, fmt.Sprintf("order by %s", m.Option("order")))
|
||||
}
|
||||
if m.Has("desc") {
|
||||
stmt = append(stmt, "desc")
|
||||
}
|
||||
|
||||
stmt = append(stmt, fmt.Sprintf("limit %s", m.Confx("limit")))
|
||||
stmt = append(stmt, fmt.Sprintf("offset %s", m.Confx("offset")))
|
||||
|
||||
for _, v := range m.Meta["other"] {
|
||||
stmt = append(stmt, m.Parse(v))
|
||||
}
|
||||
|
||||
m.Cmdy(".query", strings.Join(stmt, " "))
|
||||
return
|
||||
}},
|
||||
"update": &ctx.Command{Name: "update table condition [set field value]", Help: "修改数据, table: 关系表, condition: 条件语句, set: 修改数据",
|
||||
Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool {
|
||||
if len(arg) == 0 {
|
||||
m.Put("option", "auto_cmd", "").Spawn().Cmd("query", "show tables").Table(func(line map[string]string) {
|
||||
for _, v := range line {
|
||||
m.Auto(v, "", "")
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
if len(arg) == 2 {
|
||||
// m.Put("option", "auto_cmd", "").Spawn().Cmd("show", arg[0], "where", arg[1]).Table(func(line map[string]string) {
|
||||
// for _, v := range line {
|
||||
// m.Auto(v, "", "")
|
||||
// }
|
||||
// })
|
||||
return true
|
||||
}
|
||||
return true
|
||||
},
|
||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 2 {
|
||||
m.Cmd(".show", arg[0], "where", arg[1]).CopyTo(m, "append")
|
||||
}
|
||||
|
||||
fields := []string{}
|
||||
values := []string{}
|
||||
for i := 3; i < len(arg)-1; i += 2 {
|
||||
fields = append(fields, arg[i])
|
||||
values = append(values, fmt.Sprintf("%s='%s'", arg[i], arg[i+1]))
|
||||
}
|
||||
|
||||
stmt := []string{fmt.Sprintf("update %s", arg[0])}
|
||||
stmt = append(stmt, "set", strings.Join(values, ","))
|
||||
stmt = append(stmt, fmt.Sprintf("where %s", arg[1]))
|
||||
|
||||
m.Cmd(".exec", strings.Join(stmt, " "))
|
||||
m.Cmdy("show", arg[0], fields, "where", arg[1])
|
||||
return
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -340,6 +340,7 @@ func (nfs *NFS) Read(p []byte) (n int, err error) {
|
||||
|
||||
case termbox.KeyCtrlG:
|
||||
case termbox.KeyCtrlX:
|
||||
m.Options("show_shadow", !m.Options("show_shadow"))
|
||||
case termbox.KeyCtrlS:
|
||||
|
||||
case termbox.KeyCtrlZ:
|
||||
@ -416,7 +417,7 @@ func (nfs *NFS) Auto(what []rune, trigger string, index int) (change bool, frame
|
||||
m.Optionv("auto_target", auto_target)
|
||||
trigger = ":"
|
||||
case "command":
|
||||
m.Option("arg_index", index+1)
|
||||
m.Option("arg_index", index)
|
||||
auto_cmd = m.Option("auto_cmd", m.Option("auto_key"))
|
||||
trigger = "="
|
||||
case "argument":
|
||||
@ -471,7 +472,7 @@ func (nfs *NFS) Auto(what []rune, trigger string, index int) (change bool, frame
|
||||
}
|
||||
func (nfs *NFS) Term(msg *ctx.Message, action string, args ...interface{}) *NFS {
|
||||
m := nfs.Context.Message()
|
||||
m.Log("debug", "%s %v", action, args)
|
||||
// m.Log("debug", "%s %v", action, args)
|
||||
|
||||
switch action {
|
||||
case "init":
|
||||
@ -563,7 +564,6 @@ func (nfs *NFS) Term(msg *ctx.Message, action string, args ...interface{}) *NFS
|
||||
if len(args) > 0 {
|
||||
n = kit.Int(args[0])
|
||||
}
|
||||
m.Log("debug", "<<<< scroll page (%v, %v)", begin_row, begin_col)
|
||||
|
||||
// 向下滚动
|
||||
for i := begin_row; n > 0 && i < m.Capi("noutput"); i++ {
|
||||
@ -608,7 +608,6 @@ func (nfs *NFS) Term(msg *ctx.Message, action string, args ...interface{}) *NFS
|
||||
}
|
||||
}
|
||||
|
||||
m.Log("debug", ">>>> scroll page (%v, %v)", begin_row, begin_col)
|
||||
m.Conf("term", "begin_row", begin_row)
|
||||
m.Conf("term", "begin_col", begin_col)
|
||||
|
||||
@ -697,7 +696,7 @@ func (nfs *NFS) shadow(args ...interface{}) *NFS {
|
||||
case []rune:
|
||||
if len(args) == 1 {
|
||||
nfs.Term(m, "color", m.Confi("term", "rest_bg"), m.Confi("term", "rest_fg"), string(arg))
|
||||
} else {
|
||||
} else if m.Options("show_shadow") {
|
||||
cmd := strings.Split(string(arg), " ")
|
||||
switch table := args[1].(type) {
|
||||
case []map[string]string:
|
||||
@ -716,6 +715,9 @@ func (nfs *NFS) shadow(args ...interface{}) *NFS {
|
||||
nfs.Term(m, "color", 0, fg, "\n", kit.Format(line["format"]))
|
||||
}
|
||||
i++
|
||||
if i > 10 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
frame["lines"] = i
|
||||
@ -739,6 +741,7 @@ func (nfs *NFS) printf(arg ...interface{}) *NFS {
|
||||
m.Conf("term", "cursor_y", m.Confi("term", "cursor_y")+1)
|
||||
} else {
|
||||
nfs.out.WriteString(line)
|
||||
nfs.out.WriteString("\n")
|
||||
}
|
||||
return nfs
|
||||
}
|
||||
@ -832,8 +835,8 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
|
||||
|
||||
if nfs.in = m.Optionv("in").(*os.File); m.Has("out") {
|
||||
if nfs.out = m.Optionv("out").(*os.File); m.Cap("goos") != "windows" {
|
||||
nfs.Term(m, "init")
|
||||
defer nfs.Term(m, "exit")
|
||||
// nfs.Term(m, "init")
|
||||
// defer nfs.Term(m, "exit")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
|
||||
"toutiao_site": &ctx.Config{Name: "toutiao_site", Value: "https://www.toutiao.com/search/?keyword=%s", Help: "聊天记录"},
|
||||
},
|
||||
Commands: map[string]*ctx.Command{
|
||||
"/chat": &ctx.Command{Name: "user", Help: "应用示例", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
"/chat": &ctx.Command{Name: "user", Help: "应用示例", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
r := m.Optionv("request").(*http.Request)
|
||||
w := m.Optionv("response").(http.ResponseWriter)
|
||||
|
||||
@ -42,13 +42,15 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
|
||||
return
|
||||
}
|
||||
m.Confv("chat_msg", "-1", data)
|
||||
return
|
||||
}},
|
||||
"talk": &ctx.Command{Name: "talk", Help: "talk", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
"talk": &ctx.Command{Name: "talk", Help: "talk", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if m.Confs("default") {
|
||||
m.Echo(m.Conf("default"))
|
||||
}
|
||||
return
|
||||
}},
|
||||
"weather": &ctx.Command{Name: "weather where field", Help: "weather", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
"weather": &ctx.Command{Name: "weather where field", Help: "weather", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
where := "beijing"
|
||||
if len(arg) > 0 {
|
||||
where, arg = arg[0], arg[1:]
|
||||
@ -82,13 +84,15 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
|
||||
default:
|
||||
m.Cmd("select", "date", arg[0], "vertical")
|
||||
}
|
||||
return
|
||||
}},
|
||||
"calendar": &ctx.Command{Name: "calendar", Help: "calendar", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
"calendar": &ctx.Command{Name: "calendar", Help: "calendar", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
msg := m.Spawn().Cmd("get", m.Conf("calendar_site"),
|
||||
"parse", "div.almanac-hd")
|
||||
m.Copy(msg, "append").Copy(msg, "result")
|
||||
return
|
||||
}},
|
||||
"topic": &ctx.Command{Name: "topic", Help: "topic", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
"topic": &ctx.Command{Name: "topic", Help: "topic", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
limit := "10"
|
||||
if len(arg) > 0 {
|
||||
limit, arg = arg[0], arg[1:]
|
||||
@ -104,8 +108,9 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
|
||||
|
||||
m.Copy(msg, "append").Copy(msg, "result")
|
||||
m.Cmd("select", "limit", limit)
|
||||
return
|
||||
}},
|
||||
"pedia": &ctx.Command{Name: "pedia", Help: "pedia", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
"pedia": &ctx.Command{Name: "pedia", Help: "pedia", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
msg := m.Spawn().Cmd("get", fmt.Sprintf("%s/%s", m.Conf("pedia_site"), arg[0]),
|
||||
"parse", "div.mw-parser-output>p,div.mw-parser-output>ul",
|
||||
"sub_parse", "content", "", "text",
|
||||
@ -124,8 +129,9 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
|
||||
|
||||
m.Copy(msg, "append").Copy(msg, "result")
|
||||
m.Cmd("select", "limit", limit, "offset", offset)
|
||||
return
|
||||
}},
|
||||
"baike": &ctx.Command{Name: "baike", Help: "baike", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
"baike": &ctx.Command{Name: "baike", Help: "baike", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
msg := m.Spawn().Cmd("get", fmt.Sprintf("%s/%s", m.Conf("baike_site"), arg[0]),
|
||||
"parse", "div.mw-body",
|
||||
"sub_parse", "content", "p", "text",
|
||||
@ -144,8 +150,9 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
|
||||
|
||||
m.Copy(msg, "append").Copy(msg, "result")
|
||||
m.Cmd("select", "limit", limit, "offset", offset)
|
||||
return
|
||||
}},
|
||||
"sinas": &ctx.Command{Name: "sinas", Help: "sinas", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
"sinas": &ctx.Command{Name: "sinas", Help: "sinas", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
msg := m.Spawn().Cmd("get", fmt.Sprintf(m.Conf("sinas_site"), arg[0]),
|
||||
"parse", "div.box-result.clearfix",
|
||||
"sub_parse", "title", "h2", "text",
|
||||
@ -164,8 +171,9 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
|
||||
|
||||
m.Copy(msg, "append").Copy(msg, "result")
|
||||
m.Cmd("select", "limit", limit, "offset", offset)
|
||||
return
|
||||
}},
|
||||
"zhihu": &ctx.Command{Name: "zhihu", Help: "zhihu", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
"zhihu": &ctx.Command{Name: "zhihu", Help: "zhihu", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
msg := m.Spawn().Cmd("get", fmt.Sprintf(m.Conf("zhihu_site"), arg[0]),
|
||||
"parse", "div.SearchMain div.Card.SearchResult-Card",
|
||||
"sub_parse", "title", "", "text",
|
||||
@ -184,8 +192,10 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
|
||||
|
||||
m.Copy(msg, "append").Copy(msg, "result")
|
||||
m.Cmd("select", "limit", limit, "offset", offset)
|
||||
return
|
||||
}},
|
||||
"toutiao": &ctx.Command{Name: "toutiao", Help: "toutiao", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
|
||||
"toutiao": &ctx.Command{Name: "toutiao", Help: "toutiao", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
msg := m.Spawn().Cmd("get", fmt.Sprintf(m.Conf("toutiao_site"), arg[0]),
|
||||
"parse", "div.articleCard",
|
||||
"sub_parse", "title", "", "text",
|
||||
@ -204,6 +214,7 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
|
||||
|
||||
m.Copy(msg, "append").Copy(msg, "result")
|
||||
m.Cmd("select", "limit", limit, "offset", offset)
|
||||
return
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ func Format(arg ...interface{}) string {
|
||||
|
||||
if len(result) > 1 {
|
||||
args := []interface{}{}
|
||||
if n := strings.Count(result[0], "%") - strings.Count(result[0], "%%"); len(result) > n+1 {
|
||||
if n := strings.Count(result[0], "%") - strings.Count(result[0], "%%"); len(result) > n {
|
||||
for i := 1; i < n+1; i++ {
|
||||
args = append(args, result[i])
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user