Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature(model) support auto index fkey and setup relation on update a… #81

Merged
merged 28 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f9c4d51
feature(model) support auto index fkey and setup relation on update a…
vani-rf Oct 18, 2024
8602321
fix(lint) golint
vani-rf Oct 18, 2024
481cef9
Merge branch 'main' into feature/model-fk-index
toopay Oct 21, 2024
1a6fe2f
fix: update lint version
toopay Oct 21, 2024
c443fad
test: add Action field
toopay Oct 21, 2024
9a52ac0
test: add Action field for deletion
toopay Oct 21, 2024
f018351
fix: linter
toopay Oct 21, 2024
eb5e08c
test: add index compare test
toopay Oct 22, 2024
3773c19
test: include index and action properties on compare tests
toopay Oct 22, 2024
30a5b08
test: include index and action properties on compare tests
toopay Oct 22, 2024
23b37db
test: use action code
toopay Oct 22, 2024
b0621b5
test: include index and action properties on compare tests
toopay Oct 22, 2024
aa62af9
test: include index and action properties on compare tests
toopay Oct 22, 2024
f6afad7
test: without indexes
toopay Oct 22, 2024
0531bef
test: create target relation
toopay Oct 22, 2024
9738045
fix: nulish values
toopay Oct 22, 2024
da6d83a
feat: include action and index metadata
toopay Oct 22, 2024
893e512
test: test attach index/action
toopay Oct 22, 2024
2c39b73
linter: fix linter
toopay Oct 22, 2024
09dfb06
test: print_diff
toopay Oct 22, 2024
1070d1e
test: state extraction
toopay Oct 22, 2024
1d37b45
test: state extraction
toopay Oct 22, 2024
8b98858
test: state extraction
toopay Oct 22, 2024
739e4a7
test: index and action API
toopay Oct 22, 2024
0d3e6b5
test: index and action API
toopay Oct 22, 2024
e5cfef2
test: index and action API
toopay Oct 22, 2024
7a7d3bc
test: index and action API
toopay Oct 22, 2024
b24117e
test: index and action API
toopay Oct 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/raiden.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Setup golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: v1.58.1
version: v1.60
args: --verbose
test:
needs: lint
Expand Down Expand Up @@ -79,4 +79,4 @@ jobs:

- name: Format
if: matrix.go-version == '1.22.x'
run: diff -u <(echo -n) <(gofmt -d .)
run: diff -u <(echo -n) <(gofmt -d .)
1 change: 1 addition & 0 deletions model.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type (
Nullable bool
Default any
Unique bool
Index bool
}

// definition of join tag, example:
Expand Down
25 changes: 23 additions & 2 deletions pkg/generator/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,14 +266,35 @@ func containsRelation(relations []state.Relation, r state.Relation) bool {
return false
}

func BuildJoinTag(r *state.Relation) string {
func BuildRelationTag(r *state.Relation) string {
var tags []string
var joinTags []string

// append json tag
jsonTag := fmt.Sprintf("json:%q", utils.ToSnakeCase(r.Table)+",omitempty")
tags = append(tags, jsonTag)

if r.Action != nil {

onUpdate, onDelete := objects.RelationActionDefaultLabel, objects.RelationActionDefaultLabel
if r.Action.UpdateAction != "" {
code := strings.ToLower(r.Action.UpdateAction)
if v, ok := objects.RelationActionMapLabel[objects.RelationAction(code)]; ok {
onUpdate = v
}
}

if r.Action.DeletionAction != "" {
code := strings.ToLower(r.Action.DeletionAction)
if v, ok := objects.RelationActionMapLabel[objects.RelationAction(code)]; ok {
onDelete = v
}
}

tags = append(tags, fmt.Sprintf("onUpdate:%q", onUpdate))
tags = append(tags, fmt.Sprintf("onDelete:%q", onDelete))
}

// append relation type tag
relTypeTag := fmt.Sprintf("joinType:%s", r.RelationType)
joinTags = append(joinTags, relTypeTag)
Expand Down Expand Up @@ -350,7 +371,7 @@ func BuildRelationFields(table objects.Table, relations []state.Relation) (mappe
r.Table = fmt.Sprintf("%sThrough%s", inflection.Plural(r.Table), utils.SnakeCaseToPascalCase(inflection.Singular(throughSuffix)))
}

r.Tag = BuildJoinTag(&r)
r.Tag = BuildRelationTag(&r)

if !containsRelation(mappedRelations, r) {
mappedRelations = append(mappedRelations, r)
Expand Down
6 changes: 6 additions & 0 deletions pkg/generator/model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ func TestGenerateModels(t *testing.T) {
err1 := utils.CreateFolder(modelPath)
assert.NoError(t, err1)

relationshipAction := objects.TablesRelationshipAction{
UpdateAction: "c",
DeletionAction: "c",
}

tables := []*generator.GenerateModelInput{
{
Table: objects.Table{
Expand All @@ -42,6 +47,7 @@ func TestGenerateModels(t *testing.T) {
Table: "related_table",
ForeignKey: "test_table_id",
PrimaryKey: "id",
Action: &relationshipAction,
},
},
Policies: objects.Policies{},
Expand Down
2 changes: 1 addition & 1 deletion pkg/generator/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func GenerateStorage(folderPath string, storage *GenerateStorageInput, generateF
}

var allowedMimeTypes = ""
if storage.Bucket.AllowedMimeTypes != nil && len(storage.Bucket.AllowedMimeTypes) > 0 {
if len(storage.Bucket.AllowedMimeTypes) > 0 {
allowedMimeTypes = GenerateArrayDeclaration(reflect.ValueOf(storage.Bucket.AllowedMimeTypes), false)
}

Expand Down
9 changes: 4 additions & 5 deletions pkg/resource/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type MigrateData struct {

// Migrate resource :
//
// [ ] migrate table
// [x] migrate table
//
// [x] create table name, schema and columns
// [x] create table rls enable
Expand Down Expand Up @@ -84,8 +84,8 @@ type MigrateData struct {
// [x] create new storage
// [x] update storage
// [x] delete storage
// [ ] add storage acl
// [ ] update storage acl
// [x] add storage acl
// [x] update storage acl
func Apply(flags *Flags, config *raiden.Config) error {
// declare default variable
var migrateData MigrateData
Expand Down Expand Up @@ -165,6 +165,7 @@ func Apply(flags *Flags, config *raiden.Config) error {
}

if flags.All() || flags.ModelsOnly {
resource.Tables = tables.AttachIndexAndAction(resource.Tables, resource.Indexes, resource.RelationActions)
if data, err := tables.BuildMigrateData(appTables, resource.Tables); err != nil {
return err
} else {
Expand Down Expand Up @@ -243,7 +244,6 @@ func Migrate(config *raiden.Config, importState *state.LocalState, projectPath s
ForceCreateRelation: true,
},
})
resource.Tables[i].MigrationItems.ChangeRelationItems = make([]objects.UpdateRelationItem, 0)
} else {
updateTableRelation = append(updateTableRelation, tables.MigrateItem{
Type: t.Type,
Expand All @@ -254,7 +254,6 @@ func Migrate(config *raiden.Config, importState *state.LocalState, projectPath s
ChangeRelationItems: t.MigrationItems.ChangeRelationItems,
},
})
resource.Tables[i].MigrationItems.ChangeRelationItems = make([]objects.UpdateRelationItem, 0)
}
}
}
Expand Down
1 change: 1 addition & 0 deletions pkg/resource/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func Import(flags *Flags, config *raiden.Config) error {
if err != nil {
return err
}
spResource.Tables = tables.AttachIndexAndAction(spResource.Tables, spResource.Indexes, spResource.RelationActions)

// create import state
ImportLogger.Debug("get native roles")
Expand Down
29 changes: 24 additions & 5 deletions pkg/resource/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ import (
var LoadLogger hclog.Logger = logger.HcLog().Named("import.load")

type Resource struct {
Tables []objects.Table
Policies objects.Policies
Roles []objects.Role
Functions []objects.Function
Storages []objects.Bucket
Tables []objects.Table
Policies objects.Policies
Roles []objects.Role
Functions []objects.Function
Storages []objects.Bucket
Indexes []objects.Index
RelationActions []objects.TablesRelationshipAction
}

// The Load function loads resources based on the provided flags and project ID, and returns a resource
Expand Down Expand Up @@ -47,6 +49,12 @@ func Load(flags *Flags, cfg *raiden.Config) (*Resource, error) {
case []objects.Bucket:
resource.Storages = rs
LoadLogger.Debug("Finish Get Bucket From Supabase")
case []objects.Index:
resource.Indexes = rs
LoadLogger.Debug("Finish Get Indexes From Supabase")
case []objects.TablesRelationshipAction:
resource.RelationActions = rs
LoadLogger.Debug("Finish Get Relation Action From Supabase")
case error:
return nil, rs
}
Expand Down Expand Up @@ -99,6 +107,17 @@ func loadResource(cfg *raiden.Config, flags *Flags) <-chan any {
return supabase.GetTables(cfg, supabase.DefaultIncludedSchema)
})

wg.Add(1)
LoadLogger.Debug("Get Index From Supabase")
go loadSupabaseResource(&wg, cfg, outChan, func(cfg *raiden.Config) ([]objects.Index, error) {
return supabase.GetIndexes(cfg, supabase.DefaultIncludedSchema[0])
})

wg.Add(1)
LoadLogger.Debug("Get Table Relation Actions From Supabase")
go loadSupabaseResource(&wg, cfg, outChan, func(cfg *raiden.Config) ([]objects.TablesRelationshipAction, error) {
return supabase.GetTableRelationshipActions(cfg, supabase.DefaultIncludedSchema[0])
})
}

if flags.All() || flags.RolesOnly {
Expand Down
37 changes: 37 additions & 0 deletions pkg/resource/tables/compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,43 @@ func compareRelations(table *objects.Table, source, target []objects.TablesRelat
continue
}

if t.Index == nil && sc.Index == nil {
updateItems = append(updateItems, objects.UpdateRelationItem{
Data: sc,
Type: objects.UpdateRelationCreateIndex,
})
Logger.Debug("create new index", "constrain-name", sc.ConstraintName)
}

if t.Action != nil && sc.Action != nil {
if t.Action.UpdateAction != sc.Action.UpdateAction {
updateItems = append(updateItems, objects.UpdateRelationItem{
Data: sc,
Type: objects.UpdateRelationActionOnUpdate,
})
Logger.Debug("check on update", "t-on-update", t.Action.UpdateAction, "sc-on-delete", sc.Action.UpdateAction, "same", t.Action.UpdateAction == sc.Action.UpdateAction)
}

if t.Action.DeletionAction != sc.Action.DeletionAction {
updateItems = append(updateItems, objects.UpdateRelationItem{
Data: sc,
Type: objects.UpdateRelationActionOnDelete,
})
Logger.Debug("check on delete", "t-on-delete", t.Action.DeletionAction, "sc-on-delete", sc.Action.DeletionAction, "same", t.Action.DeletionAction == sc.Action.DeletionAction)
}
} else if t.Action != nil && sc.Action == nil {
updateItems = append(updateItems, objects.UpdateRelationItem{
Data: sc,
Type: objects.UpdateRelationActionOnUpdate,
})

updateItems = append(updateItems, objects.UpdateRelationItem{
Data: sc,
Type: objects.UpdateRelationActionOnDelete,
})
Logger.Debug("create relation new action", "on-update", t.Action.UpdateAction, "on-delete", t.Action.DeletionAction)
}

delete(mapTargetRelation, sc.ConstraintName)

if (sc.SourceSchema != t.SourceSchema) || (sc.SourceTableName != t.SourceTableName) || (sc.SourceColumnName != t.SourceColumnName) {
Expand Down
98 changes: 98 additions & 0 deletions pkg/resource/tables/compare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,102 @@ func TestCompareList(t *testing.T) {
}

func TestCompareItem(t *testing.T) {

sourceRelationshipAction := objects.TablesRelationshipAction{
UpdateAction: "c",
DeletionAction: "c",
}

targetRelationshipAction := objects.TablesRelationshipAction{
UpdateAction: "a",
DeletionAction: "a",
}

source := objects.Table{
ID: 1,
Name: "table1",
Schema: "public",
RLSEnabled: true,
RLSForced: true,
PrimaryKeys: []objects.PrimaryKey{{Name: "id", Schema: "public", TableName: "table1"}},
Columns: []objects.Column{
{Name: "id", DataType: "int", IsNullable: false},
{Name: "name", DataType: "varchar", IsNullable: true},
{Name: "nullable", DataType: "varchar", IsNullable: true},
{Name: "changeable", DataType: "varchar", IsNullable: true},
{Name: "uniqueness", DataType: "varchar", IsNullable: false, IsUnique: true},
{Name: "identity", DataType: "varchar", IsNullable: false, IsIdentity: true},
},
Relationships: []objects.TablesRelationship{
{
ConstraintName: "constraint1",
SourceSchema: "public",
SourceTableName: "table1",
SourceColumnName: "id",
TargetTableSchema: "public",
TargetTableName: "table2",
TargetColumnName: "id",
Index: &objects.Index{Schema: "public", Table: "table1", Name: "index1", Definition: "index1"},
Action: &sourceRelationshipAction,
},
},
}

target := objects.Table{
ID: 1,
Name: "table1_updated",
Schema: "private",
RLSEnabled: false,
RLSForced: false,
PrimaryKeys: []objects.PrimaryKey{{Name: "id", Schema: "public", TableName: "table1"}},
Columns: []objects.Column{
{Name: "id", DataType: "int", IsNullable: false},
{Name: "name", DataType: "varchar", IsNullable: false},
{Name: "description", DataType: "text", IsNullable: true},
{Name: "nullable", DataType: "varchar", IsNullable: false},
{Name: "changeable", DataType: "json", IsNullable: true},
{Name: "uniqueness", DataType: "varchar", IsNullable: false, IsUnique: false},
{Name: "identity", DataType: "varchar", IsNullable: false, IsIdentity: false},
},
Relationships: []objects.TablesRelationship{
{
ConstraintName: "constraint1",
SourceSchema: "public",
SourceTableName: "table1",
SourceColumnName: "id",
TargetTableSchema: "public",
TargetTableName: "table2",
TargetColumnName: "id",
Index: &objects.Index{Schema: "public", Table: "table1", Name: "index1", Definition: "index1"},
Action: &targetRelationshipAction,
},
{
ConstraintName: "constraint2",
SourceSchema: "public",
SourceTableName: "table1",
SourceColumnName: "name",
TargetTableSchema: "public",
TargetTableName: "table2",
TargetColumnName: "name",
Action: &targetRelationshipAction,
},
},
}

diffResult := tables.CompareItem(source, target)
assert.True(t, diffResult.IsConflict)
assert.Equal(t, "table1", diffResult.SourceResource.Name)
assert.Equal(t, "table1_updated", diffResult.TargetResource.Name)
assert.Equal(t, []objects.UpdateColumnType{objects.UpdateColumnNullable}, diffResult.DiffItems.ChangeColumnItems[0].UpdateItems)
assert.Equal(t, []objects.UpdateColumnType{objects.UpdateColumnNullable}, diffResult.DiffItems.ChangeColumnItems[1].UpdateItems)
}

func TestCompareItemWithoutIndex(t *testing.T) {
targetRelationshipAction := objects.TablesRelationshipAction{
UpdateAction: "c",
DeletionAction: "c",
}

source := objects.Table{
ID: 1,
Name: "table1",
Expand All @@ -84,6 +180,7 @@ func TestCompareItem(t *testing.T) {
TargetTableSchema: "public",
TargetTableName: "table2",
TargetColumnName: "id",
Action: nil,
},
},
}
Expand Down Expand Up @@ -113,6 +210,7 @@ func TestCompareItem(t *testing.T) {
TargetTableSchema: "public",
TargetTableName: "table2",
TargetColumnName: "id",
Action: &targetRelationshipAction,
},
{
ConstraintName: "constraint2",
Expand Down
Loading