Repository: danvergara/dblab
Pull request #135 (2022-10-21 19:20:27)

Fix mysql url bug
## Description

A user spotted a problem while she was trying to connect to a MariaDB server. Turns out MySQL/MariaDB doesn't need the `mysql://` scheme prefix at the beginning of the dsn, this was current behavior at the time to build the dsn from the options, but we left a mistaken behavior at the time to validate the output from the `--url` flag.

## Type of change

Please delete options that are not relevant.

- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update

## How Has This Been Tested?

Ran the fixed tests to validate the new behavior. Also, I was able to connect with MySQL instances through the `--url` flag.

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [x] I have added tests that prove my fix is effective or that my feature works
- [x] New and existing unit tests pass locally with my changes
- [x] I have checked my code and corrected any misspellings



Patch:
diff --git a/Makefile b/Makefile
index 173e64c..e1d0020 100644
--- a/Makefile
+++ b/Makefile
@@ -62,6 +62,11 @@ run-sqlite3: build-sqlite3
 run-url: build
 	./dblab --url postgres://postgres:password@localhost:5432/users?sslmode=disable
 
+.PHONY: run-mysql-url
+## run-mysql-url: Runs the app passing the url as parameter
+run-mysql-url: build
+	./dblab --url "mysql://myuser:5@klkbN#ABC@tcp(localhost:3306)/mydb"
+
 .PHONY: up
 ## up: Runs all the containers listed in the docker-compose.yml file
 up:
diff --git a/pkg/connection/connection.go b/pkg/connection/connection.go
index 17300b9..45e5c01 100644
--- a/pkg/connection/connection.go
+++ b/pkg/connection/connection.go
@@ -161,6 +161,10 @@ func formatMySQLURL(opts command.Options) (string, error) {
 
 	var e *url.Error
 
+	// removes the mysql:// scheme since mysql does not need this.
+	// we need it to know what database we're trying to connect to.
+	opts.URL = strings.ReplaceAll(opts.URL, "mysql://", "")
+
 	uri, err := url.Parse(opts.URL)
 	if err != nil {
 		// checks if *url.Error is the type of the error.


Test patch:
diff --git a/pkg/connection/connection_test.go b/pkg/connection/connection_test.go
index ff3eca9..396a58e 100644
--- a/pkg/connection/connection_test.go
+++ b/pkg/connection/connection_test.go
@@ -77,7 +77,7 @@ func TestBuildConnectionFromOptsFromURL(t *testing.T) {
 				},
 			},
 			want: want{
-				uri: "mysql://user:password@tcp(localhost:3306)/db",
+				uri: "user:password@tcp(localhost:3306)/db",
 			},
 		},
 		{
@@ -88,7 +88,7 @@ func TestBuildConnectionFromOptsFromURL(t *testing.T) {
 				},
 			},
 			want: want{
-				uri: "mysql://user:password@tcp(localhost:3306)/db?charset=utf8",
+				uri: "user:password@tcp(localhost:3306)/db?charset=utf8",
 			},
 		},
 		{
@@ -99,7 +99,7 @@ func TestBuildConnectionFromOptsFromURL(t *testing.T) {
 				},
 			},
 			want: want{
-				uri: "mysql://user:password@tcp(your-amazonaws-uri.com:3306)/dbname",
+				uri: "user:password@tcp(your-amazonaws-uri.com:3306)/dbname",
 			},
 		},
 		{
@@ -456,7 +456,7 @@ func TestFormatMySQLURL(t *testing.T) {
 				},
 			},
 			want: want{
-				uri: "mysql://user:password@tcp(localhost:3306)/db",
+				uri: "user:password@tcp(localhost:3306)/db",
 			},
 		},
 		{
@@ -467,7 +467,7 @@ func TestFormatMySQLURL(t *testing.T) {
 				},
 			},
 			want: want{
-				uri: "mysql://user:password@tcp(localhost:3306)/db?charset=utf8",
+				uri: "user:password@tcp(localhost:3306)/db?charset=utf8",
 			},
 		},
 		{
@@ -478,7 +478,7 @@ func TestFormatMySQLURL(t *testing.T) {
 				},
 			},
 			want: want{
-				uri: "mysql://user:password@tcp(your-amazonaws-uri.com:3306)/dbname",
+				uri: "user:password@tcp(your-amazonaws-uri.com:3306)/dbname",
 			},
 		},
 		{
@@ -489,7 +489,7 @@ func TestFormatMySQLURL(t *testing.T) {
 				},
 			},
 			want: want{
-				uri: "mysql://user:password@/dbname?sql_mode=TRADITIONAL",
+				uri: "user:password@/dbname?sql_mode=TRADITIONAL",
 			},
 		},
 		{
@@ -500,7 +500,7 @@ func TestFormatMySQLURL(t *testing.T) {
 				},
 			},
 			want: want{
-				uri: "mysql://user:password@unix(/cloudsql/project-id:region-name:instance-name)/dbname",
+				uri: "user:password@unix(/cloudsql/project-id:region-name:instance-name)/dbname",
 			},
 		},
 		{
@@ -527,6 +527,17 @@ func TestFormatMySQLURL(t *testing.T) {
 				err:      ErrInvalidMySQLURLFormat,
 			},
 		},
+		{
+			name: "valid with strange characters",
+			given: given{
+				opts: command.Options{
+					URL: "mysql://myuser:5@klkbN#ABC@@tcp(localhost:3306)/mydb",
+				},
+			},
+			want: want{
+				uri: "myuser:5@klkbN#ABC@@tcp(localhost:3306)/mydb",
+			},
+		},
 	}
 
 	for _, tc := range cases {