1
0
forked from x/ContextOS

mac add ctx.select

This commit is contained in:
shaoying 2018-10-18 10:06:00 +08:00
parent 6d64c777c3
commit 5f328b5bc7
3 changed files with 211 additions and 105 deletions

View File

@ -133,7 +133,7 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{
yac.Cmd("train", "stm", "goto", "goto", "exp", "opt{", "exp", "}", "exp")
yac.Cmd("train", "stm", "return", "return", "rep{", "exp", "}")
yac.Cmd("train", "word", "word", "mul{", "~", "!", "=", "exe", "str", "[a-zA-Z0-9_/\\-.:]+", "}")
yac.Cmd("train", "word", "word", "mul{", "~", "!", "=", "\\|", "exe", "str", "[a-zA-Z0-9_/\\-.:]+", "}")
yac.Cmd("train", "cmd", "cmd", "rep{", "word", "}")
yac.Cmd("train", "exe", "exe", "$", "(", "cmd", ")")

View File

@ -1,6 +1,7 @@
package ctx
import (
"encoding/csv"
"encoding/json"
"errors"
"fmt"
@ -1349,6 +1350,12 @@ func (m *Message) Cmd(args ...interface{}) *Message {
if x, ok := s.Commands[key]; ok && x.Hand != nil {
m.TryCatch(m, true, func(m *Message) {
m.Log("cmd", "%s:%s %v %v", s.Name, c.Name, m.Meta["detail"], m.Meta["option"])
rest := []string{}
for i := 0; i < len(arg); i++ {
if arg[i] == "|" {
arg, rest = arg[:i], arg[i+1:]
}
}
if args := []string{}; x.Form != nil {
for i := 0; i < len(arg); i++ {
@ -1369,7 +1376,11 @@ func (m *Message) Cmd(args ...interface{}) *Message {
}
x.Hand(m, s, key, arg...)
m.Hand = true
if m.Hand = true; len(rest) > 0 {
msg := m.Spawn().Copy(m, "option").Copy(m, "append").Cmd(rest)
m.Set("result").Set("append").Copy(msg, "result").Copy(msg, "append")
}
})
return m
}
@ -2759,8 +2770,18 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
}},
"command": &Command{
Name: "command [all|add cmd arg...|list [begin [end]]|test [begin [end]]|delete cmd]",
Help: "查看或修改命令",
Form: map[string]int{"list_name": 1, "list_help": 1, "list_cache": 2, "list_index": 1, "condition": -1},
Help: []string{
"查看或修改命令",
"list_export filename",
},
Form: map[string]int{
"list_name": 1,
"list_help": 1,
"list_cache": 2,
"list_index": 1,
"condition": -1,
"list_export": 1,
},
Hand: func(m *Message, c *Context, key string, arg ...string) {
if len(arg) == 0 {
keys := []string{}
@ -2822,8 +2843,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
m.target.Commands[m.Cap("list_count")] = &Command{
Name: strings.Join(arg[1:], " "),
Help: m.Confx("list_help"),
Hand: func(m *Message, c *Context, key string, args ...string) {
m.Log("fcuK", "wat %v %v", args, list_index)
Hand: func(cmd *Message, c *Context, key string, args ...string) {
li := list_index
if li == -1 {
if len(args) > 0 {
@ -2835,7 +2855,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
list := []string{}
j := 0
for i := 1; i < len(arg); i++ {
if arg[i] == "_" && m.Assert(j < len(args)) {
if arg[i] == "_" && cmd.Assert(j < len(args)) {
list = append(list, args[j])
j++
continue
@ -2844,17 +2864,22 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
}
list = append(list, args[j:]...)
msg := m.Spawn().Cmd(list)
msg := cmd.Spawn().Cmd(list)
if len(msg.Meta["append"]) > 0 {
for i, _ := range msg.Meta[msg.Meta["append"][0]] {
m.Add("append", "index", i)
cmd.Add("append", "index", i)
}
}
if cache_name != "" && li > -1 {
// m.Echo(m.Cap(cache_name, msg.Meta[cache_index][li]))
m.Echo(m.Cap(cache_name, fmt.Sprint(msg.Confv(m.Confx("body_response"), cache_index))))
// cmd.Echo(cmd.Cap(cache_name, msg.Meta[cache_index][li]))
cmd.Echo(cmd.Cap(cache_name, fmt.Sprint(msg.Confv(cmd.Confx("body_response"), cache_index))))
} else {
m.Copy(msg, "result").Copy(msg, "append")
cmd.Copy(msg, "result").Copy(msg, "append")
if m.Has("list_export") {
export := cmd.Spawn()
export.Copy(cmd, "option").Copy(cmd, "append")
export.Cmd("export", m.Option("list_export"))
}
}
},
}
@ -3431,6 +3456,116 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
m.Echo(arg[0], values...)
m.Append("format", m.Result(0))
}},
"select": &Command{Name: "select key value", Form: map[string]int{"order": 2, "limit": 1, "offset": 1}, Help: "选取数据", Hand: func(m *Message, c *Context, key string, arg ...string) {
msg := m.Spawn()
offset := 0
limit := 10
if m.Has("limit") {
limit = m.Optioni("limit")
}
if m.Has("offset") {
offset = m.Optioni("offset")
}
n := 0
nrow := len(m.Meta[m.Meta["append"][0]])
for i := 0; i < nrow; i++ {
if len(arg) == 0 || strings.Contains(m.Meta[arg[0]][i], arg[1]) {
if n++; offset < n && n <= offset+limit {
for _, k := range m.Meta["append"] {
msg.Add("append", k, m.Meta[k][i])
}
}
}
}
if m.Set("append").Copy(msg, "append"); m.Has("order") {
m.Sort(m.Option("order"), m.Meta["order"][1])
}
m.Table()
}},
"import": &Command{Name: "import filename", Help: "导入数据", Hand: func(m *Message, c *Context, key string, arg ...string) {
f, e := os.Open(arg[0])
m.Assert(e)
defer f.Close()
switch {
case strings.HasSuffix(arg[0], ".json"):
var data interface{}
de := json.NewDecoder(f)
de.Decode(&data)
m.Optionv("data", data)
switch d := data.(type) {
case []interface{}:
for _, value := range d {
switch val := value.(type) {
case map[string]interface{}:
for k, v := range val {
m.Add("append", k, v)
}
}
}
}
case strings.HasSuffix(arg[0], ".csv"):
r := csv.NewReader(f)
l, e := r.Read()
m.Assert(e)
m.Meta["append"] = l
for {
l, e := r.Read()
if e != nil {
break
}
for i, v := range l {
m.Add("append", m.Meta["append"][i], v)
}
}
}
m.Table()
}},
"export": &Command{Name: "export filename", Help: "导出数据", Hand: func(m *Message, c *Context, key string, arg ...string) {
f, e := os.Create(arg[0])
m.Assert(e)
defer f.Close()
switch {
case strings.HasSuffix(arg[0], ".json"):
data := []interface{}{}
nrow := len(m.Meta[m.Meta["append"][0]])
for i := 0; i < nrow; i++ {
line := map[string]interface{}{}
for _, k := range m.Meta["append"] {
line[k] = m.Meta[k][i]
}
data = append(data, line)
}
en := json.NewEncoder(f)
en.SetIndent("", " ")
en.Encode(data)
case strings.HasSuffix(arg[0], ".csv"):
w := csv.NewWriter(f)
line := []string{}
for _, v := range m.Meta["append"] {
line = append(line, v)
}
w.Write(line)
nrow := len(m.Meta[m.Meta["append"][0]])
for i := 0; i < nrow; i++ {
line := []string{}
for _, k := range m.Meta["append"] {
line = append(line, m.Meta[k][i])
}
w.Write(line)
}
w.Flush()
}
}},
},
}

View File

@ -3,19 +3,14 @@ package mdb
import (
"contexts/ctx"
"database/sql"
"encoding/json"
"fmt"
_ "github.com/go-sql-driver/mysql"
"os"
"strconv"
"strings"
)
type MDB struct {
*sql.DB
db []string
table []string
*ctx.Context
}
@ -29,13 +24,15 @@ func (mdb *MDB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
"driver": &ctx.Cache{Name: "数据库驱动(mysql)", Value: m.Confx("driver", arg, 5), Help: "数据库驱动"},
}
c.Configs = map[string]*ctx.Config{
"table": &ctx.Config{Name: "关系表", Value: "", Help: "关系表"},
"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: "", Help: "分页"},
"offset": &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: "解析"},
}
@ -43,11 +40,9 @@ func (mdb *MDB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
s.Context = c
return s
}
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")))
@ -56,7 +51,6 @@ func (mdb *MDB) Start(m *ctx.Message, arg ...string) bool {
m.Log("info", "mdb open %s", m.Cap("database"))
return false
}
func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool {
switch mdb.Context {
case m.Target():
@ -65,7 +59,6 @@ func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool {
return false
}
var Pulse *ctx.Message
var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
Caches: map[string]*ctx.Cache{
"nsource": &ctx.Cache{Name: "数据源数量", Value: "0", Help: "已打开数据库的数量"},
@ -82,11 +75,19 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
"csv_row_sep": &ctx.Config{Name: "记录分隔符", Value: "\n", Help: "记录分隔符"},
},
Commands: map[string]*ctx.Command{
"open": &ctx.Command{
Name: "open [database [username [password [address [protocol [driver]]]]]]",
"open": &ctx.Command{Name: "open [database [username [password [address [protocol [driver]]]]]]",
Help: "open打开数据库, database: 数据库名, username: 用户名, password: 密码, address: 服务地址, protocol: 服务协议, driver: 数据库类型",
Form: map[string]int{"dbname": 1, "dbhelp": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
m.Start(fmt.Sprintf("db%d", m.Capi("nsource", 1)), "数据源", arg...)
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...)
}},
"exec": &ctx.Command{Name: "exec sql [arg]", Help: "操作数据库, sql: SQL语句, arg: 操作参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) && mdb.DB != nil {
@ -131,6 +132,8 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
for i, k := range cols {
switch b := vals[i].(type) {
case nil:
m.Add("append", k, "")
case []byte:
m.Add("append", k, string(b))
case int64:
@ -152,67 +155,49 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) && mdb.DB != nil {
if len(arg) == 0 {
msg := m.Spawn().Cmd("query", "show databases")
mdb.db = []string{}
dbs := []string{}
for i, v := range msg.Meta[msg.Meta["append"][0]] {
mdb.db = append(mdb.db, v)
dbs = append(dbs, v)
m.Echo("%d: %s\n", i, v)
}
m.Target().Configs["dbs"].Value = dbs
return
}
db := arg[0]
if i, e := strconv.Atoi(arg[0]); e == nil && i < len(mdb.db) {
db = mdb.db[i]
}
db := m.Confv("dbs", arg[0]).(string)
m.Assert(m.Spawn().Cmd("exec", fmt.Sprintf("use %s", db)))
m.Echo(m.Cap("database", db))
}
}},
"table": &ctx.Command{Name: "table [which [field]]", Help: "查看关系表信息which: 表名, field: 字段名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) {
"tab": &ctx.Command{Name: "tab[which [field]]", Help: "查看关系表信息which: 表名, field: 字段名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if _, ok := m.Target().Server.(*MDB); m.Assert(ok) {
if len(arg) == 0 {
msg := m.Spawn().Cmd("query", "show tables")
mdb.table = []string{}
tables := []string{}
for i, v := range msg.Meta[msg.Meta["append"][0]] {
mdb.table = append(mdb.table, v)
tables = append(tables, v)
m.Echo("%d: %s\n", i, v)
}
m.Target().Configs["tables"].Value = tables
return
}
table := arg[0]
if i, e := strconv.Atoi(arg[0]); e == nil && i < len(mdb.table) {
table = mdb.table[i]
}
table := m.Confv("tables", arg[0]).(string)
msg := m.Spawn().Cmd("query", fmt.Sprintf("desc %s", table))
if len(arg) == 1 {
for _, v := range msg.Meta[msg.Meta["append"][0]] {
m.Echo("%s\n", v)
}
return
}
for i, v := range msg.Meta[msg.Meta["append"][0]] {
if v == arg[1] {
for _, k := range msg.Meta["append"] {
m.Echo("%s: %s\n", k, msg.Meta[k][i])
}
}
}
m.Copy(msg, "append")
m.Table()
}
}},
"show": &ctx.Command{Name: "show table fields...",
Help: "查询数据库, table: 表名, fields: 字段, where: 查询条件, group: 聚合字段, order: 排序字段",
Form: map[string]int{"where": 1, "group": 1, "order": 1, "limit": 1, "offset": 1, "other": -1,
"extras": 1, "extra_field": 1, "extra_format": 1, "trans_field": 1, "trans_map": 2,
"save": 1, "export": 2,
},
"extra_field": 1, "extra_chains": 1, "extra_format": 1, "trans_field": 1, "trans_map": 2},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) {
if _, ok := m.Target().Server.(*MDB); m.Assert(ok) {
table := m.Confx("table", arg, 0)
if i, e := strconv.Atoi(table); e == nil && i < len(mdb.table) {
table = mdb.table[i]
if v := m.Confv("tables", table); v != nil {
table = v.(string)
}
fields := []string{"*"}
@ -243,26 +228,39 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
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")
if m.Optioni("query", msg.Code()); !m.Options("save") {
m.Color(31, table).Echo(" %s %s %s %s %s %v\n", where, group, order, limit, offset, m.Meta["other"])
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)
switch v := m.Confv("template_value", m.Option("extra_chains")).(type) {
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
}
}
}
m.Color(31, 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 {
if m.Options("save") {
key := m.Meta["append"][i]
value := maps[key]
if key == m.Option("trans_field") {
for i := 0; i < len(m.Meta["trans_map"])-1; i += 2 {
if value == m.Meta["trans_map"][i] {
value = m.Meta["trans_map"][i+1]
break
}
}
}
m.Echo(value)
} else if line == -1 {
if line == -1 {
m.Color(32, v)
} else {
m.Echo(v)
@ -274,33 +272,6 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
m.Echo(m.Conf("csv_row_sep"))
return true
})
if m.Options("export") {
f, e := os.Create(m.Option("export"))
m.Assert(e)
defer f.Close()
m.Table(func(maps map[string]string, lists []string, line int) bool {
if line > -1 {
args := []interface{}{}
for i := 0; i < len(lists); i++ {
args = append(args, maps[m.Meta["append"][i]])
}
f.WriteString(fmt.Sprintf(m.Meta["export"][1], args...))
}
return true
})
}
if m.Options("save") {
f, e := os.Create(m.Option("save"))
m.Assert(e)
defer f.Close()
for _, v := range m.Meta["result"] {
f.WriteString(v)
}
}
}
}},
},