database/sql2go/parser.go

205 lines
6.8 KiB
Go
Raw Normal View History

2022-05-16 12:38:32 +08:00
// Package sql2go...
//
// Description : sql2go...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-10-25 4:49 下午
package sql2go
import (
"errors"
2023-08-11 15:17:45 +08:00
wrapperType "git.zhangdeman.cn/zhangdeman/wrapper"
2022-05-16 12:38:32 +08:00
"strings"
"github.com/xwb1989/sqlparser"
)
const (
// CreateSQLColumnTPL 每个字段的模版
2023-02-28 16:18:20 +08:00
CreateSQLColumnTPL = " {FIELD} {TYPE} `json:\"{JSON_TAG}\" gorm:\"column:{COLUMN};default:{DEFAULT_VALUE};{NOT_NULL}\"` // {COMMENT}"
// TableColumnTpl 每个字段的模版
TableColumnTpl = " {FIELD} string `json:\"{JSON_TAG}\"`"
// TableColumnDescTpl 字段描述
2024-04-14 21:56:30 +08:00
TableColumnDescTpl = " {FIELD}: \"{JSON_TAG}\""
// TableColumnCommentTpl 字段描述
2024-04-14 21:56:30 +08:00
TableColumnCommentTpl = " \"{JSON_TAG}\": \"{FIELD_COMMENT}\""
2022-05-16 12:38:32 +08:00
)
// BasicTableInfo ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 11:47 上午 2021/11/17
type BasicTableInfo struct {
TableName string `json:"table_name"` // 表名称
ModelStructName string `json:"model_struct_name"` // 生成的结构体名称
ModelStruct string `json:"model_struct"` // 生成的结构体内容
PrimaryField string `json:"primary_field"` // 主键字段
PrimaryFieldType string `json:"primary_field_type"` // 主键字段类型
ColumnDefined string `json:"column_defined"` // 字段定义
ColumnDescDefined string `json:"column_desc_defined"` // 字段描述定义
2022-05-16 12:38:32 +08:00
}
// ParseCreateTableSql 解析建表sql
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:49 下午 2021/10/25
func ParseCreateTableSql(sql string) (*BasicTableInfo, error) {
2022-05-16 12:38:32 +08:00
var (
stmt sqlparser.Statement
err error
basic *BasicTableInfo
)
basic = &BasicTableInfo{
TableName: "",
ModelStructName: "",
ModelStruct: "",
PrimaryField: "ID",
PrimaryFieldType: "",
ColumnDefined: "",
ColumnDescDefined: "",
2022-05-16 12:38:32 +08:00
}
sql = strings.ReplaceAll(strings.ReplaceAll(sql, "CURRENT_TIMESTAMP()", "CURRENT_TIMESTAMP"), "current_timestamp()", "CURRENT_TIMESTAMP")
if stmt, err = sqlparser.ParseStrictDDL(sql); nil != err {
return nil, err
2022-05-16 12:38:32 +08:00
}
r, ok := stmt.(*sqlparser.DDL)
if !ok {
return nil, errors.New("input sql is not ddl")
2022-05-16 12:38:32 +08:00
}
basic.TableName = sqlparser.String(r.NewName)
basic.ModelStructName = wrapperType.String(basic.TableName).SnakeCaseToCamel()
2022-05-16 12:38:32 +08:00
// 生成model sql
basic.ModelStruct = generateTable(basic.TableName, basic.ModelStructName, r.TableSpec.Columns)
// 生成表字段定义
columnDefined, _, getColumnFunc := generateTableColumnDefined(basic.ModelStructName, r.TableSpec.Columns)
basic.ColumnDescDefined = columnDefined
basic.ModelStruct += getColumnFunc
2024-04-14 22:00:46 +08:00
basic.ModelStruct = basic.ColumnDescDefined + "\n" + basic.ModelStruct
return basic, nil
}
// generateTable 生成表结构定义
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 20:29 2024/4/14
func generateTable(tableName string, modelStructName string, columnList []*sqlparser.ColumnDefinition) string {
structResult := "type " + modelStructName + " struct { \n"
for _, item := range columnList {
comment := ""
if item.Type.Comment == nil {
comment = item.Name.String()
} else {
comment = string(item.Type.Comment.Val)
}
2022-05-16 12:38:32 +08:00
data := map[string]string{
2023-08-11 15:17:45 +08:00
"{FIELD}": wrapperType.String(item.Name.String()).SnakeCaseToCamel(),
2022-05-16 12:38:32 +08:00
"{COLUMN}": item.Name.String(),
"{JSON_TAG}": item.Name.String(),
"{DEFAULT_VALUE}": "",
"{COMMENT}": comment,
2022-05-16 12:38:32 +08:00
"{TYPE}": sqlTypeMap[item.Type.Type],
}
/*if data["{FIELD}"] == "ID" {
2022-05-16 12:38:32 +08:00
basic.PrimaryFieldType = data["{TYPE}"]
}*/
2022-05-16 12:38:32 +08:00
if item.Type.NotNull {
data["{NOT_NULL}"] = "NOT NULL"
}
if nil != item.Type.Default {
data["{DEFAULT_VALUE}"] += string(item.Type.Default.Val)
}
val := CreateSQLColumnTPL
for k, v := range data {
val = strings.ReplaceAll(val, k, v)
}
structResult += val + "\n"
}
structResult = structResult + "}"
// 生成表名称获取方法
tableFirst := string([]byte(tableName)[:1])
funcTpl := `
2023-02-28 16:18:20 +08:00
// TableName 获取表名称
func ({{TABLE_FIRST}} {{TABLE_STRUCT_NAME}}) TableName() string {
2024-04-14 21:46:43 +08:00
return "{{TABLE_NAME}}"
2023-02-28 16:18:20 +08:00
}`
replaceTable := map[string]string{
"{{TABLE_FIRST}}": tableFirst,
"{{TABLE_STRUCT_NAME}}": modelStructName,
"{{TABLE_NAME}}": tableName,
}
for k, v := range replaceTable {
funcTpl = strings.ReplaceAll(funcTpl, k, v)
}
structResult = structResult + funcTpl
return structResult
}
// generateTableColumnDefined 生成表结构定义 + 表结构初始化
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 20:35 2024/4/14
func generateTableColumnDefined(modelStructName string, columnList []*sqlparser.ColumnDefinition) (string, string, string) {
columnDefineName := modelStructName + "Column"
structFieldResult := "type " + columnDefineName + " struct { \n"
structFieldDescInstanceResult := "&" + columnDefineName + "{ \n"
structFieldCommentInstanceResult := "map[string]string{ \n"
for _, column := range columnList {
dataMap := map[string]string{
"{FIELD}": wrapperType.String(column.Name.String()).SnakeCaseToCamel(),
"{JSON_TAG}": column.Name.String(),
"{FIELD_COMMENT}": wrapperType.TernaryOperator.String(
column.Type.Comment == nil,
wrapperType.String(column.Name.String()),
wrapperType.String(string(column.Type.Comment.Val)),
).Value(),
2023-02-28 16:18:20 +08:00
}
structFieldDefine := TableColumnTpl
structFieldDescDefine := TableColumnDescTpl
structFieldCommentDefine := TableColumnCommentTpl
for k, v := range dataMap {
structFieldDefine = strings.ReplaceAll(structFieldDefine, k, v)
structFieldDescDefine = strings.ReplaceAll(structFieldDescDefine, k, v)
structFieldCommentDefine = strings.ReplaceAll(structFieldCommentDefine, k, v)
2023-02-28 16:18:20 +08:00
}
structFieldResult += structFieldDefine + "\n"
2024-04-14 21:46:43 +08:00
structFieldDescInstanceResult += structFieldDescDefine + ",\n"
structFieldCommentInstanceResult += structFieldCommentDefine + ",\n"
2023-02-28 16:18:20 +08:00
}
structFieldResult += "}"
2024-04-14 21:46:43 +08:00
structFieldDescInstanceResult += "}"
structFieldCommentInstanceResult += "}"
tableColumnFunction := `
2023-02-28 16:18:20 +08:00
2024-04-14 21:38:53 +08:00
// Columns 获取表字段定义
func ({TABLE_FIRST} {MODEL_STRUCT_NAME}) Columns() *{COLUMN_DEFINED} {
2024-04-14 21:46:43 +08:00
return {STRUCT_FIELD_DESC_DEFINED_RESULT}
2024-04-14 21:38:53 +08:00
}
2024-04-14 21:38:53 +08:00
// ColumnComment 获取表字段描述
func ({TABLE_FIRST} {MODEL_STRUCT_NAME}) ColumnComment() map[string]string {
2024-04-14 21:46:43 +08:00
return {STRUCT_FIELD_COMMENT_DEFINED_RESULT}
2024-04-14 21:38:53 +08:00
}
`
dataMap := map[string]string{
"{COLUMN_DEFINED}": columnDefineName,
"{TABLE_FIRST}": string([]byte(strings.ToLower(modelStructName))[:1]),
"{MODEL_STRUCT_NAME}": modelStructName,
"{STRUCT_FIELD_DESC_DEFINED_RESULT}": structFieldDescInstanceResult,
"{STRUCT_FIELD_COMMENT_DEFINED_RESULT}": structFieldCommentInstanceResult,
}
for k, v := range dataMap {
tableColumnFunction = strings.ReplaceAll(tableColumnFunction, k, v)
}
return structFieldResult, structFieldDescInstanceResult, tableColumnFunction
2022-05-16 12:38:32 +08:00
}