@@ -40,7 +40,8 @@ func ping(w *wrapper) (err error) {
4040
4141// DBs sqlx wrapper supports querying master-slave database connections for HA and scalability, auto-balancer integrated.
4242type DBs struct {
43- driverName string
43+ driverName string
44+ readQuerySource ReadQuerySource
4445
4546 masters * balancer
4647 slaves * balancer
@@ -65,6 +66,13 @@ func (dbs *DBs) getDBs(s []*wrapper) ([]*sqlx.DB, int) {
6566 return r , n
6667}
6768
69+ func (dbs * DBs ) readBalancer () * balancer {
70+ if dbs .readQuerySource == ReadQuerySourceAll {
71+ return dbs .all
72+ }
73+ return dbs .slaves
74+ }
75+
6876// GetAllMasters get all master database connections, included failing one.
6977func (dbs * DBs ) GetAllMasters () ([]* sqlx.DB , int ) {
7078 return dbs .getDBs (dbs ._masters )
@@ -590,7 +598,7 @@ func _namedQuery(ctx context.Context, target *balancer, query string, arg interf
590598// NamedQuery do named query.
591599// Any named placeholder parameters are replaced with fields from arg.
592600func (dbs * DBs ) NamedQuery (query string , arg interface {}) (* sqlx.Rows , error ) {
593- return _namedQuery (context .Background (), dbs .slaves , query , arg )
601+ return _namedQuery (context .Background (), dbs .readBalancer () , query , arg )
594602}
595603
596604// NamedQueryOnMaster do named query on master.
@@ -602,7 +610,7 @@ func (dbs *DBs) NamedQueryOnMaster(query string, arg interface{}) (*sqlx.Rows, e
602610// NamedQueryContext do named query with context.
603611// Any named placeholder parameters are replaced with fields from arg.
604612func (dbs * DBs ) NamedQueryContext (ctx context.Context , query string , arg interface {}) (* sqlx.Rows , error ) {
605- return _namedQuery (ctx , dbs .slaves , query , arg )
613+ return _namedQuery (ctx , dbs .readBalancer () , query , arg )
606614}
607615
608616// NamedQueryContextOnMaster do named query with context on master.
@@ -699,7 +707,7 @@ func _query(ctx context.Context, target *balancer, query string, args ...interfa
699707// Query executes a query on slaves that returns rows, typically a SELECT.
700708// The args are for any placeholder parameters in the query.
701709func (dbs * DBs ) Query (query string , args ... interface {}) (r * sql.Rows , err error ) {
702- _ , r , err = _query (context .Background (), dbs .slaves , query , args ... )
710+ _ , r , err = _query (context .Background (), dbs .readBalancer () , query , args ... )
703711 return
704712}
705713
@@ -713,7 +721,7 @@ func (dbs *DBs) QueryOnMaster(query string, args ...interface{}) (r *sql.Rows, e
713721// QueryContext executes a query on slaves that returns rows, typically a SELECT.
714722// The args are for any placeholder parameters in the query.
715723func (dbs * DBs ) QueryContext (ctx context.Context , query string , args ... interface {}) (r * sql.Rows , err error ) {
716- _ , r , err = _query (ctx , dbs .slaves , query , args ... )
724+ _ , r , err = _query (ctx , dbs .readBalancer () , query , args ... )
717725 return
718726}
719727
@@ -758,7 +766,7 @@ func _queryx(ctx context.Context, target *balancer, query string, args ...interf
758766// Queryx executes a query on slaves that returns rows, typically a SELECT.
759767// The args are for any placeholder parameters in the query.
760768func (dbs * DBs ) Queryx (query string , args ... interface {}) (r * sqlx.Rows , err error ) {
761- _ , r , err = _queryx (context .Background (), dbs .slaves , query , args ... )
769+ _ , r , err = _queryx (context .Background (), dbs .readBalancer () , query , args ... )
762770 return
763771}
764772
@@ -772,7 +780,7 @@ func (dbs *DBs) QueryxOnMaster(query string, args ...interface{}) (r *sqlx.Rows,
772780// QueryxContext executes a query on slaves that returns rows, typically a SELECT.
773781// The args are for any placeholder parameters in the query.
774782func (dbs * DBs ) QueryxContext (ctx context.Context , query string , args ... interface {}) (r * sqlx.Rows , err error ) {
775- _ , r , err = _queryx (ctx , dbs .slaves , query , args ... )
783+ _ , r , err = _queryx (ctx , dbs .readBalancer () , query , args ... )
776784 return
777785}
778786
@@ -801,7 +809,7 @@ func _queryRow(ctx context.Context, target *balancer, query string, args ...inte
801809// QueryRow always returns a non-nil value. Errors are deferred until
802810// Row's Scan method is called.
803811func (dbs * DBs ) QueryRow (query string , args ... interface {}) (r * sql.Row , err error ) {
804- _ , r , err = _queryRow (context .Background (), dbs .slaves , query , args ... )
812+ _ , r , err = _queryRow (context .Background (), dbs .readBalancer () , query , args ... )
805813 return
806814}
807815
@@ -817,7 +825,7 @@ func (dbs *DBs) QueryRowOnMaster(query string, args ...interface{}) (r *sql.Row,
817825// QueryRow always returns a non-nil value. Errors are deferred until
818826// Row's Scan method is called.
819827func (dbs * DBs ) QueryRowContext (ctx context.Context , query string , args ... interface {}) (r * sql.Row , err error ) {
820- _ , r , err = _queryRow (ctx , dbs .slaves , query , args ... )
828+ _ , r , err = _queryRow (ctx , dbs .readBalancer () , query , args ... )
821829 return
822830}
823831
@@ -848,7 +856,7 @@ func _queryRowx(ctx context.Context, target *balancer, query string, args ...int
848856// QueryRow always returns a non-nil value. Errors are deferred until
849857// Row's Scan method is called.
850858func (dbs * DBs ) QueryRowx (query string , args ... interface {}) (r * sqlx.Row , err error ) {
851- _ , r , err = _queryRowx (context .Background (), dbs .slaves , query , args ... )
859+ _ , r , err = _queryRowx (context .Background (), dbs .readBalancer () , query , args ... )
852860 return
853861}
854862
@@ -864,7 +872,7 @@ func (dbs *DBs) QueryRowxOnMaster(query string, args ...interface{}) (r *sqlx.Ro
864872// QueryRow always returns a non-nil value. Errors are deferred until
865873// Row's Scan method is called.
866874func (dbs * DBs ) QueryRowxContext (ctx context.Context , query string , args ... interface {}) (r * sqlx.Row , err error ) {
867- _ , r , err = _queryRowx (ctx , dbs .slaves , query , args ... )
875+ _ , r , err = _queryRowx (ctx , dbs .readBalancer () , query , args ... )
868876 return
869877}
870878
@@ -904,7 +912,7 @@ func _select(ctx context.Context, target *balancer, dest interface{}, query stri
904912// Select do select on slaves.
905913// Any placeholder parameters are replaced with supplied args.
906914func (dbs * DBs ) Select (dest interface {}, query string , args ... interface {}) (err error ) {
907- _ , err = _select (context .Background (), dbs .slaves , dest , query , args ... )
915+ _ , err = _select (context .Background (), dbs .readBalancer () , dest , query , args ... )
908916 return
909917}
910918
@@ -918,7 +926,7 @@ func (dbs *DBs) SelectOnMaster(dest interface{}, query string, args ...interface
918926// SelectContext do select on slaves with context.
919927// Any placeholder parameters are replaced with supplied args.
920928func (dbs * DBs ) SelectContext (ctx context.Context , dest interface {}, query string , args ... interface {}) (err error ) {
921- _ , err = _select (ctx , dbs .slaves , dest , query , args ... )
929+ _ , err = _select (ctx , dbs .readBalancer () , dest , query , args ... )
922930 return
923931}
924932
@@ -974,7 +982,7 @@ func (dbs *DBs) GetOnMaster(dest interface{}, query string, args ...interface{})
974982// Any placeholder parameters are replaced with supplied args.
975983// An error is returned if the result set is empty.
976984func (dbs * DBs ) GetContext (ctx context.Context , dest interface {}, query string , args ... interface {}) (err error ) {
977- _ , err = _get (ctx , dbs .slaves , dest , query , args ... )
985+ _ , err = _get (ctx , dbs .readBalancer () , dest , query , args ... )
978986 return
979987}
980988
@@ -1440,9 +1448,8 @@ func (dbs *DBs) BeginTxx(ctx context.Context, opts *sql.TxOptions) (res *sqlx.Tx
14401448// ConnectMasterSlaves to master-slave databases, healthchecks will ensure they are working
14411449// driverName: mysql, postgres, etc.
14421450// masterDSNs: data source names of Masters.
1443- // slaveDSNs: data source names of Slaves.
1444- // args: args[0] = true to indicates galera/wsrep cluster.
1445- func ConnectMasterSlaves (driverName string , masterDSNs []string , slaveDSNs []string , args ... interface {}) (* DBs , []error ) {
1451+ // slaveDSNs: data source names of ReadQuerySourceSlaves.
1452+ func ConnectMasterSlaves (driverName string , masterDSNs []string , slaveDSNs []string , options ... Option ) (* DBs , []error ) {
14461453 // Validate slave address
14471454 if slaveDSNs == nil {
14481455 slaveDSNs = []string {}
@@ -1452,12 +1459,14 @@ func ConnectMasterSlaves(driverName string, masterDSNs []string, slaveDSNs []str
14521459 masterDSNs = []string {}
14531460 }
14541461
1455- isWsrep := false
1456- if len (args ) > 0 {
1457- switch args [0 ].(type ) {
1458- case bool :
1459- isWsrep = args [0 ].(bool )
1460- }
1462+ // default cluster options
1463+ opts := & clusterOptions {
1464+ isWsrep : false ,
1465+ readQuerySource : ReadQuerySourceSlaves ,
1466+ }
1467+
1468+ for _ , optFn := range options {
1469+ optFn (opts )
14611470 }
14621471
14631472 nMaster := len (masterDSNs )
@@ -1466,15 +1475,16 @@ func ConnectMasterSlaves(driverName string, masterDSNs []string, slaveDSNs []str
14661475
14671476 errResult := make ([]error , nAll )
14681477 dbs := & DBs {
1469- driverName : driverName ,
1478+ driverName : driverName ,
1479+ readQuerySource : opts .readQuerySource ,
14701480
1471- masters : newBalancer (nil , nMaster >> 2 , nMaster , isWsrep ),
1481+ masters : newBalancer (nil , nMaster >> 2 , nMaster , opts . isWsrep ),
14721482 _masters : make ([]* wrapper , nMaster ),
14731483
1474- slaves : newBalancer (nil , nSlave >> 2 , nSlave , isWsrep ),
1484+ slaves : newBalancer (nil , nSlave >> 2 , nSlave , opts . isWsrep ),
14751485 _slaves : make ([]* wrapper , nSlave ),
14761486
1477- all : newBalancer (nil , nAll >> 2 , nAll , isWsrep ),
1487+ all : newBalancer (nil , nAll >> 2 , nAll , opts . isWsrep ),
14781488 _all : make ([]* wrapper , nAll ),
14791489 }
14801490
0 commit comments