presta models

This commit is contained in:
2026-03-25 16:11:51 +01:00
parent 96383fce06
commit 7c5a993623
9 changed files with 394 additions and 38 deletions

25
app/cmd/cmds/genModels.go Normal file
View File

@@ -0,0 +1,25 @@
package cmds
import (
"context"
"log/slog"
"time"
"git.ma-al.com/goc_daniel/b2b/app/db"
genmodels "git.ma-al.com/goc_daniel/b2b/app/utils/genModels"
"github.com/spf13/cobra"
)
var generateModelsCmd = &cobra.Command{
Use: "genmodels",
Short: "generate input database models",
Run: func(cmd *cobra.Command, args []string) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5)
defer cancel()
err := genmodels.New(db.Get()).GormGenModels(ctx)
if err != nil {
slog.Error("Error performing work: " + err.Error())
}
},
}

View File

@@ -0,0 +1,60 @@
package cmds
import (
"log"
"os"
"git.ma-al.com/goc_daniel/b2b/app/delivery/web"
"git.ma-al.com/goc_daniel/b2b/app/service/langsService"
"git.ma-al.com/goc_daniel/b2b/app/utils/version"
"github.com/spf13/cobra"
)
var (
rootCmd = &cobra.Command{
Use: "b2b",
Short: "This is set of tools for b2b application",
Run: func(cmd *cobra.Command, args []string) {
if versionFlag, _ := cmd.Flags().GetBool("version"); versionFlag {
log.Println(version.String())
return
}
// Create and setup the server
server := web.New()
// Configure routes
if err := server.Setup(); err != nil {
log.Fatalf("Failed to setup server: %v", err)
}
// Load translations on startup
if err := langsService.LangSrv.LoadTranslations(); err != nil {
log.Printf("Warning: Failed to load translations on startup: %v", err)
} else {
log.Println("Translations loaded successfully on startup")
}
// Start the server
if err := server.Run(); err != nil {
log.Fatalf("Failed to start server: %v", err)
}
},
}
)
func Execute() error {
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
return nil
}
func init() {
rootCmd.Flags().BoolP("version", "v", false, "show version and exit")
rootCmd.AddCommand(generateModelsCmd)
}

View File

@@ -1,41 +1,9 @@
package main
import (
"flag"
"log"
"git.ma-al.com/goc_daniel/b2b/app/delivery/web"
"git.ma-al.com/goc_daniel/b2b/app/service/langsService"
"git.ma-al.com/goc_daniel/b2b/app/utils/version"
"git.ma-al.com/goc_daniel/b2b/app/cmd/cmds"
)
func main() {
// Check for version subcommand
versionFlag := flag.Bool("version", false, "Show version information")
flag.Parse()
if *versionFlag {
log.Println(version.String())
return
}
// Create and setup the server
server := web.New()
// Configure routes
if err := server.Setup(); err != nil {
log.Fatalf("Failed to setup server: %v", err)
}
// Load translations on startup
if err := langsService.LangSrv.LoadTranslations(); err != nil {
log.Printf("Warning: Failed to load translations on startup: %v", err)
} else {
log.Println("Translations loaded successfully on startup")
}
// Start the server
if err := server.Run(); err != nil {
log.Fatalf("Failed to start server: %v", err)
}
cmds.Execute()
}

View File

@@ -6,8 +6,12 @@ type Country struct {
Name string `gorm:"column:name" json:"name"`
Flag string `gorm:"size:16;not null;column:flag" json:"flag"`
CurrencyID uint `gorm:"column:id_currency" json:"currency_id"`
CurrencyISOCode string `gorm:"column:currency_iso_code" json:"currency_iso_code"`
CurrencyName string `gorm:"column:currency_name" json:"currency_name"`
CurrencyISOCode string `gorm:"column:iso_code" json:"currency_iso_code"`
CurrencyName string `gorm:"column:name" json:"currency_name"`
// PSCountryID int `gorm:"column:id_country" json:"ps_country_id"`
// PSCountry *PSCountry `gorm:"foreignKey:PSCountryID;references:ID" json:"ps_country"`
PSCurrencyID uint `gorm:"column:currency" json:"currency"`
PSCurrency *PSCurrency `gorm:"foreignKey:PSCurrencyID;references:currency_id" json:"ps_currency"`
}
func (Country) TableName() string {
@@ -15,10 +19,13 @@ func (Country) TableName() string {
}
type PSCountry struct {
ID uint `gorm:"primaryKey;column:id_country" json:"id"`
CurrencyID uint `gorm:"column:id_currency" json:"currency_id"`
}
func (PSCountry) TableName() string {
return "ps_country"
}
type PSCurrency struct {
Currency int `gorm:"column:currency" json:"currency"`
}

View File

@@ -79,6 +79,7 @@ func (s *MenuService) createTree(index int, all_categories *([]model.ScannedCate
}
func (s *MenuService) GetRoutes(id_lang uint) ([]model.Route, error) {
return s.routesRepo.GetRoutes(id_lang)
}

View File

@@ -0,0 +1,188 @@
package genmodels
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"gorm.io/gen"
"gorm.io/gen/field"
"gorm.io/gorm"
)
const GENERATED_FILES_FOLDER = "./app/model/prestadb"
const GENERATED_MODEL_PKG = "prestadb"
type GormGenModels struct {
db *gorm.DB
}
func New(db *gorm.DB) *GormGenModels {
return &GormGenModels{
db: db,
}
}
func (m *GormGenModels) GormGenModels(ctx context.Context) error {
// Use gorm gen to generate models
g := gen.NewGenerator(gen.Config{
OutPath: GENERATED_FILES_FOLDER,
ModelPkgPath: GENERATED_MODEL_PKG,
Mode: gen.WithoutContext,
})
g.UseDB(m.db)
// Get all table names from the database and filter for 'ps_' prefix
tableNames, err := m.db.Migrator().GetTables()
if err != nil {
return fmt.Errorf("failed to get table list: %w", err)
}
// Generate models only for tables with 'ps_' prefix
// Use gen.FieldRelateModel to add foreign key relations
for _, tableName := range tableNames {
if strings.HasPrefix(tableName, "ps_") {
g.GenerateModel(tableName, gen.FieldRelateModel(field.BelongsTo, "*", nil, &field.RelateConfig{}))
}
}
g.Execute()
// Post-process: remove query/DO files and keep only model files
if err := m.cleanupGeneratedFiles(); err != nil {
return fmt.Errorf("failed to cleanup generated files: %w", err)
}
return nil
}
func (m *GormGenModels) cleanupGeneratedFiles() error {
// Files to remove (query/DO code)
filesToRemove := []string{
"gen.go",
"do.go",
"_gen.go",
}
// Directory to clean
dir := GENERATED_FILES_FOLDER
if !strings.HasPrefix(dir, "./") {
dir = "./" + dir
}
// Get absolute path if needed
absDir, err := filepath.Abs(dir)
if err != nil {
return err
}
// Remove query files
for _, fileName := range filesToRemove {
filePath := filepath.Join(absDir, fileName)
if _, err := os.Stat(filePath); err == nil {
if err := os.Remove(filePath); err != nil {
return fmt.Errorf("failed to remove %s: %w", filePath, err)
}
fmt.Printf("Removed: %s\n", filePath)
}
}
// Rename ps_*.gen.go to *.go (e.g., ps_category.gen.go -> category.go)
files, err := os.ReadDir(absDir)
if err != nil {
return err
}
for _, file := range files {
name := file.Name()
// Check if it's a generated model file like ps_category.gen.go
if strings.HasSuffix(name, ".gen.go") && strings.HasPrefix(name, "ps_") {
oldPath := filepath.Join(absDir, name)
// Extract name: ps_category.gen.go -> category
baseName := strings.TrimSuffix(name, ".gen.go")
baseName, _ = strings.CutPrefix(baseName, "ps_")
newPath := filepath.Join(absDir, baseName+".go")
// Read file content
content, err := os.ReadFile(oldPath)
if err != nil {
return err
}
// Remove package prestadb imports that reference generated DO
// and clean up the code
content = m.cleanModelContent(content)
// Write to new file
if err := os.WriteFile(newPath, content, 0644); err != nil {
return err
}
// Remove old file
if err := os.Remove(oldPath); err != nil {
return err
}
fmt.Printf("Renamed: %s -> %s\n", oldPath, newPath)
}
}
return nil
}
func (m *GormGenModels) cleanModelContent(content []byte) []byte {
result := string(content)
// Remove imports that are only needed for query code
// Keep "gorm.io/gorm/schema" for TableName method
lines := strings.Split(result, "\n")
var newLines []string
importStarted := false
importEnded := false
for _, line := range lines {
trimmed := strings.TrimSpace(line)
// Track import block
if trimmed == "import (" {
importStarted = true
newLines = append(newLines, line)
continue
}
if importStarted && trimmed == ")" {
importEnded = true
importStarted = false
newLines = append(newLines, line)
continue
}
// Inside import block, remove query-related imports
if importStarted && !importEnded {
// Skip these imports as they're only for query code
if strings.Contains(trimmed, "\"gorm.io/gen\"") ||
strings.Contains(trimmed, "\"gorm.io/gen/field\"") ||
strings.Contains(trimmed, "\"gorm.io/plugin/dbresolver\"") ||
strings.Contains(trimmed, "gen.DO") {
continue
}
}
// Remove DO (Data Object) type definitions
if strings.Contains(trimmed, "type psCategoryDo struct") ||
strings.HasPrefix(trimmed, "func (p psCategoryDo)") {
continue
}
newLines = append(newLines, line)
}
result = strings.Join(newLines, "\n")
// Also remove the psCategoryDo references in methods
result = strings.ReplaceAll(result, "psCategoryDo", "")
return []byte(result)
}