func (b *SQLBuilder) Update(t *Table) {
	_ = t.Name
	b.w.WriteLine(`UPDATE ` + b.SourceToSQL(t))
}
Update generates a SQL UPDATE line
package qb
import (
	"bytes"
	"strconv"
	"strings"
)
type SQL interface {
	WriteString(string)
	WriteLine(string)
	Rewrite(string)
	String() string
}
type sqlWriter struct {
	sql    bytes.Buffer
	indent int
}
func (w *sqlWriter) WriteString(s string) {
	if w.sql.Len() == 0 || w.sql.Bytes()[w.sql.Len()-1] == '\n' {
		w.sql.WriteString(strings.Repeat(INDENT, w.indent))
	}
	for k, v := range strings.Split(s, "\n") {
		if k > 0 && v != `` {
			w.sql.WriteString(NEWLINE + strings.Repeat(INDENT, w.indent))
		}
		w.sql.WriteString(v)
	}
	if s[len(s)-1] == '\n' {
		w.sql.WriteString(NEWLINE)
	}
}
func (w *sqlWriter) WriteLine(s string) {
	w.WriteString(s + NEWLINE)
}
func (w *sqlWriter) Rewrite(s string) {
	w.sql = bytes.Buffer{}
	w.sql.WriteString(s)
}
func (w *sqlWriter) AddIndent() {
	w.indent++
}
func (w *sqlWriter) SubIndent() {
	w.indent--
}
func (w *sqlWriter) String() string {
	return w.sql.String()
}
type SQLBuilder struct {
	w       sqlWriter
	Context *Context
}
func NewSQLBuilder(d Driver) SQLBuilder {
	alias := NoAlias()
	return SQLBuilder{sqlWriter{}, NewContext(d, alias)}
}
func (b *SQLBuilder) SourceToSQL(s Source) string {
	return s.TableString(b.Context)
}
func (b *SQLBuilder) FieldToSQL(f Field) string {
	return f.QueryString(b.Context)
}
func (b *SQLBuilder) List(f []Field, withAlias bool) string {
	s := ``
	for k, v := range f {
		if k > 0 {
			s += COMMA
		}
		s += b.FieldToSQL(v)
		if withAlias {
			s += ` f` + strconv.Itoa(k)
		}
	}
	return s
}
func (b *SQLBuilder) Conditions(c []Condition, newline bool) {
	fn := b.w.WriteString
	if newline {
		fn = b.w.WriteLine
	}
	if len(c) == 0 {
		return
	}
	fn(c[0](b.Context))
	if newline {
		b.w.AddIndent()
		defer b.w.SubIndent()
	}
	for _, v := range c[1:] {
		if !newline {
			fn(` `)
		}
		fn(`AND ` + v(b.Context))
	}
}
func eq(f1, f2 Field) Condition {
	return func(c *Context) string {
		return ConcatQuery(c, f1, ` = `, f2)
	}
}
func (b *SQLBuilder) Select(withAlias bool, f ...Field) {
	b.w.WriteLine(`SELECT ` + b.List(f, withAlias))
}
func (b *SQLBuilder) From(src Source) {
	b.w.WriteLine(`FROM ` + b.SourceToSQL(src))
}
func (b *SQLBuilder) Join(j ...join) {
	b.w.AddIndent()
	defer b.w.SubIndent()
	for _, v := range j {
		b.w.WriteString(string(v.Type) + ` JOIN ` + b.SourceToSQL(v.New))
		if len(v.Conditions) > 0 {
			b.w.WriteString(` ON (`)
			b.Conditions(v.Conditions, false)
			b.w.WriteString(`)`)
		}
		b.w.WriteLine(``)
	}
}
func (b *SQLBuilder) Where(c ...Condition) {
	if len(c) == 0 {
		return
	}
	b.w.WriteString(`WHERE `)
	b.Conditions(c, true)
}
func (b *SQLBuilder) GroupBy(f ...Field) {
	if len(f) == 0 {
		return
	}
	b.w.WriteLine(`GROUP BY ` + b.List(f, false))
}
func (b *SQLBuilder) Having(c ...Condition) {
	if len(c) == 0 {
		return
	}
	b.w.WriteString(`HAVING `)
	b.Conditions(c, true)
}
func (b *SQLBuilder) OrderBy(o ...FieldOrder) {
	if len(o) == 0 {
		return
	}
	s := `ORDER BY `
	for k, v := range o {
		if k > 0 {
			s += COMMA
		}
		s += b.FieldToSQL(v.Field) + ` ` + v.Order
	}
	b.w.WriteLine(s)
}
func (b *SQLBuilder) LimitOffset(l, o int) {
	if l == 0 && o == 0 {
		return
	}
	b.Context.Driver.LimitOffset(&b.w, l, o)
}