Skip to content

Commit

Permalink
try delete cache key on error; bug in remapPlaceholders
Browse files Browse the repository at this point in the history
  • Loading branch information
Mario L Gutierrez committed Jun 26, 2015
1 parent 78b33d2 commit 6cad7ac
Show file tree
Hide file tree
Showing 17 changed files with 217 additions and 228 deletions.
12 changes: 11 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
# Changes from legacy to v1
## v1.1.0

* [Caching](https://github.com/mgutz/dat#caching) - caching with Redis or (in-memory for testing)
* [LogQueriesThreshold](https://github.com/mgutz/dat#tracing-sql) - log slow queries
* dat.Null* creators
* fix resource cleanup
* fix duplicate error logging
* include RFC339Nano in NullTime parsing
* HUGE BUG in remapPlaceholders

## v1.0.0

* Original dat moved to legacy branch.

Expand Down
6 changes: 3 additions & 3 deletions Gododir/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ package dat
func generateTasks(p *do.Project) {
p.Task("builder-boilerplate", nil, func(c *do.Context) {
context := do.M{
"builders": []string{"DeleteBuilder", "InsectBuilder",
"builders": []string{"CallBuilder", "DeleteBuilder", "InsectBuilder",
"InsertBuilder", "RawBuilder", "SelectBuilder", "SelectDocBuilder",
"UpdateBuilder", "UpsertBuilder"},
}

s, err := util.StrTemplate(builderTemplate, context)
c.Check(err, "Unalbe ")

ioutil.WriteFile("v1/builders_generated.go", []byte(s), 0644)
c.Run("go fmt v1/builders_generated.go")
ioutil.WriteFile("builders_generated.go", []byte(s), 0644)
c.Run("go fmt builders_generated.go")
}).Desc("Generates builder boilerplate code")
}
42 changes: 41 additions & 1 deletion Gododir/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package main

import (
"fmt"

_ "github.com/lib/pq"
do "gopkg.in/godo.v2"
)
Expand All @@ -16,9 +18,16 @@ func tasks(p *do.Project) {
p.Task("createdb", nil, createdb).Description("Creates test database")

p.Task("test", nil, func(c *do.Context) {
c.Run(`go test -race`)
c.Run(`go test -race`, do.M{"$in": "sqlx-runner"})
}).Src("**/*.go").
Desc("test with -race flag")

p.Task("test-fast", nil, func(c *do.Context) {
c.Run(`go test`)
c.Run(`go test`, do.M{"$in": "sqlx-runner"})
}).Src("**/*.go")
}).Src("**/*.go").
Desc("fater test without -race flag")

p.Task("test-dir", nil, func(c *do.Context) {
dir := c.Args.NonFlags()[0]
Expand All @@ -36,6 +45,10 @@ func tasks(p *do.Project) {
`)
})

p.Task("hello", nil, func(*do.Context) {
fmt.Println("hello?")
})

p.Task("bench", nil, func(c *do.Context) {
// Bash("go test -bench . -benchmem 2>/dev/null | column -t")
// Bash("go test -bench . -benchmem 2>/dev/null | column -t", In{"sqlx-runner"})
Expand All @@ -62,6 +75,33 @@ func tasks(p *do.Project) {

p.Task("example", nil, func(c *do.Context) {
})

p.Task("lint", nil, func(c *do.Context) {
c.Bash(`
echo Directory=.
golint
cd sqlx-runner
echo
echo Directory=sqlx-runner
golint
cd ../kvs
echo
echo Directory=kvs
golint
cd ../postgres
echo
echo Directory=postgres
golint
`)
})

p.Task("mocks", nil, func(c *do.Context) {
// go get github.com/vektra/mockery
c.Run("mockery --dir=kvs --all")
})
}

func main() {
Expand Down
137 changes: 54 additions & 83 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ library for Go.
DB.SQL(`SELECT * FROM people LIMIT 10`).QueryStructs(&people)
```

* JSON Document retrieval (single trip to Postgres!, requires Postgres 9.3+)
* JSON Document retrieval (single trip to Postgres, requires Postgres 9.3+)

```go
DB.SelectDoc("id", "user_name", "avatar").
Expand Down Expand Up @@ -140,7 +140,7 @@ func init() {
panic("Could not ping database")
}
// set to reasonable values
// set to reasonable values for production
db.SetMaxIdleConns(4)
db.SetMaxOpenConns(16)
Expand All @@ -163,7 +163,7 @@ type Post struct {
Body string `db:"body"`
UserID int64 `db:"user_id"`
State string `db:"state"`
UpdatedAt dat.Nulltime `db:"updated_at"`
UpdatedAt dat.NullTime `db:"updated_at"`
CreatedAt dat.NullTime `db:"created_at"`
}
Expand Down Expand Up @@ -260,7 +260,6 @@ DB.InsertInto("payments").
// ensure session user can only update his information
DB.Update("users").
SetWhitelist(user, "user_name", "avatar", "quote").
Record(userData).
Where("id = $1", session.UserID).
Exec()
```
Expand All @@ -282,7 +281,7 @@ b.MustInterpolate() == "SELECT * FROM posts WHERE id IN (10,20,30,40,50)"
`dat` uses [logxi](https://github.com/mgutz/logxi) for logging. By default,
*logxi* logs all warnings and errors to the console. `dat` logs the
SQL and its arguments on any error. In addition, `dat` logs slow queries
as warnings if `LogQueriesThreshold > 0`
as warnings if `runner.LogQueriesThreshold > 0`

To trace all SQL, set environment variable

Expand All @@ -298,7 +297,7 @@ Use `Returning` and `QueryStruct` to insert and update struct fields in one
trip

```go
post := Post{Title: "Swith to Postgres", State: "open"}
var post Post
err := DB.
InsertInto("posts").
Expand All @@ -316,15 +315,15 @@ post := Post{Title: "Go is awesome", State: "open"}
err := DB.
InsertInto("posts").
Blacklist("id", "user_id", "created_at", "updated_at").
Record(post).
Record(&post).
Returning("id", "created_at", "updated_at").
QueryStruct(&post)
// use wildcard to include all columns
err := DB.
InsertInto("posts").
Whitelist("*").
Record(post).
Record(&post).
Returning("id", "created_at", "updated_at").
QueryStruct(&post)
Expand Down Expand Up @@ -491,7 +490,7 @@ result, err = DB.

### Joins

Define JOINs as arguments to `From`
Define JOINs in argument to `From`

``` go
err = DB.
Expand Down Expand Up @@ -594,6 +593,52 @@ func getUsers(conn runner.Connection) ([]*dto.Users, error) {
}
```
#### Nested Transactions
Nested transaction logic is as follows:
* If `Commit` is called in a nested transaction, the operation results in no operation (NOOP).
Only the top level `Commit` commits the transaction to the database.
* If `Rollback` is called in a nested transaction, then the entire
transaction is rolled back. `Tx.IsRollbacked` is set to true.
* Either `defer Tx.AutoCommit()` or `defer Tx.AutoRollback()` **MUST BE CALLED**
for each corresponding `Begin`. The internal state of nested transactions is
tracked in these two methods.
```go
func nested(conn runner.Connection) error {
tx, err := conn.Begin()
if err != nil {
return err
}
defer tx.AutoRollback()
_, err := tx.SQL(`INSERT INTO users (email) values $1`, 'me@home.com').Exec()
if err != nil {
return err
}
// prevents AutoRollback
tx.Commit()
}
func top() {
tx, err := DB.Begin()
if err != nil {
logger.Fatal("Could not create transaction")
}
defer tx.AutoRollback()
err := nested(tx)
if err != nil {
return
}
// top level commits the transaction
tx.Commit()
}
```
### Dates
Use `dat.NullTime` type to properly handle nullable dates
Expand Down Expand Up @@ -661,80 +706,6 @@ err := DB.
QueryStruct(&post)
```
### Transactions
```go
// Start transaction
tx, err := DB.Begin()
if err != nil {
return err
}
// safe to call tx.Rollback() or tx.Commit() later
defer tx.AutoRollback()
// Issue statements that might cause errors
res, err := tx.
Update("posts").
Set("state", "deleted").
Where("deleted_at IS NOT NULL").
Exec()
if err != nil {
// AutoRollback will rollback the transaction
return err
}
// commit to prevent AutoRollback from rolling back the transaction
tx.Commit()
return nil
```
#### Nested Transactions
Nested transaction logic is as follows:
* If `Commit` is called in a nested transaction, the operation results in no operatoin (NOOP).
Only the top level `Commit` commits the transaction to the database.
* If `Rollback` is called in a nested transaction, then the entire
transaction is rolled back. `Tx.IsRollbacked` is set to true.
* Either `defer Tx.AutoCommit()` or `defer Tx.AutoRollback()` **MUST BE CALLED**
for each corresponding `Begin`. The internal state of nested transactions is
tracked in these two methods.
```go
func nested(conn runner.Connection) error {
tx, err := conn.Begin()
if err != nil {
return err
}
defer tx.AutoRollback()
_, err := tx.SQL(`INSERT INTO users (email) values $1`, 'me@home.com').Exec()
if err != nil {
return err
}
// prevents AutoRollback
tx.Commit()
}
func top() {
tx, err := DB.Begin()
if err != nil {
logger.Fatal("Could not create transaction")
}
defer tx.AutoRollback()
err := nested(tx)
if err != nil {
return
}
// top level commits the transaction
tx.Commit()
}
```
### Caching
dat implements caching backed by an in-memory or Redis store. The in-memory store
Expand Down
10 changes: 0 additions & 10 deletions builder.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
package dat

import "time"

// Cacher caches query results.
type Cacher interface {
// Cache caches the result of a Select or SelectDoc. If id is not provided, an FNV checksum
// of the SQL is used as the id. (If interpolation is set, arguments are hashed). Use invalidate to
// immediately invalidate the cache to force setting its value.
Cache(id string, duration time.Duration, invalidate bool)
}

// Builder interface is used to tie SQL generators to executors.
type Builder interface {
// ToSQL builds the SQL and arguments from builder.
Expand Down
2 changes: 1 addition & 1 deletion execer.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var nullExecer = &panicExecer{}

// panicExecer is the execer assigned when a builder is first created.
// panicExecer raises a panic if any of the Execer methods are called
// directly from dat. Runners override the execer to communicate with a live
// directly from dat. Runners override the execer to work with a live
// database.
type panicExecer struct{}

Expand Down
5 changes: 0 additions & 5 deletions generate.go

This file was deleted.

2 changes: 1 addition & 1 deletion insert.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (b *InsertBuilder) Blacklist(columns ...string) *InsertBuilder {
}

// Whitelist defines a whitelist of columns to be inserted. To
// specify all columsn of a record use "*".
// specify all columns of a record use "*".
func (b *InsertBuilder) Whitelist(columns ...string) *InsertBuilder {
b.cols = columns
return b
Expand Down
6 changes: 3 additions & 3 deletions interpolate.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func Interpolate(sql string, vals []interface{}) (string, []interface{}, error)
// Args with a blank query is an error
if sql == "" {
if lenVals != 0 {
return "", nil, ErrArgumentMismatch
return "", nil, logger.Error("Interpolation error", "err", ErrArgumentMismatch, "sql", sql, "args", vals)
}
return "", nil, nil
}
Expand All @@ -75,13 +75,13 @@ func Interpolate(sql string, vals []interface{}) (string, []interface{}, error)
// No args for a query with place holders is an error
if lenVals == 0 {
if hasPlaceholders {
return "", nil, ErrArgumentMismatch
return "", nil, logger.Error("Interpolation error", "err", ErrArgumentMismatch, "sql", sql, "args", vals)
}
return sql, nil, nil
}

if lenVals > 0 && !hasPlaceholders {
return "", nil, ErrArgumentMismatch
return "", nil, logger.Error("Interpolation error", "err", ErrArgumentMismatch, "sql", sql, "args", vals)
}

if !hasPlaceholders {
Expand Down
4 changes: 2 additions & 2 deletions interpolate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ func TestInterpolateInts(t *testing.T) {
uint64(10),
}

str, _, err := Interpolate("SELECT * FROM x WHERE a = $1 AND b = $2 AND c = $3 AND d = $4 AND e = $5 AND f = $6 AND g = $7 AND h = $8 AND i = $9 AND j = $10", args)
str, _, err := Interpolate("SELECT * FROM x WHERE a = $1 AND b = $2 AND c = $3 AND d = $4 AND e = $5 AND f = $6 AND g = $7 AND h = $8 AND i = $9 AND j = $1", args)
assert.NoError(t, err)
assert.Equal(t, str, "SELECT * FROM x WHERE a = 1 AND b = -2 AND c = 3 AND d = 4 AND e = 5 AND f = 6 AND g = 7 AND h = 8 AND i = 9 AND j = 10")
assert.Equal(t, str, "SELECT * FROM x WHERE a = 1 AND b = -2 AND c = 3 AND d = 4 AND e = 5 AND f = 6 AND g = 7 AND h = 8 AND i = 9 AND j = 1")
}

func TestInterpolateBools(t *testing.T) {
Expand Down
Loading

0 comments on commit 6cad7ac

Please sign in to comment.