-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ feat: added resolver databases based on configs #5
- Loading branch information
1 parent
180e8b2
commit 7d80adb
Showing
6 changed files
with
274 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,91 @@ | ||
package dbresolver | ||
|
||
import ( | ||
"database/sql" | ||
"fmt" | ||
"sync" | ||
"time" | ||
|
||
"github.com/sivaosorg/govm/dbx" | ||
"github.com/sivaosorg/govm/logger" | ||
"github.com/sivaosorg/govm/mysql" | ||
"github.com/sivaosorg/govm/postgres" | ||
"github.com/sivaosorg/mysqlconn" | ||
"github.com/sivaosorg/postgresconn" | ||
) | ||
|
||
// NewPostgresConnector creates a new PostgresConnector instance. | ||
func NewPostgresConnector(config postgres.PostgresConfig) *PostgresConnector { | ||
return &PostgresConnector{Config: config} | ||
} | ||
|
||
// NewMySQLConnector creates a new MySQLConnector instance. | ||
func NewMySQLConnector(config mysql.MysqlConfig) *MySQLConnector { | ||
return &MySQLConnector{Config: config} | ||
} | ||
|
||
func (p *PostgresConnector) Connect() (*sql.DB, dbx.Dbx) { | ||
psql, s := postgresconn.NewClient(p.Config) | ||
if s.IsConnected { | ||
return psql.GetConn().DB, s | ||
} | ||
return nil, s | ||
} | ||
|
||
func (m *MySQLConnector) Connect() (*sql.DB, dbx.Dbx) { | ||
msql, s := mysqlconn.NewClient(m.Config) | ||
return msql.GetConn(), s | ||
} | ||
|
||
// NewMultiTenantDBResolver creates a new MultiTenantDBResolver instance. | ||
func NewMultiTenantDBResolver() *MultiTenantDBResolver { | ||
return &MultiTenantDBResolver{ | ||
connectors: make(map[string]DBConnector), | ||
once: make(map[string]*sync.Once), | ||
} | ||
} | ||
|
||
// AddConnector adds a new database connector for a specific tenant. | ||
func (r *MultiTenantDBResolver) AddConnector(tenantId string, connector DBConnector) *MultiTenantDBResolver { | ||
mu.Lock() | ||
defer mu.Unlock() | ||
r.connectors[tenantId] = connector | ||
r.once[tenantId] = &sync.Once{} | ||
return r | ||
} | ||
|
||
// GetConnector returns a database connection for a specific tenant. | ||
func (r *MultiTenantDBResolver) GetConnector(tenantId string) (*sql.DB, dbx.Dbx) { | ||
mu.RLock() | ||
connector, ok := r.connectors[tenantId] | ||
once := r.once[tenantId] | ||
mu.RUnlock() | ||
|
||
if !ok { | ||
mu.Lock() | ||
defer mu.Unlock() | ||
// Check again to avoid race condition | ||
if connector, ok = r.connectors[tenantId]; !ok { | ||
connector = NewPostgresConnector(*postgres.GetPostgresConfigSample()) // Fallback to default config | ||
r.AddConnector(tenantId, connector) | ||
} | ||
} | ||
|
||
// This will be executed only once for the first connection | ||
once.Do(func() { | ||
start := time.Now() | ||
db, s := connector.Connect() | ||
if !s.IsConnected { | ||
logger.Errorf(fmt.Sprintf("Error initializing database connection for tenant %s (executed in %v): %s", tenantId, time.Since(start), s.Message), s.Error) | ||
} | ||
dbs[tenantId] = struct { | ||
C *sql.DB | ||
S dbx.Dbx | ||
}{ | ||
C: db, | ||
S: s, | ||
} | ||
}) | ||
conn, _ := dbs[tenantId] | ||
return conn.C, conn.S | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,23 @@ | ||
package dbresolver | ||
|
||
import ( | ||
"database/sql" | ||
"sync" | ||
|
||
"github.com/sivaosorg/govm/dbx" | ||
) | ||
|
||
var ( | ||
dbs = make(map[string]struct { | ||
C *sql.DB | ||
S dbx.Dbx | ||
}) | ||
mu sync.RWMutex | ||
defaultConfig = dbConfig{ | ||
Host: "127.0.0.1", | ||
Port: 5432, | ||
User: "default-db-user", | ||
Password: "default-db-password", | ||
Database: "default-db-name", | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,40 @@ | ||
package dbresolver | ||
|
||
import ( | ||
"database/sql" | ||
"sync" | ||
|
||
"github.com/sivaosorg/govm/dbx" | ||
"github.com/sivaosorg/govm/mysql" | ||
"github.com/sivaosorg/govm/postgres" | ||
) | ||
|
||
// dbConfig represents the common configuration for both Postgres and MySQL. | ||
type dbConfig struct { | ||
Host string `json:"host"` | ||
Port int `json:"port"` | ||
User string `json:"user"` | ||
Password string `json:"-"` | ||
Database string `json:"database"` | ||
} | ||
|
||
// DBConnector is an interface for creating and managing database connections. | ||
type DBConnector interface { | ||
Connect() (*sql.DB, dbx.Dbx) | ||
} | ||
|
||
// PostgresConnector implements the DBConnector interface for PostgreSQL. | ||
type PostgresConnector struct { | ||
Config postgres.PostgresConfig `json:"psql_conf"` | ||
} | ||
|
||
// MySQLConnector implements the DBConnector interface for MySQL. | ||
type MySQLConnector struct { | ||
Config mysql.MysqlConfig `json:"msql_conf"` | ||
} | ||
|
||
// MultiTenantDBResolver manages database connections for multiple tenants. | ||
type MultiTenantDBResolver struct { | ||
connectors map[string]DBConnector | ||
once map[string]*sync.Once | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package example | ||
|
||
import ( | ||
dbresolver "github.com/sivaosorg/db.resolver" | ||
"github.com/sivaosorg/govm/logger" | ||
"github.com/sivaosorg/govm/postgres" | ||
) | ||
|
||
func main() { | ||
config_1 := postgres.GetPostgresConfigSample(). | ||
SetEnabled(true). | ||
SetDatabase("your_db"). | ||
SetPort(6666). | ||
SetPassword("@@@@@@@@"). | ||
SetUsername("XXXX"). | ||
SetDebugMode(false) | ||
|
||
config_2 := postgres.GetPostgresConfigSample(). | ||
SetEnabled(true). | ||
SetDatabase("your_db"). | ||
SetPort(6666). | ||
SetPassword("@@@@@@@@"). | ||
SetUsername("XXXX"). | ||
SetDebugMode(false) | ||
|
||
connector1 := dbresolver.NewPostgresConnector(*config_1) | ||
connector2 := dbresolver.NewPostgresConnector(*config_2) | ||
|
||
resolver := dbresolver.NewMultiTenantDBResolver() | ||
|
||
resolver.AddConnector("psql_node1", connector1).AddConnector("psql_node2", connector2) | ||
|
||
_, s1 := resolver.GetConnector("psql_node1") | ||
|
||
logger.Infof("Conn status node1 = %v", s1.Json()) | ||
|
||
_, s2 := resolver.GetConnector("psql_node2") | ||
|
||
logger.Infof("Conn status node2 = %v", s2.Json()) | ||
|
||
_, s := resolver.GetConnector("psql_node1") | ||
|
||
logger.Infof("Conn status node1 retake = %v", s.Json()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,25 @@ | ||
module github.com/sivaosorg/db.resolver | ||
|
||
go 1.20 | ||
|
||
require ( | ||
github.com/sivaosorg/govm v1.2.8 | ||
github.com/sivaosorg/mysqlconn v1.0.5 | ||
github.com/sivaosorg/postgresconn v1.0.7 | ||
) | ||
|
||
require ( | ||
github.com/fatih/color v1.16.0 // indirect | ||
github.com/go-sql-driver/mysql v1.7.1 // indirect | ||
github.com/jmoiron/sqlx v1.3.5 // indirect | ||
github.com/json-iterator/go v1.1.12 // indirect | ||
github.com/lib/pq v1.10.9 // indirect | ||
github.com/mattn/go-colorable v0.1.13 // indirect | ||
github.com/mattn/go-isatty v0.0.20 // indirect | ||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||
github.com/modern-go/reflect2 v1.0.2 // indirect | ||
github.com/natefinch/lumberjack v2.0.0+incompatible // indirect | ||
github.com/sirupsen/logrus v1.9.3 // indirect | ||
golang.org/x/sys v0.15.0 // indirect | ||
gopkg.in/guregu/null.v3 v3.5.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= | ||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= | ||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= | ||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= | ||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= | ||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= | ||
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= | ||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= | ||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= | ||
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-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= | ||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= | ||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= | ||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= | ||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= | ||
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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= | ||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= | ||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= | ||
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM= | ||
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= | ||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= | ||
github.com/sivaosorg/govm v1.2.8 h1:SyVwq7PNUKQQNqI9PbjZ6zY9b33lks75y/qzAzxDNyI= | ||
github.com/sivaosorg/govm v1.2.8/go.mod h1:rXfPCNGc4ddPf1+VRX8Ytw/5xqehfPRrCr53Oi+cwpw= | ||
github.com/sivaosorg/mysqlconn v1.0.5 h1:VHVfk6d6NQaMNsaLhojyzxF3PV+TA0I4wekIF5fU9QI= | ||
github.com/sivaosorg/mysqlconn v1.0.5/go.mod h1:oohoHcVTYlLw/ABOYgLRF/f4F2sQjbEOLPooxGyT9O8= | ||
github.com/sivaosorg/postgresconn v1.0.7 h1:36O2bVZdFzOqFPboyDZSp7BpZODrCRjj88KELG50ehQ= | ||
github.com/sivaosorg/postgresconn v1.0.7/go.mod h1:FfrmwVY0FjdFzU/fZJn5dvGyNBwa4l5HrIMQxIhDrgE= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= | ||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= | ||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/guregu/null.v3 v3.5.0 h1:xTcasT8ETfMcUHn0zTvIYtQud/9Mx5dJqD554SZct0o= | ||
gopkg.in/guregu/null.v3 v3.5.0/go.mod h1:E4tX2Qe3h7QdL+uZ3a0vqvYwKQsRSQKM5V4YltdgH9Y= | ||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= | ||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |