Skip to content

Commit b747101

Browse files
authored
Interface enhancements (#13)
* make options.DefaultAttributes immutable * add support for DriverContext, Connector, SessionResetter, NamedValueChecker and ColumnConverter * add travis ci
1 parent a6884a0 commit b747101

File tree

6 files changed

+435
-39
lines changed

6 files changed

+435
-39
lines changed

.travis.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
language: go
2+
3+
sudo: false
4+
5+
go:
6+
- 1.8.x
7+
- 1.9.x
8+
- 1.10.x
9+
- 1.11.x
10+
- tip
11+
12+
install:
13+
- go get -d -t ./...
14+
- go get -u github.com/golang/lint/...
15+
16+
script:
17+
- golint ./...
18+
- go vet ./...
19+
- go test -v -race -cover ./...

driver.go

Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -69,21 +69,15 @@ func Wrap(d driver.Driver, options ...TraceOption) driver.Driver {
6969
if o.QueryParams && !o.Query {
7070
o.QueryParams = false
7171
}
72-
return ocDriver{parent: d, options: o}
73-
}
74-
75-
// ocDriver implements driver.Driver
76-
type ocDriver struct {
77-
parent driver.Driver
78-
options TraceOptions
72+
return wrapDriver(d, o)
7973
}
8074

8175
func (d ocDriver) Open(name string) (driver.Conn, error) {
8276
c, err := d.parent.Open(name)
8377
if err != nil {
8478
return nil, err
8579
}
86-
return &ocConn{parent: c, options: d.options}, nil
80+
return wrapConn(c, d.options), nil
8781
}
8882

8983
// ocConn implements driver.Conn
@@ -669,36 +663,6 @@ func (t ocTx) Rollback() (err error) {
669663
return
670664
}
671665

672-
func wrapStmt(stmt driver.Stmt, query string, options TraceOptions) driver.Stmt {
673-
s := ocStmt{parent: stmt, query: query, options: options}
674-
_, hasExeCtx := stmt.(driver.StmtExecContext)
675-
_, hasQryCtx := stmt.(driver.StmtQueryContext)
676-
677-
switch {
678-
case !hasExeCtx && !hasQryCtx:
679-
return struct {
680-
driver.Stmt
681-
}{s}
682-
case !hasExeCtx && hasQryCtx:
683-
return struct {
684-
driver.Stmt
685-
driver.StmtQueryContext
686-
}{s, s}
687-
case hasExeCtx && !hasQryCtx:
688-
return struct {
689-
driver.Stmt
690-
driver.StmtExecContext
691-
}{s, s}
692-
case hasExeCtx && hasQryCtx:
693-
return struct {
694-
driver.Stmt
695-
driver.StmtExecContext
696-
driver.StmtQueryContext
697-
}{s, s, s}
698-
}
699-
panic("unreachable")
700-
}
701-
702666
func paramsAttr(args []driver.Value) []trace.Attribute {
703667
attrs := make([]trace.Attribute, 0, len(args))
704668
for i, arg := range args {
@@ -759,7 +723,7 @@ func setSpanStatus(span *trace.Span, err error) {
759723
status.Code = trace.StatusCodeDeadlineExceeded
760724
case sql.ErrNoRows:
761725
status.Code = trace.StatusCodeNotFound
762-
case sql.ErrTxDone, sql.ErrConnDone:
726+
case sql.ErrTxDone, ErrConnDone:
763727
status.Code = trace.StatusCodeFailedPrecondition
764728
default:
765729
status.Code = trace.StatusCodeUnknown

driver_go1.10.go

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
// +build go1.10
2+
3+
package ocsql
4+
5+
import (
6+
"context"
7+
"database/sql"
8+
"database/sql/driver"
9+
)
10+
11+
var ErrConnDone = sql.ErrConnDone
12+
13+
// ocDriver implements driver.Driver
14+
type ocDriver struct {
15+
parent driver.Driver
16+
connector driver.Connector
17+
options TraceOptions
18+
}
19+
20+
func wrapDriver(d driver.Driver, o TraceOptions) driver.Driver {
21+
if _, ok := d.(driver.DriverContext); ok {
22+
return ocDriver{parent: d, options: o}
23+
}
24+
return struct{ driver.Driver }{ocDriver{parent: d, options: o}}
25+
}
26+
27+
func wrapConn(parent driver.Conn, options TraceOptions) driver.Conn {
28+
var (
29+
n, hasNameValueChecker = parent.(driver.NamedValueChecker)
30+
s, hasSessionResetter = parent.(driver.SessionResetter)
31+
)
32+
c := &ocConn{parent: parent, options: options}
33+
switch {
34+
case !hasNameValueChecker && !hasSessionResetter:
35+
return c
36+
case hasNameValueChecker && !hasSessionResetter:
37+
return struct {
38+
driver.Conn
39+
driver.NamedValueChecker
40+
}{c, n}
41+
case !hasNameValueChecker && hasSessionResetter:
42+
return struct {
43+
driver.Conn
44+
driver.SessionResetter
45+
}{c, s}
46+
case hasNameValueChecker && hasSessionResetter:
47+
return struct {
48+
driver.Conn
49+
driver.NamedValueChecker
50+
driver.SessionResetter
51+
}{c, n, s}
52+
}
53+
panic("unreachable")
54+
}
55+
56+
func wrapStmt(stmt driver.Stmt, query string, options TraceOptions) driver.Stmt {
57+
var (
58+
_, hasExeCtx = stmt.(driver.StmtExecContext)
59+
_, hasQryCtx = stmt.(driver.StmtQueryContext)
60+
c, hasColConv = stmt.(driver.ColumnConverter)
61+
n, hasNamValChk = stmt.(driver.NamedValueChecker)
62+
)
63+
64+
s := ocStmt{parent: stmt, query: query, options: options}
65+
switch {
66+
case !hasExeCtx && !hasQryCtx && !hasColConv && !hasNamValChk:
67+
return struct {
68+
driver.Stmt
69+
}{s}
70+
case !hasExeCtx && hasQryCtx && !hasColConv && !hasNamValChk:
71+
return struct {
72+
driver.Stmt
73+
driver.StmtQueryContext
74+
}{s, s}
75+
case hasExeCtx && !hasQryCtx && !hasColConv && !hasNamValChk:
76+
return struct {
77+
driver.Stmt
78+
driver.StmtExecContext
79+
}{s, s}
80+
case hasExeCtx && hasQryCtx && !hasColConv && !hasNamValChk:
81+
return struct {
82+
driver.Stmt
83+
driver.StmtExecContext
84+
driver.StmtQueryContext
85+
}{s, s, s}
86+
case !hasExeCtx && !hasQryCtx && hasColConv && !hasNamValChk:
87+
return struct {
88+
driver.Stmt
89+
driver.ColumnConverter
90+
}{s, c}
91+
case !hasExeCtx && hasQryCtx && hasColConv && !hasNamValChk:
92+
return struct {
93+
driver.Stmt
94+
driver.StmtQueryContext
95+
driver.ColumnConverter
96+
}{s, s, c}
97+
case hasExeCtx && !hasQryCtx && hasColConv && !hasNamValChk:
98+
return struct {
99+
driver.Stmt
100+
driver.StmtExecContext
101+
driver.ColumnConverter
102+
}{s, s, c}
103+
case hasExeCtx && hasQryCtx && hasColConv && !hasNamValChk:
104+
return struct {
105+
driver.Stmt
106+
driver.StmtExecContext
107+
driver.StmtQueryContext
108+
driver.ColumnConverter
109+
}{s, s, s, c}
110+
111+
case !hasExeCtx && !hasQryCtx && !hasColConv && hasNamValChk:
112+
return struct {
113+
driver.Stmt
114+
driver.NamedValueChecker
115+
}{s, n}
116+
case !hasExeCtx && hasQryCtx && !hasColConv && hasNamValChk:
117+
return struct {
118+
driver.Stmt
119+
driver.StmtQueryContext
120+
driver.NamedValueChecker
121+
}{s, s, n}
122+
case hasExeCtx && !hasQryCtx && !hasColConv && hasNamValChk:
123+
return struct {
124+
driver.Stmt
125+
driver.StmtExecContext
126+
driver.NamedValueChecker
127+
}{s, s, n}
128+
case hasExeCtx && hasQryCtx && !hasColConv && hasNamValChk:
129+
return struct {
130+
driver.Stmt
131+
driver.StmtExecContext
132+
driver.StmtQueryContext
133+
driver.NamedValueChecker
134+
}{s, s, s, n}
135+
case !hasExeCtx && !hasQryCtx && hasColConv && hasNamValChk:
136+
return struct {
137+
driver.Stmt
138+
driver.ColumnConverter
139+
driver.NamedValueChecker
140+
}{s, c, n}
141+
case !hasExeCtx && hasQryCtx && hasColConv && hasNamValChk:
142+
return struct {
143+
driver.Stmt
144+
driver.StmtQueryContext
145+
driver.ColumnConverter
146+
driver.NamedValueChecker
147+
}{s, s, c, n}
148+
case hasExeCtx && !hasQryCtx && hasColConv && hasNamValChk:
149+
return struct {
150+
driver.Stmt
151+
driver.StmtExecContext
152+
driver.ColumnConverter
153+
driver.NamedValueChecker
154+
}{s, s, c, n}
155+
case hasExeCtx && hasQryCtx && hasColConv && hasNamValChk:
156+
return struct {
157+
driver.Stmt
158+
driver.StmtExecContext
159+
driver.StmtQueryContext
160+
driver.ColumnConverter
161+
driver.NamedValueChecker
162+
}{s, s, s, c, n}
163+
}
164+
panic("unreachable")
165+
}
166+
167+
func (d ocDriver) OpenConnector(name string) (driver.Connector, error) {
168+
var err error
169+
d.connector, err = d.parent.(driver.DriverContext).OpenConnector(name)
170+
if err != nil {
171+
return nil, err
172+
}
173+
return d, err
174+
}
175+
176+
func (d ocDriver) Connect(ctx context.Context) (driver.Conn, error) {
177+
c, err := d.connector.Connect(ctx)
178+
if err != nil {
179+
return nil, err
180+
}
181+
return &ocConn{parent: c, options: d.options}, nil
182+
}
183+
184+
func (d ocDriver) Driver() driver.Driver {
185+
return d
186+
}

driver_go1.8.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// +build !go1.9
2+
3+
package ocsql
4+
5+
import (
6+
"database/sql/driver"
7+
"errors"
8+
)
9+
10+
// Dummy error for setSpanStatus (does exist as sql.ErrConnDone in 1.9+)
11+
var ErrConnDone = errors.New("database/sql: connection is already closed")
12+
13+
// ocDriver implements driver.Driver
14+
type ocDriver struct {
15+
parent driver.Driver
16+
options TraceOptions
17+
}
18+
19+
func wrapDriver(d driver.Driver, o TraceOptions) driver.Driver {
20+
return ocDriver{parent: d, options: o}
21+
}
22+
23+
func wrapConn(c driver.Conn, options TraceOptions) driver.Conn {
24+
return &ocConn{parent: c, options: options}
25+
}
26+
27+
func wrapStmt(stmt driver.Stmt, query string, options TraceOptions) driver.Stmt {
28+
s := ocStmt{parent: stmt, query: query, options: options}
29+
_, hasExeCtx := stmt.(driver.StmtExecContext)
30+
_, hasQryCtx := stmt.(driver.StmtQueryContext)
31+
c, hasColCnv := stmt.(driver.ColumnConverter)
32+
switch {
33+
case !hasExeCtx && !hasQryCtx && !hasColCnv:
34+
return struct {
35+
driver.Stmt
36+
}{s}
37+
case !hasExeCtx && hasQryCtx && !hasColCnv:
38+
return struct {
39+
driver.Stmt
40+
driver.StmtQueryContext
41+
}{s, s}
42+
case hasExeCtx && !hasQryCtx && !hasColCnv:
43+
return struct {
44+
driver.Stmt
45+
driver.StmtExecContext
46+
}{s, s}
47+
case hasExeCtx && hasQryCtx && !hasColCnv:
48+
return struct {
49+
driver.Stmt
50+
driver.StmtExecContext
51+
driver.StmtQueryContext
52+
}{s, s, s}
53+
case !hasExeCtx && !hasQryCtx && hasColCnv:
54+
return struct {
55+
driver.Stmt
56+
driver.ColumnConverter
57+
}{s, c}
58+
case !hasExeCtx && hasQryCtx && hasColCnv:
59+
return struct {
60+
driver.Stmt
61+
driver.StmtQueryContext
62+
driver.ColumnConverter
63+
}{s, s, c}
64+
case hasExeCtx && !hasQryCtx && hasColCnv:
65+
return struct {
66+
driver.Stmt
67+
driver.StmtExecContext
68+
driver.ColumnConverter
69+
}{s, s, c}
70+
case hasExeCtx && hasQryCtx && hasColCnv:
71+
return struct {
72+
driver.Stmt
73+
driver.StmtExecContext
74+
driver.StmtQueryContext
75+
driver.ColumnConverter
76+
}{s, s, s, c}
77+
}
78+
panic("unreachable")
79+
}

0 commit comments

Comments
 (0)