From c806ef393132a858084882e86e3c97eb16e04d2f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Nieto?= <jose.carlos@menteslibres.net>
Date: Mon, 18 Jul 2016 20:15:56 -0500
Subject: [PATCH] Move SQL functions to the sql.go file.

---
 db.go      |  29 +-----------
 sql.go     | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 wrapper.go |  61 ++----------------------
 3 files changed, 141 insertions(+), 84 deletions(-)
 create mode 100644 sql.go

diff --git a/db.go b/db.go
index 36104d40..bb6d8f5e 100644
--- a/db.go
+++ b/db.go
@@ -395,7 +395,7 @@ type Database interface {
 	ClearCache()
 }
 
-// Tx represents transactions that can be either committed or rolled back.
+// Tx has methods for transactions that can be either committed or rolled back.
 type Tx interface {
 	// Rollback discards all the instructions on the current transaction.
 	Rollback() error
@@ -509,33 +509,6 @@ type ConnectionURL interface {
 	String() string
 }
 
-// SQLDatabase represents a Database which is capable of both creating
-// transactions and use SQL builder methods.
-type SQLDatabase interface {
-	Database
-	SQLBuilder
-
-	// NewTx returns a new session that lives within a transaction. This session
-	// is completely independent from its parent.
-	NewTx() (SQLTx, error)
-
-	// Tx creates a new transaction that is passed as context to the fn function.
-	// The fn function defines a transaction operation.  If the fn function
-	// returns nil, the transaction is commited, otherwise the transaction is
-	// rolled back.  The transaction session is closed after the function exists,
-	// regardless of the error value returned by fn.
-	Tx(fn func(sess SQLTx) error) error
-}
-
-// SQLTx represents transaction on a SQL database. Transactions can only accept
-// intructions until being commited or rolled back, they become useless
-// afterwards and are automatically closed.
-type SQLTx interface {
-	Database
-	SQLBuilder
-	Tx
-}
-
 // EnvEnableDebug can be used by adapters to determine if the user has enabled
 // debugging.
 //
diff --git a/sql.go b/sql.go
new file mode 100644
index 00000000..5e987a6d
--- /dev/null
+++ b/sql.go
@@ -0,0 +1,135 @@
+// Copyright (c) 2012-present The upper.io/db authors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+package db
+
+import (
+	"database/sql"
+	"fmt"
+	"sync"
+)
+
+var (
+	sqlAdapters   map[string]*SQLAdapterFuncMap
+	sqlAdaptersMu sync.RWMutex
+)
+
+func init() {
+	sqlAdapters = make(map[string]*SQLAdapterFuncMap)
+	adapters = make(map[string]*AdapterFuncMap)
+}
+
+// SQLCommon holds common methods for SQL databases.
+type SQLCommon interface {
+	Database
+	SQLBuilder
+}
+
+// SQLTx represents transaction on a SQL database. Transactions can only accept
+// intructions until being commited or rolled back, they become useless
+// afterwards and are automatically closed.
+type SQLTx interface {
+	SQLCommon
+	Tx
+}
+
+// SQLDatabase represents a Database which is capable of both creating
+// transactions and use SQL builder methods.
+type SQLDatabase interface {
+	SQLCommon
+
+	// NewTx returns a new session that lives within a transaction. This session
+	// is completely independent from its parent.
+	NewTx() (SQLTx, error)
+
+	// Tx creates a new transaction that is passed as context to the fn function.
+	// The fn function defines a transaction operation.  If the fn function
+	// returns nil, the transaction is commited, otherwise the transaction is
+	// rolled back.  The transaction session is closed after the function exists,
+	// regardless of the error value returned by fn.
+	Tx(fn func(sess SQLTx) error) error
+}
+
+type SQLAdapterFuncMap struct {
+	New   func(sqlDB *sql.DB) (SQLDatabase, error)
+	NewTx func(sqlTx *sql.Tx) (SQLTx, error)
+	Open  func(settings ConnectionURL) (SQLDatabase, error)
+}
+
+// RegisterSQLAdapter registers a SQL database adapter. This function must be
+// called from adapter packages upon initialization. RegisterSQLAdapter calls
+// RegisterAdapter automatically.
+func RegisterSQLAdapter(name string, adapter *SQLAdapterFuncMap) {
+	sqlAdaptersMu.Lock()
+	defer sqlAdaptersMu.Unlock()
+
+	if name == "" {
+		panic(`Missing adapter name`)
+	}
+	if _, ok := sqlAdapters[name]; ok {
+		panic(`db.RegisterSQLAdapter() called twice for adapter: ` + name)
+	}
+	sqlAdapters[name] = adapter
+
+	RegisterAdapter(name, &AdapterFuncMap{
+		Open: func(settings ConnectionURL) (Database, error) {
+			return adapter.Open(settings)
+		},
+	})
+}
+
+// SQLAdapter returns SQL database functions.
+func SQLAdapter(name string) SQLAdapterFuncMap {
+	sqlAdaptersMu.RLock()
+	defer sqlAdaptersMu.RUnlock()
+
+	if fn, ok := sqlAdapters[name]; ok {
+		return *fn
+	}
+	return missingSQLAdapter(name)
+}
+
+func SQLOpen(adapter string, settings ConnectionURL) (SQLDatabase, error) {
+	return SQLAdapter(adapter).Open(settings)
+}
+
+func SQLNew(adapter string, sqlDB *sql.DB) (SQLDatabase, error) {
+	return SQLAdapter(adapter).New(sqlDB)
+}
+
+func SQLNewTx(adapter string, sqlTx *sql.Tx) (SQLTx, error) {
+	return SQLAdapter(adapter).NewTx(sqlTx)
+}
+
+func missingSQLAdapter(name string) SQLAdapterFuncMap {
+	err := fmt.Errorf("upper: Missing SQL adapter %q, forgot to import?", name)
+	return SQLAdapterFuncMap{
+		New: func(*sql.DB) (SQLDatabase, error) {
+			return nil, err
+		},
+		NewTx: func(*sql.Tx) (SQLTx, error) {
+			return nil, err
+		},
+		Open: func(ConnectionURL) (SQLDatabase, error) {
+			return nil, err
+		},
+	}
+}
diff --git a/wrapper.go b/wrapper.go
index 8fad1c0e..009ec2f5 100644
--- a/wrapper.go
+++ b/wrapper.go
@@ -22,17 +22,13 @@
 package db
 
 import (
-	"database/sql"
 	"fmt"
 	"sync"
 )
 
 var (
-	sqlAdapters map[string]*SQLAdapterFuncMap
-	adapters    map[string]*AdapterFuncMap
-
-	sqlAdaptersMu sync.RWMutex
-	adaptersMu    sync.RWMutex
+	adapters   map[string]*AdapterFuncMap
+	adaptersMu sync.RWMutex
 )
 
 func init() {
@@ -44,12 +40,8 @@ type AdapterFuncMap struct {
 	Open func(settings ConnectionURL) (Database, error)
 }
 
-type SQLAdapterFuncMap struct {
-	New   func(sqlDB *sql.DB) (SQLDatabase, error)
-	NewTx func(sqlTx *sql.Tx) (SQLTx, error)
-	Open  func(settings ConnectionURL) (SQLDatabase, error)
-}
-
+// RegisterAdapter registers a generic Database adapter. This function must be
+// called from adapter packages upon initialization.
 func RegisterAdapter(name string, adapter *AdapterFuncMap) {
 	adaptersMu.Lock()
 	defer adaptersMu.Unlock()
@@ -63,25 +55,7 @@ func RegisterAdapter(name string, adapter *AdapterFuncMap) {
 	adapters[name] = adapter
 }
 
-func RegisterSQLAdapter(name string, adapter *SQLAdapterFuncMap) {
-	sqlAdaptersMu.Lock()
-	defer sqlAdaptersMu.Unlock()
-
-	if name == "" {
-		panic(`Missing adapter name`)
-	}
-	if _, ok := sqlAdapters[name]; ok {
-		panic(`db.RegisterSQLAdapter() called twice for adapter: ` + name)
-	}
-	sqlAdapters[name] = adapter
-
-	RegisterAdapter(name, &AdapterFuncMap{
-		Open: func(settings ConnectionURL) (Database, error) {
-			return adapter.Open(settings)
-		},
-	})
-}
-
+// Adapter returns a method map from the given adapter.
 func Adapter(name string) AdapterFuncMap {
 	adaptersMu.RLock()
 	defer adaptersMu.RUnlock()
@@ -92,16 +66,6 @@ func Adapter(name string) AdapterFuncMap {
 	return missingAdapter(name)
 }
 
-func SQLAdapter(name string) SQLAdapterFuncMap {
-	sqlAdaptersMu.RLock()
-	defer sqlAdaptersMu.RUnlock()
-
-	if fn, ok := sqlAdapters[name]; ok {
-		return *fn
-	}
-	return missingSQLAdapter(name)
-}
-
 func missingAdapter(name string) AdapterFuncMap {
 	err := fmt.Errorf("upper: Missing adapter %q, forgot to import?", name)
 	return AdapterFuncMap{
@@ -111,21 +75,6 @@ func missingAdapter(name string) AdapterFuncMap {
 	}
 }
 
-func missingSQLAdapter(name string) SQLAdapterFuncMap {
-	err := fmt.Errorf("upper: Missing SQL adapter %q, forgot to import?", name)
-	return SQLAdapterFuncMap{
-		New: func(*sql.DB) (SQLDatabase, error) {
-			return nil, err
-		},
-		NewTx: func(*sql.Tx) (SQLTx, error) {
-			return nil, err
-		},
-		Open: func(ConnectionURL) (SQLDatabase, error) {
-			return nil, err
-		},
-	}
-}
-
 // Open attempts to open a database. Returns a generic Database instance on
 // success.
 func Open(adapter string, settings ConnectionURL) (Database, error) {
-- 
GitLab