db.makeDB use text format
This commit is contained in:
parent
1ae9577baf
commit
974e667004
87
README.md
87
README.md
@ -1,2 +1,89 @@
|
||||
# plugins
|
||||
|
||||
## db.makeDB 根据简化的数据结构描述自动生成数据库表结构(自动比对,增量更新)
|
||||
|
||||
```
|
||||
// Account 账号
|
||||
|
||||
User // 用户
|
||||
id c12 PK // 用户ID
|
||||
phone v20 U // 手机号
|
||||
password v80 n // 密码
|
||||
salt v50 // 随机密码
|
||||
name v100 n // 名称
|
||||
serverKey v200 // 服务密钥
|
||||
isValid b // 是否有效
|
||||
|
||||
Device // 设备
|
||||
id v30 PK // 设备ID
|
||||
userId c12 // 当前用户
|
||||
salt v50 // 随机密码
|
||||
secretTime dt // 密钥生成时间
|
||||
|
||||
// Log 日志
|
||||
|
||||
LoginLog // 登录日志
|
||||
id ubi AI // 登录ID
|
||||
way v20 // 登录途径(verifyCode/autoLogin/oneClickLogin)
|
||||
userId c12 I // 当前用户
|
||||
deviceId v30 I // 设备ID
|
||||
time dt I // 登录时间
|
||||
userAgent v200 // 设备信息
|
||||
requestId v20 // 请求ID
|
||||
sessionId v20 // 会话ID
|
||||
successful b // 是否成功
|
||||
message v1024 // 登录处理失败的信息
|
||||
```
|
||||
|
||||
## db.makeDB 缩写对照表
|
||||
|
||||
### types
|
||||
|
||||
```
|
||||
c => char
|
||||
v => varchar
|
||||
dt => datetime
|
||||
d => date
|
||||
tm => time
|
||||
i => int
|
||||
ui => int unsigned
|
||||
ti => tinyint
|
||||
uti => tinyint unsigned
|
||||
b => tinyint unsigned
|
||||
bi => bigint
|
||||
ubi => bigint unsigned
|
||||
f => float
|
||||
uf => float unsigned
|
||||
ff => double
|
||||
uff => double unsigned
|
||||
si => smallint
|
||||
usi => smallint unsigned
|
||||
mi => middleint
|
||||
umi => middleint unsigned
|
||||
t => text
|
||||
bb => blob
|
||||
```
|
||||
|
||||
### indexes
|
||||
|
||||
```
|
||||
PK => PRIMARY KEY NOT NULL
|
||||
AI => PRIMARY KEY AUTOINCREMENT NOT NULL
|
||||
I => index
|
||||
U => unique
|
||||
TI => fulltext
|
||||
```
|
||||
|
||||
### defaults
|
||||
|
||||
```
|
||||
ct => CURRENT_TIMESTAMP
|
||||
ctu => CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
```
|
||||
|
||||
### null set
|
||||
|
||||
```
|
||||
n => NULL
|
||||
nn => NOT NULL
|
||||
```
|
||||
|
163
db/MakeTable.go
163
db/MakeTable.go
@ -180,6 +180,169 @@ func MakeER(groups []ERGroup, outputFile *string, tplFile *string, ctx *plugin.C
|
||||
return err
|
||||
}
|
||||
|
||||
func ConvertTextToER(text string) []ERGroup {
|
||||
tablesByGroup := make([]ERGroup, 0)
|
||||
var lastGroup *ERGroup
|
||||
lastTableName := ""
|
||||
var lastTable *TableStruct
|
||||
lastTableComment := ""
|
||||
splitter := regexp.MustCompile(`\s+`)
|
||||
wnMatcher := regexp.MustCompile(`^([a-zA-Z]+)([0-9]+)$`)
|
||||
for _, line := range strings.Split(text, "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
lc := strings.SplitN(line, "//", 2)
|
||||
comment := ""
|
||||
if len(lc) == 2 {
|
||||
line = strings.TrimSpace(lc[0])
|
||||
comment = strings.TrimSpace(lc[1])
|
||||
}
|
||||
if line == "" {
|
||||
if comment != "" {
|
||||
commentA := strings.SplitN(comment, " ", 2)
|
||||
if len(commentA) == 1 {
|
||||
commentA = append(commentA, "")
|
||||
}
|
||||
//lastGroupName = comment
|
||||
lastGroup = &ERGroup{
|
||||
Group: commentA[0],
|
||||
Comment: commentA[1],
|
||||
Tables: make([]TableStruct, 0),
|
||||
}
|
||||
tablesByGroup = append(tablesByGroup, *lastGroup)
|
||||
lastGroup = &tablesByGroup[len(tablesByGroup)-1]
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
a := splitter.Split(line, 10)
|
||||
if len(a) == 1 {
|
||||
lastTableName = a[0]
|
||||
lastTableComment = comment
|
||||
lastTable = &TableStruct{
|
||||
Name: lastTableName,
|
||||
Comment: lastTableComment,
|
||||
Fields: make([]TableField, 0),
|
||||
}
|
||||
if lastGroup == nil {
|
||||
lastGroup = &ERGroup{
|
||||
Group: "Default",
|
||||
Tables: make([]TableStruct, 0),
|
||||
}
|
||||
tablesByGroup = append(tablesByGroup, *lastGroup)
|
||||
lastGroup = &tablesByGroup[len(tablesByGroup)-1]
|
||||
}
|
||||
lastGroup.Tables = append(lastGroup.Tables, *lastTable)
|
||||
lastTable = &lastGroup.Tables[len(lastGroup.Tables)-1]
|
||||
} else if lastTableName != "" {
|
||||
field := TableField{
|
||||
Name: a[0],
|
||||
Type: "",
|
||||
Index: "",
|
||||
IndexGroup: "",
|
||||
Default: "",
|
||||
Comment: comment,
|
||||
Null: "NOT NULL",
|
||||
Extra: "",
|
||||
}
|
||||
|
||||
for i := 1; i < len(a); i++ {
|
||||
wn := wnMatcher.FindStringSubmatch(a[i])
|
||||
tag := a[i]
|
||||
size := 0
|
||||
if wn != nil {
|
||||
tag = wn[1]
|
||||
size = u.Int(wn[2])
|
||||
}
|
||||
switch tag {
|
||||
case "PK":
|
||||
field.Index = "pk"
|
||||
field.Null = "NOT NULL"
|
||||
case "I":
|
||||
field.Index = "index"
|
||||
case "AI":
|
||||
field.Extra = "AUTO_INCREMENT"
|
||||
field.Index = "pk"
|
||||
case "TI":
|
||||
field.Index = "fulltext"
|
||||
case "U":
|
||||
field.Index = "unique"
|
||||
case "ct":
|
||||
field.Default = "CURRENT_TIMESTAMP"
|
||||
case "ctu":
|
||||
field.Default = "CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
|
||||
case "n":
|
||||
field.Null = "NULL"
|
||||
case "nn":
|
||||
field.Null = "NOT NULL"
|
||||
case "c":
|
||||
field.Type = "char"
|
||||
case "v":
|
||||
field.Type = "varchar"
|
||||
case "dt":
|
||||
field.Type = "datetime"
|
||||
case "d":
|
||||
field.Type = "date"
|
||||
case "tm":
|
||||
field.Type = "time"
|
||||
case "i":
|
||||
field.Type = "int"
|
||||
case "ui":
|
||||
field.Type = "int unsigned"
|
||||
case "ti":
|
||||
field.Type = "tinyint"
|
||||
case "uti":
|
||||
field.Type = "tinyint unsigned"
|
||||
case "b":
|
||||
field.Type = "tinyint unsigned"
|
||||
case "bi":
|
||||
field.Type = "bigint"
|
||||
case "ubi":
|
||||
field.Type = "bigint unsigned"
|
||||
case "f":
|
||||
field.Type = "float"
|
||||
case "uf":
|
||||
field.Type = "float unsigned"
|
||||
case "ff":
|
||||
field.Type = "double"
|
||||
case "uff":
|
||||
field.Type = "double unsigned"
|
||||
case "si":
|
||||
field.Type = "smallint"
|
||||
case "usi":
|
||||
field.Type = "smallint unsigned"
|
||||
case "mi":
|
||||
field.Type = "middleint"
|
||||
case "umi":
|
||||
field.Type = "middleint unsigned"
|
||||
case "t":
|
||||
field.Type = "text"
|
||||
case "bb":
|
||||
field.Type = "blob"
|
||||
default:
|
||||
}
|
||||
|
||||
if size > 0 {
|
||||
switch tag {
|
||||
case "I":
|
||||
// 索引分组
|
||||
field.Index = "index"
|
||||
field.IndexGroup = u.String(size)
|
||||
case "U":
|
||||
// 唯一索引分组
|
||||
field.Index = "unique"
|
||||
field.IndexGroup = u.String(size)
|
||||
default:
|
||||
// 带长度的类型
|
||||
field.Type += fmt.Sprintf("(%d)", size)
|
||||
}
|
||||
}
|
||||
}
|
||||
lastTable.Fields = append(lastTable.Fields, field)
|
||||
}
|
||||
}
|
||||
return tablesByGroup
|
||||
}
|
||||
|
||||
func MakeTable(conn *db.DB, table *TableStruct, ctx *plugin.Context) ([]string, error) {
|
||||
logger := ctx.GetInject("*log.Logger").(*log.Logger)
|
||||
//fmt.Println(u.JsonP(ddlKeyMatcher.FindAllStringSubmatch("(`key`,id, `name` )", 100)), "====================")
|
||||
|
39
db/db.go
39
db/db.go
@ -73,9 +73,11 @@ configs:
|
||||
"destroy": DefaultDestroy,
|
||||
"exec": DefaultExec,
|
||||
"insert": DefaultInsert,
|
||||
"make": DefaultMake,
|
||||
"makeDB": DefaultMakeDBByText,
|
||||
"makeDBBy": DefaultMakeDBByObject,
|
||||
"makeDao": DefaultMakeDao,
|
||||
"makeER": DefaultMakeER,
|
||||
"makeER": DefaultMakeERByText,
|
||||
"makeERBy": DefaultMakeERByObject,
|
||||
"makeId": DefaultMakeId,
|
||||
"query": DefaultQuery,
|
||||
"query1": DefaultQuery1,
|
||||
@ -125,9 +127,15 @@ func InKeys(numArgs int) string {
|
||||
return fmt.Sprintf("(%s)", strings.Join(a, ","))
|
||||
}
|
||||
|
||||
// Make 创建表格,如果表格已经存在则更新表结构
|
||||
// Make return 已执行的SQL列表
|
||||
func (db *DB) Make(groups []ERGroup, ctx *plugin.Context) ([]string, error) {
|
||||
// MakeDB 创建或更新数据库
|
||||
// MakeDB return 已执行的SQL列表
|
||||
func (db *DB) MakeDB(dbDesc string, ctx *plugin.Context) ([]string, error) {
|
||||
return db.MakeDBBy(ConvertTextToER(dbDesc), ctx)
|
||||
}
|
||||
|
||||
// MakeDBBy 创建或更新数据库
|
||||
// MakeDBBy return 已执行的SQL列表
|
||||
func (db *DB) MakeDBBy(groups []ERGroup, ctx *plugin.Context) ([]string, error) {
|
||||
outSql := make([]string, 0)
|
||||
for _, group := range groups {
|
||||
for _, table := range group.Tables {
|
||||
@ -143,7 +151,12 @@ func (db *DB) Make(groups []ERGroup, ctx *plugin.Context) ([]string, error) {
|
||||
}
|
||||
|
||||
// MakeER 创建ER图
|
||||
func (db *DB) MakeER(groups []ERGroup, outputFile *string, tplFile *string, ctx *plugin.Context) error {
|
||||
func (db *DB) MakeER(dbDesc string, outputFile *string, tplFile *string, ctx *plugin.Context) error {
|
||||
return MakeER(ConvertTextToER(dbDesc), outputFile, tplFile, ctx)
|
||||
}
|
||||
|
||||
// MakeERBy 创建ER图
|
||||
func (db *DB) MakeERBy(groups []ERGroup, outputFile *string, tplFile *string, ctx *plugin.Context) error {
|
||||
return MakeER(groups, outputFile, tplFile, ctx)
|
||||
}
|
||||
|
||||
@ -462,14 +475,20 @@ func DefaultReplace(ctx *plugin.Context, table string, data map[string]interface
|
||||
func DefaultUpdate(ctx *plugin.Context, table string, data map[string]interface{}, wheres string, args ...interface{}) (ExecResult, error) {
|
||||
return GetDB(ctx, nil).Update(table, data, wheres, args...)
|
||||
}
|
||||
func DefaultMake(ctx *plugin.Context, groups []ERGroup) ([]string, error) {
|
||||
return GetDB(ctx, nil).Make(groups, ctx)
|
||||
func DefaultMakeDBByText(ctx *plugin.Context, dbDesc string) ([]string, error) {
|
||||
return GetDB(ctx, nil).MakeDB(dbDesc, ctx)
|
||||
}
|
||||
func DefaultMakeDBByObject(ctx *plugin.Context, groups []ERGroup) ([]string, error) {
|
||||
return GetDB(ctx, nil).MakeDBBy(groups, ctx)
|
||||
}
|
||||
func DefaultMakeDao(ctx *plugin.Context, outputPath *string, conf *DaoConfig) error {
|
||||
return GetDB(ctx, nil).MakeDao(outputPath, conf, ctx)
|
||||
}
|
||||
func DefaultMakeER(ctx *plugin.Context, groups []ERGroup, outputFile *string, tplFile *string) error {
|
||||
return GetDB(ctx, nil).MakeER(groups, outputFile, tplFile, ctx)
|
||||
func DefaultMakeERByText(ctx *plugin.Context, dbDesc string, outputFile *string, tplFile *string) error {
|
||||
return GetDB(ctx, nil).MakeER(dbDesc, outputFile, tplFile, ctx)
|
||||
}
|
||||
func DefaultMakeERByObject(ctx *plugin.Context, groups []ERGroup, outputFile *string, tplFile *string) error {
|
||||
return GetDB(ctx, nil).MakeERBy(groups, outputFile, tplFile, ctx)
|
||||
}
|
||||
func DefaultMakeId(ctx *plugin.Context, table string, idField string, idSize uint) (string, error) {
|
||||
return GetDB(ctx, nil).MakeId(table, idField, idSize)
|
||||
|
9
tests/TestDB.txt
Normal file
9
tests/TestDB.txt
Normal file
@ -0,0 +1,9 @@
|
||||
// account 账号相关
|
||||
|
||||
user // 用户表
|
||||
id i AI // 用户编号
|
||||
name v30 // 姓名
|
||||
phone v20 U // 手机号
|
||||
addDate dt I // 创建时间
|
||||
version i I // 数据版本号
|
||||
isValid i // 是否有效(1-启用,0-禁用)
|
@ -1,7 +1,13 @@
|
||||
import db from "apigo.cc/apigo/plugins/db"
|
||||
import file from "apigo.cc/apigo/plugins/file"
|
||||
|
||||
let testDBDesc = file.loadYaml('./TestDB.yml')
|
||||
db.make(testDBDesc)
|
||||
let testDBDesc = file.read('./TestDB.txt')
|
||||
db.makeDB(testDBDesc)
|
||||
db.makeDao("db_tests")
|
||||
db.makeER(testDBDesc)
|
||||
|
||||
// let testDBDesc = file.loadYaml('./TestDB.yml')
|
||||
// console.info(db.makeDBBy(testDBDesc))
|
||||
// db.makeDao("db_tests")
|
||||
// db.makeERBy(testDBDesc)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user