2 Commits
Author SHA1 Message Date
nikola 658718056e Add embed 2026-06-16 16:33:09 +02:00
nikola 0d45841bc6 Fix readme 2026-05-31 16:48:15 +02:00
2 changed files with 73 additions and 13 deletions
+3 -3
View File
@@ -14,13 +14,13 @@ A PostgreSQL schema migration tool that generates and applies migrations by comp
### As a Library ### As a Library
```bash ```bash
go get git.petrovv.com/go-migrate go get git.petrovv.com/nikola/go_sql_schema_migrate
``` ```
### CLI Tool ### CLI Tool
```bash ```bash
go install git.petrovv.com/go-migrate/cmd/go-migrate@latest go install git.petrovv.com/nikola/go_sql_schema_migrate/cmd/go-migrate@latest
``` ```
## Usage ## Usage
@@ -28,7 +28,7 @@ go install git.petrovv.com/go-migrate/cmd/go-migrate@latest
### Library ### Library
```go ```go
import "git.petrovv.com/go-migrate" import "git.petrovv.com/nikola/go_sql_schema_migrate"
ctx := context.Background() ctx := context.Background()
db, _ := pgxpool.New(ctx, "postgres://user:pass@localhost:5432/db") db, _ := pgxpool.New(ctx, "postgres://user:pass@localhost:5432/db")
+70 -10
View File
@@ -2,6 +2,7 @@ package go_sql_schema_migrate
import ( import (
"context" "context"
"embed"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
@@ -509,7 +510,7 @@ func parseAlterTableAddConstraint(schema *Schema, stmt string) {
} }
} }
func parseSchemaFile(schema *Schema, sql string) { func ParseSchemaFile(schema *Schema, sql string) {
// Split into statements // Split into statements
statements := strings.Split(sql, ";") statements := strings.Split(sql, ";")
@@ -548,7 +549,7 @@ func parseSchemaFile(schema *Schema, sql string) {
} }
} }
func loadSchemaFiles(dir string) ([]SchemaFile, error) { func LoadSchemaFiles(dir string) ([]SchemaFile, error) {
files, err := os.ReadDir(dir) files, err := os.ReadDir(dir)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -576,8 +577,8 @@ func loadSchemaFiles(dir string) ([]SchemaFile, error) {
return schemaFiles, nil return schemaFiles, nil
} }
func loadDesiredSchema(dir string) (*Schema, error) { func LoadDesiredSchema(dir string) (*Schema, error) {
files, err := loadSchemaFiles(dir) files, err := LoadSchemaFiles(dir)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -588,7 +589,7 @@ func loadDesiredSchema(dir string) (*Schema, error) {
} }
for _, f := range files { for _, f := range files {
parseSchemaFile(schema, f.SQL) ParseSchemaFile(schema, f.SQL)
} }
return schema, nil return schema, nil
@@ -981,11 +982,6 @@ func parseForeignKey(def string) *ForeignKey {
return fk return fk
} }
// LoadDesiredSchema loads schema definitions from SQL files in the given directory
func LoadDesiredSchema(dir string) (*Schema, error) {
return loadDesiredSchema(dir)
}
// GetMigrations compares the current database schema with the desired schema // GetMigrations compares the current database schema with the desired schema
// and returns a list of SQL migration statements // and returns a list of SQL migration statements
func GetMigrations(ctx context.Context, db *pgxpool.Pool, schemaDir string) ([]string, error) { func GetMigrations(ctx context.Context, db *pgxpool.Pool, schemaDir string) ([]string, error) {
@@ -1004,3 +1000,67 @@ func GetMigrations(ctx context.Context, db *pgxpool.Pool, schemaDir string) ([]s
// Compare and generate migration SQL // Compare and generate migration SQL
return CompareSchemas(currentSchema, desiredSchema), nil return CompareSchemas(currentSchema, desiredSchema), nil
} }
func LoadSchemaFilesEmbed(dir string, fs embed.FS) ([]SchemaFile, error) {
files, err := fs.ReadDir(dir)
if err != nil {
return nil, err
}
var schemaFiles []SchemaFile
for _, f := range files {
if !f.IsDir() && strings.HasSuffix(f.Name(), ".sql") {
content, err := fs.ReadFile(filepath.Join(dir, f.Name()))
if err != nil {
return nil, err
}
schemaFiles = append(schemaFiles, SchemaFile{
Name: f.Name(),
SQL: string(content),
})
}
}
// Sort by filename (natural sort for numbered files)
sort.Slice(schemaFiles, func(i, j int) bool {
return schemaFiles[i].Name < schemaFiles[j].Name
})
return schemaFiles, nil
}
func LoadDesiredSchemaEmbed(dir string, fs embed.FS) (*Schema, error) {
files, err := LoadSchemaFilesEmbed(dir, fs)
if err != nil {
return nil, err
}
schema := &Schema{
Types: make(map[string]string),
Tables: make(map[string]*Table),
}
for _, f := range files {
ParseSchemaFile(schema, f.SQL)
}
return schema, nil
}
// GetMigrationsEmbed compares the current database schema with the desired schema
// and returns a list of SQL migration statements
func GetMigrationsEmbed(ctx context.Context, db *pgxpool.Pool, schemaDir string, fs embed.FS) ([]string, error) {
// Load current database schema
currentSchema, err := GetCurrentSchema(ctx, db)
if err != nil {
return nil, fmt.Errorf("failed to get current schema: %w", err)
}
// Load desired schema from files
desiredSchema, err := LoadDesiredSchemaEmbed(schemaDir, fs)
if err != nil {
return nil, fmt.Errorf("failed to load desired schema: %w", err)
}
// Compare and generate migration SQL
return CompareSchemas(currentSchema, desiredSchema), nil
}