1
0
forked from x/ContextOS

tce add Message.confx

This commit is contained in:
shaoying 2018-06-25 22:40:43 +08:00
parent a599d1f39b
commit f2294a5b67
6 changed files with 510 additions and 427 deletions

View File

@ -210,7 +210,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
// }}}
}},
"md5": &ctx.Command{Name: "md5 [file filename][content]", Help: "散列",
Formats: map[string]int{"file": 1},
Form: map[string]int{"file": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if m.Options("file") { // {{{
f, e := os.Open(m.Option("file"))
@ -235,7 +235,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
解密: rsa decrypt keyfile key.pem mmfile mm.txt
签名: rsa sign keyfile key.pem signfile sign.txt hello
验签: rsa verify keyfile pubkey.pem signfile sign.txt hello`,
Formats: map[string]int{"keyfile": 1, "key": 1, "mmfile": 1, "mm": 1, "signfile": 1, "signs": 1, "file": 1},
Form: map[string]int{"keyfile": 1, "key": 1, "mmfile": 1, "mm": 1, "signfile": 1, "signs": 1, "file": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if arg[0] == "gen" { // {{{
keys, e := rsa.GenerateKey(crand.Reader, 1024)
@ -355,7 +355,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
// }}}
}},
"deal": &ctx.Command{Name: "deal init|sell|buy|done [keyfile name][key str]", Help: "散列",
Formats: map[string]int{"file": 1},
Form: map[string]int{"file": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if m.Options("file") { // {{{
f, e := os.Open(m.Option("file"))

View File

@ -322,8 +322,8 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
} // }}}
}},
"time": &ctx.Command{Name: "time [parse when] format when",
Formats: map[string]int{"parse": 1},
Help: "睡眠, time(ns/us/ms/s/m/h): 时间值(纳秒/微秒/毫秒/秒/分钟/小时)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
Form: map[string]int{"parse": 1},
Help: "睡眠, time(ns/us/ms/s/m/h): 时间值(纳秒/微秒/毫秒/秒/分钟/小时)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
t := time.Now() // {{{
if m.Options("parse") {
f := "2006-01-02 15:04:05"

View File

@ -3,6 +3,7 @@ package ctx // {{{
import ( // {{{
"crypto/md5"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"html/template"
@ -45,11 +46,12 @@ type Command struct {
Name string
Help string
Formats map[string]int
Options map[string]string
Shares map[string][]string
Options map[string]string
Appends map[string]string
Hand func(m *Message, c *Context, key string, arg ...string)
Form map[string]int
Hand func(m *Message, c *Context, key string, arg ...string)
}
type Server interface {
@ -87,6 +89,144 @@ type Context struct {
Server
}
func (c *Context) Spawn(m *Message, name string, help string) *Context { // {{{
s := &Context{Name: name, Help: help, root: c.root, context: c}
if m.target = s; c.Server != nil {
c.Register(s, c.Server.Spawn(m, s, m.Meta["detail"]...))
} else {
c.Register(s, nil)
}
if m.Template != nil {
m.Template.source = s
}
return s
}
// }}}
func (c *Context) Begin(m *Message) *Context { // {{{
c.Caches["status"] = &Cache{Name: "服务状态(begin/start/close)", Value: "begin", Help: "服务状态begin:初始完成start:正在运行close:未在运行"}
c.Caches["stream"] = &Cache{Name: "服务数据", Value: "", Help: "服务数据"}
item := []string{}
m.BackTrace(func(m *Message) bool {
item = append(item, m.target.Name)
return true
})
for i := 0; i < len(item)/2; i++ {
item[i], item[len(item)-i-1] = item[len(item)-i-1], item[i]
}
c.Caches["module"] = &Cache{Name: "服务数据", Value: strings.Join(item, "."), Help: "服务数据"}
m.Index = 1
c.Pulse = m
c.Requests = []*Message{m}
c.Historys = []*Message{m}
c.Sessions = map[string]*Message{}
c.master = m.master.master
c.Owner = m.master.Owner
m.Log("begin", nil, "%d context %v %v", m.root.Capi("ncontext", 1), m.Meta["detail"], m.Meta["option"])
for k, x := range c.Configs {
if x.Hand != nil {
m.Conf(k, x.Value)
}
}
if c.Server != nil {
c.Server.Begin(m, m.Meta["detail"]...)
}
return c
}
// }}}
func (c *Context) Start(m *Message) bool { // {{{
m.Hand = true
if m != c.Requests[0] {
c.Requests, m.Index = append(c.Requests, m), len(c.Requests)+1
}
if m.Cap("status") != "start" {
running := make(chan bool)
go m.TryCatch(m, true, func(m *Message) {
m.Log(m.Cap("status", "start"), nil, "%d server %v %v", m.root.Capi("nserver", 1), m.Meta["detail"], m.Meta["option"])
if running <- true; c.Server != nil && c.Server.Start(m, m.Meta["detail"]...) {
c.Close(m, m.Meta["detail"]...)
}
})
<-running
}
return true
}
// }}}
func (c *Context) Close(m *Message, arg ...string) bool { // {{{
m.Log("close", c, "%d:%d %v", len(m.source.Sessions), len(m.target.Historys), arg)
if m.target == c {
if m.Index == 0 {
for i := len(c.Requests) - 1; i >= 0; i-- {
v := c.Requests[i]
if v.Index = -1; v.source != c && !v.source.Close(v, arg...) {
v.Index = i
return false
}
c.Requests = c.Requests[:i]
}
} else if m.Index > 0 {
for i := m.Index - 1; i < len(c.Requests)-1; i++ {
c.Requests[i] = c.Requests[i+1]
}
c.Requests = c.Requests[:len(c.Requests)-1]
}
}
if c.Server != nil && !c.Server.Close(m, arg...) {
return false
}
if m.source == c && m.target != c {
if _, ok := c.Sessions[m.Name]; ok {
delete(c.Sessions, m.Name)
}
return true
}
if len(c.Requests) > 1 {
return false
}
if m.Cap("status") == "start" {
m.Log(m.Cap("status", "close"), nil, "%d server %v", m.root.Capi("nserver", -1)+1, arg)
for _, v := range c.Sessions {
if v.target != c {
v.target.Close(v, arg...)
}
}
}
// if m.Index == 0 && c.context != nil && len(c.contexts) == 0 {
if c.context != nil {
m.Log("close", nil, "%d context %v", m.root.Capi("ncontext", -1)+1, arg)
delete(c.context.contexts, c.Name)
c.context = nil
if c.Exit != nil {
m.Log("info", nil, "before exit<-")
c.Exit <- true
m.Log("info", nil, "after exit<-")
}
}
return true
}
// }}}
func (c *Context) Password(meta string) string { // {{{
bs := md5.Sum([]byte(fmt.Sprintln("%d%d%s", time.Now().Unix(), rand.Int(), meta)))
sessid := hex.EncodeToString(bs[:])
@ -179,143 +319,6 @@ func (c *Context) Check(m *Message, arg ...string) bool { // {{{
return false
}
// }}}
func (c *Context) Spawn(m *Message, name string, help string) *Context { // {{{
s := &Context{Name: name, Help: help, root: c.root, context: c}
if m.target = s; c.Server != nil {
c.Register(s, c.Server.Spawn(m, s, m.Meta["detail"]...))
} else {
c.Register(s, nil)
}
if m.Template != nil {
m.Template.source = s
}
return s
}
// }}}
func (c *Context) Begin(m *Message) *Context { // {{{
c.Caches["status"] = &Cache{Name: "服务状态(begin/start/close)", Value: "begin", Help: "服务状态begin:初始完成start:正在运行close:未在运行"}
c.Caches["stream"] = &Cache{Name: "服务数据", Value: "", Help: "服务数据"}
item := []string{}
m.BackTrace(func(m *Message) bool {
item = append(item, m.target.Name)
return true
})
for i := 0; i < len(item)/2; i++ {
item[i], item[len(item)-i-1] = item[len(item)-i-1], item[i]
}
c.Caches["module"] = &Cache{Name: "服务数据", Value: strings.Join(item, "."), Help: "服务数据"}
m.Index = 1
c.Pulse = m
c.Requests = []*Message{m}
c.Historys = []*Message{m}
c.Sessions = map[string]*Message{}
c.master = m.master.master
c.Owner = m.master.Owner
m.Log("begin", nil, "%d context %v %v", m.root.Capi("ncontext", 1), m.Meta["detail"], m.Meta["option"])
for k, x := range c.Configs {
if x.Hand != nil {
m.Conf(k, x.Value)
}
}
if c.Server != nil {
c.Server.Begin(m, m.Meta["detail"]...)
}
return c
}
// }}}
func (c *Context) Start(m *Message) bool { // {{{
m.Hand = true
if m != c.Requests[0] {
c.Requests, m.Index = append(c.Requests, m), len(c.Requests)+1
}
if m.Cap("status") != "start" {
running := make(chan bool)
go m.AssertOne(m, true, func(m *Message) {
m.Log(m.Cap("status", "start"), nil, "%d server %v %v", m.root.Capi("nserver", 1), m.Meta["detail"], m.Meta["option"])
if running <- true; c.Server != nil && c.Server.Start(m, m.Meta["detail"]...) {
c.Close(m, m.Meta["detail"]...)
}
})
<-running
}
return true
}
// }}}
func (c *Context) Close(m *Message, arg ...string) bool { // {{{
m.Log("close", c, "%d:%d %v", len(m.source.Sessions), len(m.target.Historys), arg)
if m.target == c {
if m.Index == 0 {
for i := len(c.Requests) - 1; i >= 0; i-- {
v := c.Requests[i]
if v.Index = -1; v.source != c && !v.source.Close(v, arg...) {
v.Index = i
return false
}
c.Requests = c.Requests[:i]
}
} else if m.Index > 0 {
for i := m.Index - 1; i < len(c.Requests)-1; i++ {
c.Requests[i] = c.Requests[i+1]
}
c.Requests = c.Requests[:len(c.Requests)-1]
}
}
if c.Server != nil && !c.Server.Close(m, arg...) {
return false
}
if m.source == c && m.target != c {
if _, ok := c.Sessions[m.Name]; ok {
delete(c.Sessions, m.Name)
}
return true
}
if len(c.Requests) > 1 {
return false
}
if m.Cap("status") == "start" {
m.Log(m.Cap("status", "close"), nil, "%d server %v", m.root.Capi("nserver", -1)+1, arg)
for _, v := range c.Sessions {
if v.target != c {
v.target.Close(v, arg...)
}
}
}
// if m.Index == 0 && c.context != nil && len(c.contexts) == 0 {
if c.context != nil {
m.Log("close", nil, "%d context %v", m.root.Capi("ncontext", -1)+1, arg)
delete(c.context.contexts, c.Name)
c.context = nil
if c.Exit != nil {
m.Log("info", nil, "before exit<-")
c.Exit <- true
m.Log("info", nil, "after exit<-")
}
}
return true
}
// }}}
func (c *Context) Context() *Context { // {{{
@ -674,7 +677,7 @@ func (m *Message) Assert(e interface{}, msg ...string) bool { // {{{
}
// }}}
func (m *Message) AssertOne(msg *Message, safe bool, hand ...func(msg *Message)) *Message { // {{{
func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) *Message { // {{{
defer func() {
if e := recover(); e != nil {
@ -691,7 +694,7 @@ func (m *Message) AssertOne(msg *Message, safe bool, hand ...func(msg *Message))
}
if len(hand) > 1 {
m.AssertOne(msg, safe, hand[1:]...)
m.TryCatch(msg, safe, hand[1:]...)
} else if !safe {
msg.Assert(e)
}
@ -1138,28 +1141,75 @@ func (m *Message) Copy(msg *Message, meta string, arg ...string) *Message { // {
}
// }}}
func (m *Message) Table(cb func(map[string]string) bool) *Message { // {{{
if len(m.Meta["append"]) > 0 {
for i := 0; i < len(m.Meta[m.Meta["append"][0]]); i++ {
row := map[string]string{}
for _, k := range m.Meta["append"] {
if i < len(m.Meta[k]) {
row[k] = m.Meta[k][i]
}
}
if !cb(row) {
break
func (m *Message) Table(cb func(map[string]string, []string, int) bool) *Message { // {{{
if len(m.Meta["append"]) == 0 {
return m
}
width := make(map[string]int, len(m.Meta[m.Meta["append"][0]]))
for _, k := range m.Meta["append"] {
title := k
if m.Options("extras") && k == "extra" {
title = "extra." + m.Option("extras")
}
width[k] = len(title)
}
for i := 0; i < len(m.Meta[m.Meta["append"][0]]); i++ {
for _, k := range m.Meta["append"] {
data := m.Meta[k][i]
if len(data) > width[k] {
width[k] = len(data)
}
}
}
row := map[string]string{}
wor := []string{}
for _, k := range m.Meta["append"] {
title := k
if m.Options("extras") && k == "extra" {
title = "extra." + m.Option("extras")
}
row[k] = title
title += strings.Repeat(" ", width[k]-len(title))
wor = append(wor, title)
}
if !cb(row, wor, -1) {
return m
}
for i := 0; i < len(m.Meta[m.Meta["append"][0]]); i++ {
row := map[string]string{}
wor := []string{}
for _, k := range m.Meta["append"] {
data := m.Meta[k][i]
if m.Options("extras") && k == "extra" {
extra := map[string]interface{}{}
json.Unmarshal([]byte(data), &extra)
data = fmt.Sprintf("%v", extra[m.Option("extras")])
}
if i < len(m.Meta[k]) {
row[k] = data
data += strings.Repeat(" ", width[k]-len(data))
wor = append(wor, data)
}
}
if !cb(row, wor, i) {
break
}
}
return m
}
// }}}
func (m *Message) Sort(key string, arg ...string) {
func (m *Message) Sort(key string, arg ...string) { // {{{
table := []map[string]string{}
m.Table(func(line map[string]string) bool {
table = append(table, line)
m.Table(func(line map[string]string, lists []string, index int) bool {
if index != -1 {
table = append(table, line)
}
return true
})
@ -1215,6 +1265,8 @@ func (m *Message) Sort(key string, arg ...string) {
}
}
// }}}
func (m *Message) Insert(meta string, index int, arg ...interface{}) string { // {{{
if m.Meta == nil {
m.Meta = make(map[string][]string)
@ -1351,6 +1403,15 @@ func (m *Message) Optionv(key string, arg ...interface{}) interface{} { // {{{
return nil
}
// }}}
func (m *Message) Optionx(key string, format string) interface{} { // {{{
value := m.Option(key)
if value != "" {
return fmt.Sprintf(format, value)
}
return ""
}
// }}}
func (m *Message) Append(key string, arg ...interface{}) string { // {{{
m.Insert(key, 0, arg...)
@ -1427,7 +1488,7 @@ func (m *Message) Exec(key string, arg ...string) string { // {{{
for s := c; s != nil; s = s.context {
if x, ok := s.Commands[key]; ok && x.Hand != nil && c.Check(m, "commands", key) {
m.AssertOne(m, true, func(m *Message) {
m.TryCatch(m, true, func(m *Message) {
m.Log("cmd", s, "%d %s %v %v", len(m.target.Historys), key, arg, m.Meta["option"])
if x.Options != nil {
@ -1441,9 +1502,9 @@ func (m *Message) Exec(key string, arg ...string) string { // {{{
if m.Has("args") {
m.Meta["args"] = nil
}
if x.Formats != nil {
if x.Form != nil {
for i := 0; i < len(arg); i++ {
n, ok := x.Formats[arg[i]]
n, ok := x.Form[arg[i]]
if !ok {
m.Add("option", "args", arg[i])
continue
@ -1496,7 +1557,7 @@ func (m *Message) Deal(pre func(msg *Message, arg ...string) bool, post func(msg
}
for run := true; run; {
m.AssertOne(<-m.target.messages, true, func(msg *Message) {
m.TryCatch(<-m.target.messages, true, func(msg *Message) {
defer func() {
if msg.Wait != nil {
msg.Wait <- true
@ -1563,6 +1624,49 @@ func (m *Message) Cmd(arg ...interface{}) *Message { // {{{
// }}}
func (m *Message) Confx(key string, arg ...interface{}) string { // {{{
if len(arg) == 0 {
return m.Conf(key)
}
skip := false
if len(arg) > 1 {
if v, ok := arg[1].(bool); ok && !v {
skip = true
}
}
if len(arg) > 0 {
switch v := arg[0].(type) {
case string:
if skip || v == "" {
return m.Conf(key)
}
return v
case []string:
which := 0
if len(arg) > 1 {
if x, ok := arg[1].(int); ok {
which = x
}
}
if which < len(v) {
return v[which]
}
return m.Conf(key)
default:
x := fmt.Sprintf("%v", v)
if skip || v == nil || x == "" {
return m.Conf(key)
}
return x
}
}
return ""
}
// }}}
func (m *Message) Confs(key string, arg ...bool) bool { // {{{
if len(arg) > 0 {
if arg[0] {
@ -1637,6 +1741,49 @@ func (m *Message) Conf(key string, arg ...string) string { // {{{
return ""
}
// }}}
func (m *Message) Capx(key string, arg ...interface{}) string { // {{{
if len(arg) == 0 {
return m.Cap(key)
}
skip := false
if len(arg) > 1 {
if v, ok := arg[1].(bool); ok && !v {
skip = true
}
}
if len(arg) > 0 {
switch v := arg[0].(type) {
case string:
if skip || v == "" {
return m.Cap(key)
}
return v
case []string:
which := 0
if len(arg) > 1 {
if x, ok := arg[1].(int); ok {
which = x
}
}
if which < len(v) {
return v[which]
}
return m.Cap(key)
default:
x := fmt.Sprintf("%v", v)
if skip || v == nil || x == "" {
return m.Cap(key)
}
return x
}
}
return ""
}
// }}}
func (m *Message) Caps(key string, arg ...bool) bool { // {{{
if len(arg) > 0 {
@ -2282,8 +2429,10 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
}
// }}}
}},
"context": &Command{Name: "context back|[[home] [find|search] name] [info|lists|show|switch|[args]", Help: "查找并操作模块,\n查找起点root:根模块、back:父模块、home:本模块,\n查找方法find:路径匹配、search:模糊匹配,\n查找对象name:支持点分和正则,\n操作类型show:显示信息、switch:切换为当前、start:启动模块、spawn:分裂子模块args:启动参数",
Formats: map[string]int{
"context": &Command{
Name: "context back|[[home] [find|search] name] [info|lists|show|switch|[args]",
Help: "查找并操作模块,\n查找起点root:根模块、back:父模块、home:本模块,\n查找方法find:路径匹配、search:模糊匹配,\n查找对象name:支持点分和正则,\n操作类型show:显示信息、switch:切换为当前、start:启动模块、spawn:分裂子模块args:启动参数",
Form: map[string]int{
"back": 0, "home": 0,
"find": 1, "search": 1,
"info": 1, "lists": 0, "show": 0, "switch": 0,
@ -2456,43 +2605,47 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
}
// }}}
}},
"server": &Command{Name: "server [spawn|begin|start|close|][args]", Help: "服务启动停止切换", Hand: func(m *Message, c *Context, key string, arg ...string) {
switch len(arg) { // {{{
case 0:
m.Travel(m.target.root, func(msg *Message) bool {
if msg.Cap("status") == "start" {
msg.Echo("%s(%s): %s\n", msg.target.Name, msg.Cap("stream"), msg.target.Help)
}
return true
})
"server": &Command{
Name: "server [spawn|begin|start|close|][args]",
Help: "服务启动停止切换",
Hand: func(m *Message, c *Context, key string, arg ...string) {
switch len(arg) { // {{{
case 0:
m.Travel(m.target.root, func(msg *Message) bool {
if msg.Cap("status") == "start" {
msg.Echo("%s(%s): %s\n", msg.target.Name, msg.Cap("stream"), msg.target.Help)
}
return true
})
default:
switch arg[0] {
case "spawn":
if len(arg) > 1 {
default:
switch arg[0] {
case "spawn":
if len(arg) > 1 {
msg := m.Spawn(m.Target())
msg.Detail(0, arg[2:])
msg.Target().Spawn(msg, arg[0], arg[1])
}
case "begin":
msg := m.Spawn(m.Target())
msg.Detail(0, arg[2:])
msg.Target().Spawn(msg, arg[0], arg[1])
msg.Detail(0, arg)
msg.Target().Begin(msg)
case "start":
msg := m.Spawn(m.Target())
msg.Detail(0, arg)
msg.Target().Start(msg)
case "close":
msg := m.Spawn(m.Target())
msg.Detail(0, arg)
msg.Target().Close(msg)
}
case "begin":
msg := m.Spawn(m.Target())
msg.Detail(0, arg)
msg.Target().Begin(msg)
case "start":
msg := m.Spawn(m.Target())
msg.Detail(0, arg)
msg.Target().Start(msg)
case "close":
msg := m.Spawn(m.Target())
msg.Detail(0, arg)
msg.Target().Close(msg)
}
}
// }}}
}},
"command": &Command{Name: "command [all] add [key [name help]]", Help: "查看或修改命令",
Formats: map[string]int{"all": 0, "delete": 0, "void": 0, "condition": -1},
// }}}
}},
"command": &Command{
Name: "command [all] add [key [name help]]", Help: "查看或修改命令",
Form: map[string]int{"all": 0, "delete": 0, "void": 0, "condition": -1},
Hand: func(m *Message, c *Context, key string, arg ...string) {
all := m.Has("all") // {{{
if len(arg) == 0 {
@ -2681,8 +2834,10 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
}
// }}}
}},
"config": &Command{Name: "config [all] [[delete|void] key [value]|[name value help]]", Help: "删除、置空、查看、修改或添加配置",
Formats: map[string]int{"all": 0, "delete": 0, "void": 0},
"config": &Command{
Name: "config [all] [[delete|void] key [value]|[name value help]]",
Help: "删除、置空、查看、修改或添加配置",
Form: map[string]int{"all": 0, "delete": 0, "void": 0},
Hand: func(m *Message, c *Context, key string, arg ...string) {
all := m.Has("all") // {{{
@ -2741,8 +2896,10 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
}
// }}}
}},
"cache": &Command{Name: "cache [all] [[delete|void] key [value]|[name value help]]", Help: "删除、置空、查看、修改或添加缓存",
Formats: map[string]int{"all": 0, "delete": 0, "void": 0},
"cache": &Command{
Name: "cache [all] [[delete|void] key [value]|[name value help]]",
Help: "删除、置空、查看、修改或添加缓存",
Form: map[string]int{"all": 0, "delete": 0, "void": 0},
Hand: func(m *Message, c *Context, key string, arg ...string) {
all := m.Has("all") // {{{
@ -2795,9 +2952,9 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
// }}}
}},
"right": &Command{
Name: "right [share|add|del group [cache|config|command item]]",
Help: "用户组管理,查看、添加、删除用户组或是接口",
Formats: map[string]int{"check": 0, "add": 0, "del": 0, "brow": 0, "cache": 0, "config": 0, "command": 0},
Name: "right [share|add|del group [cache|config|command item]]",
Help: "用户组管理,查看、添加、删除用户组或是接口",
Form: map[string]int{"check": 0, "add": 0, "del": 0, "brow": 0, "cache": 0, "config": 0, "command": 0},
Hand: func(m *Message, c *Context, key string, arg ...string) {
index := m.Target().Index // {{{
if index == nil {
@ -3031,13 +3188,6 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
}
} // }}}
}},
"sort": &Command{Name: "sort", Help: "服务启动停止切换", Hand: func(m *Message, c *Context, key string, arg ...string) {
m.Append("name", "shy", "yun")
m.Append("page", "10", "20")
m.Log("fuck", nil, "before %v", m.Meta)
m.Sort(arg[0], arg[1:]...)
m.Log("fuck", nil, "after %v", m.Meta)
}},
},
Index: map[string]*Context{
"void": &Context{Name: "void",

View File

@ -2,14 +2,14 @@ package mdb // {{{
// }}}
import ( // {{{
"contexts"
"encoding/json"
"strconv"
"strings"
"database/sql"
"encoding/json"
_ "github.com/go-sql-driver/mysql"
"fmt"
"os"
"strconv"
"strings"
)
// }}}
@ -17,9 +17,6 @@ import ( // {{{
type MDB struct {
*sql.DB
list map[string][]string
list_key []string
table []string
*ctx.Context
}
@ -73,7 +70,7 @@ func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool { // {{{
switch mdb.Context {
case m.Target():
if mdb.DB != nil {
m.Log("info", nil, "%d close %s %s", Pulse.Capi("nsource", -1)+1, m.Cap("driver"), m.Cap("source"))
m.Log("info", nil, "close")
mdb.DB.Close()
mdb.DB = nil
}
@ -87,264 +84,200 @@ func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool { // {{{
var Pulse *ctx.Message
var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
Caches: map[string]*ctx.Cache{
"count": &ctx.Cache{Name: "count", Value: "0", Help: "主机协议"},
"nsource": &ctx.Cache{Name: "数据源数量", Value: "0", Help: "已打开数据库的数量"},
"dbname": &ctx.Cache{Name: "生成模块名", Value: "", Help: "生成模块名", Hand: func(m *ctx.Message, x *ctx.Cache, arg ...string) string {
return fmt.Sprintf("db%d", Pulse.Capi("nsource", 1))
}},
},
Configs: map[string]*ctx.Config{
"driver": &ctx.Config{Name: "数据库驱动(mysql)", Value: "mysql", Help: "数据库驱动"},
"driver": &ctx.Config{Name: "数据库驱动(mysql)", Value: "mysql", Help: "数据库驱动"},
"csv_sep": &ctx.Config{Name: "字段分隔符", Value: "\t", Help: "字段分隔符"},
},
Commands: map[string]*ctx.Command{
"open": &ctx.Command{Name: "open source [name]", Help: "打开数据库", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
"open": &ctx.Command{Name: "open source [name]", Help: "打开数据库, source: 数据源, name: 模块名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
m.Assert(len(arg) > 0, "缺少参数") // {{{
name := fmt.Sprintf("db%d", Pulse.Capi("nsource", 1))
if len(arg) > 1 {
name = arg[1]
}
m.Start(name, "数据存储", arg...)
Pulse.Cap("stream", Pulse.Cap("nsource"))
m.Start(m.Capx("dbname", arg, 1), "数据存储", arg...)
m.Echo(m.Target().Name)
// }}}
}},
"exec": &ctx.Command{Name: "exec sql [arg]", Help: "操作数据库",
"exec": &ctx.Command{Name: "exec sql [arg]", Help: "操作数据库, sql: SQL语句, arg: 查询参数",
Appends: map[string]string{"last": "最后插入元组的标识", "nrow": "修改元组的数量"},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
mdb, ok := m.Target().Server.(*MDB) // {{{
m.Assert(ok, "目标模块类型错误")
m.Assert(len(arg) > 0, "缺少参数")
m.Assert(mdb.DB != nil, "数据库未打开")
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) { // {{{
which := make([]interface{}, 0, len(arg))
for _, v := range arg[1:] {
which = append(which, v)
}
ret, e := mdb.Exec(arg[0], which...)
m.Assert(e)
id, e := ret.LastInsertId()
m.Assert(e)
n, e := ret.RowsAffected()
m.Assert(e)
m.Log("info", nil, "last(%s) nrow(%s)", m.Append("last", id), m.Append("nrow", n))
m.Echo("%d", id).Echo("%d", n)
}
// }}}
}},
"query": &ctx.Command{Name: "query 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) { // {{{
which := make([]interface{}, 0, len(arg))
for _, v := range arg[1:] {
which = append(which, v)
}
ret, e := mdb.Exec(arg[0], which...)
rows, e := mdb.Query(arg[0], which...)
m.Assert(e)
id, e := ret.LastInsertId()
m.Assert(e)
n, e := ret.RowsAffected()
defer rows.Close()
cols, e := rows.Columns()
m.Assert(e)
num := len(cols)
m.Echo("%d", id).Echo("%d", n)
m.Add("append", "last", fmt.Sprintf("%d", id))
m.Add("append", "nrow", fmt.Sprintf("%d", n))
m.Log("info", nil, "last(%d) nrow(%d)", id, n)
// }}}
}},
"query": &ctx.Command{Name: "query sql [arg]", Help: "执行查询语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
mdb, ok := m.Target().Server.(*MDB) // {{{
m.Assert(ok, "目标模块类型错误")
m.Assert(len(arg) > 0, "缺少参数")
m.Assert(mdb.DB != nil, "数据库未打开")
for rows.Next() {
vals := make([]interface{}, num)
ptrs := make([]interface{}, num)
for i := range vals {
ptrs[i] = &vals[i]
}
rows.Scan(ptrs...)
which := make([]interface{}, 0, len(arg))
for _, v := range arg[1:] {
which = append(which, v)
}
rows, e := mdb.Query(arg[0], which...)
m.Assert(e)
defer rows.Close()
cols, e := rows.Columns()
m.Assert(e)
num := len(cols)
for rows.Next() {
vals := make([]interface{}, num)
ptrs := make([]interface{}, num)
for i := range vals {
ptrs[i] = &vals[i]
}
rows.Scan(ptrs...)
for i, k := range cols {
switch b := vals[i].(type) {
case []byte:
m.Add("append", k, string(b))
case int64:
m.Add("append", k, fmt.Sprintf("%d", b))
default:
m.Add("append", k, "")
for i, k := range cols {
switch b := vals[i].(type) {
case []byte:
m.Add("append", k, string(b))
case int64:
m.Add("append", k, fmt.Sprintf("%d", b))
default:
m.Add("append", k, fmt.Sprintf("%v", b))
}
}
}
}
if len(m.Meta["append"]) > 0 {
m.Log("info", nil, "rows(%d) cols(%d)", len(m.Meta[m.Meta["append"][0]]), len(m.Meta["append"]))
} else {
m.Log("info", nil, "rows(0) cols(0)")
if len(m.Meta["append"]) > 0 {
m.Log("info", nil, "rows(%d) cols(%d)", len(m.Meta[m.Meta["append"][0]]), len(m.Meta["append"]))
} else {
m.Log("info", nil, "rows(0) cols(0)")
}
}
// }}}
}},
"table": &ctx.Command{Name: "table", Help: "执行查询语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
mdb, ok := m.Target().Server.(*MDB) // {{{
m.Assert(ok)
msg := m.Spawn(m.Target())
if len(arg) > 0 {
"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) { // {{{
msg := m.Spawn()
if len(arg) == 0 {
msg.Cmd("query", "show tables")
mdb.table = []string{}
for i, v := range msg.Meta[msg.Meta["append"][0]] {
mdb.table = append(mdb.table, v)
m.Echo("%d: %s\n", i, v)
}
return
}
table := arg[0]
index, e := strconv.Atoi(arg[0])
if e == nil && index < len(mdb.table) {
table = mdb.table[index]
}
msg.Cmd("query", fmt.Sprintf("desc %s", table))
if len(arg) > 1 {
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])
}
}
}
} else {
msg.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
}
} else {
msg.Cmd("query", "show tables")
mdb.table = []string{}
for i, v := range msg.Meta[msg.Meta["append"][0]] {
mdb.table = append(mdb.table, v)
m.Echo("%d: %s\n", i, v)
if v == arg[1] {
for _, k := range msg.Meta["append"] {
m.Echo("%s: %s\n", k, msg.Meta[k][i])
}
}
}
}
// }}}
}},
"get": &ctx.Command{Name: "get [where str] [parse str] [table [field]]", Help: "执行查询语句",
Formats: map[string]int{"where": 1, "parse": 1},
"show": &ctx.Command{
Name: "show table fields... [where conditions]|[group fields]|[order fields]|[save filename]",
Help: "查询数据库, table: 表名, fields: 字段, where: 查询条件, group: 聚合字段, order: 排序字段",
Form: map[string]int{"where": 1, "group": 1, "order": 1, "extras": 1, "save": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
where := m.Conf("where") // {{{
if m.Options("where") {
where = m.Option("where")
if m.Options("extras") { // {{{
arg = append(arg, "extra")
}
fields := strings.Join(arg[1:], ",")
where := m.Optionx("where", "where %s")
group := m.Optionx("group", "group by %s")
order := m.Optionx("order", "order by %s")
msg := m.Spawn().Cmd("query", fmt.Sprintf("select %s from %s %s %s %s", fields, arg[0], where, group, order))
if !m.Options("save") {
m.Echo("\033[31m%s\033[0m %s %s %s\n", arg[0], where, group, order)
}
msg.Table(func(maps map[string]string, lists []string, index int) bool {
for i, v := range lists {
if m.Options("save") {
m.Echo(maps[msg.Meta["append"][i]]).Echo(m.Conf("csv_sep"))
} else if index == -1 {
m.Echo("\033[32m%s\033[0m", v).Echo(m.Conf("csv_sep"))
} else {
m.Echo(v).Echo(m.Conf("csv_sep"))
}
}
m.Echo("\n")
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)
}
}
// }}}
}},
"get": &ctx.Command{Name: "get [where str] [parse str] [table [field]]", Help: "执行查询语句",
Form: map[string]int{"where": 1, "parse": 2},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
where := m.Confx("where", m.Option("where")) // {{{
if where != "" {
where = "where " + where
}
parse := m.Conf("parse")
if m.Options("parse") {
parse = m.Option("parse")
}
parse := m.Confx("parse", m.Option("parse"))
extra := m.Confx("extra", m.Meta["parse"], 1)
table := m.Confx("table", arg, 0)
field := m.Confx("field", arg, 1)
table := m.Conf("table")
if len(arg) > 0 {
table = arg[0]
}
field := m.Conf("field")
if len(arg) > 1 {
field = arg[1]
}
rest := []string{}
if len(arg) > 2 {
rest = arg[2:]
}
msg := m.Spawn(m.Target())
msg.Cmd("query", fmt.Sprintf("select %s from %s where %s", field, table, where), rest)
m.Copy(msg, "result").Copy(msg, "append")
m.Table(func(row map[string]string) bool {
msg := m.Spawn().Cmd("query", fmt.Sprintf("select %s from %s %s", field, table, where))
msg.Table(func(row map[string]string, lists []string, index int) bool {
if index == -1 {
return true
}
data := map[string]interface{}{}
switch parse {
case "json":
json.Unmarshal([]byte(row[field]), data)
m.Echo("%v", data)
if json.Unmarshal([]byte(row[field]), &data); extra == "" {
for k, v := range data {
m.Echo("%s: %v\n", k, v)
}
} else if v, ok := data[extra]; ok {
m.Echo("%v", v)
}
default:
m.Echo("%v", row[field])
}
return false
}) // }}}
}},
"show": &ctx.Command{Name: "show table field [where conditions]|[group fields]|[order fields]", Help: "执行查询语句",
Formats: map[string]int{"where": 1, "group": 1, "order": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
msg := m.Spawn(m.Target()) // {{{
fields := strings.Join(arg[1:], ",")
condition := ""
if m.Options("where") {
condition = fmt.Sprintf("where %s", m.Option("where"))
}
group := ""
if m.Options("group") {
group = fmt.Sprintf("group by %s", m.Option("group"))
}
order := ""
if m.Options("order") {
order = fmt.Sprintf("order by %s", m.Option("order"))
}
msg.Cmd("query", fmt.Sprintf("select %s from %s %s %s %s", fields, arg[0], condition, group, order))
m.Echo("\033[31m%s\033[0m %s %s %s\n", arg[0], condition, group, order)
for _, k := range msg.Meta["append"] {
m.Echo("\033[32m%s\033[0m\t", k)
}
m.Echo("\n")
for i := 0; i < len(msg.Meta[msg.Meta["append"][0]]); i++ {
for _, k := range msg.Meta["append"] {
m.Echo("%s\t", msg.Meta[k][i])
}
m.Echo("\n")
}
// }}}
}},
"list": &ctx.Command{Name: "list add table field [where condition]", Help: "执行查询语句",
Formats: map[string]int{"where": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
mdb, ok := m.Target().Server.(*MDB) // {{{
m.Assert(ok)
if len(arg) == 0 {
for _, k := range mdb.list_key {
m.Echo("%s: %v\n", k, mdb.list[k])
}
return
}
switch arg[0] {
case "add":
if mdb.list == nil {
mdb.list = make(map[string][]string)
}
mdb.list[m.Cap("count")] = append(mdb.list[m.Cap("count")], m.Option("where"))
mdb.list[m.Cap("count")] = append(mdb.list[m.Cap("count")], arg[1:]...)
mdb.list_key = append(mdb.list_key, m.Cap("count"))
m.Capi("count", 1)
case "set":
mdb.list[arg[1]] = []string{m.Option("where")}
mdb.list[arg[1]] = append(mdb.list[arg[1]], arg[2:]...)
default:
if table, ok := mdb.list[arg[0]]; ok {
msg := m.Spawn(m.Target())
fields := strings.Join(table[2:], ",")
condition := ""
if len(arg) > 1 && len(arg[1]) > 0 {
condition = fmt.Sprintf("where %s", arg[1])
} else if len(table[0]) > 0 {
condition = fmt.Sprintf("where %s", table[0])
}
other := ""
if len(arg) > 2 {
other = strings.Join(arg[2:], " ")
}
msg.Cmd("query", fmt.Sprintf("select %s from %s %s %s", fields, table[1], condition, other))
m.Echo("%s %s\n", table[1], condition)
for _, k := range msg.Meta["append"] {
m.Echo("%s\t", k)
}
m.Echo("\n")
for i := 0; i < len(msg.Meta[msg.Meta["append"][0]]); i++ {
for _, k := range msg.Meta["append"] {
m.Echo("%s\t", msg.Meta[k][i])
}
m.Echo("\n")
}
}
}
// }}}
}},
},
Index: map[string]*ctx.Context{
"void": &ctx.Context{Name: "void",

View File

@ -140,7 +140,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
// }}}
}},
"send": &ctx.Command{Name: "send [domain str] cmd arg...", Help: "远程执行",
Formats: map[string]int{"domain": 1},
Form: map[string]int{"domain": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if ssh, ok := m.Target().Server.(*SSH); m.Assert(ok) { // {{{

View File

@ -396,7 +396,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
// }}}
}},
"get": &ctx.Command{Name: "get [method GET|POST] [file filename] url arg...", Help: "访问URL",
Formats: map[string]int{"method": 1, "file": 2},
Form: map[string]int{"method": 1, "file": 2},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
web, ok := m.Target().Server.(*WEB) // {{{
m.Assert(ok)