Skip to content

Commit

Permalink
Update migrations.
Browse files Browse the repository at this point in the history
* Remove old migrations.
* Make goose table replicated.
* Allow custom migration names.
* Update README.md
  • Loading branch information
KevinJoiner committed Apr 24, 2024
1 parent bac3531 commit 93cc109
Show file tree
Hide file tree
Showing 15 changed files with 85 additions and 348 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ format:
@golangci-lint run --fix

migration: build
./bin/codegen -output=./pkg/migrations -package=migrations -generators=migration
./bin/codegen -output=./pkg/migrations -package=migrations -generators=migration -migration.file-name="${name}"

tools-golangci-lint:
@mkdir -p bin
Expand Down
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@ Welcome to the **Model Garage**, a Golang toolkit for managing and working with

## Features

1. **Model Creation**: Create models from vspec CSV schemas, represented as Go structs and matching Clickhouse tables.

1. **Model Creation**: Create models from vspec CSV schemas, represented as Go structs.
2. **JSON Conversion**: Easily convert JSON data for your models with automatically generated and customizable conversion functions.

3. **Random Data Generation**: [**Coming Soon**] Quickly generate models populated with random data for testing or sample data.
## Migrations

To create a new migration, run the following command:

```bash
Make migration name=<migration_name>
```

This will create a new migration file the given name in the `migrations` directory.
this creation should be used over the goose binary to ensure expected behavior of embedded migrations.

## Repo structure

Expand All @@ -32,7 +39,7 @@ go run github.com/DIMO-Network/model-garage/cmd/codegen -output=pkg/vss -genera
The Model generation is handled by packages in `internal/codegen`. They are responsible for creating Go structs, Clickhouse tables, and conversion functions from the vspec CSV schema and definitions file. definitions file is a YAML file that specifies the conversions for each field in the vspec schema. The conversion functions are meant to be overridden with custom logic as needed. When generation is re-run, the conversion functions are not overwritten. Below is an example of a definitions file:

```yaml
# vspecName: The name of the VSpec field in the VSS schema
# vspecName: The name of the VSpec field in the VSS schema
- vspecName: DIMO.DefinitionID

# isArray: Whether the field is an array or not
Expand Down Expand Up @@ -67,7 +74,6 @@ The Model generation is handled by packages in `internal/codegen`. They are resp
- VehicleNonLocationData
```
##### Generation Process
1. First, the vspec CSV schema and definitions file are parsed.
Expand All @@ -77,4 +83,3 @@ The Model generation is handled by packages in `internal/codegen`. They are resp

**Conversion Functions**
For each field, a conversion function is created. If a conversion is specified in the definitions file, the conversion function will use the specified conversion. If no conversion is specified, the conversion info function will assume a direct copy. The conversion functions are meant to be overridden with custom logic as needed. When generation is re-run, the conversion functions are not overwritten.

7 changes: 7 additions & 0 deletions cmd/codegen/codegen.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/DIMO-Network/model-garage/internal/codegen/convert"
"github.com/DIMO-Network/model-garage/internal/codegen/graphql"
"github.com/DIMO-Network/model-garage/internal/codegen/migration"
"github.com/DIMO-Network/model-garage/pkg/runner"
"github.com/DIMO-Network/model-garage/schema"
)
Expand All @@ -28,6 +29,9 @@ func main() {
// GQL flags
gqlOutFile := flag.String("graphql.output-file", "", "Path of the generate gql file that is appened to the outputDir.")
gqlTemplateFile := flag.String("graphql.template-file", "", "Path to the template file. Which is executed with codegen.TemplateData data.")
// Migration flags
migrationFileName := flag.String("migration.file-name", "", "Name of the migration file. Default is the model name.")

flag.Parse()

var vspecReader io.Reader
Expand Down Expand Up @@ -67,6 +71,9 @@ func main() {
Convert: convert.Config{
WithTest: *withTest,
},
Migration: migration.Config{
FileName: *migrationFileName,
},
}

err := runner.Execute(vspecReader, definitionReader, gens, cfg)
Expand Down
43 changes: 32 additions & 11 deletions internal/codegen/migration/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,38 @@ import (
"time"

"github.com/DIMO-Network/model-garage/internal/codegen"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)

var migrationFileFormat = "%s_%s_migration.go"
var (
delemReplacer = strings.NewReplacer("_", " ", "-", " ", ".", " ")
titleCaser = cases.Title(language.AmericanEnglish, cases.NoLower)
lowerCaser = cases.Lower(language.AmericanEnglish)
)

const timestampFormat = "20060102150405"
const (
migrationFileFormat = "%s_%s_migration.go"
timestampFormat = "20060102150405"
)

//go:embed migration.tmpl
var migrationFileTemplate string

// Config is the configuration for the migration generator.
type Config struct {
// fileName is the name of the migration file.
FileName string
}

// Generate creates a new ClickHouse table file.
func Generate(tmplData *codegen.TemplateData, outputDir string) error {
func Generate(tmplData *codegen.TemplateData, outputDir string, cfg Config) error {
version := time.Now().UTC().Format(timestampFormat)
migrationTempl, err := createMigrationTemplate(version)
fileName := cfg.FileName
if fileName == "" {
fileName = tmplData.ModelName
}
migrationTempl, err := createMigrationTemplate(fileName)
if err != nil {
return err
}
Expand All @@ -33,7 +52,9 @@ func Generate(tmplData *codegen.TemplateData, outputDir string) error {
if err != nil {
return fmt.Errorf("error executing ClickHouse table template: %w", err)
}
migrationFilePath := getFilePath(strings.ToLower(tmplData.ModelName), outputDir, version)

fileName = delemReplacer.Replace(fileName)
migrationFilePath := getFilePath(fileName, outputDir, version)
err = codegen.FormatAndWriteToFile(outBuf.Bytes(), migrationFilePath)
if err != nil {
return fmt.Errorf("error writing file: %w", err)
Expand All @@ -42,19 +63,19 @@ func Generate(tmplData *codegen.TemplateData, outputDir string) error {
return nil
}

func createMigrationTemplate(version string) (*template.Template, error) {
func createMigrationTemplate(fileName string) (*template.Template, error) {
funcName := strings.ReplaceAll(titleCaser.String(fileName), " ", "")
tmpl, err := template.New("migrationTemplate").Funcs(template.FuncMap{
"escapeDesc": func(desc string) string { return strings.ReplaceAll(desc, `'`, `\'`) },
"lower": strings.ToLower,
"version": func() string { return version },
"funcName": func() string { return funcName },
}).Parse(migrationFileTemplate)
if err != nil {
return nil, fmt.Errorf("error parsing ClickHouse table template: %w", err)
}
return tmpl, nil
}

func getFilePath(modelName, outputDir string, version string) string {
migrationFileName := fmt.Sprintf(migrationFileFormat, version, modelName)
func getFilePath(fileName, outputDir string, version string) string {
noSpaceName := lowerCaser.String(strings.ReplaceAll(fileName, " ", "_"))
migrationFileName := fmt.Sprintf(migrationFileFormat, version, noSpaceName)
return filepath.Clean(filepath.Join(outputDir, migrationFileName))
}
6 changes: 3 additions & 3 deletions internal/codegen/migration/migration.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import (

func init() {
_, filename, _, _ := runtime.Caller(0)
registerFunc := func() { goose.AddNamedMigrationContext(filename, upCommand{{ version }}, downCommand{{ version }}) }
registerFunc := func() { goose.AddNamedMigrationContext(filename, up{{ funcName }}, down{{ funcName }}) }
registerFuncs = append(registerFuncs, registerFunc)
registerFunc()
}

func upCommand{{ version }}(ctx context.Context, tx *sql.Tx) error {
func up{{ funcName }}(ctx context.Context, tx *sql.Tx) error {
// This code is executed when the migration is applied.
upStatements := []string{
}
Expand All @@ -27,7 +27,7 @@ func upCommand{{ version }}(ctx context.Context, tx *sql.Tx) error {
return nil
}

func downCommand{{ version }}(ctx context.Context, tx *sql.Tx) error {
func down{{ funcName }}(ctx context.Context, tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
downStatements :=[]string{
}
Expand Down
79 changes: 0 additions & 79 deletions pkg/migrations/20240402091429_init.go

This file was deleted.

45 changes: 0 additions & 45 deletions pkg/migrations/20240405125845_dynamic_signals.go

This file was deleted.

32 changes: 0 additions & 32 deletions pkg/migrations/20240411014301_drop_subject.go

This file was deleted.

Loading

0 comments on commit 93cc109

Please sign in to comment.