Skip to content

Commit

Permalink
reflect review comments and bugfix
Browse files Browse the repository at this point in the history
  • Loading branch information
isacikgoz committed Feb 4, 2025
1 parent 07fa84c commit aa7da50
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 14 deletions.
22 changes: 8 additions & 14 deletions internal/store/compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,14 @@ func Compare(srcDSN, dstDSN string, opts CompareOptions) ([]string, error) {
return nil, fmt.Errorf("include and exclude flags cannot be used together")
}

// find a more elegant solution fo this
// essentially we want to exclude some
// patterns from comparing.
for k := range srcTables {
for e := range excl {
if strings.Contains(k, strings.ToLower(e)) {
delete(srcTables, k)
}
}
for e := range incl {
if !strings.Contains(k, strings.ToLower(e)) {
delete(srcTables, k)
}
}
if len(incl) > 0 {
// include removes elements from the input map if they are not included.
// works with exact match and case-insensitive.
srcTables = filterMap(srcTables, opts.IncludePatterns, include)
} else if len(excl) > 0 {
// exclude removes elements from the input map by the given keys.
// filteration is case-insensitive and made with strings.Contains.
srcTables = filterMap(srcTables, opts.ExcludePatterns, exclude)
}

var mismatchs []string
Expand Down
37 changes: 37 additions & 0 deletions internal/store/util.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package store

import (
"maps"
"strings"

"github.com/go-sql-driver/mysql"
)

type filterMode int

const (
include filterMode = iota
exclude
)

func normalizeDSN(dataSource string) (string, error) {
if strings.HasPrefix(dataSource, "postgres") {
return dataSource, nil
Expand All @@ -32,3 +40,32 @@ func sliceToMap(inc []string) map[string]struct{} {

return m
}

func filterMap[V any](m map[string]V, keys []string, mode filterMode) map[string]V {
result := maps.Clone(m)

keySet := make(map[string]struct{}, len(keys))
for _, k := range keys {
keySet[strings.ToLower(k)] = struct{}{}
}

switch mode {
case include:
maps.DeleteFunc(result, func(k string, _ V) bool {
_, exists := keySet[strings.ToLower(k)]
return !exists
})
case exclude:
for k := range result {
for e := range keySet {
if strings.Contains(k, strings.ToLower(e)) {
delete(result, k)
}
}
}
default:
panic("unknown filter mode")
}

return result
}
90 changes: 90 additions & 0 deletions internal/store/util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package store

import (
"reflect"
"testing"
)

func TestFilterMap(t *testing.T) {
tests := []struct {
name string
inputMap map[string]int
keys []string
mode filterMode
expected map[string]int
}{
{
name: "include keys",
inputMap: map[string]int{
"key1": 1,
"key2": 2,
"key3": 3,
},
keys: []string{"key1", "key3"},
mode: include,
expected: map[string]int{
"key1": 1,
"key3": 3,
},
},
{
name: "exclude keys",
inputMap: map[string]int{
"key1": 1,
"key2": 2,
"key3": 3,
},
keys: []string{"key1", "key3"},
mode: exclude,
expected: map[string]int{
"key2": 2,
},
},
{
name: "include no keys",
inputMap: map[string]int{
"key1": 1,
"key2": 2,
"key3": 3,
},
keys: []string{},
mode: include,
expected: map[string]int{},
},
{
name: "exclude no keys",
inputMap: map[string]int{
"key1": 1,
"key2": 2,
"key3": 3,
},
keys: []string{},
mode: exclude,
expected: map[string]int{
"key1": 1,
"key2": 2,
"key3": 3,
},
},
{
name: "exclude keys match",
inputMap: map[string]int{
"key1": 1,
"key2": 2,
"key3": 3,
},
keys: []string{"key"},
mode: exclude,
expected: map[string]int{},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := filterMap(tt.inputMap, tt.keys, tt.mode)
if !reflect.DeepEqual(result, tt.expected) {
t.Errorf("filterMap() = %v, want %v", result, tt.expected)
}
})
}
}

0 comments on commit aa7da50

Please sign in to comment.