Skip to content

Commit 54e0726

Browse files
committed
chore(multi-tenant): adapting generate from db for new templates
1 parent 8abe8d5 commit 54e0726

File tree

7 files changed

+78
-74
lines changed

7 files changed

+78
-74
lines changed

cmd/cli/cli/cli.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func NewCli(cmd *cobra.Command) *Cli {
2020
func (c *Cli) Start() {
2121
generatorInstance := generator.NewGenerator()
2222
generatorInstance.DeclareCommands(c.Cmd)
23+
generatorInstance.DeclareDomainCreatorFromSchema(c.Cmd)
2324
migratorInstance := migrator.NewMigrator()
2425
migratorInstance.DeclareCommands(c.Cmd)
2526
}

cmd/cli/migrator/migrator.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ func (m *Migrator) DeclareCommands(cmd *cobra.Command) {
3636
},
3737
&cobra.Command{
3838
Use: "generate-schema-from-db",
39-
Short: "generate-schema-from-db <schema name>",
40-
Long: "generate HCL schema from database connected on env",
39+
Short: "generate-schema-from-db <schema name> <database name>",
40+
Long: "generate HCL schema from connection on env \ngenerate all databases if <database name> is not provided (all databases generations does`nt work with domain generation from schema)",
4141
PreRun: m.BootMigrator,
4242
Run: m.Generate,
4343
},
@@ -60,11 +60,15 @@ func (m *Migrator) Inspect(_ *cobra.Command, _ []string) {
6060

6161
func (m *Migrator) Generate(_ *cobra.Command, args []string) {
6262
schema := ""
63+
if len(args) > 0 {
64+
schema = args[0]
65+
}
66+
databaseName := ""
6367
if len(args) > 1 {
64-
schema = args[1]
68+
databaseName = args[1]
6569
}
6670
migratorInstance := migrator.NewMigrator(m.dsn, m.dsnTest, m.database)
67-
migratorInstance.Generate(schema)
71+
migratorInstance.Generate(schema, databaseName)
6872
}
6973

7074
func (m *Migrator) BootMigrator(_ *cobra.Command, _ []string) {

schemas/schema.my.hcl

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
table "dummy" {
2-
schema = schema.skeleton
2+
schema = schema.zord
33
column "id" {
44
null = false
55
type = char(26)
@@ -16,15 +16,7 @@ table "dummy" {
1616
columns = [column.id]
1717
}
1818
}
19-
20-
//{{newTable}}
21-
22-
variable "database" {
23-
type = string
24-
}
25-
26-
schema "skeleton" {
27-
name = var.database
19+
schema "zord" {
2820
charset = "utf8mb4"
2921
collate = "utf8mb4_0900_ai_ci"
3022
}

tools/generator/generateFromDb.go

Lines changed: 55 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func (cg *CodeGenerator) ReadFromSchema(schema string, table string) {
2727
}
2828

2929
func (cg *CodeGenerator) getHclFile(schema string) (*hclwrite.File, error) {
30-
filepath := fmt.Sprintf("tools/migrator/schema/%s.my.hcl", schema)
30+
filepath := fmt.Sprintf("schemas/%s.my.hcl", schema)
3131
content, err := os.ReadFile(filepath)
3232
if err != nil {
3333
fmt.Println("Error reading file:", err)
@@ -45,7 +45,7 @@ func (cg *CodeGenerator) handleHclBlock(block *hclwrite.Block) error {
4545
return nil
4646
}
4747

48-
tableName := block.Labels()[0]
48+
tableName := CamelCase(block.Labels()[0])
4949
replacers := cg.generateDomainFromHclBlock(block, tableName)
5050
validateErr := cg.validateFiles(tableName)
5151
if validateErr != nil {
@@ -65,21 +65,21 @@ func (cg *CodeGenerator) generateDomainFromHclBlock(block *hclwrite.Block, table
6565
*cg.isIntId = false
6666
domain := cg.generateDomainStruct(block.Body().Blocks(), tableName, cg.primaryKey, cg.pkType)
6767
dataType := cg.generateStruct(block.Body().Blocks(), nil, nil, cg.generateDeclarationLine)
68-
createAttrData := cg.generateStruct(block.Body().Blocks(), nil, nil, cg.generateCreateAttributionLine)
69-
editAttrData := cg.generateStruct(block.Body().Blocks(), nil, nil, cg.generateCreateAttributionLine)
68+
createAttrData := cg.generateStruct(block.Body().Blocks(), nil, nil, cg.generateAttributionLine)
69+
editAttrData := cg.generateStruct(block.Body().Blocks(), nil, nil, cg.generateAttributionLine)
7070
replacers := GetReplacersConfig(cg.config, cg.domainType, []string{tableName})
7171
replacers["{{domainType}}"] = domain
7272
replacers["{{dataType}}"] = dataType
7373
replacers["{{pkDbName}}"] = *cg.primaryKey
74-
replacers["{{pkName}}"] = PascalCase(*cg.primaryKey)
74+
replacers["{{pkName}}"] = *cg.primaryKey
7575
replacers["{{pkType}}"] = *cg.pkType
7676
replacers["{{createServiceData}}"] = createAttrData
7777
replacers["{{editServiceData}}"] = editAttrData
7878
if *cg.needImportTime {
7979
replacers["{{optionalImports}}"] = "\"time\""
8080
}
8181
if !*cg.isIntId {
82-
replacers["{{idVar}}"] = "id := s.idCreator.Create()"
82+
replacers["{{idVar}}"] = "domain." + PascalCase(*cg.primaryKey) + " = s.idCreator.Create()"
8383
}
8484
return replacers
8585
}
@@ -88,13 +88,13 @@ func (cg *CodeGenerator) generateDomainStruct(blocks []*hclwrite.Block, tableNam
8888
*pk = cg.findPkOnBlocks(blocks)
8989
structString := "type " + PascalCase(tableName) + " struct {\n"
9090
structString += cg.generateStruct(blocks, pk, pkType, cg.generateDeclarationLine)
91-
structString += "\tclient string\n\tfilters *filters.Filters"
91+
structString += "\tclient string\n\tfilters *filters.Filters\n"
9292
structString += "}"
9393
return structString
9494
}
9595

9696
func (cg *CodeGenerator) generateStruct(blocks []*hclwrite.Block, pk, pkType *string, strFormationFunc func(string, string, string, string) string) string {
97-
declarationString := "\n"
97+
declarationString := ""
9898
for _, block := range blocks {
9999
if block.Type() == "column" {
100100
token, ok := block.Body().Attributes()["type"]
@@ -103,9 +103,14 @@ func (cg *CodeGenerator) generateStruct(blocks []*hclwrite.Block, pk, pkType *st
103103
}
104104
tokenStr := string(token.Expr().BuildTokens(nil).Bytes())
105105
goType := cg.dbTypesToGoTypes(tokenStr)
106+
nullable, nullOk := block.Body().Attributes()["null"]
107+
isNullable := cg.verifyIsNullable(nullable, nullOk)
108+
if isNullable {
109+
goType = "*" + goType
110+
}
106111

107112
if pk != nil && block.Labels()[0] == *pk {
108-
*pkType = fmt.Sprintf("%s string `param:\"id\"`", PascalCase(*pk))
113+
*pkType = fmt.Sprintf("%s string `param:\"id\"`\n", PascalCase(*pk))
109114
}
110115

111116
declarationString = strFormationFunc(
@@ -138,23 +143,12 @@ func (cg *CodeGenerator) generateDeclarationLine(str, name, goType, dbTag string
138143
)
139144
}
140145

141-
func (cg *CodeGenerator) generateCreateAttributionLine(str, name, _, _ string) string {
142-
if name == PascalCase(*cg.primaryKey) {
143-
return ""
144-
}
145-
return fmt.Sprintf(
146-
"{{domainCamelCase}}Data.%s = data.%s",
147-
str,
148-
name,
149-
)
150-
}
151-
152-
func (cg *CodeGenerator) generateEditAttributionLine(str, name, _, _ string) string {
146+
func (cg *CodeGenerator) generateAttributionLine(str, name, _, _ string) string {
153147
if name == PascalCase(*cg.primaryKey) {
154-
return ""
148+
return str
155149
}
156150
return fmt.Sprintf(
157-
"%s %s: data.%s,\n",
151+
"%s domain.%s = data.%s\n",
158152
str,
159153
name,
160154
name,
@@ -173,7 +167,7 @@ func (cg *CodeGenerator) findPkOnBlocks(blocks []*hclwrite.Block) string {
173167
str = cg.getColumnFromAttrString(pkAttr)
174168
}
175169
}
176-
return str
170+
return PascalCase(str)
177171
}
178172

179173
func (cg *CodeGenerator) getColumnFromAttrString(attrStr string) string {
@@ -185,52 +179,63 @@ func (cg *CodeGenerator) getColumnFromAttrString(attrStr string) string {
185179

186180
func (cg *CodeGenerator) dbTypesToGoTypes(typo string) string {
187181
dbTypesMap := map[string]string{
188-
" bigint": "*int64",
189-
" bit": "* ",
190-
" char": "*string",
191-
" decimal": "*float64",
192-
" float": "*float32",
193-
" double": "*float64",
194-
" int": "*int",
195-
" longtext": "*string",
196-
" mediumint": "*int",
197-
" mediumtext": "*string",
198-
" smallint": "*int16",
199-
" text": "*string",
200-
" time": "*string",
201-
" timestamp": "*string",
202-
" datetime": "*time.Time",
203-
" date": "*string",
204-
" tinyint": "*int8",
205-
" tinytext": "*string",
206-
" varbinary": "*string",
207-
" varchar": "*string",
208-
" json": "*string",
182+
" bigint": "int64",
183+
" bit": " ",
184+
" char": "string",
185+
" decimal": "float64",
186+
" float": "float32",
187+
" double": "float64",
188+
" int": "int",
189+
" longtext": "string",
190+
" mediumint": "int",
191+
" mediumtext": "string",
192+
" smallint": "int16",
193+
" text": "string",
194+
" time": "string",
195+
" timestamp": "string",
196+
" datetime": "time.Time",
197+
" date": "string",
198+
" tinyint": "int8",
199+
" tinytext": "string",
200+
" varbinary": "string",
201+
" varchar": "string",
202+
" json": "string",
209203
}
210204

211205
GolangType, ok := dbTypesMap[typo]
212206
if ok {
213-
if GolangType == "*time.Time" {
207+
if GolangType == "time.Time" {
214208
*cg.needImportTime = true
215209
}
216210
return GolangType
217211
}
218212

219213
if strings.Contains(typo, "char") {
220-
return "*string"
214+
return "string"
221215
}
222216

223217
if strings.Contains(typo, "double") {
224-
return "*float64"
218+
return "float64"
225219
}
226220

227221
if strings.Contains(typo, "year") {
228-
return "*string"
222+
return "string"
229223
}
230224

231225
if strings.Contains(typo, "decimal") {
232-
return "*float64"
226+
return "float64"
233227
}
234228

235229
return typo
236230
}
231+
232+
func (cg *CodeGenerator) verifyIsNullable(token *hclwrite.Attribute, ok bool) bool {
233+
if !ok {
234+
return false
235+
}
236+
value := token.Expr().BuildTokens(nil).Bytes()
237+
if string(value) == "true" {
238+
return true
239+
}
240+
return false
241+
}

tools/generator/stubs/crud/services/CREATE/service.go.stub

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func (s *Service) GetResponse() (*Response, *services.Error) {
3434
return s.response, s.Error
3535
}
3636

37-
func (s *Service) produceResponseRule(data *Data, {{domainCamelCase}}Data *{{domainCamelCase}}.{{domainPascalCase}}) {
37+
func (s *Service) produceResponseRule(data *Data, domain *{{domainCamelCase}}.{{domainPascalCase}}) {
3838
{{idVar}}
3939
{{createServiceData}}
4040

@@ -44,12 +44,12 @@ func (s *Service) produceResponseRule(data *Data, {{domainCamelCase}}Data *{{dom
4444
return
4545
}
4646

47-
err := s.repository.Create(*{{domainCamelCase}}Data, tx, true)
47+
err := s.repository.Create(*domain, tx, true)
4848
if err != nil {
4949
s.InternalServerError("error on create", err)
5050
return
5151
}
5252
s.response = &Response{
53-
Data: *{{domainCamelCase}}Data,
53+
Data: *domain,
5454
}
5555
}

tools/generator/stubs/crud/services/EDIT/service.go.stub

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ func (s *Service) GetResponse() (*Response, *services.Error) {
3333
return s.response, s.Error
3434
}
3535

36-
func (s *Service) produceResponseRule(id string, data *Data, {{domainCamelCase}}Data *{{domainCamelCase}}.{{domainPascalCase}}) {
37-
{{domainCamelCase}}Data.{{pkName}} = id
36+
func (s *Service) produceResponseRule(id string, data *Data, domain *{{domainCamelCase}}.{{domainPascalCase}}) {
37+
domain.{{pkName}} = id
3838
{{editServiceData}}
3939

40-
affected, err := s.repository.Edit(*{{domainCamelCase}}Data, "{{pkDbName}}", id)
40+
affected, err := s.repository.Edit(*domain, "{{pkDbName}}", id)
4141
if err != nil {
4242
s.InternalServerError("error on edit", err)
4343
return

tools/migrator/migrate.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ func (m *Migrator) Inspect() {
9696
fmt.Println(res)
9797
}
9898

99-
func (m *Migrator) Generate(schemaName string) {
99+
func (m *Migrator) Generate(schemaName string, database string) {
100100
workdir, err := atlasexec.NewWorkingDir(
101101
atlasexec.WithAtlasHCLPath("schemas/schema.my.hcl"),
102102
)
@@ -111,16 +111,18 @@ func (m *Migrator) Generate(schemaName string) {
111111
fmt.Printf("failed to initialize client: %v", err)
112112
return
113113
}
114-
114+
if database != "" {
115+
database = "/" + database
116+
}
115117
res, err := client.SchemaInspect(context.Background(), &atlasexec.SchemaInspectParams{
116118
DevURL: "mysql://" + m.dsnTest,
117-
URL: "mysql://" + m.dsn,
119+
URL: "mysql://" + m.dsn + database,
118120
})
119121
if err != nil {
120122
fmt.Printf("failed to inspect schema: %v", err)
121123
return
122124
}
123-
err = os.WriteFile("tools/migrator/schema/"+schemaName+".my.hcl", []byte(res), 0755)
125+
err = os.WriteFile("schemas/"+schemaName+".my.hcl", []byte(res), 0755)
124126
if err != nil {
125127
fmt.Println(err)
126128
return

0 commit comments

Comments
 (0)