Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b20ad35485 |
@@ -5,6 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
||||||
|
"git.warky.dev/wdevs/relspecgo/pkg/writers"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TemplateData represents the data passed to the template for code generation
|
// TemplateData represents the data passed to the template for code generation
|
||||||
@@ -133,8 +134,10 @@ func NewModelData(table *models.Table, schema string, typeMapper *TypeMapper) *M
|
|||||||
// Find primary key
|
// Find primary key
|
||||||
for _, col := range table.Columns {
|
for _, col := range table.Columns {
|
||||||
if col.IsPrimaryKey {
|
if col.IsPrimaryKey {
|
||||||
model.PrimaryKeyField = SnakeCaseToPascalCase(col.Name)
|
// Sanitize column name to remove backticks
|
||||||
model.IDColumnName = col.Name
|
safeName := writers.SanitizeStructTagValue(col.Name)
|
||||||
|
model.PrimaryKeyField = SnakeCaseToPascalCase(safeName)
|
||||||
|
model.IDColumnName = safeName
|
||||||
// Check if PK type is a SQL type (contains resolvespec_common or sql_types)
|
// Check if PK type is a SQL type (contains resolvespec_common or sql_types)
|
||||||
goType := typeMapper.SQLTypeToGoType(col.Type, col.NotNull)
|
goType := typeMapper.SQLTypeToGoType(col.Type, col.NotNull)
|
||||||
model.PrimaryKeyIsSQL = strings.Contains(goType, "resolvespec_common") || strings.Contains(goType, "sql_types")
|
model.PrimaryKeyIsSQL = strings.Contains(goType, "resolvespec_common") || strings.Contains(goType, "sql_types")
|
||||||
@@ -154,10 +157,13 @@ func NewModelData(table *models.Table, schema string, typeMapper *TypeMapper) *M
|
|||||||
|
|
||||||
// columnToField converts a models.Column to FieldData
|
// columnToField converts a models.Column to FieldData
|
||||||
func columnToField(col *models.Column, table *models.Table, typeMapper *TypeMapper) *FieldData {
|
func columnToField(col *models.Column, table *models.Table, typeMapper *TypeMapper) *FieldData {
|
||||||
fieldName := SnakeCaseToPascalCase(col.Name)
|
// Sanitize column name first to remove backticks before generating field name
|
||||||
|
safeName := writers.SanitizeStructTagValue(col.Name)
|
||||||
|
fieldName := SnakeCaseToPascalCase(safeName)
|
||||||
goType := typeMapper.SQLTypeToGoType(col.Type, col.NotNull)
|
goType := typeMapper.SQLTypeToGoType(col.Type, col.NotNull)
|
||||||
bunTag := typeMapper.BuildBunTag(col, table)
|
bunTag := typeMapper.BuildBunTag(col, table)
|
||||||
jsonTag := col.Name // Use column name for JSON tag
|
// Use same sanitized name for JSON tag
|
||||||
|
jsonTag := safeName
|
||||||
|
|
||||||
return &FieldData{
|
return &FieldData{
|
||||||
Name: fieldName,
|
Name: fieldName,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
||||||
|
"git.warky.dev/wdevs/relspecgo/pkg/writers"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TypeMapper handles type conversions between SQL and Go types for Bun
|
// TypeMapper handles type conversions between SQL and Go types for Bun
|
||||||
@@ -164,11 +165,14 @@ func (tm *TypeMapper) BuildBunTag(column *models.Column, table *models.Table) st
|
|||||||
var parts []string
|
var parts []string
|
||||||
|
|
||||||
// Column name comes first (no prefix)
|
// Column name comes first (no prefix)
|
||||||
parts = append(parts, column.Name)
|
// Sanitize to remove backticks which would break struct tag syntax
|
||||||
|
safeName := writers.SanitizeStructTagValue(column.Name)
|
||||||
|
parts = append(parts, safeName)
|
||||||
|
|
||||||
// Add type if specified
|
// Add type if specified
|
||||||
if column.Type != "" {
|
if column.Type != "" {
|
||||||
typeStr := column.Type
|
// Sanitize type to remove backticks
|
||||||
|
typeStr := writers.SanitizeStructTagValue(column.Type)
|
||||||
if column.Length > 0 {
|
if column.Length > 0 {
|
||||||
typeStr = fmt.Sprintf("%s(%d)", typeStr, column.Length)
|
typeStr = fmt.Sprintf("%s(%d)", typeStr, column.Length)
|
||||||
} else if column.Precision > 0 {
|
} else if column.Precision > 0 {
|
||||||
@@ -188,7 +192,9 @@ func (tm *TypeMapper) BuildBunTag(column *models.Column, table *models.Table) st
|
|||||||
|
|
||||||
// Default value
|
// Default value
|
||||||
if column.Default != nil {
|
if column.Default != nil {
|
||||||
parts = append(parts, fmt.Sprintf("default:%v", column.Default))
|
// Sanitize default value to remove backticks
|
||||||
|
safeDefault := writers.SanitizeStructTagValue(fmt.Sprintf("%v", column.Default))
|
||||||
|
parts = append(parts, fmt.Sprintf("default:%s", safeDefault))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nullable (Bun uses nullzero for nullable fields)
|
// Nullable (Bun uses nullzero for nullable fields)
|
||||||
@@ -263,7 +269,7 @@ func (tm *TypeMapper) NeedsFmtImport(generateGetIDStr bool) bool {
|
|||||||
|
|
||||||
// GetSQLTypesImport returns the import path for sql_types (ResolveSpec common)
|
// GetSQLTypesImport returns the import path for sql_types (ResolveSpec common)
|
||||||
func (tm *TypeMapper) GetSQLTypesImport() string {
|
func (tm *TypeMapper) GetSQLTypesImport() string {
|
||||||
return "github.com/bitechdev/ResolveSpec/pkg/common"
|
return "github.com/bitechdev/ResolveSpec/pkg/spectypes"
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBunImport returns the import path for Bun
|
// GetBunImport returns the import path for Bun
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
||||||
|
"git.warky.dev/wdevs/relspecgo/pkg/writers"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TemplateData represents the data passed to the template for code generation
|
// TemplateData represents the data passed to the template for code generation
|
||||||
@@ -131,8 +132,10 @@ func NewModelData(table *models.Table, schema string, typeMapper *TypeMapper) *M
|
|||||||
// Find primary key
|
// Find primary key
|
||||||
for _, col := range table.Columns {
|
for _, col := range table.Columns {
|
||||||
if col.IsPrimaryKey {
|
if col.IsPrimaryKey {
|
||||||
model.PrimaryKeyField = SnakeCaseToPascalCase(col.Name)
|
// Sanitize column name to remove backticks
|
||||||
model.IDColumnName = col.Name
|
safeName := writers.SanitizeStructTagValue(col.Name)
|
||||||
|
model.PrimaryKeyField = SnakeCaseToPascalCase(safeName)
|
||||||
|
model.IDColumnName = safeName
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,10 +152,13 @@ func NewModelData(table *models.Table, schema string, typeMapper *TypeMapper) *M
|
|||||||
|
|
||||||
// columnToField converts a models.Column to FieldData
|
// columnToField converts a models.Column to FieldData
|
||||||
func columnToField(col *models.Column, table *models.Table, typeMapper *TypeMapper) *FieldData {
|
func columnToField(col *models.Column, table *models.Table, typeMapper *TypeMapper) *FieldData {
|
||||||
fieldName := SnakeCaseToPascalCase(col.Name)
|
// Sanitize column name first to remove backticks before generating field name
|
||||||
|
safeName := writers.SanitizeStructTagValue(col.Name)
|
||||||
|
fieldName := SnakeCaseToPascalCase(safeName)
|
||||||
goType := typeMapper.SQLTypeToGoType(col.Type, col.NotNull)
|
goType := typeMapper.SQLTypeToGoType(col.Type, col.NotNull)
|
||||||
gormTag := typeMapper.BuildGormTag(col, table)
|
gormTag := typeMapper.BuildGormTag(col, table)
|
||||||
jsonTag := col.Name // Use column name for JSON tag
|
// Use same sanitized name for JSON tag
|
||||||
|
jsonTag := safeName
|
||||||
|
|
||||||
return &FieldData{
|
return &FieldData{
|
||||||
Name: fieldName,
|
Name: fieldName,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
||||||
|
"git.warky.dev/wdevs/relspecgo/pkg/writers"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TypeMapper handles type conversions between SQL and Go types
|
// TypeMapper handles type conversions between SQL and Go types
|
||||||
@@ -199,12 +200,15 @@ func (tm *TypeMapper) BuildGormTag(column *models.Column, table *models.Table) s
|
|||||||
var parts []string
|
var parts []string
|
||||||
|
|
||||||
// Always include column name (lowercase as per user requirement)
|
// Always include column name (lowercase as per user requirement)
|
||||||
parts = append(parts, fmt.Sprintf("column:%s", column.Name))
|
// Sanitize to remove backticks which would break struct tag syntax
|
||||||
|
safeName := writers.SanitizeStructTagValue(column.Name)
|
||||||
|
parts = append(parts, fmt.Sprintf("column:%s", safeName))
|
||||||
|
|
||||||
// Add type if specified
|
// Add type if specified
|
||||||
if column.Type != "" {
|
if column.Type != "" {
|
||||||
// Include length, precision, scale if present
|
// Include length, precision, scale if present
|
||||||
typeStr := column.Type
|
// Sanitize type to remove backticks
|
||||||
|
typeStr := writers.SanitizeStructTagValue(column.Type)
|
||||||
if column.Length > 0 {
|
if column.Length > 0 {
|
||||||
typeStr = fmt.Sprintf("%s(%d)", typeStr, column.Length)
|
typeStr = fmt.Sprintf("%s(%d)", typeStr, column.Length)
|
||||||
} else if column.Precision > 0 {
|
} else if column.Precision > 0 {
|
||||||
@@ -234,7 +238,9 @@ func (tm *TypeMapper) BuildGormTag(column *models.Column, table *models.Table) s
|
|||||||
|
|
||||||
// Default value
|
// Default value
|
||||||
if column.Default != nil {
|
if column.Default != nil {
|
||||||
parts = append(parts, fmt.Sprintf("default:%v", column.Default))
|
// Sanitize default value to remove backticks
|
||||||
|
safeDefault := writers.SanitizeStructTagValue(fmt.Sprintf("%v", column.Default))
|
||||||
|
parts = append(parts, fmt.Sprintf("default:%s", safeDefault))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for unique constraint
|
// Check for unique constraint
|
||||||
@@ -331,5 +337,5 @@ func (tm *TypeMapper) NeedsFmtImport(generateGetIDStr bool) bool {
|
|||||||
|
|
||||||
// GetSQLTypesImport returns the import path for sql_types
|
// GetSQLTypesImport returns the import path for sql_types
|
||||||
func (tm *TypeMapper) GetSQLTypesImport() string {
|
func (tm *TypeMapper) GetSQLTypesImport() string {
|
||||||
return "github.com/bitechdev/ResolveSpec/pkg/common/sql_types"
|
return "github.com/bitechdev/ResolveSpec/pkg/spectypes"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,3 +61,26 @@ func SanitizeFilename(name string) string {
|
|||||||
|
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SanitizeStructTagValue sanitizes a value to be safely used inside Go struct tags.
|
||||||
|
// Go struct tags are delimited by backticks, so any backtick in the value would break the syntax.
|
||||||
|
// This function:
|
||||||
|
// - Removes DBML/DCTX comments in brackets
|
||||||
|
// - Removes all quotes (double, single, and backticks)
|
||||||
|
// - Returns a clean identifier safe for use in struct tags and field names
|
||||||
|
func SanitizeStructTagValue(value string) string {
|
||||||
|
// Remove DBML/DCTX style comments in brackets (e.g., [note: 'description'])
|
||||||
|
commentRegex := regexp.MustCompile(`\s*\[.*?\]\s*`)
|
||||||
|
value = commentRegex.ReplaceAllString(value, "")
|
||||||
|
|
||||||
|
// Trim whitespace
|
||||||
|
value = strings.TrimSpace(value)
|
||||||
|
|
||||||
|
// Remove all quotes: backticks, double quotes, and single quotes
|
||||||
|
// This ensures the value is clean for use as Go identifiers and struct tag values
|
||||||
|
value = strings.ReplaceAll(value, "`", "")
|
||||||
|
value = strings.ReplaceAll(value, `"`, "")
|
||||||
|
value = strings.ReplaceAll(value, `'`, "")
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user