diff --git a/src/contexts/cli/cli_linux.go b/src/contexts/cli/cli_linux.go index 0c3edfa8..824c1565 100644 --- a/src/contexts/cli/cli_linux.go +++ b/src/contexts/cli/cli_linux.go @@ -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 } diff --git a/src/contexts/ctx/ctx_type.go b/src/contexts/ctx/ctx_type.go index 822d4af4..a3d8061a 100644 --- a/src/contexts/ctx/ctx_type.go +++ b/src/contexts/ctx/ctx_type.go @@ -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: diff --git a/src/contexts/log/log.go b/src/contexts/log/log.go index 11b5598f..12c21336 100644 --- a/src/contexts/log/log.go +++ b/src/contexts/log/log.go @@ -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: "日志输出配置"}, diff --git a/src/contexts/mdb/mdb.go b/src/contexts/mdb/mdb.go index ae0db6aa..589486f1 100644 --- a/src/contexts/mdb/mdb.go +++ b/src/contexts/mdb/mdb.go @@ -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 + }}, }, } diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index 9a13e18d..82a013e0 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -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") } } diff --git a/src/examples/chat/chat.go b/src/examples/chat/chat.go index 4f4557e0..2ffe9444 100644 --- a/src/examples/chat/chat.go +++ b/src/examples/chat/chat.go @@ -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 }}, }, } diff --git a/src/toolkit/kit.go b/src/toolkit/kit.go index a63aa00e..e57fde22 100644 --- a/src/toolkit/kit.go +++ b/src/toolkit/kit.go @@ -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]) }