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 ad487a8
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 16 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
module github.com/mattermost/dbcmp

go 1.20
go 1.23

require (
github.com/Masterminds/squirrel v1.5.4
github.com/blang/semver/v4 v4.0.0
github.com/brianvoe/gofakeit/v6 v6.23.0
github.com/go-sql-driver/mysql v1.7.1
github.com/jmoiron/sqlx v1.3.5
Expand All @@ -14,7 +15,6 @@ require (
)

require (
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/uuid v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6Fm
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
Expand All @@ -36,6 +37,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
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 ad487a8

Please sign in to comment.