func (b *Builder) LeftJoin(table, first, operator string, second ...string) *Builder {
	return b.join(table, first, operator, dealValues(second...), "left")
}
LeftJoin left join
package builder
import (
	"strconv"
	"strings"
	"sync"
)
var operators = []string{
	"=", "<", ">", "<=", ">=", "<>", "!=", "<=>",
	"like", "like binary", "not like", "ilike",
	"&", "|", "^", "<<", ">>",
	"rlike", "regexp", "not regexp",
	"~", "~*", "!~", "!~*", "similar to",
	"not similar to", "not ilike", "~~*", "!~~*"}
type Builder struct {
	Connection       Connector      
	PSql             string         
	PArgs            []interface{}  
	Aggregate        map[string]string
	Columns          []string             
	Values           []map[string]string  
	IsDistinct       bool                 
	FromTable        string               
	Groups           []string             
	LimitNum         int                  
	OffsetNum        int                  
	Unions           map[string]interface{}
	UnionLimitNum    int
	UnionOffsetNum   int
	UnionOrders      map[string]interface{}
	Lock             map[string]interface{}
	Operators        map[string]interface{}
	Components       map[string][]map[string]string  
	SelectComponents []string                        
	UseWrite         bool                            
	mu               sync.Mutex
	debug            bool
}
func New(c Connector) *Builder {
	return &Builder{
		Connection: c,
		Components: map[string][]map[string]string{},
		SelectComponents: []string{
			"aggregate",
			"columns",
			"from",
			"joins",
			"wheres",
			"groups",
			"havings",
			"orders",
			"limit",
			"offset",
			"unions",
			"lock",
		}}
}
func (b *Builder) Reset() {
	var pa []interface{}
	b.Aggregate = map[string]string{}
	b.Columns = []string{}
	b.Values = []map[string]string{}
	b.IsDistinct = false
	b.FromTable = ""
	b.PArgs = pa
	b.Groups = []string{}
	b.LimitNum = 0
	b.OffsetNum = 0
	b.Unions = map[string]interface{}{}
	b.UnionLimitNum = 0
	b.UnionOffsetNum = 0
	b.UnionOrders = map[string]interface{}{}
	b.Lock = map[string]interface{}{}
	b.Operators = map[string]interface{}{}
	b.Components = map[string][]map[string]string{}
	b.UseWrite = false
	b.debug = false
	b.mu.Unlock()
}
func (b *Builder) Debug(bo ...bool) *Builder {
	b.debug = true
	if bo != nil && bo[0] == false {
		b.debug = false
	}
	return b
}
func (b *Builder) Insert(values []map[string]string) int64 {
	b.Values = values
	return b.Connection.Insert()
}
func (b *Builder) InsertOne(value map[string]string) int64 {
	b.Values = append(b.Values, value)
	return b.Connection.Insert()
}
func (b *Builder) Update(value map[string]string) int64 {
	b.Values = append(b.Values, value)
	return b.Connection.Update()
}
func (b *Builder) Increment(column string, amount ...string) bool {
	num := " + 1"
	if amount != nil {
		num = " + " + amount[0]
	}
	columns := map[string]string{
		column: column + num,
	}
	return b.Update(columns) > 0
}
func (b *Builder) Exists() bool {
	if b.Columns == nil {
		b.Columns = append(b.Columns, "*")
		b.Components["columns"] = nil
	}
	return b.Connection.Exists()
}
func (b *Builder) RunSelect() []map[string]interface{} { return b.Connection.Select(true) }
func (b *Builder) Delete() int64 { return b.Connection.Delete() }
func (b *Builder) UseWriteDB() { b.UseWrite = true }
func invalidOperatorAndValue(operator, value string) bool {
	hasop, nc := false, false
	for _, v := range operators {
		if operator == v {
			hasop = true
		}
	}
	for _, v := range []string{"=", "<>", "!="} {
		if operator != v {
			nc = true
		}
	}
	return value == "" && hasop && nc
}
func (b *Builder) invalidOperator(operator string) bool {
	op := strings.ToLower(operator)
	inOp := true
	for _, v := range operators {
		if op == v {
			inOp = false
		}
	}
	return inOp
}
func (b *Builder) GroupBy(column string) *Builder {
	b.Groups = append(b.Groups, column)
	b.Components["groups"] = nil
	return b
}
func (b *Builder) OrderBy(column string, direction ...string) *Builder {
	if direction == nil {
		direction = append(direction, "asc")
	} else {
		direction[0] = strings.ToLower(direction[0])
	}
	order := map[string]string{
		"column":    column,
		"direction": direction[0],
	}
	b.Components["orders"] = append(b.Components["orders"], order)
	return b
}
func (b *Builder) OrderByDesc(column string) *Builder { return b.OrderBy(column, "desc") }
func (b *Builder) WhereNotBetween(column string, values ...string) *Builder {
	return b.whereBetweenOrIn("Between", column, values, "and", true)
}
func (b *Builder) OrWhereNotBetween(column string, values ...string) *Builder {
	return b.whereBetweenOrIn("Between", column, values, "or", true)
}
func (b *Builder) WhereBetween(column string, values ...string) *Builder {
	return b.whereBetweenOrIn("Between", column, values, "and")
}
func (b *Builder) OrWhereBetween(column string, values ...string) *Builder {
	return b.whereBetweenOrIn("Between", column, values, "or")
}
func (b *Builder) WhereIn(column string, values ...string) *Builder {
	return b.whereBetweenOrIn("In", column, values, "and")
}
func (b *Builder) OrWhereIn(column string, values ...string) *Builder {
	return b.whereBetweenOrIn("In", column, values, "or")
}
func (b *Builder) WhereNotIn(column string, values ...string) *Builder {
	return b.whereBetweenOrIn("In", column, values, "and", true)
}
func (b *Builder) OrWhereNotIn(column string, values ...string) *Builder {
	return b.whereBetweenOrIn("In", column, values, "or", true)
}
func (b *Builder) whereBetweenOrIn(whereDateType, column string, values []string, logical string, isNot ...bool) *Builder {
	var not bool
	if isNot != nil && isNot[0] {
		not = true
	}
	where := map[string]string{
		"type":    whereDateType,
		"column":  column,
		"not":     strconv.FormatBool(not),
		"logical": logical,
		"value":   strings.Join(values, ","),
	}
	b.Components["wheres"] = append(b.Components["wheres"], where)
	return b
}
func dealValues(values ...string) string {
	var value string
	if len(values) > 0 {
		value = values[0]
	}
	return value
}
func dealWhereValues(values ...string) (value, pt string) {
	if len(values) > 1 {
		pt = values[1]
	}
	if len(values) > 0 {
		value = values[0]
	}
	return
}
func (b *Builder) WhereTime(column, operator string, values ...string) *Builder {
	value, pt := dealWhereValues(values...)
	return b.where("Time", column, operator, value, "and", pt)
}
func (b *Builder) OrWhereTime(column, operator string, values ...string) *Builder {
	value, pt := dealWhereValues(values...)
	return b.where("Time", column, operator, value, "or", pt)
}
func (b *Builder) WhereDay(column, operator string, values ...string) *Builder {
	value, pt := dealWhereValues(values...)
	return b.where("Day", column, operator, value, "and", pt)
}
func (b *Builder) OrWhereDay(column, operator string, values ...string) *Builder {
	value, pt := dealWhereValues(values...)
	return b.where("Day", column, operator, value, "or", pt)
}
func (b *Builder) WhereMonth(column, operator string, values ...string) *Builder {
	value, pt := dealWhereValues(values...)
	return b.where("Month", column, operator, value, "and", pt)
}
func (b *Builder) OrWhereMonth(column, operator string, values ...string) *Builder {
	value, pt := dealWhereValues(values...)
	return b.where("Month", column, operator, value, "or", pt)
}
func (b *Builder) WhereYear(column, operator string, values ...string) *Builder {
	value, pt := dealWhereValues(values...)
	return b.where("Year", column, operator, value, "and", pt)
}
func (b *Builder) OrWhereYear(column, operator string, values ...string) *Builder {
	value, pt := dealWhereValues(values...)
	return b.where("Year", column, operator, value, "or", pt)
}
func (b *Builder) WhereDate(column, operator string, values ...string) *Builder {
	value, pt := dealWhereValues(values...)
	return b.where("Date", column, operator, value, "and", pt)
}
func (b *Builder) OrWhereDate(column, operator string, values ...string) *Builder {
	value, pt := dealWhereValues(values...)
	return b.where("Date", column, operator, value, "or", pt)
}
func (b *Builder) Having(column, operator string, values ...string) *Builder {
	var value string
	if len(values) > 0 {
		value = values[0]
	}
	return b.having(column, operator, value, "and")
}
func (b *Builder) OrHaving(column, operator string, values ...string) *Builder {
	var value string
	if len(values) > 0 {
		value = values[0]
	}
	return b.having(column, operator, value, "or")
}
func (b *Builder) having(column, operator, value, logical string) *Builder {
	if invalidOperatorAndValue(operator, value) {
	}
	if value == "" {
		operator, value = "=", operator
	}
	having := map[string]string{
		"type":     "Basic",
		"column":   column,
		"operator": operator,
		"value":    value,
		"logical":  logical,
	}
	b.Components["havings"] = append(b.Components["havings"], having)
	return b
}
func (b *Builder) Join(table, first, operator string, second ...string) *Builder {
	return b.join(table, first, operator, dealValues(second...), "inner")
}
func (b *Builder) RightJoin(table, first, operator string, second ...string) *Builder {
	return b.join(table, first, operator, dealValues(second...), "right")
}