remove xorm dir as it's relocated to github.com/go-xorm/cmd
This commit is contained in:
parent
e7277992ad
commit
a0919b5371
|
@ -1,2 +0,0 @@
|
|||
[deps]
|
||||
github.com/go-xorm/xorm=../
|
|
@ -1,62 +0,0 @@
|
|||
# xorm tools
|
||||
|
||||
|
||||
xorm tools is a set of tools for database operation.
|
||||
|
||||
## Install
|
||||
|
||||
`go get github.com/go-xorm/xorm/xorm`
|
||||
|
||||
and you should install the depends below:
|
||||
|
||||
* github.com/go-xorm/xorm
|
||||
|
||||
* Mysql: [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql)
|
||||
|
||||
* MyMysql: [github.com/ziutek/mymysql/godrv](https://github.com/ziutek/mymysql/godrv)
|
||||
|
||||
* SQLite: [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3)
|
||||
|
||||
* Postgres: [github.com/bylevel/pq](https://github.com/bylevel/pq)
|
||||
|
||||
|
||||
## Reverse
|
||||
|
||||
After you installed the tool, you can type
|
||||
|
||||
`xorm help reverse`
|
||||
|
||||
to get help
|
||||
|
||||
example:
|
||||
|
||||
sqlite:
|
||||
`xorm reverse sqite3 test.db templates/goxorm`
|
||||
|
||||
mysql:
|
||||
`xorm reverse mysql root:@/xorm_test?charset=utf8 templates/goxorm`
|
||||
|
||||
mymysql:
|
||||
`xorm reverse mymysql xorm_test2/root/ templates/goxorm`
|
||||
|
||||
postgres:
|
||||
`xorm reverse postgres "dbname=xorm_test sslmode=disable" templates/goxorm`
|
||||
|
||||
will generated go files in `./model` directory
|
||||
|
||||
## Template and Config
|
||||
|
||||
Now, xorm tool supports go and c++ two languages and have go, goxorm, c++ three of default templates. In template directory, we can put a config file to control how to generating.
|
||||
|
||||
````
|
||||
lang=go
|
||||
genJson=1
|
||||
```
|
||||
|
||||
lang must be go or c++ now.
|
||||
genJson can be 1 or 0, if 1 then the struct will have json tag.
|
||||
|
||||
## LICENSE
|
||||
|
||||
BSD License
|
||||
[http://creativecommons.org/licenses/BSD/](http://creativecommons.org/licenses/BSD/)
|
66
xorm/c++.go
66
xorm/c++.go
|
@ -1,66 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
//"fmt"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
var (
|
||||
CPlusTmpl LangTmpl = LangTmpl{
|
||||
template.FuncMap{"Mapper": mapper.Table2Obj,
|
||||
"Type": cPlusTypeStr,
|
||||
"UnTitle": unTitle,
|
||||
},
|
||||
nil,
|
||||
genCPlusImports,
|
||||
}
|
||||
)
|
||||
|
||||
func cPlusTypeStr(col *core.Column) string {
|
||||
tp := col.SQLType
|
||||
name := strings.ToUpper(tp.Name)
|
||||
switch name {
|
||||
case core.Bit, core.TinyInt, core.SmallInt, core.MediumInt, core.Int, core.Integer, core.Serial:
|
||||
return "int"
|
||||
case core.BigInt, core.BigSerial:
|
||||
return "__int64"
|
||||
case core.Char, core.Varchar, core.TinyText, core.Text, core.MediumText, core.LongText:
|
||||
return "tstring"
|
||||
case core.Date, core.DateTime, core.Time, core.TimeStamp:
|
||||
return "time_t"
|
||||
case core.Decimal, core.Numeric:
|
||||
return "tstring"
|
||||
case core.Real, core.Float:
|
||||
return "float"
|
||||
case core.Double:
|
||||
return "double"
|
||||
case core.TinyBlob, core.Blob, core.MediumBlob, core.LongBlob, core.Bytea:
|
||||
return "tstring"
|
||||
case core.Bool:
|
||||
return "bool"
|
||||
default:
|
||||
return "tstring"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func genCPlusImports(tables []*core.Table) map[string]string {
|
||||
imports := make(map[string]string)
|
||||
|
||||
for _, table := range tables {
|
||||
for _, col := range table.Columns() {
|
||||
switch cPlusTypeStr(col) {
|
||||
case "time_t":
|
||||
imports[`<time.h>`] = `<time.h>`
|
||||
case "tstring":
|
||||
imports["<string>"] = "<string>"
|
||||
//case "__int64":
|
||||
// imports[""] = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
return imports
|
||||
}
|
78
xorm/cmd.go
78
xorm/cmd.go
|
@ -1,78 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A Command is an implementation of a go command
|
||||
// like go build or go fix.
|
||||
type Command struct {
|
||||
// Run runs the command.
|
||||
// The args are the arguments after the command name.
|
||||
Run func(cmd *Command, args []string)
|
||||
|
||||
// UsageLine is the one-line usage message.
|
||||
// The first word in the line is taken to be the command name.
|
||||
UsageLine string
|
||||
|
||||
// Short is the short description shown in the 'go help' output.
|
||||
Short string
|
||||
|
||||
// Long is the long message shown in the 'go help <this-command>' output.
|
||||
Long string
|
||||
|
||||
// Flag is a set of flags specific to this command.
|
||||
Flags map[string]bool
|
||||
}
|
||||
|
||||
// Name returns the command's name: the first word in the usage line.
|
||||
func (c *Command) Name() string {
|
||||
name := c.UsageLine
|
||||
i := strings.Index(name, " ")
|
||||
if i >= 0 {
|
||||
name = name[:i]
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func (c *Command) Usage() {
|
||||
fmt.Fprintf(os.Stderr, "usage: %s\n\n", c.UsageLine)
|
||||
fmt.Fprintf(os.Stderr, "%s\n", strings.TrimSpace(c.Long))
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
// Runnable reports whether the command can be run; otherwise
|
||||
// it is a documentation pseudo-command such as importpath.
|
||||
func (c *Command) Runnable() bool {
|
||||
return c.Run != nil
|
||||
}
|
||||
|
||||
// checkFlags checks if the flag exists with correct format.
|
||||
func checkFlags(flags map[string]bool, args []string, print func(string)) int {
|
||||
num := 0 // Number of valid flags, use to cut out.
|
||||
for i, f := range args {
|
||||
// Check flag prefix '-'.
|
||||
if !strings.HasPrefix(f, "-") {
|
||||
// Not a flag, finish check process.
|
||||
break
|
||||
}
|
||||
|
||||
// Check if it a valid flag.
|
||||
if v, ok := flags[f]; ok {
|
||||
flags[f] = !v
|
||||
if !v {
|
||||
print(f)
|
||||
} else {
|
||||
fmt.Println("DISABLE: " + f)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("[ERRO] Unknown flag: %s.\n", f)
|
||||
return -1
|
||||
}
|
||||
num = i + 1
|
||||
}
|
||||
|
||||
return num
|
||||
}
|
261
xorm/go.go
261
xorm/go.go
|
@ -1,261 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"reflect"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
var (
|
||||
GoLangTmpl LangTmpl = LangTmpl{
|
||||
template.FuncMap{"Mapper": mapper.Table2Obj,
|
||||
"Type": typestring,
|
||||
"Tag": tag,
|
||||
"UnTitle": unTitle,
|
||||
"gt": gt,
|
||||
"getCol": getCol,
|
||||
},
|
||||
formatGo,
|
||||
genGoImports,
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
errBadComparisonType = errors.New("invalid type for comparison")
|
||||
errBadComparison = errors.New("incompatible types for comparison")
|
||||
errNoComparison = errors.New("missing argument for comparison")
|
||||
)
|
||||
|
||||
type kind int
|
||||
|
||||
const (
|
||||
invalidKind kind = iota
|
||||
boolKind
|
||||
complexKind
|
||||
intKind
|
||||
floatKind
|
||||
integerKind
|
||||
stringKind
|
||||
uintKind
|
||||
)
|
||||
|
||||
func basicKind(v reflect.Value) (kind, error) {
|
||||
switch v.Kind() {
|
||||
case reflect.Bool:
|
||||
return boolKind, nil
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return intKind, nil
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return uintKind, nil
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return floatKind, nil
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
return complexKind, nil
|
||||
case reflect.String:
|
||||
return stringKind, nil
|
||||
}
|
||||
return invalidKind, errBadComparisonType
|
||||
}
|
||||
|
||||
// eq evaluates the comparison a == b || a == c || ...
|
||||
func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) {
|
||||
v1 := reflect.ValueOf(arg1)
|
||||
k1, err := basicKind(v1)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if len(arg2) == 0 {
|
||||
return false, errNoComparison
|
||||
}
|
||||
for _, arg := range arg2 {
|
||||
v2 := reflect.ValueOf(arg)
|
||||
k2, err := basicKind(v2)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if k1 != k2 {
|
||||
return false, errBadComparison
|
||||
}
|
||||
truth := false
|
||||
switch k1 {
|
||||
case boolKind:
|
||||
truth = v1.Bool() == v2.Bool()
|
||||
case complexKind:
|
||||
truth = v1.Complex() == v2.Complex()
|
||||
case floatKind:
|
||||
truth = v1.Float() == v2.Float()
|
||||
case intKind:
|
||||
truth = v1.Int() == v2.Int()
|
||||
case stringKind:
|
||||
truth = v1.String() == v2.String()
|
||||
case uintKind:
|
||||
truth = v1.Uint() == v2.Uint()
|
||||
default:
|
||||
panic("invalid kind")
|
||||
}
|
||||
if truth {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// lt evaluates the comparison a < b.
|
||||
func lt(arg1, arg2 interface{}) (bool, error) {
|
||||
v1 := reflect.ValueOf(arg1)
|
||||
k1, err := basicKind(v1)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
v2 := reflect.ValueOf(arg2)
|
||||
k2, err := basicKind(v2)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if k1 != k2 {
|
||||
return false, errBadComparison
|
||||
}
|
||||
truth := false
|
||||
switch k1 {
|
||||
case boolKind, complexKind:
|
||||
return false, errBadComparisonType
|
||||
case floatKind:
|
||||
truth = v1.Float() < v2.Float()
|
||||
case intKind:
|
||||
truth = v1.Int() < v2.Int()
|
||||
case stringKind:
|
||||
truth = v1.String() < v2.String()
|
||||
case uintKind:
|
||||
truth = v1.Uint() < v2.Uint()
|
||||
default:
|
||||
panic("invalid kind")
|
||||
}
|
||||
return truth, nil
|
||||
}
|
||||
|
||||
// le evaluates the comparison <= b.
|
||||
func le(arg1, arg2 interface{}) (bool, error) {
|
||||
// <= is < or ==.
|
||||
lessThan, err := lt(arg1, arg2)
|
||||
if lessThan || err != nil {
|
||||
return lessThan, err
|
||||
}
|
||||
return eq(arg1, arg2)
|
||||
}
|
||||
|
||||
// gt evaluates the comparison a > b.
|
||||
func gt(arg1, arg2 interface{}) (bool, error) {
|
||||
// > is the inverse of <=.
|
||||
lessOrEqual, err := le(arg1, arg2)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return !lessOrEqual, nil
|
||||
}
|
||||
|
||||
func getCol(cols map[string]*core.Column, name string) *core.Column {
|
||||
return cols[name]
|
||||
}
|
||||
|
||||
func formatGo(src string) (string, error) {
|
||||
source, err := format.Source([]byte(src))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(source), nil
|
||||
}
|
||||
|
||||
func genGoImports(tables []*core.Table) map[string]string {
|
||||
imports := make(map[string]string)
|
||||
|
||||
for _, table := range tables {
|
||||
for _, col := range table.Columns() {
|
||||
if typestring(col) == "time.Time" {
|
||||
imports["time"] = "time"
|
||||
}
|
||||
}
|
||||
}
|
||||
return imports
|
||||
}
|
||||
|
||||
func typestring(col *core.Column) string {
|
||||
st := col.SQLType
|
||||
t := core.SQLType2Type(st)
|
||||
s := t.String()
|
||||
if s == "[]uint8" {
|
||||
return "[]byte"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func tag(table *core.Table, col *core.Column) string {
|
||||
isNameId := (mapper.Table2Obj(col.Name) == "Id")
|
||||
isIdPk := isNameId && typestring(col) == "int64"
|
||||
|
||||
res := make([]string, 0)
|
||||
if !col.Nullable {
|
||||
if !isIdPk {
|
||||
res = append(res, "not null")
|
||||
}
|
||||
}
|
||||
if col.IsPrimaryKey {
|
||||
if !isIdPk {
|
||||
res = append(res, "pk")
|
||||
}
|
||||
}
|
||||
if col.Default != "" {
|
||||
res = append(res, "default "+col.Default)
|
||||
}
|
||||
if col.IsAutoIncrement {
|
||||
if !isIdPk {
|
||||
res = append(res, "autoincr")
|
||||
}
|
||||
}
|
||||
if col.IsCreated {
|
||||
res = append(res, "created")
|
||||
}
|
||||
if col.IsUpdated {
|
||||
res = append(res, "updated")
|
||||
}
|
||||
for name, _ := range col.Indexes {
|
||||
index := table.Indexes[name]
|
||||
var uistr string
|
||||
if index.Type == core.UniqueType {
|
||||
uistr = "unique"
|
||||
} else if index.Type == core.IndexType {
|
||||
uistr = "index"
|
||||
}
|
||||
if len(index.Cols) > 1 {
|
||||
uistr += "(" + index.Name + ")"
|
||||
}
|
||||
res = append(res, uistr)
|
||||
}
|
||||
|
||||
nstr := col.SQLType.Name
|
||||
if col.Length != 0 {
|
||||
if col.Length2 != 0 {
|
||||
nstr += fmt.Sprintf("(%v,%v)", col.Length, col.Length2)
|
||||
} else {
|
||||
nstr += fmt.Sprintf("(%v)", col.Length)
|
||||
}
|
||||
}
|
||||
res = append(res, nstr)
|
||||
|
||||
var tags []string
|
||||
if genJson {
|
||||
tags = append(tags, "json:\""+col.Name+"\"")
|
||||
}
|
||||
if len(res) > 0 {
|
||||
tags = append(tags, "xorm:\""+strings.Join(res, " ")+"\"")
|
||||
}
|
||||
if len(tags) > 0 {
|
||||
return "`" + strings.Join(tags, " ") + "`"
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
51
xorm/lang.go
51
xorm/lang.go
|
@ -1,51 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/go-xorm/core"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
type LangTmpl struct {
|
||||
Funcs template.FuncMap
|
||||
Formater func(string) (string, error)
|
||||
GenImports func([]*core.Table) map[string]string
|
||||
}
|
||||
|
||||
var (
|
||||
mapper = &core.SnakeMapper{}
|
||||
langTmpls = map[string]LangTmpl{
|
||||
"go": GoLangTmpl,
|
||||
"c++": CPlusTmpl,
|
||||
}
|
||||
)
|
||||
|
||||
func loadConfig(f string) map[string]string {
|
||||
bts, err := ioutil.ReadFile(f)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
configs := make(map[string]string)
|
||||
lines := strings.Split(string(bts), "\n")
|
||||
for _, line := range lines {
|
||||
line = strings.TrimRight(line, "\r")
|
||||
vs := strings.Split(line, "=")
|
||||
if len(vs) == 2 {
|
||||
configs[strings.TrimSpace(vs[0])] = strings.TrimSpace(vs[1])
|
||||
}
|
||||
}
|
||||
return configs
|
||||
}
|
||||
|
||||
func unTitle(src string) string {
|
||||
if src == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
if len(src) == 1 {
|
||||
return strings.ToLower(string(src[0]))
|
||||
} else {
|
||||
return strings.ToLower(string(src[0])) + src[1:]
|
||||
}
|
||||
}
|
288
xorm/reverse.go
288
xorm/reverse.go
|
@ -1,288 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings" //[SWH|+]
|
||||
"text/template"
|
||||
|
||||
_ "github.com/bylevel/pq"
|
||||
"github.com/dvirsky/go-pylog/logging"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/go-xorm/core"
|
||||
"github.com/go-xorm/xorm"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
_ "github.com/ziutek/mymysql/godrv"
|
||||
)
|
||||
|
||||
var CmdReverse = &Command{
|
||||
UsageLine: "reverse [-m] driverName datasourceName tmplPath [generatedPath]",
|
||||
Short: "reverse a db to codes",
|
||||
Long: `
|
||||
according database's tables and columns to generate codes for Go, C++ and etc.
|
||||
|
||||
-m Generated one go file for every table
|
||||
driverName Database driver name, now supported four: mysql mymysql sqlite3 postgres
|
||||
datasourceName Database connection uri, for detail infomation please visit driver's project page
|
||||
tmplPath Template dir for generated. the default templates dir has provide 1 template
|
||||
generatedPath This parameter is optional, if blank, the default value is model, then will
|
||||
generated all codes in model dir
|
||||
`,
|
||||
}
|
||||
|
||||
func init() {
|
||||
CmdReverse.Run = runReverse
|
||||
CmdReverse.Flags = map[string]bool{
|
||||
"-s": false,
|
||||
"-l": false,
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
genJson bool = false
|
||||
)
|
||||
|
||||
func printReversePrompt(flag string) {
|
||||
}
|
||||
|
||||
type Tmpl struct {
|
||||
Tables []*core.Table
|
||||
Imports map[string]string
|
||||
Model string
|
||||
}
|
||||
|
||||
func dirExists(dir string) bool {
|
||||
d, e := os.Stat(dir)
|
||||
switch {
|
||||
case e != nil:
|
||||
return false
|
||||
case !d.IsDir():
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func runReverse(cmd *Command, args []string) {
|
||||
num := checkFlags(cmd.Flags, args, printReversePrompt)
|
||||
if num == -1 {
|
||||
return
|
||||
}
|
||||
args = args[num:]
|
||||
|
||||
if len(args) < 3 {
|
||||
fmt.Println("params error, please see xorm help reverse")
|
||||
return
|
||||
}
|
||||
|
||||
var isMultiFile bool = true
|
||||
if use, ok := cmd.Flags["-s"]; ok {
|
||||
isMultiFile = !use
|
||||
}
|
||||
|
||||
curPath, err := os.Getwd()
|
||||
if err != nil {
|
||||
fmt.Println(curPath)
|
||||
return
|
||||
}
|
||||
|
||||
var genDir string
|
||||
var model string
|
||||
if len(args) == 4 {
|
||||
genDir, err = filepath.Abs(args[3])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
//[SWH|+] 经测试,path.Base不能解析windows下的“\”,需要替换为“/”
|
||||
genDir = strings.Replace(genDir, "\\", "/", -1)
|
||||
model = path.Base(genDir)
|
||||
} else {
|
||||
model = "model"
|
||||
genDir = path.Join(curPath, model)
|
||||
}
|
||||
|
||||
dir, err := filepath.Abs(args[2])
|
||||
if err != nil {
|
||||
logging.Error("%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !dirExists(dir) {
|
||||
logging.Error("Template %v path is not exist", dir)
|
||||
return
|
||||
}
|
||||
|
||||
var langTmpl LangTmpl
|
||||
var ok bool
|
||||
var lang string = "go"
|
||||
var prefix string = "" //[SWH|+]
|
||||
|
||||
cfgPath := path.Join(dir, "config")
|
||||
info, err := os.Stat(cfgPath)
|
||||
var configs map[string]string
|
||||
if err == nil && !info.IsDir() {
|
||||
configs = loadConfig(cfgPath)
|
||||
if l, ok := configs["lang"]; ok {
|
||||
lang = l
|
||||
}
|
||||
if j, ok := configs["genJson"]; ok {
|
||||
genJson, err = strconv.ParseBool(j)
|
||||
}
|
||||
|
||||
//[SWH|+]
|
||||
if j, ok := configs["prefix"]; ok {
|
||||
prefix = j
|
||||
}
|
||||
}
|
||||
|
||||
if langTmpl, ok = langTmpls[lang]; !ok {
|
||||
fmt.Println("Unsupported programing language", lang)
|
||||
return
|
||||
}
|
||||
|
||||
os.MkdirAll(genDir, os.ModePerm)
|
||||
|
||||
Orm, err := xorm.NewEngine(args[0], args[1])
|
||||
if err != nil {
|
||||
logging.Error("%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
tables, err := Orm.DBMetas()
|
||||
if err != nil {
|
||||
logging.Error("%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
filepath.Walk(dir, func(f string, info os.FileInfo, err error) error {
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if info.Name() == "config" {
|
||||
return nil
|
||||
}
|
||||
|
||||
bs, err := ioutil.ReadFile(f)
|
||||
if err != nil {
|
||||
logging.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
t := template.New(f)
|
||||
t.Funcs(langTmpl.Funcs)
|
||||
|
||||
tmpl, err := t.Parse(string(bs))
|
||||
if err != nil {
|
||||
logging.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
var w *os.File
|
||||
fileName := info.Name()
|
||||
newFileName := fileName[:len(fileName)-4]
|
||||
ext := path.Ext(newFileName)
|
||||
|
||||
if !isMultiFile {
|
||||
w, err = os.OpenFile(path.Join(genDir, newFileName), os.O_RDWR|os.O_CREATE, 0600)
|
||||
if err != nil {
|
||||
logging.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
imports := langTmpl.GenImports(tables)
|
||||
|
||||
tbls := make([]*core.Table, 0)
|
||||
for _, table := range tables {
|
||||
//[SWH|+]
|
||||
if prefix != "" {
|
||||
table.Name = strings.TrimPrefix(table.Name, prefix)
|
||||
}
|
||||
tbls = append(tbls, table)
|
||||
}
|
||||
|
||||
newbytes := bytes.NewBufferString("")
|
||||
|
||||
t := &Tmpl{Tables: tbls, Imports: imports, Model: model}
|
||||
err = tmpl.Execute(newbytes, t)
|
||||
if err != nil {
|
||||
logging.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
tplcontent, err := ioutil.ReadAll(newbytes)
|
||||
if err != nil {
|
||||
logging.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
var source string
|
||||
if langTmpl.Formater != nil {
|
||||
source, err = langTmpl.Formater(string(tplcontent))
|
||||
if err != nil {
|
||||
logging.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
source = string(tplcontent)
|
||||
}
|
||||
|
||||
w.WriteString(source)
|
||||
w.Close()
|
||||
} else {
|
||||
for _, table := range tables {
|
||||
//[SWH|+]
|
||||
if prefix != "" {
|
||||
table.Name = strings.TrimPrefix(table.Name, prefix)
|
||||
}
|
||||
// imports
|
||||
tbs := []*core.Table{table}
|
||||
imports := langTmpl.GenImports(tbs)
|
||||
|
||||
w, err := os.OpenFile(path.Join(genDir, unTitle(mapper.Table2Obj(table.Name))+ext), os.O_RDWR|os.O_CREATE, 0600)
|
||||
if err != nil {
|
||||
logging.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
newbytes := bytes.NewBufferString("")
|
||||
|
||||
t := &Tmpl{Tables: tbs, Imports: imports, Model: model}
|
||||
err = tmpl.Execute(newbytes, t)
|
||||
if err != nil {
|
||||
logging.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
tplcontent, err := ioutil.ReadAll(newbytes)
|
||||
if err != nil {
|
||||
logging.Error("%v", err)
|
||||
return err
|
||||
}
|
||||
var source string
|
||||
if langTmpl.Formater != nil {
|
||||
source, err = langTmpl.Formater(string(tplcontent))
|
||||
if err != nil {
|
||||
logging.Error("%v-%v", err, string(tplcontent))
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
source = string(tplcontent)
|
||||
}
|
||||
|
||||
w.WriteString(source)
|
||||
w.Close()
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
}
|
147
xorm/shell.go
147
xorm/shell.go
|
@ -1,147 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/go-xorm/xorm"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var CmdShell = &Command{
|
||||
UsageLine: "shell driverName datasourceName",
|
||||
Short: "a general shell to operate all kinds of database",
|
||||
Long: `
|
||||
general database's shell for sqlite3, mysql, postgres.
|
||||
|
||||
driverName Database driver name, now supported four: mysql mymysql sqlite3 postgres
|
||||
datasourceName Database connection uri, for detail infomation please visit driver's project page
|
||||
`,
|
||||
}
|
||||
|
||||
func init() {
|
||||
CmdShell.Run = runShell
|
||||
CmdShell.Flags = map[string]bool{}
|
||||
}
|
||||
|
||||
var engine *xorm.Engine
|
||||
|
||||
func shellHelp() {
|
||||
fmt.Println(`
|
||||
show tables show all tables
|
||||
columns <table_name> show table's column info
|
||||
indexes <table_name> show table's index info
|
||||
exit exit shell
|
||||
source <sql_file> exec sql file to current database
|
||||
dump [-nodata] <sql_file> dump structs or records to sql file
|
||||
help show this document
|
||||
<statement> SQL statement
|
||||
`)
|
||||
}
|
||||
|
||||
func runShell(cmd *Command, args []string) {
|
||||
if len(args) != 2 {
|
||||
fmt.Println("params error, please see xorm help shell")
|
||||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
engine, err = xorm.NewEngine(args[0], args[1])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
err = engine.Ping()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
var scmd string
|
||||
fmt.Print("xorm$ ")
|
||||
for {
|
||||
var input string
|
||||
_, err := fmt.Scan(&input)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
continue
|
||||
}
|
||||
if strings.ToLower(input) == "exit" {
|
||||
fmt.Println("bye")
|
||||
return
|
||||
}
|
||||
if !strings.HasSuffix(input, ";") {
|
||||
scmd = scmd + " " + input
|
||||
continue
|
||||
}
|
||||
scmd = scmd + " " + input
|
||||
lcmd := strings.TrimSpace(strings.ToLower(scmd))
|
||||
if strings.HasPrefix(lcmd, "select") {
|
||||
res, err := engine.Query(scmd + "\n")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
if len(res) <= 0 {
|
||||
fmt.Println("no records")
|
||||
} else {
|
||||
columns := make(map[string]int)
|
||||
for k, _ := range res[0] {
|
||||
columns[k] = len(k)
|
||||
}
|
||||
|
||||
for _, m := range res {
|
||||
for k, s := range m {
|
||||
l := len(string(s))
|
||||
if l > columns[k] {
|
||||
columns[k] = l
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var maxlen = 0
|
||||
for _, l := range columns {
|
||||
maxlen = maxlen + l + 3
|
||||
}
|
||||
maxlen = maxlen + 1
|
||||
|
||||
fmt.Println(strings.Repeat("-", maxlen))
|
||||
fmt.Print("|")
|
||||
slice := make([]string, 0)
|
||||
for k, l := range columns {
|
||||
fmt.Print(" " + k + " ")
|
||||
fmt.Print(strings.Repeat(" ", l-len(k)))
|
||||
fmt.Print("|")
|
||||
slice = append(slice, k)
|
||||
}
|
||||
fmt.Print("\n")
|
||||
for _, r := range res {
|
||||
fmt.Print("|")
|
||||
for _, k := range slice {
|
||||
fmt.Print(" " + string(r[k]) + " ")
|
||||
fmt.Print(strings.Repeat(" ", columns[k]-len(string(r[k]))))
|
||||
fmt.Print("|")
|
||||
}
|
||||
fmt.Print("\n")
|
||||
}
|
||||
fmt.Println(strings.Repeat("-", maxlen))
|
||||
//fmt.Println(res)
|
||||
}
|
||||
}
|
||||
} else if lcmd == "show tables;" {
|
||||
/*tables, err := engine.DBMetas()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
|
||||
}*/
|
||||
} else {
|
||||
cnt, err := engine.Exec(scmd)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
fmt.Printf("%d records changed.\n", cnt)
|
||||
}
|
||||
}
|
||||
scmd = ""
|
||||
fmt.Print("xorm$ ")
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
{{ range .Imports}}
|
||||
#include {{.}}
|
||||
{{ end }}
|
||||
|
||||
{{range .Tables}}class {{Mapper .Name}} {
|
||||
{{$table := .}}
|
||||
public:
|
||||
{{range .Columns}}{{$name := Mapper .Name}} {{Type .}} Get{{Mapper .Name}}() {
|
||||
return this->m_{{UnTitle $name}};
|
||||
}
|
||||
|
||||
void Set{{$name}}({{Type .}} {{UnTitle $name}}) {
|
||||
this->m_{{UnTitle $name}} = {{UnTitle $name}};
|
||||
}
|
||||
|
||||
{{end}}private:
|
||||
{{range .Columns}}{{$name := Mapper .Name}} {{Type .}} m_{{UnTitle $name}};
|
||||
{{end}}
|
||||
}
|
||||
|
||||
{{end}}
|
|
@ -1 +0,0 @@
|
|||
lang=c++
|
|
@ -1 +0,0 @@
|
|||
lang=go
|
|
@ -1,14 +0,0 @@
|
|||
package {{.Model}}
|
||||
|
||||
import (
|
||||
{{range .Imports}}"{{.}}"{{end}}
|
||||
)
|
||||
|
||||
{{range .Tables}}
|
||||
type {{Mapper .Name}} struct {
|
||||
{{$table := .}}
|
||||
{{range .Columns}} {{Mapper .Name}} {{Type .}}
|
||||
{{end}}
|
||||
}
|
||||
|
||||
{{end}}
|
|
@ -1,3 +0,0 @@
|
|||
lang=go
|
||||
genJson=0
|
||||
prefix=cos_
|
|
@ -1,18 +0,0 @@
|
|||
package {{.Model}}
|
||||
|
||||
{{$ilen := len .Imports}}
|
||||
{{if gt $ilen 0}}
|
||||
import (
|
||||
{{range .Imports}}"{{.}}"{{end}}
|
||||
)
|
||||
{{end}}
|
||||
|
||||
{{range .Tables}}
|
||||
type {{Mapper .Name}} struct {
|
||||
{{$table := .}}
|
||||
{{$columns := .Columns}}
|
||||
{{range .ColumnsSeq}}{{$col := getCol $columns .}} {{Mapper $col.Name}} {{Type $col}} {{Tag $table $col}}
|
||||
{{end}}
|
||||
}
|
||||
|
||||
{{end}}
|
162
xorm/xorm.go
162
xorm/xorm.go
|
@ -1,162 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/dvirsky/go-pylog/logging"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"text/template"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// +build go1.1
|
||||
|
||||
// Test that go1.1 tag above is included in builds. main.go refers to this definition.
|
||||
const go11tag = true
|
||||
|
||||
const version = "0.1"
|
||||
|
||||
// Commands lists the available commands and help topics.
|
||||
// The order here is the order in which they are printed by 'gopm help'.
|
||||
var commands = []*Command{
|
||||
CmdReverse,
|
||||
CmdShell,
|
||||
}
|
||||
|
||||
func init() {
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
}
|
||||
|
||||
func main() {
|
||||
logging.SetLevel(logging.ALL)
|
||||
// Check length of arguments.
|
||||
args := os.Args[1:]
|
||||
if len(args) < 1 {
|
||||
usage()
|
||||
return
|
||||
}
|
||||
|
||||
// Show help documentation.
|
||||
if args[0] == "help" {
|
||||
help(args[1:])
|
||||
return
|
||||
}
|
||||
|
||||
// Check commands and run.
|
||||
for _, comm := range commands {
|
||||
if comm.Name() == args[0] && comm.Run != nil {
|
||||
comm.Run(comm, args[1:])
|
||||
exit()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "xorm: unknown subcommand %q\nRun 'xorm help' for usage.\n", args[0])
|
||||
setExitStatus(2)
|
||||
exit()
|
||||
}
|
||||
|
||||
var exitStatus = 0
|
||||
var exitMu sync.Mutex
|
||||
|
||||
func setExitStatus(n int) {
|
||||
exitMu.Lock()
|
||||
if exitStatus < n {
|
||||
exitStatus = n
|
||||
}
|
||||
exitMu.Unlock()
|
||||
}
|
||||
|
||||
var usageTemplate = `xorm is a database tool based xorm package.
|
||||
Usage:
|
||||
|
||||
xorm command [arguments]
|
||||
|
||||
The commands are:
|
||||
{{range .}}{{if .Runnable}}
|
||||
{{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
|
||||
|
||||
Use "xorm help [command]" for more information about a command.
|
||||
|
||||
Additional help topics:
|
||||
{{range .}}{{if not .Runnable}}
|
||||
{{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
|
||||
|
||||
Use "xorm help [topic]" for more information about that topic.
|
||||
|
||||
`
|
||||
|
||||
var helpTemplate = `{{if .Runnable}}usage: xorm {{.UsageLine}}
|
||||
|
||||
{{end}}{{.Long | trim}}
|
||||
`
|
||||
|
||||
// tmpl executes the given template text on data, writing the result to w.
|
||||
func tmpl(w io.Writer, text string, data interface{}) {
|
||||
t := template.New("top")
|
||||
t.Funcs(template.FuncMap{"trim": strings.TrimSpace, "capitalize": capitalize})
|
||||
template.Must(t.Parse(text))
|
||||
if err := t.Execute(w, data); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func capitalize(s string) string {
|
||||
if s == "" {
|
||||
return s
|
||||
}
|
||||
r, n := utf8.DecodeRuneInString(s)
|
||||
return string(unicode.ToTitle(r)) + s[n:]
|
||||
}
|
||||
|
||||
func printUsage(w io.Writer) {
|
||||
tmpl(w, usageTemplate, commands)
|
||||
}
|
||||
|
||||
func usage() {
|
||||
printUsage(os.Stderr)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
// help implements the 'help' command.
|
||||
func help(args []string) {
|
||||
if len(args) == 0 {
|
||||
printUsage(os.Stdout)
|
||||
// not exit 2: succeeded at 'gopm help'.
|
||||
return
|
||||
}
|
||||
if len(args) != 1 {
|
||||
fmt.Fprintf(os.Stderr, "usage: xorm help command\n\nToo many arguments given.\n")
|
||||
os.Exit(2) // failed at 'gopm help'
|
||||
}
|
||||
|
||||
arg := args[0]
|
||||
|
||||
for _, cmd := range commands {
|
||||
if cmd.Name() == arg {
|
||||
tmpl(os.Stdout, helpTemplate, cmd)
|
||||
// not exit 2: succeeded at 'gopm help cmd'.
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "Unknown help topic %#q. Run 'xorm help'.\n", arg)
|
||||
os.Exit(2) // failed at 'gopm help cmd'
|
||||
}
|
||||
|
||||
var atexitFuncs []func()
|
||||
|
||||
func atexit(f func()) {
|
||||
atexitFuncs = append(atexitFuncs, f)
|
||||
}
|
||||
|
||||
func exit() {
|
||||
for _, f := range atexitFuncs {
|
||||
f()
|
||||
}
|
||||
os.Exit(exitStatus)
|
||||
}
|
Loading…
Reference in New Issue