forked from x/ContextOS
mac som
This commit is contained in:
parent
2121742e61
commit
6d64c777c3
@ -8,6 +8,7 @@ source etc/local.shy
|
|||||||
~shell1
|
~shell1
|
||||||
alias import nfs
|
alias import nfs
|
||||||
alias send send
|
alias send send
|
||||||
|
alias open open
|
||||||
alias dial dial
|
alias dial dial
|
||||||
alias pwd pwd
|
alias pwd pwd
|
||||||
|
|
||||||
|
@ -1,20 +1,15 @@
|
|||||||
package mdb // {{{
|
package mdb
|
||||||
// }}}
|
|
||||||
import ( // {{{
|
import (
|
||||||
"bufio"
|
|
||||||
"contexts/ctx"
|
"contexts/ctx"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
|
||||||
_ "github.com/go-sql-driver/mysql"
|
|
||||||
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
type MDB struct {
|
type MDB struct {
|
||||||
*sql.DB
|
*sql.DB
|
||||||
|
|
||||||
@ -49,15 +44,11 @@ func (mdb *MDB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mdb *MDB) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
func (mdb *MDB) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||||
if mdb.Context == Index {
|
|
||||||
Pulse = m
|
|
||||||
}
|
|
||||||
return mdb
|
return mdb
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
func (mdb *MDB) Start(m *ctx.Message, arg ...string) bool {
|
||||||
func (mdb *MDB) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|
||||||
db, e := sql.Open(m.Cap("driver"), fmt.Sprintf("%s:%s@%s(%s)/%s",
|
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.Cap("username"), m.Cap("password"), m.Cap("protocol"), m.Cap("address"), m.Cap("database")))
|
||||||
m.Assert(e)
|
m.Assert(e)
|
||||||
@ -66,23 +57,14 @@ func (mdb *MDB) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool {
|
||||||
func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool { // {{{
|
|
||||||
return false
|
|
||||||
switch mdb.Context {
|
switch mdb.Context {
|
||||||
case m.Target():
|
case m.Target():
|
||||||
if mdb.DB != nil {
|
|
||||||
m.Log("info", "mdb close %s", m.Cap("database"))
|
|
||||||
mdb.DB.Close()
|
|
||||||
mdb.DB = nil
|
|
||||||
}
|
|
||||||
case m.Source():
|
case m.Source():
|
||||||
}
|
}
|
||||||
return true
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
var Pulse *ctx.Message
|
var Pulse *ctx.Message
|
||||||
var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
|
var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
|
||||||
Caches: map[string]*ctx.Cache{
|
Caches: map[string]*ctx.Cache{
|
||||||
@ -96,48 +78,36 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
|
|||||||
"address": &ctx.Config{Name: "默认地址", Value: "", Help: "默认地址"},
|
"address": &ctx.Config{Name: "默认地址", Value: "", Help: "默认地址"},
|
||||||
"driver": &ctx.Config{Name: "数据库驱动(mysql)", Value: "mysql", Help: "数据库驱动"},
|
"driver": &ctx.Config{Name: "数据库驱动(mysql)", Value: "mysql", Help: "数据库驱动"},
|
||||||
|
|
||||||
"dbhelp": &ctx.Config{Name: "默认帮助", Value: "数据存储", Help: "默认帮助"},
|
|
||||||
"dbname": &ctx.Config{Name: "默认模块名", Value: "db", Help: "默认模块名", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string {
|
|
||||||
if len(arg) > 0 { // {{{
|
|
||||||
return arg[0]
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%s%d", x.Value, m.Capi("nsource", 1))
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
|
|
||||||
"csv_col_sep": &ctx.Config{Name: "字段分隔符", Value: "\t", Help: "字段分隔符"},
|
"csv_col_sep": &ctx.Config{Name: "字段分隔符", Value: "\t", Help: "字段分隔符"},
|
||||||
"csv_row_sep": &ctx.Config{Name: "记录分隔符", Value: "\n", Help: "记录分隔符"},
|
"csv_row_sep": &ctx.Config{Name: "记录分隔符", Value: "\n", Help: "记录分隔符"},
|
||||||
},
|
},
|
||||||
Commands: map[string]*ctx.Command{
|
Commands: map[string]*ctx.Command{
|
||||||
"open": &ctx.Command{
|
"open": &ctx.Command{
|
||||||
Name: "open [database [username [password [address [protocol [driver]]]]]] [dbname name] [dbhelp help]",
|
Name: "open [database [username [password [address [protocol [driver]]]]]]",
|
||||||
Help: "open打开数据库, database: 数据库名, username: 用户名, password: 密码, address: 服务地址, protocol: 服务协议, driver: 数据库类型, dbname: 模块名称, dbhelp: 帮助信息",
|
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) {
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
m.Start(m.Confx("dbname"), m.Confx("dbhelp"), arg...)
|
m.Start(fmt.Sprintf("db%d", m.Capi("nsource", 1)), "数据源", arg...)
|
||||||
}},
|
}},
|
||||||
"exec": &ctx.Command{Name: "exec sql [arg]", Help: "操作数据库, sql: SQL语句, arg: 操作参数",
|
"exec": &ctx.Command{Name: "exec sql [arg]", Help: "操作数据库, sql: SQL语句, arg: 操作参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
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 {
|
||||||
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) { // {{{
|
which := make([]interface{}, 0, len(arg))
|
||||||
which := make([]interface{}, 0, len(arg))
|
for _, v := range arg[1:] {
|
||||||
for _, v := range arg[1:] {
|
which = append(which, v)
|
||||||
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", "last(%s) nrow(%s)", m.Append("last", id), m.Append("nrow", n))
|
|
||||||
m.Echo("%d", id).Echo("%d", n)
|
|
||||||
}
|
}
|
||||||
// }}}
|
|
||||||
}},
|
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", "last(%s) nrow(%s)", m.Append("last", id), m.Append("nrow", n))
|
||||||
|
m.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) {
|
"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) { // {{{
|
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) && mdb.DB != nil {
|
||||||
which := make([]interface{}, 0, len(arg))
|
which := make([]interface{}, 0, len(arg))
|
||||||
for _, v := range arg[1:] {
|
for _, v := range arg[1:] {
|
||||||
which = append(which, v)
|
which = append(which, v)
|
||||||
@ -177,10 +147,9 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
|
|||||||
m.Log("info", "rows(0) cols(0)")
|
m.Log("info", "rows(0) cols(0)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// }}}
|
|
||||||
}},
|
}},
|
||||||
"db": &ctx.Command{Name: "db [which]", Help: "查看或选择数据库信息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
"db": &ctx.Command{Name: "db [which]", Help: "查看或选择数据库信息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) { // {{{
|
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) && mdb.DB != nil {
|
||||||
if len(arg) == 0 {
|
if len(arg) == 0 {
|
||||||
msg := m.Spawn().Cmd("query", "show databases")
|
msg := m.Spawn().Cmd("query", "show databases")
|
||||||
mdb.db = []string{}
|
mdb.db = []string{}
|
||||||
@ -196,12 +165,11 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
|
|||||||
db = mdb.db[i]
|
db = mdb.db[i]
|
||||||
}
|
}
|
||||||
m.Assert(m.Spawn().Cmd("exec", fmt.Sprintf("use %s", db)))
|
m.Assert(m.Spawn().Cmd("exec", fmt.Sprintf("use %s", db)))
|
||||||
m.Cap("database", 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) {
|
"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) { // {{{
|
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) {
|
||||||
if len(arg) == 0 {
|
if len(arg) == 0 {
|
||||||
msg := m.Spawn().Cmd("query", "show tables")
|
msg := m.Spawn().Cmd("query", "show tables")
|
||||||
mdb.table = []string{}
|
mdb.table = []string{}
|
||||||
@ -233,14 +201,15 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// }}}
|
|
||||||
}},
|
}},
|
||||||
"show": &ctx.Command{
|
"show": &ctx.Command{Name: "show table fields...",
|
||||||
Name: "show table fields... [where conditions] [group fields] [order fields] [limit fields] [offset fields] [save filename] [other rest...]",
|
|
||||||
Help: "查询数据库, table: 表名, fields: 字段, where: 查询条件, group: 聚合字段, order: 排序字段",
|
Help: "查询数据库, table: 表名, fields: 字段, where: 查询条件, group: 聚合字段, order: 排序字段",
|
||||||
Form: map[string]int{"where": 1, "group": 1, "order": 1, "limit": 1, "offset": 1, "extras": 1, "extra_field": 1, "extra_format": 1, "trans_field": 1, "trans_map": 2, "save": 1, "export": 2, "other": -1},
|
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,
|
||||||
|
},
|
||||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) { // {{{
|
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) {
|
||||||
table := m.Confx("table", arg, 0)
|
table := m.Confx("table", arg, 0)
|
||||||
if i, e := strconv.Atoi(table); e == nil && i < len(mdb.table) {
|
if i, e := strconv.Atoi(table); e == nil && i < len(mdb.table) {
|
||||||
table = mdb.table[i]
|
table = mdb.table[i]
|
||||||
@ -332,80 +301,9 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
|
|||||||
f.WriteString(v)
|
f.WriteString(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // }}}
|
|
||||||
}},
|
|
||||||
"get": &ctx.Command{Name: "get field offset table where [parse func field]", Help: "执行查询语句",
|
|
||||||
Form: map[string]int{"parse": 2},
|
|
||||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
|
||||||
index := 0 // {{{
|
|
||||||
if len(arg) > 1 {
|
|
||||||
if i, e := strconv.Atoi(arg[1]); e == nil {
|
|
||||||
index = i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
field := m.Confx("field", arg, 0)
|
|
||||||
offset := m.Confx("offset", arg, 1, "offset %s")
|
|
||||||
table := m.Confx("table", arg, 2, "from %s")
|
|
||||||
where := m.Confx("where", arg, 3, "where %s")
|
|
||||||
limit := "limit 1"
|
|
||||||
|
|
||||||
msg := m.Spawn().Cmd("query", fmt.Sprintf("select %s %s %s %s %s", field, table, where, limit, offset))
|
|
||||||
value := msg.Matrix(index, field)
|
|
||||||
|
|
||||||
switch m.Confx("parse", m.Option("parse")) {
|
|
||||||
case "json":
|
|
||||||
extra := ""
|
|
||||||
if len(m.Meta["parse"]) > 1 {
|
|
||||||
extra = m.Meta["parse"][1]
|
|
||||||
}
|
|
||||||
data := map[string]interface{}{}
|
|
||||||
if json.Unmarshal([]byte(value), &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", value)
|
|
||||||
}
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
"csv": &ctx.Command{Name: "csv scv_file sql_file sql", Help: "执行查询语句",
|
|
||||||
Form: map[string]int{"csv_col_sep": 1},
|
|
||||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
|
||||||
f, e := os.Open(arg[0])
|
|
||||||
m.Assert(e)
|
|
||||||
|
|
||||||
s, e := os.Create(arg[1])
|
|
||||||
m.Assert(e)
|
|
||||||
|
|
||||||
head := false
|
|
||||||
bio := bufio.NewScanner(f)
|
|
||||||
for bio.Scan() {
|
|
||||||
line := bio.Text()
|
|
||||||
if !head {
|
|
||||||
head = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
args := []interface{}{}
|
|
||||||
for _, v := range strings.Split(line, m.Confx("csv_col_sep")) {
|
|
||||||
args = append(args, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
s.WriteString(fmt.Sprintf(arg[2], args...))
|
|
||||||
s.WriteString(";\n")
|
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
Index: map[string]*ctx.Context{
|
|
||||||
"void": &ctx.Context{Name: "void",
|
|
||||||
Commands: map[string]*ctx.Command{
|
|
||||||
"open": &ctx.Command{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user