Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BreakChanges] Update QueryRow* APIs #12

Merged
merged 4 commits into from
Jul 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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