From f544b6ad73c605fcfe671ecd669b0ad0804ad926 Mon Sep 17 00:00:00 2001
From: Carlos Nieto <jose.carlos@menteslibres.net>
Date: Sun, 13 Apr 2014 08:11:46 -0500
Subject: [PATCH] Moving *sqlutil.T wrapper (t) to a new file.

---
 ql/collection.go |   1 +
 ql/result.go     |  99 ++-----------------------------
 ql/util.go       | 150 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 155 insertions(+), 95 deletions(-)
 create mode 100644 ql/util.go

diff --git a/ql/collection.go b/ql/collection.go
index da0c94a8..bcdc3d43 100644
--- a/ql/collection.go
+++ b/ql/collection.go
@@ -61,6 +61,7 @@ func (self *Table) Find(terms ...interface{}) db.Result {
 		self,
 		queryChunks,
 		nil,
+		&t{&self.T},
 	}
 
 	return result
diff --git a/ql/result.go b/ql/result.go
index af72da0c..5ee594c2 100644
--- a/ql/result.go
+++ b/ql/result.go
@@ -26,18 +26,11 @@ package ql
 import (
 	"database/sql"
 	"fmt"
-	"reflect"
 	"strings"
 	"upper.io/db"
 	"upper.io/db/util/sqlutil"
-	//"menteslibres.net/gosexy/to"
-	"upper.io/db/util"
 )
 
-type T struct {
-	*sqlutil.T
-}
-
 type counter struct {
 	Total uint64 `field:"total"`
 }
@@ -47,6 +40,7 @@ type Result struct {
 	queryChunks *sqlutil.QueryChunks
 	// This is the main query cursor. It starts as a nil value.
 	cursor *sql.Rows
+	t      *t
 }
 
 // Executes a SELECT statement that can feed Next(), All() or One().
@@ -132,7 +126,7 @@ func (self *Result) All(dst interface{}) error {
 	defer self.Close()
 
 	// Fetching all results within the cursor.
-	err = self.table.T.FetchRows(dst, self.cursor)
+	err = self.t.qlFetchRows(dst, self.cursor)
 
 	return err
 }
@@ -161,8 +155,7 @@ func (self *Result) Next(dst interface{}) error {
 	}
 
 	// Fetching the next result from the cursor.
-	t := &T{&self.table.T}
-	if err = t.qlFetchRow(dst, self.cursor); err != nil {
+	if err = self.t.qlFetchRow(dst, self.cursor); err != nil {
 		self.Close()
 		return err
 	}
@@ -246,93 +239,9 @@ func (self *Result) Count() (uint64, error) {
 	}
 
 	dst := counter{}
-	self.table.T.FetchRow(&dst, rows)
+	self.t.FetchRow(&dst, rows)
 
 	rows.Close()
 
 	return dst.Total, nil
 }
-
-func getRowColumns(rows *sql.Rows) ([]string, error) {
-	// Column names.
-	columns, err := rows.Columns()
-
-	if err != nil {
-		return nil, err
-	}
-
-	// Column names to lower case.
-	for i, _ := range columns {
-		columns[i] = strings.ToLower(columns[i])
-	}
-
-	return columns, nil
-}
-
-func (self *T) qlFetchRow(dst interface{}, rows *sql.Rows) error {
-
-	dstv := reflect.ValueOf(dst)
-
-	if dstv.IsNil() || dstv.Kind() != reflect.Ptr {
-		return db.ErrExpectingPointer
-	}
-
-	item_v := dstv.Elem()
-
-	columns, err := getRowColumns(rows)
-
-	if err != nil {
-		return err
-	}
-
-	next := rows.Next()
-
-	if next == false {
-		if err = rows.Err(); err != nil {
-			return err
-		}
-		return db.ErrNoMoreRows
-	}
-
-	item, err := self.qlFetchResult(item_v.Type(), rows, columns)
-
-	if err != nil {
-		return err
-	}
-
-	item_v.Set(reflect.Indirect(item))
-
-	return nil
-}
-
-func (self *T) qlFetchResult(item_t reflect.Type, rows *sql.Rows, columns []string) (item reflect.Value, err error) {
-	expecting := len(columns)
-
-	scanArgs := make([]interface{}, expecting)
-
-	switch item_t.Kind() {
-	case reflect.Struct:
-		// Creating new value of the expected type
-		item = reflect.New(item_t)
-		// Pairing each column with it's index
-		for i, columnName := range columns {
-			index := util.GetStructFieldIndex(item_t, columnName)
-			if index != nil {
-				dest_f := item.Elem().FieldByIndex(index)
-				scanArgs[i] = dest_f.Addr().Interface()
-			}
-		}
-	// case reflect.Map: // TODO
-	default:
-		return item, db.ErrUnsupportedDestination
-		//return item, db.ErrExpectingMapOrStruct
-	}
-
-	err = rows.Scan(scanArgs...)
-
-	if err != nil {
-		return item, err
-	}
-
-	return item, nil
-}
diff --git a/ql/util.go b/ql/util.go
new file mode 100644
index 00000000..88afee90
--- /dev/null
+++ b/ql/util.go
@@ -0,0 +1,150 @@
+/*
+  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.
+*/
+
+package ql
+
+import (
+	"database/sql"
+	"reflect"
+	"strings"
+	"upper.io/db"
+	"upper.io/db/util"
+	"upper.io/db/util/sqlutil"
+)
+
+// Wrapper for sqlutil.T
+type t struct {
+	*sqlutil.T
+}
+
+func (self *t) qlFetchRow(dst interface{}, rows *sql.Rows) error {
+
+	dstv := reflect.ValueOf(dst)
+
+	if dstv.IsNil() || dstv.Kind() != reflect.Ptr {
+		return db.ErrExpectingPointer
+	}
+
+	item_v := dstv.Elem()
+
+	columns, err := sqlutil.GetRowColumns(rows)
+
+	if err != nil {
+		return err
+	}
+
+	next := rows.Next()
+
+	if next == false {
+		if err = rows.Err(); err != nil {
+			return err
+		}
+		return db.ErrNoMoreRows
+	}
+
+	item, err := self.qlFetchResult(item_v.Type(), rows, columns)
+
+	if err != nil {
+		return err
+	}
+
+	item_v.Set(reflect.Indirect(item))
+
+	return nil
+}
+
+func (self *t) qlFetchResult(item_t reflect.Type, rows *sql.Rows, columns []string) (item reflect.Value, err error) {
+	expecting := len(columns)
+
+	scanArgs := make([]interface{}, expecting)
+
+	switch item_t.Kind() {
+	case reflect.Struct:
+		// Creating new value of the expected type.
+		item = reflect.New(item_t)
+		// Pairing each column with its index.
+		for i, columnName := range columns {
+			index := util.GetStructFieldIndex(item_t, columnName)
+			if index != nil {
+				dest_f := item.Elem().FieldByIndex(index)
+				scanArgs[i] = dest_f.Addr().Interface()
+			}
+		}
+	// case reflect.Map: // TODO
+	default:
+		return item, db.ErrUnsupportedDestination
+		//return item, db.ErrExpectingMapOrStruct
+	}
+
+	err = rows.Scan(scanArgs...)
+
+	if err != nil {
+		return item, err
+	}
+
+	return item, nil
+}
+
+func (self *t) qlFetchRows(dst interface{}, rows *sql.Rows) error {
+
+	// Destination.
+	dstv := reflect.ValueOf(dst)
+
+	if dstv.IsNil() || dstv.Kind() != reflect.Ptr {
+		return db.ErrExpectingPointer
+	}
+
+	if dstv.Elem().Kind() != reflect.Slice {
+		return db.ErrExpectingSlicePointer
+	}
+
+	if dstv.Kind() != reflect.Ptr || dstv.Elem().Kind() != reflect.Slice || dstv.IsNil() {
+		return db.ErrExpectingSliceMapStruct
+	}
+
+	columns, err := sqlutil.GetRowColumns(rows)
+
+	if err != nil {
+		return err
+	}
+
+	slicev := dstv.Elem()
+	item_t := slicev.Type().Elem()
+
+	for rows.Next() {
+
+		item, err := self.qlFetchResult(item_t, rows, columns)
+
+		if err != nil {
+			return err
+		}
+
+		slicev = reflect.Append(slicev, reflect.Indirect(item))
+	}
+
+	rows.Close()
+
+	dstv.Elem().Set(slicev)
+
+	return nil
+}
-- 
GitLab