Files
relspecgo/pkg/writers/writer.go
Hein 5fb09b78c3
All checks were successful
CI / Test (1.24) (push) Successful in -25m5s
CI / Test (1.25) (push) Successful in -24m57s
CI / Build (push) Successful in -26m5s
CI / Lint (push) Successful in -25m51s
Integration Tests / Integration Tests (push) Successful in -25m42s
Release / Build and Release (push) Successful in -24m39s
feat(relations): 🎉 add flatten schema option for output
* Introduce `--flatten-schema` flag to convert, merge, and split commands.
* Modify database writing functions to support flattened schema names.
* Update template functions to handle schema.table naming convention.
* Enhance PostgreSQL writer to utilize flattened schema in generated SQL.
* Update tests to ensure compatibility with new flattening feature.
* Dependencies updated for improved functionality.
2026-02-05 14:07:55 +02:00

106 lines
3.7 KiB
Go

package writers
import (
"regexp"
"strings"
"git.warky.dev/wdevs/relspecgo/pkg/models"
)
// Writer defines the interface for writing database specifications
// to various output formats at different granularity levels
type Writer interface {
// WriteDatabase takes a Database model and writes it to the desired format
WriteDatabase(db *models.Database) error
// WriteSchema takes a Schema model and writes it to the desired format
WriteSchema(schema *models.Schema) error
// WriteTable takes a Table model and writes it to the desired format
WriteTable(table *models.Table) error
}
// WriterOptions contains common options for writers
type WriterOptions struct {
// OutputPath is the path where the output should be written
OutputPath string
// PackageName is the Go package name (for code generation)
PackageName string
// FlattenSchema disables schema.table dot notation and instead joins
// schema and table with an underscore (e.g., "public_users").
// Useful for databases like SQLite that do not support schemas.
FlattenSchema bool
// Additional options can be added here as needed
Metadata map[string]interface{}
}
// QualifiedTableName returns a schema-qualified table name.
// When flatten is true, schema and table are joined with underscore (e.g., "schema_table").
// When flatten is false, they are dot-separated (e.g., "schema.table").
// If schema is empty, just the table name is returned regardless of flatten.
func QualifiedTableName(schema, table string, flatten bool) string {
if schema == "" {
return table
}
if flatten {
return schema + "_" + table
}
return schema + "." + table
}
// SanitizeFilename removes quotes, comments, and invalid characters from identifiers
// to make them safe for use in filenames. This handles:
// - Double and single quotes: "table_name" or 'table_name' -> table_name
// - DBML comments: table [note: 'description'] -> table
// - Invalid filename characters: replaced with underscores
func SanitizeFilename(name string) string {
// Remove DBML/DCTX style comments in brackets (e.g., [note: 'description'])
commentRegex := regexp.MustCompile(`\s*\[.*?\]\s*`)
name = commentRegex.ReplaceAllString(name, "")
// Remove quotes (both single and double)
name = strings.ReplaceAll(name, `"`, "")
name = strings.ReplaceAll(name, `'`, "")
// Remove backticks (MySQL style identifiers)
name = strings.ReplaceAll(name, "`", "")
// Replace invalid filename characters with underscores
// Invalid chars: / \ : * ? " < > | and control characters
invalidChars := regexp.MustCompile(`[/\\:*?"<>|\x00-\x1f\x7f]`)
name = invalidChars.ReplaceAllString(name, "_")
// Trim whitespace and consecutive underscores
name = strings.TrimSpace(name)
name = regexp.MustCompile(`_+`).ReplaceAllString(name, "_")
name = strings.Trim(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
}