@@ -11,70 +11,62 @@ go get github.com/gchaincl/sqlhooks
11
11
12
12
# Usage [ ![ GoDoc] ( https://godoc.org/github.com/gchaincl/dotsql?status.svg )] ( https://godoc.org/github.com/gchaincl/sqlhooks )
13
13
``` go
14
- package main
14
+ package main
15
15
16
- import (
17
- " database/sql"
18
- " log"
19
- " time"
16
+ import (
17
+ " log"
18
+ " time"
20
19
21
- " github.com/gchaincl/sqlhooks"
22
- _ " github.com/mattn/go-sqlite3"
23
- )
20
+ " github.com/gchaincl/sqlhooks"
21
+ _ " github.com/mattn/go-sqlite3"
22
+ )
24
23
25
- func main () {
26
- // Define your hooks
27
- // They will print execution time
28
- hooks := sqlhooks.Hooks {
29
- Exec: func (query string , args ...interface {}) func (error ) {
30
- log.Printf (" [exec] %s , args: %v " , query, args)
31
- return nil
32
- },
33
- Query: func (query string , args ...interface {}) func (error ) {
34
- t := time.Now ()
35
- id := t.Nanosecond ()
36
- log.Printf (" [query#%d ] %s , args: %v " , id, query, args)
37
- // This will be executed when Query statements has completed
38
- return func (err error ) {
39
- log.Printf (" [query#%d ] took: %s (err: %v )" , id, time.Since (t), err)
40
- }
41
- },
24
+ // Hooks satisfies sqlhooks.Queryer interface
25
+ type Hooks struct {
26
+ count int
42
27
}
43
28
44
- // Connect to hooked sqlite3 driver
45
- db , err := sqlhooks.Open (" sqlite3" , " :memory:" , &hooks)
46
- if err != nil {
47
- panic (err)
29
+ func (h *Hooks ) BeforeQuery (ctx *sqlhooks.Context) error {
30
+ h.count ++
31
+ ctx.Set (" t" , time.Now ())
32
+ ctx.Set (" id" , h.count )
33
+ log.Printf (" [query#%d ] %s , args: %v " , ctx.Get (" id" ).(int ), ctx.Query , ctx.Args )
34
+ return nil
35
+ }
36
+
37
+ func (h *Hooks ) AfterQuery (ctx *sqlhooks.Context) error {
38
+ d := time.Since (ctx.Get (" t" ).(time.Time ))
39
+ log.Printf (" [query#%d ] took %s (err: %v )" , ctx.Get (" id" ).(int ), d, ctx.Error )
40
+ return ctx.Error
41
+ }
42
+
43
+ func main () {
44
+ hooks := &Hooks{}
45
+
46
+ // Connect to attached driver
47
+ db , _ := sqlhooks.Open (" sqlite3" , " :memory:" , hooks)
48
+
49
+ // Do you're stuff
50
+ db.Exec (" CREATE TABLE t (id INTEGER, text VARCHAR(16))" )
51
+ db.Exec (" INSERT into t (text) VALUES(?), (?)" , " foo" , " bar" )
52
+ db.Query (" SELECT id, text FROM t" )
53
+ db.Query (" Invalid Query" )
48
54
}
49
55
50
- // Do you're stuff
51
- db.Exec (" CREATE TABLE t (id INTEGER, text VARCHAR(16))" )
52
- db.Exec (" INSERT into t (text) VALUES(?), (?))" , " foo" , " bar" )
53
- db.Query (" SELECT id, text FROM t" )
54
- db.Query (" Invalid Query" )
55
- }
56
56
```
57
57
58
- sqlhooks will intercept Query and Exec functions, run your hooks, execute que queries and finally execute the returned func(). Output will look like:
59
58
```
60
- 2016/04/23 19:43:53 [exec] CREATE TABLE t (id INTEGER, text VARCHAR(16)), args: []
61
- 2016/04/23 19:43:53 [exec] INSERT into t (text) VALUES(?), (?)), args: [foo bar]
62
- 2016/04/23 19:43:53 [query#487301557] SELECT id, text FROM t, args: []
63
- 2016/04/23 19:43:53 [query#487301557] took: 37.765µs (err: <nil>)
64
- 2016/04/23 19:43:53 [query#487405691] Invalid Query, args: []
65
- 2016/04/23 19:43:53 [query#487405691] took: 18.312µs (err: near "Invalid": syntax error)
59
+ 2016/06/02 14:28:24 [query#1] SELECT id, text FROM t, args: []
60
+ 2016/06/02 14:28:24 [query#1] took 122.406µs (err: <nil>)
61
+ 2016/06/02 14:28:24 [query#2] Invalid Query, args: []
62
+ 2016/06/02 14:28:24 [query#2] took 23.148µs (err: near "Invalid": syntax error)
66
63
```
67
64
68
65
# Benchmark
69
66
```
70
- BenchmarkExec-4 500000 4335 ns/op 566 B/op 16 allocs/op
71
- BenchmarkExecWithSQLHooks-4 500000 4918 ns/op 646 B/op 19 allocs/op
72
- BenchmarkPreparedExec-4 1000000 1884 ns/op 181 B/op 7 allocs/op
73
- BenchmarkPreparedExecWithSQLHooks-4 1000000 1919 ns/op 197 B/op 8 allocs/op
67
+ PASS
68
+ BenchmarkExec-4 500000 4604 ns/op
69
+ BenchmarkExecWithSQLHooks-4 300000 5726 ns/op
70
+ BenchmarkPreparedExec-4 1000000 1820 ns/op
71
+ BenchmarkPreparedExecWithSQLHooks-4 1000000 2088 ns/op
74
72
```
75
-
76
- # TODO
77
- - [ ] ` Hooks{} ` should be an interface instead of a struct
78
- - [x] Exec and Query hooks should return ` func(error) `
79
- - [ ] Arguments should be pointers so queries can be modified
80
- - [x] Implement hooks on Tx
0 commit comments