good morning!!!!

Skip to content
Snippets Groups Projects
Commit 5ecb9e05 authored by José Carlos Nieto's avatar José Carlos Nieto
Browse files

Some cleaning, also moving debug function to sqlutil package.

parent 2ff97d67
No related branches found
No related tags found
No related merge requests found
/* // Copyright (c) 2012-2014 José Carlos Nieto, https://menteslibres.net/xiam
Copyright (c) 2012-2014 José Carlos Nieto, https://menteslibres.net/xiam //
// Permission is hereby granted, free of charge, to any person obtaining
Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the
a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including
"Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish,
without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to
distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to
permit persons to whom the Software is furnished to do so, subject to // the following conditions:
the following conditions: //
// The above copyright notice and this permission notice shall be
The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software.
included in all copies or substantial portions of the Software. //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package postgresql package postgresql
...@@ -35,14 +33,88 @@ import ( ...@@ -35,14 +33,88 @@ import (
"upper.io/db/util/sqlutil" "upper.io/db/util/sqlutil"
) )
// Represents a PostgreSQL table. const defaultOperator = `=`
type Table struct { type Table struct {
sqlutil.T sqlutil.T
source *Source source *Source
names []string names []string
} }
const defaultOperator = `=` func whereValues(term interface{}) (where sqlgen.Where, args []interface{}) {
args = []interface{}{}
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)
}
}
return where, args
}
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] = toInternal(value_v.Index(i).Interface())
}
return args
} else {
return nil
}
default:
args = []interface{}{toInternal(value)}
}
return args
}
func conditionValues(cond db.Cond) (columnValues sqlgen.ColumnValues, args []interface{}) { func conditionValues(cond db.Cond) (columnValues sqlgen.ColumnValues, args []interface{}) {
...@@ -103,50 +175,6 @@ func conditionValues(cond db.Cond) (columnValues sqlgen.ColumnValues, args []int ...@@ -103,50 +175,6 @@ func conditionValues(cond db.Cond) (columnValues sqlgen.ColumnValues, args []int
return columnValues, args return columnValues, args
} }
func whereValues(term interface{}) (where sqlgen.Where, args []interface{}) {
args = []interface{}{}
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)
}
}
return where, args
}
func (self *Table) Find(terms ...interface{}) db.Result { func (self *Table) Find(terms ...interface{}) db.Result {
where, arguments := whereValues(terms) where, arguments := whereValues(terms)
...@@ -249,10 +277,6 @@ func (self *Table) Name() string { ...@@ -249,10 +277,6 @@ func (self *Table) Name() string {
return strings.Join(self.names, `, `) return strings.Join(self.names, `, `)
} }
func toInternalInterface(val interface{}) interface{} {
return toInternal(val)
}
// Converts a Go value into internal database representation. // Converts a Go value into internal database representation.
func toInternal(val interface{}) interface{} { func toInternal(val interface{}) interface{} {
switch t := val.(type) { switch t := val.(type) {
...@@ -271,39 +295,3 @@ func toInternal(val interface{}) interface{} { ...@@ -271,39 +295,3 @@ func toInternal(val interface{}) interface{} {
} }
return to.String(val) return to.String(val)
} }
// Convers a database representation (after auto-conversion) into a Go value.
func toNative(val interface{}) interface{} {
return val
}
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] = toInternal(value_v.Index(i).Interface())
}
return args
} else {
return nil
}
default:
args = []interface{}{toInternal(value)}
}
return args
}
/* // Copyright (c) 2012-2014 José Carlos Nieto, https://menteslibres.net/xiam
Copyright (c) 2012-2014 José Carlos Nieto, https://menteslibres.net/xiam //
// Permission is hereby granted, free of charge, to any person obtaining
Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the
a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including
"Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish,
without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to
distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to
permit persons to whom the Software is furnished to do so, subject to // the following conditions:
the following conditions: //
// The above copyright notice and this permission notice shall be
The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software.
included in all copies or substantial portions of the Software. //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package postgresql package postgresql
...@@ -27,30 +25,29 @@ import ( ...@@ -27,30 +25,29 @@ import (
"database/sql" "database/sql"
"fmt" "fmt"
_ "github.com/xiam/gopostgresql" _ "github.com/xiam/gopostgresql"
"log"
"os" "os"
"reflect" "reflect"
"regexp" "regexp"
"strings" "strings"
"upper.io/db" "upper.io/db"
"upper.io/db/util/sqlgen" "upper.io/db/util/sqlgen"
"upper.io/db/util/sqlutil"
) )
// Format for saving dates. const Driver = `postgresql`
var DateFormat = "2006-01-02 15:04:05"
var (
// Format for saving dates.
DateFormat = "2006-01-02 15:04:05"
// Format for saving times. // Format for saving times.
var TimeFormat = "%d:%02d:%02d.%d" TimeFormat = "%d:%02d:%02d.%d"
SSLMode = "disable"
var SSLMode = "disable" )
var columnPattern = regexp.MustCompile(`^([a-z]+)\(?([0-9,]+)?\)?\s?([a-z]*)?`)
var sqlPlaceholder = sqlgen.Value{sqlgen.Raw{`?`}}
var reInvisibleChars = regexp.MustCompile(`[\s\r\n\t]+`)
const Driver = `postgresql` var (
columnPattern = regexp.MustCompile(`^([a-z]+)\(?([0-9,]+)?\)?\s?([a-z]*)?`)
sqlPlaceholder = sqlgen.Value{sqlgen.Raw{`?`}}
)
type Source struct { type Source struct {
config db.Settings config db.Settings
...@@ -59,6 +56,11 @@ type Source struct { ...@@ -59,6 +56,11 @@ type Source struct {
tx *sql.Tx tx *sql.Tx
} }
type columnSchema_t struct {
ColumnName string `db:"column_name"`
DataType string `db:"data_type"`
}
func debugEnabled() bool { func debugEnabled() bool {
if os.Getenv(db.EnvEnableDebug) != "" { if os.Getenv(db.EnvEnableDebug) != "" {
return true return true
...@@ -70,12 +72,6 @@ func init() { ...@@ -70,12 +72,6 @@ func init() {
db.Register(Driver, &Source{}) db.Register(Driver, &Source{})
} }
func debugLogQuery(s string, args []interface{}) {
s = reInvisibleChars.ReplaceAllString(s, ` `)
s = strings.TrimSpace(s)
log.Printf("\n\tSQL: %s\n\tARGS: %v\n\n", s, args)
}
func (self *Source) doExec(stmt sqlgen.Statement, args ...interface{}) (sql.Result, error) { func (self *Source) doExec(stmt sqlgen.Statement, args ...interface{}) (sql.Result, error) {
if self.session == nil { if self.session == nil {
...@@ -90,7 +86,7 @@ func (self *Source) doExec(stmt sqlgen.Statement, args ...interface{}) (sql.Resu ...@@ -90,7 +86,7 @@ func (self *Source) doExec(stmt sqlgen.Statement, args ...interface{}) (sql.Resu
} }
if debugEnabled() == true { if debugEnabled() == true {
debugLogQuery(query, args) sqlutil.DebugQuery(query, args)
} }
if self.tx != nil { if self.tx != nil {
...@@ -113,7 +109,7 @@ func (self *Source) doQuery(stmt sqlgen.Statement, args ...interface{}) (*sql.Ro ...@@ -113,7 +109,7 @@ func (self *Source) doQuery(stmt sqlgen.Statement, args ...interface{}) (*sql.Ro
} }
if debugEnabled() == true { if debugEnabled() == true {
debugLogQuery(query, args) sqlutil.DebugQuery(query, args)
} }
if self.tx != nil { if self.tx != nil {
...@@ -136,7 +132,7 @@ func (self *Source) doQueryRow(stmt sqlgen.Statement, args ...interface{}) (*sql ...@@ -136,7 +132,7 @@ func (self *Source) doQueryRow(stmt sqlgen.Statement, args ...interface{}) (*sql
} }
if debugEnabled() == true { if debugEnabled() == true {
debugLogQuery(query, args) sqlutil.DebugQuery(query, args)
} }
if self.tx != nil { if self.tx != nil {
...@@ -327,11 +323,6 @@ func (self *Source) tableExists(names ...string) error { ...@@ -327,11 +323,6 @@ func (self *Source) tableExists(names ...string) error {
return nil return nil
} }
type pgColumnSchema struct {
ColumnName string `db:"column_name"`
DataType string `db:"data_type"`
}
// Returns a collection instance by name. // Returns a collection instance by name.
func (self *Source) Collection(names ...string) (db.Collection, error) { func (self *Source) Collection(names ...string) (db.Collection, error) {
...@@ -346,7 +337,7 @@ func (self *Source) Collection(names ...string) (db.Collection, error) { ...@@ -346,7 +337,7 @@ func (self *Source) Collection(names ...string) (db.Collection, error) {
col.PrimaryKey = `id` col.PrimaryKey = `id`
columns_t := []pgColumnSchema{} columns_t := []columnSchema_t{}
for _, name := range names { for _, name := range names {
chunks := strings.SplitN(name, " ", 2) chunks := strings.SplitN(name, " ", 2)
......
/* // Copyright (c) 2012-2014 José Carlos Nieto, https://menteslibres.net/xiam
Copyright (c) 2012-2014 José Carlos Nieto, https://menteslibres.net/xiam //
// Permission is hereby granted, free of charge, to any person obtaining
Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the
a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including
"Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish,
without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to
distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to
permit persons to whom the Software is furnished to do so, subject to // the following conditions:
the following conditions: //
// The above copyright notice and this permission notice shall be
The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software.
included in all copies or substantial portions of the Software. //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package postgresql package postgresql
......
/* // Copyright (c) 2012-2014 José Carlos Nieto, https://menteslibres.net/xiam
Copyright (c) 2012-2014 José Carlos Nieto, https://menteslibres.net/xiam //
// Permission is hereby granted, free of charge, to any person obtaining
Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the
a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including
"Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish,
without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to
distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to
permit persons to whom the Software is furnished to do so, subject to // the following conditions:
the following conditions: //
// The above copyright notice and this permission notice shall be
The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software.
included in all copies or substantial portions of the Software. //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package postgresql package postgresql
...@@ -37,12 +35,12 @@ type counter struct { ...@@ -37,12 +35,12 @@ type counter struct {
type Result struct { type Result struct {
table *Table table *Table
cursor *sql.Rows // This is the main query cursor. It starts as a nil value. cursor *sql.Rows // This is the main query cursor. It starts as a nil value.
arguments []interface{}
limit sqlgen.Limit limit sqlgen.Limit
offset sqlgen.Offset offset sqlgen.Offset
columns sqlgen.Columns columns sqlgen.Columns
where sqlgen.Where where sqlgen.Where
orderBy sqlgen.OrderBy orderBy sqlgen.OrderBy
arguments []interface{}
} }
// Executes a SELECT statement that can feed Next(), All() or One(). // Executes a SELECT statement that can feed Next(), All() or One().
......
// 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 postgresql package postgresql
type Tx struct { type Tx struct {
......
...@@ -25,25 +25,28 @@ package sqlutil ...@@ -25,25 +25,28 @@ package sqlutil
import ( import (
"database/sql" "database/sql"
"log"
"menteslibres.net/gosexy/to" "menteslibres.net/gosexy/to"
"reflect" "reflect"
"regexp"
"strings" "strings"
"upper.io/db" "upper.io/db"
"upper.io/db/util" "upper.io/db/util"
) )
var (
reInvisibleChars = regexp.MustCompile(`[\s\r\n\t]+`)
)
type T struct { type T struct {
PrimaryKey string PrimaryKey string
ColumnTypes map[string]reflect.Kind ColumnTypes map[string]reflect.Kind
} }
type QueryChunks struct { func DebugQuery(s string, args []interface{}) {
Fields []string s = reInvisibleChars.ReplaceAllString(s, ` `)
Limit string s = strings.TrimSpace(s)
Offset string log.Printf("\n\tSQL: %s\n\tARGS: %v\n\n", s, args)
Sort string
Conditions string
Arguments []interface{}
} }
func (self *T) ColumnLike(s string) string { func (self *T) ColumnLike(s string) string {
...@@ -352,8 +355,3 @@ func (self *T) FieldValues(item interface{}, convertFn func(interface{}) interfa ...@@ -352,8 +355,3 @@ func (self *T) FieldValues(item interface{}, convertFn func(interface{}) interfa
return fields, values, nil return fields, values, nil
} }
func NewQueryChunks() *QueryChunks {
self := &QueryChunks{}
return self
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment