Skip to content

Commit e3b6e11

Browse files
committed
feat: get table info
1 parent 21272ae commit e3b6e11

File tree

7 files changed

+286
-55
lines changed

7 files changed

+286
-55
lines changed

pkg/sql2code/parser/mongodb.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,10 +261,11 @@ func ConvertToSQLByMgoFields(tableName string, fields []*MgoField) (string, map[
261261
protoObjectStrs = append(protoObjectStrs, field.ProtoObjectStr)
262262
}
263263
}
264+
265+
fieldStr = strings.TrimSuffix(fieldStr, ",\n")
264266
if isHaveID {
265-
fieldStr = " id bigint unsigned primary key,\n" + fieldStr
267+
fieldStr = " `id` varchar(24),\n" + fieldStr + ",\n PRIMARY KEY (id)"
266268
}
267-
fieldStr = strings.TrimSuffix(fieldStr, ",\n")
268269

269270
if len(objectStrs) > 0 {
270271
srcMongoTypeMap[SubStructKey] = strings.Join(objectStrs, "\n") + "\n"

pkg/sql2code/parser/option.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ type options struct {
3030
IsEmbed bool // is gorm.Model embedded
3131
IsWebProto bool // true: proto file include router path and swagger info, false: normal proto file without router and swagger
3232
IsExtendedAPI bool // true: extended api (9 api), false: basic api (5 api)
33+
34+
IsCustomTemplate bool // true: custom extend template, false: sponge template
3335
}
3436

3537
var defaultOptions = options{
@@ -149,6 +151,13 @@ func WithExtendedAPI() Option {
149151
}
150152
}
151153

154+
// WithCustomTemplate set custom template
155+
func WithCustomTemplate() Option {
156+
return func(o *options) {
157+
o.IsCustomTemplate = true
158+
}
159+
}
160+
152161
func parseOption(options []Option) options {
153162
o := defaultOptions
154163
for _, f := range options {

pkg/sql2code/parser/parser.go

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ const (
3737
CodeTypeService = "service"
3838
// CodeTypeCrudInfo crud info json data
3939
CodeTypeCrudInfo = "crud_info"
40+
// CodeTypeTableInfo table info json data
41+
CodeTypeTableInfo = "table_info"
4042

4143
// DBDriverMysql mysql driver
4244
DBDriverMysql = "mysql"
@@ -87,6 +89,7 @@ func ParseSQL(sql string, options ...Option) (map[string]string, error) {
8789
importPath := make(map[string]struct{})
8890
tableNames := make([]string, 0, len(stmts))
8991
primaryKeysCodes := make([]string, 0, len(stmts))
92+
tableInfoCodes := make([]string, 0, len(stmts))
9093
for _, stmt := range stmts {
9194
if ct, ok := stmt.(*ast.CreateTableStmt); ok {
9295
code, err2 := makeCode(ct, opt)
@@ -101,6 +104,7 @@ func ParseSQL(sql string, options ...Option) (map[string]string, error) {
101104
modelJSONCodes = append(modelJSONCodes, code.modelJSON)
102105
tableNames = append(tableNames, toCamel(ct.Table.Name.String()))
103106
primaryKeysCodes = append(primaryKeysCodes, code.crudInfo)
107+
tableInfoCodes = append(tableInfoCodes, string(code.tableInfo))
104108
for _, s := range code.importPaths {
105109
importPath[s] = struct{}{}
106110
}
@@ -124,24 +128,27 @@ func ParseSQL(sql string, options ...Option) (map[string]string, error) {
124128
}
125129

126130
var codesMap = map[string]string{
127-
CodeTypeModel: modelCode,
128-
CodeTypeJSON: strings.Join(modelJSONCodes, "\n\n"),
129-
CodeTypeDAO: strings.Join(updateFieldsCodes, "\n\n"),
130-
CodeTypeHandler: strings.Join(handlerStructCodes, "\n\n"),
131-
CodeTypeProto: strings.Join(protoFileCodes, "\n\n"),
132-
CodeTypeService: strings.Join(serviceStructCodes, "\n\n"),
133-
TableName: strings.Join(tableNames, ", "),
134-
CodeTypeCrudInfo: strings.Join(primaryKeysCodes, "||||"),
131+
CodeTypeModel: modelCode,
132+
CodeTypeJSON: strings.Join(modelJSONCodes, "\n\n"),
133+
CodeTypeDAO: strings.Join(updateFieldsCodes, "\n\n"),
134+
CodeTypeHandler: strings.Join(handlerStructCodes, "\n\n"),
135+
CodeTypeProto: strings.Join(protoFileCodes, "\n\n"),
136+
CodeTypeService: strings.Join(serviceStructCodes, "\n\n"),
137+
TableName: strings.Join(tableNames, ", "),
138+
CodeTypeCrudInfo: strings.Join(primaryKeysCodes, "||||"),
139+
CodeTypeTableInfo: strings.Join(tableInfoCodes, "||||"),
135140
}
136141

137142
return codesMap, nil
138143
}
139144

140145
type tmplData struct {
141-
TableName string
142-
TName string
146+
TableNamePrefix string
147+
148+
RawTableName string // raw table name, example: foo_bar
149+
TableName string // table name in camel case, example: FooBar
150+
TName string // table name first letter in lower case, example: fooBar
143151
NameFunc bool
144-
RawTableName string
145152
Fields []tmplField
146153
Comment string
147154
SubStructs string // sub structs for model
@@ -351,25 +358,31 @@ type codeText struct {
351358
protoFile string
352359
serviceStruct string
353360
crudInfo string
361+
tableInfo []byte
354362
}
355363

356364
// nolint
357365
func makeCode(stmt *ast.CreateTableStmt, opt options) (*codeText, error) {
358366
importPath := make([]string, 0, 1)
359367
data := tmplData{
360-
TableName: stmt.Table.Name.String(),
361-
RawTableName: stmt.Table.Name.String(),
362-
//Fields: make([]tmplField, 0, 1),
363-
DBDriver: opt.DBDriver,
368+
TableNamePrefix: opt.TablePrefix,
369+
RawTableName: stmt.Table.Name.String(),
370+
DBDriver: opt.DBDriver,
364371
}
365-
tablePrefix := opt.TablePrefix
366-
if tablePrefix != "" && strings.HasPrefix(data.TableName, tablePrefix) {
372+
373+
tablePrefix := data.TableNamePrefix
374+
if tablePrefix != "" && strings.HasPrefix(data.RawTableName, tablePrefix) {
367375
data.NameFunc = true
368-
data.TableName = data.TableName[len(tablePrefix):]
376+
data.TableName = toCamel(data.RawTableName[len(tablePrefix):])
377+
} else {
378+
data.TableName = toCamel(data.RawTableName)
369379
}
380+
data.TName = firstLetterToLower(data.TableName)
381+
370382
if opt.ForceTableName || data.RawTableName != inflection.Plural(data.RawTableName) {
371383
data.NameFunc = true
372384
}
385+
373386
switch opt.DBDriver {
374387
case DBDriverMongodb:
375388
if opt.JSONNamedType != 0 {
@@ -379,9 +392,6 @@ func makeCode(stmt *ast.CreateTableStmt, opt options) (*codeText, error) {
379392
}
380393
}
381394

382-
data.TableName = toCamel(data.TableName)
383-
data.TName = firstLetterToLower(data.TableName)
384-
385395
// find table comment
386396
for _, o := range stmt.Options {
387397
if o.Tp == ast.TableOptionComment {
@@ -518,18 +528,23 @@ func makeCode(stmt *ast.CreateTableStmt, opt options) (*codeText, error) {
518528
data.Fields = append(data.Fields, field)
519529
}
520530

531+
if v, ok := opt.FieldTypes[SubStructKey]; ok {
532+
data.SubStructs = v
533+
}
534+
if v, ok := opt.FieldTypes[ProtoSubStructKey]; ok {
535+
data.ProtoSubStructs = v
536+
}
537+
521538
if len(data.Fields) == 0 {
522539
return nil, errors.New("no columns found in table " + data.TableName)
523540
}
524541

525542
data.CrudInfo = newCrudInfo(data)
526543
data.CrudInfo.IsCommonType = data.isCommonStyle(opt.IsEmbed)
527544

528-
if v, ok := opt.FieldTypes[SubStructKey]; ok {
529-
data.SubStructs = v
530-
}
531-
if v, ok := opt.FieldTypes[ProtoSubStructKey]; ok {
532-
data.ProtoSubStructs = v
545+
if opt.IsCustomTemplate {
546+
tableInfo := newTableInfo(data)
547+
return &codeText{tableInfo: tableInfo.getCode()}, nil
533548
}
534549

535550
updateFieldsCode, err := getUpdateFieldsCode(data, opt.IsEmbed)

pkg/sql2code/parser/parser_test.go

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,8 @@ import (
1111
)
1212

1313
func TestParseSQL(t *testing.T) {
14-
sqls := []string{`create table user
15-
(
16-
id bigint unsigned auto_increment
17-
primary key,
14+
sqls := []string{`create table user (
15+
id bigint unsigned auto_increment,
1816
created_at datetime null,
1917
updated_at datetime null,
2018
deleted_at datetime null,
@@ -26,34 +24,32 @@ func TestParseSQL(t *testing.T) {
2624
gender tinyint not null comment '性别,1:男,2:女,3:未知',
2725
status tinyint not null comment '账号状态,1:未激活,2:已激活,3:封禁',
2826
login_state tinyint not null comment '登录状态,1:未登录,2:已登录',
27+
primary key (id),
2928
constraint user_email_uindex
3029
unique (email)
3130
);`,
3231

33-
`create table user_order
34-
(
35-
id varchar(36) not null comment '订单id'
36-
primary key,
32+
`create table user_order (
33+
id varchar(36) not null comment '订单id',
3734
product_id varchar(36) not null comment '商品id',
3835
user_id bigint unsigned not null comment '用户id',
3936
status smallint null comment '0:未支付, 1:已支付, 2:已取消',
4037
created_at timestamp null comment '创建时间',
41-
updated_at timestamp null comment '更新时间'
38+
updated_at timestamp null comment '更新时间',
39+
primary key (id)
4240
);`,
4341

44-
`create table user_str
45-
(
46-
user_id varchar(36) not null comment '用户id'
47-
primary key,
42+
`create table user_str (
43+
user_id varchar(36) not null comment '用户id',
4844
username varchar(50) not null comment '用户名',
4945
email varchar(100) not null comment '邮箱',
5046
created_at datetime null comment '创建时间',
47+
primary key (user_id),
5148
constraint email
5249
unique (email)
5350
);`,
5451

55-
`create table user_no_primary
56-
(
52+
`create table user_no_primary (
5753
username varchar(50) not null comment '用户名',
5854
email varchar(100) not null comment '邮箱',
5955
user_id varchar(36) not null comment '用户id',
@@ -66,6 +62,9 @@ func TestParseSQL(t *testing.T) {
6662
codes, err := ParseSQL(sql, WithJSONTag(0), WithEmbed())
6763
assert.Nil(t, err)
6864
for k, v := range codes {
65+
if k == CodeTypeTableInfo {
66+
continue
67+
}
6968
assert.NotEmpty(t, k)
7069
assert.NotEmpty(t, v)
7170
}
@@ -74,6 +73,9 @@ func TestParseSQL(t *testing.T) {
7473
codes, err = ParseSQL(sql, WithJSONTag(1), WithWebProto(), WithDBDriver(DBDriverMysql))
7574
assert.Nil(t, err)
7675
for k, v := range codes {
76+
if k == CodeTypeTableInfo {
77+
continue
78+
}
7779
assert.NotEmpty(t, k)
7880
assert.NotEmpty(t, v)
7981
}
@@ -82,6 +84,9 @@ func TestParseSQL(t *testing.T) {
8284
codes, err = ParseSQL(sql, WithJSONTag(0), WithDBDriver(DBDriverPostgresql))
8385
assert.Nil(t, err)
8486
for k, v := range codes {
87+
if k == CodeTypeTableInfo {
88+
continue
89+
}
8590
assert.NotEmpty(t, k)
8691
assert.NotEmpty(t, v)
8792
}
@@ -90,38 +95,70 @@ func TestParseSQL(t *testing.T) {
9095
codes, err = ParseSQL(sql, WithJSONTag(0), WithDBDriver(DBDriverSqlite))
9196
assert.Nil(t, err)
9297
for k, v := range codes {
98+
if k == CodeTypeTableInfo {
99+
continue
100+
}
93101
assert.NotEmpty(t, k)
94102
assert.NotEmpty(t, v)
95103
}
96104
//printCode(codes)
105+
106+
codes, err = ParseSQL(sql, WithDBDriver(DBDriverSqlite), WithCustomTemplate())
107+
assert.Nil(t, err)
108+
for k, v := range codes {
109+
if k == CodeTypeTableInfo {
110+
assert.NotEmpty(t, k)
111+
assert.NotEmpty(t, v)
112+
break
113+
}
114+
}
115+
//printCode(codes)
97116
}
98117
}
99118

100119
func TestParseSqlWithTablePrefix(t *testing.T) {
101120
sql := `CREATE TABLE t_person_info (
102-
id BIGINT(11) PRIMARY KEY AUTO_INCREMENT NOT NULL COMMENT 'id',
121+
id BIGINT(11) AUTO_INCREMENT NOT NULL COMMENT 'id',
103122
age INT(11) unsigned NULL,
104123
name VARCHAR(30) NOT NULL DEFAULT 'default_name' COMMENT 'name',
105124
created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
106125
login_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
107126
gender INT(8) NULL,
108127
num INT(11) DEFAULT 3 NULL,
109-
comment TEXT
128+
comment TEXT,
129+
PRIMARY KEY (id)
110130
) COMMENT="person info";`
111131

112132
codes, err := ParseSQL(sql, WithTablePrefix("t_"), WithJSONTag(0), WithNullStyle(NullDisable))
113133
assert.Nil(t, err)
114134
for k, v := range codes {
135+
if k == CodeTypeTableInfo {
136+
continue
137+
}
115138
assert.NotEmpty(t, k)
116139
assert.NotEmpty(t, v)
117140
}
118-
t.Log(codes[CodeTypeJSON])
119-
120141
//printCode(codes)
121142

143+
codes, err = ParseSQL(sql, WithTablePrefix("t_"), WithJSONTag(0), WithCustomTemplate())
144+
assert.Nil(t, err)
145+
for k, v := range codes {
146+
if k != CodeTypeTableInfo {
147+
continue
148+
}
149+
assert.NotEmpty(t, k)
150+
assert.NotEmpty(t, v)
151+
}
152+
jsonData := codes[CodeTypeTableInfo]
153+
t.Log(jsonData)
154+
t.Log(UnMarshalTableInfo(jsonData))
155+
122156
codes, err = ParseSQL(sql, WithTablePrefix("t_"), WithJSONTag(0), WithEmbed())
123157
assert.Nil(t, err)
124158
for k, v := range codes {
159+
if k == CodeTypeTableInfo {
160+
continue
161+
}
125162
assert.NotEmpty(t, k)
126163
assert.NotEmpty(t, v)
127164
}
@@ -130,6 +167,9 @@ func TestParseSqlWithTablePrefix(t *testing.T) {
130167
codes, err = ParseSQL(sql, WithTablePrefix("t_"), WithJSONTag(0), WithWebProto())
131168
assert.Nil(t, err)
132169
for k, v := range codes {
170+
if k == CodeTypeTableInfo {
171+
continue
172+
}
133173
assert.NotEmpty(t, k)
134174
assert.NotEmpty(t, v)
135175
}
@@ -138,6 +178,9 @@ func TestParseSqlWithTablePrefix(t *testing.T) {
138178
codes, err = ParseSQL(sql, WithTablePrefix("t_"), WithJSONTag(0), WithDBDriver(DBDriverPostgresql))
139179
assert.Nil(t, err)
140180
for k, v := range codes {
181+
if k == CodeTypeTableInfo {
182+
continue
183+
}
141184
assert.NotEmpty(t, k)
142185
assert.NotEmpty(t, v)
143186
}

0 commit comments

Comments
 (0)