diff --git a/ql/_dumps/structs.sql b/ql/_dumps/structs.sql
index 7c340904ec1baf611a9068aed683d14651a8e4fd..997b8165a367ddc20afc4e8849d2988979c5e78e 100644
--- a/ql/_dumps/structs.sql
+++ b/ql/_dumps/structs.sql
@@ -6,6 +6,22 @@ CREATE TABLE artist (
   name string
 );
 
+DROP TABLE IF EXISTS publication;
+
+CREATE TABLE publication (
+  title string,
+  author_id int
+);
+
+DROP TABLE IF EXISTS review;
+
+CREATE TABLE review (
+  publication_id int,
+  name string,
+  comments string,
+  created time
+);
+
 DROP TABLE IF EXISTS data_types;
 
 CREATE TABLE data_types (
diff --git a/ql/collection.go b/ql/collection.go
index 4adcc8a5776a78b71f567b7aa8bb419a60f50e1d..aa8c776804f8079b4dd82065388e057d0e310610 100644
--- a/ql/collection.go
+++ b/ql/collection.go
@@ -1,25 +1,23 @@
-/*
-  Copyright (c) 2014 JosĂŠ Carlos Nieto, https://menteslibres.net/xiam
-
-  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.
-*/
+// Copyright (c) 2012-2014 JosĂŠ Carlos Nieto, https://menteslibres.net/xiam
+//
+// 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 ql
 
@@ -28,232 +26,240 @@ import (
 	"reflect"
 	"strings"
 	"upper.io/db"
+	"upper.io/db/util/sqlgen"
 	"upper.io/db/util/sqlutil"
 )
 
-// Represents a QL table.
+const defaultOperator = `==`
+
 type Table struct {
-	source *Source
 	sqlutil.T
+	source *Source
+	names  []string
 }
 
-func mirrorFn(a interface{}) interface{} {
-	return a
-}
-
-func (self *Table) Find(terms ...interface{}) db.Result {
+func whereValues(term interface{}) (where sqlgen.Where, args []interface{}) {
 
-	queryChunks := sqlutil.NewQueryChunks()
+	args = []interface{}{}
 
-	// No specific fields given.
-	if len(queryChunks.Fields) == 0 {
-		queryChunks.Fields = []string{`*`}
+	switch t := term.(type) {
+	case []interface{}:
+		l := len(t)
+		where = make(sqlgen.Where, 0, l)
+		for _, cond := range t {
+			w, v := whereValues(cond)
+			args = append(args, v...)
+			where = append(where, w...)
+		}
+	case db.And:
+		and := make(sqlgen.And, 0, len(t))
+		for _, cond := range t {
+			k, v := whereValues(cond)
+			args = append(args, v...)
+			and = append(and, k...)
+		}
+		where = append(where, and)
+	case db.Or:
+		or := make(sqlgen.Or, 0, len(t))
+		for _, cond := range t {
+			k, v := whereValues(cond)
+			args = append(args, v...)
+			or = append(or, k...)
+		}
+		where = append(where, or)
+	case db.Raw:
+		if s, ok := t.Value.(string); ok == true {
+			where = append(where, sqlgen.Raw{s})
+		}
+	case db.Cond:
+		k, v := conditionValues(t)
+		args = append(args, v...)
+		for _, kk := range k {
+			where = append(where, kk)
+		}
 	}
 
-	// Compiling conditions
-	queryChunks.Conditions, queryChunks.Arguments = self.compileConditions(terms)
+	return where, args
+}
 
-	if queryChunks.Conditions == "" {
-		queryChunks.Conditions = `1 == 1`
-	}
+func interfaceArgs(value interface{}) (args []interface{}) {
 
-	// Creating a result handler.
-	result := &Result{
-		self,
-		queryChunks,
-		nil,
-		&t{&self.T},
+	if value == nil {
+		return nil
 	}
 
-	return result
-}
+	value_v := reflect.ValueOf(value)
 
-// Transforms conditions into arguments for sql.Exec/sql.Query
-func (self *Table) compileConditions(term interface{}) (string, []interface{}) {
-	sql := []string{}
-	args := []interface{}{}
+	switch value_v.Type().Kind() {
+	case reflect.Slice:
+		var i, total int
 
-	switch t := term.(type) {
-	case []interface{}:
-		for i := range t {
-			rsql, rargs := self.compileConditions(t[i])
-			if rsql != "" {
-				sql = append(sql, rsql)
-				args = append(args, rargs...)
-			}
-		}
-		if len(sql) > 0 {
-			return `(` + strings.Join(sql, ` && `) + `)`, args
-		}
-	case db.Or:
-		for i := range t {
-			rsql, rargs := self.compileConditions(t[i])
-			if rsql != "" {
-				sql = append(sql, rsql)
-				args = append(args, rargs...)
-			}
-		}
-		if len(sql) > 0 {
-			return `(` + strings.Join(sql, ` || `) + `)`, args
-		}
-	case db.And:
-		for i := range t {
-			rsql, rargs := self.compileConditions(t[i])
-			if rsql != "" {
-				sql = append(sql, rsql)
-				args = append(args, rargs...)
+		total = value_v.Len()
+		if total > 0 {
+			args = make([]interface{}, total)
+
+			for i = 0; i < total; i++ {
+				args[i] = value_v.Index(i).Interface()
 			}
+
+			return args
+		} else {
+			return nil
 		}
-		if len(sql) > 0 {
-			return `(` + strings.Join(sql, ` && `) + `)`, args
-		}
-	case db.Cond:
-		return self.compileStatement(t)
+	default:
+		args = []interface{}{value}
 	}
 
-	return "", args
+	return args
 }
 
-func (self *Table) compileStatement(cond db.Cond) (string, []interface{}) {
+func conditionValues(cond db.Cond) (columnValues sqlgen.ColumnValues, args []interface{}) {
 
-	total := len(cond)
+	args = []interface{}{}
 
-	str := make([]string, 0, total)
-	arg := make([]interface{}, 0, total)
+	for column, value := range cond {
+		var columnValue sqlgen.ColumnValue
 
-	// Walking over conditions
-	for field, value := range cond {
-		// Removing leading or trailing spaces.
-		field = strings.TrimSpace(field)
+		// Guessing operator from input, or using a default one.
+		column := strings.TrimSpace(column)
+		chunks := strings.SplitN(column, ` `, 2)
 
-		chunks := strings.SplitN(field, ` `, 2)
-
-		// Default operator.
-		op := `==`
+		columnValue.Column = sqlgen.Column{chunks[0]}
 
 		if len(chunks) > 1 {
-			// User has defined a different operator.
-			op = chunks[1]
+			columnValue.Operator = chunks[1]
+		} else {
+			columnValue.Operator = defaultOperator
 		}
 
 		switch value := value.(type) {
 		case db.Func:
+			// Catches functions.
 			value_i := interfaceArgs(value.Args)
+			columnValue.Operator = value.Name
+
 			if value_i == nil {
-				str = append(str, fmt.Sprintf(`%s %s ()`, chunks[0], value.Name))
+				// A function with no arguments.
+				columnValue.Value = sqlgen.Value{sqlgen.Raw{`()`}}
 			} else {
-				str = append(str, fmt.Sprintf(`%s %s (?%s)`, chunks[0], value.Name, strings.Repeat(`,?`, len(value_i)-1)))
-				arg = append(arg, value_i...)
+				// A function with one or more arguments.
+				columnValue.Value = sqlgen.Value{sqlgen.Raw{fmt.Sprintf(`(?%s)`, strings.Repeat(`, ?`, len(value_i)-1))}}
 			}
+
+			args = append(args, value_i...)
 		default:
+			// Catches everything else.
 			value_i := interfaceArgs(value)
-			if value_i == nil {
-				str = append(str, fmt.Sprintf(`%s %s ()`, chunks[0], op))
+			l := len(value_i)
+			if value_i == nil || l == 0 {
+				// Nil value given.
+				columnValue.Value = sqlgen.Value{sqlgen.Raw{`NULL`}}
 			} else {
-				str = append(str, fmt.Sprintf(`%s %s (?%s)`, chunks[0], op, strings.Repeat(`,?`, len(value_i)-1)))
-				arg = append(arg, value_i...)
+				if l > 1 {
+					// Array value given.
+					columnValue.Value = sqlgen.Value{sqlgen.Raw{fmt.Sprintf(`(?%s)`, strings.Repeat(`, ?`, len(value_i)-1))}}
+				} else {
+					// Single value given.
+					columnValue.Value = sqlPlaceholder
+				}
+				args = append(args, value_i...)
 			}
 		}
+
+		columnValues = append(columnValues, columnValue)
 	}
 
-	switch len(str) {
-	case 1:
-		return str[0], arg
-	case 0:
-		return "", []interface{}{}
+	return columnValues, args
+}
+
+func (self *Table) Find(terms ...interface{}) db.Result {
+	where, arguments := whereValues(terms)
+
+	result := &Result{
+		table:     self,
+		where:     where,
+		arguments: arguments,
+		t:         &t{&self.T},
 	}
 
-	return `(` + strings.Join(str, ` AND `) + `)`, arg
+	return result
+}
+
+func (self *Table) tableN(i int) string {
+	if len(self.names) > i {
+		chunks := strings.SplitN(self.names[i], " ", 2)
+		if len(chunks) > 0 {
+			return chunks[0]
+		}
+	}
+	return ""
 }
 
 // Deletes all the rows within the collection.
-func (self *Table) Truncate() (err error) {
+func (self *Table) Truncate() error {
 
-	_, err = self.source.doExec(
-		fmt.Sprintf(`TRUNCATE TABLE %s`, self.Name()),
-	)
+	_, err := self.source.doExec(sqlgen.Statement{
+		Type:  sqlgen.SqlTruncate,
+		Table: sqlgen.Table{self.tableN(0)},
+	})
 
-	return err
+	if err != nil {
+		return err
+	}
+
+	return nil
 }
 
 // Appends an item (map or struct) into the collection.
 func (self *Table) Append(item interface{}) (interface{}, error) {
 
-	fields, values, err := self.FieldValues(item, mirrorFn)
+	cols, vals, err := self.FieldValues(item, toInternal)
 
-	// Error ocurred, stop appending.
-	if err != nil {
-		return nil, err
+	var columns sqlgen.Columns
+	var values sqlgen.Values
+
+	for _, col := range cols {
+		columns = append(columns, sqlgen.Column{col})
 	}
 
-	res, err := self.source.doExec(
-		fmt.Sprintf(`INSERT INTO %s`, self.Name()),
-		sqlFields(fields),
-		`VALUES`,
-		sqlValues(values),
-	)
+	for i := 0; i < len(vals); i++ {
+		values = append(values, sqlPlaceholder)
+	}
 
+	// Error ocurred, stop appending.
 	if err != nil {
 		return nil, err
 	}
 
-	var id int64
-
-	id, err = res.LastInsertId()
+	res, err := self.source.doExec(sqlgen.Statement{
+		Type:    sqlgen.SqlInsert,
+		Table:   sqlgen.Table{self.tableN(0)},
+		Columns: columns,
+		Values:  values,
+	}, vals...)
 
 	if err != nil {
 		return nil, err
 	}
 
+	var id int64
+	id, _ = res.LastInsertId()
+
 	return id, nil
 }
 
 // Returns true if the collection exists.
 func (self *Table) Exists() bool {
-	rows, err := self.source.doQuery(
-		`SELECT Name
-			FROM __Table
-		WHERE Name == ?
-		`,
-		[]interface{}{self.Name()},
-	)
-
-	if err != nil {
+	if err := self.source.tableExists(self.names...); err != nil {
 		return false
 	}
-
-	defer rows.Close()
-
-	return rows.Next()
+	return true
 }
 
-func interfaceArgs(value interface{}) (args []interface{}) {
-
-	if value == nil {
-		return nil
-	}
-
-	value_v := reflect.ValueOf(value)
-
-	switch value_v.Type().Kind() {
-	case reflect.Slice:
-		var i, total int
-
-		total = value_v.Len()
-		if total > 0 {
-			args = make([]interface{}, total)
-
-			for i = 0; i < total; i++ {
-				args[i] = value_v.Index(i).Interface()
-			}
-
-			return args
-		} else {
-			return nil
-		}
-	default:
-		args = []interface{}{value}
-	}
+func (self *Table) Name() string {
+	return strings.Join(self.names, `, `)
+}
 
-	return args
+func toInternal(v interface{}) interface{} {
+	return v
 }
diff --git a/ql/database.go b/ql/database.go
index 9d4db014538bd67c174e4bc21667e5c82aade866..aa0efd74d50b69a028013c75abe270be367050ce 100644
--- a/ql/database.go
+++ b/ql/database.go
@@ -1,25 +1,23 @@
-/*
-  Copyright (c) 2014 JosĂŠ Carlos Nieto, https://menteslibres.net/xiam
-
-  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.
-*/
+// Copyright (c) 2012-2014 JosĂŠ Carlos Nieto, https://menteslibres.net/xiam
+//
+// 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 ql
 
@@ -27,38 +25,41 @@ import (
 	"database/sql"
 	"fmt"
 	_ "github.com/cznic/ql/driver"
-	"log"
 	"os"
 	"reflect"
 	"strings"
 	"time"
 	"upper.io/db"
+	"upper.io/db/util/sqlgen"
+	"upper.io/db/util/sqlutil"
 )
 
-var Debug = false
+const Driver = `ql`
 
-// Format for saving dates.
-var DateFormat = "2006-01-02 15:04:05"
-
-// Format for saving times.
-var TimeFormat = "%d:%02d:%02d.%d"
-
-var timeType = reflect.TypeOf(time.Time{}).Kind()
+var (
+	// Format for saving dates.
+	DateFormat = "2006-01-02 15:04:05.000"
+	// Format for saving times.
+	TimeFormat = "%d:%02d:%02d.%03d"
+	timeType   = reflect.TypeOf(time.Time{}).Kind()
+)
 
-const driverName = `ql`
+var template *sqlgen.Template
 
-type sqlValues_t []interface{}
+var (
+	sqlPlaceholder = sqlgen.Value{sqlgen.Raw{`?`}}
+)
 
 type Source struct {
 	config      db.Settings
 	session     *sql.DB
-	name        string
 	collections map[string]db.Collection
+	tx          *sql.Tx
 }
 
-type sqlQuery struct {
-	Query []string
-	Args  []interface{}
+type columnSchema_t struct {
+	ColumnName string `db:"name"`
+	DataType   string `db:"type"`
 }
 
 func debugEnabled() bool {
@@ -69,129 +70,156 @@ func debugEnabled() bool {
 }
 
 func init() {
-	db.Register(driverName, &Source{})
-}
-
-func debugLogQuery(s string, q *sqlQuery) {
-	log.Printf("SQL: %s\nARGS: %v\n", strings.TrimSpace(s), q.Args)
-}
-
-func sqlCompile(terms []interface{}) *sqlQuery {
-	q := &sqlQuery{}
 
-	q.Query = []string{}
-
-	for _, term := range terms {
-		switch t := term.(type) {
-		case sqlValues_t:
-			args := make([]string, len(t))
-			for i, arg := range t {
-				args[i] = `?`
-				q.Args = append(q.Args, arg)
-			}
-			q.Query = append(q.Query, `(`+strings.Join(args, `, `)+`)`)
-		case string:
-			q.Query = append(q.Query, t)
-		default:
-			if reflect.TypeOf(t).Kind() == reflect.Slice {
-				var v = reflect.ValueOf(t)
-				for i := 0; i < v.Len(); i++ {
-					q.Args = append(q.Args, v.Index(i).Interface())
-				}
-			} else {
-				q.Args = append(q.Args, t)
-			}
-		}
+	template = &sqlgen.Template{
+		qlColumnSeparator,
+		qlIdentifierSeparator,
+		qlIdentifierQuote,
+		qlValueSeparator,
+		qlValueQuote,
+		qlAndKeyword,
+		qlOrKeyword,
+		qlNotKeyword,
+		qlDescKeyword,
+		qlAscKeyword,
+		qlDefaultOperator,
+		qlClauseGroup,
+		qlClauseOperator,
+		qlColumnValue,
+		qlTableAliasLayout,
+		qlColumnAliasLayout,
+		qlSortByColumnLayout,
+		qlWhereLayout,
+		qlOrderByLayout,
+		qlInsertLayout,
+		qlSelectLayout,
+		qlUpdateLayout,
+		qlDeleteLayout,
+		qlTruncateLayout,
+		qlDropDatabaseLayout,
+		qlDropTableLayout,
+		qlSelectCountLayout,
 	}
 
-	return q
-}
-
-func sqlFields(names []string) string {
-	return `(` + strings.Join(names, `, `) + `)`
+	db.Register(Driver, &Source{})
 }
 
-func sqlValues(values []interface{}) sqlValues_t {
-	ret := make(sqlValues_t, len(values))
-	for i, _ := range values {
-		ret[i] = values[i]
-	}
-	return ret
-}
-
-func (self *Source) doExec(terms ...interface{}) (res sql.Result, err error) {
-	var tx *sql.Tx
+func (self *Source) doExec(stmt sqlgen.Statement, args ...interface{}) (sql.Result, error) {
 
 	if self.session == nil {
 		return nil, db.ErrNotConnected
 	}
 
-	chunks := sqlCompile(terms)
-
-	query := strings.Join(chunks.Query, ` `)
+	query := stmt.Compile(template)
 
-	for i := 0; i < len(chunks.Args); i++ {
+	l := len(args)
+	for i := 0; i < l; i++ {
 		query = strings.Replace(query, `?`, fmt.Sprintf(`$%d`, i+1), 1)
 	}
 
 	if debugEnabled() == true {
-		debugLogQuery(query, chunks)
+		sqlutil.DebugQuery(query, args)
 	}
 
-	if tx, err = self.session.Begin(); err != nil {
-		return nil, err
-	}
+	if self.tx == nil {
+		var tx *sql.Tx
+		var err error
+		var res sql.Result
 
-	if res, err = tx.Exec(query, chunks.Args...); err != nil {
-		return nil, err
-	}
+		if tx, err = self.session.Begin(); err != nil {
+			return nil, err
+		}
 
-	if err = tx.Commit(); err != nil {
-		return nil, err
+		if res, err = tx.Exec(query, args...); err != nil {
+			return nil, err
+		}
+
+		if err = tx.Commit(); err != nil {
+			return nil, err
+		}
+
+		return res, nil
 	}
 
-	return res, nil
+	return self.tx.Exec(query, args...)
 }
 
-func (self *Source) doQuery(terms ...interface{}) (*sql.Rows, error) {
+func (self *Source) doQuery(stmt sqlgen.Statement, args ...interface{}) (*sql.Rows, error) {
 	if self.session == nil {
 		return nil, db.ErrNotConnected
 	}
 
-	chunks := sqlCompile(terms)
+	query := stmt.Compile(template)
 
-	query := strings.Join(chunks.Query, ` `)
-
-	for i := 0; i < len(chunks.Args); i++ {
+	l := len(args)
+	for i := 0; i < l; i++ {
 		query = strings.Replace(query, `?`, fmt.Sprintf(`$%d`, i+1), 1)
 	}
 
 	if debugEnabled() == true {
-		debugLogQuery(query, chunks)
+		sqlutil.DebugQuery(query, args)
+	}
+
+	if self.tx == nil {
+		var tx *sql.Tx
+		var err error
+		var rows *sql.Rows
+
+		if tx, err = self.session.Begin(); err != nil {
+			return nil, err
+		}
+
+		if rows, err = tx.Query(query, args...); err != nil {
+			return nil, err
+		}
+
+		if err = tx.Commit(); err != nil {
+			return nil, err
+		}
+
+		return rows, nil
 	}
 
-	return self.session.Query(query, chunks.Args...)
+	return self.tx.Query(query, args...)
 }
 
-func (self *Source) doQueryRow(terms ...interface{}) (*sql.Row, error) {
+func (self *Source) doQueryRow(stmt sqlgen.Statement, args ...interface{}) (*sql.Row, error) {
 	if self.session == nil {
 		return nil, db.ErrNotConnected
 	}
 
-	chunks := sqlCompile(terms)
+	query := stmt.Compile(template)
 
-	query := strings.Join(chunks.Query, ` `)
-
-	for i := 0; i < len(chunks.Args); i++ {
+	l := len(args)
+	for i := 0; i < l; i++ {
 		query = strings.Replace(query, `?`, fmt.Sprintf(`$%d`, i+1), 1)
 	}
 
-	if Debug == true {
-		fmt.Printf("Q: %s\n", query)
-		fmt.Printf("A: %v\n", chunks.Args)
+	if debugEnabled() == true {
+		sqlutil.DebugQuery(query, args)
 	}
 
-	return self.session.QueryRow(query, chunks.Args...), nil
+	if self.tx == nil {
+		var tx *sql.Tx
+		var err error
+		var row *sql.Row
+
+		if tx, err = self.session.Begin(); err != nil {
+			return nil, err
+		}
+
+		if row = tx.QueryRow(query, args...); err != nil {
+			return nil, err
+		}
+
+		if err = tx.Commit(); err != nil {
+			return nil, err
+		}
+
+		return row, nil
+	} else {
+		return self.tx.QueryRow(query, args...), nil
+	}
 }
 
 // Returns the string name of the database.
@@ -199,6 +227,47 @@ func (self *Source) Name() string {
 	return self.config.Database
 }
 
+//  Ping verifies a connection to the database is still alive,
+//  establishing a connection if necessary.
+func (self *Source) Ping() error {
+	return self.session.Ping()
+}
+
+func (self *Source) clone() (*Source, error) {
+	src := &Source{}
+	src.Setup(self.config)
+
+	if err := src.Open(); err != nil {
+		return nil, err
+	}
+
+	return src, nil
+}
+
+func (self *Source) Clone() (db.Database, error) {
+	return self.clone()
+}
+
+func (self *Source) Transaction() (db.Tx, error) {
+	var err error
+	var clone *Source
+	var sqlTx *sql.Tx
+
+	if clone, err = self.clone(); err != nil {
+		return nil, err
+	}
+
+	if sqlTx, err = clone.session.Begin(); err != nil {
+		return nil, err
+	}
+
+	tx := &Tx{clone}
+
+	clone.tx = sqlTx
+
+	return tx, nil
+}
+
 // Stores database settings.
 func (self *Source) Setup(config db.Settings) error {
 	self.config = config
@@ -242,22 +311,15 @@ func (self *Source) Use(database string) error {
 	return self.Open()
 }
 
-// Starts a transaction block.
-func (self *Source) Begin() error {
-	_, err := self.session.Exec(`BEGIN`)
-	return err
-}
-
-// Ends a transaction block.
-func (self *Source) End() error {
-	_, err := self.session.Exec(`END`)
-	return err
-}
-
 // Drops the currently active database.
 func (self *Source) Drop() error {
-	self.session.Query(fmt.Sprintf(`DROP DATABASE "%s"`, self.config.Database))
-	return nil
+
+	_, err := self.doQuery(sqlgen.Statement{
+		Type:     sqlgen.SqlDropDatabase,
+		Database: sqlgen.Database{self.config.Database},
+	})
+
+	return err
 }
 
 // Returns a list of all tables within the currently active database.
@@ -265,7 +327,13 @@ func (self *Source) Collections() ([]string, error) {
 	var collections []string
 	var collection string
 
-	rows, err := self.session.Query(`SELECT Name FROM __Table`)
+	rows, err := self.doQuery(sqlgen.Statement{
+		Type:  sqlgen.SqlSelect,
+		Table: sqlgen.Table{`__Table`},
+		Columns: sqlgen.Columns{
+			{`Name`},
+		},
+	})
 
 	if err != nil {
 		return nil, err
@@ -274,114 +342,136 @@ func (self *Source) Collections() ([]string, error) {
 	defer rows.Close()
 
 	for rows.Next() {
-		if err = rows.Scan(&collection); err != nil {
-			return nil, err
-		}
+		rows.Scan(&collection)
 		collections = append(collections, collection)
 	}
 
-	err = rows.Err()
+	return collections, nil
+}
 
-	if err != nil {
-		return nil, err
+func (self *Source) tableExists(names ...string) error {
+	for _, name := range names {
+
+		rows, err := self.doQuery(sqlgen.Statement{
+			Type:  sqlgen.SqlSelect,
+			Table: sqlgen.Table{`__Table`},
+			Columns: sqlgen.Columns{
+				{`Name`},
+			},
+			Where: sqlgen.Where{
+				sqlgen.ColumnValue{sqlgen.Column{`Name`}, `==`, sqlPlaceholder},
+			},
+		}, name)
+
+		if err != nil {
+			return db.ErrCollectionDoesNotExists
+		}
+
+		defer rows.Close()
+
+		if rows.Next() == false {
+			return db.ErrCollectionDoesNotExists
+		}
 	}
 
-	return collections, nil
+	return nil
 }
 
 // Returns a collection instance by name.
-func (self *Source) Collection(name string) (db.Collection, error) {
+func (self *Source) Collection(names ...string) (db.Collection, error) {
 
-	if collection, ok := self.collections[name]; ok == true {
-		return collection, nil
+	if len(names) == 0 {
+		return nil, db.ErrMissingCollectionName
 	}
 
-	table := &Table{}
+	col := &Table{
+		source: self,
+		names:  names,
+	}
 
-	table.source = self
-	table.DB = self
-	table.PrimaryKey = `id`
+	col.PrimaryKey = `id`
 
-	table.SetName = name
+	columns_t := []columnSchema_t{}
 
-	// Table exists?
-	if table.Exists() == false {
-		return table, db.ErrCollectionDoesNotExists
-	}
+	for _, name := range names {
+		chunks := strings.SplitN(name, " ", 2)
 
-	// Fetching table datatypes and mapping to internal gotypes.
-	rows, err := table.source.doQuery(
-		`SELECT
-			Name, Type
-		FROM __Column
-		WHERE
-			TableName == ?`,
-		[]string{table.Name()},
-	)
+		if len(chunks) > 0 {
 
-	if err != nil {
-		return table, err
-	}
+			name = chunks[0]
 
-	columns := []struct {
-		Name string
-		Type string
-	}{}
+			if err := self.tableExists(name); err != nil {
+				return nil, err
+			}
 
-	err = table.FetchRows(&columns, rows)
+			rows, err := self.doQuery(sqlgen.Statement{
+				Type:  sqlgen.SqlSelect,
+				Table: sqlgen.Table{`__Column`},
+				Columns: sqlgen.Columns{
+					{`Name`},
+					{`Type`},
+				},
+				Where: sqlgen.Where{
+					sqlgen.ColumnValue{sqlgen.Column{`TableName`}, `==`, sqlPlaceholder},
+				},
+			}, name)
+
+			if err != nil {
+				return nil, err
+			}
 
-	if err != nil {
-		return nil, err
-	}
+			if err = col.FetchRows(&columns_t, rows); err != nil {
+				return nil, err
+			}
 
-	table.ColumnTypes = make(map[string]reflect.Kind, len(columns))
-
-	for _, column := range columns {
-
-		column.Name = strings.ToLower(column.Name)
-		column.Type = strings.ToLower(column.Type)
-
-		// Default properties.
-		dtype := column.Type
-
-		ctype := reflect.String
-
-		// Guessing datatypes.
-		switch dtype {
-		case `int`:
-			ctype = reflect.Int
-		case `int8`:
-			ctype = reflect.Int8
-		case `int16`:
-			ctype = reflect.Int16
-		case `int32`, `rune`:
-			ctype = reflect.Int32
-		case `int64`:
-			ctype = reflect.Int64
-		case `uint`:
-			ctype = reflect.Uint
-		case `uint8`:
-			ctype = reflect.Uint8
-		case `uint16`:
-			ctype = reflect.Uint16
-		case `uint32`:
-			ctype = reflect.Uint32
-		case `uint64`:
-			ctype = reflect.Uint64
-		case `float64`:
-			ctype = reflect.Float64
-		case `float32`:
-			ctype = reflect.Float32
-		case `time`:
-			ctype = timeType
-		default:
-			ctype = reflect.String
-		}
+			col.ColumnTypes = make(map[string]reflect.Kind, len(columns_t))
+
+			for _, column := range columns_t {
+
+				column.ColumnName = strings.ToLower(column.ColumnName)
+				column.DataType = strings.ToLower(column.DataType)
+
+				// Default properties.
+				dtype := column.DataType
+				ctype := reflect.String
+
+				// Guessing datatypes.
+				switch dtype {
+				case `int`:
+					ctype = reflect.Int
+				case `int8`:
+					ctype = reflect.Int8
+				case `int16`:
+					ctype = reflect.Int16
+				case `int32`, `rune`:
+					ctype = reflect.Int32
+				case `int64`:
+					ctype = reflect.Int64
+				case `uint`:
+					ctype = reflect.Uint
+				case `uint8`:
+					ctype = reflect.Uint8
+				case `uint16`:
+					ctype = reflect.Uint16
+				case `uint32`:
+					ctype = reflect.Uint32
+				case `uint64`:
+					ctype = reflect.Uint64
+				case `float64`:
+					ctype = reflect.Float64
+				case `float32`:
+					ctype = reflect.Float32
+				case `time`:
+					ctype = timeType
+				default:
+					ctype = reflect.String
+				}
 
-		table.ColumnTypes[column.Name] = ctype
-	}
+				col.ColumnTypes[column.ColumnName] = ctype
+			}
 
-	self.collections[name] = table
+		}
+	}
 
-	return table, nil
+	return col, nil
 }
diff --git a/ql/database_test.go b/ql/database_test.go
index 668a059a6a3ec0e7388a79e863f5cb67631b04b8..d0693a9daaaf98572189ba47b7c62d3abdb6cc51 100644
--- a/ql/database_test.go
+++ b/ql/database_test.go
@@ -1,57 +1,50 @@
-/*
-  Copyright (c) 2014 JosĂŠ Carlos Nieto, https://menteslibres.net/xiam
-
-  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.
-*/
-
-/*
-	Tests for the ql wrapper.
-
-	Execute the Makefile in ./_dumps/ to create the expected database structure.
+// Copyright (c) 2012-2014 JosĂŠ Carlos Nieto, https://menteslibres.net/xiam
+//
+// 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.
 
-	cd _dumps
-	make
-	cd ..
-	go test
-*/
 package ql
 
+// In order to execute these tests you must initialize the database first:
+//
+// cd _dumps
+// make
+// cd ..
+// go test
+
 import (
-	"database/sql"
+	//"database/sql"
 	"menteslibres.net/gosexy/to"
 	"os"
+	//"reflect"
 	"strings"
 	"testing"
 	"time"
 	"upper.io/db"
 )
 
-// Wrapper.
-const wrapperName = "ql"
-
-// Wrapper settings.
-const dbname = "file://_dumps/test.db"
+const (
+	database = `_dumps/test.db`
+)
 
-// Global settings for tests.
 var settings = db.Settings{
-	Database: dbname,
+	Database: database,
 }
 
 // Structure for testing conversions and datatypes.
@@ -80,39 +73,41 @@ type testValuesStruct struct {
 
 // Declaring some values to insert, we expect the same values to be returned.
 var testValues = testValuesStruct{
-	uint(1), uint8(1), uint16(1), uint32(1), uint64(1),
-	int(-1), int8(-1), int16(-1), int32(-1), int64(-1),
-	float32(1.337), float64(1.337),
+	1, 1, 1, 1, 1,
+	-1, -1, -1, -1, -1,
+	1.337, 1.337,
 	true,
 	"Hello world!",
-	time.Date(2012, 7, 28, 1, 2, 3, 0, time.UTC),
+	time.Date(2012, 7, 28, 1, 2, 3, 0, time.Local),
 	time.Second * time.Duration(7331),
 }
 
-// Enabling outputting some information to stdout (like the SQL query and its
+// Loggin some information to stdout (like the SQL query and its
 // arguments), useful for development.
 func TestEnableDebug(t *testing.T) {
 	os.Setenv(db.EnvEnableDebug, "TRUE")
 }
 
-// Trying to open an empty datasource, it must fail.
+// Attempts to open an empty datasource.
 func TestOpenFailed(t *testing.T) {
-	_, err := db.Open(wrapperName, db.Settings{})
+	var err error
 
-	if err == nil {
-		t.Errorf("Expecting an error.")
+	// Attempt to open an empty database.
+	if _, err = db.Open(Driver, db.Settings{}); err == nil {
+		// Must fail.
+		t.Fatalf("Expecting an error.")
 	}
 }
 
-// Truncates all collections.
+// Attempts to get all collections and truncate each one of them.
 func TestTruncate(t *testing.T) {
-
 	var err error
+	var sess db.Database
+	var collections []string
+	var col db.Collection
 
 	// Opening database.
-	sess, err := db.Open(wrapperName, settings)
-
-	if err != nil {
+	if sess, err = db.Open(Driver, settings); err != nil {
 		t.Fatalf(err.Error())
 	}
 
@@ -120,158 +115,162 @@ func TestTruncate(t *testing.T) {
 	defer sess.Close()
 
 	// Getting a list of all collections in this database.
-	collections, err := sess.Collections()
-
-	if err != nil {
+	if collections, err = sess.Collections(); err != nil {
 		t.Fatalf(err.Error())
 	}
 
+	if len(collections) == 0 {
+		t.Fatalf("Expecting some collections.")
+	}
+
+	// Walking over collections.
 	for _, name := range collections {
 
-		// Pointing the collection.
-		col, err := sess.Collection(name)
-		if err != nil {
+		// Getting a collection.
+		if col, err = sess.Collection(name); err != nil {
 			t.Fatalf(err.Error())
 		}
 
-		// Since this is a SQL collection (table), the structure must exists before
-		// we can use it.
-		exists := col.Exists()
-
-		if exists == true {
-			// Truncating the structure, if exists.
-			err = col.Truncate()
-
-			if err != nil {
+		// Table must exists before we can use it.
+		if col.Exists() == true {
+			// Truncating the table.
+			if err = col.Truncate(); err != nil {
 				t.Fatalf(err.Error())
 			}
 		}
-
 	}
 }
 
-// This test appends some data into the "artist" table.
+// Attempts to append some data into the "artist" table.
 func TestAppend(t *testing.T) {
-
 	var err error
 	var id interface{}
+	var sess db.Database
+	var artist db.Collection
+	var total uint64
 
-	// Opening database.
-	sess, err := db.Open(wrapperName, settings)
-
-	if err != nil {
+	if sess, err = db.Open(Driver, settings); err != nil {
 		t.Fatalf(err.Error())
 	}
 
-	// We should close the database when it's no longer in use.
 	defer sess.Close()
 
-	// Getting a pointer to the "artist" collection.
-	artist, err := sess.Collection("artist")
-
-	if err != nil {
+	if artist, err = sess.Collection("artist"); err != nil {
 		t.Fatalf(err.Error())
 	}
 
-	// Appending a map.
-	id, err = artist.Append(map[string]string{
+	// Attempt to append a map.
+	item_m := map[string]string{
 		"name": "Ozzie",
-	})
+	}
+
+	if id, err = artist.Append(item_m); err != nil {
+		t.Fatalf(err.Error())
+	}
 
 	if to.Int64(id) == 0 {
 		t.Fatalf("Expecting an ID.")
 	}
 
-	// Appending a struct.
-	id, err = artist.Append(struct {
-		Name string `field:name`
+	// Attempt to append a struct.
+	item_s := struct {
+		Name string `db:"name"`
 	}{
 		"Flea",
-	})
+	}
+
+	if id, err = artist.Append(item_s); err != nil {
+		t.Fatalf(err.Error())
+	}
 
 	if to.Int64(id) == 0 {
 		t.Fatalf("Expecting an ID.")
 	}
 
-	// Appending a struct (using tags to specify the field name).
-	id, err = artist.Append(struct {
-		ArtistName string `field:"name"`
+	// Append to append a tagged struct.
+	item_t := struct {
+		ArtistName string `db:"name"`
 	}{
 		"Slash",
-	})
+	}
+
+	if id, err = artist.Append(item_t); err != nil {
+		t.Fatalf(err.Error())
+	}
 
 	if to.Int64(id) == 0 {
 		t.Fatalf("Expecting an ID.")
 	}
 
+	// Counting elements, must be exactly 3 elements.
+	if total, err = artist.Find().Count(); err != nil {
+		t.Fatalf(err.Error())
+	}
+
+	if total != 3 {
+		t.Fatalf("Expecting exactly 3 rows.")
+	}
+
 }
 
-// This test tries to use an empty filter and count how many elements were
-// added into the artist collection.
+// Attempts to count all rows in our newly defined set.
 func TestResultCount(t *testing.T) {
-
 	var err error
 	var res db.Result
+	var sess db.Database
+	var artist db.Collection
+	var total uint64
 
-	// Opening database.
-	sess, err := db.Open(wrapperName, settings)
-
-	if err != nil {
+	if sess, err = db.Open(Driver, settings); err != nil {
 		t.Fatalf(err.Error())
 	}
 
 	defer sess.Close()
 
 	// We should close the database when it's no longer in use.
-	artist, _ := sess.Collection("artist")
+	if artist, err = sess.Collection("artist"); err != nil {
+		t.Fatalf(err.Error())
+	}
 
+	// Defining a set with no conditions.
 	res = artist.Find()
 
 	// Counting all the matching rows.
-	total, err := res.Count()
-
-	if err != nil {
+	if total, err = res.Count(); err != nil {
 		t.Fatalf(err.Error())
 	}
 
 	if total == 0 {
-		t.Fatalf("Should not be empty, we've just added some rows!")
+		t.Fatalf("Counter should not be zero, we've just added some rows!")
 	}
-
 }
 
-// This test uses and result and tries to fetch items one by one.
+// Attempts to fetch results one by one.
 func TestResultFetch(t *testing.T) {
-
 	var err error
 	var res db.Result
+	var sess db.Database
+	var artist db.Collection
 
-	// Opening database.
-	sess, err := db.Open(wrapperName, settings)
-
-	if err != nil {
+	if sess, err = db.Open(Driver, settings); err != nil {
 		t.Fatalf(err.Error())
 	}
 
-	// We should close the database when it's no longer in use.
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-
-	if err != nil {
+	if artist, err = sess.Collection("artist"); err != nil {
 		t.Fatalf(err.Error())
 	}
 
-	// Testing map
-	res = artist.Find().Select("id() AS id", "name")
-
+	// Dumping into a map.
 	row_m := map[string]interface{}{}
 
+	res = artist.Find().Select("id() as id", "name")
+
 	for {
 		err = res.Next(&row_m)
 
 		if err == db.ErrNoMoreRows {
-			// No more row_ms left.
 			break
 		}
 
@@ -289,19 +288,18 @@ func TestResultFetch(t *testing.T) {
 
 	res.Close()
 
-	// Testing struct
+	// Dumping into an struct with no tags.
 	row_s := struct {
 		Id   uint64
 		Name string
 	}{}
 
-	res = artist.Find().Select("id() AS id", "name")
+	res = artist.Find().Select("id() as id", "name")
 
 	for {
 		err = res.Next(&row_s)
 
 		if err == db.ErrNoMoreRows {
-			// No more row_s' left.
 			break
 		}
 
@@ -319,19 +317,18 @@ func TestResultFetch(t *testing.T) {
 
 	res.Close()
 
-	// Testing tagged struct
+	// Dumping into a tagged struct.
 	row_t := struct {
 		Value1 uint64 `field:"id"`
 		Value2 string `field:"name"`
 	}{}
 
-	res = artist.Find().Select("id() AS id", "name")
+	res = artist.Find().Select("id() as id", "name")
 
 	for {
 		err = res.Next(&row_t)
 
 		if err == db.ErrNoMoreRows {
-			// No more row_t's left.
 			break
 		}
 
@@ -349,54 +346,62 @@ func TestResultFetch(t *testing.T) {
 
 	res.Close()
 
-	// Testing Result.All() with a slice of maps.
-	res = artist.Find().Select("id() AS id", "name")
-
+	// Dumping into an slice of maps.
 	all_rows_m := []map[string]interface{}{}
-	err = res.All(&all_rows_m)
 
-	if err != nil {
+	res = artist.Find().Select("id() as id", "name")
+	if err = res.All(&all_rows_m); err != nil {
 		t.Fatalf(err.Error())
 	}
 
+	if len(all_rows_m) != 3 {
+		t.Fatalf("Expecting 3 items.")
+	}
+
 	for _, single_row_m := range all_rows_m {
 		if to.Int64(single_row_m["id"]) == 0 {
 			t.Fatalf("Expecting a not null ID.")
 		}
 	}
 
-	// Testing Result.All() with a slice of structs.
-	res = artist.Find().Select("id() AS id", "name")
+	// Dumping into an slice of structs.
 
 	all_rows_s := []struct {
 		Id   uint64
 		Name string
 	}{}
-	err = res.All(&all_rows_s)
 
-	if err != nil {
+	res = artist.Find().Select("id() as id", "name")
+	if err = res.All(&all_rows_s); err != nil {
 		t.Fatalf(err.Error())
 	}
 
+	if len(all_rows_s) != 3 {
+		t.Fatalf("Expecting 3 items.")
+	}
+
 	for _, single_row_s := range all_rows_s {
 		if single_row_s.Id == 0 {
 			t.Fatalf("Expecting a not null ID.")
 		}
 	}
 
-	// Testing Result.All() with a slice of tagged structs.
-	res = artist.Find().Select("id() AS id", "name")
-
+	// Dumping into an slice of tagged structs.
 	all_rows_t := []struct {
 		Value1 uint64 `field:"id"`
 		Value2 string `field:"name"`
 	}{}
-	err = res.All(&all_rows_t)
 
-	if err != nil {
+	res = artist.Find().Select("id() as id", "name")
+
+	if err = res.All(&all_rows_t); err != nil {
 		t.Fatalf(err.Error())
 	}
 
+	if len(all_rows_t) != 3 {
+		t.Fatalf("Expecting 3 items.")
+	}
+
 	for _, single_row_t := range all_rows_t {
 		if single_row_t.Value1 == 0 {
 			t.Fatalf("Expecting a not null ID.")
@@ -404,28 +409,23 @@ func TestResultFetch(t *testing.T) {
 	}
 }
 
-// This test tries to update some previously added rows.
+// Attempts to modify previously added rows.
 func TestUpdate(t *testing.T) {
 	var err error
+	var sess db.Database
+	var artist db.Collection
 
-	// Opening database.
-	sess, err := db.Open(wrapperName, settings)
-
-	if err != nil {
+	if sess, err = db.Open(Driver, settings); err != nil {
 		t.Fatalf(err.Error())
 	}
 
-	// We should close the database when it's no longer in use.
 	defer sess.Close()
 
-	// Getting a pointer to the "artist" collection.
-	artist, err := sess.Collection("artist")
-
-	if err != nil {
+	if artist, err = sess.Collection("artist"); err != nil {
 		t.Fatalf(err.Error())
 	}
 
-	// Value
+	// Defining destination struct
 	value := struct {
 		Id   uint64
 		Name string
@@ -434,96 +434,83 @@ func TestUpdate(t *testing.T) {
 	// Getting the first artist.
 	res := artist.Find(db.Cond{"id() !=": 0}).Limit(1)
 
-	err = res.One(&value)
-
-	if err != nil {
+	if err = res.One(&value); err != nil {
 		t.Fatalf(err.Error())
 	}
 
-	// Updating with a map
+	// Updating set with a map
 	row_m := map[string]interface{}{
 		"name": strings.ToUpper(value.Name),
 	}
 
-	err = res.Update(row_m)
-
-	if err != nil {
+	if err = res.Update(row_m); err != nil {
 		t.Fatalf(err.Error())
 	}
 
-	err = res.One(&value)
-
-	if err != nil {
+	// Pulling it again.
+	if err = res.One(&value); err != nil {
 		t.Fatalf(err.Error())
 	}
 
+	// Verifying.
 	if value.Name != row_m["name"] {
 		t.Fatalf("Expecting a modification.")
 	}
 
-	// Updating with a struct
+	// Updating set with a struct
 	row_s := struct {
 		Name string
 	}{strings.ToLower(value.Name)}
 
-	err = res.Update(row_s)
-
-	if err != nil {
+	if err = res.Update(row_s); err != nil {
 		t.Fatalf(err.Error())
 	}
 
-	err = res.One(&value)
-
-	if err != nil {
+	// Pulling it again.
+	if err = res.One(&value); err != nil {
 		t.Fatalf(err.Error())
 	}
 
+	// Verifying
 	if value.Name != row_s.Name {
 		t.Fatalf("Expecting a modification.")
 	}
 
-	// Updating with a tagged struct
+	// Updating set with a tagged struct
 	row_t := struct {
-		Value1 string `field:"name"`
+		Value1 string `db:"name"`
 	}{strings.Replace(value.Name, "z", "Z", -1)}
 
-	err = res.Update(row_t)
-
-	if err != nil {
+	if err = res.Update(row_t); err != nil {
 		t.Fatalf(err.Error())
 	}
 
-	err = res.One(&value)
-
-	if err != nil {
+	// Pulling it again.
+	if err = res.One(&value); err != nil {
 		t.Fatalf(err.Error())
 	}
 
+	// Verifying
 	if value.Name != row_t.Value1 {
 		t.Fatalf("Expecting a modification.")
 	}
-
 }
 
-// Test database functions
+// Attempts to use functions within database queries.
 func TestFunction(t *testing.T) {
 	var err error
 	var res db.Result
+	var sess db.Database
+	var artist db.Collection
+	var total uint64
 
-	// Opening database.
-	sess, err := db.Open(wrapperName, settings)
-
-	if err != nil {
+	if sess, err = db.Open(Driver, settings); err != nil {
 		t.Fatalf(err.Error())
 	}
 
-	// We should close the database when it's no longer in use.
 	defer sess.Close()
 
-	// Getting a pointer to the "artist" collection.
-	artist, err := sess.Collection("artist")
-
-	if err != nil {
+	if artist, err = sess.Collection("artist"); err != nil {
 		t.Fatalf(err.Error())
 	}
 
@@ -535,99 +522,296 @@ func TestFunction(t *testing.T) {
 	res = artist.Find(db.Cond{"id() NOT IN": []int{0, -1}})
 
 	if err = res.One(&row_s); err != nil {
-		t.Fatalf("One: %q", err)
+		t.Fatalf(err.Error())
+	}
+
+	if total, err = res.Count(); err != nil {
+		t.Fatalf(err.Error())
+	}
+
+	if total != 3 {
+		t.Fatalf("Expecting 3 items.")
 	}
 
 	res = artist.Find(db.Cond{"id()": db.Func{"NOT IN", []int{0, -1}}})
 
 	if err = res.One(&row_s); err != nil {
-		t.Fatalf("One: %q", err)
+		t.Fatalf(err.Error())
+	}
+
+	if total, err = res.Count(); err != nil {
+		t.Fatalf(err.Error())
+	}
+
+	if total != 3 {
+		t.Fatalf("Expecting 3 items.")
 	}
 
 	res.Close()
 }
 
-// This test tries to remove some previously added rows.
+// Attempts to delete previously added rows.
 func TestRemove(t *testing.T) {
+	var err error
+	var res db.Result
+	var sess db.Database
+	var artist db.Collection
+
+	if sess, err = db.Open(Driver, settings); err != nil {
+		t.Fatalf(err.Error())
+	}
+
+	defer sess.Close()
 
+	if artist, err = sess.Collection("artist"); err != nil {
+		t.Fatalf(err.Error())
+	}
+
+	// Getting the artist with id = 1
+	res = artist.Find(db.Cond{"id()": 1})
+
+	// Trying to remove the row.
+	if err = res.Remove(); err != nil {
+		t.Fatalf(err.Error())
+	}
+}
+
+// Attempts to use SQL raw statements.
+func TestRawRelations(t *testing.T) {
+	var sess db.Database
 	var err error
 
-	// Opening database.
-	sess, err := db.Open(wrapperName, settings)
+	var artist db.Collection
+	var publication db.Collection
+	var review db.Collection
 
-	if err != nil {
+	type artist_t struct {
+		Id   int64  `db:"id,omitempty"`
+		Name string `db:"name"`
+	}
+
+	type publication_t struct {
+		Id       int64  `db:"id,omitempty"`
+		Title    string `db:"title"`
+		AuthorId int64  `db:"author_id"`
+	}
+
+	type review_t struct {
+		Id            int64     `db:"id,omitempty"`
+		PublicationId int64     `db:"publication_id"`
+		Name          string    `db:"name"`
+		Comments      string    `db:"comments"`
+		Created       time.Time `db:"created"`
+	}
+
+	if sess, err = db.Open(Driver, settings); err != nil {
 		t.Fatalf(err.Error())
 	}
 
-	// We should close the database when it's no longer in use.
 	defer sess.Close()
 
-	// Getting a pointer to the "artist" collection.
-	artist, err := sess.Collection("artist")
+	// Artist collection.
+	if artist, err = sess.Collection("artist"); err != nil {
+		t.Fatalf(err.Error())
+	}
 
-	if err != nil {
+	if err = artist.Truncate(); err != nil {
 		t.Fatalf(err.Error())
 	}
 
-	// Getting the artist with id = 1
-	res := artist.Find(db.Cond{"id()": 1})
+	// Publication collection.
+	if publication, err = sess.Collection("publication"); err != nil {
+		t.Fatalf(err.Error())
+	}
 
-	// Trying to remove the row.
-	err = res.Remove()
+	if err = publication.Truncate(); err != nil {
+		t.Fatalf(err.Error())
+	}
+
+	// Review collection.
+	if review, err = sess.Collection("review"); err != nil {
+		t.Fatalf(err.Error())
+	}
+
+	if err = review.Truncate(); err != nil {
+		t.Fatalf(err.Error())
+	}
+
+	// Adding some artists.
+	var miyazakiId interface{}
+	miyazaki := artist_t{Name: `Hayao Miyazaki`}
+	if miyazakiId, err = artist.Append(miyazaki); err != nil {
+		t.Fatalf(err.Error())
+	}
+	miyazaki.Id = miyazakiId.(int64)
+
+	var asimovId interface{}
+	asimov := artist_t{Name: `Isaac Asimov`}
+	if asimovId, err = artist.Append(asimov); err != nil {
+		t.Fatalf(err.Error())
+	}
+
+	var marquezId interface{}
+	marquez := artist_t{Name: `Gabriel GarcĂ­a MĂĄrquez`}
+	if marquezId, err = artist.Append(marquez); err != nil {
+		t.Fatalf(err.Error())
+	}
+
+	// Adding some publications.
+	publication.Append(publication_t{
+		Title:    `Tonari no Totoro`,
+		AuthorId: miyazakiId.(int64),
+	})
+
+	publication.Append(publication_t{
+		Title:    `Howl's Moving Castle`,
+		AuthorId: miyazakiId.(int64),
+	})
+
+	publication.Append(publication_t{
+		Title:    `Ponyo`,
+		AuthorId: miyazakiId.(int64),
+	})
+
+	publication.Append(publication_t{
+		Title:    `Memoria de mis Putas Tristes`,
+		AuthorId: marquezId.(int64),
+	})
+
+	publication.Append(publication_t{
+		Title:    `El Coronel no tiene quien le escriba`,
+		AuthorId: marquezId.(int64),
+	})
+
+	publication.Append(publication_t{
+		Title:    `El Amor en los tiempos del CĂłlera`,
+		AuthorId: marquezId.(int64),
+	})
+
+	publication.Append(publication_t{
+		Title:    `I, Robot`,
+		AuthorId: asimovId.(int64),
+	})
 
+	var foundationId interface{}
+	foundationId, err = publication.Append(publication_t{
+		Title:    `Foundation`,
+		AuthorId: asimovId.(int64),
+	})
 	if err != nil {
 		t.Fatalf(err.Error())
 	}
+
+	publication.Append(publication_t{
+		Title:    `The Robots of Dawn`,
+		AuthorId: asimovId.(int64),
+	})
+
+	// Adding reviews for foundation.
+	review.Append(review_t{
+		PublicationId: foundationId.(int64),
+		Name:          "John Doe",
+		Comments:      "I love The Foundation series.",
+		Created:       time.Now(),
+	})
+
+	review.Append(review_t{
+		PublicationId: foundationId.(int64),
+		Name:          "Edr Pls",
+		Comments:      "The Foundation series made me fall in love with Isaac Asimov.",
+		Created:       time.Now(),
+	})
+
+	/*
+		// TODO: Not supported by QL.
+
+		// Exec'ing a raw query.
+		var artistPublication db.Collection
+		if artistPublication, err = sess.Collection(`artist AS a, publication AS p`); err != nil {
+			t.Fatalf(err.Error())
+		}
+
+		res := artistPublication.Find(
+			db.Raw{`a.id() = p.author_id`},
+		).Select(
+			"p.id() as id",
+			"p.title as publication_title",
+			"a.name AS artist_name",
+		)
+
+		type artistPublication_t struct {
+			Id               int64  `db:"id"`
+			PublicationTitle string `db:"publication_title"`
+			ArtistName       string `db:"artist_name"`
+		}
+
+		all := []artistPublication_t{}
+
+		if err = res.All(&all); err != nil {
+			t.Fatalf(err.Error())
+		}
+
+		if len(all) != 9 {
+			t.Fatalf("Expecting some rows.")
+		}
+	*/
+
 }
 
 /*
-// This test tries to add many different datatypes to a single row in a
-// collection, then it tries to get the stored datatypes and check if the
-// stored and the original values match.
+// TODO: Not supported by QL.
+
+// Attempts to add many different datatypes to a single row in a collection,
+// then it tries to get the stored datatypes and check if the stored and the
+// original values match.
 func TestDataTypes(t *testing.T) {
 	var res db.Result
+	var sess db.Database
+	var dataTypes db.Collection
+	var err error
+	var id interface{}
+	var exists uint64
 
-	// Opening database.
-	sess, err := db.Open(wrapperName, settings)
-
-	if err != nil {
+	if sess, err = db.Open(Driver, settings); err != nil {
 		t.Fatalf(err.Error())
 	}
 
-	// We should close the database when it's no longer in use.
 	defer sess.Close()
 
 	// Getting a pointer to the "data_types" collection.
-	dataTypes, err := sess.Collection("data_types")
-	dataTypes.Truncate()
+	if dataTypes, err = sess.Collection("data_types"); err != nil {
+		t.Fatalf(err.Error())
+	}
 
-	// Appending our test subject.
-	id, err := dataTypes.Append(testValues)
+	// Removing all data.
+	if err = dataTypes.Truncate(); err != nil {
+		t.Fatalf(err.Error())
+	}
 
-	if err != nil {
+	// Appending our test subject.
+	if id, err = dataTypes.Append(testValues); err != nil {
 		t.Fatalf(err.Error())
 	}
 
-	// Trying to get the same subject we added.
+	// Defining our set.
 	res = dataTypes.Find(db.Cond{"id": id})
 
-	exists, err := res.Count()
-
-	if err != nil {
+	if exists, err = res.Count(); err != nil {
 		t.Fatalf(err.Error())
 	}
 
 	if exists == 0 {
-		t.Errorf("Expecting an item.")
+		t.Fatalf("Expecting an item.")
 	}
 
 	// Trying to dump the subject into an empty structure of the same type.
 	var item testValuesStruct
+
 	res.One(&item)
 
 	// The original value and the test subject must match.
 	if reflect.DeepEqual(item, testValues) == false {
-		t.Errorf("Struct is different.")
+		t.Fatalf("Struct is different.")
 	}
 }
 */
@@ -637,36 +821,40 @@ func TestDisableDebug(t *testing.T) {
 	os.Setenv(db.EnvEnableDebug, "")
 }
 
+/*
+// TODO: Unsupported by QL
 // Benchmarking raw database/sql.
-func BenchmarkAppendRaw(b *testing.B) {
-	sess, err := db.Open(wrapperName, settings)
+func BenchmarkAppendRawSQL(b *testing.B) {
+	var err error
+	var sess db.Database
 
-	if err != nil {
+	if sess, err = db.Open(Driver, settings); err != nil {
 		b.Fatalf(err.Error())
 	}
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	artist.Truncate()
-
 	driver := sess.Driver().(*sql.DB)
 
+	if _, err = driver.Exec("TRUNCATE TABLE artist"); err != nil {
+		b.Fatalf(err.Error())
+	}
+
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		_, err := driver.Exec(`INSERT INTO artist (name) VALUES('Hayao Miyazaki')`)
-		if err != nil {
+		if _, err = driver.Exec("INSERT INTO artist (name) VALUES('Hayao Miyazaki')"); err != nil {
 			b.Fatalf(err.Error())
 		}
 	}
 }
+*/
 
 // Benchmarking Append().
 //
 // Contributed by wei2912
 // See: https://github.com/gosexy/db/issues/20#issuecomment-20097801
-func BenchmarkAppendDbItem(b *testing.B) {
-	sess, err := db.Open(wrapperName, settings)
+func BenchmarkAppendUpper(b *testing.B) {
+	sess, err := db.Open(Driver, settings)
 
 	if err != nil {
 		b.Fatalf(err.Error())
@@ -677,68 +865,132 @@ func BenchmarkAppendDbItem(b *testing.B) {
 	artist, err := sess.Collection("artist")
 	artist.Truncate()
 
+	item := struct {
+		Name string `db:"name"`
+	}{"Hayao Miyazaki"}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if _, err = artist.Append(item); err != nil {
+			b.Fatalf(err.Error())
+		}
+	}
+}
+
+/*
+// TODO: QL still has some issues here.
+
+// Benchmarking raw database/sql.
+func BenchmarkAppendTxRawSQL(b *testing.B) {
+	var err error
+	var sess db.Database
+	var tx *sql.Tx
+
+	if sess, err = db.Open(Driver, settings); err != nil {
+		b.Fatalf(err.Error())
+	}
+
+	defer sess.Close()
+
+	driver := sess.Driver().(*sql.DB)
+
+	if tx, err = driver.Begin(); err != nil {
+		b.Fatalf(err.Error())
+	}
+
+	if _, err = tx.Exec("TRUNCATE TABLE artist"); err != nil {
+		b.Fatalf(err.Error())
+	}
+
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		_, err = artist.Append(map[string]string{"name": "Leonardo DaVinci"})
-		if err != nil {
+		if _, err = tx.Exec("INSERT INTO artist (name) VALUES('Hayao Miyazaki')"); err != nil {
 			b.Fatalf(err.Error())
 		}
 	}
+
+	if err = tx.Commit(); err != nil {
+		b.Fatalf(err.Error())
+	}
 }
 
 // Benchmarking Append() with transactions.
-//
-// Contributed by wei2912
-// See: https://github.com/gosexy/db/issues/20#issuecomment-20167939
-// Applying the BEGIN and END transaction optimizations.
-func BenchmarkAppendDbItem_Transaction(b *testing.B) {
-	sess, err := db.Open(wrapperName, settings)
+func BenchmarkAppendTxUpper(b *testing.B) {
+	var sess db.Database
+	var err error
 
-	if err != nil {
+	if sess, err = db.Open(Driver, settings); err != nil {
 		b.Fatalf(err.Error())
 	}
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	artist.Truncate()
+	var tx db.Tx
+	if tx, err = sess.Transaction(); err != nil {
+		b.Fatalf(err.Error())
+	}
 
-	err = sess.Begin()
-	if err != nil {
+	var artist db.Collection
+	if artist, err = tx.Collection("artist"); err != nil {
 		b.Fatalf(err.Error())
 	}
 
+	if err = artist.Truncate(); err != nil {
+		b.Fatalf(err.Error())
+	}
+
+	item := struct {
+		Name string `db:"name"`
+	}{"Hayao Miyazaki"}
+
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		_, err = artist.Append(map[string]string{"name": "Isaac Asimov"})
-		if err != nil {
+		if _, err = artist.Append(item); err != nil {
 			b.Fatalf(err.Error())
 		}
 	}
 
-	err = sess.End()
-	if err != nil {
+	if err = tx.Commit(); err != nil {
 		b.Fatalf(err.Error())
 	}
 }
 
-// Benchmarking Append with a struct.
-func BenchmarkAppendStruct(b *testing.B) {
-	sess, err := db.Open(wrapperName, settings)
+// Benchmarking Append() with map.
+func BenchmarkAppendTxUpperMap(b *testing.B) {
+	var sess db.Database
+	var err error
 
-	if err != nil {
+	if sess, err = db.Open(Driver, settings); err != nil {
 		b.Fatalf(err.Error())
 	}
 
 	defer sess.Close()
 
-	artist, err := sess.Collection("artist")
-	artist.Truncate()
+	var tx db.Tx
+	if tx, err = sess.Transaction(); err != nil {
+		b.Fatalf(err.Error())
+	}
+
+	var artist db.Collection
+	if artist, err = tx.Collection("artist"); err != nil {
+		b.Fatalf(err.Error())
+	}
+
+	if err = artist.Truncate(); err != nil {
+		b.Fatalf(err.Error())
+	}
+
+	item := map[string]string{"name": "Hayao Miyazaki"}
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		_, err = artist.Append(struct{ Name string }{"John Lennon"})
-		if err != nil {
+		if _, err = artist.Append(item); err != nil {
 			b.Fatalf(err.Error())
 		}
 	}
+
+	if err = tx.Commit(); err != nil {
+		b.Fatalf(err.Error())
+	}
 }
+*/
diff --git a/ql/layout.go b/ql/layout.go
new file mode 100644
index 0000000000000000000000000000000000000000..15f9a44f8c0e0b2d427671c232e4c1c5d53dc428
--- /dev/null
+++ b/ql/layout.go
@@ -0,0 +1,124 @@
+// Copyright (c) 2012-2014 JosĂŠ Carlos Nieto, https://menteslibres.net/xiam
+//
+// 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 ql
+
+const (
+	qlColumnSeparator     = `.`
+	qlIdentifierSeparator = `, `
+	qlIdentifierQuote     = `{{.Raw}}`
+	qlValueSeparator      = `, `
+	qlValueQuote          = `"{{.}}"`
+	qlAndKeyword          = `&&`
+	qlOrKeyword           = `||`
+	qlNotKeyword          = `!=`
+	qlDescKeyword         = `DESC`
+	qlAscKeyword          = `ASC`
+	qlDefaultOperator     = `==`
+	qlClauseGroup         = `({{.}})`
+	qlClauseOperator      = ` {{.}} `
+	qlColumnValue         = `{{.Column}} {{.Operator}} {{.Value}}`
+	qlTableAliasLayout    = `{{.Name}}{{if .Alias}} AS {{.Alias}}{{end}}`
+	qlColumnAliasLayout   = `{{.Name}}{{if .Alias}} AS {{.Alias}}{{end}}`
+	qlSortByColumnLayout  = `{{.Column}} {{.Sort}}`
+
+	qlOrderByLayout = `
+		{{if .SortColumns}}
+			ORDER BY {{.SortColumns}}
+		{{end}}
+	`
+
+	qlWhereLayout = `
+		{{if .Conds}}
+			WHERE {{.Conds}}
+		{{end}}
+	`
+
+	qlSelectLayout = `
+		SELECT
+
+			{{if .Columns}}
+				{{.Columns}}
+			{{else}}
+				*
+			{{end}}
+
+			FROM {{.Table}}
+
+			{{.Where}}
+
+			{{.OrderBy}}
+
+			{{if .Limit}}
+				LIMIT {{.Limit}}
+			{{end}}
+
+			{{if .Offset}}
+				OFFSET {{.Offset}}
+			{{end}}
+	`
+	qlDeleteLayout = `
+		DELETE
+			FROM {{.Table}}
+			{{.Where}}
+	`
+	qlUpdateLayout = `
+		UPDATE
+			{{.Table}}
+		SET {{.ColumnValues}}
+			{{ .Where }}
+	`
+
+	qlSelectCountLayout = `
+		SELECT
+			count(1) AS total
+		FROM {{.Table}}
+			{{.Where}}
+
+			{{if .Limit}}
+				LIMIT {{.Limit}}
+			{{end}}
+
+			{{if .Offset}}
+				OFFSET {{.Offset}}
+			{{end}}
+	`
+
+	qlInsertLayout = `
+		INSERT INTO {{.Table}}
+			({{.Columns}})
+		VALUES
+			({{.Values}})
+		{{.Extra}}
+	`
+
+	qlTruncateLayout = `
+		TRUNCATE TABLE {{.Table}}
+	`
+
+	qlDropDatabaseLayout = `
+		DROP DATABASE {{.Database}}
+	`
+
+	qlDropTableLayout = `
+		DROP TABLE {{.Table}}
+	`
+)
diff --git a/ql/result.go b/ql/result.go
index 5ee594c26fb2190459c315cb56a90123fe756fdd..bcdfb3c4b4867b8371a1391c65acb800e7051a0e 100644
--- a/ql/result.go
+++ b/ql/result.go
@@ -1,46 +1,47 @@
-/*
-  Copyright (c) 2014 JosĂŠ Carlos Nieto, https://menteslibres.net/xiam
-
-  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.
-*/
+// Copyright (c) 2012-2014 JosĂŠ Carlos Nieto, https://menteslibres.net/xiam
+//
+// 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 ql
 
 import (
 	"database/sql"
-	"fmt"
 	"strings"
 	"upper.io/db"
-	"upper.io/db/util/sqlutil"
+	"upper.io/db/util/sqlgen"
 )
 
-type counter struct {
-	Total uint64 `field:"total"`
+type counter_t struct {
+	Total uint64 `db:"total"`
 }
 
 type Result struct {
-	table       *Table
-	queryChunks *sqlutil.QueryChunks
-	// This is the main query cursor. It starts as a nil value.
-	cursor *sql.Rows
-	t      *t
+	table     *Table
+	cursor    *sql.Rows // This is the main query cursor. It starts as a nil value.
+	limit     sqlgen.Limit
+	offset    sqlgen.Offset
+	columns   sqlgen.Columns
+	where     sqlgen.Where
+	orderBy   sqlgen.OrderBy
+	arguments []interface{}
+	t         *t
 }
 
 // Executes a SELECT statement that can feed Next(), All() or One().
@@ -48,38 +49,28 @@ func (self *Result) setCursor() error {
 	var err error
 	// We need a cursor, if the cursor does not exists yet then we create one.
 	if self.cursor == nil {
-		self.cursor, err = self.table.source.doQuery(
-			// Mandatory SQL.
-			fmt.Sprintf(
-				`SELECT %s FROM %s WHERE %s`,
-				// Fields.
-				strings.Join(self.queryChunks.Fields, `, `),
-				// Table name
-				self.table.Name(),
-				// Conditions
-				self.queryChunks.Conditions,
-			),
-			// Arguments
-			self.queryChunks.Arguments,
-			// Optional SQL
-			self.queryChunks.Sort,
-			self.queryChunks.Limit,
-			self.queryChunks.Offset,
-		)
+		self.cursor, err = self.table.source.doQuery(sqlgen.Statement{
+			Type:    sqlgen.SqlSelect,
+			Table:   sqlgen.Table{self.table.Name()},
+			Columns: self.columns,
+			Limit:   self.limit,
+			Offset:  self.offset,
+			Where:   self.where,
+		}, self.arguments...)
 	}
 	return err
 }
 
 // Determines the maximum limit of results to be returned.
 func (self *Result) Limit(n uint) db.Result {
-	self.queryChunks.Limit = fmt.Sprintf(`LIMIT %d`, n)
+	self.limit = sqlgen.Limit(n)
 	return self
 }
 
 // Determines how many documents will be skipped before starting to grab
 // results.
 func (self *Result) Skip(n uint) db.Result {
-	self.queryChunks.Offset = fmt.Sprintf(`OFFSET %d`, n)
+	self.offset = sqlgen.Offset(n)
 	return self
 }
 
@@ -87,24 +78,43 @@ func (self *Result) Skip(n uint) db.Result {
 // prefixed by - (minus) which means descending order, ascending order would be
 // used otherwise.
 func (self *Result) Sort(fields ...string) db.Result {
-	sort := make([]string, 0, len(fields))
+
+	sortColumns := make(sqlgen.SortColumns, 0, len(fields))
 
 	for _, field := range fields {
-		if strings.HasPrefix(field, `-`) == true {
-			sort = append(sort, field[1:]+` DESC`)
+		var sort sqlgen.SortColumn
+
+		if strings.HasPrefix(field, `-`) {
+			// Explicit descending order.
+			sort = sqlgen.SortColumn{
+				sqlgen.Column{field[1:]},
+				sqlgen.SqlSortDesc,
+			}
 		} else {
-			sort = append(sort, field+` ASC`)
+			// Ascending order.
+			sort = sqlgen.SortColumn{
+				sqlgen.Column{field},
+				sqlgen.SqlSortAsc,
+			}
 		}
+
+		sortColumns = append(sortColumns, sort)
 	}
 
-	self.queryChunks.Sort = `ORDER BY ` + strings.Join(sort, `, `)
+	self.orderBy.SortColumns = sortColumns
 
 	return self
 }
 
 // Retrieves only the given fields.
 func (self *Result) Select(fields ...string) db.Result {
-	self.queryChunks.Fields = fields
+	self.columns = make(sqlgen.Columns, 0, len(fields))
+
+	l := len(fields)
+	for i := 0; i < l; i++ {
+		self.columns = append(self.columns, sqlgen.Column{fields[i]})
+	}
+
 	return self
 }
 
@@ -132,7 +142,9 @@ func (self *Result) All(dst interface{}) error {
 }
 
 // Fetches only one result from the resultset.
-func (self *Result) One(dst interface{}) (err error) {
+func (self *Result) One(dst interface{}) error {
+	var err error
+
 	if self.cursor != nil {
 		return db.ErrQueryIsPending
 	}
@@ -146,34 +158,34 @@ func (self *Result) One(dst interface{}) (err error) {
 
 // Fetches the next result from the resultset.
 func (self *Result) Next(dst interface{}) error {
+
 	var err error
 
 	// Current cursor.
-	if err = self.setCursor(); err != nil {
+	err = self.setCursor()
+
+	if err != nil {
 		self.Close()
-		return err
 	}
 
 	// Fetching the next result from the cursor.
-	if err = self.t.qlFetchRow(dst, self.cursor); err != nil {
+	err = self.t.qlFetchRow(dst, self.cursor)
+
+	if err != nil {
 		self.Close()
-		return err
 	}
 
-	return nil
+	return err
 }
 
 // Removes the matching items from the collection.
 func (self *Result) Remove() error {
 	var err error
-	_, err = self.table.source.doExec(
-		fmt.Sprintf(
-			`DELETE FROM %s WHERE %s`,
-			self.table.Name(),
-			self.queryChunks.Conditions,
-		),
-		self.queryChunks.Arguments,
-	)
+	_, err = self.table.source.doExec(sqlgen.Statement{
+		Type:  sqlgen.SqlDelete,
+		Table: sqlgen.Table{self.table.Name()},
+		Where: self.where,
+	}, self.arguments...)
 	return err
 
 }
@@ -182,32 +194,21 @@ func (self *Result) Remove() error {
 // struct.
 func (self *Result) Update(values interface{}) error {
 
-	ff, vv, err := self.table.FieldValues(values, mirrorFn)
-
-	if err != nil {
-		return err
-	}
+	ff, vv, err := self.table.FieldValues(values, toInternal)
 
 	total := len(ff)
 
-	updateFields := make([]string, total)
-	updateArgs := make([]interface{}, total)
+	cvs := make(sqlgen.ColumnValues, 0, total)
 
 	for i := 0; i < total; i++ {
-		updateFields[i] = fmt.Sprintf(`%s = ?`, ff[i])
-		updateArgs[i] = vv[i]
+		cvs = append(cvs, sqlgen.ColumnValue{sqlgen.Column{ff[i]}, "=", sqlPlaceholder})
 	}
 
-	_, err = self.table.source.doExec(
-		fmt.Sprintf(
-			`UPDATE %s %s WHERE %s`,
-			self.table.Name(),
-			strings.Join(updateFields, `, `),
-			self.queryChunks.Conditions,
-		),
-		updateArgs,
-		self.queryChunks.Arguments,
-	)
+	_, err = self.table.source.doExec(sqlgen.Statement{
+		Type:         sqlgen.SqlUpdate,
+		Table:        sqlgen.Table{self.table.Name()},
+		ColumnValues: cvs,
+	}, vv...)
 
 	return err
 }
@@ -225,23 +226,22 @@ func (self *Result) Close() error {
 // Counts matching elements.
 func (self *Result) Count() (uint64, error) {
 
-	rows, err := self.table.source.doQuery(
-		fmt.Sprintf(
-			`SELECT count(1) AS total FROM %s WHERE %s`,
-			self.table.Name(),
-			self.queryChunks.Conditions,
-		),
-		self.queryChunks.Arguments,
-	)
+	rows, err := self.table.source.doQuery(sqlgen.Statement{
+		Type:   sqlgen.SqlSelectCount,
+		Table:  sqlgen.Table{self.table.Name()},
+		Where:  self.where,
+		Limit:  self.limit,
+		Offset: self.offset,
+	}, self.arguments...)
 
 	if err != nil {
 		return 0, err
 	}
 
-	dst := counter{}
-	self.t.FetchRow(&dst, rows)
+	defer rows.Close()
 
-	rows.Close()
+	dst := counter_t{}
+	self.t.FetchRow(&dst, rows)
 
 	return dst.Total, nil
 }
diff --git a/ql/tx.go b/ql/tx.go
new file mode 100644
index 0000000000000000000000000000000000000000..3c6b5bedcde5f7c28ca80ff616ee3e9ce627852a
--- /dev/null
+++ b/ql/tx.go
@@ -0,0 +1,34 @@
+// Copyright (c) 2012-2014 JosĂŠ Carlos Nieto, https://menteslibres.net/xiam
+//
+// 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 ql
+
+type Tx struct {
+	*Source
+}
+
+func (self *Tx) Commit() error {
+	return self.Source.tx.Commit()
+}
+
+func (self *Tx) Rollback() error {
+	return self.Source.tx.Rollback()
+}