From 03a98b4a50039fa1d3f8f4c44b57d61bf7576245 Mon Sep 17 00:00:00 2001 From: Miguel de la Cruz Date: Thu, 10 Jun 2021 19:07:45 +0200 Subject: [PATCH] Fix MySQL migration connection when the DSN doesn't contain any query parameters --- server/services/store/sqlstore/migrate.go | 18 ++++++++-- .../services/store/sqlstore/migrate_test.go | 35 +++++++++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 server/services/store/sqlstore/migrate_test.go diff --git a/server/services/store/sqlstore/migrate.go b/server/services/store/sqlstore/migrate.go index bfe7d2bbeb7..ccf58685fb1 100644 --- a/server/services/store/sqlstore/migrate.go +++ b/server/services/store/sqlstore/migrate.go @@ -68,16 +68,28 @@ func (pm *PrefixedMigration) ReadDown(version uint) (io.ReadCloser, string, erro return pm.executeTemplate(r, identifier) } +func appendMultipleStatementsFlag(connectionString string) (string, error) { + config, err := mysqldriver.ParseDSN(connectionString) + if err != nil { + return "", err + } + + if config.Params == nil { + config.Params = map[string]string{} + } + + config.Params["multiStatements"] = "true" + return config.FormatDSN(), nil +} + // migrations in MySQL need to run with the multiStatements flag // enabled, so this method creates a new connection ensuring that it's // enabled func (s *SQLStore) getMySQLMigrationConnection() (*sql.DB, error) { - config, err := mysqldriver.ParseDSN(s.connectionString) + connectionString, err := appendMultipleStatementsFlag(s.connectionString) if err != nil { return nil, err } - config.Params["multiStatements"] = "true" - connectionString := config.FormatDSN() db, err := sql.Open(s.dbType, connectionString) if err != nil { diff --git a/server/services/store/sqlstore/migrate_test.go b/server/services/store/sqlstore/migrate_test.go new file mode 100644 index 00000000000..12ba070a6f9 --- /dev/null +++ b/server/services/store/sqlstore/migrate_test.go @@ -0,0 +1,35 @@ +package sqlstore + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGetMySQLMigrationConnection(t *testing.T) { + testCases := []struct { + Scenario string + DSN string + ExpectedDSN string + }{ + { + "Should append multiStatements param to the DSN path with existing params", + "user:rand?&ompasswith@character@unix(/var/run/mysqld/mysqld.sock)/focalboard?writeTimeout=30s", + "user:rand?&ompasswith@character@unix(/var/run/mysqld/mysqld.sock)/focalboard?writeTimeout=30s&multiStatements=true", + }, + { + "Should append multiStatements param to the DSN path with no existing params", + "user:rand?&ompasswith@character@unix(/var/run/mysqld/mysqld.sock)/focalboard", + "user:rand?&ompasswith@character@unix(/var/run/mysqld/mysqld.sock)/focalboard?multiStatements=true", + }, + } + + for _, tc := range testCases { + t.Run(tc.Scenario, func(t *testing.T) { + res, err := appendMultipleStatementsFlag(tc.DSN) + require.NoError(t, err) + assert.Equal(t, tc.ExpectedDSN, res) + }) + } +}