1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-25 16:58:06 +08:00
Change-Id: I359a53b2521bc0e92d079bc37a57e62c990458b9
This commit is contained in:
shaoying 2019-01-16 20:34:58 +08:00
parent 5a0ac5646e
commit 108155dd31
7 changed files with 254 additions and 284 deletions

View File

@ -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
}

View File

@ -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:

View File

@ -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: "日志输出配置"},

View File

@ -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
}},
},
}

View File

@ -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")
}
}

View File

@ -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
}},
},
}

View File

@ -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])
}