diff --git a/postgresql/collection.go b/postgresql/collection.go
index 5af922023ef99079ce82b7453d4a48dc4d059f26..3f71764f10c449e4786ce484af03795cbc713bc5 100644
--- a/postgresql/collection.go
+++ b/postgresql/collection.go
@@ -30,27 +30,20 @@ import (
 	"upper.io/db"
 	"upper.io/db/util/sqlgen"
 	"upper.io/db/util/sqlutil"
+	"upper.io/db/util/sqlutil/result"
 )
 
-const defaultOperator = `=`
-
 type table struct {
 	sqlutil.T
-	source     *source
+	*source
 	primaryKey string
 	names      []string
 }
 
+// Find creates a result set with the given conditions.
 func (t *table) Find(terms ...interface{}) db.Result {
 	where, arguments := sqlutil.ToWhereWithArguments(terms)
-
-	result := &result{
-		table:     t,
-		where:     where,
-		arguments: arguments,
-	}
-
-	return result
+	return result.NewResult(t, where, arguments)
 }
 
 func (t *table) tableN(i int) string {
@@ -63,9 +56,9 @@ func (t *table) tableN(i int) string {
 	return ""
 }
 
-// Deletes all the rows within the collection.
+// Truncate deletes all rows within the table.
 func (t *table) Truncate() error {
-	_, err := t.source.doExec(sqlgen.Statement{
+	_, err := t.source.Exec(sqlgen.Statement{
 		Type:  sqlgen.Truncate,
 		Table: sqlgen.TableWithName(t.tableN(0)),
 	})
@@ -77,7 +70,7 @@ func (t *table) Truncate() error {
 	return nil
 }
 
-// Appends an item (map or struct) into the collection.
+// Append inserts an item (map or struct) into the collection.
 func (t *table) Append(item interface{}) (interface{}, error) {
 
 	cols, vals, err := t.FieldValues(item)
@@ -134,7 +127,7 @@ func (t *table) Append(item interface{}) (interface{}, error) {
 	if len(pKey) == 0 {
 		var res sql.Result
 
-		if res, err = t.source.doExec(stmt, arguments...); err != nil {
+		if res, err = t.source.Exec(stmt, arguments...); err != nil {
 			return nil, err
 		}
 
@@ -149,7 +142,7 @@ func (t *table) Append(item interface{}) (interface{}, error) {
 
 	// A primary key was found.
 	stmt.Extra = sqlgen.Extra(fmt.Sprintf(`RETURNING "%s"`, strings.Join(pKey, `", "`)))
-	if rows, err = t.source.doQuery(stmt, arguments...); err != nil {
+	if rows, err = t.source.Query(stmt, arguments...); err != nil {
 		return nil, err
 	}
 
@@ -196,7 +189,7 @@ func (t *table) Append(item interface{}) (interface{}, error) {
 	return keyMap, nil
 }
 
-// Returns true if the collection exists.
+// Exists returns true if the collection exists.
 func (t *table) Exists() bool {
 	if err := t.source.tableExists(t.names...); err != nil {
 		return false
@@ -204,6 +197,7 @@ func (t *table) Exists() bool {
 	return true
 }
 
+// Name returns the name of the table or tables that form the collection.
 func (t *table) Name() string {
 	return strings.Join(t.names, `, `)
 }
diff --git a/postgresql/connection.go b/postgresql/connection.go
index b1d6ab909f1a42a678e13e50b8084ce53bbfeb3f..451383ce96af9a707eb03d9e354405127da4aeca 100644
--- a/postgresql/connection.go
+++ b/postgresql/connection.go
@@ -37,8 +37,8 @@ type scanner struct {
 	i int
 }
 
-// Next returns the next rune.
-// It returns 0, false if the end of the text has been reached.
+// Next returns the next rune.  It returns 0, false if the end of the text has
+// been reached.
 func (s *scanner) Next() (rune, bool) {
 	if s.i >= len(s.s) {
 		return 0, false
@@ -48,8 +48,8 @@ func (s *scanner) Next() (rune, bool) {
 	return r, true
 }
 
-// SkipSpaces returns the next non-whitespace rune.
-// It returns 0, false if the end of the text has been reached.
+// SkipSpaces returns the next non-whitespace rune.  It returns 0, false if the
+// end of the text has been reached.
 func (s *scanner) SkipSpaces() (rune, bool) {
 	r, ok := s.Next()
 	for unicode.IsSpace(r) && ok {
diff --git a/postgresql/database.go b/postgresql/database.go
index 401dd31b6ab448a053728bf2b48fa3dddd8dbf5a..f4d51bc185e1a414a438cc3a6d7640e1a46344e7 100644
--- a/postgresql/database.go
+++ b/postgresql/database.go
@@ -30,34 +30,30 @@ import (
 	"time"
 
 	"github.com/jmoiron/sqlx"
-	_ "github.com/lib/pq" // PostgreSQL driver.
-	"upper.io/cache"
+	_ "github.com/lib/pq" // Go PostgreSQL driver.
 	"upper.io/db"
 	"upper.io/db/util/schema"
 	"upper.io/db/util/sqlgen"
 	"upper.io/db/util/sqlutil"
-)
-
-const (
-	// Adapter is the public name of the adapter.
-	Adapter = `postgresql`
+	"upper.io/db/util/sqlutil/tx"
 )
 
 var (
-	// Query template
-	template *sqlgen.Template
-
-	// Query statement placeholder
 	sqlPlaceholder = sqlgen.RawValue(`?`)
 )
 
 type source struct {
 	connURL db.ConnectionURL
 	session *sqlx.DB
-	tx      *tx
+	tx      *sqltx.Tx
 	schema  *schema.DatabaseSchema
 }
 
+type tx struct {
+	*sqltx.Tx
+	*source
+}
+
 type columnSchemaT struct {
 	Name     string `db:"column_name"`
 	DataType string `db:"data_type"`
@@ -77,12 +73,12 @@ func debugLog(query string, args []interface{}, err error, start int64, end int6
 	}
 }
 
-// Returns the underlying *sqlx.DB instance.
+// Driver returns the underlying *sqlx.DB instance.
 func (s *source) Driver() interface{} {
 	return s.session
 }
 
-// Attempts to connect to a database using the stored settings.
+// Open attempts to connect to the PostgreSQL server using the stored settings.
 func (s *source) Open() error {
 	var err error
 
@@ -90,8 +86,6 @@ func (s *source) Open() error {
 	// condition checks for that type and provides backwards compatibility.
 	if settings, ok := s.connURL.(db.Settings); ok {
 
-		// User is providing a db.Settings struct, let's translate it into a
-		// ConnectionURL{}.
 		conn := ConnectionURL{
 			User:     settings.User,
 			Password: settings.Password,
@@ -102,7 +96,6 @@ func (s *source) Open() error {
 			},
 		}
 
-		// Replace original s.connURL
 		s.connURL = conn
 	}
 
@@ -119,6 +112,7 @@ func (s *source) Open() error {
 	return nil
 }
 
+// Clone returns a cloned db.Database session.
 func (s *source) Clone() (db.Database, error) {
 	return s.clone()
 }
@@ -134,13 +128,13 @@ func (s *source) clone() (*source, error) {
 	return src, nil
 }
 
-// Ping verifies a connection to the database is still alive,
-// establishing a connection if necessary.
+// Ping checks whether a connection to the database is still alive by pinging
+// it, establishing a connection if necessary.
 func (s *source) Ping() error {
 	return s.session.Ping()
 }
 
-// Closes the current database session.
+// Close terminates the current database session.
 func (s *source) Close() error {
 	if s.session != nil {
 		return s.session.Close()
@@ -148,7 +142,7 @@ func (s *source) Close() error {
 	return nil
 }
 
-// Returns a collection instance by name.
+// Collection returns a table by name.
 func (s *source) Collection(names ...string) (db.Collection, error) {
 	var err error
 
@@ -157,7 +151,7 @@ func (s *source) Collection(names ...string) (db.Collection, error) {
 	}
 
 	if s.tx != nil {
-		if s.tx.done {
+		if s.tx.Done() {
 			return nil, sql.ErrTxDone
 		}
 	}
@@ -188,8 +182,7 @@ func (s *source) Collection(names ...string) (db.Collection, error) {
 	return col, nil
 }
 
-// Collections() Returns a list of non-system tables/collections contained
-// within the currently active database.
+// Collections returns a list of non-system tables within the database.
 func (s *source) Collections() (collections []string, err error) {
 
 	tablesInSchema := len(s.schema.Tables)
@@ -220,7 +213,7 @@ func (s *source) Collections() (collections []string, err error) {
 
 	// Executing statement.
 	var rows *sqlx.Rows
-	if rows, err = s.doQuery(stmt); err != nil {
+	if rows, err = s.Query(stmt); err != nil {
 		return nil, err
 	}
 
@@ -246,7 +239,7 @@ func (s *source) Collections() (collections []string, err error) {
 	return collections, nil
 }
 
-// Changes the active database.
+// Use changes the active database.
 func (s *source) Use(database string) (err error) {
 	var conn ConnectionURL
 
@@ -261,26 +254,28 @@ func (s *source) Use(database string) (err error) {
 	return s.Open()
 }
 
-// Drops the currently active database.
+// Drop removes all tables within the current database.
 func (s *source) Drop() error {
-	_, err := s.doQuery(sqlgen.Statement{
+	_, err := s.Query(sqlgen.Statement{
 		Type:     sqlgen.DropDatabase,
 		Database: sqlgen.DatabaseWithName(s.schema.Name),
 	})
 	return err
 }
 
-// Stores database settings.
+// Setup stores database settings.
 func (s *source) Setup(connURL db.ConnectionURL) error {
 	s.connURL = connURL
 	return s.Open()
 }
 
-// Returns the string name of the database.
+// Name returns the name of the database.
 func (s *source) Name() string {
 	return s.schema.Name
 }
 
+// Transaction starts a transaction block and returns a db.Tx struct that can
+// be used to issue transactional queries.
 func (s *source) Transaction() (db.Tx, error) {
 	var err error
 	var clone *source
@@ -294,14 +289,12 @@ func (s *source) Transaction() (db.Tx, error) {
 		return nil, err
 	}
 
-	tx := &tx{source: clone, sqlTx: sqlTx}
-
-	clone.tx = tx
+	clone.tx = sqltx.New(sqlTx)
 
-	return tx, nil
+	return tx{Tx: clone.tx, source: clone}, nil
 }
 
-func (s *source) doExec(stmt sqlgen.Statement, args ...interface{}) (sql.Result, error) {
+func (s *source) Exec(stmt sqlgen.Statement, args ...interface{}) (sql.Result, error) {
 	var query string
 	var res sql.Result
 	var err error
@@ -326,7 +319,7 @@ func (s *source) doExec(stmt sqlgen.Statement, args ...interface{}) (sql.Result,
 	}
 
 	if s.tx != nil {
-		res, err = s.tx.sqlTx.Exec(query, args...)
+		res, err = s.tx.Exec(query, args...)
 	} else {
 		res, err = s.session.Exec(query, args...)
 	}
@@ -334,7 +327,7 @@ func (s *source) doExec(stmt sqlgen.Statement, args ...interface{}) (sql.Result,
 	return res, err
 }
 
-func (s *source) doQuery(stmt sqlgen.Statement, args ...interface{}) (*sqlx.Rows, error) {
+func (s *source) Query(stmt sqlgen.Statement, args ...interface{}) (*sqlx.Rows, error) {
 	var rows *sqlx.Rows
 	var query string
 	var err error
@@ -359,7 +352,7 @@ func (s *source) doQuery(stmt sqlgen.Statement, args ...interface{}) (*sqlx.Rows
 	}
 
 	if s.tx != nil {
-		rows, err = s.tx.sqlTx.Queryx(query, args...)
+		rows, err = s.tx.Queryx(query, args...)
 	} else {
 		rows, err = s.session.Queryx(query, args...)
 	}
@@ -367,7 +360,7 @@ func (s *source) doQuery(stmt sqlgen.Statement, args ...interface{}) (*sqlx.Rows
 	return rows, err
 }
 
-func (s *source) doQueryRow(stmt sqlgen.Statement, args ...interface{}) (*sqlx.Row, error) {
+func (s *source) QueryRow(stmt sqlgen.Statement, args ...interface{}) (*sqlx.Row, error) {
 	var query string
 	var row *sqlx.Row
 	var err error
@@ -392,7 +385,7 @@ func (s *source) doQueryRow(stmt sqlgen.Statement, args ...interface{}) (*sqlx.R
 	}
 
 	if s.tx != nil {
-		row = s.tx.sqlTx.QueryRowx(query, args...)
+		row = s.tx.QueryRowx(query, args...)
 	} else {
 		row = s.session.QueryRowx(query, args...)
 	}
@@ -415,7 +408,7 @@ func (s *source) populateSchema() (err error) {
 
 	var row *sqlx.Row
 
-	if row, err = s.doQueryRow(stmt); err != nil {
+	if row, err = s.QueryRow(stmt); err != nil {
 		return err
 	}
 
@@ -470,7 +463,7 @@ func (s *source) tableExists(names ...string) error {
 			),
 		}
 
-		if rows, err = s.doQuery(stmt, s.schema.Name, names[i]); err != nil {
+		if rows, err = s.Query(stmt, s.schema.Name, names[i]); err != nil {
 			return db.ErrCollectionDoesNotExist
 		}
 
@@ -517,7 +510,7 @@ func (s *source) tableColumns(tableName string) ([]string, error) {
 	var rows *sqlx.Rows
 	var err error
 
-	if rows, err = s.doQuery(stmt, s.schema.Name, tableName); err != nil {
+	if rows, err = s.Query(stmt, s.schema.Name, tableName); err != nil {
 		return nil, err
 	}
 
@@ -572,7 +565,7 @@ func (s *source) getPrimaryKey(tableName string) ([]string, error) {
 	var rows *sqlx.Rows
 	var err error
 
-	if rows, err = s.doQuery(stmt); err != nil {
+	if rows, err = s.Query(stmt); err != nil {
 		return nil, err
 	}
 
@@ -588,39 +581,3 @@ func (s *source) getPrimaryKey(tableName string) ([]string, error) {
 
 	return tableSchema.PrimaryKey, nil
 }
-
-func init() {
-	template = &sqlgen.Template{
-		pgsqlColumnSeparator,
-		pgsqlIdentifierSeparator,
-		pgsqlIdentifierQuote,
-		pgsqlValueSeparator,
-		pgsqlValueQuote,
-		pgsqlAndKeyword,
-		pgsqlOrKeyword,
-		pgsqlNotKeyword,
-		pgsqlDescKeyword,
-		pgsqlAscKeyword,
-		pgsqlDefaultOperator,
-		pgsqlClauseGroup,
-		pgsqlClauseOperator,
-		pgsqlColumnValue,
-		pgsqlTableAliasLayout,
-		pgsqlColumnAliasLayout,
-		pgsqlSortByColumnLayout,
-		pgsqlWhereLayout,
-		pgsqlOrderByLayout,
-		pgsqlInsertLayout,
-		pgsqlSelectLayout,
-		pgsqlUpdateLayout,
-		pgsqlDeleteLayout,
-		pgsqlTruncateLayout,
-		pgsqlDropDatabaseLayout,
-		pgsqlDropTableLayout,
-		pgsqlSelectCountLayout,
-		pgsqlGroupByLayout,
-		cache.NewCache(),
-	}
-
-	db.Register(Adapter, &source{})
-}
diff --git a/postgresql/postgresql.go b/postgresql/postgresql.go
new file mode 100644
index 0000000000000000000000000000000000000000..8aa0d45d0ef900a76c2545fcba5140c55b8863cb
--- /dev/null
+++ b/postgresql/postgresql.go
@@ -0,0 +1,74 @@
+// Copyright (c) 2012-2015 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 postgresql
+
+import (
+	"upper.io/cache"
+	"upper.io/db"
+	"upper.io/db/util/sqlgen"
+)
+
+// Adapter is the public name of the adapter.
+const Adapter = `postgresql`
+
+var (
+	_ = db.Database(&source{})
+	_ = db.Collection(&table{})
+)
+
+var template *sqlgen.Template
+
+func init() {
+	template = &sqlgen.Template{
+		ColumnSeparator:     pgsqlColumnSeparator,
+		IdentifierSeparator: pgsqlIdentifierSeparator,
+		IdentifierQuote:     pgsqlIdentifierQuote,
+		ValueSeparator:      pgsqlValueSeparator,
+		ValueQuote:          pgsqlValueQuote,
+		AndKeyword:          pgsqlAndKeyword,
+		OrKeyword:           pgsqlOrKeyword,
+		NotKeyword:          pgsqlNotKeyword,
+		DescKeyword:         pgsqlDescKeyword,
+		AscKeyword:          pgsqlAscKeyword,
+		DefaultOperator:     pgsqlDefaultOperator,
+		ClauseGroup:         pgsqlClauseGroup,
+		ClauseOperator:      pgsqlClauseOperator,
+		ColumnValue:         pgsqlColumnValue,
+		TableAliasLayout:    pgsqlTableAliasLayout,
+		ColumnAliasLayout:   pgsqlColumnAliasLayout,
+		SortByColumnLayout:  pgsqlSortByColumnLayout,
+		WhereLayout:         pgsqlWhereLayout,
+		OrderByLayout:       pgsqlOrderByLayout,
+		InsertLayout:        pgsqlInsertLayout,
+		SelectLayout:        pgsqlSelectLayout,
+		UpdateLayout:        pgsqlUpdateLayout,
+		DeleteLayout:        pgsqlDeleteLayout,
+		TruncateLayout:      pgsqlTruncateLayout,
+		DropDatabaseLayout:  pgsqlDropDatabaseLayout,
+		DropTableLayout:     pgsqlDropTableLayout,
+		CountLayout:         pgsqlSelectCountLayout,
+		GroupByLayout:       pgsqlGroupByLayout,
+		Cache:               cache.NewCache(),
+	}
+
+	db.Register(Adapter, &source{})
+}
diff --git a/postgresql/layout.go b/postgresql/template.go
similarity index 100%
rename from postgresql/layout.go
rename to postgresql/template.go
diff --git a/postgresql/result.go b/util/sqlutil/result/result.go
similarity index 83%
rename from postgresql/result.go
rename to util/sqlutil/result/result.go
index f289f229f15bdf9a51b344d5d2e4118fb29ba30d..9616c9bb9d4b5ab214440883476445c6d885dec3 100644
--- a/postgresql/result.go
+++ b/util/sqlutil/result/result.go
@@ -19,7 +19,7 @@
 // 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 postgresql
+package result
 
 import (
 	"fmt"
@@ -31,12 +31,16 @@ import (
 	"upper.io/db/util/sqlutil"
 )
 
+var (
+	sqlPlaceholder = sqlgen.RawValue(`?`)
+)
+
 type counter struct {
 	Total uint64 `db:"_t"`
 }
 
-type result struct {
-	table     *table
+type Result struct {
+	table     DataProvider
 	cursor    *sqlx.Rows // This is the main query cursor. It starts as a nil value.
 	limit     sqlgen.Limit
 	offset    sqlgen.Offset
@@ -47,12 +51,22 @@ type result struct {
 	arguments []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(p DataProvider, where sqlgen.Where, arguments []interface{}) *Result {
+	return &Result{
+		table:     p,
+		where:     where,
+		arguments: arguments,
+	}
+}
+
 // Executes a SELECT statement that can feed Next(), All() or One().
-func (r *result) setCursor() error {
+func (r *Result) setCursor() error {
 	var err error
 	// We need a cursor, if the cursor does not exists yet then we create one.
 	if r.cursor == nil {
-		r.cursor, err = r.table.source.doQuery(sqlgen.Statement{
+		r.cursor, err = r.table.Query(sqlgen.Statement{
 			Type:    sqlgen.Select,
 			Table:   sqlgen.TableWithName(r.table.Name()),
 			Columns: &r.columns,
@@ -67,27 +81,27 @@ func (r *result) setCursor() error {
 }
 
 // Sets conditions for reducing the working set.
-func (r *result) Where(terms ...interface{}) db.Result {
+func (r *Result) Where(terms ...interface{}) db.Result {
 	r.where, r.arguments = sqlutil.ToWhereWithArguments(terms)
 	return r
 }
 
 // Determines the maximum limit of results to be returned.
-func (r *result) Limit(n uint) db.Result {
+func (r *Result) Limit(n uint) db.Result {
 	r.limit = sqlgen.Limit(n)
 	return r
 }
 
 // Determines how many documents will be skipped before starting to grab
 // results.
-func (r *result) Skip(n uint) db.Result {
+func (r *Result) Skip(n uint) db.Result {
 	r.offset = sqlgen.Offset(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 {
+func (r *Result) Group(fields ...interface{}) db.Result {
 	var columns []sqlgen.Fragment
 
 	for i := range fields {
@@ -107,7 +121,7 @@ func (r *result) Group(fields ...interface{}) db.Result {
 // 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 {
+func (r *Result) Sort(fields ...interface{}) db.Result {
 
 	var sortColumns sqlgen.SortColumns
 
@@ -144,7 +158,7 @@ func (r *result) Sort(fields ...interface{}) db.Result {
 }
 
 // Retrieves only the given fields.
-func (r *result) Select(fields ...interface{}) db.Result {
+func (r *Result) Select(fields ...interface{}) db.Result {
 
 	r.columns = sqlgen.Columns{}
 
@@ -176,7 +190,7 @@ func (r *result) Select(fields ...interface{}) db.Result {
 }
 
 // Dumps all results into a pointer to an slice of structs or maps.
-func (r *result) All(dst interface{}) error {
+func (r *Result) All(dst interface{}) error {
 	var err error
 
 	if r.cursor != nil {
@@ -199,7 +213,7 @@ func (r *result) All(dst interface{}) error {
 }
 
 // Fetches only one result from the resultset.
-func (r *result) One(dst interface{}) error {
+func (r *Result) One(dst interface{}) error {
 	var err error
 
 	if r.cursor != nil {
@@ -214,7 +228,7 @@ func (r *result) One(dst interface{}) error {
 }
 
 // Fetches the next result from the resultset.
-func (r *result) Next(dst interface{}) (err error) {
+func (r *Result) Next(dst interface{}) (err error) {
 
 	if err = r.setCursor(); err != nil {
 		r.Close()
@@ -230,10 +244,10 @@ func (r *result) Next(dst interface{}) (err error) {
 }
 
 // Removes the matching items from the collection.
-func (r *result) Remove() error {
+func (r *Result) Remove() error {
 	var err error
 
-	_, err = r.table.source.doExec(sqlgen.Statement{
+	_, err = r.table.Exec(sqlgen.Statement{
 		Type:  sqlgen.Delete,
 		Table: sqlgen.TableWithName(r.table.Name()),
 		Where: &r.where,
@@ -245,7 +259,7 @@ func (r *result) Remove() error {
 
 // Updates matching items from the collection with values of the given map or
 // struct.
-func (r *result) Update(values interface{}) error {
+func (r *Result) Update(values interface{}) error {
 
 	ff, vv, err := r.table.FieldValues(values)
 	if err != nil {
@@ -260,7 +274,7 @@ func (r *result) Update(values interface{}) error {
 
 	vv = append(vv, r.arguments...)
 
-	_, err = r.table.source.doExec(sqlgen.Statement{
+	_, err = r.table.Exec(sqlgen.Statement{
 		Type:         sqlgen.Update,
 		Table:        sqlgen.TableWithName(r.table.Name()),
 		ColumnValues: cvs,
@@ -271,7 +285,7 @@ func (r *result) Update(values interface{}) error {
 }
 
 // Closes the result set.
-func (r *result) Close() (err error) {
+func (r *Result) Close() (err error) {
 	if r.cursor != nil {
 		err = r.cursor.Close()
 		r.cursor = nil
@@ -280,10 +294,10 @@ func (r *result) Close() (err error) {
 }
 
 // Counts the elements within the main conditions of the set.
-func (r *result) Count() (uint64, error) {
+func (r *Result) Count() (uint64, error) {
 	var count counter
 
-	row, err := r.table.source.doQueryRow(sqlgen.Statement{
+	row, err := r.table.QueryRow(sqlgen.Statement{
 		Type:  sqlgen.Count,
 		Table: sqlgen.TableWithName(r.table.Name()),
 		Where: &r.where,
diff --git a/util/sqlutil/result/table.go b/util/sqlutil/result/table.go
new file mode 100644
index 0000000000000000000000000000000000000000..57ec42ac1bdf8abe90ea0667e7b8177089820c8d
--- /dev/null
+++ b/util/sqlutil/result/table.go
@@ -0,0 +1,15 @@
+package result
+
+import (
+	"database/sql"
+	"github.com/jmoiron/sqlx"
+	"upper.io/db/util/sqlgen"
+)
+
+type DataProvider interface {
+	Name() string
+	Query(sqlgen.Statement, ...interface{}) (*sqlx.Rows, error)
+	QueryRow(sqlgen.Statement, ...interface{}) (*sqlx.Row, error)
+	Exec(sqlgen.Statement, ...interface{}) (sql.Result, error)
+	FieldValues(interface{}) ([]string, []interface{}, error)
+}
diff --git a/postgresql/tx.go b/util/sqlutil/tx/tx.go
similarity index 84%
rename from postgresql/tx.go
rename to util/sqlutil/tx/tx.go
index 70b979d74e3763a57941e60e13e261083236778a..533c54058f9f855dbc3004e8fad03f5f3022e0bb 100644
--- a/postgresql/tx.go
+++ b/util/sqlutil/tx/tx.go
@@ -19,26 +19,28 @@
 // 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 postgresql
+package sqltx
 
 import (
 	"github.com/jmoiron/sqlx"
 )
 
-type tx struct {
-	*source
-	sqlTx *sqlx.Tx
-	done  bool
+type Tx struct {
+	*sqlx.Tx
+	done bool
 }
 
-func (t *tx) Commit() (err error) {
-	err = t.sqlTx.Commit()
-	if err == nil {
+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
 }
-
-func (t *tx) Rollback() error {
-	return t.sqlTx.Rollback()
-}