// Package sql2go... // // Description : sql2go... // // Author : go_developer@163.com<白茶清欢> // // Date : 2021-10-25 4:49 下午 package sql2go import ( "errors" wrapperType "git.zhangdeman.cn/zhangdeman/wrapper" "strings" "github.com/xwb1989/sqlparser" ) const ( // CreateSQLColumnTPL 每个字段的模版 CreateSQLColumnTPL = " {FIELD} {TYPE} `json:\"{JSON_TAG}\" gorm:\"column:{COLUMN};default:{DEFAULT_VALUE};{NOT_NULL}\"` // {COMMENT}" // TableColumnTpl 每个字段的模版 TableColumnTpl = " {FIELD} string `json:\"{JSON_TAG}\"`" // TableColumnDescTpl 字段描述 TableColumnDescTpl = " {FIELD}: \"{JSON_TAG}\"" // TableColumnCommentTpl 字段描述 TableColumnCommentTpl = " \"{JSON_TAG}\": \"{FIELD_COMMENT}\"" ) // 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"` // 字段描述定义 } // ParseCreateTableSql 解析建表sql // // Author : go_developer@163.com<白茶清欢> // // Date : 4:49 下午 2021/10/25 func ParseCreateTableSql(sql string) (*BasicTableInfo, error) { var ( stmt sqlparser.Statement err error basic *BasicTableInfo ) basic = &BasicTableInfo{ TableName: "", ModelStructName: "", ModelStruct: "", PrimaryField: "ID", PrimaryFieldType: "", ColumnDefined: "", ColumnDescDefined: "", } 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 } r, ok := stmt.(*sqlparser.DDL) if !ok { return nil, errors.New("input sql is not ddl") } basic.TableName = sqlparser.String(r.NewName) basic.ModelStructName = wrapperType.String(basic.TableName).SnakeCaseToCamel() // 生成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 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) } data := map[string]string{ "{FIELD}": wrapperType.String(item.Name.String()).SnakeCaseToCamel(), "{COLUMN}": item.Name.String(), "{JSON_TAG}": item.Name.String(), "{DEFAULT_VALUE}": "", "{COMMENT}": comment, "{TYPE}": sqlTypeMap[item.Type.Type], } /*if data["{FIELD}"] == "ID" { basic.PrimaryFieldType = data["{TYPE}"] }*/ 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 := ` // TableName 获取表名称 func ({{TABLE_FIRST}} {{TABLE_STRUCT_NAME}}) TableName() string { return "{{TABLE_NAME}}" }` 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(), } 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) } structFieldResult += structFieldDefine + "\n" structFieldDescInstanceResult += structFieldDescDefine + ",\n" structFieldCommentInstanceResult += structFieldCommentDefine + ",\n" } structFieldResult += "}" structFieldDescInstanceResult += "}" structFieldCommentInstanceResult += "}" tableColumnFunction := ` // Columns 获取表字段定义 func ({TABLE_FIRST} {MODEL_STRUCT_NAME}) Columns() *{COLUMN_DEFINED} { return {STRUCT_FIELD_DESC_DEFINED_RESULT} } // ColumnComment 获取表字段描述 func ({TABLE_FIRST} {MODEL_STRUCT_NAME}) ColumnComment() map[string]string { return {STRUCT_FIELD_COMMENT_DEFINED_RESULT} } ` 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 }