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 // Additional options can be added here as needed Metadata map[string]interface{} } // 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 }