func (q *Qbs) WhereEqual(column string, value interface{}) *Qbs {
	q.criteria.condition = NewEqualCondition(column, value)
	return q
}
Snakecase column name
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
}