From f3de91d79f009917652ec6b4917af4de18e74afe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Nieto?= <jose.carlos@menteslibres.net>
Date: Wed, 7 Oct 2015 08:54:26 -0500
Subject: [PATCH] Promoting builder to its own project and moving some
 non-public subpackages to internal.

---
 builder/builder.go                        | 772 -------------------
 builder/builder_test.go                   | 236 ------
 builder/template_test.go                  | 193 -----
 {util => internal}/adapter/nonexistent.go |   0
 {util => internal}/schema/schema.go       |   0
 internal/sqladapter/collection.go         |   2 +-
 internal/sqladapter/database.go           |  12 +-
 mongo/database.go                         |   2 +-
 mongo/result.go                           |   2 +-
 mysql/collection.go                       |   6 +-
 mysql/database.go                         |  10 +-
 mysql/database_test.go                    |   2 +-
 mysql/mysql.go                            |   4 +-
 mysql/tx.go                               |   2 +-
 postgresql/collection.go                  |   4 +-
 postgresql/database.go                    |   2 +-
 postgresql/postgresql.go                  |   4 +-
 postgresql/tx.go                          |   2 +-
 ql/collection.go                          |   6 +-
 ql/database.go                            |  10 +-
 ql/database_test.go                       |   2 +-
 ql/ql.go                                  |   4 +-
 ql/tx.go                                  |   2 +-
 sqlite/collection.go                      |   6 +-
 sqlite/database.go                        |  10 +-
 sqlite/database_test.go                   |   2 +-
 sqlite/sqlite.go                          |   4 +-
 sqlite/tx.go                              |   2 +-
 util/sqlgen/column.go                     |  91 ---
 util/sqlgen/column_test.go                | 119 ---
 util/sqlgen/column_value.go               | 101 ---
 util/sqlgen/column_value_test.go          | 156 ----
 util/sqlgen/columns.go                    |  63 --
 util/sqlgen/columns_test.go               |  73 --
 util/sqlgen/database.go                   |  37 -
 util/sqlgen/database_test.go              |  53 --
 util/sqlgen/default.go                    | 192 -----
 util/sqlgen/group_by.go                   |  50 --
 util/sqlgen/group_by_test.go              |  73 --
 util/sqlgen/interfaces.go                 |  15 -
 util/sqlgen/join.go                       | 177 -----
 util/sqlgen/join_test.go                  | 250 ------
 util/sqlgen/order_by.go                   | 164 ----
 util/sqlgen/order_by_test.go              | 143 ----
 util/sqlgen/raw.go                        |  38 -
 util/sqlgen/raw_test.go                   |  72 --
 util/sqlgen/statement.go                  | 130 ----
 util/sqlgen/statement_test.go             | 885 ----------------------
 util/sqlgen/table.go                      | 110 ---
 util/sqlgen/table_test.go                 | 136 ----
 util/sqlgen/template.go                   |  88 ---
 util/sqlgen/utilities.go                  | 157 ----
 util/sqlgen/utilities_test.go             | 284 -------
 util/sqlgen/value.go                      | 163 ----
 util/sqlgen/value_test.go                 |  99 ---
 util/sqlgen/where.go                      | 123 ---
 util/sqlgen/where_test.go                 | 113 ---
 util/sqlutil/convert.go                   | 291 -------
 util/sqlutil/debug.go                     |  83 --
 util/sqlutil/fetch.go                     | 293 -------
 util/sqlutil/result/result.go             | 170 -----
 util/sqlutil/scanner.go                   | 193 -----
 util/sqlutil/tx/tx.go                     |  46 --
 63 files changed, 51 insertions(+), 6483 deletions(-)
 delete mode 100644 builder/builder.go
 delete mode 100644 builder/builder_test.go
 delete mode 100644 builder/template_test.go
 rename {util => internal}/adapter/nonexistent.go (100%)
 rename {util => internal}/schema/schema.go (100%)
 delete mode 100644 util/sqlgen/column.go
 delete mode 100644 util/sqlgen/column_test.go
 delete mode 100644 util/sqlgen/column_value.go
 delete mode 100644 util/sqlgen/column_value_test.go
 delete mode 100644 util/sqlgen/columns.go
 delete mode 100644 util/sqlgen/columns_test.go
 delete mode 100644 util/sqlgen/database.go
 delete mode 100644 util/sqlgen/database_test.go
 delete mode 100644 util/sqlgen/default.go
 delete mode 100644 util/sqlgen/group_by.go
 delete mode 100644 util/sqlgen/group_by_test.go
 delete mode 100644 util/sqlgen/interfaces.go
 delete mode 100644 util/sqlgen/join.go
 delete mode 100644 util/sqlgen/join_test.go
 delete mode 100644 util/sqlgen/order_by.go
 delete mode 100644 util/sqlgen/order_by_test.go
 delete mode 100644 util/sqlgen/raw.go
 delete mode 100644 util/sqlgen/raw_test.go
 delete mode 100644 util/sqlgen/statement.go
 delete mode 100644 util/sqlgen/statement_test.go
 delete mode 100644 util/sqlgen/table.go
 delete mode 100644 util/sqlgen/table_test.go
 delete mode 100644 util/sqlgen/template.go
 delete mode 100644 util/sqlgen/utilities.go
 delete mode 100644 util/sqlgen/utilities_test.go
 delete mode 100644 util/sqlgen/value.go
 delete mode 100644 util/sqlgen/value_test.go
 delete mode 100644 util/sqlgen/where.go
 delete mode 100644 util/sqlgen/where_test.go
 delete mode 100644 util/sqlutil/convert.go
 delete mode 100644 util/sqlutil/debug.go
 delete mode 100644 util/sqlutil/fetch.go
 delete mode 100644 util/sqlutil/result/result.go
 delete mode 100644 util/sqlutil/scanner.go
 delete mode 100644 util/sqlutil/tx/tx.go

diff --git a/builder/builder.go b/builder/builder.go
deleted file mode 100644
index 7cedc38b..00000000
--- a/builder/builder.go
+++ /dev/null
@@ -1,772 +0,0 @@
-package builder
-
-import (
-	"database/sql"
-	"errors"
-	"fmt"
-	"github.com/jmoiron/sqlx"
-	"github.com/jmoiron/sqlx/reflectx"
-	"reflect"
-	"regexp"
-	"sort"
-	"strconv"
-	"strings"
-	"upper.io/db"
-	"upper.io/db/util/sqlgen"
-	"upper.io/db/util/sqlutil"
-)
-
-type SelectMode uint8
-
-var mapper = reflectx.NewMapper("db")
-
-type fieldValue struct {
-	fields []string
-	values []interface{}
-}
-
-func (fv *fieldValue) Len() int {
-	return len(fv.fields)
-}
-
-func (fv *fieldValue) Swap(i, j int) {
-	fv.fields[i], fv.fields[j] = fv.fields[j], fv.fields[i]
-	fv.values[i], fv.values[j] = fv.values[j], fv.values[i]
-}
-
-func (fv *fieldValue) Less(i, j int) bool {
-	return fv.fields[i] < fv.fields[j]
-}
-
-var (
-	reInvisibleChars       = regexp.MustCompile(`[\s\r\n\t]+`)
-	reColumnCompareExclude = regexp.MustCompile(`[^a-zA-Z0-9]`)
-)
-
-var (
-	sqlPlaceholder = sqlgen.RawValue(`?`)
-)
-
-const (
-	selectModeAll SelectMode = iota
-	selectModeDistinct
-)
-
-type sqlDatabase interface {
-	Query(stmt *sqlgen.Statement, args ...interface{}) (*sqlx.Rows, error)
-	QueryRow(stmt *sqlgen.Statement, args ...interface{}) (*sqlx.Row, error)
-	Exec(stmt *sqlgen.Statement, args ...interface{}) (sql.Result, error)
-}
-
-type Builder struct {
-	sess sqlDatabase
-	t    *sqlutil.TemplateWithUtils
-}
-
-func (b *Builder) Exec(query interface{}, args ...interface{}) (sql.Result, error) {
-	switch q := query.(type) {
-	case *sqlgen.Statement:
-		return b.sess.Exec(q, args...)
-	default:
-		return nil, errors.New("Unsupported query type.")
-	}
-}
-
-func (b *Builder) SelectAllFrom(table string) db.QuerySelector {
-	qs := &QuerySelector{
-		builder: b,
-		table:   table,
-	}
-
-	qs.stringer = &stringer{qs, b.t.Template}
-	return qs
-}
-
-func (b *Builder) Select(columns ...interface{}) db.QuerySelector {
-	qs := &QuerySelector{
-		builder: b,
-	}
-
-	qs.stringer = &stringer{qs, b.t.Template}
-	return qs.Columns(columns...)
-}
-
-func (b *Builder) InsertInto(table string) db.QueryInserter {
-	qi := &QueryInserter{
-		builder: b,
-		table:   table,
-	}
-
-	qi.stringer = &stringer{qi, b.t.Template}
-	return qi
-}
-
-func (b *Builder) DeleteFrom(table string) db.QueryDeleter {
-	qd := &QueryDeleter{
-		builder: b,
-		table:   table,
-	}
-
-	qd.stringer = &stringer{qd, b.t.Template}
-	return qd
-}
-
-func (b *Builder) Update(table string) db.QueryUpdater {
-	qu := &QueryUpdater{
-		builder:      b,
-		table:        table,
-		columnValues: &sqlgen.ColumnValues{},
-	}
-
-	qu.stringer = &stringer{qu, b.t.Template}
-	return qu
-}
-
-type QueryInserter struct {
-	*stringer
-	builder   *Builder
-	table     string
-	values    []*sqlgen.Values
-	columns   []sqlgen.Fragment
-	arguments []interface{}
-	extra     string
-}
-
-func (qi *QueryInserter) Extra(s string) db.QueryInserter {
-	qi.extra = s
-	return qi
-}
-
-func (qi *QueryInserter) Exec() (sql.Result, error) {
-	return qi.builder.sess.Exec(qi.statement())
-}
-
-func (qi *QueryInserter) Query() (*sqlx.Rows, error) {
-	return qi.builder.sess.Query(qi.statement(), qi.arguments...)
-}
-
-func (qi *QueryInserter) QueryRow() (*sqlx.Row, error) {
-	return qi.builder.sess.QueryRow(qi.statement(), qi.arguments...)
-}
-
-func (qi *QueryInserter) Iterator() db.Iterator {
-	rows, err := qi.builder.sess.Query(qi.statement(), qi.arguments...)
-	return &iterator{rows, err}
-}
-
-func (qi *QueryInserter) Columns(columns ...string) db.QueryInserter {
-	l := len(columns)
-	f := make([]sqlgen.Fragment, l)
-	for i := 0; i < l; i++ {
-		f[i] = sqlgen.ColumnWithName(columns[i])
-	}
-	qi.columns = append(qi.columns, f...)
-	return qi
-}
-
-func (qi *QueryInserter) Values(values ...interface{}) db.QueryInserter {
-	if len(qi.columns) == 0 && len(values) == 1 {
-		ff, vv, _ := Map(values[0])
-
-		columns, vals, arguments, _ := qi.builder.t.ToColumnsValuesAndArguments(ff, vv)
-
-		qi.arguments = append(qi.arguments, arguments...)
-		qi.values = append(qi.values, vals)
-
-		for _, c := range columns.Columns {
-			qi.columns = append(qi.columns, c)
-		}
-	} else if len(qi.columns) == 0 || len(values) == len(qi.columns) {
-		qi.arguments = append(qi.arguments, values...)
-
-		l := len(values)
-		placeholders := make([]sqlgen.Fragment, l)
-		for i := 0; i < l; i++ {
-			placeholders[i] = sqlgen.RawValue(`?`)
-		}
-		qi.values = append(qi.values, sqlgen.NewValueGroup(placeholders...))
-	}
-
-	return qi
-}
-
-func (qi *QueryInserter) statement() *sqlgen.Statement {
-	stmt := &sqlgen.Statement{
-		Type:  sqlgen.Insert,
-		Table: sqlgen.TableWithName(qi.table),
-		Extra: sqlgen.Extra(qi.extra),
-	}
-
-	if len(qi.values) > 0 {
-		stmt.Values = sqlgen.JoinValueGroups(qi.values...)
-	}
-
-	if len(qi.columns) > 0 {
-		stmt.Columns = sqlgen.JoinColumns(qi.columns...)
-	}
-	return stmt
-}
-
-type QueryDeleter struct {
-	*stringer
-	builder   *Builder
-	table     string
-	limit     int
-	where     *sqlgen.Where
-	arguments []interface{}
-}
-
-func (qd *QueryDeleter) Where(terms ...interface{}) db.QueryDeleter {
-	where, arguments := qd.builder.t.ToWhereWithArguments(terms)
-	qd.where = &where
-	qd.arguments = append(qd.arguments, arguments...)
-	return qd
-}
-
-func (qd *QueryDeleter) Limit(limit int) db.QueryDeleter {
-	qd.limit = limit
-	return qd
-}
-
-func (qd *QueryDeleter) Exec() (sql.Result, error) {
-	return qd.builder.sess.Exec(qd.statement(), qd.arguments...)
-}
-
-func (qd *QueryDeleter) statement() *sqlgen.Statement {
-	stmt := &sqlgen.Statement{
-		Type:  sqlgen.Delete,
-		Table: sqlgen.TableWithName(qd.table),
-	}
-
-	if qd.Where != nil {
-		stmt.Where = qd.where
-	}
-
-	if qd.limit != 0 {
-		stmt.Limit = sqlgen.Limit(qd.limit)
-	}
-
-	return stmt
-}
-
-type QueryUpdater struct {
-	*stringer
-	builder      *Builder
-	table        string
-	columnValues *sqlgen.ColumnValues
-	limit        int
-	where        *sqlgen.Where
-	arguments    []interface{}
-}
-
-func (qu *QueryUpdater) Set(terms ...interface{}) db.QueryUpdater {
-	if len(terms) == 1 {
-		ff, vv, _ := Map(terms[0])
-
-		cvs := make([]sqlgen.Fragment, len(ff))
-
-		for i := range ff {
-			cvs[i] = &sqlgen.ColumnValue{
-				Column:   sqlgen.ColumnWithName(ff[i]),
-				Operator: qu.builder.t.AssignmentOperator,
-				Value:    sqlPlaceholder,
-			}
-		}
-		qu.columnValues.Append(cvs...)
-		qu.arguments = append(qu.arguments, vv...)
-	} else if len(terms) > 1 {
-		cv, arguments := qu.builder.t.ToColumnValues(terms)
-		qu.columnValues.Append(cv.ColumnValues...)
-		qu.arguments = append(qu.arguments, arguments...)
-	}
-
-	return qu
-}
-
-func (qu *QueryUpdater) Where(terms ...interface{}) db.QueryUpdater {
-	where, arguments := qu.builder.t.ToWhereWithArguments(terms)
-	qu.where = &where
-	qu.arguments = append(qu.arguments, arguments...)
-	return qu
-}
-
-func (qu *QueryUpdater) Exec() (sql.Result, error) {
-	return qu.builder.sess.Exec(qu.statement(), qu.arguments...)
-}
-
-func (qu *QueryUpdater) Limit(limit int) db.QueryUpdater {
-	qu.limit = limit
-	return qu
-}
-
-func (qu *QueryUpdater) statement() *sqlgen.Statement {
-	stmt := &sqlgen.Statement{
-		Type:         sqlgen.Update,
-		Table:        sqlgen.TableWithName(qu.table),
-		ColumnValues: qu.columnValues,
-	}
-
-	if qu.Where != nil {
-		stmt.Where = qu.where
-	}
-
-	if qu.limit != 0 {
-		stmt.Limit = sqlgen.Limit(qu.limit)
-	}
-
-	return stmt
-}
-
-type iterator struct {
-	cursor *sqlx.Rows // This is the main query cursor. It starts as a nil value.
-	err    error
-}
-
-type QuerySelector struct {
-	*stringer
-	mode      SelectMode
-	builder   *Builder
-	table     string
-	where     *sqlgen.Where
-	groupBy   *sqlgen.GroupBy
-	orderBy   sqlgen.OrderBy
-	limit     sqlgen.Limit
-	offset    sqlgen.Offset
-	columns   *sqlgen.Columns
-	joins     []*sqlgen.Join
-	arguments []interface{}
-	err       error
-}
-
-func (qs *QuerySelector) From(tables ...string) db.QuerySelector {
-	qs.table = strings.Join(tables, ",")
-	return qs
-}
-
-func (qs *QuerySelector) Columns(columns ...interface{}) db.QuerySelector {
-	f, err := columnFragments(qs.builder.t, columns)
-	if err != nil {
-		qs.err = err
-		return qs
-	}
-	qs.columns = sqlgen.JoinColumns(f...)
-	return qs
-}
-
-func (qs *QuerySelector) Distinct() db.QuerySelector {
-	qs.mode = selectModeDistinct
-	return qs
-}
-
-func (qs *QuerySelector) Where(terms ...interface{}) db.QuerySelector {
-	where, arguments := qs.builder.t.ToWhereWithArguments(terms)
-	qs.where = &where
-	qs.arguments = append(qs.arguments, arguments...)
-	return qs
-}
-
-func (qs *QuerySelector) GroupBy(columns ...interface{}) db.QuerySelector {
-	var fragments []sqlgen.Fragment
-	fragments, qs.err = columnFragments(qs.builder.t, columns)
-	if fragments != nil {
-		qs.groupBy = sqlgen.GroupByColumns(fragments...)
-	}
-	return qs
-}
-
-func (qs *QuerySelector) OrderBy(columns ...interface{}) db.QuerySelector {
-	var sortColumns sqlgen.SortColumns
-
-	for i := range columns {
-		var sort *sqlgen.SortColumn
-
-		switch value := columns[i].(type) {
-		case db.Raw:
-			sort = &sqlgen.SortColumn{
-				Column: sqlgen.RawValue(fmt.Sprintf(`%v`, value.Value)),
-			}
-		case string:
-			if strings.HasPrefix(value, `-`) {
-				sort = &sqlgen.SortColumn{
-					Column: sqlgen.ColumnWithName(value[1:]),
-					Order:  sqlgen.Descendent,
-				}
-			} else {
-				sort = &sqlgen.SortColumn{
-					Column: sqlgen.ColumnWithName(value),
-					Order:  sqlgen.Ascendent,
-				}
-			}
-		}
-		sortColumns.Columns = append(sortColumns.Columns, sort)
-	}
-
-	qs.orderBy.SortColumns = &sortColumns
-
-	return qs
-}
-
-func (qs *QuerySelector) Using(columns ...interface{}) db.QuerySelector {
-	if len(qs.joins) == 0 {
-		qs.err = errors.New(`Cannot use Using() without a preceding Join() expression.`)
-		return qs
-	}
-
-	lastJoin := qs.joins[len(qs.joins)-1]
-
-	if lastJoin.On != nil {
-		qs.err = errors.New(`Cannot use Using() and On() with the same Join() expression.`)
-		return qs
-	}
-
-	fragments, err := columnFragments(qs.builder.t, columns)
-	if err != nil {
-		qs.err = err
-		return qs
-	}
-
-	lastJoin.Using = sqlgen.UsingColumns(fragments...)
-	return qs
-}
-
-func (qs *QuerySelector) pushJoin(t string, tables []interface{}) db.QuerySelector {
-	if qs.joins == nil {
-		qs.joins = []*sqlgen.Join{}
-	}
-
-	tableNames := make([]string, len(tables))
-	for i := range tables {
-		tableNames[i] = fmt.Sprintf("%s", tables[i])
-	}
-
-	qs.joins = append(qs.joins,
-		&sqlgen.Join{
-			Type:  t,
-			Table: sqlgen.TableWithName(strings.Join(tableNames, ", ")),
-		},
-	)
-
-	return qs
-}
-
-func (qs *QuerySelector) FullJoin(tables ...interface{}) db.QuerySelector {
-	return qs.pushJoin("FULL", tables)
-}
-
-func (qs *QuerySelector) CrossJoin(tables ...interface{}) db.QuerySelector {
-	return qs.pushJoin("CROSS", tables)
-}
-
-func (qs *QuerySelector) RightJoin(tables ...interface{}) db.QuerySelector {
-	return qs.pushJoin("RIGHT", tables)
-}
-
-func (qs *QuerySelector) LeftJoin(tables ...interface{}) db.QuerySelector {
-	return qs.pushJoin("LEFT", tables)
-}
-
-func (qs *QuerySelector) Join(tables ...interface{}) db.QuerySelector {
-	return qs.pushJoin("", tables)
-}
-
-func (qs *QuerySelector) On(terms ...interface{}) db.QuerySelector {
-	if len(qs.joins) == 0 {
-		qs.err = errors.New(`Cannot use On() without a preceding Join() expression.`)
-		return qs
-	}
-
-	lastJoin := qs.joins[len(qs.joins)-1]
-
-	if lastJoin.On != nil {
-		qs.err = errors.New(`Cannot use Using() and On() with the same Join() expression.`)
-		return qs
-	}
-
-	w, a := qs.builder.t.ToWhereWithArguments(terms)
-	o := sqlgen.On(w)
-	lastJoin.On = &o
-
-	qs.arguments = append(qs.arguments, a...)
-	return qs
-}
-
-func (qs *QuerySelector) Limit(n int) db.QuerySelector {
-	qs.limit = sqlgen.Limit(n)
-	return qs
-}
-
-func (qs *QuerySelector) Offset(n int) db.QuerySelector {
-	qs.offset = sqlgen.Offset(n)
-	return qs
-}
-
-func (qs *QuerySelector) statement() *sqlgen.Statement {
-	return &sqlgen.Statement{
-		Type:    sqlgen.Select,
-		Table:   sqlgen.TableWithName(qs.table),
-		Columns: qs.columns,
-		Limit:   qs.limit,
-		Offset:  qs.offset,
-		Joins:   sqlgen.JoinConditions(qs.joins...),
-		Where:   qs.where,
-		OrderBy: &qs.orderBy,
-		GroupBy: qs.groupBy,
-	}
-}
-
-func (qs *QuerySelector) Query() (*sqlx.Rows, error) {
-	return qs.builder.sess.Query(qs.statement(), qs.arguments...)
-}
-
-func (qs *QuerySelector) QueryRow() (*sqlx.Row, error) {
-	return qs.builder.sess.QueryRow(qs.statement(), qs.arguments...)
-}
-
-func (qs *QuerySelector) Iterator() db.Iterator {
-	rows, err := qs.builder.sess.Query(qs.statement(), qs.arguments...)
-	return &iterator{rows, err}
-}
-
-func columnFragments(template *sqlutil.TemplateWithUtils, columns []interface{}) ([]sqlgen.Fragment, error) {
-	l := len(columns)
-	f := make([]sqlgen.Fragment, l)
-
-	for i := 0; i < l; i++ {
-		switch v := columns[i].(type) {
-		case db.Func:
-			var s string
-			a := template.ToInterfaceArguments(v.Args)
-			if len(a) == 0 {
-				s = fmt.Sprintf(`%s()`, v.Name)
-			} else {
-				ss := make([]string, 0, len(a))
-				for j := range a {
-					ss = append(ss, fmt.Sprintf(`%v`, a[j]))
-				}
-				s = fmt.Sprintf(`%s(%s)`, v.Name, strings.Join(ss, `, `))
-			}
-			f[i] = sqlgen.RawValue(s)
-		case db.Raw:
-			f[i] = sqlgen.RawValue(fmt.Sprintf("%v", v.Value))
-		case sqlgen.Fragment:
-			f[i] = v
-		case string:
-			f[i] = sqlgen.ColumnWithName(v)
-		case interface{}:
-			f[i] = sqlgen.ColumnWithName(fmt.Sprintf("%v", v))
-		default:
-			return nil, fmt.Errorf("Unexpected argument type %T for Select() argument.", v)
-		}
-	}
-
-	return f, nil
-}
-
-type hasStatement interface {
-	statement() *sqlgen.Statement
-}
-
-type stringer struct {
-	i hasStatement
-	t *sqlgen.Template
-}
-
-func (s *stringer) String() string {
-	if s != nil && s.i != nil {
-		q := s.compileAndReplacePlaceholders(s.i.statement())
-		q = reInvisibleChars.ReplaceAllString(q, ` `)
-		return strings.TrimSpace(q)
-	}
-	return ""
-}
-
-func (s *stringer) compileAndReplacePlaceholders(stmt *sqlgen.Statement) (query string) {
-	buf := stmt.Compile(s.t)
-
-	j := 1
-	for i := range buf {
-		if buf[i] == '?' {
-			query = query + "$" + strconv.Itoa(j)
-			j++
-		} else {
-			query = query + string(buf[i])
-		}
-	}
-
-	return query
-}
-
-func NewBuilder(sess sqlDatabase, t *sqlgen.Template) *Builder {
-	return &Builder{
-		sess: sess,
-		t:    sqlutil.NewTemplateWithUtils(t),
-	}
-}
-
-func (iter *iterator) Scan(dst ...interface{}) error {
-	if iter.err != nil {
-		return iter.err
-	}
-	return iter.cursor.Scan(dst...)
-}
-
-func (iter *iterator) One(dst interface{}) error {
-	if iter.err != nil {
-		return iter.err
-	}
-
-	defer iter.Close()
-
-	if !iter.Next(dst) {
-		return iter.Err()
-	}
-
-	return nil
-}
-
-func (iter *iterator) All(dst interface{}) error {
-	var err error
-
-	if iter.err != nil {
-		return iter.err
-	}
-
-	defer iter.Close()
-
-	// Fetching all results within the cursor.
-	err = sqlutil.FetchRows(iter.cursor, dst)
-
-	return err
-}
-
-func (iter *iterator) Err() (err error) {
-	return iter.err
-}
-
-func (iter *iterator) Next(dst ...interface{}) bool {
-	var err error
-
-	if iter.err != nil {
-		return false
-	}
-
-	switch len(dst) {
-	case 0:
-		if ok := iter.cursor.Next(); !ok {
-			iter.err = iter.cursor.Err()
-			iter.Close()
-			return false
-		}
-		return true
-	case 1:
-		if err = sqlutil.FetchRow(iter.cursor, dst[0]); err != nil {
-			iter.err = err
-			iter.Close()
-			return false
-		}
-		return true
-	}
-
-	iter.err = db.ErrUnsupported
-	return false
-}
-
-func (iter *iterator) Close() (err error) {
-	if iter.cursor != nil {
-		err = iter.cursor.Close()
-		iter.cursor = nil
-	}
-	return err
-}
-
-func Map(item interface{}) ([]string, []interface{}, error) {
-	var fv fieldValue
-
-	itemV := reflect.ValueOf(item)
-	itemT := itemV.Type()
-
-	if itemT.Kind() == reflect.Ptr {
-		// Single derefence. Just in case user passed a pointer to struct instead of a struct.
-		item = itemV.Elem().Interface()
-		itemV = reflect.ValueOf(item)
-		itemT = itemV.Type()
-	}
-
-	switch itemT.Kind() {
-
-	case reflect.Struct:
-
-		fieldMap := mapper.TypeMap(itemT).Names
-		nfields := len(fieldMap)
-
-		fv.values = make([]interface{}, 0, nfields)
-		fv.fields = make([]string, 0, nfields)
-
-		for _, fi := range fieldMap {
-			// log.Println("=>", fi.Name, fi.Options)
-
-			fld := reflectx.FieldByIndexesReadOnly(itemV, fi.Index)
-			if fld.Kind() == reflect.Ptr && fld.IsNil() {
-				continue
-			}
-
-			var value interface{}
-			if _, ok := fi.Options["stringarray"]; ok {
-				value = sqlutil.StringArray(fld.Interface().([]string))
-			} else if _, ok := fi.Options["int64array"]; ok {
-				value = sqlutil.Int64Array(fld.Interface().([]int64))
-			} else if _, ok := fi.Options["jsonb"]; ok {
-				value = sqlutil.JsonbType{fld.Interface()}
-			} else {
-				value = fld.Interface()
-			}
-
-			if _, ok := fi.Options["omitempty"]; ok {
-				if value == fi.Zero.Interface() {
-					continue
-				}
-			}
-
-			fv.fields = append(fv.fields, fi.Name)
-			v, err := marshal(value)
-			if err != nil {
-				return nil, nil, err
-			}
-			fv.values = append(fv.values, v)
-		}
-
-	case reflect.Map:
-		nfields := itemV.Len()
-		fv.values = make([]interface{}, nfields)
-		fv.fields = make([]string, nfields)
-		mkeys := itemV.MapKeys()
-
-		for i, keyV := range mkeys {
-			valv := itemV.MapIndex(keyV)
-			fv.fields[i] = fmt.Sprintf("%v", keyV.Interface())
-
-			v, err := marshal(valv.Interface())
-			if err != nil {
-				return nil, nil, err
-			}
-
-			fv.values[i] = v
-		}
-	default:
-		return nil, nil, db.ErrExpectingMapOrStruct
-	}
-
-	sort.Sort(&fv)
-
-	return fv.fields, fv.values, nil
-}
-
-func marshal(v interface{}) (interface{}, error) {
-	if m, isMarshaler := v.(db.Marshaler); isMarshaler {
-		var err error
-		if v, err = m.MarshalDB(); err != nil {
-			return nil, err
-		}
-	}
-	return v, nil
-}
diff --git a/builder/builder_test.go b/builder/builder_test.go
deleted file mode 100644
index aa510156..00000000
--- a/builder/builder_test.go
+++ /dev/null
@@ -1,236 +0,0 @@
-package builder
-
-import (
-	"github.com/stretchr/testify/assert"
-	"testing"
-	"upper.io/db"
-	"upper.io/db/util/sqlutil"
-)
-
-func TestSelect(t *testing.T) {
-
-	b := &Builder{t: sqlutil.NewTemplateWithUtils(&testTemplate)}
-	assert := assert.New(t)
-
-	assert.Equal(
-		`SELECT * FROM "artist"`,
-		b.SelectAllFrom("artist").String(),
-	)
-
-	assert.Equal(
-		`SELECT * FROM "artist"`,
-		b.Select().From("artist").String(),
-	)
-
-	assert.Equal(
-		`SELECT * FROM "artist" LIMIT -1 OFFSET 5`,
-		b.Select().From("artist").Limit(-1).Offset(5).String(),
-	)
-
-	assert.Equal(
-		`SELECT "id" FROM "artist"`,
-		b.Select("id").From("artist").String(),
-	)
-
-	assert.Equal(
-		`SELECT "id", "name" FROM "artist"`,
-		b.Select("id", "name").From("artist").String(),
-	)
-
-	assert.Equal(
-		`SELECT * FROM "artist" WHERE ("name" = $1)`,
-		b.SelectAllFrom("artist").Where("name", "Haruki").String(),
-	)
-
-	assert.Equal(
-		`SELECT * FROM "artist" WHERE (name LIKE $1)`,
-		b.SelectAllFrom("artist").Where("name LIKE ?", `%F%`).String(),
-	)
-
-	assert.Equal(
-		`SELECT "id" FROM "artist" WHERE (name LIKE $1 OR name LIKE $2)`,
-		b.Select("id").From("artist").Where(`name LIKE ? OR name LIKE ?`, `%Miya%`, `F%`).String(),
-	)
-
-	assert.Equal(
-		`SELECT * FROM "artist" WHERE ("id" > $1)`,
-		b.SelectAllFrom("artist").Where("id >", 2).String(),
-	)
-
-	assert.Equal(
-		`SELECT * FROM "artist" WHERE (id <= 2 AND name != $1)`,
-		b.SelectAllFrom("artist").Where("id <= 2 AND name != ?", "A").String(),
-	)
-
-	assert.Equal(
-		`SELECT * FROM "artist" WHERE ("id" IN ($1, $2, $3, $4))`,
-		b.SelectAllFrom("artist").Where("id IN", []int{1, 9, 8, 7}).String(),
-	)
-
-	assert.Equal(
-		`SELECT * FROM "artist" WHERE (name IS NOT NULL)`,
-		b.SelectAllFrom("artist").Where("name IS NOT NULL").String(),
-	)
-
-	assert.Equal(
-		`SELECT * FROM "artist" AS "a", "publication" AS "p" WHERE (p.author_id = a.id) LIMIT 1`,
-		b.Select().From("artist a", "publication as p").Where("p.author_id = a.id").Limit(1).String(),
-	)
-
-	assert.Equal(
-		`SELECT "id" FROM "artist" NATURAL JOIN "publication"`,
-		b.Select("id").From("artist").Join("publication").String(),
-	)
-
-	assert.Equal(
-		`SELECT * FROM "artist" AS "a" JOIN "publication" AS "p" ON (p.author_id = a.id) LIMIT 1`,
-		b.SelectAllFrom("artist a").Join("publication p").On("p.author_id = a.id").Limit(1).String(),
-	)
-
-	assert.Equal(
-		`SELECT * FROM "artist" AS "a" JOIN "publication" AS "p" ON (p.author_id = a.id) WHERE ("a"."id" = $1) LIMIT 1`,
-		b.SelectAllFrom("artist a").Join("publication p").On("p.author_id = a.id").Where("a.id", 2).Limit(1).String(),
-	)
-
-	assert.Equal(
-		`SELECT * FROM "artist" JOIN "publication" AS "p" ON (p.author_id = a.id) WHERE (a.id = 2) LIMIT 1`,
-		b.SelectAllFrom("artist").Join("publication p").On("p.author_id = a.id").Where("a.id = 2").Limit(1).String(),
-	)
-
-	assert.Equal(
-		`SELECT * FROM "artist" AS "a" JOIN "publication" AS "p" ON (p.title LIKE $1 OR p.title LIKE $2) WHERE (a.id = $3) LIMIT 1`,
-		b.SelectAllFrom("artist a").Join("publication p").On("p.title LIKE ? OR p.title LIKE ?", "%Totoro%", "%Robot%").Where("a.id = ?", 2).Limit(1).String(),
-	)
-
-	assert.Equal(
-		`SELECT * FROM "artist" AS "a" LEFT JOIN "publication" AS "p1" ON (p1.id = a.id) RIGHT JOIN "publication" AS "p2" ON (p2.id = a.id)`,
-		b.SelectAllFrom("artist a").
-			LeftJoin("publication p1").On("p1.id = a.id").
-			RightJoin("publication p2").On("p2.id = a.id").
-			String(),
-	)
-
-	assert.Equal(
-		`SELECT * FROM "artist" CROSS JOIN "publication"`,
-		b.SelectAllFrom("artist").CrossJoin("publication").String(),
-	)
-
-	assert.Equal(
-		`SELECT * FROM "artist" JOIN "publication" USING ("id")`,
-		b.SelectAllFrom("artist").Join("publication").Using("id").String(),
-	)
-
-	assert.Equal(
-		`SELECT DATE()`,
-		b.Select(db.Raw{"DATE()"}).String(),
-	)
-}
-
-func TestInsert(t *testing.T) {
-	b := &Builder{t: sqlutil.NewTemplateWithUtils(&testTemplate)}
-	assert := assert.New(t)
-
-	assert.Equal(
-		`INSERT INTO "artist" VALUES ($1, $2), ($3, $4), ($5, $6)`,
-		b.InsertInto("artist").
-			Values(10, "Ryuichi Sakamoto").
-			Values(11, "Alondra de la Parra").
-			Values(12, "Haruki Murakami").
-			String(),
-	)
-
-	assert.Equal(
-		`INSERT INTO "artist" ("id", "name") VALUES ($1, $2)`,
-		b.InsertInto("artist").Values(map[string]string{"id": "12", "name": "Chavela Vargas"}).String(),
-	)
-
-	assert.Equal(
-		`INSERT INTO "artist" ("id", "name") VALUES ($1, $2) RETURNING "id"`,
-		b.InsertInto("artist").Values(map[string]string{"id": "12", "name": "Chavela Vargas"}).Extra(`RETURNING "id"`).String(),
-	)
-
-	assert.Equal(
-		`INSERT INTO "artist" ("id", "name") VALUES ($1, $2)`,
-		b.InsertInto("artist").Values(map[string]interface{}{"name": "Chavela Vargas", "id": 12}).String(),
-	)
-
-	assert.Equal(
-		`INSERT INTO "artist" ("id", "name") VALUES ($1, $2)`,
-		b.InsertInto("artist").Values(struct {
-			ID   int    `db:"id"`
-			Name string `db:"name"`
-		}{12, "Chavela Vargas"}).String(),
-	)
-
-	assert.Equal(
-		`INSERT INTO "artist" ("name", "id") VALUES ($1, $2)`,
-		b.InsertInto("artist").Columns("name", "id").Values("Chavela Vargas", 12).String(),
-	)
-}
-
-func TestUpdate(t *testing.T) {
-	b := &Builder{t: sqlutil.NewTemplateWithUtils(&testTemplate)}
-	assert := assert.New(t)
-
-	assert.Equal(
-		`UPDATE "artist" SET "name" = $1`,
-		b.Update("artist").Set("name", "Artist").String(),
-	)
-
-	assert.Equal(
-		`UPDATE "artist" SET "name" = $1 WHERE ("id" < $2)`,
-		b.Update("artist").Set("name = ?", "Artist").Where("id <", 5).String(),
-	)
-
-	assert.Equal(
-		`UPDATE "artist" SET "name" = $1 WHERE ("id" < $2)`,
-		b.Update("artist").Set(map[string]string{"name": "Artist"}).Where(db.Cond{"id <": 5}).String(),
-	)
-
-	assert.Equal(
-		`UPDATE "artist" SET "name" = $1 WHERE ("id" < $2)`,
-		b.Update("artist").Set(struct {
-			Nombre string `db:"name"`
-		}{"Artist"}).Where(db.Cond{"id <": 5}).String(),
-	)
-
-	assert.Equal(
-		`UPDATE "artist" SET "name" = $1, "last_name" = $2 WHERE ("id" < $3)`,
-		b.Update("artist").Set(struct {
-			Nombre string `db:"name"`
-		}{"Artist"}).Set(map[string]string{"last_name": "Foo"}).Where(db.Cond{"id <": 5}).String(),
-	)
-
-	assert.Equal(
-		`UPDATE "artist" SET "name" = $1 || ' ' || $2 || id, "id" = id + $3 WHERE (id > $4)`,
-		b.Update("artist").Set(
-			"name = ? || ' ' || ? || id", "Artist", "#",
-			"id = id + ?", 10,
-		).Where("id > ?", 0).String(),
-	)
-}
-
-func TestDelete(t *testing.T) {
-	b := &Builder{t: sqlutil.NewTemplateWithUtils(&testTemplate)}
-	assert := assert.New(t)
-
-	assert.Equal(
-		`DELETE FROM "artist" WHERE (name = $1) LIMIT 1`,
-		b.DeleteFrom("artist").Where("name = ?", "Chavela Vargas").Limit(1).String(),
-	)
-
-	assert.Equal(
-		`DELETE FROM "artist" WHERE (id > 5)`,
-		b.DeleteFrom("artist").Where("id > 5").String(),
-	)
-}
-
-func TestTruncate(t *testing.T) {
-	b := &Builder{t: sqlutil.NewTemplateWithUtils(&testTemplate)}
-	assert := assert.New(t)
-
-	assert.Equal(
-		`TRUNCATE TABLE "artist" RESTART IDENTITY`,
-		b.TruncateTable("artist").Extra("RESTART IDENTITY").String(),
-	)
-}
diff --git a/builder/template_test.go b/builder/template_test.go
deleted file mode 100644
index 157e23bd..00000000
--- a/builder/template_test.go
+++ /dev/null
@@ -1,193 +0,0 @@
-package builder
-
-import (
-	"upper.io/cache"
-	"upper.io/db/util/sqlgen"
-)
-
-const (
-	defaultColumnSeparator     = `.`
-	defaultIdentifierSeparator = `, `
-	defaultIdentifierQuote     = `"{{.Value}}"`
-	defaultValueSeparator      = `, `
-	defaultValueQuote          = `'{{.}}'`
-	defaultAndKeyword          = `AND`
-	defaultOrKeyword           = `OR`
-	defaultNotKeyword          = `NOT`
-	defaultDescKeyword         = `DESC`
-	defaultAscKeyword          = `ASC`
-	defaultDefaultOperator     = `=`
-	defaultAssignmentOperator  = `=`
-	defaultClauseGroup         = `({{.}})`
-	defaultClauseOperator      = ` {{.}} `
-	defaultColumnValue         = `{{.Column}} {{.Operator}} {{.Value}}`
-	defaultTableAliasLayout    = `{{.Name}}{{if .Alias}} AS {{.Alias}}{{end}}`
-	defaultColumnAliasLayout   = `{{.Name}}{{if .Alias}} AS {{.Alias}}{{end}}`
-	defaultSortByColumnLayout  = `{{.Column}} {{.Order}}`
-
-	defaultOrderByLayout = `
-		{{if .SortColumns}}
-			ORDER BY {{.SortColumns}}
-		{{end}}
-	`
-
-	defaultWhereLayout = `
-		{{if .Conds}}
-			WHERE {{.Conds}}
-		{{end}}
-	`
-
-	defaultUsingLayout = `
-		{{if .Columns}}
-			USING ({{.Columns}})
-		{{end}}
-	`
-
-	defaultJoinLayout = `
-		{{if .Table}}
-			{{ if .On }}
-				{{.Type}} JOIN {{.Table}}
-				{{.On}}
-			{{ else if .Using }}
-				{{.Type}} JOIN {{.Table}}
-				{{.Using}}
-			{{ else if .Type | eq "CROSS" }}
-				{{.Type}} JOIN {{.Table}}
-			{{else}}
-				NATURAL {{.Type}} JOIN {{.Table}}
-			{{end}}
-		{{end}}
-	`
-
-	defaultOnLayout = `
-		{{if .Conds}}
-			ON {{.Conds}}
-		{{end}}
-	`
-
-	defaultSelectLayout = `
-    SELECT
-
-      {{if .Columns}}
-        {{.Columns}}
-      {{else}}
-        *
-      {{end}}
-
-      {{if .Table}}
-        FROM {{.Table}}
-      {{end}}
-
-      {{.Joins}}
-
-      {{.Where}}
-
-      {{.GroupBy}}
-
-      {{.OrderBy}}
-
-      {{if .Limit}}
-        LIMIT {{.Limit}}
-      {{end}}
-
-      {{if .Offset}}
-        OFFSET {{.Offset}}
-      {{end}}
-	`
-	defaultDeleteLayout = `
-    DELETE
-      FROM {{.Table}}
-      {{.Where}}
-    {{if .Limit}}
-      LIMIT {{.Limit}}
-    {{end}}
-    {{if .Offset}}
-      OFFSET {{.Offset}}
-    {{end}}
-	`
-	defaultUpdateLayout = `
-		UPDATE
-			{{.Table}}
-		SET {{.ColumnValues}}
-			{{ .Where }}
-	`
-
-	defaultCountLayout = `
-		SELECT
-			COUNT(1) AS _t
-		FROM {{.Table}}
-			{{.Where}}
-
-			{{if .Limit}}
-				LIMIT {{.Limit}}
-			{{end}}
-
-			{{if .Offset}}
-				OFFSET {{.Offset}}
-			{{end}}
-	`
-
-	defaultInsertLayout = `
-    INSERT INTO {{.Table}}
-      {{if .Columns }}({{.Columns}}){{end}}
-    VALUES
-      {{.Values}}
-    {{.Extra}}
-	`
-
-	defaultTruncateLayout = `
-		TRUNCATE TABLE {{.Table}} {{.Extra}}
-	`
-
-	defaultDropDatabaseLayout = `
-		DROP DATABASE {{.Database}}
-	`
-
-	defaultDropTableLayout = `
-		DROP TABLE {{.Table}}
-	`
-
-	defaultGroupByColumnLayout = `{{.Column}}`
-
-	defaultGroupByLayout = `
-		{{if .GroupColumns}}
-			GROUP BY {{.GroupColumns}}
-		{{end}}
-	`
-)
-
-var testTemplate = sqlgen.Template{
-	ColumnSeparator:     defaultColumnSeparator,
-	IdentifierSeparator: defaultIdentifierSeparator,
-	IdentifierQuote:     defaultIdentifierQuote,
-	ValueSeparator:      defaultValueSeparator,
-	ValueQuote:          defaultValueQuote,
-	AndKeyword:          defaultAndKeyword,
-	OrKeyword:           defaultOrKeyword,
-	NotKeyword:          defaultNotKeyword,
-	DescKeyword:         defaultDescKeyword,
-	AscKeyword:          defaultAscKeyword,
-	DefaultOperator:     defaultDefaultOperator,
-	AssignmentOperator:  defaultAssignmentOperator,
-	ClauseGroup:         defaultClauseGroup,
-	ClauseOperator:      defaultClauseOperator,
-	ColumnValue:         defaultColumnValue,
-	TableAliasLayout:    defaultTableAliasLayout,
-	ColumnAliasLayout:   defaultColumnAliasLayout,
-	SortByColumnLayout:  defaultSortByColumnLayout,
-	WhereLayout:         defaultWhereLayout,
-	OnLayout:            defaultOnLayout,
-	UsingLayout:         defaultUsingLayout,
-	JoinLayout:          defaultJoinLayout,
-	OrderByLayout:       defaultOrderByLayout,
-	InsertLayout:        defaultInsertLayout,
-	SelectLayout:        defaultSelectLayout,
-	UpdateLayout:        defaultUpdateLayout,
-	DeleteLayout:        defaultDeleteLayout,
-	TruncateLayout:      defaultTruncateLayout,
-	DropDatabaseLayout:  defaultDropDatabaseLayout,
-	DropTableLayout:     defaultDropTableLayout,
-	CountLayout:         defaultCountLayout,
-	GroupByLayout:       defaultGroupByLayout,
-	Cache:               cache.NewCache(),
-}
diff --git a/util/adapter/nonexistent.go b/internal/adapter/nonexistent.go
similarity index 100%
rename from util/adapter/nonexistent.go
rename to internal/adapter/nonexistent.go
diff --git a/util/schema/schema.go b/internal/schema/schema.go
similarity index 100%
rename from util/schema/schema.go
rename to internal/schema/schema.go
diff --git a/internal/sqladapter/collection.go b/internal/sqladapter/collection.go
index e86e3cb4..7dbd06cb 100644
--- a/internal/sqladapter/collection.go
+++ b/internal/sqladapter/collection.go
@@ -2,7 +2,7 @@ package sqladapter
 
 import (
 	"upper.io/db"
-	"upper.io/db/util/sqlutil/result"
+	"upper.io/db/internal/sqlutil/result"
 )
 
 type Collection interface {
diff --git a/internal/sqladapter/database.go b/internal/sqladapter/database.go
index cdf408fb..294d80fa 100644
--- a/internal/sqladapter/database.go
+++ b/internal/sqladapter/database.go
@@ -8,12 +8,12 @@ import (
 	"github.com/jmoiron/sqlx"
 	"upper.io/cache"
 	"upper.io/db"
-	"upper.io/db/builder"
-	"upper.io/db/util/adapter"
-	"upper.io/db/util/schema"
-	"upper.io/db/util/sqlgen"
-	"upper.io/db/util/sqlutil"
-	"upper.io/db/util/sqlutil/tx"
+	"upper.io/builder"
+	"upper.io/db/internal/adapter"
+	"upper.io/db/internal/schema"
+	"upper.io/builder/sqlgen"
+	"upper.io/db/internal/sqlutil"
+	"upper.io/db/internal/sqlutil/tx"
 )
 
 type PartialDatabase interface {
diff --git a/mongo/database.go b/mongo/database.go
index 7a0a0acc..7277cb48 100644
--- a/mongo/database.go
+++ b/mongo/database.go
@@ -29,7 +29,7 @@ import (
 
 	"gopkg.in/mgo.v2"
 	"upper.io/db"
-	"upper.io/db/util/adapter"
+	"upper.io/db/internal/adapter"
 )
 
 // Adapter holds the name of the mongodb adapter.
diff --git a/mongo/result.go b/mongo/result.go
index 70823c8c..6839d39d 100644
--- a/mongo/result.go
+++ b/mongo/result.go
@@ -32,7 +32,7 @@ import (
 	"gopkg.in/mgo.v2"
 	"gopkg.in/mgo.v2/bson"
 	"upper.io/db"
-	"upper.io/db/util/sqlutil"
+	"upper.io/db/internal/sqlutil"
 )
 
 // result represents a query result.
diff --git a/mysql/collection.go b/mysql/collection.go
index fb5cccd4..429099da 100644
--- a/mysql/collection.go
+++ b/mysql/collection.go
@@ -26,9 +26,9 @@ import (
 	"strings"
 
 	"upper.io/db"
-	"upper.io/db/util/sqlgen"
-	"upper.io/db/util/sqlutil"
-	"upper.io/db/util/sqlutil/result"
+	"upper.io/builder/sqlgen"
+	"upper.io/db/internal/sqlutil"
+	"upper.io/db/internal/sqlutil/result"
 )
 
 type table struct {
diff --git a/mysql/database.go b/mysql/database.go
index b3fe31a3..aa1c567b 100644
--- a/mysql/database.go
+++ b/mysql/database.go
@@ -31,11 +31,11 @@ import (
 	"github.com/jmoiron/sqlx"
 	"upper.io/cache"
 	"upper.io/db"
-	"upper.io/db/util/adapter"
-	"upper.io/db/util/schema"
-	"upper.io/db/util/sqlgen"
-	"upper.io/db/util/sqlutil"
-	"upper.io/db/util/sqlutil/tx"
+	"upper.io/db/internal/adapter"
+	"upper.io/db/internal/schema"
+	"upper.io/builder/sqlgen"
+	"upper.io/db/internal/sqlutil"
+	"upper.io/db/internal/sqlutil/tx"
 )
 
 var (
diff --git a/mysql/database_test.go b/mysql/database_test.go
index 2f356e82..87f1325e 100644
--- a/mysql/database_test.go
+++ b/mysql/database_test.go
@@ -36,7 +36,7 @@ import (
 
 	"github.com/jmoiron/sqlx"
 	"upper.io/db"
-	"upper.io/db/util/sqlutil"
+	"upper.io/db/internal/sqlutil"
 )
 
 const (
diff --git a/mysql/mysql.go b/mysql/mysql.go
index f5ea9f57..d46c200c 100644
--- a/mysql/mysql.go
+++ b/mysql/mysql.go
@@ -24,8 +24,8 @@ package mysql // import "upper.io/db/mysql"
 import (
 	"upper.io/cache"
 	"upper.io/db"
-	"upper.io/db/util/sqlgen"
-	"upper.io/db/util/sqlutil"
+	"upper.io/builder/sqlgen"
+	"upper.io/db/internal/sqlutil"
 )
 
 // Adapter is the public name of the adapter.
diff --git a/mysql/tx.go b/mysql/tx.go
index 0d0d1738..21b6ecf8 100644
--- a/mysql/tx.go
+++ b/mysql/tx.go
@@ -22,7 +22,7 @@
 package mysql
 
 import (
-	"upper.io/db/util/sqlutil/tx"
+	"upper.io/db/internal/sqlutil/tx"
 )
 
 type tx struct {
diff --git a/postgresql/collection.go b/postgresql/collection.go
index 50a8c304..4c1c7272 100644
--- a/postgresql/collection.go
+++ b/postgresql/collection.go
@@ -27,9 +27,9 @@ import (
 	"strings"
 
 	"upper.io/db"
-	"upper.io/db/builder"
+	"upper.io/builder"
 	"upper.io/db/internal/sqladapter"
-	"upper.io/db/util/sqlgen"
+	"upper.io/builder/sqlgen"
 )
 
 type table struct {
diff --git a/postgresql/database.go b/postgresql/database.go
index 9c249779..dfd11052 100644
--- a/postgresql/database.go
+++ b/postgresql/database.go
@@ -29,7 +29,7 @@ import (
 	_ "github.com/lib/pq" // PostgreSQL driver.
 	"upper.io/db"
 	"upper.io/db/internal/sqladapter"
-	"upper.io/db/util/sqlgen"
+	"upper.io/builder/sqlgen"
 )
 
 type database struct {
diff --git a/postgresql/postgresql.go b/postgresql/postgresql.go
index 2c952d11..f0d51db4 100644
--- a/postgresql/postgresql.go
+++ b/postgresql/postgresql.go
@@ -24,8 +24,8 @@ package postgresql // import "upper.io/db/postgresql"
 import (
 	"upper.io/cache"
 	"upper.io/db"
-	"upper.io/db/util/sqlgen"
-	"upper.io/db/util/sqlutil"
+	"upper.io/builder/sqlgen"
+	"upper.io/db/internal/sqlutil"
 )
 
 // Adapter is the public name of the adapter.
diff --git a/postgresql/tx.go b/postgresql/tx.go
index 89560de7..5a91a828 100644
--- a/postgresql/tx.go
+++ b/postgresql/tx.go
@@ -23,7 +23,7 @@ package postgresql
 
 import (
 	"upper.io/db"
-	"upper.io/db/util/sqlutil/tx"
+	"upper.io/db/internal/sqlutil/tx"
 )
 
 type tx struct {
diff --git a/ql/collection.go b/ql/collection.go
index b6b5fcf3..3687cc4b 100644
--- a/ql/collection.go
+++ b/ql/collection.go
@@ -27,9 +27,9 @@ import (
 	"strings"
 
 	"upper.io/db"
-	"upper.io/db/util/sqlgen"
-	"upper.io/db/util/sqlutil"
-	"upper.io/db/util/sqlutil/result"
+	"upper.io/builder/sqlgen"
+	"upper.io/db/internal/sqlutil"
+	"upper.io/db/internal/sqlutil/result"
 )
 
 type table struct {
diff --git a/ql/database.go b/ql/database.go
index 69a6f861..80607d77 100644
--- a/ql/database.go
+++ b/ql/database.go
@@ -34,11 +34,11 @@ import (
 	"github.com/jmoiron/sqlx"
 	"upper.io/cache"
 	"upper.io/db"
-	"upper.io/db/util/adapter"
-	"upper.io/db/util/schema"
-	"upper.io/db/util/sqlgen"
-	"upper.io/db/util/sqlutil"
-	"upper.io/db/util/sqlutil/tx"
+	"upper.io/db/internal/adapter"
+	"upper.io/db/internal/schema"
+	"upper.io/builder/sqlgen"
+	"upper.io/db/internal/sqlutil"
+	"upper.io/db/internal/sqlutil/tx"
 )
 
 var (
diff --git a/ql/database_test.go b/ql/database_test.go
index bd6abdb0..d7f0f20c 100644
--- a/ql/database_test.go
+++ b/ql/database_test.go
@@ -40,7 +40,7 @@ import (
 
 	"github.com/jmoiron/sqlx"
 	"upper.io/db"
-	"upper.io/db/util/sqlutil"
+	"upper.io/db/internal/sqlutil"
 )
 
 const (
diff --git a/ql/ql.go b/ql/ql.go
index 3249a413..3710a8c0 100644
--- a/ql/ql.go
+++ b/ql/ql.go
@@ -24,8 +24,8 @@ package ql // import "upper.io/db/ql"
 import (
 	"upper.io/cache"
 	"upper.io/db"
-	"upper.io/db/util/sqlgen"
-	"upper.io/db/util/sqlutil"
+	"upper.io/builder/sqlgen"
+	"upper.io/db/internal/sqlutil"
 )
 
 // Adapter is the public name of the adapter.
diff --git a/ql/tx.go b/ql/tx.go
index b6659a48..9bf3b26d 100644
--- a/ql/tx.go
+++ b/ql/tx.go
@@ -22,7 +22,7 @@
 package ql
 
 import (
-	"upper.io/db/util/sqlutil/tx"
+	"upper.io/db/internal/sqlutil/tx"
 )
 
 type tx struct {
diff --git a/sqlite/collection.go b/sqlite/collection.go
index 59442646..fe5d27ea 100644
--- a/sqlite/collection.go
+++ b/sqlite/collection.go
@@ -27,9 +27,9 @@ import (
 	"database/sql"
 
 	"upper.io/db"
-	"upper.io/db/util/sqlgen"
-	"upper.io/db/util/sqlutil"
-	"upper.io/db/util/sqlutil/result"
+	"upper.io/builder/sqlgen"
+	"upper.io/db/internal/sqlutil"
+	"upper.io/db/internal/sqlutil/result"
 )
 
 type table struct {
diff --git a/sqlite/database.go b/sqlite/database.go
index 052f672d..453d6745 100644
--- a/sqlite/database.go
+++ b/sqlite/database.go
@@ -34,11 +34,11 @@ import (
 	_ "github.com/mattn/go-sqlite3" // SQLite3 driver.
 	"upper.io/cache"
 	"upper.io/db"
-	"upper.io/db/util/adapter"
-	"upper.io/db/util/schema"
-	"upper.io/db/util/sqlgen"
-	"upper.io/db/util/sqlutil"
-	"upper.io/db/util/sqlutil/tx"
+	"upper.io/db/internal/adapter"
+	"upper.io/db/internal/schema"
+	"upper.io/builder/sqlgen"
+	"upper.io/db/internal/sqlutil"
+	"upper.io/db/internal/sqlutil/tx"
 )
 
 var (
diff --git a/sqlite/database_test.go b/sqlite/database_test.go
index 321753c1..a7557e31 100644
--- a/sqlite/database_test.go
+++ b/sqlite/database_test.go
@@ -42,7 +42,7 @@ import (
 
 	"github.com/jmoiron/sqlx"
 	"upper.io/db"
-	"upper.io/db/util/sqlutil"
+	"upper.io/db/internal/sqlutil"
 )
 
 const (
diff --git a/sqlite/sqlite.go b/sqlite/sqlite.go
index 753c217a..865d6b15 100644
--- a/sqlite/sqlite.go
+++ b/sqlite/sqlite.go
@@ -24,8 +24,8 @@ package sqlite // import "upper.io/db/sqlite"
 import (
 	"upper.io/cache"
 	"upper.io/db"
-	"upper.io/db/util/sqlgen"
-	"upper.io/db/util/sqlutil"
+	"upper.io/builder/sqlgen"
+	"upper.io/db/internal/sqlutil"
 )
 
 // Adapter is the public name of the adapter.
diff --git a/sqlite/tx.go b/sqlite/tx.go
index 99bbe9f9..a7032308 100644
--- a/sqlite/tx.go
+++ b/sqlite/tx.go
@@ -22,7 +22,7 @@
 package sqlite
 
 import (
-	"upper.io/db/util/sqlutil/tx"
+	"upper.io/db/internal/sqlutil/tx"
 )
 
 type tx struct {
diff --git a/util/sqlgen/column.go b/util/sqlgen/column.go
deleted file mode 100644
index 4eb395e1..00000000
--- a/util/sqlgen/column.go
+++ /dev/null
@@ -1,91 +0,0 @@
-package sqlgen
-
-import (
-	"fmt"
-	"strings"
-)
-
-type columnT struct {
-	Name  string
-	Alias string
-}
-
-// Column represents a SQL column.
-type Column struct {
-	Name interface{}
-	hash string
-}
-
-// ColumnWithName creates and returns a Column with the given name.
-func ColumnWithName(name string) *Column {
-	return &Column{Name: name}
-}
-
-// Hash returns a unique identifier.
-func (c *Column) Hash() string {
-	if c.hash == "" {
-		var s string
-
-		switch t := c.Name.(type) {
-		case Fragment:
-			s = t.Hash()
-		case fmt.Stringer:
-			s = t.String()
-		case string:
-			s = t
-		default:
-			s = fmt.Sprintf("%v", c.Name)
-		}
-
-		c.hash = fmt.Sprintf(`Column{Name:%q}`, s)
-	}
-
-	return c.hash
-}
-
-// Compile transforms the ColumnValue into an equivalent SQL representation.
-func (c *Column) Compile(layout *Template) (compiled string) {
-
-	if z, ok := layout.Read(c); ok {
-		return z
-	}
-
-	switch value := c.Name.(type) {
-	case string:
-		input := trimString(value)
-
-		chunks := separateByAS(input)
-
-		if len(chunks) == 1 {
-			chunks = separateBySpace(input)
-		}
-
-		name := chunks[0]
-
-		nameChunks := strings.SplitN(name, layout.ColumnSeparator, 2)
-
-		for i := range nameChunks {
-			nameChunks[i] = trimString(nameChunks[i])
-			nameChunks[i] = mustParse(layout.IdentifierQuote, Raw{Value: nameChunks[i]})
-		}
-
-		name = strings.Join(nameChunks, layout.ColumnSeparator)
-
-		var alias string
-
-		if len(chunks) > 1 {
-			alias = trimString(chunks[1])
-			alias = mustParse(layout.IdentifierQuote, Raw{Value: alias})
-		}
-
-		compiled = mustParse(layout.ColumnAliasLayout, columnT{name, alias})
-	case Raw:
-		compiled = value.String()
-	default:
-		compiled = fmt.Sprintf("%v", c.Name)
-	}
-
-	layout.Write(c, compiled)
-
-	return
-}
diff --git a/util/sqlgen/column_test.go b/util/sqlgen/column_test.go
deleted file mode 100644
index e5fdb7d8..00000000
--- a/util/sqlgen/column_test.go
+++ /dev/null
@@ -1,119 +0,0 @@
-package sqlgen
-
-import (
-	"fmt"
-	"testing"
-)
-
-func TestColumnHash(t *testing.T) {
-	var s, e string
-
-	column := Column{Name: "role.name"}
-
-	s = column.Hash()
-	e = fmt.Sprintf(`Column{Name:"%s"}`, column.Name)
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestColumnString(t *testing.T) {
-	var s, e string
-
-	column := Column{Name: "role.name"}
-
-	s = column.Compile(defaultTemplate)
-	e = `"role"."name"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestColumnAs(t *testing.T) {
-	var s, e string
-
-	column := Column{Name: "role.name as foo"}
-
-	s = column.Compile(defaultTemplate)
-	e = `"role"."name" AS "foo"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestColumnImplicitAs(t *testing.T) {
-	var s, e string
-
-	column := Column{Name: "role.name foo"}
-
-	s = column.Compile(defaultTemplate)
-	e = `"role"."name" AS "foo"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestColumnRaw(t *testing.T) {
-	var s, e string
-
-	column := Column{Name: Raw{Value: "role.name As foo"}}
-
-	s = column.Compile(defaultTemplate)
-	e = `role.name As foo`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func BenchmarkColumnWithName(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = ColumnWithName("a")
-	}
-}
-
-func BenchmarkColumnHash(b *testing.B) {
-	c := Column{Name: "name"}
-	for i := 0; i < b.N; i++ {
-		c.Hash()
-	}
-}
-
-func BenchmarkColumnCompile(b *testing.B) {
-	c := Column{Name: "name"}
-	for i := 0; i < b.N; i++ {
-		c.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkColumnCompileNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		c := Column{Name: "name"}
-		c.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkColumnWithDotCompile(b *testing.B) {
-	c := Column{Name: "role.name"}
-	for i := 0; i < b.N; i++ {
-		c.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkColumnWithImplicitAsKeywordCompile(b *testing.B) {
-	c := Column{Name: "role.name foo"}
-	for i := 0; i < b.N; i++ {
-		c.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkColumnWithAsKeywordCompile(b *testing.B) {
-	c := Column{Name: "role.name AS foo"}
-	for i := 0; i < b.N; i++ {
-		c.Compile(defaultTemplate)
-	}
-}
diff --git a/util/sqlgen/column_value.go b/util/sqlgen/column_value.go
deleted file mode 100644
index 9674b41a..00000000
--- a/util/sqlgen/column_value.go
+++ /dev/null
@@ -1,101 +0,0 @@
-package sqlgen
-
-import (
-	"fmt"
-	"strings"
-)
-
-// ColumnValue represents a bundle between a column and a corresponding value.
-type ColumnValue struct {
-	Column   Fragment
-	Operator string
-	Value    Fragment
-	hash     string
-}
-
-type columnValueT struct {
-	Column   string
-	Operator string
-	Value    string
-}
-
-// Hash returns a unique identifier.
-func (c *ColumnValue) Hash() string {
-	if c.hash == "" {
-		c.hash = fmt.Sprintf(`ColumnValue{Name:%q, Operator:%q, Value:%q}`, c.Column.Hash(), c.Operator, c.Value.Hash())
-	}
-	return c.hash
-}
-
-// Compile transforms the ColumnValue into an equivalent SQL representation.
-func (c *ColumnValue) Compile(layout *Template) (compiled string) {
-
-	if z, ok := layout.Read(c); ok {
-		return z
-	}
-
-	data := columnValueT{
-		c.Column.Compile(layout),
-		c.Operator,
-		c.Value.Compile(layout),
-	}
-
-	compiled = mustParse(layout.ColumnValue, data)
-
-	layout.Write(c, compiled)
-
-	return
-}
-
-// ColumnValues represents an array of ColumnValue
-type ColumnValues struct {
-	ColumnValues []Fragment
-	hash         string
-}
-
-// JoinColumnValues returns an array of ColumnValue
-func JoinColumnValues(values ...Fragment) *ColumnValues {
-	return &ColumnValues{ColumnValues: values}
-}
-
-func (c *ColumnValues) Append(values ...Fragment) *ColumnValues {
-	for _, f := range values {
-		c.ColumnValues = append(c.ColumnValues, f)
-	}
-	c.hash = ""
-	return c
-}
-
-// Hash returns a unique identifier.
-func (c *ColumnValues) Hash() string {
-	if c.hash == "" {
-		s := make([]string, len(c.ColumnValues))
-		for i := range c.ColumnValues {
-			s[i] = c.ColumnValues[i].Hash()
-		}
-		c.hash = fmt.Sprintf("ColumnValues{ColumnValues:{%s}}", strings.Join(s, ", "))
-	}
-	return c.hash
-}
-
-// Compile transforms the ColumnValues into its SQL representation.
-func (c *ColumnValues) Compile(layout *Template) (compiled string) {
-
-	if z, ok := layout.Read(c); ok {
-		return z
-	}
-
-	l := len(c.ColumnValues)
-
-	out := make([]string, l)
-
-	for i := range c.ColumnValues {
-		out[i] = c.ColumnValues[i].Compile(layout)
-	}
-
-	compiled = strings.Join(out, layout.IdentifierSeparator)
-
-	layout.Write(c, compiled)
-
-	return
-}
diff --git a/util/sqlgen/column_value_test.go b/util/sqlgen/column_value_test.go
deleted file mode 100644
index 9a954697..00000000
--- a/util/sqlgen/column_value_test.go
+++ /dev/null
@@ -1,156 +0,0 @@
-package sqlgen
-
-import (
-	"fmt"
-	"testing"
-)
-
-func TestColumnValueHash(t *testing.T) {
-	var s, e string
-
-	c := &ColumnValue{Column: ColumnWithName("id"), Operator: "=", Value: NewValue(1)}
-
-	s = c.Hash()
-	e = fmt.Sprintf(`ColumnValue{Name:%q, Operator:%q, Value:%q}`, c.Column.Hash(), c.Operator, c.Value.Hash())
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestColumnValuesHash(t *testing.T) {
-	var s, e string
-
-	c := JoinColumnValues(
-		&ColumnValue{Column: ColumnWithName("id"), Operator: "=", Value: NewValue(1)},
-		&ColumnValue{Column: ColumnWithName("id"), Operator: "=", Value: NewValue(2)},
-	)
-
-	s = c.Hash()
-
-	e = fmt.Sprintf(`ColumnValues{ColumnValues:{%s, %s}}`, c.ColumnValues[0].Hash(), c.ColumnValues[1].Hash())
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestColumnValue(t *testing.T) {
-	var s, e string
-	var cv *ColumnValue
-
-	cv = &ColumnValue{Column: ColumnWithName("id"), Operator: "=", Value: NewValue(1)}
-
-	s = cv.Compile(defaultTemplate)
-	e = `"id" = '1'`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-
-	cv = &ColumnValue{Column: ColumnWithName("date"), Operator: "=", Value: NewValue(RawValue("NOW()"))}
-
-	s = cv.Compile(defaultTemplate)
-	e = `"date" = NOW()`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestColumnValues(t *testing.T) {
-	var s, e string
-
-	cvs := JoinColumnValues(
-		&ColumnValue{Column: ColumnWithName("id"), Operator: ">", Value: NewValue(8)},
-		&ColumnValue{Column: ColumnWithName("other.id"), Operator: "<", Value: NewValue(&Raw{Value: "100"})},
-		&ColumnValue{Column: ColumnWithName("name"), Operator: "=", Value: NewValue("Haruki Murakami")},
-		&ColumnValue{Column: ColumnWithName("created"), Operator: ">=", Value: NewValue(&Raw{Value: "NOW()"})},
-		&ColumnValue{Column: ColumnWithName("modified"), Operator: "<=", Value: NewValue(&Raw{Value: "NOW()"})},
-	)
-
-	s = cvs.Compile(defaultTemplate)
-	e = `"id" > '8', "other"."id" < 100, "name" = 'Haruki Murakami', "created" >= NOW(), "modified" <= NOW()`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func BenchmarkNewColumnValue(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = &ColumnValue{Column: ColumnWithName("a"), Operator: "=", Value: NewValue(Raw{Value: "7"})}
-	}
-}
-
-func BenchmarkColumnValueHash(b *testing.B) {
-	cv := &ColumnValue{Column: ColumnWithName("id"), Operator: "=", Value: NewValue(1)}
-	for i := 0; i < b.N; i++ {
-		cv.Hash()
-	}
-}
-
-func BenchmarkColumnValueCompile(b *testing.B) {
-	cv := &ColumnValue{Column: ColumnWithName("id"), Operator: "=", Value: NewValue(1)}
-	for i := 0; i < b.N; i++ {
-		cv.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkColumnValueCompileNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		cv := &ColumnValue{Column: ColumnWithName("id"), Operator: "=", Value: NewValue(1)}
-		cv.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkJoinColumnValues(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = JoinColumnValues(
-			&ColumnValue{Column: ColumnWithName("id"), Operator: ">", Value: NewValue(8)},
-			&ColumnValue{Column: ColumnWithName("other.id"), Operator: "<", Value: NewValue(Raw{Value: "100"})},
-			&ColumnValue{Column: ColumnWithName("name"), Operator: "=", Value: NewValue("Haruki Murakami")},
-			&ColumnValue{Column: ColumnWithName("created"), Operator: ">=", Value: NewValue(Raw{Value: "NOW()"})},
-			&ColumnValue{Column: ColumnWithName("modified"), Operator: "<=", Value: NewValue(Raw{Value: "NOW()"})},
-		)
-	}
-}
-
-func BenchmarkColumnValuesHash(b *testing.B) {
-	cvs := JoinColumnValues(
-		&ColumnValue{Column: ColumnWithName("id"), Operator: ">", Value: NewValue(8)},
-		&ColumnValue{Column: ColumnWithName("other.id"), Operator: "<", Value: NewValue(Raw{Value: "100"})},
-		&ColumnValue{Column: ColumnWithName("name"), Operator: "=", Value: NewValue("Haruki Murakami")},
-		&ColumnValue{Column: ColumnWithName("created"), Operator: ">=", Value: NewValue(Raw{Value: "NOW()"})},
-		&ColumnValue{Column: ColumnWithName("modified"), Operator: "<=", Value: NewValue(Raw{Value: "NOW()"})},
-	)
-	for i := 0; i < b.N; i++ {
-		cvs.Hash()
-	}
-}
-
-func BenchmarkColumnValuesCompile(b *testing.B) {
-	cvs := JoinColumnValues(
-		&ColumnValue{Column: ColumnWithName("id"), Operator: ">", Value: NewValue(8)},
-		&ColumnValue{Column: ColumnWithName("other.id"), Operator: "<", Value: NewValue(Raw{Value: "100"})},
-		&ColumnValue{Column: ColumnWithName("name"), Operator: "=", Value: NewValue("Haruki Murakami")},
-		&ColumnValue{Column: ColumnWithName("created"), Operator: ">=", Value: NewValue(Raw{Value: "NOW()"})},
-		&ColumnValue{Column: ColumnWithName("modified"), Operator: "<=", Value: NewValue(Raw{Value: "NOW()"})},
-	)
-	for i := 0; i < b.N; i++ {
-		cvs.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkColumnValuesCompileNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		cvs := JoinColumnValues(
-			&ColumnValue{Column: ColumnWithName("id"), Operator: ">", Value: NewValue(8)},
-			&ColumnValue{Column: ColumnWithName("other.id"), Operator: "<", Value: NewValue(Raw{Value: "100"})},
-			&ColumnValue{Column: ColumnWithName("name"), Operator: "=", Value: NewValue("Haruki Murakami")},
-			&ColumnValue{Column: ColumnWithName("created"), Operator: ">=", Value: NewValue(Raw{Value: "NOW()"})},
-			&ColumnValue{Column: ColumnWithName("modified"), Operator: "<=", Value: NewValue(Raw{Value: "NOW()"})},
-		)
-		cvs.Compile(defaultTemplate)
-	}
-}
diff --git a/util/sqlgen/columns.go b/util/sqlgen/columns.go
deleted file mode 100644
index eb105180..00000000
--- a/util/sqlgen/columns.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package sqlgen
-
-import (
-	"fmt"
-	"strings"
-)
-
-// Columns represents an array of Column.
-type Columns struct {
-	Columns []Fragment
-	hash    string
-}
-
-// Hash returns a unique identifier.
-func (c *Columns) Hash() string {
-	if c.hash == "" {
-		s := make([]string, len(c.Columns))
-		for i := range c.Columns {
-			s[i] = c.Columns[i].Hash()
-		}
-		c.hash = fmt.Sprintf("Columns{Columns:{%s}}", strings.Join(s, ", "))
-	}
-	return c.hash
-}
-
-// JoinColumns creates and returns an array of Column.
-func JoinColumns(columns ...Fragment) *Columns {
-	return &Columns{Columns: columns}
-}
-
-// OnConditions creates and retuens a new On.
-func OnConditions(conditions ...Fragment) *On {
-	return &On{Conditions: conditions}
-}
-
-// UsingColumns builds a Using from the given columns.
-func UsingColumns(columns ...Fragment) *Using {
-	return &Using{Columns: columns}
-}
-
-// Compile transforms the Columns into an equivalent SQL representation.
-func (c *Columns) Compile(layout *Template) (compiled string) {
-
-	if z, ok := layout.Read(c); ok {
-		return z
-	}
-
-	l := len(c.Columns)
-
-	if l > 0 {
-		out := make([]string, l)
-
-		for i := 0; i < l; i++ {
-			out[i] = c.Columns[i].Compile(layout)
-		}
-
-		compiled = strings.Join(out, layout.IdentifierSeparator)
-	}
-
-	layout.Write(c, compiled)
-
-	return
-}
diff --git a/util/sqlgen/columns_test.go b/util/sqlgen/columns_test.go
deleted file mode 100644
index a4f43979..00000000
--- a/util/sqlgen/columns_test.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package sqlgen
-
-import (
-	"testing"
-)
-
-func TestColumns(t *testing.T) {
-	var s, e string
-
-	columns := JoinColumns(
-		&Column{Name: "id"},
-		&Column{Name: "customer"},
-		&Column{Name: "service_id"},
-		&Column{Name: "role.name"},
-		&Column{Name: "role.id"},
-	)
-
-	s = columns.Compile(defaultTemplate)
-	e = `"id", "customer", "service_id", "role"."name", "role"."id"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func BenchmarkJoinColumns(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = JoinColumns(
-			&Column{Name: "a"},
-			&Column{Name: "b"},
-			&Column{Name: "c"},
-		)
-	}
-}
-
-func BenchmarkColumnsHash(b *testing.B) {
-	c := JoinColumns(
-		&Column{Name: "id"},
-		&Column{Name: "customer"},
-		&Column{Name: "service_id"},
-		&Column{Name: "role.name"},
-		&Column{Name: "role.id"},
-	)
-	for i := 0; i < b.N; i++ {
-		c.Hash()
-	}
-}
-
-func BenchmarkColumnsCompile(b *testing.B) {
-	c := JoinColumns(
-		&Column{Name: "id"},
-		&Column{Name: "customer"},
-		&Column{Name: "service_id"},
-		&Column{Name: "role.name"},
-		&Column{Name: "role.id"},
-	)
-	for i := 0; i < b.N; i++ {
-		c.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkColumnsCompileNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		c := JoinColumns(
-			&Column{Name: "id"},
-			&Column{Name: "customer"},
-			&Column{Name: "service_id"},
-			&Column{Name: "role.name"},
-			&Column{Name: "role.id"},
-		)
-		c.Compile(defaultTemplate)
-	}
-}
diff --git a/util/sqlgen/database.go b/util/sqlgen/database.go
deleted file mode 100644
index df7001dd..00000000
--- a/util/sqlgen/database.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package sqlgen
-
-import (
-	"fmt"
-)
-
-// Database represents a SQL database.
-type Database struct {
-	Name string
-	hash string
-}
-
-// DatabaseWithName returns a Database with the given name.
-func DatabaseWithName(name string) *Database {
-	return &Database{Name: name}
-}
-
-// Hash returns a unique identifier.
-func (d *Database) Hash() string {
-	if d.hash == "" {
-		d.hash = fmt.Sprintf(`Database{Name:%q}`, d.Name)
-	}
-	return d.hash
-}
-
-// Compile transforms the Database into an equivalent SQL representation.
-func (d *Database) Compile(layout *Template) (compiled string) {
-	if c, ok := layout.Read(d); ok {
-		return c
-	}
-
-	compiled = mustParse(layout.IdentifierQuote, Raw{Value: d.Name})
-
-	layout.Write(d, compiled)
-
-	return
-}
diff --git a/util/sqlgen/database_test.go b/util/sqlgen/database_test.go
deleted file mode 100644
index 33b1ad82..00000000
--- a/util/sqlgen/database_test.go
+++ /dev/null
@@ -1,53 +0,0 @@
-package sqlgen
-
-import (
-	"fmt"
-	"testing"
-)
-
-func TestDatabaseHash(t *testing.T) {
-	var s, e string
-
-	column := Database{Name: "users"}
-
-	s = column.Hash()
-	e = fmt.Sprintf(`Database{Name:"%s"}`, column.Name)
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestDatabaseCompile(t *testing.T) {
-	var s, e string
-
-	column := Database{Name: "name"}
-
-	s = column.Compile(defaultTemplate)
-	e = `"name"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func BenchmarkDatabaseHash(b *testing.B) {
-	c := Database{Name: "name"}
-	for i := 0; i < b.N; i++ {
-		c.Hash()
-	}
-}
-
-func BenchmarkDatabaseCompile(b *testing.B) {
-	c := Database{Name: "name"}
-	for i := 0; i < b.N; i++ {
-		c.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkDatabaseCompileNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		c := Database{Name: "name"}
-		c.Compile(defaultTemplate)
-	}
-}
diff --git a/util/sqlgen/default.go b/util/sqlgen/default.go
deleted file mode 100644
index db531ccd..00000000
--- a/util/sqlgen/default.go
+++ /dev/null
@@ -1,192 +0,0 @@
-package sqlgen
-
-import (
-	"upper.io/cache"
-)
-
-const (
-	defaultColumnSeparator     = `.`
-	defaultIdentifierSeparator = `, `
-	defaultIdentifierQuote     = `"{{.Value}}"`
-	defaultValueSeparator      = `, `
-	defaultValueQuote          = `'{{.}}'`
-	defaultAndKeyword          = `AND`
-	defaultOrKeyword           = `OR`
-	defaultNotKeyword          = `NOT`
-	defaultDescKeyword         = `DESC`
-	defaultAscKeyword          = `ASC`
-	defaultDefaultOperator     = `=`
-	defaultAssignmentOperator  = `=`
-	defaultClauseGroup         = `({{.}})`
-	defaultClauseOperator      = ` {{.}} `
-	defaultColumnValue         = `{{.Column}} {{.Operator}} {{.Value}}`
-	defaultTableAliasLayout    = `{{.Name}}{{if .Alias}} AS {{.Alias}}{{end}}`
-	defaultColumnAliasLayout   = `{{.Name}}{{if .Alias}} AS {{.Alias}}{{end}}`
-	defaultSortByColumnLayout  = `{{.Column}} {{.Order}}`
-
-	defaultOrderByLayout = `
-		{{if .SortColumns}}
-			ORDER BY {{.SortColumns}}
-		{{end}}
-	`
-
-	defaultWhereLayout = `
-		{{if .Conds}}
-			WHERE {{.Conds}}
-		{{end}}
-	`
-
-	defaultUsingLayout = `
-		{{if .Columns}}
-			USING ({{.Columns}})
-		{{end}}
-	`
-
-	defaultJoinLayout = `
-		{{if .Table}}
-			{{ if .On }}
-				{{.Type}} JOIN {{.Table}}
-				{{.On}}
-			{{ else if .Using }}
-				{{.Type}} JOIN {{.Table}}
-				{{.Using}}
-			{{ else if .Type | eq "CROSS" }}
-				{{.Type}} JOIN {{.Table}}
-			{{else}}
-				NATURAL {{.Type}} JOIN {{.Table}}
-			{{end}}
-		{{end}}
-	`
-
-	defaultOnLayout = `
-		{{if .Conds}}
-			ON {{.Conds}}
-		{{end}}
-	`
-
-	defaultSelectLayout = `
-    SELECT
-
-      {{if .Columns}}
-        {{.Columns}}
-      {{else}}
-        *
-      {{end}}
-
-      {{if .Table}}
-        FROM {{.Table}}
-      {{end}}
-
-      {{.Joins}}
-
-      {{.Where}}
-
-      {{.GroupBy}}
-
-      {{.OrderBy}}
-
-      {{if .Limit}}
-        LIMIT {{.Limit}}
-      {{end}}
-
-      {{if .Offset}}
-        OFFSET {{.Offset}}
-      {{end}}
-	`
-	defaultDeleteLayout = `
-    DELETE
-      FROM {{.Table}}
-      {{.Where}}
-    {{if .Limit}}
-      LIMIT {{.Limit}}
-    {{end}}
-    {{if .Offset}}
-      OFFSET {{.Offset}}
-    {{end}}
-	`
-	defaultUpdateLayout = `
-		UPDATE
-			{{.Table}}
-		SET {{.ColumnValues}}
-			{{ .Where }}
-	`
-
-	defaultCountLayout = `
-		SELECT
-			COUNT(1) AS _t
-		FROM {{.Table}}
-			{{.Where}}
-
-			{{if .Limit}}
-				LIMIT {{.Limit}}
-			{{end}}
-
-			{{if .Offset}}
-				OFFSET {{.Offset}}
-			{{end}}
-	`
-
-	defaultInsertLayout = `
-    INSERT INTO {{.Table}}
-      {{if .Columns }}({{.Columns}}){{end}}
-    VALUES
-      {{.Values}}
-    {{.Extra}}
-	`
-
-	defaultTruncateLayout = `
-		TRUNCATE TABLE {{.Table}}
-	`
-
-	defaultDropDatabaseLayout = `
-		DROP DATABASE {{.Database}}
-	`
-
-	defaultDropTableLayout = `
-		DROP TABLE {{.Table}}
-	`
-
-	defaultGroupByColumnLayout = `{{.Column}}`
-
-	defaultGroupByLayout = `
-		{{if .GroupColumns}}
-			GROUP BY {{.GroupColumns}}
-		{{end}}
-	`
-)
-
-var defaultTemplate = &Template{
-	ColumnSeparator:     defaultColumnSeparator,
-	IdentifierSeparator: defaultIdentifierSeparator,
-	IdentifierQuote:     defaultIdentifierQuote,
-	ValueSeparator:      defaultValueSeparator,
-	ValueQuote:          defaultValueQuote,
-	AndKeyword:          defaultAndKeyword,
-	OrKeyword:           defaultOrKeyword,
-	NotKeyword:          defaultNotKeyword,
-	DescKeyword:         defaultDescKeyword,
-	AscKeyword:          defaultAscKeyword,
-	DefaultOperator:     defaultDefaultOperator,
-	AssignmentOperator:  defaultAssignmentOperator,
-	ClauseGroup:         defaultClauseGroup,
-	ClauseOperator:      defaultClauseOperator,
-	ColumnValue:         defaultColumnValue,
-	TableAliasLayout:    defaultTableAliasLayout,
-	ColumnAliasLayout:   defaultColumnAliasLayout,
-	SortByColumnLayout:  defaultSortByColumnLayout,
-	WhereLayout:         defaultWhereLayout,
-	OnLayout:            defaultOnLayout,
-	UsingLayout:         defaultUsingLayout,
-	JoinLayout:          defaultJoinLayout,
-	OrderByLayout:       defaultOrderByLayout,
-	InsertLayout:        defaultInsertLayout,
-	SelectLayout:        defaultSelectLayout,
-	UpdateLayout:        defaultUpdateLayout,
-	DeleteLayout:        defaultDeleteLayout,
-	TruncateLayout:      defaultTruncateLayout,
-	DropDatabaseLayout:  defaultDropDatabaseLayout,
-	DropTableLayout:     defaultDropTableLayout,
-	CountLayout:         defaultCountLayout,
-	GroupByLayout:       defaultGroupByLayout,
-	Cache:               cache.NewCache(),
-}
diff --git a/util/sqlgen/group_by.go b/util/sqlgen/group_by.go
deleted file mode 100644
index fe8ed3f3..00000000
--- a/util/sqlgen/group_by.go
+++ /dev/null
@@ -1,50 +0,0 @@
-package sqlgen
-
-import (
-	"fmt"
-)
-
-// GroupBy represents a SQL's "group by" statement.
-type GroupBy struct {
-	Columns Fragment
-	hash    string
-}
-
-type groupByT struct {
-	GroupColumns string
-}
-
-// Hash returns a unique identifier.
-func (g *GroupBy) Hash() string {
-	if g.hash == "" {
-		if g.Columns != nil {
-			g.hash = fmt.Sprintf(`GroupBy(%s)`, g.Columns.Hash())
-		}
-	}
-	return g.hash
-}
-
-// GroupByColumns creates and returns a GroupBy with the given column.
-func GroupByColumns(columns ...Fragment) *GroupBy {
-	return &GroupBy{Columns: JoinColumns(columns...)}
-}
-
-// Compile transforms the GroupBy into an equivalent SQL representation.
-func (g *GroupBy) Compile(layout *Template) (compiled string) {
-
-	if c, ok := layout.Read(g); ok {
-		return c
-	}
-
-	if g.Columns != nil {
-		data := groupByT{
-			GroupColumns: g.Columns.Compile(layout),
-		}
-
-		compiled = mustParse(layout.GroupByLayout, data)
-	}
-
-	layout.Write(g, compiled)
-
-	return
-}
diff --git a/util/sqlgen/group_by_test.go b/util/sqlgen/group_by_test.go
deleted file mode 100644
index c6c6a6f3..00000000
--- a/util/sqlgen/group_by_test.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package sqlgen
-
-import (
-	"testing"
-)
-
-func TestGroupBy(t *testing.T) {
-	var s, e string
-
-	columns := GroupByColumns(
-		&Column{Name: "id"},
-		&Column{Name: "customer"},
-		&Column{Name: "service_id"},
-		&Column{Name: "role.name"},
-		&Column{Name: "role.id"},
-	)
-
-	s = columns.Compile(defaultTemplate)
-	e = `GROUP BY "id", "customer", "service_id", "role"."name", "role"."id"`
-
-	if trim(s) != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func BenchmarkGroupByColumns(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = GroupByColumns(
-			&Column{Name: "a"},
-			&Column{Name: "b"},
-			&Column{Name: "c"},
-		)
-	}
-}
-
-func BenchmarkGroupByHash(b *testing.B) {
-	c := GroupByColumns(
-		&Column{Name: "id"},
-		&Column{Name: "customer"},
-		&Column{Name: "service_id"},
-		&Column{Name: "role.name"},
-		&Column{Name: "role.id"},
-	)
-	for i := 0; i < b.N; i++ {
-		c.Hash()
-	}
-}
-
-func BenchmarkGroupByCompile(b *testing.B) {
-	c := GroupByColumns(
-		&Column{Name: "id"},
-		&Column{Name: "customer"},
-		&Column{Name: "service_id"},
-		&Column{Name: "role.name"},
-		&Column{Name: "role.id"},
-	)
-	for i := 0; i < b.N; i++ {
-		c.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkGroupByCompileNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		c := GroupByColumns(
-			&Column{Name: "id"},
-			&Column{Name: "customer"},
-			&Column{Name: "service_id"},
-			&Column{Name: "role.name"},
-			&Column{Name: "role.id"},
-		)
-		c.Compile(defaultTemplate)
-	}
-}
diff --git a/util/sqlgen/interfaces.go b/util/sqlgen/interfaces.go
deleted file mode 100644
index a077715a..00000000
--- a/util/sqlgen/interfaces.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package sqlgen
-
-import (
-	"upper.io/cache"
-)
-
-// Fragment is any interface that can be both cached and compiled.
-type Fragment interface {
-	cache.Hashable
-	compilable
-}
-
-type compilable interface {
-	Compile(*Template) string
-}
diff --git a/util/sqlgen/join.go b/util/sqlgen/join.go
deleted file mode 100644
index ea336c48..00000000
--- a/util/sqlgen/join.go
+++ /dev/null
@@ -1,177 +0,0 @@
-package sqlgen
-
-import (
-	"fmt"
-	"strings"
-)
-
-type innerJoinT struct {
-	Type  string
-	Table string
-	On    string
-	Using string
-}
-
-// Joins represents the union of different join conditions.
-type Joins struct {
-	Conditions []Fragment
-	hash       string
-}
-
-// Hash returns a unique identifier.
-func (j *Joins) Hash() string {
-	if j.hash == "" {
-		hash := make([]string, len(j.Conditions))
-		for i := range j.Conditions {
-			hash[i] = j.Conditions[i].Hash()
-		}
-		j.hash = fmt.Sprintf(`Join{%s}`, strings.Join(hash, `, `))
-	}
-	return j.hash
-}
-
-// Compile transforms the Where into an equivalent SQL representation.
-func (j *Joins) Compile(layout *Template) (compiled string) {
-	if c, ok := layout.Read(j); ok {
-		return c
-	}
-
-	l := len(j.Conditions)
-
-	chunks := make([]string, 0, l)
-
-	if l > 0 {
-		for i := 0; i < l; i++ {
-			chunks = append(chunks, j.Conditions[i].Compile(layout))
-		}
-	}
-
-	compiled = strings.Join(chunks, " ")
-
-	layout.Write(j, compiled)
-
-	return
-}
-
-// JoinConditions creates a Joins object.
-func JoinConditions(joins ...*Join) *Joins {
-	fragments := make([]Fragment, len(joins))
-	for i := range fragments {
-		fragments[i] = joins[i]
-	}
-	return &Joins{Conditions: fragments}
-}
-
-// Join represents a generic JOIN statement.
-type Join struct {
-	Type string
-	*Table
-	*On
-	*Using
-	hash string
-}
-
-// Hash returns a unique string given a JOIN.
-func (j *Join) Hash() string {
-	if j.hash == "" {
-		if j.Table != nil && j.Table.Hash() != "" {
-			j.hash = fmt.Sprintf(`Join{%s}`, strings.Join([]string{
-				j.Type,
-				j.Table.Hash(),
-				getHash(j.On),
-				getHash(j.Using),
-			}, ", "))
-		}
-	}
-	return j.hash
-}
-
-// Compile transforms the Join into its equivalent SQL representation.
-func (j *Join) Compile(layout *Template) (compiled string) {
-
-	if c, ok := layout.Read(j); ok {
-		return c
-	}
-
-	if j.Table != nil {
-		data := innerJoinT{
-			Type:  j.Type,
-			Table: j.Table.Compile(layout),
-			On:    layout.doCompile(j.On),
-			Using: layout.doCompile(j.Using),
-		}
-		compiled = mustParse(layout.JoinLayout, data)
-	}
-
-	layout.Write(j, compiled)
-
-	return
-}
-
-// On represents JOIN conditions.
-type On Where
-
-// Hash returns a unique identifier.
-func (o *On) Hash() string {
-	if o.hash == "" {
-		w := Where(*o)
-		o.hash = fmt.Sprintf(`On{%s}`, w.Hash())
-	}
-	return o.hash
-}
-
-// Compile transforms the On into an equivalent SQL representation.
-func (o *On) Compile(layout *Template) (compiled string) {
-	if c, ok := layout.Read(o); ok {
-		return c
-	}
-
-	grouped := groupCondition(layout, o.Conditions, mustParse(layout.ClauseOperator, layout.AndKeyword))
-
-	if grouped != "" {
-		compiled = mustParse(layout.OnLayout, conds{grouped})
-	}
-
-	layout.Write(o, compiled)
-
-	return
-}
-
-// Using represents a USING function.
-type Using Columns
-
-type usingT struct {
-	Columns string
-}
-
-// Hash returns a unique identifier.
-func (u *Using) Hash() string {
-	if u.hash == "" {
-		c := Columns(*u)
-		u.hash = fmt.Sprintf(`Using{%s}`, c.Hash())
-	}
-	return u.hash
-}
-
-// Compile transforms the Using into an equivalent SQL representation.
-func (u *Using) Compile(layout *Template) (compiled string) {
-	if u == nil {
-		return ""
-	}
-
-	if c, ok := layout.Read(u); ok {
-		return c
-	}
-
-	if len(u.Columns) > 0 {
-		c := Columns(*u)
-		data := usingT{
-			Columns: c.Compile(layout),
-		}
-		compiled = mustParse(layout.UsingLayout, data)
-	}
-
-	layout.Write(u, compiled)
-
-	return
-}
diff --git a/util/sqlgen/join_test.go b/util/sqlgen/join_test.go
deleted file mode 100644
index 9fd06cf1..00000000
--- a/util/sqlgen/join_test.go
+++ /dev/null
@@ -1,250 +0,0 @@
-package sqlgen
-
-import (
-	"testing"
-)
-
-func TestOnAndRawOrAnd(t *testing.T) {
-	var s, e string
-
-	on := OnConditions(
-		JoinWithAnd(
-			&ColumnValue{Column: &Column{Name: "id"}, Operator: ">", Value: NewValue(&Raw{Value: "8"})},
-			&ColumnValue{Column: &Column{Name: "id"}, Operator: "<", Value: NewValue(&Raw{Value: "99"})},
-		),
-		&ColumnValue{Column: &Column{Name: "name"}, Operator: "=", Value: NewValue("John")},
-		&Raw{Value: "city_id = 728"},
-		JoinWithOr(
-			&ColumnValue{Column: &Column{Name: "last_name"}, Operator: "=", Value: NewValue("Smith")},
-			&ColumnValue{Column: &Column{Name: "last_name"}, Operator: "=", Value: NewValue("Reyes")},
-		),
-		JoinWithAnd(
-			&ColumnValue{Column: &Column{Name: "age"}, Operator: ">", Value: NewValue(&Raw{Value: "18"})},
-			&ColumnValue{Column: &Column{Name: "age"}, Operator: "<", Value: NewValue(&Raw{Value: "41"})},
-		),
-	)
-
-	s = trim(on.Compile(defaultTemplate))
-	e = `ON (("id" > 8 AND "id" < 99) AND "name" = 'John' AND city_id = 728 AND ("last_name" = 'Smith' OR "last_name" = 'Reyes') AND ("age" > 18 AND "age" < 41))`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestUsing(t *testing.T) {
-	var s, e string
-
-	using := UsingColumns(
-		&Column{Name: "country"},
-		&Column{Name: "state"},
-	)
-
-	s = trim(using.Compile(defaultTemplate))
-	e = `USING ("country", "state")`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestJoinOn(t *testing.T) {
-	var s, e string
-
-	join := JoinConditions(
-		&Join{
-			Table: TableWithName("countries c"),
-			On: OnConditions(
-				&ColumnValue{
-					Column:   &Column{Name: "p.country_id"},
-					Operator: "=",
-					Value:    NewValue(&Column{Name: "a.id"}),
-				},
-				&ColumnValue{
-					Column:   &Column{Name: "p.country_code"},
-					Operator: "=",
-					Value:    NewValue(&Column{Name: "a.code"}),
-				},
-			),
-		},
-	)
-
-	s = trim(join.Compile(defaultTemplate))
-	e = `JOIN "countries" AS "c" ON ("p"."country_id" = "a"."id" AND "p"."country_code" = "a"."code")`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestInnerJoinOn(t *testing.T) {
-	var s, e string
-
-	join := JoinConditions(&Join{
-		Type:  "INNER",
-		Table: TableWithName("countries c"),
-		On: OnConditions(
-			&ColumnValue{
-				Column:   &Column{Name: "p.country_id"},
-				Operator: "=",
-				Value:    NewValue(ColumnWithName("a.id")),
-			},
-			&ColumnValue{
-				Column:   &Column{Name: "p.country_code"},
-				Operator: "=",
-				Value:    NewValue(ColumnWithName("a.code")),
-			},
-		),
-	})
-
-	s = trim(join.Compile(defaultTemplate))
-	e = `INNER JOIN "countries" AS "c" ON ("p"."country_id" = "a"."id" AND "p"."country_code" = "a"."code")`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestLeftJoinUsing(t *testing.T) {
-	var s, e string
-
-	join := JoinConditions(&Join{
-		Type:  "LEFT",
-		Table: TableWithName("countries"),
-		Using: UsingColumns(ColumnWithName("name")),
-	})
-
-	s = trim(join.Compile(defaultTemplate))
-	e = `LEFT JOIN "countries" USING ("name")`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestNaturalJoinOn(t *testing.T) {
-	var s, e string
-
-	join := JoinConditions(&Join{
-		Table: TableWithName("countries"),
-	})
-
-	s = trim(join.Compile(defaultTemplate))
-	e = `NATURAL JOIN "countries"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestNaturalInnerJoinOn(t *testing.T) {
-	var s, e string
-
-	join := JoinConditions(&Join{
-		Type:  "INNER",
-		Table: TableWithName("countries"),
-	})
-
-	s = trim(join.Compile(defaultTemplate))
-	e = `NATURAL INNER JOIN "countries"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestCrossJoin(t *testing.T) {
-	var s, e string
-
-	join := JoinConditions(&Join{
-		Type:  "CROSS",
-		Table: TableWithName("countries"),
-	})
-
-	s = trim(join.Compile(defaultTemplate))
-	e = `CROSS JOIN "countries"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestMultipleJoins(t *testing.T) {
-	var s, e string
-
-	join := JoinConditions(&Join{
-		Type:  "LEFT",
-		Table: TableWithName("countries"),
-	}, &Join{
-		Table: TableWithName("cities"),
-	})
-
-	s = trim(join.Compile(defaultTemplate))
-	e = `NATURAL LEFT JOIN "countries" NATURAL JOIN "cities"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func BenchmarkJoin(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = JoinConditions(&Join{
-			Table: TableWithName("countries c"),
-			On: OnConditions(
-				&ColumnValue{
-					Column:   &Column{Name: "p.country_id"},
-					Operator: "=",
-					Value:    NewValue(&Column{Name: "a.id"}),
-				},
-				&ColumnValue{
-					Column:   &Column{Name: "p.country_code"},
-					Operator: "=",
-					Value:    NewValue(&Column{Name: "a.code"}),
-				},
-			),
-		})
-	}
-}
-
-func BenchmarkCompileJoin(b *testing.B) {
-	j := JoinConditions(&Join{
-		Table: TableWithName("countries c"),
-		On: OnConditions(
-			&ColumnValue{
-				Column:   &Column{Name: "p.country_id"},
-				Operator: "=",
-				Value:    NewValue(&Column{Name: "a.id"}),
-			},
-			&ColumnValue{
-				Column:   &Column{Name: "p.country_code"},
-				Operator: "=",
-				Value:    NewValue(&Column{Name: "a.code"}),
-			},
-		),
-	})
-	for i := 0; i < b.N; i++ {
-		j.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkCompileJoinNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		j := JoinConditions(&Join{
-			Table: TableWithName("countries c"),
-			On: OnConditions(
-				&ColumnValue{
-					Column:   &Column{Name: "p.country_id"},
-					Operator: "=",
-					Value:    NewValue(&Column{Name: "a.id"}),
-				},
-				&ColumnValue{
-					Column:   &Column{Name: "p.country_code"},
-					Operator: "=",
-					Value:    NewValue(&Column{Name: "a.code"}),
-				},
-			),
-		})
-		j.Compile(defaultTemplate)
-	}
-}
diff --git a/util/sqlgen/order_by.go b/util/sqlgen/order_by.go
deleted file mode 100644
index d437cde3..00000000
--- a/util/sqlgen/order_by.go
+++ /dev/null
@@ -1,164 +0,0 @@
-package sqlgen
-
-import (
-	"fmt"
-	"strings"
-)
-
-// Order represents the order in which SQL results are sorted.
-type Order uint8
-
-// Possible values for Order
-const (
-	DefaultOrder = Order(iota)
-	Ascendent
-	Descendent
-)
-
-// SortColumn represents the column-order relation in an ORDER BY clause.
-type SortColumn struct {
-	Column Fragment
-	Order
-	hash string
-}
-
-type sortColumnT struct {
-	Column string
-	Order  string
-}
-
-// SortColumns represents the columns in an ORDER BY clause.
-type SortColumns struct {
-	Columns []Fragment
-	hash    string
-}
-
-// OrderBy represents an ORDER BY clause.
-type OrderBy struct {
-	SortColumns Fragment
-	hash        string
-}
-
-type orderByT struct {
-	SortColumns string
-}
-
-// JoinSortColumns creates and returns an array of column-order relations.
-func JoinSortColumns(values ...Fragment) *SortColumns {
-	return &SortColumns{Columns: values}
-}
-
-// JoinWithOrderBy creates an returns an OrderBy using the given SortColumns.
-func JoinWithOrderBy(sc *SortColumns) *OrderBy {
-	return &OrderBy{SortColumns: sc}
-}
-
-// Hash returns a unique identifier.
-func (s *SortColumn) Hash() string {
-	if s.hash == "" {
-		s.hash = fmt.Sprintf(`SortColumn{Column:%s, Order:%s}`, s.Column.Hash(), s.Order.Hash())
-	}
-	return s.hash
-}
-
-// Compile transforms the SortColumn into an equivalent SQL representation.
-func (s *SortColumn) Compile(layout *Template) (compiled string) {
-
-	if c, ok := layout.Read(s); ok {
-		return c
-	}
-
-	data := sortColumnT{
-		Column: s.Column.Compile(layout),
-		Order:  s.Order.Compile(layout),
-	}
-
-	compiled = mustParse(layout.SortByColumnLayout, data)
-
-	layout.Write(s, compiled)
-
-	return
-}
-
-// Hash returns a unique identifier.
-func (s *SortColumns) Hash() string {
-	if s.hash == "" {
-		h := make([]string, len(s.Columns))
-		for i := range s.Columns {
-			h[i] = s.Columns[i].Hash()
-		}
-		s.hash = fmt.Sprintf(`SortColumns(%s)`, strings.Join(h, `, `))
-	}
-	return s.hash
-}
-
-// Compile transforms the SortColumns into an equivalent SQL representation.
-func (s *SortColumns) Compile(layout *Template) (compiled string) {
-
-	if z, ok := layout.Read(s); ok {
-		return z
-	}
-
-	z := make([]string, len(s.Columns))
-
-	for i := range s.Columns {
-		z[i] = s.Columns[i].Compile(layout)
-	}
-
-	compiled = strings.Join(z, layout.IdentifierSeparator)
-
-	layout.Write(s, compiled)
-
-	return
-}
-
-// Hash returns a unique identifier.
-func (s *OrderBy) Hash() string {
-	if s.hash == "" {
-		if s.SortColumns != nil {
-			s.hash = `OrderBy(` + s.SortColumns.Hash() + `)`
-		}
-	}
-	return s.hash
-}
-
-// Compile transforms the SortColumn into an equivalent SQL representation.
-func (s *OrderBy) Compile(layout *Template) (compiled string) {
-
-	if z, ok := layout.Read(s); ok {
-		return z
-	}
-
-	if s.SortColumns != nil {
-		data := orderByT{
-			SortColumns: s.SortColumns.Compile(layout),
-		}
-		compiled = mustParse(layout.OrderByLayout, data)
-	}
-
-	layout.Write(s, compiled)
-
-	return
-}
-
-// Hash returns a unique identifier.
-func (s Order) Hash() string {
-	switch s {
-	case Ascendent:
-		return `Order{ASC}`
-	case Descendent:
-		return `Order{DESC}`
-	}
-	return `Order{DEFAULT}`
-}
-
-// Compile transforms the SortColumn into an equivalent SQL representation.
-func (s Order) Compile(layout *Template) string {
-	switch s {
-	case Ascendent:
-		return layout.AscKeyword
-	case Descendent:
-		return layout.DescKeyword
-	}
-	return ""
-}
diff --git a/util/sqlgen/order_by_test.go b/util/sqlgen/order_by_test.go
deleted file mode 100644
index bbb7ac84..00000000
--- a/util/sqlgen/order_by_test.go
+++ /dev/null
@@ -1,143 +0,0 @@
-package sqlgen
-
-import (
-	"testing"
-)
-
-func TestOrderBy(t *testing.T) {
-	o := JoinWithOrderBy(
-		JoinSortColumns(
-			&SortColumn{Column: &Column{Name: "foo"}},
-		),
-	)
-
-	s := o.Compile(defaultTemplate)
-	e := `ORDER BY "foo"`
-
-	if trim(s) != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestOrderByDesc(t *testing.T) {
-	o := JoinWithOrderBy(
-		JoinSortColumns(
-			&SortColumn{Column: &Column{Name: "foo"}, Order: Descendent},
-		),
-	)
-
-	s := o.Compile(defaultTemplate)
-	e := `ORDER BY "foo" DESC`
-
-	if trim(s) != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func BenchmarkOrderBy(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		JoinWithOrderBy(
-			JoinSortColumns(
-				&SortColumn{Column: &Column{Name: "foo"}},
-			),
-		)
-	}
-}
-
-func BenchmarkOrderByHash(b *testing.B) {
-	o := OrderBy{
-		SortColumns: JoinSortColumns(
-			&SortColumn{Column: &Column{Name: "foo"}},
-		),
-	}
-	for i := 0; i < b.N; i++ {
-		o.Hash()
-	}
-}
-
-func BenchmarkCompileOrderByCompile(b *testing.B) {
-	o := OrderBy{
-		SortColumns: JoinSortColumns(
-			&SortColumn{Column: &Column{Name: "foo"}},
-		),
-	}
-	for i := 0; i < b.N; i++ {
-		o.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkCompileOrderByCompileNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		o := JoinWithOrderBy(
-			JoinSortColumns(
-				&SortColumn{Column: &Column{Name: "foo"}},
-			),
-		)
-		o.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkCompileOrderCompile(b *testing.B) {
-	o := Descendent
-	for i := 0; i < b.N; i++ {
-		o.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkCompileOrderCompileNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		o := Descendent
-		o.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkSortColumnHash(b *testing.B) {
-	s := &SortColumn{Column: &Column{Name: "foo"}}
-	for i := 0; i < b.N; i++ {
-		s.Hash()
-	}
-}
-
-func BenchmarkSortColumnCompile(b *testing.B) {
-	s := &SortColumn{Column: &Column{Name: "foo"}}
-	for i := 0; i < b.N; i++ {
-		s.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkSortColumnCompileNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		s := &SortColumn{Column: &Column{Name: "foo"}}
-		s.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkSortColumnsHash(b *testing.B) {
-	s := JoinSortColumns(
-		&SortColumn{Column: &Column{Name: "foo"}},
-		&SortColumn{Column: &Column{Name: "bar"}},
-	)
-	for i := 0; i < b.N; i++ {
-		s.Hash()
-	}
-}
-
-func BenchmarkSortColumnsCompile(b *testing.B) {
-	s := JoinSortColumns(
-		&SortColumn{Column: &Column{Name: "foo"}},
-		&SortColumn{Column: &Column{Name: "bar"}},
-	)
-	for i := 0; i < b.N; i++ {
-		s.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkSortColumnsCompileNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		s := JoinSortColumns(
-			&SortColumn{Column: &Column{Name: "foo"}},
-			&SortColumn{Column: &Column{Name: "bar"}},
-		)
-		s.Compile(defaultTemplate)
-	}
-}
diff --git a/util/sqlgen/raw.go b/util/sqlgen/raw.go
deleted file mode 100644
index ca16c26c..00000000
--- a/util/sqlgen/raw.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package sqlgen
-
-import (
-	"fmt"
-)
-
-var (
-	_ = fmt.Stringer(&Raw{})
-)
-
-// Raw represents a value that is meant to be used in a query without escaping.
-type Raw struct {
-	Value string // Value should not be modified after assigned.
-	hash  string
-}
-
-// RawValue creates and returns a new raw value.
-func RawValue(v string) *Raw {
-	return &Raw{Value: v}
-}
-
-// Hash returns a unique identifier.
-func (r *Raw) Hash() string {
-	if r.hash == "" {
-		r.hash = `Raw{Value:"` + r.Value + `"}`
-	}
-	return r.hash
-}
-
-// Compile returns the raw value.
-func (r *Raw) Compile(*Template) string {
-	return r.Value
-}
-
-// String returns the raw value.
-func (r *Raw) String() string {
-	return r.Value
-}
diff --git a/util/sqlgen/raw_test.go b/util/sqlgen/raw_test.go
deleted file mode 100644
index 9ad57ad6..00000000
--- a/util/sqlgen/raw_test.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package sqlgen
-
-import (
-	"fmt"
-	"testing"
-)
-
-func TestRawString(t *testing.T) {
-	var s, e string
-
-	raw := &Raw{Value: "foo"}
-
-	s = raw.Compile(defaultTemplate)
-	e = `foo`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestRawCompile(t *testing.T) {
-	var s, e string
-
-	raw := &Raw{Value: "foo"}
-
-	s = raw.Compile(defaultTemplate)
-	e = `foo`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestRawHash(t *testing.T) {
-	var s, e string
-
-	raw := &Raw{Value: "foo"}
-
-	s = raw.Hash()
-	e = fmt.Sprintf(`Raw{Value:"%s"}`, raw)
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func BenchmarkRawCreate(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = Raw{Value: "foo"}
-	}
-}
-
-func BenchmarkRawString(b *testing.B) {
-	raw := &Raw{Value: "foo"}
-	for i := 0; i < b.N; i++ {
-		raw.String()
-	}
-}
-
-func BenchmarkRawCompile(b *testing.B) {
-	raw := &Raw{Value: "foo"}
-	for i := 0; i < b.N; i++ {
-		raw.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkRawHash(b *testing.B) {
-	raw := &Raw{Value: "foo"}
-	for i := 0; i < b.N; i++ {
-		raw.Hash()
-	}
-}
diff --git a/util/sqlgen/statement.go b/util/sqlgen/statement.go
deleted file mode 100644
index 67de2340..00000000
--- a/util/sqlgen/statement.go
+++ /dev/null
@@ -1,130 +0,0 @@
-package sqlgen
-
-import (
-	"reflect"
-	"strconv"
-	"strings"
-
-	"upper.io/cache"
-)
-
-// Statement represents different kinds of SQL statements.
-type Statement struct {
-	Type
-	Table        Fragment
-	Database     Fragment
-	Columns      Fragment
-	Values       Fragment
-	ColumnValues Fragment
-	OrderBy      Fragment
-	GroupBy      Fragment
-	Joins        Fragment
-	Where        Fragment
-	Extra
-
-	Limit
-	Offset
-
-	hash string
-}
-
-type statementT struct {
-	Table        string
-	Database     string
-	Columns      string
-	Values       string
-	ColumnValues string
-	OrderBy      string
-	GroupBy      string
-	Extra        string
-	Where        string
-	Joins        string
-	Limit
-	Offset
-}
-
-func (layout *Template) doCompile(c Fragment) string {
-	if c != nil && !reflect.ValueOf(c).IsNil() {
-		return c.Compile(layout)
-	}
-	return ""
-}
-
-func getHash(h cache.Hashable) string {
-	if h != nil && !reflect.ValueOf(h).IsNil() {
-		return h.Hash()
-	}
-	return ""
-}
-
-// Hash returns a unique identifier.
-func (s *Statement) Hash() string {
-	if s.hash == "" {
-		parts := strings.Join([]string{
-			strconv.Itoa(int(s.Type)),
-			getHash(s.Table),
-			getHash(s.Database),
-			strconv.Itoa(int(s.Limit)),
-			strconv.Itoa(int(s.Offset)),
-			getHash(s.Columns),
-			getHash(s.Values),
-			getHash(s.ColumnValues),
-			getHash(s.OrderBy),
-			getHash(s.GroupBy),
-			string(s.Extra),
-			getHash(s.Where),
-			getHash(s.Joins),
-		}, ";")
-
-		s.hash = `Statement{` + parts + `}`
-	}
-	return s.hash
-}
-
-// Compile transforms the Statement into an equivalent SQL query.
-func (s *Statement) Compile(layout *Template) (compiled string) {
-
-	if z, ok := layout.Read(s); ok {
-		return z
-	}
-
-	data := statementT{
-		Table:        layout.doCompile(s.Table),
-		Database:     layout.doCompile(s.Database),
-		Limit:        s.Limit,
-		Offset:       s.Offset,
-		Columns:      layout.doCompile(s.Columns),
-		Values:       layout.doCompile(s.Values),
-		ColumnValues: layout.doCompile(s.ColumnValues),
-		OrderBy:      layout.doCompile(s.OrderBy),
-		GroupBy:      layout.doCompile(s.GroupBy),
-		Extra:        string(s.Extra),
-		Where:        layout.doCompile(s.Where),
-		Joins:        layout.doCompile(s.Joins),
-	}
-
-	switch s.Type {
-	case Truncate:
-		compiled = mustParse(layout.TruncateLayout, data)
-	case DropTable:
-		compiled = mustParse(layout.DropTableLayout, data)
-	case DropDatabase:
-		compiled = mustParse(layout.DropDatabaseLayout, data)
-	case Count:
-		compiled = mustParse(layout.CountLayout, data)
-	case Select:
-		compiled = mustParse(layout.SelectLayout, data)
-	case Delete:
-		compiled = mustParse(layout.DeleteLayout, data)
-	case Update:
-		compiled = mustParse(layout.UpdateLayout, data)
-	case Insert:
-		compiled = mustParse(layout.InsertLayout, data)
-	default:
-		panic("Unknown template type.")
-	}
-
-	layout.Write(s, compiled)
-
-	return compiled
-}
diff --git a/util/sqlgen/statement_test.go b/util/sqlgen/statement_test.go
deleted file mode 100644
index 0f3dfb56..00000000
--- a/util/sqlgen/statement_test.go
+++ /dev/null
@@ -1,885 +0,0 @@
-package sqlgen
-
-import (
-	"regexp"
-	"strings"
-	"testing"
-)
-
-var (
-	reInvisible = regexp.MustCompile(`[\t\n\r]`)
-	reSpace     = regexp.MustCompile(`\s+`)
-)
-
-func trim(a string) string {
-	a = reInvisible.ReplaceAllString(strings.TrimSpace(a), " ")
-	a = reSpace.ReplaceAllString(strings.TrimSpace(a), " ")
-	return a
-}
-
-func TestTruncateTable(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:  Truncate,
-		Table: TableWithName("table_name"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `TRUNCATE TABLE "table_name"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestDropTable(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:  DropTable,
-		Table: TableWithName("table_name"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `DROP TABLE "table_name"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestDropDatabase(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:     DropDatabase,
-		Database: &Database{Name: "table_name"},
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `DROP DATABASE "table_name"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestCount(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:  Count,
-		Table: TableWithName("table_name"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT COUNT(1) AS _t FROM "table_name"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestCountRelation(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:  Count,
-		Table: TableWithName("information_schema.tables"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT COUNT(1) AS _t FROM "information_schema"."tables"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestCountWhere(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:  Count,
-		Table: TableWithName("table_name"),
-		Where: WhereConditions(
-			&ColumnValue{Column: &Column{Name: "a"}, Operator: "=", Value: NewValue(RawValue("7"))},
-		),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT COUNT(1) AS _t FROM "table_name" WHERE ("a" = 7)`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestSelectStarFrom(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:  Select,
-		Table: TableWithName("table_name"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT * FROM "table_name"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestSelectStarFromAlias(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:  Select,
-		Table: TableWithName("table.name AS foo"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT * FROM "table"."name" AS "foo"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestSelectStarFromRawWhere(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:  Select,
-		Table: TableWithName("table.name AS foo"),
-		Where: WhereConditions(
-			&Raw{Value: "foo.id = bar.foo_id"},
-		),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT * FROM "table"."name" AS "foo" WHERE (foo.id = bar.foo_id)`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-
-	stmt = Statement{
-		Type:  Select,
-		Table: TableWithName("table.name AS foo"),
-		Where: WhereConditions(
-			&Raw{Value: "foo.id = bar.foo_id"},
-			&Raw{Value: "baz.id = exp.baz_id"},
-		),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT * FROM "table"."name" AS "foo" WHERE (foo.id = bar.foo_id AND baz.id = exp.baz_id)`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestSelectStarFromMany(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:  Select,
-		Table: TableWithName("first.table AS foo, second.table as BAR, third.table aS baz"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT * FROM "first"."table" AS "foo", "second"."table" AS "BAR", "third"."table" AS "baz"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestSelectArtistNameFrom(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:  Select,
-		Table: TableWithName("artist"),
-		Columns: JoinColumns(
-			&Column{Name: "artist.name"},
-		),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "artist"."name" FROM "artist"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestSelectJoin(t *testing.T) {
-	var s, e string
-
-	stmt := Statement{
-		Type:  Select,
-		Table: TableWithName("artist a"),
-		Columns: JoinColumns(
-			&Column{Name: "a.name"},
-		),
-		Joins: JoinConditions(&Join{
-			Table: TableWithName("books b"),
-			On: OnConditions(
-				&ColumnValue{
-					Column:   ColumnWithName("b.author_id"),
-					Operator: `=`,
-					Value:    NewValue(ColumnWithName("a.id")),
-				},
-			),
-		}),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "a"."name" FROM "artist" AS "a" JOIN "books" AS "b" ON ("b"."author_id" = "a"."id")`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestSelectJoinUsing(t *testing.T) {
-	var s, e string
-
-	stmt := Statement{
-		Type:  Select,
-		Table: TableWithName("artist a"),
-		Columns: JoinColumns(
-			&Column{Name: "a.name"},
-		),
-		Joins: JoinConditions(&Join{
-			Table: TableWithName("books b"),
-			Using: UsingColumns(
-				ColumnWithName("artist_id"),
-				ColumnWithName("country"),
-			),
-		}),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "a"."name" FROM "artist" AS "a" JOIN "books" AS "b" USING ("artist_id", "country")`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestSelectUnfinishedJoin(t *testing.T) {
-	var s, e string
-
-	stmt := Statement{
-		Type:  Select,
-		Table: TableWithName("artist a"),
-		Columns: JoinColumns(
-			&Column{Name: "a.name"},
-		),
-		Joins: JoinConditions(&Join{}),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "a"."name" FROM "artist" AS "a"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestSelectNaturalJoin(t *testing.T) {
-	var s, e string
-
-	stmt := Statement{
-		Type:  Select,
-		Table: TableWithName("artist"),
-		Joins: JoinConditions(&Join{
-			Table: TableWithName("books"),
-		}),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT * FROM "artist" NATURAL JOIN "books"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestSelectRawFrom(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:  Select,
-		Table: TableWithName(`artist`),
-		Columns: JoinColumns(
-			&Column{Name: `artist.name`},
-			&Column{Name: Raw{Value: `CONCAT(artist.name, " ", artist.last_name)`}},
-		),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "artist"."name", CONCAT(artist.name, " ", artist.last_name) FROM "artist"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestSelectFieldsFrom(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type: Select,
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		Table: TableWithName("table_name"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "foo", "bar", "baz" FROM "table_name"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestSelectFieldsFromWithLimitOffset(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	// LIMIT only.
-	stmt = Statement{
-		Type: Select,
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		Limit: 42,
-		Table: TableWithName("table_name"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "foo", "bar", "baz" FROM "table_name" LIMIT 42`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-
-	// OFFSET only.
-	stmt = Statement{
-		Type: Select,
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		Offset: 17,
-		Table:  TableWithName("table_name"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "foo", "bar", "baz" FROM "table_name" OFFSET 17`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-
-	// LIMIT AND OFFSET.
-	stmt = Statement{
-		Type: Select,
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		Limit:  42,
-		Offset: 17,
-		Table:  TableWithName("table_name"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "foo", "bar", "baz" FROM "table_name" LIMIT 42 OFFSET 17`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestStatementGroupBy(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	// Simple GROUP BY
-	stmt = Statement{
-		Type: Select,
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		GroupBy: GroupByColumns(
-			&Column{Name: "foo"},
-		),
-		Table: TableWithName("table_name"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "foo", "bar", "baz" FROM "table_name" GROUP BY "foo"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-
-	stmt = Statement{
-		Type: Select,
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		GroupBy: GroupByColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-		),
-		Table: TableWithName("table_name"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "foo", "bar", "baz" FROM "table_name" GROUP BY "foo", "bar"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestSelectFieldsFromWithOrderBy(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	// Simple ORDER BY
-	stmt = Statement{
-		Type: Select,
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		OrderBy: JoinWithOrderBy(
-			JoinSortColumns(
-				&SortColumn{Column: &Column{Name: "foo"}},
-			),
-		),
-		Table: TableWithName("table_name"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "foo", "bar", "baz" FROM "table_name" ORDER BY "foo"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-
-	// ORDER BY field ASC
-	stmt = Statement{
-		Type: Select,
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		OrderBy: JoinWithOrderBy(
-			JoinSortColumns(
-				&SortColumn{Column: &Column{Name: "foo"}, Order: Ascendent},
-			),
-		),
-		Table: TableWithName("table_name"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "foo", "bar", "baz" FROM "table_name" ORDER BY "foo" ASC`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-
-	// ORDER BY field DESC
-	stmt = Statement{
-		Type: Select,
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		OrderBy: JoinWithOrderBy(
-			JoinSortColumns(
-				&SortColumn{Column: &Column{Name: "foo"}, Order: Descendent},
-			),
-		),
-		Table: TableWithName("table_name"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "foo", "bar", "baz" FROM "table_name" ORDER BY "foo" DESC`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-
-	// ORDER BY many fields
-	stmt = Statement{
-		Type: Select,
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		OrderBy: JoinWithOrderBy(
-			JoinSortColumns(
-				&SortColumn{Column: &Column{Name: "foo"}, Order: Descendent},
-				&SortColumn{Column: &Column{Name: "bar"}, Order: Ascendent},
-				&SortColumn{Column: &Column{Name: "baz"}, Order: Descendent},
-			),
-		),
-		Table: TableWithName("table_name"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "foo", "bar", "baz" FROM "table_name" ORDER BY "foo" DESC, "bar" ASC, "baz" DESC`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-
-	// ORDER BY function
-	stmt = Statement{
-		Type: Select,
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		OrderBy: JoinWithOrderBy(
-			JoinSortColumns(
-				&SortColumn{Column: &Column{Name: Raw{Value: "FOO()"}}, Order: Descendent},
-				&SortColumn{Column: &Column{Name: Raw{Value: "BAR()"}}, Order: Ascendent},
-			),
-		),
-		Table: TableWithName("table_name"),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "foo", "bar", "baz" FROM "table_name" ORDER BY FOO() DESC, BAR() ASC`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestSelectFieldsFromWhere(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type: Select,
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		Table: TableWithName("table_name"),
-		Where: WhereConditions(
-			&ColumnValue{Column: &Column{Name: "baz"}, Operator: "=", Value: NewValue(99)},
-		),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "foo", "bar", "baz" FROM "table_name" WHERE ("baz" = '99')`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestSelectFieldsFromWhereLimitOffset(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type: Select,
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		Table: TableWithName("table_name"),
-		Where: WhereConditions(
-			&ColumnValue{Column: &Column{Name: "baz"}, Operator: "=", Value: NewValue(99)},
-		),
-		Limit:  10,
-		Offset: 23,
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `SELECT "foo", "bar", "baz" FROM "table_name" WHERE ("baz" = '99') LIMIT 10 OFFSET 23`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestDelete(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:  Delete,
-		Table: TableWithName("table_name"),
-		Where: WhereConditions(
-			&ColumnValue{Column: &Column{Name: "baz"}, Operator: "=", Value: NewValue(99)},
-		),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `DELETE FROM "table_name" WHERE ("baz" = '99')`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestUpdate(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:  Update,
-		Table: TableWithName("table_name"),
-		ColumnValues: JoinColumnValues(
-			&ColumnValue{Column: &Column{Name: "foo"}, Operator: "=", Value: NewValue(76)},
-		),
-		Where: WhereConditions(
-			&ColumnValue{Column: &Column{Name: "baz"}, Operator: "=", Value: NewValue(99)},
-		),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `UPDATE "table_name" SET "foo" = '76' WHERE ("baz" = '99')`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-
-	stmt = Statement{
-		Type:  Update,
-		Table: TableWithName("table_name"),
-		ColumnValues: JoinColumnValues(
-			&ColumnValue{Column: &Column{Name: "foo"}, Operator: "=", Value: NewValue(76)},
-			&ColumnValue{Column: &Column{Name: "bar"}, Operator: "=", Value: NewValue(Raw{Value: "88"})},
-		),
-		Where: WhereConditions(
-			&ColumnValue{Column: &Column{Name: "baz"}, Operator: "=", Value: NewValue(99)},
-		),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `UPDATE "table_name" SET "foo" = '76', "bar" = 88 WHERE ("baz" = '99')`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestInsert(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:  Insert,
-		Table: TableWithName("table_name"),
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		Values: NewValueGroup(
-			&Value{V: "1"},
-			&Value{V: 2},
-			&Value{V: Raw{Value: "3"}},
-		),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `INSERT INTO "table_name" ("foo", "bar", "baz") VALUES ('1', '2', 3)`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestInsertMultiple(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:  Insert,
-		Table: TableWithName("table_name"),
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		Values: JoinValueGroups(
-			NewValueGroup(
-				NewValue("1"),
-				NewValue("2"),
-				NewValue(RawValue("3")),
-			),
-			NewValueGroup(
-				NewValue(RawValue("4")),
-				NewValue(RawValue("5")),
-				NewValue(RawValue("6")),
-			),
-		),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `INSERT INTO "table_name" ("foo", "bar", "baz") VALUES ('1', '2', 3), (4, 5, 6)`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestInsertExtra(t *testing.T) {
-	var s, e string
-	var stmt Statement
-
-	stmt = Statement{
-		Type:  Insert,
-		Table: TableWithName("table_name"),
-		Extra: "RETURNING id",
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		Values: NewValueGroup(
-			&Value{V: "1"},
-			&Value{V: 2},
-			&Value{V: Raw{Value: "3"}},
-		),
-	}
-
-	s = trim(stmt.Compile(defaultTemplate))
-	e = `INSERT INTO "table_name" ("foo", "bar", "baz") VALUES ('1', '2', 3) RETURNING id`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func BenchmarkStatementSimpleQuery(b *testing.B) {
-	stmt := Statement{
-		Type:  Count,
-		Table: TableWithName("table_name"),
-		Where: WhereConditions(
-			&ColumnValue{Column: &Column{Name: "a"}, Operator: "=", Value: NewValue(Raw{Value: "7"})},
-		),
-	}
-
-	for i := 0; i < b.N; i++ {
-		_ = stmt.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkStatementSimpleQueryHash(b *testing.B) {
-	stmt := Statement{
-		Type:  Count,
-		Table: TableWithName("table_name"),
-		Where: WhereConditions(
-			&ColumnValue{Column: &Column{Name: "a"}, Operator: "=", Value: NewValue(Raw{Value: "7"})},
-		),
-	}
-
-	for i := 0; i < b.N; i++ {
-		_ = stmt.Hash()
-	}
-}
-
-func BenchmarkStatementSimpleQueryNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		stmt := Statement{
-			Type:  Count,
-			Table: TableWithName("table_name"),
-			Where: WhereConditions(
-				&ColumnValue{Column: &Column{Name: "a"}, Operator: "=", Value: NewValue(Raw{Value: "7"})},
-			),
-		}
-		_ = stmt.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkStatementComplexQuery(b *testing.B) {
-	stmt := Statement{
-		Type:  Insert,
-		Table: TableWithName("table_name"),
-		Columns: JoinColumns(
-			&Column{Name: "foo"},
-			&Column{Name: "bar"},
-			&Column{Name: "baz"},
-		),
-		Values: NewValueGroup(
-			&Value{V: "1"},
-			&Value{V: 2},
-			&Value{V: Raw{Value: "3"}},
-		),
-	}
-
-	for i := 0; i < b.N; i++ {
-		_ = stmt.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkStatementComplexQueryNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		stmt := Statement{
-			Type:  Insert,
-			Table: TableWithName("table_name"),
-			Columns: JoinColumns(
-				&Column{Name: "foo"},
-				&Column{Name: "bar"},
-				&Column{Name: "baz"},
-			),
-			Values: NewValueGroup(
-				&Value{V: "1"},
-				&Value{V: 2},
-				&Value{V: Raw{Value: "3"}},
-			),
-		}
-		_ = stmt.Compile(defaultTemplate)
-	}
-}
diff --git a/util/sqlgen/table.go b/util/sqlgen/table.go
deleted file mode 100644
index 43dcda62..00000000
--- a/util/sqlgen/table.go
+++ /dev/null
@@ -1,110 +0,0 @@
-package sqlgen
-
-import (
-	"fmt"
-	"strings"
-)
-
-type tableT struct {
-	Name  string
-	Alias string
-}
-
-// Table struct represents a SQL table.
-type Table struct {
-	Name interface{}
-	hash string
-}
-
-func quotedTableName(layout *Template, input string) string {
-	input = trimString(input)
-
-	// chunks := reAliasSeparator.Split(input, 2)
-	chunks := separateByAS(input)
-
-	if len(chunks) == 1 {
-		// chunks = reSpaceSeparator.Split(input, 2)
-		chunks = separateBySpace(input)
-	}
-
-	name := chunks[0]
-
-	nameChunks := strings.SplitN(name, layout.ColumnSeparator, 2)
-
-	for i := range nameChunks {
-		// nameChunks[i] = strings.TrimSpace(nameChunks[i])
-		nameChunks[i] = trimString(nameChunks[i])
-		nameChunks[i] = mustParse(layout.IdentifierQuote, Raw{Value: nameChunks[i]})
-	}
-
-	name = strings.Join(nameChunks, layout.ColumnSeparator)
-
-	var alias string
-
-	if len(chunks) > 1 {
-		// alias = strings.TrimSpace(chunks[1])
-		alias = trimString(chunks[1])
-		alias = mustParse(layout.IdentifierQuote, Raw{Value: alias})
-	}
-
-	return mustParse(layout.TableAliasLayout, tableT{name, alias})
-}
-
-// TableWithName creates an returns a Table with the given name.
-func TableWithName(name string) *Table {
-	return &Table{Name: name}
-}
-
-// Hash returns a string hash of the table value.
-func (t *Table) Hash() string {
-	if t.hash == "" {
-		var s string
-
-		switch v := t.Name.(type) {
-		case Fragment:
-			s = v.Hash()
-		case fmt.Stringer:
-			s = v.String()
-		case string:
-			s = v
-		default:
-			s = fmt.Sprintf("%v", t.Name)
-		}
-
-		t.hash = fmt.Sprintf(`Table{Name:%q}`, s)
-	}
-
-	return t.hash
-}
-
-// Compile transforms a table struct into a SQL chunk.
-func (t *Table) Compile(layout *Template) (compiled string) {
-
-	if z, ok := layout.Read(t); ok {
-		return z
-	}
-
-	switch value := t.Name.(type) {
-	case string:
-		if t.Name == "" {
-			return
-		}
-
-		// Splitting tables by a comma
-		parts := separateByComma(value)
-
-		l := len(parts)
-
-		for i := 0; i < l; i++ {
-			parts[i] = quotedTableName(layout, parts[i])
-		}
-
-		compiled = strings.Join(parts, layout.IdentifierSeparator)
-	case Raw:
-		compiled = value.String()
-	}
-
-	layout.Write(t, compiled)
-
-	return
-}
diff --git a/util/sqlgen/table_test.go b/util/sqlgen/table_test.go
deleted file mode 100644
index df9528de..00000000
--- a/util/sqlgen/table_test.go
+++ /dev/null
@@ -1,136 +0,0 @@
-package sqlgen
-
-import (
-	"testing"
-)
-
-func TestTableSimple(t *testing.T) {
-	var s, e string
-
-	table := TableWithName("artist")
-
-	s = trim(table.Compile(defaultTemplate))
-	e = `"artist"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestTableCompound(t *testing.T) {
-	var s, e string
-
-	table := TableWithName("artist.foo")
-
-	s = trim(table.Compile(defaultTemplate))
-	e = `"artist"."foo"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestTableCompoundAlias(t *testing.T) {
-	var s, e string
-
-	table := TableWithName("artist.foo AS baz")
-
-	s = trim(table.Compile(defaultTemplate))
-	e = `"artist"."foo" AS "baz"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestTableImplicitAlias(t *testing.T) {
-	var s, e string
-
-	table := TableWithName("artist.foo baz")
-
-	s = trim(table.Compile(defaultTemplate))
-	e = `"artist"."foo" AS "baz"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestTableMultiple(t *testing.T) {
-	var s, e string
-
-	table := TableWithName("artist.foo, artist.bar, artist.baz")
-
-	s = trim(table.Compile(defaultTemplate))
-	e = `"artist"."foo", "artist"."bar", "artist"."baz"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestTableMultipleAlias(t *testing.T) {
-	var s, e string
-
-	table := TableWithName("artist.foo AS foo, artist.bar as bar, artist.baz As baz")
-
-	s = trim(table.Compile(defaultTemplate))
-	e = `"artist"."foo" AS "foo", "artist"."bar" AS "bar", "artist"."baz" AS "baz"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestTableMinimal(t *testing.T) {
-	var s, e string
-
-	table := TableWithName("a")
-
-	s = trim(table.Compile(defaultTemplate))
-	e = `"a"`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestTableEmpty(t *testing.T) {
-	var s, e string
-
-	table := TableWithName("")
-
-	s = trim(table.Compile(defaultTemplate))
-	e = ``
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func BenchmarkTableWithName(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = TableWithName("foo")
-	}
-}
-
-func BenchmarkTableHash(b *testing.B) {
-	t := TableWithName("name")
-	for i := 0; i < b.N; i++ {
-		t.Hash()
-	}
-}
-
-func BenchmarkTableCompile(b *testing.B) {
-	t := TableWithName("name")
-	for i := 0; i < b.N; i++ {
-		t.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkTableCompileNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		t := TableWithName("name")
-		t.Compile(defaultTemplate)
-	}
-}
diff --git a/util/sqlgen/template.go b/util/sqlgen/template.go
deleted file mode 100644
index 5592353f..00000000
--- a/util/sqlgen/template.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package sqlgen
-
-import (
-	"bytes"
-	"text/template"
-
-	"upper.io/cache"
-)
-
-// Type is the type of SQL query the statement represents.
-type Type uint
-
-// Values for Type.
-const (
-	Truncate = Type(iota)
-	DropTable
-	DropDatabase
-	Count
-	Insert
-	Select
-	Update
-	Delete
-)
-
-type (
-	// Limit represents the SQL limit in a query.
-	Limit int
-	// Offset represents the SQL offset in a query.
-	Offset int
-	// Extra represents any custom SQL that is to be appended to the query.
-	Extra string
-)
-
-var (
-	parsedTemplates = make(map[string]*template.Template)
-)
-
-// Template is an SQL template.
-type Template struct {
-	ColumnSeparator     string
-	IdentifierSeparator string
-	IdentifierQuote     string
-	ValueSeparator      string
-	ValueQuote          string
-	AndKeyword          string
-	OrKeyword           string
-	NotKeyword          string
-	DescKeyword         string
-	AscKeyword          string
-	DefaultOperator     string
-	AssignmentOperator  string
-	ClauseGroup         string
-	ClauseOperator      string
-	ColumnValue         string
-	TableAliasLayout    string
-	ColumnAliasLayout   string
-	SortByColumnLayout  string
-	WhereLayout         string
-	OnLayout            string
-	UsingLayout         string
-	JoinLayout          string
-	OrderByLayout       string
-	InsertLayout        string
-	SelectLayout        string
-	UpdateLayout        string
-	DeleteLayout        string
-	TruncateLayout      string
-	DropDatabaseLayout  string
-	DropTableLayout     string
-	CountLayout         string
-	GroupByLayout       string
-	*cache.Cache
-}
-
-func mustParse(text string, data interface{}) string {
-	var b bytes.Buffer
-	var ok bool
-
-	if _, ok = parsedTemplates[text]; !ok {
-		parsedTemplates[text] = template.Must(template.New("").Parse(text))
-	}
-
-	if err := parsedTemplates[text].Execute(&b, data); err != nil {
-		panic("There was an error compiling the following template:\n" + text + "\nError was: " + err.Error())
-	}
-
-	return b.String()
-}
diff --git a/util/sqlgen/utilities.go b/util/sqlgen/utilities.go
deleted file mode 100644
index 305ab209..00000000
--- a/util/sqlgen/utilities.go
+++ /dev/null
@@ -1,157 +0,0 @@
-package sqlgen
-
-import (
-	"strings"
-)
-
-const (
-	stageExpect = iota
-	stageCapture
-	stageClose
-)
-
-// isBlankSymbol returns true if the given byte is either space, tab, carriage
-// return or newline.
-func isBlankSymbol(in byte) bool {
-	return in == ' ' || in == '\t' || in == '\r' || in == '\n'
-}
-
-// trimString returns a slice of s with a leading and trailing blank symbols
-// (as defined by isBlankSymbol) removed.
-func trimString(s string) string {
-
-	// This conversion is rather slow.
-	// return string(trimBytes([]byte(s)))
-
-	start, end := 0, len(s)-1
-
-	if end < start {
-		return ""
-	}
-
-	for isBlankSymbol(s[start]) {
-		start++
-		if start >= end {
-			return ""
-		}
-	}
-
-	for isBlankSymbol(s[end]) {
-		end--
-	}
-
-	return s[start : end+1]
-}
-
-// trimBytes returns a slice of s with a leading and trailing blank symbols (as
-// defined by isBlankSymbol) removed.
-func trimBytes(s []byte) []byte {
-
-	start, end := 0, len(s)-1
-
-	if end < start {
-		return []byte{}
-	}
-
-	for isBlankSymbol(s[start]) {
-		start++
-		if start >= end {
-			return []byte{}
-		}
-	}
-
-	for isBlankSymbol(s[end]) {
-		end--
-	}
-
-	return s[start : end+1]
-}
-
-/*
-// Separates by a comma, ignoring spaces too.
-// This was slower than strings.Split.
-func separateByComma(in string) (out []string) {
-
-	out = []string{}
-
-	start, lim := 0, len(in)-1
-
-	for start < lim {
-		var end int
-
-		for end = start; end <= lim; end++ {
-			// Is a comma?
-			if in[end] == ',' {
-				break
-			}
-		}
-
-		out = append(out, trimString(in[start:end]))
-
-		start = end + 1
-	}
-
-	return
-}
-*/
-
-// Separates by a comma, ignoring spaces too.
-func separateByComma(in string) (out []string) {
-	out = strings.Split(in, ",")
-	for i := range out {
-		out[i] = trimString(out[i])
-	}
-	return
-}
-
-// Separates by spaces, ignoring spaces too.
-func separateBySpace(in string) (out []string) {
-	if len(in) == 0 {
-		return []string{""}
-	}
-
-	pre := strings.Split(in, " ")
-	out = make([]string, 0, len(pre))
-
-	for i := range pre {
-		pre[i] = trimString(pre[i])
-		if pre[i] != "" {
-			out = append(out, pre[i])
-		}
-	}
-
-	return
-}
-
-func separateByAS(in string) (out []string) {
-	out = []string{}
-
-	if len(in) < 6 {
-		// The minimum expression with the AS keyword is "x AS y", 6 chars.
-		return []string{in}
-	}
-
-	start, lim := 0, len(in)-1
-
-	for start <= lim {
-		var end int
-
-		for end = start; end <= lim; end++ {
-			if end > 3 && isBlankSymbol(in[end]) && isBlankSymbol(in[end-3]) {
-				if (in[end-1] == 's' || in[end-1] == 'S') && (in[end-2] == 'a' || in[end-2] == 'A') {
-					break
-				}
-			}
-		}
-
-		if end < lim {
-			out = append(out, trimString(in[start:end-3]))
-		} else {
-			out = append(out, trimString(in[start:end]))
-		}
-
-		start = end + 1
-	}
-
-	return
-}
diff --git a/util/sqlgen/utilities_test.go b/util/sqlgen/utilities_test.go
deleted file mode 100644
index 4d5ec550..00000000
--- a/util/sqlgen/utilities_test.go
+++ /dev/null
@@ -1,284 +0,0 @@
-package sqlgen
-
-import (
-	"bytes"
-	"regexp"
-	"strings"
-	"testing"
-	"unicode"
-)
-
-const (
-	blankSymbol         = ' '
-	stringWithCommas    = "Hello,,World!,Enjoy"
-	stringWithSpaces    = " Hello  World! Enjoy"
-	stringWithASKeyword = "table.Name AS myTableAlias"
-)
-
-var (
-	bytesWithLeadingBlanks  = []byte("               Hello world!             ")
-	stringWithLeadingBlanks = string(bytesWithLeadingBlanks)
-)
-
-func TestUtilIsBlankSymbol(t *testing.T) {
-	if isBlankSymbol(' ') == false {
-		t.Fail()
-	}
-	if isBlankSymbol('\n') == false {
-		t.Fail()
-	}
-	if isBlankSymbol('\t') == false {
-		t.Fail()
-	}
-	if isBlankSymbol('\r') == false {
-		t.Fail()
-	}
-	if isBlankSymbol('x') == true {
-		t.Fail()
-	}
-}
-
-func TestUtilTrimBytes(t *testing.T) {
-	var trimmed []byte
-
-	trimmed = trimBytes([]byte("  \t\nHello World!     \n"))
-	if string(trimmed) != "Hello World!" {
-		t.Fatalf("Got: %s\n", string(trimmed))
-	}
-
-	trimmed = trimBytes([]byte("Nope"))
-	if string(trimmed) != "Nope" {
-		t.Fatalf("Got: %s\n", string(trimmed))
-	}
-
-	trimmed = trimBytes([]byte(""))
-	if string(trimmed) != "" {
-		t.Fatalf("Got: %s\n", string(trimmed))
-	}
-
-	trimmed = trimBytes([]byte(" "))
-	if string(trimmed) != "" {
-		t.Fatalf("Got: %s\n", string(trimmed))
-	}
-
-	trimmed = trimBytes(nil)
-	if string(trimmed) != "" {
-		t.Fatalf("Got: %s\n", string(trimmed))
-	}
-}
-
-func TestUtilSeparateByComma(t *testing.T) {
-	chunks := separateByComma("Hello,,World!,Enjoy")
-
-	if len(chunks) != 4 {
-		t.Fatal()
-	}
-
-	if chunks[0] != "Hello" {
-		t.Fatal()
-	}
-	if chunks[1] != "" {
-		t.Fatal()
-	}
-	if chunks[2] != "World!" {
-		t.Fatal()
-	}
-	if chunks[3] != "Enjoy" {
-		t.Fatal()
-	}
-}
-
-func TestUtilSeparateBySpace(t *testing.T) {
-	chunks := separateBySpace("       Hello        World!        Enjoy")
-
-	if len(chunks) != 3 {
-		t.Fatal()
-	}
-
-	if chunks[0] != "Hello" {
-		t.Fatal()
-	}
-	if chunks[1] != "World!" {
-		t.Fatal()
-	}
-	if chunks[2] != "Enjoy" {
-		t.Fatal()
-	}
-}
-
-func TestUtilSeparateByAS(t *testing.T) {
-	var chunks []string
-
-	var tests = []string{
-		`table.Name AS myTableAlias`,
-		`table.Name     AS         myTableAlias`,
-		"table.Name\tAS\r\nmyTableAlias",
-	}
-
-	for _, test := range tests {
-		chunks = separateByAS(test)
-
-		if len(chunks) != 2 {
-			t.Fatalf(`Expecting 2 results.`)
-		}
-
-		if chunks[0] != "table.Name" {
-			t.Fatal(`Expecting first result to be "table.Name".`)
-		}
-		if chunks[1] != "myTableAlias" {
-			t.Fatal(`Expecting second result to be myTableAlias.`)
-		}
-	}
-
-	// Single character.
-	chunks = separateByAS("a")
-
-	if len(chunks) != 1 {
-		t.Fatalf(`Expecting 1 results.`)
-	}
-
-	if chunks[0] != "a" {
-		t.Fatal(`Expecting first result to be "a".`)
-	}
-
-	// Empty name
-	chunks = separateByAS("")
-
-	if len(chunks) != 1 {
-		t.Fatalf(`Expecting 1 results.`)
-	}
-
-	if chunks[0] != "" {
-		t.Fatal(`Expecting first result to be "".`)
-	}
-
-	// Single name
-	chunks = separateByAS("  A Single Table ")
-
-	if len(chunks) != 1 {
-		t.Fatalf(`Expecting 1 results.`)
-	}
-
-	if chunks[0] != "A Single Table" {
-		t.Fatal(`Expecting first result to be "ASingleTable".`)
-	}
-
-	// Minimal expression.
-	chunks = separateByAS("a AS b")
-
-	if len(chunks) != 2 {
-		t.Fatalf(`Expecting 2 results.`)
-	}
-
-	if chunks[0] != "a" {
-		t.Fatal(`Expecting first result to be "a".`)
-	}
-
-	if chunks[1] != "b" {
-		t.Fatal(`Expecting first result to be "b".`)
-	}
-
-	// Minimal expression with spaces.
-	chunks = separateByAS("   a    AS    b ")
-
-	if len(chunks) != 2 {
-		t.Fatalf(`Expecting 2 results.`)
-	}
-
-	if chunks[0] != "a" {
-		t.Fatal(`Expecting first result to be "a".`)
-	}
-
-	if chunks[1] != "b" {
-		t.Fatal(`Expecting first result to be "b".`)
-	}
-
-	// Minimal expression + 1 with spaces.
-	chunks = separateByAS("   a    AS    bb ")
-
-	if len(chunks) != 2 {
-		t.Fatalf(`Expecting 2 results.`)
-	}
-
-	if chunks[0] != "a" {
-		t.Fatal(`Expecting first result to be "a".`)
-	}
-
-	if chunks[1] != "bb" {
-		t.Fatal(`Expecting first result to be "bb".`)
-	}
-}
-
-func BenchmarkUtilIsBlankSymbol(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = isBlankSymbol(blankSymbol)
-	}
-}
-
-func BenchmarkUtilStdlibIsBlankSymbol(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = unicode.IsSpace(blankSymbol)
-	}
-}
-
-func BenchmarkUtilTrimBytes(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = trimBytes(bytesWithLeadingBlanks)
-	}
-}
-func BenchmarkUtilStdlibBytesTrimSpace(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = bytes.TrimSpace(bytesWithLeadingBlanks)
-	}
-}
-
-func BenchmarkUtilTrimString(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = trimString(stringWithLeadingBlanks)
-	}
-}
-
-func BenchmarkUtilStdlibStringsTrimSpace(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = strings.TrimSpace(stringWithLeadingBlanks)
-	}
-}
-
-func BenchmarkUtilSeparateByComma(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = separateByComma(stringWithCommas)
-	}
-}
-
-func BenchmarkUtilRegExpSeparateByComma(b *testing.B) {
-	sep := regexp.MustCompile(`\s*?,\s*?`)
-	for i := 0; i < b.N; i++ {
-		_ = sep.Split(stringWithCommas, -1)
-	}
-}
-
-func BenchmarkUtilSeparateBySpace(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = separateBySpace(stringWithSpaces)
-	}
-}
-
-func BenchmarkUtilRegExpSeparateBySpace(b *testing.B) {
-	sep := regexp.MustCompile(`\s+`)
-	for i := 0; i < b.N; i++ {
-		_ = sep.Split(stringWithSpaces, -1)
-	}
-}
-
-func BenchmarkUtilSeparateByAS(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = separateByAS(stringWithASKeyword)
-	}
-}
-
-func BenchmarkUtilRegExpSeparateByAS(b *testing.B) {
-	sep := regexp.MustCompile(`(?i:\s+AS\s+)`)
-	for i := 0; i < b.N; i++ {
-		_ = sep.Split(stringWithASKeyword, -1)
-	}
-}
diff --git a/util/sqlgen/value.go b/util/sqlgen/value.go
deleted file mode 100644
index ab5a4606..00000000
--- a/util/sqlgen/value.go
+++ /dev/null
@@ -1,163 +0,0 @@
-package sqlgen
-
-import (
-	//"database/sql/driver"
-	"fmt"
-	//"log"
-	"strings"
-)
-
-// ValueGroups represents an array of value groups.
-type ValueGroups struct {
-	Values []*Values
-	hash   string
-}
-
-// Values represents an array of Value.
-type Values struct {
-	Values []Fragment
-	hash   string
-}
-
-// Value represents an escaped SQL value.
-type Value struct {
-	V    interface{}
-	hash string
-}
-
-// NewValue creates and returns a Value.
-func NewValue(v interface{}) *Value {
-	return &Value{V: v}
-}
-
-// NewValueGroup creates and returns an array of values.
-func NewValueGroup(v ...Fragment) *Values {
-	return &Values{Values: v}
-}
-
-// Hash returns a unique identifier.
-func (v *Value) Hash() string {
-	if v.hash == "" {
-		switch t := v.V.(type) {
-		case Fragment:
-			v.hash = `Value(` + t.Hash() + `)`
-		case string:
-			v.hash = `Value(` + t + `)`
-		default:
-			v.hash = fmt.Sprintf(`Value(%v)`, v.V)
-		}
-	}
-	return v.hash
-}
-
-// Compile transforms the Value into an equivalent SQL representation.
-func (v *Value) Compile(layout *Template) (compiled string) {
-
-	if z, ok := layout.Read(v); ok {
-		return z
-	}
-
-	switch t := v.V.(type) {
-	case Raw:
-		compiled = t.Compile(layout)
-	case Fragment:
-		compiled = t.Compile(layout)
-	default:
-		compiled = mustParse(layout.ValueQuote, RawValue(fmt.Sprintf(`%v`, v.V)))
-	}
-
-	layout.Write(v, compiled)
-
-	return
-}
-
-/*
-func (v *Value) Scan(src interface{}) error {
-	log.Println("Scan(", src, ") on", v.V)
-	return nil
-}
-
-func (v *Value) Value() (driver.Value, error) {
-	log.Println("Value() on", v.V)
-	return v.V, nil
-}
-*/
-
-// Hash returns a unique identifier.
-func (vs *Values) Hash() string {
-	if vs.hash == "" {
-		hash := make([]string, len(vs.Values))
-		for i := range vs.Values {
-			hash[i] = vs.Values[i].Hash()
-		}
-		vs.hash = `Values(` + strings.Join(hash, `,`) + `)`
-	}
-	return vs.hash
-}
-
-// Compile transforms the Values into an equivalent SQL representation.
-func (vs *Values) Compile(layout *Template) (compiled string) {
-	if c, ok := layout.Read(vs); ok {
-		return c
-	}
-
-	l := len(vs.Values)
-	if l > 0 {
-		chunks := make([]string, 0, l)
-		for i := 0; i < l; i++ {
-			chunks = append(chunks, vs.Values[i].Compile(layout))
-		}
-		compiled = mustParse(layout.ClauseGroup, strings.Join(chunks, layout.ValueSeparator))
-	}
-	layout.Write(vs, compiled)
-	return
-}
-
-/*
-func (vs Values) Scan(src interface{}) error {
-	log.Println("Values.Scan(", src, ")")
-	return nil
-}
-
-func (vs Values) Value() (driver.Value, error) {
-	log.Println("Values.Value()")
-	return vs, nil
-}
-*/
-
-// Hash returns a unique identifier.
-func (vg *ValueGroups) Hash() string {
-	if vg.hash == "" {
-		l := len(vg.Values)
-		hashes := make([]string, l)
-		for i := 0; i < l; i++ {
-			hashes[i] = vg.Values[i].Hash()
-		}
-		vg.hash = fmt.Sprintf(`ValueGroups(%v)`, strings.Join(hashes, ", "))
-	}
-	return vg.hash
-}
-
-// Compile transforms the ValueGroups into an equivalent SQL representation.
-func (vg *ValueGroups) Compile(layout *Template) (compiled string) {
-	if c, ok := layout.Read(vg); ok {
-		return c
-	}
-
-	l := len(vg.Values)
-	if l > 0 {
-		chunks := make([]string, 0, l)
-		for i := 0; i < l; i++ {
-			chunks = append(chunks, vg.Values[i].Compile(layout))
-		}
-		compiled = strings.Join(chunks, layout.ValueSeparator)
-	}
-
-	layout.Write(vg, compiled)
-	return
-}
-
-// JoinValueGroups creates a new *ValueGroups object.
-func JoinValueGroups(values ...*Values) *ValueGroups {
-	return &ValueGroups{Values: values}
-}
diff --git a/util/sqlgen/value_test.go b/util/sqlgen/value_test.go
deleted file mode 100644
index 84c3c004..00000000
--- a/util/sqlgen/value_test.go
+++ /dev/null
@@ -1,99 +0,0 @@
-package sqlgen
-
-import (
-	"testing"
-)
-
-func TestValue(t *testing.T) {
-	var s, e string
-	var val *Value
-
-	val = NewValue(1)
-
-	s = val.Compile(defaultTemplate)
-	e = `'1'`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-
-	val = NewValue(&Raw{Value: "NOW()"})
-
-	s = val.Compile(defaultTemplate)
-	e = `NOW()`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestValues(t *testing.T) {
-	var s, e string
-
-	val := NewValueGroup(
-		&Value{V: &Raw{Value: "1"}},
-		&Value{V: &Raw{Value: "2"}},
-		&Value{V: "3"},
-	)
-
-	s = val.Compile(defaultTemplate)
-	e = `(1, 2, '3')`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func BenchmarkValue(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = NewValue("a")
-	}
-}
-
-func BenchmarkValueHash(b *testing.B) {
-	v := NewValue("a")
-	for i := 0; i < b.N; i++ {
-		_ = v.Hash()
-	}
-}
-
-func BenchmarkValueCompile(b *testing.B) {
-	v := NewValue("a")
-	for i := 0; i < b.N; i++ {
-		_ = v.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkValueCompileNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		v := NewValue("a")
-		_ = v.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkValues(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = NewValueGroup(NewValue("a"), NewValue("b"))
-	}
-}
-
-func BenchmarkValuesHash(b *testing.B) {
-	vs := NewValueGroup(NewValue("a"), NewValue("b"))
-	for i := 0; i < b.N; i++ {
-		_ = vs.Hash()
-	}
-}
-
-func BenchmarkValuesCompile(b *testing.B) {
-	vs := NewValueGroup(NewValue("a"), NewValue("b"))
-	for i := 0; i < b.N; i++ {
-		_ = vs.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkValuesCompileNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		vs := NewValueGroup(NewValue("a"), NewValue("b"))
-		_ = vs.Compile(defaultTemplate)
-	}
-}
diff --git a/util/sqlgen/where.go b/util/sqlgen/where.go
deleted file mode 100644
index 64ea9f10..00000000
--- a/util/sqlgen/where.go
+++ /dev/null
@@ -1,123 +0,0 @@
-package sqlgen
-
-import (
-	"fmt"
-	"strings"
-)
-
-// Or represents an SQL OR operator.
-type Or Where
-
-// And represents an SQL AND operator.
-type And Where
-
-// Where represents an SQL WHERE clause.
-type Where struct {
-	Conditions []Fragment
-	hash       string
-}
-
-type conds struct {
-	Conds string
-}
-
-// WhereConditions creates and retuens a new Where.
-func WhereConditions(conditions ...Fragment) *Where {
-	return &Where{Conditions: conditions}
-}
-
-// JoinWithOr creates and returns a new Or.
-func JoinWithOr(conditions ...Fragment) *Or {
-	return &Or{Conditions: conditions}
-}
-
-// JoinWithAnd creates and returns a new And.
-func JoinWithAnd(conditions ...Fragment) *And {
-	return &And{Conditions: conditions}
-}
-
-// Hash returns a unique identifier.
-func (w *Where) Hash() string {
-	if w.hash == "" {
-		hash := make([]string, len(w.Conditions))
-		for i := range w.Conditions {
-			hash[i] = w.Conditions[i].Hash()
-		}
-		w.hash = fmt.Sprintf(`Where{%s}`, strings.Join(hash, `, `))
-	}
-	return w.hash
-}
-
-// Hash returns a unique identifier.
-func (o *Or) Hash() string {
-	w := Where(*o)
-	return `Or(` + w.Hash() + `)`
-}
-
-// Hash returns a unique identifier.
-func (a *And) Hash() string {
-	w := Where(*a)
-	return `Or(` + w.Hash() + `)`
-}
-
-// Compile transforms the Or into an equivalent SQL representation.
-func (o *Or) Compile(layout *Template) (compiled string) {
-
-	if z, ok := layout.Read(o); ok {
-		return z
-	}
-
-	compiled = groupCondition(layout, o.Conditions, mustParse(layout.ClauseOperator, layout.OrKeyword))
-
-	layout.Write(o, compiled)
-
-	return
-}
-
-// Compile transforms the And into an equivalent SQL representation.
-func (a *And) Compile(layout *Template) (compiled string) {
-	if c, ok := layout.Read(a); ok {
-		return c
-	}
-
-	compiled = groupCondition(layout, a.Conditions, mustParse(layout.ClauseOperator, layout.AndKeyword))
-
-	layout.Write(a, compiled)
-
-	return
-}
-
-// Compile transforms the Where into an equivalent SQL representation.
-func (w *Where) Compile(layout *Template) (compiled string) {
-	if c, ok := layout.Read(w); ok {
-		return c
-	}
-
-	grouped := groupCondition(layout, w.Conditions, mustParse(layout.ClauseOperator, layout.AndKeyword))
-
-	if grouped != "" {
-		compiled = mustParse(layout.WhereLayout, conds{grouped})
-	}
-
-	layout.Write(w, compiled)
-
-	return
-}
-
-func groupCondition(layout *Template, terms []Fragment, joinKeyword string) string {
-	l := len(terms)
-
-	chunks := make([]string, 0, l)
-
-	if l > 0 {
-		for i := 0; i < l; i++ {
-			chunks = append(chunks, terms[i].Compile(layout))
-		}
-	}
-
-	if len(chunks) > 0 {
-		return mustParse(layout.ClauseGroup, strings.Join(chunks, joinKeyword))
-	}
-
-	return ""
-}
diff --git a/util/sqlgen/where_test.go b/util/sqlgen/where_test.go
deleted file mode 100644
index c4b2a182..00000000
--- a/util/sqlgen/where_test.go
+++ /dev/null
@@ -1,113 +0,0 @@
-package sqlgen
-
-import (
-	"testing"
-)
-
-func TestWhereAnd(t *testing.T) {
-	var s, e string
-
-	and := JoinWithAnd(
-		&ColumnValue{Column: &Column{Name: "id"}, Operator: ">", Value: NewValue(&Raw{Value: "8"})},
-		&ColumnValue{Column: &Column{Name: "id"}, Operator: "<", Value: NewValue(&Raw{Value: "99"})},
-		&ColumnValue{Column: &Column{Name: "name"}, Operator: "=", Value: NewValue("John")},
-	)
-
-	s = and.Compile(defaultTemplate)
-	e = `("id" > 8 AND "id" < 99 AND "name" = 'John')`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestWhereOr(t *testing.T) {
-	var s, e string
-
-	or := JoinWithOr(
-		&ColumnValue{Column: &Column{Name: "id"}, Operator: "=", Value: NewValue(&Raw{Value: "8"})},
-		&ColumnValue{Column: &Column{Name: "id"}, Operator: "=", Value: NewValue(&Raw{Value: "99"})},
-	)
-
-	s = or.Compile(defaultTemplate)
-	e = `("id" = 8 OR "id" = 99)`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestWhereAndOr(t *testing.T) {
-	var s, e string
-
-	and := JoinWithAnd(
-		&ColumnValue{Column: &Column{Name: "id"}, Operator: ">", Value: NewValue(&Raw{Value: "8"})},
-		&ColumnValue{Column: &Column{Name: "id"}, Operator: "<", Value: NewValue(&Raw{Value: "99"})},
-		&ColumnValue{Column: &Column{Name: "name"}, Operator: "=", Value: NewValue("John")},
-		JoinWithOr(
-			&ColumnValue{Column: &Column{Name: "last_name"}, Operator: "=", Value: NewValue("Smith")},
-			&ColumnValue{Column: &Column{Name: "last_name"}, Operator: "=", Value: NewValue("Reyes")},
-		),
-	)
-
-	s = and.Compile(defaultTemplate)
-	e = `("id" > 8 AND "id" < 99 AND "name" = 'John' AND ("last_name" = 'Smith' OR "last_name" = 'Reyes'))`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func TestWhereAndRawOrAnd(t *testing.T) {
-	var s, e string
-
-	where := WhereConditions(
-		JoinWithAnd(
-			&ColumnValue{Column: &Column{Name: "id"}, Operator: ">", Value: NewValue(&Raw{Value: "8"})},
-			&ColumnValue{Column: &Column{Name: "id"}, Operator: "<", Value: NewValue(&Raw{Value: "99"})},
-		),
-		&ColumnValue{Column: &Column{Name: "name"}, Operator: "=", Value: NewValue("John")},
-		&Raw{Value: "city_id = 728"},
-		JoinWithOr(
-			&ColumnValue{Column: &Column{Name: "last_name"}, Operator: "=", Value: NewValue("Smith")},
-			&ColumnValue{Column: &Column{Name: "last_name"}, Operator: "=", Value: NewValue("Reyes")},
-		),
-		JoinWithAnd(
-			&ColumnValue{Column: &Column{Name: "age"}, Operator: ">", Value: NewValue(&Raw{Value: "18"})},
-			&ColumnValue{Column: &Column{Name: "age"}, Operator: "<", Value: NewValue(&Raw{Value: "41"})},
-		),
-	)
-
-	s = trim(where.Compile(defaultTemplate))
-	e = `WHERE (("id" > 8 AND "id" < 99) AND "name" = 'John' AND city_id = 728 AND ("last_name" = 'Smith' OR "last_name" = 'Reyes') AND ("age" > 18 AND "age" < 41))`
-
-	if s != e {
-		t.Fatalf("Got: %s, Expecting: %s", s, e)
-	}
-}
-
-func BenchmarkWhere(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_ = WhereConditions(
-			&ColumnValue{Column: &Column{Name: "baz"}, Operator: "=", Value: NewValue(99)},
-		)
-	}
-}
-
-func BenchmarkCompileWhere(b *testing.B) {
-	w := WhereConditions(
-		&ColumnValue{Column: &Column{Name: "baz"}, Operator: "=", Value: NewValue(99)},
-	)
-	for i := 0; i < b.N; i++ {
-		w.Compile(defaultTemplate)
-	}
-}
-
-func BenchmarkCompileWhereNoCache(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		w := WhereConditions(
-			&ColumnValue{Column: &Column{Name: "baz"}, Operator: "=", Value: NewValue(99)},
-		)
-		w.Compile(defaultTemplate)
-	}
-}
diff --git a/util/sqlutil/convert.go b/util/sqlutil/convert.go
deleted file mode 100644
index 1033a6eb..00000000
--- a/util/sqlutil/convert.go
+++ /dev/null
@@ -1,291 +0,0 @@
-package sqlutil
-
-import (
-	"fmt"
-	"reflect"
-	"strings"
-
-	"upper.io/db"
-	"upper.io/db/util/sqlgen"
-)
-
-var (
-	sqlPlaceholder     = sqlgen.RawValue(`?`)
-	sqlNull            = sqlgen.RawValue(`NULL`)
-	sqlIsOperator      = `IS`
-	sqlInOperator      = `IN`
-	sqlDefaultOperator = `=`
-)
-
-type TemplateWithUtils struct {
-	*sqlgen.Template
-}
-
-func NewTemplateWithUtils(template *sqlgen.Template) *TemplateWithUtils {
-	return &TemplateWithUtils{template}
-}
-
-// ToWhereWithArguments converts the given db.Cond parameters into a sqlgen.Where
-// value.
-func (tu *TemplateWithUtils) ToWhereWithArguments(term interface{}) (where sqlgen.Where, args []interface{}) {
-	args = []interface{}{}
-
-	switch t := term.(type) {
-	case []interface{}:
-		if len(t) > 0 {
-			if s, ok := t[0].(string); ok {
-				if strings.ContainsAny(s, "?") || len(t) == 1 {
-					where.Conditions = []sqlgen.Fragment{sqlgen.RawValue(s)}
-					args = t[1:]
-				} else {
-					cond := db.Cond{}
-
-					if len(t) > 2 {
-						cond[s] = t[1:]
-					} else {
-						cond[s] = t[1]
-					}
-
-					cv, v := tu.ToColumnValues(cond)
-
-					args = append(args, v...)
-					for i := range cv.ColumnValues {
-						where.Conditions = append(where.Conditions, cv.ColumnValues[i])
-					}
-				}
-				return
-			}
-		}
-		for i := range t {
-			w, v := tu.ToWhereWithArguments(t[i])
-			if len(w.Conditions) == 0 {
-				continue
-			}
-			args = append(args, v...)
-			where.Conditions = append(where.Conditions, w.Conditions...)
-		}
-		return
-	case db.And:
-		var op sqlgen.And
-		for i := range t {
-			w, v := tu.ToWhereWithArguments(t[i])
-			if len(w.Conditions) == 0 {
-				continue
-			}
-			args = append(args, v...)
-			op.Conditions = append(op.Conditions, w.Conditions...)
-		}
-		if len(op.Conditions) > 0 {
-			where.Conditions = append(where.Conditions, &op)
-		}
-		return
-	case db.Or:
-		var op sqlgen.Or
-		for i := range t {
-			w, v := tu.ToWhereWithArguments(t[i])
-			if len(w.Conditions) == 0 {
-				continue
-			}
-			args = append(args, v...)
-			op.Conditions = append(op.Conditions, w.Conditions...)
-		}
-		if len(op.Conditions) > 0 {
-			where.Conditions = append(where.Conditions, &op)
-		}
-		return
-	case db.Raw:
-		if s, ok := t.Value.(string); ok {
-			where.Conditions = append(where.Conditions, sqlgen.RawValue(s))
-		}
-		return
-	case db.Cond:
-		cv, v := tu.ToColumnValues(t)
-		args = append(args, v...)
-		for i := range cv.ColumnValues {
-			where.Conditions = append(where.Conditions, cv.ColumnValues[i])
-		}
-		return
-	case db.Constrainer:
-		cv, v := tu.ToColumnValues(t.Constraint())
-		args = append(args, v...)
-		for i := range cv.ColumnValues {
-			where.Conditions = append(where.Conditions, cv.ColumnValues[i])
-		}
-		return
-	}
-
-	panic(fmt.Sprintf(db.ErrUnknownConditionType.Error(), term))
-}
-
-// ToInterfaceArguments converts the given value into an array of interfaces.
-func (tu *TemplateWithUtils) ToInterfaceArguments(value interface{}) (args []interface{}) {
-	if value == nil {
-		return nil
-	}
-
-	v := reflect.ValueOf(value)
-
-	switch v.Type().Kind() {
-	case reflect.Slice:
-		var i, total int
-
-		total = v.Len()
-		if total > 0 {
-			args = make([]interface{}, total)
-
-			for i = 0; i < total; i++ {
-				args[i] = v.Index(i).Interface()
-			}
-
-			return args
-		}
-		return nil
-	default:
-		args = []interface{}{value}
-	}
-
-	return args
-}
-
-// ToColumnValues converts the given db.Cond into a sqlgen.ColumnValues struct.
-func (tu *TemplateWithUtils) ToColumnValues(term interface{}) (cv sqlgen.ColumnValues, args []interface{}) {
-	args = []interface{}{}
-
-	switch t := term.(type) {
-	case []interface{}:
-		l := len(t)
-		for i := 0; i < l; i++ {
-			column := t[i].(string)
-
-			if !strings.ContainsAny(column, "=") {
-				column = fmt.Sprintf("%s = ?", column)
-			}
-
-			chunks := strings.SplitN(column, "=", 2)
-
-			column = chunks[0]
-			format := strings.TrimSpace(chunks[1])
-
-			columnValue := sqlgen.ColumnValue{
-				Column:   sqlgen.ColumnWithName(column),
-				Operator: "=",
-				Value:    sqlgen.RawValue(format),
-			}
-
-			ps := strings.Count(format, "?")
-			if i+ps < l {
-				for j := 0; j < ps; j++ {
-					args = append(args, t[i+j+1])
-				}
-				i = i + ps
-			} else {
-				panic(fmt.Sprintf("Format string %q has more placeholders than given arguments.", format))
-			}
-
-			cv.ColumnValues = append(cv.ColumnValues, &columnValue)
-		}
-		return cv, args
-		// Return error.
-	case db.Cond:
-		for column, value := range t {
-			columnValue := sqlgen.ColumnValue{}
-
-			// Guessing operator from input, or using a default one.
-			column := strings.TrimSpace(column)
-			chunks := strings.SplitN(column, ` `, 2)
-
-			columnValue.Column = sqlgen.ColumnWithName(chunks[0])
-
-			if len(chunks) > 1 {
-				columnValue.Operator = chunks[1]
-			}
-
-			switch value := value.(type) {
-			case db.Func:
-				v := tu.ToInterfaceArguments(value.Args)
-				columnValue.Operator = value.Name
-
-				if v == nil {
-					// A function with no arguments.
-					columnValue.Value = sqlgen.RawValue(`()`)
-				} else {
-					// A function with one or more arguments.
-					columnValue.Value = sqlgen.RawValue(fmt.Sprintf(`(?%s)`, strings.Repeat(`, ?`, len(v)-1)))
-				}
-
-				args = append(args, v...)
-			default:
-				v := tu.ToInterfaceArguments(value)
-
-				if v == nil {
-					// Nil value given.
-					columnValue.Value = sqlNull
-					if columnValue.Operator == "" {
-						columnValue.Operator = sqlIsOperator
-					}
-				} else {
-					if len(v) > 1 {
-						// Array value given.
-						columnValue.Value = sqlgen.RawValue(fmt.Sprintf(`(?%s)`, strings.Repeat(`, ?`, len(v)-1)))
-						if columnValue.Operator == "" {
-							columnValue.Operator = sqlInOperator
-						}
-					} else {
-						// Single value given.
-						columnValue.Value = sqlPlaceholder
-					}
-					args = append(args, v...)
-				}
-			}
-
-			// Using guessed operator if no operator was given.
-			if columnValue.Operator == "" {
-				if tu.DefaultOperator != "" {
-					columnValue.Operator = tu.DefaultOperator
-				} else {
-					columnValue.Operator = sqlDefaultOperator
-				}
-			}
-
-			cv.ColumnValues = append(cv.ColumnValues, &columnValue)
-		}
-		return cv, args
-	}
-
-	panic("Unknown map type.")
-}
-
-// ToColumnsValuesAndArguments maps the given columnNames and columnValues into
-// sqlgen's Columns and Values, it also extracts and returns query arguments.
-func (tu *TemplateWithUtils) ToColumnsValuesAndArguments(columnNames []string, columnValues []interface{}) (*sqlgen.Columns, *sqlgen.Values, []interface{}, error) {
-	var arguments []interface{}
-
-	columns := new(sqlgen.Columns)
-
-	columns.Columns = make([]sqlgen.Fragment, 0, len(columnNames))
-	for i := range columnNames {
-		columns.Columns = append(columns.Columns, sqlgen.ColumnWithName(columnNames[i]))
-	}
-
-	values := new(sqlgen.Values)
-
-	arguments = make([]interface{}, 0, len(columnValues))
-	values.Values = make([]sqlgen.Fragment, 0, len(columnValues))
-
-	for i := range columnValues {
-		switch v := columnValues[i].(type) {
-		case *sqlgen.Value:
-			// Adding value.
-			values.Values = append(values.Values, v)
-		case sqlgen.Value:
-			// Adding value.
-			values.Values = append(values.Values, &v)
-		default:
-			// Adding both value and placeholder.
-			values.Values = append(values.Values, sqlPlaceholder)
-			arguments = append(arguments, v)
-		}
-	}
-
-	return columns, values, arguments, nil
-}
diff --git a/util/sqlutil/debug.go b/util/sqlutil/debug.go
deleted file mode 100644
index 2357b59a..00000000
--- a/util/sqlutil/debug.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2012-2015 The upper.io/db authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-package sqlutil
-
-import (
-	"fmt"
-	"log"
-	"os"
-	"regexp"
-	"strings"
-
-	"upper.io/db"
-)
-
-var (
-	reInvisibleChars       = regexp.MustCompile(`[\s\r\n\t]+`)
-	reColumnCompareExclude = regexp.MustCompile(`[^a-zA-Z0-9]`)
-)
-
-func init() {
-	if os.Getenv(db.EnvEnableDebug) != "" {
-		db.Debug = true
-	}
-}
-
-// Debug is used for printing SQL queries and arguments.
-type Debug struct {
-	SQL   string
-	Args  []interface{}
-	Err   error
-	Start int64
-	End   int64
-}
-
-// Print prints a debug message to stdlog.
-func (d *Debug) Print() {
-	d.SQL = reInvisibleChars.ReplaceAllString(d.SQL, ` `)
-	d.SQL = strings.TrimSpace(d.SQL)
-
-	s := make([]string, 0, 3)
-
-	if d.SQL != "" {
-		s = append(s, fmt.Sprintf(`Q: %s`, d.SQL))
-	}
-
-	if len(d.Args) > 0 {
-		s = append(s, fmt.Sprintf(`A: %v`, d.Args))
-	}
-
-	if d.Err != nil {
-		s = append(s, fmt.Sprintf(`E: %q`, d.Err))
-	}
-
-	s = append(s, fmt.Sprintf(`T: %0.5fs`, float64(d.End-d.Start)/float64(1e9)))
-
-	log.Printf("\n\t%s\n\n", strings.Join(s, "\n\t"))
-}
-
-func Log(query string, args []interface{}, err error, start int64, end int64) {
-	if db.Debug {
-		d := Debug{query, args, err, start, end}
-		d.Print()
-	}
-}
diff --git a/util/sqlutil/fetch.go b/util/sqlutil/fetch.go
deleted file mode 100644
index 823bf64b..00000000
--- a/util/sqlutil/fetch.go
+++ /dev/null
@@ -1,293 +0,0 @@
-// Copyright (c) 2012-2015 The upper.io/db authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-package sqlutil
-
-import (
-	"encoding/json"
-	"reflect"
-
-	"github.com/jmoiron/sqlx"
-	"github.com/jmoiron/sqlx/reflectx"
-	"upper.io/db"
-)
-
-// FetchRow receives a *sqlx.Rows value and tries to map all the rows into a
-// single struct given by the pointer `dst`.
-func FetchRow(rows *sqlx.Rows, dst interface{}) error {
-	var columns []string
-	var err error
-
-	dstv := reflect.ValueOf(dst)
-
-	if dstv.IsNil() || dstv.Kind() != reflect.Ptr {
-		return db.ErrExpectingPointer
-	}
-
-	itemV := dstv.Elem()
-
-	if columns, err = rows.Columns(); err != nil {
-		return err
-	}
-
-	reset(dst)
-
-	next := rows.Next()
-
-	if next == false {
-		if err = rows.Err(); err != nil {
-			return err
-		}
-		return db.ErrNoMoreRows
-	}
-
-	itemT := itemV.Type()
-	item, err := fetchResult(itemT, rows, columns)
-
-	if err != nil {
-		return err
-	}
-
-	if itemT.Kind() == reflect.Ptr {
-		itemV.Set(item)
-	} else {
-		itemV.Set(reflect.Indirect(item))
-	}
-
-	return nil
-}
-
-// FetchRows receives a *sqlx.Rows value and tries to map all the rows into a
-// slice of structs given by the pointer `dst`.
-func FetchRows(rows *sqlx.Rows, dst interface{}) error {
-	var err error
-
-	defer rows.Close()
-
-	// Destination.
-	dstv := reflect.ValueOf(dst)
-
-	if dstv.IsNil() || dstv.Kind() != reflect.Ptr {
-		return db.ErrExpectingPointer
-	}
-
-	if dstv.Elem().Kind() != reflect.Slice {
-		return db.ErrExpectingSlicePointer
-	}
-
-	if dstv.Kind() != reflect.Ptr || dstv.Elem().Kind() != reflect.Slice || dstv.IsNil() {
-		return db.ErrExpectingSliceMapStruct
-	}
-
-	var columns []string
-	if columns, err = rows.Columns(); err != nil {
-		return err
-	}
-
-	slicev := dstv.Elem()
-	itemT := slicev.Type().Elem()
-
-	reset(dst)
-
-	for rows.Next() {
-		item, err := fetchResult(itemT, rows, columns)
-		if err != nil {
-			return err
-		}
-		if itemT.Kind() == reflect.Ptr {
-			slicev = reflect.Append(slicev, item)
-		} else {
-			slicev = reflect.Append(slicev, reflect.Indirect(item))
-		}
-	}
-
-	dstv.Elem().Set(slicev)
-
-	return nil
-}
-
-func fetchResult(itemT reflect.Type, rows *sqlx.Rows, columns []string) (reflect.Value, error) {
-	var item reflect.Value
-	var err error
-
-	objT := itemT
-
-	switch objT.Kind() {
-	case reflect.Map:
-		item = reflect.MakeMap(objT)
-	case reflect.Struct:
-		item = reflect.New(objT)
-	case reflect.Ptr:
-		objT = itemT.Elem()
-		if objT.Kind() != reflect.Struct {
-			return item, db.ErrExpectingMapOrStruct
-		}
-		item = reflect.New(objT)
-	default:
-		return item, db.ErrExpectingMapOrStruct
-	}
-
-	switch objT.Kind() {
-
-	case reflect.Struct:
-
-		values := make([]interface{}, len(columns))
-		typeMap := rows.Mapper.TypeMap(itemT)
-		fieldMap := typeMap.Names
-		wrappedValues := map[*reflectx.FieldInfo]interface{}{}
-
-		for i, k := range columns {
-			fi, ok := fieldMap[k]
-			if !ok {
-				values[i] = new(interface{})
-				continue
-			}
-
-			// TODO: refactor into a nice pattern
-			if _, ok := fi.Options["stringarray"]; ok {
-				values[i] = &[]byte{}
-				wrappedValues[fi] = values[i]
-			} else if _, ok := fi.Options["int64array"]; ok {
-				values[i] = &[]byte{}
-				wrappedValues[fi] = values[i]
-			} else if _, ok := fi.Options["jsonb"]; ok {
-				values[i] = &[]byte{}
-				wrappedValues[fi] = values[i]
-			} else {
-				f := reflectx.FieldByIndexes(item, fi.Index)
-				values[i] = f.Addr().Interface()
-			}
-
-			if u, ok := values[i].(db.Unmarshaler); ok {
-				values[i] = scanner{u}
-			}
-		}
-
-		// Scanner - for reads
-		// Valuer  - for writes
-
-		// OptionTypes
-		// - before/after scan
-		// - before/after valuer..
-
-		if err = rows.Scan(values...); err != nil {
-			return item, err
-		}
-
-		// TODO: move this stuff out of here.. find a nice pattern
-		for fi, v := range wrappedValues {
-			var opt string
-			if _, ok := fi.Options["stringarray"]; ok {
-				opt = "stringarray"
-			} else if _, ok := fi.Options["int64array"]; ok {
-				opt = "int64array"
-			} else if _, ok := fi.Options["jsonb"]; ok {
-				opt = "jsonb"
-			}
-
-			b := v.(*[]byte)
-
-			f := reflectx.FieldByIndexesReadOnly(item, fi.Index)
-
-			switch opt {
-			case "stringarray":
-				v := StringArray{}
-				err := v.Scan(*b)
-				if err != nil {
-					return item, err
-				}
-				f.Set(reflect.ValueOf(v))
-			case "int64array":
-				v := Int64Array{}
-				err := v.Scan(*b)
-				if err != nil {
-					return item, err
-				}
-				f.Set(reflect.ValueOf(v))
-			case "jsonb":
-				if len(*b) == 0 {
-					continue
-				}
-
-				var vv reflect.Value
-				t := reflect.PtrTo(f.Type())
-
-				switch t.Kind() {
-				case reflect.Map:
-					vv = reflect.MakeMap(t)
-				case reflect.Slice:
-					vv = reflect.MakeSlice(t, 0, 0)
-				default:
-					vv = reflect.New(t)
-				}
-
-				err := json.Unmarshal(*b, vv.Interface())
-				if err != nil {
-					return item, err
-				}
-
-				vv = vv.Elem().Elem()
-
-				if !vv.IsValid() || (vv.Kind() == reflect.Ptr && vv.IsNil()) {
-					continue
-				}
-
-				f.Set(vv)
-			}
-		}
-
-	case reflect.Map:
-
-		columns, err := rows.Columns()
-		if err != nil {
-			return item, err
-		}
-
-		values := make([]interface{}, len(columns))
-		for i := range values {
-			if itemT.Elem().Kind() == reflect.Interface {
-				values[i] = new(interface{})
-			} else {
-				values[i] = reflect.New(itemT.Elem()).Interface()
-			}
-		}
-
-		if err = rows.Scan(values...); err != nil {
-			return item, err
-		}
-
-		for i, column := range columns {
-			item.SetMapIndex(reflect.ValueOf(column), reflect.Indirect(reflect.ValueOf(values[i])))
-		}
-
-	}
-
-	return item, nil
-}
-
-func reset(data interface{}) error {
-	// Resetting element.
-	v := reflect.ValueOf(data).Elem()
-	t := v.Type()
-	z := reflect.Zero(t)
-	v.Set(z)
-	return nil
-}
diff --git a/util/sqlutil/result/result.go b/util/sqlutil/result/result.go
deleted file mode 100644
index 2e50932e..00000000
--- a/util/sqlutil/result/result.go
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright (c) 2012-2015 The upper.io/db authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-package result
-
-import (
-	"upper.io/db"
-)
-
-type Result struct {
-	b       db.QueryBuilder
-	table   string
-	iter    db.Iterator
-	limit   int
-	offset  int
-	fields  []interface{}
-	columns []interface{}
-	orderBy []interface{}
-	groupBy []interface{}
-	conds   []interface{}
-}
-
-// NewResult creates and results a new result set on the given table, this set
-// is limited by the given sqlgen.Where conditions.
-func NewResult(b db.QueryBuilder, table string, conds []interface{}) *Result {
-	return &Result{
-		b:     b,
-		table: table,
-		conds: conds,
-	}
-}
-
-// Sets conditions for reducing the working set.
-func (r *Result) Where(conds ...interface{}) db.Result {
-	r.conds = conds
-	return r
-}
-
-// Determines the maximum limit of results to be returned.
-func (r *Result) Limit(n uint) db.Result {
-	r.limit = int(n)
-	return r
-}
-
-// Determines how many documents will be skipped before starting to grab
-// results.
-func (r *Result) Skip(n uint) db.Result {
-	r.offset = int(n)
-	return r
-}
-
-// Used to group results that have the same value in the same column or
-// columns.
-func (r *Result) Group(fields ...interface{}) db.Result {
-	r.groupBy = fields
-	return r
-}
-
-// Determines sorting of results according to the provided names. Fields may be
-// prefixed by - (minus) which means descending order, ascending order would be
-// used otherwise.
-func (r *Result) Sort(fields ...interface{}) db.Result {
-	r.orderBy = fields
-	return r
-}
-
-// Retrieves only the given fields.
-func (r *Result) Select(fields ...interface{}) db.Result {
-	r.fields = fields
-	return r
-}
-
-// Dumps all results into a pointer to an slice of structs or maps.
-func (r *Result) All(dst interface{}) error {
-	return r.buildSelect().Iterator().All(dst)
-}
-
-// Fetches only one result from the resultset.
-func (r *Result) One(dst interface{}) error {
-	return r.buildSelect().Iterator().One(dst)
-}
-
-// Fetches the next result from the resultset.
-func (r *Result) Next(dst interface{}) (err error) {
-	if r.iter == nil {
-		r.iter = r.buildSelect().Iterator()
-	}
-	if !r.iter.Next(dst) {
-		return r.iter.Err()
-	}
-	return nil
-}
-
-// Removes the matching items from the collection.
-func (r *Result) Remove() error {
-	q := r.b.DeleteFrom(r.table).
-		Where(r.conds...).
-		Limit(r.limit)
-
-	_, err := q.Exec()
-	return err
-}
-
-// Closes the result set.
-func (r *Result) Close() error {
-	if r.iter != nil {
-		return r.iter.Close()
-	}
-	return nil
-}
-
-// Updates matching items from the collection with values of the given map or
-// struct.
-func (r *Result) Update(values interface{}) error {
-	q := r.b.Update(r.table).
-		Set(values).
-		Where(r.conds...).
-		Limit(r.limit)
-
-	_, err := q.Exec()
-	return err
-}
-
-// Counts the elements within the main conditions of the set.
-func (r *Result) Count() (uint64, error) {
-	counter := struct {
-		Count uint64 `db:"_t"`
-	}{}
-
-	q := r.buildSelect()
-	q.Columns(db.Raw{"COUNT(1) AS _t"}).Limit(1)
-
-	if err := q.Iterator().One(&counter); err != nil {
-		return 0, err
-	}
-
-	return counter.Count, nil
-}
-
-func (r *Result) buildSelect() db.QuerySelector {
-	q := r.b.Select(r.fields...)
-
-	q.From(r.table)
-	q.Where(r.conds...)
-	q.Limit(r.limit)
-	q.Offset(r.offset)
-
-	q.GroupBy(r.groupBy...)
-	q.OrderBy(r.orderBy...)
-
-	return q
-}
diff --git a/util/sqlutil/scanner.go b/util/sqlutil/scanner.go
deleted file mode 100644
index 5fed1f43..00000000
--- a/util/sqlutil/scanner.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright (c) 2012-2015 The upper.io/db authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-package sqlutil
-
-import (
-	"database/sql"
-	"database/sql/driver"
-	"encoding/json"
-	"errors"
-	"strconv"
-	"strings"
-
-	"upper.io/db"
-)
-
-type scanner struct {
-	v db.Unmarshaler
-}
-
-func (u scanner) Scan(v interface{}) error {
-	return u.v.UnmarshalDB(v)
-}
-
-var _ sql.Scanner = scanner{}
-
-//------
-
-type JsonbType struct {
-	V interface{}
-}
-
-func (j *JsonbType) Scan(src interface{}) error {
-	b, ok := src.([]byte)
-	if !ok {
-		return errors.New("Scan source was not []bytes")
-	}
-
-	v := JsonbType{}
-	if err := json.Unmarshal(b, &v.V); err != nil {
-		return err
-	}
-	*j = v
-	return nil
-}
-
-func (j JsonbType) Value() (driver.Value, error) {
-	b, err := json.Marshal(j.V)
-	if err != nil {
-		return nil, err
-	}
-	return b, nil
-}
-
-//------
-
-type StringArray []string
-
-func (a *StringArray) Scan(src interface{}) error {
-	if src == nil {
-		*a = StringArray{}
-		return nil
-	}
-	b, ok := src.([]byte)
-	if !ok {
-		return errors.New("Scan source was not []bytes")
-	}
-	if len(b) == 0 {
-		return nil
-	}
-	s := string(b)[1 : len(b)-1]
-	if s == "" {
-		return nil
-	}
-	results := strings.Split(s, ",")
-	*a = StringArray(results)
-	return nil
-}
-
-// Value implements the driver.Valuer interface.
-func (a StringArray) Value() (driver.Value, error) {
-	if a == nil {
-		return nil, nil
-	}
-
-	if n := len(a); n > 0 {
-		// There will be at least two curly brackets, 2*N bytes of quotes,
-		// and N-1 bytes of delimiters.
-		b := make([]byte, 1, 1+3*n)
-		b[0] = '{'
-
-		b = appendArrayQuotedString(b, a[0])
-		for i := 1; i < n; i++ {
-			b = append(b, ',')
-			b = appendArrayQuotedString(b, a[i])
-		}
-
-		return append(b, '}'), nil
-	}
-
-	return []byte{'{', '}'}, nil
-}
-
-func appendArrayQuotedString(b []byte, v string) []byte {
-	b = append(b, '"')
-	for {
-		i := strings.IndexAny(v, `"\`)
-		if i < 0 {
-			b = append(b, v...)
-			break
-		}
-		if i > 0 {
-			b = append(b, v[:i]...)
-		}
-		b = append(b, '\\', v[i])
-		v = v[i+1:]
-	}
-	return append(b, '"')
-}
-
-//------
-
-type Int64Array []int64
-
-func (a *Int64Array) Scan(src interface{}) error {
-	if src == nil {
-		return nil
-	}
-	b, ok := src.([]byte)
-	if !ok {
-		return errors.New("Scan source was not []bytes")
-	}
-	if len(b) == 0 {
-		return nil
-	}
-
-	s := string(b)[1 : len(b)-1]
-	results := make([]int64, 0)
-	if s != "" {
-		parts := strings.Split(s, ",")
-		for _, n := range parts {
-			i, err := strconv.ParseInt(n, 10, 64)
-			if err != nil {
-				return err
-			}
-			results = append(results, i)
-		}
-	}
-	*a = Int64Array(results)
-	return nil
-}
-
-// Value implements the driver.Valuer interface.
-func (a Int64Array) Value() (driver.Value, error) {
-	if a == nil {
-		return nil, nil
-	}
-
-	if n := len(a); n > 0 {
-		// There will be at least two curly brackets, N bytes of values,
-		// and N-1 bytes of delimiters.
-		b := make([]byte, 1, 1+2*n)
-		b[0] = '{'
-
-		b = strconv.AppendInt(b, a[0], 10)
-		for i := 1; i < n; i++ {
-			b = append(b, ',')
-			b = strconv.AppendInt(b, a[i], 10)
-		}
-
-		return append(b, '}'), nil
-	}
-
-	return []byte{'{', '}'}, nil
-}
diff --git a/util/sqlutil/tx/tx.go b/util/sqlutil/tx/tx.go
deleted file mode 100644
index 18ebbf3c..00000000
--- a/util/sqlutil/tx/tx.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2012-2015 The upper.io/db authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-package sqltx
-
-import (
-	"github.com/jmoiron/sqlx"
-)
-
-type Tx struct {
-	*sqlx.Tx
-	done bool
-}
-
-func New(tx *sqlx.Tx) *Tx {
-	return &Tx{Tx: tx}
-}
-
-func (t *Tx) Done() bool {
-	return t.done
-}
-
-func (t *Tx) Commit() (err error) {
-	if err = t.Tx.Commit(); err == nil {
-		t.done = true
-	}
-	return err
-}
-- 
GitLab