From f8f5e0d493ba5a19b71c71fe61a3d5cf0bc4ea6e Mon Sep 17 00:00:00 2001
From: Antonio Pagano
Date: Fri, 14 Nov 2025 15:01:34 -0500
Subject: [PATCH 1/3] feat: allowing to specify the driver and the params for
each conFn
---
db/conn_fn.go | 57 +++++++++++++++
db/conn_options.go | 35 +++++++++
db/conn_settings.go | 24 +++++++
db/{connection_test.go => conn_test.go} | 0
db/connection.go | 96 -------------------------
5 files changed, 116 insertions(+), 96 deletions(-)
create mode 100644 db/conn_fn.go
create mode 100644 db/conn_options.go
create mode 100644 db/conn_settings.go
rename db/{connection_test.go => conn_test.go} (100%)
delete mode 100644 db/connection.go
diff --git a/db/conn_fn.go b/db/conn_fn.go
new file mode 100644
index 0000000..33b5401
--- /dev/null
+++ b/db/conn_fn.go
@@ -0,0 +1,57 @@
+package db
+
+import (
+ "database/sql"
+ "sync"
+)
+
+var (
+ dbPool = map[string]*sql.DB{}
+ cmux sync.Mutex
+)
+
+// ConnFn is the database connection builder function that
+// will be used by the application based on the driver and
+// connection string.
+type ConnFn func() (*sql.DB, error)
+
+// ConnectionFn is the database connection builder function that
+// will be used by the application based on the driver and
+// connection string. It opens the connection only once
+// and return the same connection on subsequent calls.
+func ConnectionFn(url string, opts ...connectionOption) ConnFn {
+ return func() (cx *sql.DB, err error) {
+ cmux.Lock()
+ defer cmux.Unlock()
+
+ // Return existing connection if available and valid
+ // to avoid reopening connections. Otherwise continue
+ // to create a new one.
+ if conn := dbPool[url]; conn != nil && conn.Ping() == nil {
+ return conn, nil
+ }
+
+ cs := &connSettings{
+ url: url,
+
+ driver: "postgres",
+ params: "",
+ }
+
+ // Apply options before connecting to the database.
+ for _, v := range opts {
+ v(cs)
+ }
+
+ conn, err := sql.Open(cs.driver, cs.connectionURL())
+ if err != nil {
+ return nil, err
+ }
+
+ // This uses url instead of modURL while the params apply
+ // to all connections.
+ dbPool[url] = conn
+
+ return conn, nil
+ }
+}
diff --git a/db/conn_options.go b/db/conn_options.go
new file mode 100644
index 0000000..d1f5443
--- /dev/null
+++ b/db/conn_options.go
@@ -0,0 +1,35 @@
+package db
+
+import "net/url"
+
+// connectionOptions for the database
+type connectionOption func(*connSettings)
+
+// WithDriver allows to specify the driver to use driver defaults to
+// postgres.
+func WithDriver(name string) connectionOption {
+ return func(cs *connSettings) {
+ cs.driver = name
+ }
+}
+
+// Params allows to specify additional connection parameters
+// that will be encoded as URL params next to the connection string.
+// params should be in key,value,key,value,... format.
+// e.g Params("sslmode", "disable", "timezone", "UTC")
+func Params(params ...string) connectionOption {
+ vals := url.Values{}
+ for i := 0; i < len(params); i += 2 {
+ key := params[i]
+ if i+1 >= len(params) {
+ vals.Add(key, "")
+ break
+ }
+
+ vals.Add(key, params[i+1])
+ }
+
+ return func(cs *connSettings) {
+ cs.params = vals.Encode()
+ }
+}
diff --git a/db/conn_settings.go b/db/conn_settings.go
new file mode 100644
index 0000000..427658a
--- /dev/null
+++ b/db/conn_settings.go
@@ -0,0 +1,24 @@
+package db
+
+import "strings"
+
+// connSettings holds database connection settings.
+// while opening the connection, its modified by
+// connectionOption functions.
+type connSettings struct {
+ params string
+ driver string
+ url string
+}
+
+func (cs connSettings) connectionURL() string {
+ if cs.params == "" {
+ return cs.url
+ }
+
+ if strings.Contains(cs.url, "?") {
+ return cs.url + "&" + cs.params
+ }
+
+ return cs.url + "?" + cs.params
+}
diff --git a/db/connection_test.go b/db/conn_test.go
similarity index 100%
rename from db/connection_test.go
rename to db/conn_test.go
diff --git a/db/connection.go b/db/connection.go
deleted file mode 100644
index 6cf1b60..0000000
--- a/db/connection.go
+++ /dev/null
@@ -1,96 +0,0 @@
-package db
-
-import (
- "database/sql"
- "net/url"
- "strings"
- "sync"
-)
-
-var (
- dbPool = map[string]*sql.DB{}
- cmux sync.Mutex
-
- // DriverName defaults to postgres
- driverName = "postgres"
-
- // Connection params to be appended to the connection string
- connParams string
-)
-
-// ConnFn is the database connection builder function that
-// will be used by the application based on the driver and
-// connection string.
-type ConnFn func() (*sql.DB, error)
-
-// connectionOptions for the database
-type connectionOption func()
-
-// ConnectionFn is the database connection builder function that
-// will be used by the application based on the driver and
-// connection string. It opens the connection only once
-// and return the same connection on subsequent calls.
-func ConnectionFn(url string, opts ...connectionOption) ConnFn {
- return func() (cx *sql.DB, err error) {
- cmux.Lock()
- defer cmux.Unlock()
-
- if conn := dbPool[url]; conn != nil && conn.Ping() == nil {
- return conn, nil
- }
-
- // Apply options before connecting to the database.
- for _, v := range opts {
- v()
- }
-
- // Modify the URL to include connection params
- // if any.
- modURL := url
- if strings.Contains(modURL, "?") {
- modURL = modURL + "&" + connParams
- } else if connParams != "" {
- modURL = modURL + "?" + connParams
- }
-
- conn, err := sql.Open(driverName, modURL)
- if err != nil {
- return nil, err
- }
-
- // This uses url instead of modURL while the params apply
- // to all connections.
- dbPool[url] = conn
-
- return conn, nil
- }
-}
-
-// WithDriver allows to specify the driver to use driver defaults to
-// postgres.
-func WithDriver(name string) connectionOption {
- return func() {
- driverName = name
- }
-}
-
-// Params allows to specify additional connection parameters
-// that will be encoded as URL params next to the connection string.
-// params should be in key,value,key,value,... format.
-// e.g Params("sslmode", "disable", "timezone", "UTC")
-func Params(params ...string) connectionOption {
- vals := url.Values{}
- for i := 0; i < len(params); i += 2 {
- key := params[i]
- if i+1 >= len(params) {
- vals.Add(key, "")
- break
- }
-
- vals.Add(key, params[i+1])
- }
-
- return func() {
- connParams = vals.Encode()
- }
-}
From 8fa751ddf5c9a891c1de562c676aee38d1811285 Mon Sep 17 00:00:00 2001
From: Antonio Pagano
Date: Fri, 14 Nov 2025 15:06:56 -0500
Subject: [PATCH 2/3] task: solving some minor warnings from the linter
---
db/manager.go | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/db/manager.go b/db/manager.go
index a7a370d..ed66e4f 100644
--- a/db/manager.go
+++ b/db/manager.go
@@ -12,15 +12,13 @@ import (
"strings"
)
-var (
- // postgresURLExp is the regular expression to extract the database name
- // and the user credentials from the database URL.
- postgresURLExp = regexp.MustCompile(`postgres://(.*):(.*)@(.*):(.*)/([^?]*)`)
-)
+// postgresURLExp is the regular expression to extract the database name
+// and the user credentials from the database URL.
+var postgresURLExp = regexp.MustCompile(`postgres://(.*):(.*)@(.*):(.*)/([^?]*)`)
// Create a new database based on the passed URL.
func Create(url string) error {
- var createFn func(string) error = createSQLite
+ createFn := createSQLite
if strings.Contains(url, "postgres") {
createFn = createPostgres
}
@@ -48,7 +46,13 @@ func createPostgres(conURL string) error {
return fmt.Errorf("invalid database URL: %s", conURL)
}
- db, err := sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s:%s/postgres?sslmode=disable", matches[1], matches[2], matches[3], matches[4]))
+ db, err := sql.Open(
+ "postgres",
+ fmt.Sprintf(
+ "postgres://%s:%s@%s:%s/postgres?sslmode=disable",
+ matches[1], matches[2], matches[3], matches[4],
+ ),
+ )
if err != nil {
return fmt.Errorf("connecting to database: %w", err)
}
@@ -56,7 +60,6 @@ func createPostgres(conURL string) error {
var exists int
row := db.QueryRow("SELECT COUNT(datname) FROM pg_database WHERE datname ilike $1", matches[5])
err = row.Scan(&exists)
-
if err != nil {
return err
}
@@ -75,7 +78,7 @@ func createPostgres(conURL string) error {
// Drop a database based on the passed URL.
func Drop(url string) error {
- var dropFn func(string) error = dropSQLite
+ dropFn := dropSQLite
if strings.Contains(url, "postgres") {
dropFn = dropPostgres
}
From 2281de1ff603beb42f8bcf68d768a356616749a4 Mon Sep 17 00:00:00 2001
From: Antonio Pagano
Date: Fri, 14 Nov 2025 15:11:30 -0500
Subject: [PATCH 3/3] task: a bit more of readability
---
db/manager.go | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/db/manager.go b/db/manager.go
index ed66e4f..c8bc487 100644
--- a/db/manager.go
+++ b/db/manager.go
@@ -46,13 +46,12 @@ func createPostgres(conURL string) error {
return fmt.Errorf("invalid database URL: %s", conURL)
}
- db, err := sql.Open(
- "postgres",
- fmt.Sprintf(
- "postgres://%s:%s@%s:%s/postgres?sslmode=disable",
- matches[1], matches[2], matches[3], matches[4],
- ),
+ dsn := fmt.Sprintf(
+ "postgres://%s:%s@%s:%s/postgres?sslmode=disable",
+ matches[1], matches[2], matches[3], matches[4],
)
+
+ db, err := sql.Open("postgres", dsn)
if err != nil {
return fmt.Errorf("connecting to database: %w", err)
}