Add parseable `@<namespace>[(<target>)]: <args>` directives embedded in DBML.
They are stored losslessly on each object's Metadata, round-trip unchanged
through the DBML writer, and are translated to SQL only by the writer for the
matching dialect.
- models: Directive type + catalog; Metadata map added to Column and Index
- dbml reader: parse and attach directives at database/table/column/index
level; line-numbered errors; repeatable by default with singleton duplicate
detection. Fixes a preexisting bug where an `indexes {}` closing brace ended
the table early, dropping trailing Note: and directive lines.
- dbml writer: re-emit directives at their location; idempotent output
- pgsql writer: PARTITION BY / INHERITS / WITH / TABLESPACE (table),
STORAGE / COMPRESSION / identity (column), WITH / TABLESPACE (index)
- sqlite writer: WITHOUT ROWID / STRICT (table), COLLATE (column)
- --strict-directives flag on ReaderOptions and WriterOptions
- docs/DBML_DIRECTIVES.md + reader/writer READMEs
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ss2MY5J11cRGwEz86ZXk7d
95 lines
2.7 KiB
Go
95 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"runtime/debug"
|
|
"time"
|
|
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var (
|
|
// Version information, set via ldflags during build
|
|
version = "dev"
|
|
buildDate = "unknown"
|
|
prisma7 bool
|
|
noVersion bool
|
|
strictDirectives bool
|
|
)
|
|
|
|
func init() {
|
|
// If version wasn't set via ldflags, try to get it from build info
|
|
if version == "dev" {
|
|
if info, ok := debug.ReadBuildInfo(); ok {
|
|
// Try to get version from VCS
|
|
var vcsRevision, vcsTime string
|
|
for _, setting := range info.Settings {
|
|
switch setting.Key {
|
|
case "vcs.revision":
|
|
if len(setting.Value) >= 7 {
|
|
vcsRevision = setting.Value[:7]
|
|
}
|
|
case "vcs.time":
|
|
vcsTime = setting.Value
|
|
}
|
|
}
|
|
|
|
if vcsRevision != "" {
|
|
version = vcsRevision
|
|
}
|
|
|
|
if vcsTime != "" {
|
|
if t, err := time.Parse(time.RFC3339, vcsTime); err == nil {
|
|
buildDate = t.UTC().Format("2006-01-02 15:04:05 UTC")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var rootCmd = &cobra.Command{
|
|
Use: "relspec",
|
|
Short: "RelSpec - Database schema conversion and analysis tool",
|
|
Long: `RelSpec is a database relations specification tool that provides
|
|
bidirectional conversion between various database schema formats.
|
|
|
|
It reads database schemas from multiple sources (live databases, DBML,
|
|
DCTX, DrawDB, etc.) and writes them to various formats (GORM, Bun,
|
|
JSON, YAML, SQL, etc.).`,
|
|
}
|
|
|
|
func init() {
|
|
rootCmd.AddCommand(convertCmd)
|
|
rootCmd.AddCommand(diffCmd)
|
|
rootCmd.AddCommand(inspectCmd)
|
|
rootCmd.AddCommand(scriptsCmd)
|
|
rootCmd.AddCommand(jobCmd)
|
|
rootCmd.AddCommand(assetsCmd)
|
|
rootCmd.AddCommand(templCmd)
|
|
rootCmd.AddCommand(editCmd)
|
|
rootCmd.AddCommand(mergeCmd)
|
|
rootCmd.AddCommand(splitCmd)
|
|
rootCmd.AddCommand(versionCmd)
|
|
rootCmd.AddCommand(reportCmd)
|
|
rootCmd.PersistentFlags().BoolVar(&prisma7, "prisma7", false, "Use Prisma 7 generator conventions when reading/writing Prisma schemas")
|
|
rootCmd.PersistentFlags().BoolVar(&noVersion, "no-version", false, "Suppress the RelSpec version header")
|
|
rootCmd.PersistentFlags().BoolVar(&strictDirectives, "strict-directives", false, "Fail on unknown or untranslatable DBML dialect directives (@postgres:, @sqlite:, …)")
|
|
}
|
|
|
|
// printVersionHeader prints the "RelSpec <version> (built: <date>)" banner
|
|
// that precedes all command output. It is invoked from main() before cobra
|
|
// parses/executes anything, so it runs even for --help and bare invocations.
|
|
// It is skipped when --no-version is present, or when the version subcommand
|
|
// is being run (which prints its own, more detailed output).
|
|
func printVersionHeader(args []string) {
|
|
for _, a := range args {
|
|
if a == "--no-version" {
|
|
return
|
|
}
|
|
}
|
|
if len(args) > 0 && args[0] == "version" {
|
|
return
|
|
}
|
|
fmt.Printf("RelSpec %s (built: %s)\n\n", version, buildDate)
|
|
}
|