Audit with AI
This commit is contained in:
@@ -9,11 +9,16 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
// version can be set at build time using:
|
||||
// go build -ldflags "-X main.version=v1.2.3" ./cmd
|
||||
var version = "dev"
|
||||
|
||||
func generate(scheamPath, outDir string) error {
|
||||
// read schame.sql
|
||||
f, err := os.ReadFile(scheamPath)
|
||||
@@ -29,14 +34,15 @@ func generate(scheamPath, outDir string) error {
|
||||
|
||||
// Output dir, create if not exists.
|
||||
if _, err := os.Stat(outDir); os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(outDir, 0740); err != nil {
|
||||
if err := os.MkdirAll(outDir, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// schema.go will hold all tables info
|
||||
var sb strings.Builder
|
||||
sb.WriteString("// Code generated by code.patial.tech/go/pgm/cmd DO NOT EDIT.\n\n")
|
||||
sb.WriteString(fmt.Sprintf("// Code generated by code.patial.tech/go/pgm/cmd %s on %s DO NOT EDIT.\n\n",
|
||||
GetVersionString(), time.Now().Format("2006-01-02 15:04:05")))
|
||||
sb.WriteString(fmt.Sprintf("package %s \n", filepath.Base(outDir)))
|
||||
sb.WriteString(`
|
||||
import "code.patial.tech/go/pgm"
|
||||
@@ -70,7 +76,7 @@ func generate(scheamPath, outDir string) error {
|
||||
sb.WriteString("}\n")
|
||||
}
|
||||
modalDir = strings.ToLower(name)
|
||||
os.Mkdir(filepath.Join(outDir, modalDir), 0740)
|
||||
os.Mkdir(filepath.Join(outDir, modalDir), 0755)
|
||||
|
||||
if err = writeColFile(t.Table, t.Columns, filepath.Join(outDir, modalDir), caser); err != nil {
|
||||
return err
|
||||
@@ -95,13 +101,14 @@ func generate(scheamPath, outDir string) error {
|
||||
}
|
||||
|
||||
// Save file to disk
|
||||
os.WriteFile(filepath.Join(outDir, "schema.go"), code, 0640)
|
||||
os.WriteFile(filepath.Join(outDir, "schema.go"), code, 0644)
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeColFile(tblName string, cols []*Column, outDir string, caser cases.Caser) error {
|
||||
var sb strings.Builder
|
||||
sb.WriteString("// Code generated by code.patial.tech/go/pgm/cmd DO NOT EDIT.\n\n")
|
||||
sb.WriteString(fmt.Sprintf("// Code generated by code.patial.tech/go/pgm/cmd %s on %s DO NOT EDIT.\n\n",
|
||||
GetVersionString(), time.Now().Format("2006-01-02 15:04:05")))
|
||||
sb.WriteString(fmt.Sprintf("package %s\n\n", filepath.Base(outDir)))
|
||||
sb.WriteString(fmt.Sprintf("import %q\n\n", "code.patial.tech/go/pgm"))
|
||||
sb.WriteString("const (")
|
||||
@@ -129,7 +136,7 @@ func writeColFile(tblName string, cols []*Column, outDir string, caser cases.Cas
|
||||
return err
|
||||
}
|
||||
// Save file to disk.
|
||||
return os.WriteFile(filepath.Join(outDir, tblName+".go"), code, 0640)
|
||||
return os.WriteFile(filepath.Join(outDir, tblName+".go"), code, 0644)
|
||||
}
|
||||
|
||||
// pluralToSingular converts plural table names to singular forms
|
||||
|
||||
21
cmd/main.go
21
cmd/main.go
@@ -9,29 +9,42 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
const usageTxt = `Please provide output director and input schema.
|
||||
var (
|
||||
showVersion bool
|
||||
)
|
||||
|
||||
const usageTxt = `Please provide output directory and input schema.
|
||||
Example:
|
||||
pgm/cmd -o ./db ./db/schema.sql
|
||||
pgm -o ./db ./schema.sql
|
||||
|
||||
`
|
||||
|
||||
func main() {
|
||||
var outDir string
|
||||
flag.StringVar(&outDir, "o", "", "-o as output directory path")
|
||||
flag.BoolVar(&showVersion, "version", false, "show version information")
|
||||
flag.Parse()
|
||||
|
||||
// Handle version flag
|
||||
if showVersion {
|
||||
fmt.Printf("pgm %s\n", GetVersionString())
|
||||
fmt.Println("PostgreSQL Query Mapper - Schema code generator")
|
||||
fmt.Println("https://code.patial.tech/go/pgm")
|
||||
return
|
||||
}
|
||||
if len(os.Args) < 4 {
|
||||
fmt.Print(usageTxt)
|
||||
return
|
||||
}
|
||||
|
||||
if outDir == "" {
|
||||
println("missing, -o output directory path")
|
||||
fmt.Fprintln(os.Stderr, "Error: missing output directory path (-o flag required)")
|
||||
os.Exit(1)
|
||||
return
|
||||
}
|
||||
|
||||
if err := generate(os.Args[3], outDir); err != nil {
|
||||
println(err.Error())
|
||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
15
cmd/parse.go
15
cmd/parse.go
@@ -1,5 +1,20 @@
|
||||
// Patial Tech.
|
||||
// Author, Ankit Patial
|
||||
//
|
||||
// SQL Parser Limitations:
|
||||
// This is a simple regex-based SQL parser with the following known limitations:
|
||||
// - No support for multi-line comments /* */
|
||||
// - May struggle with complex data types (e.g., arrays, JSON, JSONB)
|
||||
// - No handling of quoted identifiers with special characters
|
||||
// - Advanced features like PARTITION BY, INHERITS not supported
|
||||
// - Does not handle all PostgreSQL-specific syntax
|
||||
// - Constraints like CHECK, EXCLUDE not parsed
|
||||
//
|
||||
// For complex schemas, consider:
|
||||
// 1. Simplifying your schema for generation
|
||||
// 2. Using multiple simple CREATE TABLE statements
|
||||
// 3. Contributing a more robust parser implementation
|
||||
// 4. Using a proper SQL parser library
|
||||
|
||||
package main
|
||||
|
||||
|
||||
67
cmd/version.go
Normal file
67
cmd/version.go
Normal file
@@ -0,0 +1,67 @@
|
||||
// Patial Tech.
|
||||
// Author, Ankit Patial
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Version returns the version of the pgm CLI tool.
|
||||
// It tries to detect the version in the following order:
|
||||
// 1. Build-time ldflags (set via: go build -ldflags "-X main.version=v1.2.3")
|
||||
// 2. VCS information from build metadata (git tag/commit)
|
||||
// 3. Falls back to "dev" if no version information is available
|
||||
func Version() string {
|
||||
// If version was set at build time via ldflags
|
||||
if version != "" && version != "dev" {
|
||||
return version
|
||||
}
|
||||
|
||||
// Try to get version from build info (Go 1.18+)
|
||||
if info, ok := debug.ReadBuildInfo(); ok {
|
||||
// Check for version in main module
|
||||
if info.Main.Version != "" && info.Main.Version != "(devel)" {
|
||||
return info.Main.Version
|
||||
}
|
||||
|
||||
// Try to extract from VCS information
|
||||
var revision, modified string
|
||||
for _, setting := range info.Settings {
|
||||
switch setting.Key {
|
||||
case "vcs.revision":
|
||||
revision = setting.Value
|
||||
case "vcs.modified":
|
||||
modified = setting.Value
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a git revision
|
||||
if revision != "" {
|
||||
// Shorten commit hash to 7 characters
|
||||
if len(revision) > 7 {
|
||||
revision = revision[:7]
|
||||
}
|
||||
|
||||
// Add -dirty suffix if modified
|
||||
if modified == "true" {
|
||||
return "dev-" + revision + "-dirty"
|
||||
}
|
||||
return "dev-" + revision
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to dev
|
||||
return "dev"
|
||||
}
|
||||
|
||||
// GetVersionString returns a formatted version string for display
|
||||
func GetVersionString() string {
|
||||
v := Version()
|
||||
|
||||
// Clean up version string for display
|
||||
v = strings.TrimPrefix(v, "v")
|
||||
|
||||
return "v" + v
|
||||
}
|
||||
Reference in New Issue
Block a user