diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..56dbf4da --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ + +BENCH=src/example/bench.go + +install: + go install $(BENCH) + +build: + go build $(BENCH) diff --git a/src/contexts/mdb/mdb.go b/src/contexts/mdb/mdb.go index 693df84c..eced0f23 100644 --- a/src/contexts/mdb/mdb.go +++ b/src/contexts/mdb/mdb.go @@ -1,7 +1,8 @@ -package mdb - -import ( +package mdb // {{{ +// }}} +import ( // {{{ "contexts" + "strings" "database/sql" _ "github.com/go-sql-driver/mysql" @@ -9,12 +10,17 @@ import ( "fmt" ) +// }}} + type MDB struct { *sql.DB + + list map[string][]string + list_key []string *ctx.Context } -func (mdb *MDB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { +func (mdb *MDB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ c.Caches = map[string]*ctx.Cache{ "source": &ctx.Cache{Name: "数据库参数", Value: "", Help: "数据库参数"}, "driver": &ctx.Cache{Name: "数据库驱动", Value: "", Help: "数据库驱动"}, @@ -26,14 +32,17 @@ func (mdb *MDB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server return s } -func (mdb *MDB) Begin(m *ctx.Message, arg ...string) ctx.Server { +// }}} +func (mdb *MDB) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ + mdb.Context.Master(nil) if mdb.Context == Index { Pulse = m } return mdb } -func (mdb *MDB) Start(m *ctx.Message, arg ...string) bool { +// }}} +func (mdb *MDB) Start(m *ctx.Message, arg ...string) bool { // {{{ if len(arg) > 0 { m.Cap("source", arg[0]) } @@ -54,7 +63,8 @@ func (mdb *MDB) Start(m *ctx.Message, arg ...string) bool { return false } -func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool { +// }}} +func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool { // {{{ switch mdb.Context { case m.Target(): if mdb.DB != nil { @@ -67,9 +77,12 @@ func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool { return true } +// }}} + 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: "已打开数据库的数量"}, }, Configs: map[string]*ctx.Config{ @@ -77,15 +90,16 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心", }, Commands: map[string]*ctx.Command{ "open": &ctx.Command{Name: "open source [driver]", Help: "打开数据库", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - m.Assert(len(arg) > 0, "缺少参数") + m.Assert(len(arg) > 0, "缺少参数") // {{{ m.Start(fmt.Sprintf("db%d", Pulse.Capi("nsource", 1)), "数据存储", arg...) Pulse.Cap("stream", Pulse.Cap("nsource")) m.Echo(m.Target().Name) + // }}} }}, "exec": &ctx.Command{Name: "exec sql [arg]", Help: "操作数据库", Appends: map[string]string{"last": "最后插入元组的标识", "nrow": "修改元组的数量"}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - mdb, ok := m.Target().Server.(*MDB) + mdb, ok := m.Target().Server.(*MDB) // {{{ m.Assert(ok, "目标模块类型错误") m.Assert(len(arg) > 0, "缺少参数") m.Assert(mdb.DB != nil, "数据库未打开") @@ -106,9 +120,10 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心", 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) + mdb, ok := m.Target().Server.(*MDB) // {{{ m.Assert(ok, "目标模块类型错误") m.Assert(len(arg) > 0, "缺少参数") m.Assert(mdb.DB != nil, "数据库未打开") @@ -151,6 +166,81 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心", } 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) { + msg := m.Spawn(m.Target()) // {{{ + if len(arg) > 0 { + msg.Cmd("query", fmt.Sprintf("desc %s", arg[0])) + 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 { + for _, v := range msg.Meta[msg.Meta["append"][0]] { + m.Echo("%s\n", v) + } + } + } else { + msg.Cmd("query", "show tables") + for _, v := range msg.Meta[msg.Meta["append"][0]] { + m.Echo("%s\n", v) + } + } + // }}} + }}, + "list": &ctx.Command{Name: "list add table field", Help: "执行查询语句", 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) + } + m.Capi("count", 1) + mdb.list[m.Cap("count")] = arg[1:] + mdb.list_key = append(mdb.list_key, m.Cap("count")) + case "set": + mdb.list[arg[1]] = arg[2:] + default: + if table, ok := mdb.list[arg[0]]; ok { + msg := m.Spawn(m.Target()) + + fields := strings.Join(table[1:], ",") + condition := "" + if len(arg) > 1 && len(arg[1]) > 0 { + condition = fmt.Sprintf("where %s", arg[1]) + } + other := "" + if len(arg) > 2 { + other = strings.Join(arg[2:], " ") + } + + msg.Cmd("query", fmt.Sprintf("select %s from %s %s %s", fields, table[0], condition, other)) + for _, k := range msg.Meta["append"] { + m.Echo("\t%s", k) + } + m.Echo("\n") + for i := 0; i < len(msg.Meta[msg.Meta["append"][0]]); i++ { + for _, k := range msg.Meta["append"] { + m.Echo("\t%s", msg.Meta[k][i]) + } + m.Echo("\n") + } + } + } + // }}} }}, }, Index: map[string]*ctx.Context{ diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go index d2b6f856..6cd157b1 100644 --- a/src/contexts/web/web.go +++ b/src/contexts/web/web.go @@ -32,6 +32,9 @@ type WEB struct { *http.ServeMux *http.Server + client *http.Client + cookie map[string]*http.Cookie + list map[string]string list_key []string @@ -39,8 +42,8 @@ type WEB struct { *ctx.Context } -func (web *WEB) generate(m *ctx.Message, arg string) string { // {{{ - add, e := url.Parse(arg) +func (web *WEB) generate(m *ctx.Message, uri string, arg ...string) string { // {{{ + add, e := url.Parse(uri) m.Assert(e) adds := []string{} @@ -76,12 +79,31 @@ func (web *WEB) generate(m *ctx.Message, arg string) string { // {{{ } } + args := []string{} + for i := 0; i < len(arg)-1; i += 2 { + args = append(args, arg[i]+"="+arg[i+1]) + } + p := strings.Join(args, "&") + if add.RawQuery != "" { adds = append(adds, "?") adds = append(adds, add.RawQuery) + if p != "" { + adds = append(adds, "&") + adds = append(adds, p) + } } else if m.Confs("query") { adds = append(adds, "?") adds = append(adds, m.Conf("query")) + if p != "" { + adds = append(adds, "&") + adds = append(adds, p) + } + } else { + if p != "" { + adds = append(adds, "?") + adds = append(adds, p) + } } return strings.Join(adds, "") @@ -147,22 +169,23 @@ func (web *WEB) Trans(m *ctx.Message, key string, hand func(*ctx.Message, *ctx.C // }}} func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { // {{{ + web.Log("fuck", nil, "why") if web.Message != nil { log.Println() web.Log("cmd", nil, "%v %s %s", r.RemoteAddr, r.Method, r.URL) if web.Conf("logheaders") == "yes" { for k, v := range r.Header { - log.Printf("%s: %v", k, v) + web.Log("info", nil, "%s: %v", k, v) } - log.Println() + web.Log("info", nil, "") } if r.ParseForm(); len(r.PostForm) > 0 { for k, v := range r.PostForm { - log.Printf("%s: %v", k, v) + web.Log("info", nil, "%s: %v", k, v) } - log.Println() + web.Log("info", nil, "") } } @@ -170,9 +193,9 @@ func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { // {{{ if web.Message != nil && web.Conf("logheaders") == "yes" { for k, v := range w.Header() { - log.Printf("%s: %v", k, v) + web.Log("info", nil, "%s: %v", k, v) } - log.Println() + web.Log("info", nil, "") } } @@ -348,15 +371,56 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", }) } // }}} }}, - "get": &ctx.Command{Name: "get url", Help: "访问URL", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + "cookie": &ctx.Command{Name: "cookie add|del arg...", Help: "访问URL", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { web, ok := m.Target().Server.(*WEB) // {{{ m.Assert(ok) - uri := web.generate(m, arg[0]) + switch len(arg) { + case 0: + for k, v := range web.cookie { + m.Echo("%s: %v\n", k, v.Value) + } + case 1: + if v, ok := web.cookie[arg[0]]; ok { + m.Echo("%s", v.Value) + } + default: + if web.cookie == nil { + web.cookie = make(map[string]*http.Cookie) + } + if v, ok := web.cookie[arg[0]]; ok { + v.Value = arg[1] + } else { + web.cookie[arg[0]] = &http.Cookie{Name: arg[0], Value: arg[1]} + } + } + // }}} + }}, + "get": &ctx.Command{Name: "get url arg...", Help: "访问URL", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + web, ok := m.Target().Server.(*WEB) // {{{ + m.Assert(ok) + + uri := web.generate(m, arg[0], arg[1:]...) m.Log("info", nil, "GET %s", uri) - res, e := http.Get(uri) + if web.client == nil { + web.client = &http.Client{} + } + + req, e := http.NewRequest("GET", uri, nil) m.Assert(e) + for _, v := range web.cookie { + req.AddCookie(v) + } + + res, e := web.client.Do(req) + m.Assert(e) + if web.cookie == nil { + web.cookie = make(map[string]*http.Cookie) + } + for _, v := range res.Cookies() { + web.cookie[v.Name] = v + } for k, v := range res.Header { m.Log("info", nil, "%s: %v", k, v) @@ -386,7 +450,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", m.Echo(string(buf)) // }}} }}, - "list": &ctx.Command{Name: "list [index|add|del [url]]", Help: "查看、访问、添加url", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + "list": &ctx.Command{Name: "list [set|add|del [url]]", Help: "查看、访问、添加url", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { web, ok := m.Target().Server.(*WEB) // {{{ m.Assert(ok) @@ -400,7 +464,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", case 1: msg := m.Spawn(m.Target()).Cmd("get", web.list[arg[0]]) m.Copy(msg, "result") - case 2: + default: switch arg[0] { case "add": m.Capi("count", 1) @@ -408,8 +472,11 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", web.list_key = append(web.list_key, m.Cap("count")) case "del": delete(web.list, arg[1]) + case "set": + web.list[arg[1]] = arg[2] default: - web.list[arg[0]] = arg[1] + msg := m.Spawn(m.Target()).Cmd("get", web.list[arg[0]], arg[1:]) + m.Copy(msg, "result") } } // }}} }},