diff --git a/internal/database/migrations.go b/internal/database/migrations.go index dc4208491..83d7797f0 100644 --- a/internal/database/migrations.go +++ b/internal/database/migrations.go @@ -6,10 +6,20 @@ import ( "embed" "fmt" "path" + "regexp" + "strings" "github.com/blang/semver" ) +// compareWordsInString is a helper function to compare words in two strings without special characters. +func compareWordsInString(input, expected string) bool { + re := regexp.MustCompile(`\b\w+\b`) + cleaned := strings.Join(re.FindAllString(input, -1), " ") + fmt.Println(cleaned) + return strings.Contains(expected, cleaned) +} + //go:embed migrations/* var migrationFiles embed.FS diff --git a/internal/database/migrations_test.go b/internal/database/migrations_test.go new file mode 100644 index 000000000..a0b603034 --- /dev/null +++ b/internal/database/migrations_test.go @@ -0,0 +1,92 @@ +package database + +import "testing" + +func TestCompareWordsInString(t *testing.T) { + tests := []struct { + name string + input string + expected string + want bool + }{ + { + name: "equal", + input: "hello world", + expected: "hello world", + want: true, + }, + { + name: "not equal", + input: "hello world", + expected: "hello", + want: false, + }, + { + name: "equal with special characters", + input: "hello, world", + expected: "hello world", + want: true, + }, + { + name: "not equal with special characters", + input: "hello, world", + expected: "hello", + want: false, + }, + { + name: "equal with special characters and spaces", + input: "hello, world", + expected: "hello world", + want: true, + }, + { + name: "not equal with special characters and spaces", + input: "hello, world", + expected: "hello", + want: false, + }, + { + name: "equal with special characters and spaces", + input: "hello, world", + expected: "hello world", + want: true, + }, + { + name: "not equal with special characters and spaces", + input: "hello, 'world'", + expected: "hello", + want: false, + }, + { + name: "equal with special characters and spaces", + input: `hello, "world"`, + expected: "hello world", + want: true, + }, + { + name: "not equal with special characters and spaces", + input: "hello, world", + expected: "hello", + want: false, + }, + { + name: "migration string", + input: `pq: column "has_content" of relation "bookmark" already exists`, + expected: "pq column has_content of relation bookmark already exists", + want: true, + }, + { + name: "migration string", + input: `pq: column »has_content« of relation »bookmark« already exists`, + expected: "pq column has_content of relation bookmark already exists", + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := compareWordsInString(tt.input, tt.expected); got != tt.want { + t.Errorf("compareWordsInString() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/internal/database/pg.go b/internal/database/pg.go index 66df2dd8d..d45795e0a 100644 --- a/internal/database/pg.go +++ b/internal/database/pg.go @@ -28,7 +28,7 @@ var postgresMigrations = []migration{ defer tx.Rollback() _, err = tx.Exec(`ALTER TABLE bookmark ADD COLUMN has_content BOOLEAN DEFAULT FALSE NOT NULL`) - if err != nil && strings.Contains(err.Error(), `column "has_content" of relation "bookmark" already exists`) { + if err != nil && compareWordsInString(err.Error(), `pq column has_content of relation bookmark already exists`) { tx.Rollback() } else if err != nil { return fmt.Errorf("failed to add has_content column to bookmark table: %w", err) @@ -45,7 +45,7 @@ var postgresMigrations = []migration{ defer tx.Rollback() _, err = tx.Exec(`ALTER TABLE account ADD COLUMN config JSONB NOT NULL DEFAULT '{}'`) - if err != nil && strings.Contains(err.Error(), `column "config" of relation "account" already exists`) { + if err != nil && compareWordsInString(err.Error(), `pq column config of relation account already exists`) { tx.Rollback() } else if err != nil { return fmt.Errorf("failed to add config column to account table: %w", err)