Skip to content

Commit

Permalink
[BreakChanges] Update QueryRow* APIs (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
linxGnu committed Jul 6, 2021
1 parent 7295fe3 commit 28dab12
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 96 deletions.
4 changes: 0 additions & 4 deletions balancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@ func newBalancer(ctx context.Context, numHealthChecker int, numDbInstance int, i
return c
}

func (c *balancer) size() int {
return c.dbs.size()
}

func (c *balancer) getHealthCheckPeriod() uint64 {
return atomic.LoadUint64(&c.healthCheckPeriod)
}
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ module github.com/linxGnu/mssqlx
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-sql-driver/mysql v1.6.0
github.com/jmoiron/sqlx v1.3.2-0.20210128211550-a1d5e6473423
github.com/lib/pq v1.10.0
github.com/mattn/go-sqlite3 v1.14.6
github.com/jmoiron/sqlx v1.3.4
github.com/lib/pq v1.10.2
github.com/mattn/go-sqlite3 v1.14.7
github.com/stretchr/testify v1.7.0
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
11 changes: 6 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/jmoiron/sqlx v1.3.2-0.20210128211550-a1d5e6473423 h1:5dW2FAtvUgEOn6kHCOW0ldbcFVEHDdjRlpdps/5HSLI=
github.com/jmoiron/sqlx v1.3.2-0.20210128211550-a1d5e6473423/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w=
github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.0 h1:Zx5DJFEYQXio93kgXnQ09fXNiUKsqv4OUEu2UtGcB1E=
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA=
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down
76 changes: 31 additions & 45 deletions mssqlx.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import (

var (
// ErrNetwork networking error
ErrNetwork = errors.New("Network error/Connection refused")
ErrNetwork = errors.New("network error/connection refused")

// ErrNoConnection there is no connection to db
ErrNoConnection = errors.New("No connection available")
ErrNoConnection = errors.New("no connection available")

// ErrNoConnectionOrWsrep there is no connection to db or Wsrep is not ready
ErrNoConnectionOrWsrep = errors.New("No connection available or Wsrep is not ready")
ErrNoConnectionOrWsrep = errors.New("no connection available or Wsrep is not ready")
)

const (
Expand Down Expand Up @@ -761,93 +761,79 @@ func (dbs *DBs) QueryxContextOnMaster(ctx context.Context, query string, args ..
return
}

func _queryRow(ctx context.Context, target *balancer, query string, args ...interface{}) (dbr *wrapper, res *sql.Row, err error) {
var w *wrapper

if w, err = getDBFromBalancer(target); err != nil {
reportError(query, err)
} else {
res, dbr = w.db.QueryRowContext(ctx, query, args...), w
func (dbs *DBs) _queryRow(ctx context.Context, target *balancer, query string, args ...interface{}) *sql.Row {
w, err := getDBFromBalancer(target)
if err != nil {
// no available node -> pick one
w = dbs._all[0]
}

return
return w.db.QueryRowContext(ctx, query, args...)
}

// QueryRow executes a query on slaves that is expected to return at most one row.
// QueryRow always returns a non-nil value. Errors are deferred until
// Row's Scan method is called.
func (dbs *DBs) QueryRow(query string, args ...interface{}) (r *sql.Row, err error) {
_, r, err = _queryRow(context.Background(), dbs.readBalancer(), query, args...)
return
func (dbs *DBs) QueryRow(query string, args ...interface{}) *sql.Row {
return dbs._queryRow(context.Background(), dbs.readBalancer(), query, args...)
}

// QueryRowOnMaster executes a query on masters that is expected to return at most one row.
// QueryRow always returns a non-nil value. Errors are deferred until
// Row's Scan method is called.
func (dbs *DBs) QueryRowOnMaster(query string, args ...interface{}) (r *sql.Row, err error) {
_, r, err = _queryRow(context.Background(), dbs.masters, query, args...)
return
func (dbs *DBs) QueryRowOnMaster(query string, args ...interface{}) *sql.Row {
return dbs._queryRow(context.Background(), dbs.masters, query, args...)
}

// QueryRowContext executes a query on slaves that is expected to return at most one row.
// QueryRow always returns a non-nil value. Errors are deferred until
// Row's Scan method is called.
func (dbs *DBs) QueryRowContext(ctx context.Context, query string, args ...interface{}) (r *sql.Row, err error) {
_, r, err = _queryRow(ctx, dbs.readBalancer(), query, args...)
return
func (dbs *DBs) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row {
return dbs._queryRow(ctx, dbs.readBalancer(), query, args...)
}

// QueryRowContextOnMaster executes a query on masters that is expected to return at most one row.
// QueryRow always returns a non-nil value. Errors are deferred until
// Row's Scan method is called.
func (dbs *DBs) QueryRowContextOnMaster(ctx context.Context, query string, args ...interface{}) (r *sql.Row, err error) {
_, r, err = _queryRow(ctx, dbs.masters, query, args...)
return
func (dbs *DBs) QueryRowContextOnMaster(ctx context.Context, query string, args ...interface{}) *sql.Row {
return dbs._queryRow(ctx, dbs.masters, query, args...)
}

func _queryRowx(ctx context.Context, target *balancer, query string, args ...interface{}) (dbr *wrapper, res *sqlx.Row, err error) {
var w *wrapper

if w, err = getDBFromBalancer(target); err != nil {
reportError(query, err)
} else {
res, dbr = w.db.QueryRowxContext(ctx, query, args...), w
func (dbs *DBs) _queryRowx(ctx context.Context, target *balancer, query string, args ...interface{}) *sqlx.Row {
w, err := getDBFromBalancer(target)
if err != nil {
// no available node -> pick one
w = dbs._all[0]
}

return
return w.db.QueryRowxContext(ctx, query, args...)
}

// QueryRowx executes a query on slaves that is expected to return at most one row.
// But return sqlx.Row instead of sql.Row.
// QueryRow always returns a non-nil value. Errors are deferred until
// Row's Scan method is called.
func (dbs *DBs) QueryRowx(query string, args ...interface{}) (r *sqlx.Row, err error) {
_, r, err = _queryRowx(context.Background(), dbs.readBalancer(), query, args...)
return
func (dbs *DBs) QueryRowx(query string, args ...interface{}) *sqlx.Row {
return dbs._queryRowx(context.Background(), dbs.readBalancer(), query, args...)
}

// QueryRowxOnMaster executes a query on masters that is expected to return at most one row.
// QueryRow always returns a non-nil value. Errors are deferred until
// Row's Scan method is called.
func (dbs *DBs) QueryRowxOnMaster(query string, args ...interface{}) (r *sqlx.Row, err error) {
_, r, err = _queryRowx(context.Background(), dbs.masters, query, args...)
return
func (dbs *DBs) QueryRowxOnMaster(query string, args ...interface{}) *sqlx.Row {
return dbs._queryRowx(context.Background(), dbs.masters, query, args...)
}

// QueryRowxContext executes a query on slaves that is expected to return at most one row.
// QueryRow always returns a non-nil value. Errors are deferred until
// Row's Scan method is called.
func (dbs *DBs) QueryRowxContext(ctx context.Context, query string, args ...interface{}) (r *sqlx.Row, err error) {
_, r, err = _queryRowx(ctx, dbs.readBalancer(), query, args...)
return
func (dbs *DBs) QueryRowxContext(ctx context.Context, query string, args ...interface{}) *sqlx.Row {
return dbs._queryRowx(ctx, dbs.readBalancer(), query, args...)
}

// QueryRowxContextOnMaster executes a query on masters that is expected to return at most one row.
// QueryRow always returns a non-nil value. Errors are deferred until
// Row's Scan method is called.
func (dbs *DBs) QueryRowxContextOnMaster(ctx context.Context, query string, args ...interface{}) (r *sqlx.Row, err error) {
_, r, err = _queryRowx(ctx, dbs.masters, query, args...)
return
func (dbs *DBs) QueryRowxContextOnMaster(ctx context.Context, query string, args ...interface{}) *sqlx.Row {
return dbs._queryRowx(ctx, dbs.masters, query, args...)
}

func _select(ctx context.Context, target *balancer, dest interface{}, query string, args ...interface{}) (dbr *wrapper, err error) {
Expand Down
53 changes: 22 additions & 31 deletions mssqlx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,18 @@ func TestParseError(t *testing.T) {
}
}

func (c *balancer) size() int {
return c.dbs.size()
}

func (b *dbList) size() (v int) {
list, stored := b.list.Load().([]*wrapper)
if stored {
v = len(list)
}
return
}

func TestDbBalancer(t *testing.T) {
dbB := newBalancer(context.Background(), 0, 4, true)

Expand Down Expand Up @@ -942,37 +954,16 @@ func TestNilReceivers(t *testing.T) {
t.Error("Expected error when getting into nil struct ptr.")
}

if _, err = db.QueryRow("SELECT * FROM person LIMIT 1"); err != nil {
t.Error("Fail query row")
}

if r, err := db.QueryRowOnMaster("SELECT * FROM person LIMIT 2"); err != nil || r == nil {
t.Error("Fail query row")
}

if _, err = db.QueryRowContext(context.Background(), "SELECT * FROM person LIMIT 1"); err != nil {
t.Error("Fail query row")
}

if r, err := db.QueryRowContextOnMaster(context.Background(), "SELECT * FROM person LIMIT 2"); err != nil || r == nil {
t.Error("Fail query row")
}

if _, err = db.QueryRowx("SELECT * FROM person LIMIT 1"); err != nil {
t.Error("Fail query row")
}

if r, err := db.QueryRowxOnMaster("SELECT * FROM person LIMIT 2"); err != nil || r == nil {
t.Error("Fail query row")
}

if _, err = db.QueryRowxContext(context.Background(), "SELECT * FROM person LIMIT 1"); err != nil {
t.Error("Fail query row")
}

if r, err := db.QueryRowxContextOnMaster(context.Background(), "SELECT * FROM person LIMIT 2"); err != nil || r == nil {
t.Error("Fail query row")
}
var num int
require.Nil(t, db.QueryRow("SELECT count(1) FROM person").Scan(&num))
require.True(t, num > 0)
require.NotNil(t, db.QueryRowOnMaster("SELECT * FROM person LIMIT 2"))
require.NotNil(t, db.QueryRowContext(context.Background(), "SELECT * FROM person LIMIT 1"))
require.NotNil(t, db.QueryRowContextOnMaster(context.Background(), "SELECT * FROM person LIMIT 2"))
require.NotNil(t, db.QueryRowx("SELECT * FROM person LIMIT 1"))
require.NotNil(t, db.QueryRowxOnMaster("SELECT * FROM person LIMIT 2"))
require.NotNil(t, db.QueryRowxContext(context.Background(), "SELECT * FROM person LIMIT 1"))
require.NotNil(t, db.QueryRowxContextOnMaster(context.Background(), "SELECT * FROM person LIMIT 2"))

var pp *[]Person
if err = db.Select(pp, "SELECT * FROM person"); err == nil {
Expand Down
8 changes: 0 additions & 8 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,6 @@ type dbList struct {
_ [9]uint64
}

func (b *dbList) size() (v int) {
list, stored := b.list.Load().([]*wrapper)
if stored {
v = len(list)
}
return
}

func (b *dbList) current() (w *wrapper) {
list, stored := b.list.Load().([]*wrapper)
if stored {
Expand Down

0 comments on commit 28dab12

Please sign in to comment.