func (q *Qbs) QueryRow(query string, args ...interface{}) *sql.Row {
	q.log(query, args...)
	query = q.Dialect.substituteMarkers(query)
	stmt, err := q.prepare(query)
	if err != nil {
		q.updateTxError(err)
		return nil
	}
	return stmt.QueryRow(args...)
}
Same as sql.Db.QueryRow or sql.Tx.QueryRow depends on if transaction has began
package qbs
import (
	"database/sql"
	"errors"
	"fmt"
	"log"
	"os"
	"reflect"
	"strings"
	"sync"
	"time"
)
var driver, driverSource, dbName string
var dial Dialect
var connectionLimit chan struct{}
var blockingOnLimit bool
var ConnectionLimitError = errors.New("Connection limit reached")
var db *sql.DB
var stmtMap map[string]*sql.Stmt
var mu *sync.RWMutex
var queryLogger *log.Logger = log.New(os.Stdout, "qbs:", log.LstdFlags)
var errorLogger *log.Logger = log.New(os.Stderr, "qbs:", log.LstdFlags)
type Qbs struct {
	Dialect      Dialect
	Log          bool  
	tx           *sql.Tx
	txStmtMap    map[string]*sql.Stmt
	criteria     *criteria
	firstTxError error
}
type Validator interface {
	Validate(*Qbs) error
}
func Register(driverName, driverSourceName, databaseName string, dialect Dialect) {
	driverSource = driverSourceName
	dbName = databaseName
	if db == nil {
		var err error
		var database *sql.DB
		database, err = sql.Open(driverName, driverSource)
		if err != nil {
			panic(err)
		}
		RegisterWithDb(driverName, database, dialect)
	}
}
func RegisterWithDb(driverName string, database *sql.DB, dialect Dialect) {
	driver = driverName
	dial = dialect
	db = database
	db.SetMaxIdleConns(100)
	stmtMap = make(map[string]*sql.Stmt)
	mu = new(sync.RWMutex)
}
func WithQbs(task func(*Qbs) error) error {
	q, err := GetQbs()
	if err != nil {
		return err
	}
	defer q.Close()
	return task(q)
}
func GetQbs() (q *Qbs, err error) {
	if driver == "" || dial == nil {
		panic("database driver has not been registered, should call Register first.")
	}
	if connectionLimit != nil {
		if blockingOnLimit {
			connectionLimit <- struct{}{}
		} else {
			select {
			case connectionLimit <- struct{}{}:
			default:
				return nil, ConnectionLimitError
			}
		}
	}
	q = new(Qbs)
	q.Dialect = dial
	q.criteria = new(criteria)
	return q, nil
}
func ChangePoolSize(size int) {
	db.SetMaxIdleConns(size)
}
func SetLogger(query *log.Logger, err *log.Logger) {
	queryLogger = query
	errorLogger = err
}
func SetConnectionLimit(maxCon int, blocking bool) {
	if maxCon > 0 {
		connectionLimit = make(chan struct{}, maxCon)
	} else if maxCon < 0 {
		connectionLimit = nil
	}
	blockingOnLimit = blocking
}
func (q *Qbs) Reset() {
	q.criteria = new(criteria)
}
func (q *Qbs) Begin() error {
	if q.tx != nil {
		panic("cannot start nested transaction")
	}
	tx, err := db.Begin()
	q.tx = tx
	q.txStmtMap = make(map[string]*sql.Stmt)
	return err
}
func (q *Qbs) InTransaction() bool {
	return q.tx != nil
}
func (q *Qbs) updateTxError(e error) error {
	if e != nil {
		if errorLogger != nil {
			errorLogger.Println(e)
		}
		if q.firstTxError == nil {
			q.firstTxError = e
		}
	}
	return e
}
func (q *Qbs) Commit() error {
	err := q.tx.Commit()
	q.updateTxError(err)
	q.tx = nil
	for _, v := range q.txStmtMap {
		v.Close()
	}
	q.txStmtMap = nil
	return q.firstTxError
}
func (q *Qbs) Rollback() error {
	err := q.tx.Rollback()
	q.tx = nil
	for _, v := range q.txStmtMap {
		v.Close()
	}
	q.txStmtMap = nil
	return q.updateTxError(err)
}
func (q *Qbs) Where(expr string, args ...interface{}) *Qbs {
	q.criteria.condition = NewCondition(expr, args...)
	return q
}
func (q *Qbs) WhereEqual(column string, value interface{}) *Qbs {
	q.criteria.condition = NewEqualCondition(column, value)
	return q
}
func (q *Qbs) WhereIn(column string, values []interface{}) *Qbs {
	q.criteria.condition = NewInCondition(column, values)
	return q
}
func (q *Qbs) Condition(condition *Condition) *Qbs {
	q.criteria.condition = condition
	return q
}
func (q *Qbs) Limit(limit int) *Qbs {
	q.criteria.limit = limit
	return q
}
func (q *Qbs) Offset(offset int) *Qbs {
	q.criteria.offset = offset
	return q
}
func (q *Qbs) OrderBy(path string) *Qbs {
	q.criteria.orderBys = append(q.criteria.orderBys, order{q.Dialect.quote(path), false})
	return q
}
func (q *Qbs) OrderByDesc(path string) *Qbs {
	q.criteria.orderBys = append(q.criteria.orderBys, order{q.Dialect.quote(path), true})
	return q
}
func (q *Qbs) OmitFields(fieldName ...string) *Qbs {
	q.criteria.omitFields = fieldName
	return q
}
func (q *Qbs) OmitJoin() *Qbs {
	q.criteria.omitJoin = true
	return q
}
func (q *Qbs) Find(structPtr interface{}) error {
	q.criteria.model = structPtrToModel(structPtr, !q.criteria.omitJoin, q.criteria.omitFields)
	q.criteria.limit = 1
	if !q.criteria.model.pkZero() {
		idPath := q.Dialect.quote(q.criteria.model.table) + "." + q.Dialect.quote(q.criteria.model.pk.name)
		idCondition := NewCondition(idPath+" = ?", q.criteria.model.pk.value)
		if q.criteria.condition == nil {
			q.criteria.condition = idCondition
		} else {
			q.criteria.condition = idCondition.AndCondition(q.criteria.condition)
		}
	}
	query, args := q.Dialect.querySql(q.criteria)
	return q.doQueryRow(structPtr, query, args...)
}
func (q *Qbs) FindAll(ptrOfSliceOfStructPtr interface{}) error {
	strucType := reflect.TypeOf(ptrOfSliceOfStructPtr).Elem().Elem().Elem()
	strucPtr := reflect.New(strucType).Interface()
	q.criteria.model = structPtrToModel(strucPtr, !q.criteria.omitJoin, q.criteria.omitFields)
	query, args := q.Dialect.querySql(q.criteria)
	return q.doQueryRows(ptrOfSliceOfStructPtr, query, args...)
}
func (q *Qbs) doQueryRow(out interface{}, query string, args ...interface{}) error {
	defer q.Reset()
	rowValue := reflect.ValueOf(out)
	q.log(query, args...)
	stmt, err := q.prepare(query)
	if err != nil {
		return q.updateTxError(err)
	}
	rows, err := stmt.Query(args...)
	if err != nil {
		return q.updateTxError(err)
	}
	defer rows.Close()
	if rows.Next() {
		err = q.scanRows(rowValue, rows)
		if err != nil {
			return err
		}
	} else {
		return sql.ErrNoRows
	}
	return nil
}
func (q *Qbs) doQueryRows(out interface{}, query string, args ...interface{}) error {
	defer q.Reset()
	sliceValue := reflect.Indirect(reflect.ValueOf(out))
	structType := sliceValue.Type().Elem().Elem()
	q.log(query, args...)
	stmt, err := q.prepare(query)
	if err != nil {
		return q.updateTxError(err)
	}
	rows, err := stmt.Query(args...)
	if err != nil {
		return q.updateTxError(err)
	}
	defer rows.Close()
	for rows.Next() {
		rowValue := reflect.New(structType)
		err = q.scanRows(rowValue, rows)
		if err != nil {
			return err
		}
		sliceValue.Set(reflect.Append(sliceValue, rowValue))
	}
	return nil
}
func (q *Qbs) scanRows(rowValue reflect.Value, rows *sql.Rows) (err error) {
	cols, _ := rows.Columns()
	containers := make([]interface{}, 0, len(cols))
	for i := 0; i < cap(containers); i++ {
		var v interface{}
		containers = append(containers, &v)
	}
	err = rows.Scan(containers...)
	if err != nil {
		return
	}
	for i, v := range containers {
		value := reflect.Indirect(reflect.ValueOf(v))
		if !value.Elem().IsValid() {
			continue
		}
		key := cols[i]
		paths := strings.Split(key, "___")
		if len(paths) == 2 {
			subStruct := rowValue.Elem().FieldByName(TableNameToStructName(paths[0]))
			if subStruct.IsNil() {
				subStruct.Set(reflect.New(subStruct.Type().Elem()))
			}
			subField := subStruct.Elem().FieldByName(ColumnNameToFieldName(paths[1]))
			if subField.IsValid() {
				err = q.Dialect.setModelValue(value, subField)
				if err != nil {
					return
				}
			}
		} else {
			field := rowValue.Elem().FieldByName(ColumnNameToFieldName(key))
			if field.IsValid() {
				err = q.Dialect.setModelValue(value, field)
				if err != nil {
					return
				}
			}
		}
	}
	return
}
func (q *Qbs) Exec(query string, args ...interface{}) (sql.Result, error) {
	defer q.Reset()
	query = q.Dialect.substituteMarkers(query)
	q.log(query, args...)
	stmt, err := q.prepare(query)
	if err != nil {
		return nil, q.updateTxError(err)
	}
	result, err := stmt.Exec(args...)
	if err != nil {
		return nil, q.updateTxError(err)
	}
	return result, nil
}