Skip to content

Commit

Permalink
Merge pull request #17 from go-carrot/v2.1.0
Browse files Browse the repository at this point in the history
Add predicates to bulk fetch
  • Loading branch information
BrandonRomano authored Jul 25, 2017
2 parents c55ab7c + f401ffd commit 8fb7f15
Show file tree
Hide file tree
Showing 10 changed files with 1,014 additions and 101 deletions.
7 changes: 7 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ go:
services:
- postgresql
before_script:
- go get golang.org/x/tools/cmd/cover
- |
psql \
--command='create database travis_ci_test;' \
Expand All @@ -22,6 +23,12 @@ before_script:
slug text NOT NULL UNIQUE,
name text NOT NULL,
age int NOT NULL
);
CREATE TABLE toys(
id serial PRIMARY KEY,
name text NOT NULL,
owner bigint NOT NULL REFERENCES animals(id) ON DELETE CASCADE,
second_owner bigint REFERENCES animals(id)
);' \
--username='postgres' \
--dbname='travis_ci_test'
Expand Down
33 changes: 4 additions & 29 deletions bulk_fetch.go → bulk_fetch_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,12 @@ import (
"strings"
)

// OrderByType is an enumeration of the SQL standard order by
type OrderByType int

const (
ORDER_BY_ASC OrderByType = iota
ORDER_BY_DESC
)

// OrderBy is the definition of a single order by clause
type OrderBy struct {
Field string
Type OrderByType
}

// ToString converts an OrderBy to SQL
func (ob *OrderBy) ToString() string {
obType := ""
switch ob.Type {
case ORDER_BY_ASC:
obType = " ASC"
case ORDER_BY_DESC:
obType = " DESC"
}
return ob.Field + obType
}

// BulkFetchConfig is the configuration of a Model.BulkFetch()
type BulkFetchConfig struct {
Limit int
Offset int
OrderBys []OrderBy
Limit int
Offset int
OrderBys []OrderBy
Predicates []Predicate
}

// ConsumeSortQuery consumes a `sort` query parameter
Expand Down
99 changes: 99 additions & 0 deletions logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package surf

import (
"fmt"
"gopkg.in/guregu/null.v3"
"io"
"strconv"
"strings"
"time"
)

var (
loggingEnabled = false
loggingWriter io.Writer
)

// SetLogging adjusts the configuration for logging. You can enable
// and disable the logging here. By default, logging is disabled.
//
// Most calls to this function will be called like SetLogging(true, os.Stdout)
func SetLogging(enabled bool, writer io.Writer) {
loggingEnabled = enabled
loggingWriter = writer
}

// printQuery prints a query if the user has enabled logging
func PrintSqlQuery(query string, args ...interface{}) {
if loggingEnabled {
for i, arg := range args {
query = strings.Replace(query, "$"+strconv.Itoa(i+1), pointerToLogString(arg), 1)
}
fmt.Fprint(loggingWriter, query)
}
}

// pointerToLogString converts a value pointer to the string
// that should be logged for it
func pointerToLogString(pointer interface{}) string {
switch v := pointer.(type) {
case *string:
return "'" + *v + "'"
case *float32:
return strconv.FormatFloat(float64(*v), 'f', -1, 32)
case *float64:
return strconv.FormatFloat(*v, 'f', -1, 64)
case *bool:
return strconv.FormatBool(*v)
case *int:
return strconv.Itoa(*v)
case *int8:
return strconv.FormatInt(int64(*v), 10)
case *int16:
return strconv.FormatInt(int64(*v), 10)
case *int32:
return strconv.FormatInt(int64(*v), 10)
case *int64:
return strconv.FormatInt(*v, 10)
case *uint:
return strconv.FormatUint(uint64(*v), 10)
case *uint8:
return strconv.FormatUint(uint64(*v), 10)
case *uint16:
return strconv.FormatUint(uint64(*v), 10)
case *uint32:
return strconv.FormatUint(uint64(*v), 10)
case *uint64:
return strconv.FormatUint(*v, 10)
case *time.Time:
return "'" + (*v).Format(time.RFC3339) + "'"
case *null.Int:
if v.Valid {
return strconv.FormatInt(v.Int64, 10)
}
break
case *null.String:
if v.Valid {
return "'" + v.String + "'"
}
break
case *null.Bool:
if v.Valid {
return strconv.FormatBool(v.Bool)
}
break
case *null.Float:
if v.Valid {
return strconv.FormatFloat(v.Float64, 'f', -1, 64)
}
break
case *null.Time:
if v.Valid {
return "'" + v.Time.Format(time.RFC3339) + "'"
}
break
default:
return fmt.Sprintf("%v", v)
}
return "null"
}
147 changes: 147 additions & 0 deletions logger_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package surf_test

import (
"github.com/go-carrot/surf"
"github.com/stretchr/testify/assert"
"gopkg.in/guregu/null.v3"
"testing"
"time"
)

type StackWriter struct {
Stack []string
}

func (sw *StackWriter) Write(p []byte) (n int, err error) {
sw.Stack = append(sw.Stack, string(p))
return 0, nil
}

func (sw *StackWriter) Peek() string {
if len(sw.Stack) > 0 {
return sw.Stack[len(sw.Stack)-1]
}
return ""
}

func TestLogger(t *testing.T) {
// Enable logging
stackWriter := &StackWriter{}
surf.SetLogging(true, stackWriter)

// float32
var idFloat32 float32 = 8.8
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idFloat32)
assert.Equal(t, "SELECT * FROM table WHERE id = 8.8", stackWriter.Peek())

// float64
var idFloat64 float64 = 8.9
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idFloat64)
assert.Equal(t, "SELECT * FROM table WHERE id = 8.9", stackWriter.Peek())

// bool
var idBool bool = false
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idBool)
assert.Equal(t, "SELECT * FROM table WHERE id = false", stackWriter.Peek())

// int
var idInt int = 190
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idInt)
assert.Equal(t, "SELECT * FROM table WHERE id = 190", stackWriter.Peek())

// int8
var idInt8 int8 = 8
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idInt8)
assert.Equal(t, "SELECT * FROM table WHERE id = 8", stackWriter.Peek())

// int16
var idInt16 int16 = 111
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idInt16)
assert.Equal(t, "SELECT * FROM table WHERE id = 111", stackWriter.Peek())

// int32
var idInt32 int32 = 1110
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idInt32)
assert.Equal(t, "SELECT * FROM table WHERE id = 1110", stackWriter.Peek())

// int64
var idInt64 int64 = 11100
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idInt64)
assert.Equal(t, "SELECT * FROM table WHERE id = 11100", stackWriter.Peek())

// uint
var idUInt uint = 200
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idUInt)
assert.Equal(t, "SELECT * FROM table WHERE id = 200", stackWriter.Peek())

// uint8
var idUInt8 uint8 = 127
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idUInt8)
assert.Equal(t, "SELECT * FROM table WHERE id = 127", stackWriter.Peek())

// uint16
var idUInt16 uint16 = 1278
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idUInt16)
assert.Equal(t, "SELECT * FROM table WHERE id = 1278", stackWriter.Peek())

// uint32
var idUInt32 uint32 = 12788
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idUInt32)
assert.Equal(t, "SELECT * FROM table WHERE id = 12788", stackWriter.Peek())

// uint64
var idUInt64 uint64 = 127888
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idUInt64)
assert.Equal(t, "SELECT * FROM table WHERE id = 127888", stackWriter.Peek())

// time.Time
const layout = "Jan 2, 2006 at 3:04pm (MST)"
idTime, _ := time.Parse(layout, "Feb 3, 2013 at 7:54pm (PST)")
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idTime)
assert.Equal(t, "SELECT * FROM table WHERE id = '2013-02-03T19:54:00Z'", stackWriter.Peek())

// null.Int
idNullInt := null.IntFrom(100)
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idNullInt)
assert.Equal(t, "SELECT * FROM table WHERE id = 100", stackWriter.Peek())

idNullIntNull := null.Int{}
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idNullIntNull)
assert.Equal(t, "SELECT * FROM table WHERE id = null", stackWriter.Peek())

// null.String
idNullString := null.StringFrom("Hello")
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idNullString)
assert.Equal(t, "SELECT * FROM table WHERE id = 'Hello'", stackWriter.Peek())

idNullStringNull := null.String{}
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idNullStringNull)
assert.Equal(t, "SELECT * FROM table WHERE id = null", stackWriter.Peek())

// null.Bool
idNullBool := null.BoolFrom(false)
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idNullBool)
assert.Equal(t, "SELECT * FROM table WHERE id = false", stackWriter.Peek())

idNullBoolNull := null.Bool{}
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idNullBoolNull)
assert.Equal(t, "SELECT * FROM table WHERE id = null", stackWriter.Peek())

// null.Float
idNullFloat := null.FloatFrom(1.2)
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idNullFloat)
assert.Equal(t, "SELECT * FROM table WHERE id = 1.2", stackWriter.Peek())

idNullFloatNull := null.Float{}
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idNullFloatNull)
assert.Equal(t, "SELECT * FROM table WHERE id = null", stackWriter.Peek())

// null.Time
idNullTime := null.TimeFrom(idTime)
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idNullTime)
assert.Equal(t, "SELECT * FROM table WHERE id = '2013-02-03T19:54:00Z'", stackWriter.Peek())

idNullTimeNull := null.Time{}
surf.PrintSqlQuery("SELECT * FROM table WHERE id = $1", &idNullTimeNull)
assert.Equal(t, "SELECT * FROM table WHERE id = null", stackWriter.Peek())
}
2 changes: 2 additions & 0 deletions model.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ type Field struct {
Updatable bool
UniqueIdentifier bool
SkipValidation bool
GetReference func() (BuildModel, string)
SetReference func(Model) error
IsSet func(interface{}) bool
}

Expand Down
Loading

0 comments on commit 8fb7f15

Please sign in to comment.