Рефакторинг

This commit is contained in:
Ymnuk 2023-07-26 16:19:28 +03:00
parent 6deb8f7c27
commit 49e39dbe0e
91 changed files with 390 additions and 188 deletions

View File

@ -13,6 +13,13 @@ basePath: /api
db:
sqlite: true
tables:
- id: d62df683-7e0c-4b96-b8e6-11c660f58ff8
name: test1
pk: uuid
fields:
- id: e14d5504-fc3b-4ea1-9b5d-22bfa77fce94
name: F1
type: text
- id: 5fb86d34-aada-409a-ac9d-29fd1f7c2d1b
name: test___test_1
pk: uuid
@ -51,6 +58,32 @@ backend:
- name: tile_server
type: string
help: Tile server for download tiles map
rest:
/reference/test1:
groupName: nogroup
data:
id: 00000000-0000-0000-0000-000000000000
name: db.test1
visible:
- id: 00000000-0000-0000-0000-000000000000
name: F1
filter:
- id: 00000000-0000-0000-0000-000000000000
name: F1
editable: true
fieldId:
id: 00000000-0000-0000-0000-000000000000
roles:
GET:
- APP_ADMIN
LIST:
- APP_ADMIN
POST:
- APP_ADMIN
PUT:
- APP_ADMIN
DELETE:
- APP_ADMIN
frontend:
lang: angular
theme: primeng/resources/themes/mdc-light-indigo/theme.css

View File

@ -6,6 +6,7 @@ import (
"path/filepath"
"strings"
"git.ymnuktech.ru/ymnuk/yt-gen-app/lib/templ"
"git.ymnuktech.ru/ymnuk/yt-gen-app/structs"
)
@ -115,7 +116,7 @@ func generateBackendTmpl() {
}
if len(staticTmpls) > 0 {
for _, staticTmpl := range staticTmpls {
if err := WriteTmplFile(staticTmpl.FileIn, staticTmpl.FileOut); err != nil {
if err := templ.WriteTmplFile(staticTmpl.FileIn, staticTmpl.FileOut); err != nil {
log.Fatal(err)
}
}
@ -124,82 +125,82 @@ func generateBackendTmpl() {
func generateModelBase() {
// main
if err := PrepareTmplFile("tmpl/backend/main.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "main.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/main.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "main.go")); err != nil {
log.Fatal(err)
}
if err := PrepareTmplFile("tmpl/backend/lib/config.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "lib", "config.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/lib/config.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "lib", "config.go")); err != nil {
log.Fatal(err)
}
// db
if err := PrepareTmplFile("tmpl/backend/db/model/user.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "db", "model", "user.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/db/model/user.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "db", "model", "user.go")); err != nil {
log.Fatal(err)
}
if err := PrepareTmplFile("tmpl/backend/db/db.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "db", "db.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/db/db.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "db", "db.go")); err != nil {
log.Fatal(err)
}
if len(Project.DB.Tables) > 0 {
for _, table := range Project.DB.Tables {
if err := PrepareTmplFile("tmpl/backend/db/model/model.tmpl", table, filepath.Join(AppConfig.OutdirBackend, "db", "model", strings.ToLower(table.Name)+".go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/db/model/model.tmpl", table, filepath.Join(AppConfig.OutdirBackend, "db", "model", strings.ToLower(table.Name)+".go")); err != nil {
log.Fatal(err)
}
}
}
// middleware
if err := PrepareTmplFile("tmpl/backend/middleware/middleware.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "middleware", "middleware.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/middleware/middleware.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "middleware", "middleware.go")); err != nil {
log.Fatal(err)
}
if err := PrepareTmplFile("tmpl/backend/middleware/in-role.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "middleware", "in-role.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/middleware/in-role.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "middleware", "in-role.go")); err != nil {
log.Fatal(err)
}
// route
if err := PrepareTmplFile("tmpl/backend/route/route.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "route.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/route/route.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "route.go")); err != nil {
log.Fatal(err)
}
// route/api
if err := PrepareTmplFile("tmpl/backend/route/api/index.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "index.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/route/api/index.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "index.go")); err != nil {
log.Fatal(err)
}
// route/api/auth
if err := PrepareTmplFile("tmpl/backend/route/api/auth/index.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "auth", "index.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/route/api/auth/index.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "auth", "index.go")); err != nil {
log.Fatal(err)
}
// route/api/user
if err := PrepareTmplFile("tmpl/backend/route/api/user/index.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "index.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/route/api/user/index.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "index.go")); err != nil {
log.Fatal(err)
}
if err := PrepareTmplFile("tmpl/backend/route/api/user/ldap-search.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "ldap-search.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/route/api/user/ldap-search.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "ldap-search.go")); err != nil {
log.Fatal(err)
}
if err := PrepareTmplFile("tmpl/backend/route/api/user/get.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "get.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/route/api/user/get.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "get.go")); err != nil {
log.Fatal(err)
}
if err := PrepareTmplFile("tmpl/backend/route/api/user/list-users.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "list-users.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/route/api/user/list-users.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "list-users.go")); err != nil {
log.Fatal(err)
}
if err := PrepareTmplFile("tmpl/backend/route/api/user/post.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "post.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/route/api/user/post.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "post.go")); err != nil {
log.Fatal(err)
}
if err := PrepareTmplFile("tmpl/backend/route/api/user/lock.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "lock.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/route/api/user/lock.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "lock.go")); err != nil {
log.Fatal(err)
}
if err := PrepareTmplFile("tmpl/backend/route/api/user/unlock.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "unlock.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/route/api/user/unlock.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "unlock.go")); err != nil {
log.Fatal(err)
}
if err := PrepareTmplFile("tmpl/backend/route/api/user/put.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "put.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/route/api/user/put.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "put.go")); err != nil {
log.Fatal(err)
}
if err := PrepareTmplFile("tmpl/backend/route/api/user/delete.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "delete.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/route/api/user/delete.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "delete.go")); err != nil {
log.Fatal(err)
}
// route/api/user/role
if err := PrepareTmplFile("tmpl/backend/route/api/user/role/index.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "role", "index.go")); err != nil {
if err := templ.PrepareTmplFile("tmpl/backend/route/api/user/role/index.tmpl", Project, filepath.Join(AppConfig.OutdirBackend, "route", "api", "user", "role", "index.go")); err != nil {
log.Fatal(err)
}

View File

@ -5,6 +5,8 @@ import (
"os/exec"
"path/filepath"
"strings"
"git.ymnuktech.ru/ymnuk/yt-gen-app/lib/templ"
)
func execCommands() {
@ -16,7 +18,7 @@ func execCommands() {
log.Fatal(cmd.Err)
}
if buff, err := content.ReadFile("tmpl/backend/go-list-module.txt"); err != nil {
if buff, err := templ.Content.ReadFile("tmpl/backend/go-list-module.txt"); err != nil {
log.Fatal(err)
} else {
strs := strings.Split(string(buff), "\n")

View File

@ -5,6 +5,7 @@ import (
"os"
"path/filepath"
"git.ymnuktech.ru/ymnuk/yt-gen-app/lib/templ"
"git.ymnuktech.ru/ymnuk/yt-gen-app/structs"
)
@ -205,7 +206,7 @@ func generateFrontendAngularTmpl() {
if len(staticTmpls) > 0 {
for _, staticTmpl := range staticTmpls {
if err := WriteTmplFile(staticTmpl.FileIn, staticTmpl.FileOut); err != nil {
if err := templ.WriteTmplFile(staticTmpl.FileIn, staticTmpl.FileOut); err != nil {
log.Fatal(err)
}
}

View File

@ -3,24 +3,25 @@ package lib
import (
"testing"
"git.ymnuktech.ru/ymnuk/yt-gen-app/lib/templ"
"git.ymnuktech.ru/ymnuk/yt-gen-app/structs"
)
func TestFieldType(t *testing.T) {
if fieldDBName(&structs.Field{Name: "Field"}) != "field" {
if templ.FieldDBName(&structs.Field{Name: "Field"}) != "field" {
t.Fail()
}
if fieldDBName(&structs.Field{Name: "Field_NAME"}) != "field_name" {
if templ.FieldDBName(&structs.Field{Name: "Field_NAME"}) != "field_name" {
t.Fail()
}
if fieldDBName(&structs.Field{Name: "fIELD_nAMe"}) != "field_name" {
if templ.FieldDBName(&structs.Field{Name: "fIELD_nAMe"}) != "field_name" {
t.Fail()
}
}
func TestDBModelAttrib(t *testing.T) {
str := fieldDescript(&structs.Field{
str := templ.FieldDescript(&structs.Field{
Name: "Field_naME1",
Type: "int",
Description: "Hello world",
@ -31,14 +32,14 @@ func TestDBModelAttrib(t *testing.T) {
}
func TestVarNameUpper(t *testing.T) {
if str := fieldNamePrepare("tile_server"); str != "TileServer" {
if str := templ.FieldNamePrepare("tile_server"); str != "TileServer" {
t.Error("Field name not equal")
return
}
}
func TestVarNameLower(t *testing.T) {
if str := fieldNameLowerPrepare("TileServer"); str != "tile_server" {
if str := templ.FieldNameLowerPrepare("TileServer"); str != "tile_server" {
t.Error("Field name not equal")
return
}

View File

@ -1,135 +1,10 @@
package lib
import (
"fmt"
"log"
"strings"
"git.ymnuktech.ru/ymnuk/yt-gen-app/lib/prepare"
"git.ymnuktech.ru/ymnuk/yt-gen-app/structs"
uuid "github.com/satori/go.uuid"
)
func PrepareMetadata(project *structs.Project) {
if project == nil {
log.Fatal("Metadata is empty")
}
if project.Name == "" {
log.Fatal("Should be set project name")
}
// Подготовка БД
if len(project.DB.Tables) > 0 {
for i := range project.DB.Tables {
if project.DB.Tables[i].ID == uuid.Nil {
project.DB.Tables[i].ID = uuid.NewV4()
}
if len(project.DB.Tables[i].Fields) > 0 {
for j := range project.DB.Tables[i].Fields {
project.DB.Tables[i].Fields[j].Name = fieldDBName(&project.DB.Tables[i].Fields[j])
if project.DB.Tables[i].Fields[j].ID == uuid.Nil {
project.DB.Tables[i].Fields[j].ID = uuid.NewV4()
}
project.DB.Tables[i].Fields[j].Type = strings.Trim(project.DB.Tables[i].Fields[j].Type, " ")
project.DB.Tables[i].Fields[j].Type = strings.ToLower(project.DB.Tables[i].Fields[j].Type)
if project.DB.Tables[i].Fields[j].Type == "" {
project.DB.Tables[i].Fields[j].Type = "text"
}
}
}
if project.DB.Tables[i].Recursive {
project.DB.Tables[i].FkFields = append(project.DB.Tables[i].FkFields, structs.Field{
Name: "parent",
Description: "Recursive foreign key for self table",
})
switch project.DB.Tables[i].Pk {
case "uuid":
project.DB.Tables[i].FkFields[len(project.DB.Tables[i].FkFields)-1].Type = "uuid"
case "int":
project.DB.Tables[i].FkFields[len(project.DB.Tables[i].FkFields)-1].Type = "bigint"
case "bigintint":
project.DB.Tables[i].FkFields[len(project.DB.Tables[i].FkFields)-1].Type = "bigint"
default:
log.Fatalf("Error primary key type '%s' in table '%s'", project.DB.Tables[i].Pk, project.DB.Tables[i].Name)
}
}
if len(project.DB.Tables[i].FKs) > 0 {
for j := range project.DB.Tables[i].FKs {
if project.DB.Tables[i].FKs[j].ID == uuid.Nil {
project.DB.Tables[i].FKs[j].ID = uuid.NewV4()
}
if project.DB.Tables[i].FKs[j].TableID == uuid.Nil && project.DB.Tables[i].FKs[j].TableName != "" {
for k := range project.DB.Tables {
if project.DB.Tables[k].Name == project.DB.Tables[i].FKs[j].TableName {
project.DB.Tables[i].FKs[j].TableID = project.DB.Tables[k].ID
project.DB.Tables[i].FKs[j].Type = project.DB.Tables[k].Pk
/*project.DB.Tables[i].FkFields = append(project.DB.Tables[i].FkFields, structs.Field{
Name: fmt.Sprintf("%s", project.DB.Tables[k].Name),
Type: project.DB.Tables[k].Pk,
})*/
}
}
}
if project.DB.Tables[i].FKs[j].TableID != uuid.Nil {
for k := range project.DB.Tables {
if project.DB.Tables[k].ID == project.DB.Tables[i].FKs[j].TableID {
project.DB.Tables[i].FKs[j].TableName = project.DB.Tables[k].Name
project.DB.Tables[k].Children = append(project.DB.Tables[k].Children, project.DB.Tables[i].Name)
}
}
}
if project.DB.Tables[i].FKs[j].TableName == "" {
log.Fatalf("Error foreign key for '%s' table", project.DB.Tables[i].FKs[j].TableID.String())
}
project.DB.Tables[i].FkFields = append(project.DB.Tables[i].FkFields, structs.Field{
Name: fmt.Sprintf("%s", strings.ToLower(project.DB.Tables[i].FKs[j].TableName)),
Type: project.DB.Tables[i].Pk,
Description: fmt.Sprintf("Foreign key for \\\"%s\\\" table", project.DB.Tables[i].FKs[j].TableName),
})
}
}
}
}
// Подготовка ролей
hasAppAdmin := false
hasSecAdmin := false
if len(project.Roles) > 0 {
for i := range project.Roles {
project.Roles[i].Name = strings.Trim(project.Roles[i].Name, " ")
if project.Roles[i].Name == "" {
log.Fatal("Should be set role name")
}
project.Roles[i].Name = strings.ReplaceAll(project.Roles[i].Name, " ", "_")
if project.Roles[i].ID == uuid.Nil {
project.Roles[i].ID = uuid.NewV4()
}
if project.Roles[i].Display == "" {
project.Roles[i].Display = project.Roles[i].Name
}
if project.Roles[i].Name == "APP_ADMIN" {
hasAppAdmin = true
}
if project.Roles[i].Name == "SEC_ADMIN" {
hasSecAdmin = true
}
}
}
if !hasAppAdmin {
project.Roles = append(project.Roles, structs.Role{
ID: uuid.NewV4(),
Name: "APP_ADMIN",
Display: "Администратор приложения",
})
}
if !hasSecAdmin {
project.Roles = append(project.Roles, structs.Role{
ID: uuid.NewV4(),
Name: "SEC_ADMIN",
Display: "Администратор безопасности",
})
}
project = prepare.PrepareMetadata(project)
}

84
lib/prepare/prepare-db.go Normal file
View File

@ -0,0 +1,84 @@
package prepare
import (
"fmt"
"log"
"strings"
"git.ymnuktech.ru/ymnuk/yt-gen-app/lib/templ"
"git.ymnuktech.ru/ymnuk/yt-gen-app/structs"
uuid "github.com/satori/go.uuid"
)
// Подготовка БД
func prepareDB(project *structs.Project) *structs.Project {
if len(project.DB.Tables) > 0 {
for i := range project.DB.Tables {
if project.DB.Tables[i].ID == uuid.Nil {
project.DB.Tables[i].ID = uuid.NewV4()
}
if len(project.DB.Tables[i].Fields) > 0 {
for j := range project.DB.Tables[i].Fields {
project.DB.Tables[i].Fields[j].Name = templ.FieldDBName(&project.DB.Tables[i].Fields[j])
if project.DB.Tables[i].Fields[j].ID == uuid.Nil {
project.DB.Tables[i].Fields[j].ID = uuid.NewV4()
}
project.DB.Tables[i].Fields[j].Type = strings.Trim(project.DB.Tables[i].Fields[j].Type, " ")
project.DB.Tables[i].Fields[j].Type = strings.ToLower(project.DB.Tables[i].Fields[j].Type)
if project.DB.Tables[i].Fields[j].Type == "" {
project.DB.Tables[i].Fields[j].Type = "text"
}
}
}
if project.DB.Tables[i].Recursive {
project.DB.Tables[i].FkFields = append(project.DB.Tables[i].FkFields, structs.Field{
Name: "parent",
Description: "Recursive foreign key for self table",
})
switch project.DB.Tables[i].Pk {
case "uuid":
project.DB.Tables[i].FkFields[len(project.DB.Tables[i].FkFields)-1].Type = "uuid"
case "int":
project.DB.Tables[i].FkFields[len(project.DB.Tables[i].FkFields)-1].Type = "bigint"
case "bigintint":
project.DB.Tables[i].FkFields[len(project.DB.Tables[i].FkFields)-1].Type = "bigint"
default:
log.Fatalf("Error primary key type '%s' in table '%s'", project.DB.Tables[i].Pk, project.DB.Tables[i].Name)
}
}
if len(project.DB.Tables[i].FKs) > 0 {
for j := range project.DB.Tables[i].FKs {
if project.DB.Tables[i].FKs[j].ID == uuid.Nil {
project.DB.Tables[i].FKs[j].ID = uuid.NewV4()
}
if project.DB.Tables[i].FKs[j].TableID == uuid.Nil && project.DB.Tables[i].FKs[j].TableName != "" {
for k := range project.DB.Tables {
if project.DB.Tables[k].Name == project.DB.Tables[i].FKs[j].TableName {
project.DB.Tables[i].FKs[j].TableID = project.DB.Tables[k].ID
project.DB.Tables[i].FKs[j].Type = project.DB.Tables[k].Pk
}
}
}
if project.DB.Tables[i].FKs[j].TableID != uuid.Nil {
for k := range project.DB.Tables {
if project.DB.Tables[k].ID == project.DB.Tables[i].FKs[j].TableID {
project.DB.Tables[i].FKs[j].TableName = project.DB.Tables[k].Name
project.DB.Tables[k].Children = append(project.DB.Tables[k].Children, project.DB.Tables[i].Name)
}
}
}
if project.DB.Tables[i].FKs[j].TableName == "" {
log.Fatalf("Error foreign key for '%s' table", project.DB.Tables[i].FKs[j].TableID.String())
}
project.DB.Tables[i].FkFields = append(project.DB.Tables[i].FkFields, structs.Field{
Name: fmt.Sprintf("%s", strings.ToLower(project.DB.Tables[i].FKs[j].TableName)),
Type: project.DB.Tables[i].Pk,
Description: fmt.Sprintf("Foreign key for \\\"%s\\\" table", project.DB.Tables[i].FKs[j].TableName),
})
}
}
}
}
return project
}

View File

@ -0,0 +1,23 @@
package prepare
import (
"log"
"git.ymnuktech.ru/ymnuk/yt-gen-app/structs"
)
func PrepareMetadata(project *structs.Project) *structs.Project {
if project == nil {
log.Fatal("Metadata is empty")
}
if project.Name == "" {
log.Fatal("Should be set project name")
}
project = prepareDB(project)
project = prepareRoles(project)
project = prepareRest(project)
return project
}

108
lib/prepare/prepare-rest.go Normal file
View File

@ -0,0 +1,108 @@
package prepare
import (
"log"
"strings"
"git.ymnuktech.ru/ymnuk/yt-gen-app/structs"
uuid "github.com/satori/go.uuid"
)
func prepareRest(project *structs.Project) *structs.Project {
if project == nil {
log.Fatal("Пустой проект")
}
if len(project.Backend.Rest) > 0 {
// Обрабатываем REST для подготовки данных
for i := range project.Backend.Rest {
if _, ok := project.Backend.Rest[i]; !ok {
log.Fatal("Нет пути в REST")
}
if project.Backend.Rest[i].Data.Name == "" && project.Backend.Rest[i].Data.ID == uuid.Nil {
log.Fatal("Не указан источник данных")
}
if project.Backend.Rest[i].Data.Name != "" && project.Backend.Rest[i].Data.ID == uuid.Nil {
// Есть имя, но нет ID. Найдем
dataArr := strings.Split(project.Backend.Rest[i].Data.Name, ".")
if len(dataArr) > 2 {
log.Fatal("Неверно указано имя источника данных в REST. Формат: <db/interface>.<Название>")
}
if len(dataArr) == 2 {
// Есть интерфейс
switch strings.ToLower(dataArr[0]) {
case "db":
project.Backend.Rest[i].Data.ID = findSourceDataInDBByName(project, dataArr[1])
case "interface":
project.Backend.Rest[i].Data.ID = findSourceDataInInterfaceByName(project, dataArr[1])
default:
log.Fatal("Неизвестный формат источника")
}
continue
}
if len(dataArr) == 1 {
// Нет интерфейса, по этому ищем где первым попадется
project.Backend.Rest[i].Data.ID = findSourceDataInDBByName(project, dataArr[1])
if project.Backend.Rest[i].Data.ID != uuid.Nil {
continue
}
project.Backend.Rest[i].Data.ID = findSourceDataInInterfaceByName(project, dataArr[1])
if project.Backend.Rest[i].Data.ID == uuid.Nil {
log.Fatal("Не найдена структура данных для REST")
}
continue
}
}
if project.Backend.Rest[i].Data.Name == "" && project.Backend.Rest[i].Data.ID != uuid.Nil {
// Есть имя, но нет ID. Найдем
project.Backend.Rest[i].Data.Name = findSourceDataInDBByID(project, project.Backend.Rest[i].Data.ID)
if project.Backend.Rest[i].Data.ID != uuid.Nil {
continue
}
project.Backend.Rest[i].Data.Name = findSourceDataInInterfaceByID(project, project.Backend.Rest[i].Data.ID)
if project.Backend.Rest[i].Data.ID == uuid.Nil {
log.Fatal("Не найдена структура данных для REST")
}
}
}
}
return project
}
// Найти ID таблицы по имени
func findSourceDataInDBByName(project *structs.Project, name string) uuid.UUID {
if len(project.DB.Tables) == 0 {
return uuid.Nil
}
for i := range project.DB.Tables {
if project.DB.Tables[i].Name == name {
return project.DB.Tables[i].ID
}
}
return uuid.Nil
}
// Найти имя таблицы по ID
func findSourceDataInDBByID(project *structs.Project, id uuid.UUID) string {
if len(project.DB.Tables) == 0 {
return ""
}
for i := range project.DB.Tables {
if project.DB.Tables[i].ID == id {
return project.DB.Tables[i].Name
}
}
return ""
}
func findSourceDataInInterfaceByName(project *structs.Project, name string) uuid.UUID {
// TODO
log.Fatal("Функция в разработки")
return uuid.Nil
}
func findSourceDataInInterfaceByID(project *structs.Project, id uuid.UUID) string {
// TODO
log.Fatal("Функция в разработки")
return ""
}

View File

@ -0,0 +1,54 @@
package prepare
import (
"log"
"strings"
"git.ymnuktech.ru/ymnuk/yt-gen-app/structs"
uuid "github.com/satori/go.uuid"
)
// Подготовка ролей
func prepareRoles(project *structs.Project) *structs.Project {
hasAppAdmin := false
hasSecAdmin := false
if len(project.Roles) > 0 {
for i := range project.Roles {
project.Roles[i].Name = strings.Trim(project.Roles[i].Name, " ")
if project.Roles[i].Name == "" {
log.Fatal("Should be set role name")
}
project.Roles[i].Name = strings.ReplaceAll(project.Roles[i].Name, " ", "_")
if project.Roles[i].ID == uuid.Nil {
project.Roles[i].ID = uuid.NewV4()
}
if project.Roles[i].Display == "" {
project.Roles[i].Display = project.Roles[i].Name
}
if project.Roles[i].Name == "APP_ADMIN" {
hasAppAdmin = true
}
if project.Roles[i].Name == "SEC_ADMIN" {
hasSecAdmin = true
}
}
}
if !hasAppAdmin {
project.Roles = append(project.Roles, structs.Role{
ID: uuid.NewV4(),
Name: "APP_ADMIN",
Display: "Администратор приложения",
})
}
if !hasSecAdmin {
project.Roles = append(project.Roles, structs.Role{
ID: uuid.NewV4(),
Name: "SEC_ADMIN",
Display: "Администратор безопасности",
})
}
return project
}

View File

@ -1,4 +1,4 @@
package lib
package templ
import (
"crypto/rand"

View File

@ -1,4 +1,4 @@
package lib
package templ
import (
"bufio"
@ -15,21 +15,21 @@ import (
)
//go:embed tmpl/*
var content embed.FS
var Content embed.FS
var funcMap = template.FuncMap{
"fieldName": fieldName,
"fieldNamePrepare": fieldNamePrepare,
"fieldNameLowerPrepare": fieldNameLowerPrepare,
"fieldType": fieldType,
"hasFieldType": hasFieldType,
"fieldDescript": fieldDescript,
"configParamName": configParamName,
"configParamType": configParamType,
"configParamTag": configParamTag,
"fieldName": FieldName,
"fieldNamePrepare": FieldNamePrepare,
"fieldNameLowerPrepare": FieldNameLowerPrepare,
"fieldType": FieldType,
"hasFieldType": HasFieldType,
"fieldDescript": FieldDescript,
"configParamName": ConfigParamName,
"configParamType": ConfigParamType,
"configParamTag": ConfigParamTag,
}
func fieldNamePrepare(value string) string {
func FieldNamePrepare(value string) string {
value = strings.Trim(value, " ")
if value == "" {
log.Fatal("Should be set name for field")
@ -52,7 +52,7 @@ func fieldNamePrepare(value string) string {
return value
}
func fieldNameLowerPrepare(value string) string {
func FieldNameLowerPrepare(value string) string {
var regexpForReplace = regexp.MustCompile(`([A-Z])`)
value = strings.ToLower(regexpForReplace.ReplaceAllString(value, "_$1"))
if []rune(value)[0] == '_' {
@ -62,7 +62,7 @@ func fieldNameLowerPrepare(value string) string {
return value
}
func fieldName(field *structs.Field) string {
func FieldName(field *structs.Field) string {
if field == nil {
log.Fatal("Field is null")
}
@ -70,12 +70,12 @@ func fieldName(field *structs.Field) string {
if field.Name == "" {
log.Fatal("Should be set name for field")
}
field.Name = fieldNamePrepare(field.Name)
field.Name = FieldNamePrepare(field.Name)
return field.Name
}
// Возвращает имя в БД
func fieldDBName(field *structs.Field) (res string) {
func FieldDBName(field *structs.Field) (res string) {
res = strings.Trim(field.Name, " ")
if res == "" {
log.Fatal("Shoudl be set name for field")
@ -84,7 +84,7 @@ func fieldDBName(field *structs.Field) (res string) {
return
}
func fieldType(field *structs.Field) string {
func FieldType(field *structs.Field) string {
if field == nil {
log.Fatal("field is empty")
}
@ -109,7 +109,7 @@ func fieldType(field *structs.Field) string {
return ""
}
func hasFieldType(fields []structs.Field, typeName string) (has bool) {
func HasFieldType(fields []structs.Field, typeName string) (has bool) {
for _, field := range fields {
if (field.Type == "date" || field.Type == "time") && (typeName == "date" || typeName == "time") {
return true
@ -121,7 +121,7 @@ func hasFieldType(fields []structs.Field, typeName string) (has bool) {
return false
}
func fieldTypeDB(field *structs.Field) string {
func FieldTypeDB(field *structs.Field) string {
field.Type = strings.ToLower(strings.Trim(field.Type, " "))
switch field.Type {
case "text":
@ -148,8 +148,8 @@ func fieldTypeDB(field *structs.Field) string {
}
// Генерирование описания таблиц в БД
func fieldDescript(field *structs.Field) (str string) {
str = fmt.Sprintf("`gorm:\"column:%s;type:%s", fieldDBName(field), fieldTypeDB(field))
func FieldDescript(field *structs.Field) (str string) {
str = fmt.Sprintf("`gorm:\"column:%s;type:%s", FieldDBName(field), FieldTypeDB(field))
field.Description = strings.Trim(field.Description, " ")
if field.Description != "" {
str += fmt.Sprintf(";comment:%s", field.Description)
@ -160,7 +160,7 @@ func fieldDescript(field *structs.Field) (str string) {
}
// Вернуть название параметра
func configParamName(field *structs.ParamConfig) string {
func ConfigParamName(field *structs.ParamConfig) string {
if field == nil {
log.Fatal("Field is null")
}
@ -168,11 +168,11 @@ func configParamName(field *structs.ParamConfig) string {
if field.Name == "" {
log.Fatal("Should be set name for field")
}
return fieldNamePrepare(field.Name)
return FieldNamePrepare(field.Name)
}
// Вернуть тип параметра
func configParamType(field *structs.ParamConfig) string {
func ConfigParamType(field *structs.ParamConfig) string {
if field == nil {
log.Fatal("Param should be set")
}
@ -190,7 +190,7 @@ func configParamType(field *structs.ParamConfig) string {
}
// Вернуть строку для тэгирования параметров
func configParamTag(field *structs.ParamConfig) string {
func ConfigParamTag(field *structs.ParamConfig) string {
if field == nil {
log.Fatal("Param should be set")
}
@ -214,7 +214,7 @@ func configParamTag(field *structs.ParamConfig) string {
func WriteTmplFile(filename string, outname string) error {
fmt.Printf("Generate: %s\n", outname)
if buff, err := content.ReadFile(filename); err != nil {
if buff, err := Content.ReadFile(filename); err != nil {
return err
} else {
if err = os.WriteFile(outname, buff, 0755); err != nil {
@ -230,7 +230,7 @@ func PrepareTmplFile(filename string, data interface{}, outname string) (err err
var (
buff []byte
)
if buff, err = content.ReadFile(filename); err != nil {
if buff, err = Content.ReadFile(filename); err != nil {
return err
}
var (

View File

Before

Width:  |  Height:  |  Size: 948 B

After

Width:  |  Height:  |  Size: 948 B

View File

@ -1,11 +1,31 @@
package structs
import uuid "github.com/satori/go.uuid"
type Backend struct {
Config []ParamConfig `yaml:"config" json:"config"` // Параметры, передаваемые при запуске сервера
Config []ParamConfig `yaml:"config,omitempty" json:"config,omitempty"` // Параметры, передаваемые при запуске сервера
Rest map[string]*Rest `yaml:"rest,omitempty" json:"rest,omitempty"` // Подготовка REST для сервера
RestGroups []string `yaml:"-" json:"-"` // Названия групп
}
type ParamConfig struct {
Name string `yaml:"name" json:"name"` // Название параметра
Type string `yaml:"type" json:"type"` // Тип параметра
Help string `yaml:"help" json:"help"` // Справка помощи параметра
Name string `yaml:"name" json:"name,omitempty" default:"param"` // Название параметра
Type string `yaml:"type" json:"type,omitempty" default:"string"` // Тип параметра
Help string `yaml:"help" json:"help,omitempty"` // Справка помощи параметра
}
type VisField struct {
ID uuid.UUID `yaml:"id,omitempty" json:"id,omitempty"`
Name string `yaml:"name,omitempty" json:"name,omitempty"`
}
type Rest struct {
GroupName string `yaml:"groupName,omitempty" json:"groupName,omitempty" default:"nogroup"` // Имя группы, в которую входит данный путь REST
Data VisField `yaml:"data,omitempty" json:"data,omitempty"` // Модель данных, на основе которой строиться запрос
Visible []VisField `yaml:"visible,omitempty" json:"visible,omitempty"` // Список видимых полей. Если указан хоть один, то отображаются только те, которые указаны, иначе отображаются все
Invisible []VisField `yaml:"invisible,omitempty" json:"invisible,omitempty"` // Список невидимых полей. Если указан хоть один, то отображаются все кроме указанного, иначе берется правило из поля "visible". Является приоритетным и в данном случае поле "visible" игнорируется
Filter []VisField `yaml:"filter,omitempty" json:"filter,omitempty"` // Указывается список полей, по которым будет осуществляться поиск
Editable bool `yaml:"editable,omitempty" json:"editable,omitempty"` // Модель является редактируемой, т.е. необходимо сгенерировать rest для данной модели. Для данного пути будут сформированы методы GET, POST, PUT и DELETE с соответствующим путем /<path>/{id}
FieldID VisField `yaml:"fieldId,omitempty" json:"fieldId,omitempty"` // Поле, которое является ключевым при работе с конкретной записью
Roles map[string][]string `yaml:"roles,omitempty" json:"roles,omitempty"` // Список ролей, которым разрешено работать с данным. Операция: массив строк с названием ролей. Если не указано, то все роли. Операция для просмотра списка: LIST
}