func (dbs *DBs) MapperFunc(mf func(string) string) {
	_mapperFunc(dbs._all, mf)
}
MapperFunc sets a new mapper for this db using the default sqlx struct tag
and the provided mapper function.
package mssqlx
import (
	"context"
	"database/sql"
	"errors"
	"os"
	"sync"
	"time"
	"github.com/hashicorp/go-multierror"
	"github.com/jmoiron/sqlx"
)
var (
	ErrNoConnection = errors.New("no connection available")
	ErrNoConnectionOrWsrep = errors.New("no connection available or Wsrep is not ready")
)
const (
	DefaultHealthCheckPeriodInMilli = 40
)
var hostName string
func init() {
	hostName, _ = os.Hostname()
}
func ping(w *wrapper) (err error) {
	_, err = w.db.Exec("SELECT 1")
	return
}
type DBs struct {
	driverName      string
	readQuerySource ReadQuerySource
	masters *balancer
	slaves  *balancer
	all     *balancer
	_masters []*wrapper
	_slaves  []*wrapper
	_all     []*wrapper
}
func (dbs *DBs) DriverName() string {
	return dbs.driverName
}
func (dbs *DBs) getDBs(s []*wrapper) ([]*sqlx.DB, int) {
	n := len(s)
	r := make([]*sqlx.DB, n)
	for i, v := range s {
		r[i] = v.db
	}
	return r, n
}
func (dbs *DBs) readBalancer() *balancer {
	if dbs.readQuerySource == ReadQuerySourceAll {
		return dbs.all
	}
	return dbs.slaves
}
func (dbs *DBs) GetAllMasters() ([]*sqlx.DB, int) {
	return dbs.getDBs(dbs._masters)
}
func (dbs *DBs) GetAllSlaves() ([]*sqlx.DB, int) {
	return dbs.getDBs(dbs._slaves)
}
func _ping(target []*wrapper) []error {
	if target == nil {
		return nil
	}
	nn := len(target)
	if nn == 0 {
		return nil
	}
	errResult := make([]error, nn)
	var wg sync.WaitGroup
	for i := range target {
		if target[i] != nil && target[i].db != nil {
			wg.Add(1)
			go func(ind int, wg *sync.WaitGroup) {
				errResult[ind] = target[ind].db.Ping()
				wg.Done()
			}(i, &wg)
		}
	}
	wg.Wait()
	return errResult
}
func (dbs *DBs) Ping() []error {
	return _ping(dbs._all)
}
func (dbs *DBs) PingMaster() []error {
	return _ping(dbs._masters)
}
func (dbs *DBs) PingSlave() []error {
	return _ping(dbs._slaves)
}
func _close(target []*wrapper) []error {
	if target == nil {
		return nil
	}
	nn := len(target)
	if nn == 0 {
		return nil
	}
	errResult := make([]error, nn)
	var wg sync.WaitGroup
	for i, db := range target {
		if db != nil && db.db != nil {
			wg.Add(1)
			go func(db *wrapper, ind int, wg *sync.WaitGroup) {
				errResult[ind] = db.db.Close()
				wg.Done()
			}(db, i, &wg)
		}
	}
	wg.Wait()
	return errResult
}
func (dbs *DBs) Destroy() []error {
	res := _close(dbs._all)
	if dbs.masters != nil {
		dbs.masters.destroy()
	}
	if dbs.slaves != nil {
		dbs.slaves.destroy()
	}
	dbs.all.destroy()
	return res
}
func (dbs *DBs) DestroyMaster() []error {
	if dbs.masters != nil {
		dbs.masters.destroy()
	}
	return _close(dbs._masters)
}
func (dbs *DBs) DestroySlave() []error {
	if dbs.slaves != nil {
		dbs.slaves.destroy()
	}
	return _close(dbs._slaves)
}
func _setMaxIdleConns(target []*wrapper, n int) {
	if target == nil {
		return
	}
	nn := len(target)
	if nn == 0 {
		return
	}
	var wg sync.WaitGroup
	for _, db := range target {
		if db != nil && db.db != nil {
			wg.Add(1)
			go func(db *wrapper, wg *sync.WaitGroup) {
				db.db.SetMaxIdleConns(n)
				wg.Done()
			}(db, &wg)
		}
	}
	wg.Wait()
}
func (dbs *DBs) SetHealthCheckPeriod(period uint64) {
	dbs.masters.setHealthCheckPeriod(period)
	dbs.slaves.setHealthCheckPeriod(period)
}
func (dbs *DBs) SetMasterHealthCheckPeriod(period uint64) {
	dbs.masters.setHealthCheckPeriod(period)
}
func (dbs *DBs) SetSlaveHealthCheckPeriod(period uint64) {
	dbs.slaves.setHealthCheckPeriod(period)
}
func (dbs *DBs) SetMaxIdleConns(n int) {
	_setMaxIdleConns(dbs._all, n)
}
func (dbs *DBs) SetMasterMaxIdleConns(n int) {
	_setMaxIdleConns(dbs._masters, n)
}
func (dbs *DBs) SetSlaveMaxIdleConns(n int) {
	_setMaxIdleConns(dbs._slaves, n)
}
func _setMaxOpenConns(target []*wrapper, n int) {
	if target == nil {
		return
	}
	nn := len(target)
	if nn == 0 {
		return
	}
	var wg sync.WaitGroup
	for _, db := range target {
		if db != nil && db.db != nil {
			wg.Add(1)
			go func(db *wrapper, wg *sync.WaitGroup) {
				db.db.SetMaxOpenConns(n)
				wg.Done()
			}(db, &wg)
		}
	}
	wg.Wait()
}
func (dbs *DBs) SetMaxOpenConns(n int) {
	_setMaxOpenConns(dbs._all, n)
}
func (dbs *DBs) SetMasterMaxOpenConns(n int) {
	_setMaxOpenConns(dbs._masters, n)
}
func (dbs *DBs) SetSlaveMaxOpenConns(n int) {
	_setMaxOpenConns(dbs._slaves, n)
}
func _setConnMaxLifetime(target []*wrapper, d time.Duration) {
	if target == nil {
		return
	}
	nn := len(target)
	if nn == 0 {
		return
	}
	var wg sync.WaitGroup
	for _, db := range target {
		if db != nil && db.db != nil {
			wg.Add(1)
			go func(db *wrapper, wg *sync.WaitGroup) {
				db.db.SetConnMaxLifetime(d)
				wg.Done()
			}(db, &wg)
		}
	}
	wg.Wait()
}
func (dbs *DBs) SetConnMaxLifetime(d time.Duration) {
	_setConnMaxLifetime(dbs._all, d)
}
func (dbs *DBs) SetMasterConnMaxLifetime(d time.Duration) {
	_setConnMaxLifetime(dbs._masters, d)
}
func (dbs *DBs) SetSlaveConnMaxLifetime(d time.Duration) {
	_setConnMaxLifetime(dbs._slaves, d)
}
func _stats(target []*wrapper) []sql.DBStats {
	if target == nil {
		return nil
	}
	nn := len(target)
	if nn == 0 {
		return nil
	}
	result := make([]sql.DBStats, nn)
	var wg sync.WaitGroup
	for ind, db := range target {
		if db != nil && db.db != nil {
			wg.Add(1)
			go func(db *wrapper, ind int, wg *sync.WaitGroup) {
				result[ind] = db.db.Stats()
				wg.Done()
			}(db, ind, &wg)
		}
	}
	wg.Wait()
	return result
}
func (dbs *DBs) Stats() (stats []sql.DBStats) {
	stats = _stats(dbs._all)
	return
}
func (dbs *DBs) StatsMaster() (stats []sql.DBStats) {
	stats = _stats(dbs._masters)
	return
}
func (dbs *DBs) StatsSlave() (stats []sql.DBStats) {
	stats = _stats(dbs._slaves)
	return
}
func _mapperFunc(target []*wrapper, mf func(string) string) {
	if target == nil {
		return
	}
	nn := len(target)
	if nn == 0 {
		return
	}
	var wg sync.WaitGroup
	for ind, db := range target {
		if db != nil {
			wg.Add(1)
			go func(db *wrapper, ind int) {
				db.db.MapperFunc(mf)
				wg.Done()
			}(db, ind)
		}
	}
	wg.Wait()
}