Signed-off-by: 商讯在线 <swhbox@foxmail.com>
This commit is contained in:
商讯在线 2014-04-17 22:34:19 +08:00
parent b21b2f598c
commit 99a0987009
5 changed files with 404 additions and 404 deletions

View File

@ -1,65 +1,65 @@
package main package main
import ( import (
//"fmt" //"fmt"
"github.com/lunny/xorm" "github.com/go-xorm/xorm"
"strings" "strings"
"text/template" "text/template"
) )
var ( var (
CPlusTmpl LangTmpl = LangTmpl{ CPlusTmpl LangTmpl = LangTmpl{
template.FuncMap{"Mapper": mapper.Table2Obj, template.FuncMap{"Mapper": mapper.Table2Obj,
"Type": cPlusTypeStr, "Type": cPlusTypeStr,
"UnTitle": unTitle, "UnTitle": unTitle,
}, },
nil, nil,
genCPlusImports, genCPlusImports,
} }
) )
func cPlusTypeStr(col *xorm.Column) string { func cPlusTypeStr(col *xorm.Column) string {
tp := col.SQLType tp := col.SQLType
name := strings.ToUpper(tp.Name) name := strings.ToUpper(tp.Name)
switch name { switch name {
case xorm.Bit, xorm.TinyInt, xorm.SmallInt, xorm.MediumInt, xorm.Int, xorm.Integer, xorm.Serial: case xorm.Bit, xorm.TinyInt, xorm.SmallInt, xorm.MediumInt, xorm.Int, xorm.Integer, xorm.Serial:
return "int" return "int"
case xorm.BigInt, xorm.BigSerial: case xorm.BigInt, xorm.BigSerial:
return "__int64" return "__int64"
case xorm.Char, xorm.Varchar, xorm.TinyText, xorm.Text, xorm.MediumText, xorm.LongText: case xorm.Char, xorm.Varchar, xorm.TinyText, xorm.Text, xorm.MediumText, xorm.LongText:
return "tstring" return "tstring"
case xorm.Date, xorm.DateTime, xorm.Time, xorm.TimeStamp: case xorm.Date, xorm.DateTime, xorm.Time, xorm.TimeStamp:
return "time_t" return "time_t"
case xorm.Decimal, xorm.Numeric: case xorm.Decimal, xorm.Numeric:
return "tstring" return "tstring"
case xorm.Real, xorm.Float: case xorm.Real, xorm.Float:
return "float" return "float"
case xorm.Double: case xorm.Double:
return "double" return "double"
case xorm.TinyBlob, xorm.Blob, xorm.MediumBlob, xorm.LongBlob, xorm.Bytea: case xorm.TinyBlob, xorm.Blob, xorm.MediumBlob, xorm.LongBlob, xorm.Bytea:
return "tstring" return "tstring"
case xorm.Bool: case xorm.Bool:
return "bool" return "bool"
default: default:
return "tstring" return "tstring"
} }
return "" return ""
} }
func genCPlusImports(tables []*xorm.Table) map[string]string { func genCPlusImports(tables []*xorm.Table) map[string]string {
imports := make(map[string]string) imports := make(map[string]string)
for _, table := range tables { for _, table := range tables {
for _, col := range table.Columns { for _, col := range table.Columns {
switch cPlusTypeStr(col) { switch cPlusTypeStr(col) {
case "time_t": case "time_t":
imports[`<time.h>`] = `<time.h>` imports[`<time.h>`] = `<time.h>`
case "tstring": case "tstring":
imports["<string>"] = "<string>" imports["<string>"] = "<string>"
//case "__int64": //case "__int64":
// imports[""] = "" // imports[""] = ""
} }
} }
} }
return imports return imports
} }

View File

@ -1,263 +1,263 @@
package main package main
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/lunny/xorm" "github.com/go-xorm/xorm"
"go/format" "go/format"
"reflect" "reflect"
"strings" "strings"
"text/template" "text/template"
) )
var ( var (
GoLangTmpl LangTmpl = LangTmpl{ GoLangTmpl LangTmpl = LangTmpl{
template.FuncMap{"Mapper": mapper.Table2Obj, template.FuncMap{"Mapper": mapper.Table2Obj,
"Type": typestring, "Type": typestring,
"Tag": tag, "Tag": tag,
"UnTitle": unTitle, "UnTitle": unTitle,
"gt": gt, "gt": gt,
"getCol": getCol, "getCol": getCol,
}, },
formatGo, formatGo,
genGoImports, genGoImports,
} }
) )
var ( var (
errBadComparisonType = errors.New("invalid type for comparison") errBadComparisonType = errors.New("invalid type for comparison")
errBadComparison = errors.New("incompatible types for comparison") errBadComparison = errors.New("incompatible types for comparison")
errNoComparison = errors.New("missing argument for comparison") errNoComparison = errors.New("missing argument for comparison")
) )
type kind int type kind int
const ( const (
invalidKind kind = iota invalidKind kind = iota
boolKind boolKind
complexKind complexKind
intKind intKind
floatKind floatKind
integerKind integerKind
stringKind stringKind
uintKind uintKind
) )
func basicKind(v reflect.Value) (kind, error) { func basicKind(v reflect.Value) (kind, error) {
switch v.Kind() { switch v.Kind() {
case reflect.Bool: case reflect.Bool:
return boolKind, nil return boolKind, nil
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return intKind, nil return intKind, nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return uintKind, nil return uintKind, nil
case reflect.Float32, reflect.Float64: case reflect.Float32, reflect.Float64:
return floatKind, nil return floatKind, nil
case reflect.Complex64, reflect.Complex128: case reflect.Complex64, reflect.Complex128:
return complexKind, nil return complexKind, nil
case reflect.String: case reflect.String:
return stringKind, nil return stringKind, nil
} }
return invalidKind, errBadComparisonType return invalidKind, errBadComparisonType
} }
// eq evaluates the comparison a == b || a == c || ... // eq evaluates the comparison a == b || a == c || ...
func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) { func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) {
v1 := reflect.ValueOf(arg1) v1 := reflect.ValueOf(arg1)
k1, err := basicKind(v1) k1, err := basicKind(v1)
if err != nil { if err != nil {
return false, err return false, err
} }
if len(arg2) == 0 { if len(arg2) == 0 {
return false, errNoComparison return false, errNoComparison
} }
for _, arg := range arg2 { for _, arg := range arg2 {
v2 := reflect.ValueOf(arg) v2 := reflect.ValueOf(arg)
k2, err := basicKind(v2) k2, err := basicKind(v2)
if err != nil { if err != nil {
return false, err return false, err
} }
if k1 != k2 { if k1 != k2 {
return false, errBadComparison return false, errBadComparison
} }
truth := false truth := false
switch k1 { switch k1 {
case boolKind: case boolKind:
truth = v1.Bool() == v2.Bool() truth = v1.Bool() == v2.Bool()
case complexKind: case complexKind:
truth = v1.Complex() == v2.Complex() truth = v1.Complex() == v2.Complex()
case floatKind: case floatKind:
truth = v1.Float() == v2.Float() truth = v1.Float() == v2.Float()
case intKind: case intKind:
truth = v1.Int() == v2.Int() truth = v1.Int() == v2.Int()
case stringKind: case stringKind:
truth = v1.String() == v2.String() truth = v1.String() == v2.String()
case uintKind: case uintKind:
truth = v1.Uint() == v2.Uint() truth = v1.Uint() == v2.Uint()
default: default:
panic("invalid kind") panic("invalid kind")
} }
if truth { if truth {
return true, nil return true, nil
} }
} }
return false, nil return false, nil
} }
// lt evaluates the comparison a < b. // lt evaluates the comparison a < b.
func lt(arg1, arg2 interface{}) (bool, error) { func lt(arg1, arg2 interface{}) (bool, error) {
v1 := reflect.ValueOf(arg1) v1 := reflect.ValueOf(arg1)
k1, err := basicKind(v1) k1, err := basicKind(v1)
if err != nil { if err != nil {
return false, err return false, err
} }
v2 := reflect.ValueOf(arg2) v2 := reflect.ValueOf(arg2)
k2, err := basicKind(v2) k2, err := basicKind(v2)
if err != nil { if err != nil {
return false, err return false, err
} }
if k1 != k2 { if k1 != k2 {
return false, errBadComparison return false, errBadComparison
} }
truth := false truth := false
switch k1 { switch k1 {
case boolKind, complexKind: case boolKind, complexKind:
return false, errBadComparisonType return false, errBadComparisonType
case floatKind: case floatKind:
truth = v1.Float() < v2.Float() truth = v1.Float() < v2.Float()
case intKind: case intKind:
truth = v1.Int() < v2.Int() truth = v1.Int() < v2.Int()
case stringKind: case stringKind:
truth = v1.String() < v2.String() truth = v1.String() < v2.String()
case uintKind: case uintKind:
truth = v1.Uint() < v2.Uint() truth = v1.Uint() < v2.Uint()
default: default:
panic("invalid kind") panic("invalid kind")
} }
return truth, nil return truth, nil
} }
// le evaluates the comparison <= b. // le evaluates the comparison <= b.
func le(arg1, arg2 interface{}) (bool, error) { func le(arg1, arg2 interface{}) (bool, error) {
// <= is < or ==. // <= is < or ==.
lessThan, err := lt(arg1, arg2) lessThan, err := lt(arg1, arg2)
if lessThan || err != nil { if lessThan || err != nil {
return lessThan, err return lessThan, err
} }
return eq(arg1, arg2) return eq(arg1, arg2)
} }
// gt evaluates the comparison a > b. // gt evaluates the comparison a > b.
func gt(arg1, arg2 interface{}) (bool, error) { func gt(arg1, arg2 interface{}) (bool, error) {
// > is the inverse of <=. // > is the inverse of <=.
lessOrEqual, err := le(arg1, arg2) lessOrEqual, err := le(arg1, arg2)
if err != nil { if err != nil {
return false, err return false, err
} }
return !lessOrEqual, nil return !lessOrEqual, nil
} }
func getCol(cols map[string]*xorm.Column, name string) *xorm.Column { func getCol(cols map[string]*xorm.Column, name string) *xorm.Column {
return cols[name] return cols[name]
} }
func formatGo(src string) (string, error) { func formatGo(src string) (string, error) {
source, err := format.Source([]byte(src)) source, err := format.Source([]byte(src))
if err != nil { if err != nil {
return "", err return "", err
} }
return string(source), nil return string(source), nil
} }
func genGoImports(tables []*xorm.Table) map[string]string { func genGoImports(tables []*xorm.Table) map[string]string {
imports := make(map[string]string) imports := make(map[string]string)
for _, table := range tables { for _, table := range tables {
for _, col := range table.Columns { for _, col := range table.Columns {
if typestring(col) == "time.Time" { if typestring(col) == "time.Time" {
imports["time"] = "time" imports["time"] = "time"
} }
} }
} }
return imports return imports
} }
func typestring(col *xorm.Column) string { func typestring(col *xorm.Column) string {
st := col.SQLType st := col.SQLType
/*if col.IsPrimaryKey { /*if col.IsPrimaryKey {
return "int64" return "int64"
}*/ }*/
t := xorm.SQLType2Type(st) t := xorm.SQLType2Type(st)
s := t.String() s := t.String()
if s == "[]uint8" { if s == "[]uint8" {
return "[]byte" return "[]byte"
} }
return s return s
} }
func tag(table *xorm.Table, col *xorm.Column) string { func tag(table *xorm.Table, col *xorm.Column) string {
isNameId := (mapper.Table2Obj(col.Name) == "Id") isNameId := (mapper.Table2Obj(col.Name) == "Id")
isIdPk := isNameId && typestring(col) == "int64" isIdPk := isNameId && typestring(col) == "int64"
res := make([]string, 0) res := make([]string, 0)
if !col.Nullable { if !col.Nullable {
if !isIdPk { if !isIdPk {
res = append(res, "not null") res = append(res, "not null")
} }
} }
if col.IsPrimaryKey { if col.IsPrimaryKey {
if !isIdPk { if !isIdPk {
res = append(res, "pk") res = append(res, "pk")
} }
} }
if col.Default != "" { if col.Default != "" {
res = append(res, "default "+col.Default) res = append(res, "default "+col.Default)
} }
if col.IsAutoIncrement { if col.IsAutoIncrement {
if !isIdPk { if !isIdPk {
res = append(res, "autoincr") res = append(res, "autoincr")
} }
} }
if col.IsCreated { if col.IsCreated {
res = append(res, "created") res = append(res, "created")
} }
if col.IsUpdated { if col.IsUpdated {
res = append(res, "updated") res = append(res, "updated")
} }
for name, _ := range col.Indexes { for name, _ := range col.Indexes {
index := table.Indexes[name] index := table.Indexes[name]
var uistr string var uistr string
if index.Type == xorm.UniqueType { if index.Type == xorm.UniqueType {
uistr = "unique" uistr = "unique"
} else if index.Type == xorm.IndexType { } else if index.Type == xorm.IndexType {
uistr = "index" uistr = "index"
} }
if len(index.Cols) > 1 { if len(index.Cols) > 1 {
uistr += "(" + index.Name + ")" uistr += "(" + index.Name + ")"
} }
res = append(res, uistr) res = append(res, uistr)
} }
nstr := col.SQLType.Name nstr := col.SQLType.Name
if col.Length != 0 { if col.Length != 0 {
if col.Length2 != 0 { if col.Length2 != 0 {
nstr += fmt.Sprintf("(%v,%v)", col.Length, col.Length2) nstr += fmt.Sprintf("(%v,%v)", col.Length, col.Length2)
} else { } else {
nstr += fmt.Sprintf("(%v)", col.Length) nstr += fmt.Sprintf("(%v)", col.Length)
} }
} }
res = append(res, nstr) res = append(res, nstr)
var tags []string var tags []string
if genJson { if genJson {
tags = append(tags, "json:\""+col.Name+"\"") tags = append(tags, "json:\""+col.Name+"\"")
} }
if len(res) > 0 { if len(res) > 0 {
tags = append(tags, "xorm:\""+strings.Join(res, " ")+"\"") tags = append(tags, "xorm:\""+strings.Join(res, " ")+"\"")
} }
if len(tags) > 0 { if len(tags) > 0 {
return "`" + strings.Join(tags, " ") + "`" return "`" + strings.Join(tags, " ") + "`"
} else { } else {
return "" return ""
} }
} }

View File

@ -1,51 +1,51 @@
package main package main
import ( import (
"github.com/lunny/xorm" "github.com/go-xorm/xorm"
"io/ioutil" "io/ioutil"
"strings" "strings"
"text/template" "text/template"
) )
type LangTmpl struct { type LangTmpl struct {
Funcs template.FuncMap Funcs template.FuncMap
Formater func(string) (string, error) Formater func(string) (string, error)
GenImports func([]*xorm.Table) map[string]string GenImports func([]*xorm.Table) map[string]string
} }
var ( var (
mapper = &xorm.SnakeMapper{} mapper = &xorm.SnakeMapper{}
langTmpls = map[string]LangTmpl{ langTmpls = map[string]LangTmpl{
"go": GoLangTmpl, "go": GoLangTmpl,
"c++": CPlusTmpl, "c++": CPlusTmpl,
} }
) )
func loadConfig(f string) map[string]string { func loadConfig(f string) map[string]string {
bts, err := ioutil.ReadFile(f) bts, err := ioutil.ReadFile(f)
if err != nil { if err != nil {
return nil return nil
} }
configs := make(map[string]string) configs := make(map[string]string)
lines := strings.Split(string(bts), "\n") lines := strings.Split(string(bts), "\n")
for _, line := range lines { for _, line := range lines {
line = strings.TrimRight(line, "\r") line = strings.TrimRight(line, "\r")
vs := strings.Split(line, "=") vs := strings.Split(line, "=")
if len(vs) == 2 { if len(vs) == 2 {
configs[strings.TrimSpace(vs[0])] = strings.TrimSpace(vs[1]) configs[strings.TrimSpace(vs[0])] = strings.TrimSpace(vs[1])
} }
} }
return configs return configs
} }
func unTitle(src string) string { func unTitle(src string) string {
if src == "" { if src == "" {
return "" return ""
} }
if len(src) == 1 { if len(src) == 1 {
return strings.ToLower(string(src[0])) return strings.ToLower(string(src[0]))
} else { } else {
return strings.ToLower(string(src[0])) + src[1:] return strings.ToLower(string(src[0])) + src[1:]
} }
} }

View File

@ -13,8 +13,8 @@ import (
"github.com/dvirsky/go-pylog/logging" "github.com/dvirsky/go-pylog/logging"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/go-xorm/xorm"
_ "github.com/lib/pq" _ "github.com/lib/pq"
"github.com/lunny/xorm"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
_ "github.com/ziutek/mymysql/godrv" _ "github.com/ziutek/mymysql/godrv"
) )

View File

@ -1,15 +1,15 @@
package main package main
import ( import (
"fmt" "fmt"
"github.com/lunny/xorm" "github.com/go-xorm/xorm"
"strings" "strings"
) )
var CmdShell = &Command{ var CmdShell = &Command{
UsageLine: "shell driverName datasourceName", UsageLine: "shell driverName datasourceName",
Short: "a general shell to operate all kinds of database", Short: "a general shell to operate all kinds of database",
Long: ` Long: `
general database's shell for sqlite3, mysql, postgres. general database's shell for sqlite3, mysql, postgres.
driverName Database driver name, now supported four: mysql mymysql sqlite3 postgres driverName Database driver name, now supported four: mysql mymysql sqlite3 postgres
@ -18,14 +18,14 @@ general database's shell for sqlite3, mysql, postgres.
} }
func init() { func init() {
CmdShell.Run = runShell CmdShell.Run = runShell
CmdShell.Flags = map[string]bool{} CmdShell.Flags = map[string]bool{}
} }
var engine *xorm.Engine var engine *xorm.Engine
func shellHelp() { func shellHelp() {
fmt.Println(` fmt.Println(`
show tables show all tables show tables show all tables
columns <table_name> show table's column info columns <table_name> show table's column info
indexes <table_name> show table's index info indexes <table_name> show table's index info
@ -38,110 +38,110 @@ func shellHelp() {
} }
func runShell(cmd *Command, args []string) { func runShell(cmd *Command, args []string) {
if len(args) != 2 { if len(args) != 2 {
fmt.Println("params error, please see xorm help shell") fmt.Println("params error, please see xorm help shell")
return return
} }
var err error var err error
engine, err = xorm.NewEngine(args[0], args[1]) engine, err = xorm.NewEngine(args[0], args[1])
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return return
} }
err = engine.Ping() err = engine.Ping()
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return return
} }
var scmd string var scmd string
fmt.Print("xorm$ ") fmt.Print("xorm$ ")
for { for {
var input string var input string
_, err := fmt.Scan(&input) _, err := fmt.Scan(&input)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
continue continue
} }
if strings.ToLower(input) == "exit" { if strings.ToLower(input) == "exit" {
fmt.Println("bye") fmt.Println("bye")
return return
} }
if !strings.HasSuffix(input, ";") { if !strings.HasSuffix(input, ";") {
scmd = scmd + " " + input scmd = scmd + " " + input
continue continue
} }
scmd = scmd + " " + input scmd = scmd + " " + input
lcmd := strings.TrimSpace(strings.ToLower(scmd)) lcmd := strings.TrimSpace(strings.ToLower(scmd))
if strings.HasPrefix(lcmd, "select") { if strings.HasPrefix(lcmd, "select") {
res, err := engine.Query(scmd + "\n") res, err := engine.Query(scmd + "\n")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} else { } else {
if len(res) <= 0 { if len(res) <= 0 {
fmt.Println("no records") fmt.Println("no records")
} else { } else {
columns := make(map[string]int) columns := make(map[string]int)
for k, _ := range res[0] { for k, _ := range res[0] {
columns[k] = len(k) columns[k] = len(k)
} }
for _, m := range res { for _, m := range res {
for k, s := range m { for k, s := range m {
l := len(string(s)) l := len(string(s))
if l > columns[k] { if l > columns[k] {
columns[k] = l columns[k] = l
} }
} }
} }
var maxlen = 0 var maxlen = 0
for _, l := range columns { for _, l := range columns {
maxlen = maxlen + l + 3 maxlen = maxlen + l + 3
} }
maxlen = maxlen + 1 maxlen = maxlen + 1
fmt.Println(strings.Repeat("-", maxlen)) fmt.Println(strings.Repeat("-", maxlen))
fmt.Print("|") fmt.Print("|")
slice := make([]string, 0) slice := make([]string, 0)
for k, l := range columns { for k, l := range columns {
fmt.Print(" " + k + " ") fmt.Print(" " + k + " ")
fmt.Print(strings.Repeat(" ", l-len(k))) fmt.Print(strings.Repeat(" ", l-len(k)))
fmt.Print("|") fmt.Print("|")
slice = append(slice, k) slice = append(slice, k)
} }
fmt.Print("\n") fmt.Print("\n")
for _, r := range res { for _, r := range res {
fmt.Print("|") fmt.Print("|")
for _, k := range slice { for _, k := range slice {
fmt.Print(" " + string(r[k]) + " ") fmt.Print(" " + string(r[k]) + " ")
fmt.Print(strings.Repeat(" ", columns[k]-len(string(r[k])))) fmt.Print(strings.Repeat(" ", columns[k]-len(string(r[k]))))
fmt.Print("|") fmt.Print("|")
} }
fmt.Print("\n") fmt.Print("\n")
} }
fmt.Println(strings.Repeat("-", maxlen)) fmt.Println(strings.Repeat("-", maxlen))
//fmt.Println(res) //fmt.Println(res)
} }
} }
} else if lcmd == "show tables;" { } else if lcmd == "show tables;" {
/*tables, err := engine.DBMetas() /*tables, err := engine.DBMetas()
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} else { } else {
}*/ }*/
} else { } else {
cnt, err := engine.Exec(scmd) cnt, err := engine.Exec(scmd)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} else { } else {
fmt.Printf("%d records changed.\n", cnt) fmt.Printf("%d records changed.\n", cnt)
} }
} }
scmd = "" scmd = ""
fmt.Print("xorm$ ") fmt.Print("xorm$ ")
} }
} }