1
+ // +build go1.9
2
+
1
3
package postgres
2
4
3
5
import (
@@ -7,9 +9,10 @@ import (
7
9
"io/ioutil"
8
10
nurl "net/url"
9
11
10
- "github.com/lib/pq "
12
+ "context "
11
13
"github.com/golang-migrate/migrate"
12
14
"github.com/golang-migrate/migrate/database"
15
+ "github.com/lib/pq"
13
16
)
14
17
15
18
func init () {
@@ -33,7 +36,8 @@ type Config struct {
33
36
}
34
37
35
38
type Postgres struct {
36
- db * sql.DB
39
+ // Locking and unlocking need to use the same connection
40
+ conn * sql.Conn
37
41
isLocked bool
38
42
39
43
// Open and WithInstance need to garantuee that config is never nil
@@ -65,8 +69,14 @@ func WithInstance(instance *sql.DB, config *Config) (database.Driver, error) {
65
69
config .MigrationsTable = DefaultMigrationsTable
66
70
}
67
71
72
+ conn , err := instance .Conn (context .Background ())
73
+
74
+ if err != nil {
75
+ return nil , err
76
+ }
77
+
68
78
px := & Postgres {
69
- db : instance ,
79
+ conn : conn ,
70
80
config : config ,
71
81
}
72
82
@@ -105,7 +115,7 @@ func (p *Postgres) Open(url string) (database.Driver, error) {
105
115
}
106
116
107
117
func (p * Postgres ) Close () error {
108
- return p .db .Close ()
118
+ return p .conn .Close ()
109
119
}
110
120
111
121
// https://www.postgresql.org/docs/9.6/static/explicit-locking.html#ADVISORY-LOCKS
@@ -123,7 +133,7 @@ func (p *Postgres) Lock() error {
123
133
// or return false if the lock cannot be acquired immediately.
124
134
query := `SELECT pg_try_advisory_lock($1)`
125
135
var success bool
126
- if err := p .db . QueryRow ( query , aid ).Scan (& success ); err != nil {
136
+ if err := p .conn . QueryRowContext ( context . Background (), query , aid ).Scan (& success ); err != nil {
127
137
return & database.Error {OrigErr : err , Err : "try lock failed" , Query : []byte (query )}
128
138
}
129
139
@@ -146,7 +156,7 @@ func (p *Postgres) Unlock() error {
146
156
}
147
157
148
158
query := `SELECT pg_advisory_unlock($1)`
149
- if _ , err := p .db . Exec ( query , aid ); err != nil {
159
+ if _ , err := p .conn . ExecContext ( context . Background (), query , aid ); err != nil {
150
160
return & database.Error {OrigErr : err , Query : []byte (query )}
151
161
}
152
162
p .isLocked = false
@@ -161,7 +171,7 @@ func (p *Postgres) Run(migration io.Reader) error {
161
171
162
172
// run migration
163
173
query := string (migr [:])
164
- if _ , err := p .db . Exec ( query ); err != nil {
174
+ if _ , err := p .conn . ExecContext ( context . Background (), query ); err != nil {
165
175
// TODO: cast to postgress error and get line number
166
176
return database.Error {OrigErr : err , Err : "migration failed" , Query : migr }
167
177
}
@@ -170,7 +180,7 @@ func (p *Postgres) Run(migration io.Reader) error {
170
180
}
171
181
172
182
func (p * Postgres ) SetVersion (version int , dirty bool ) error {
173
- tx , err := p .db . Begin ( )
183
+ tx , err := p .conn . BeginTx ( context . Background (), & sql. TxOptions {} )
174
184
if err != nil {
175
185
return & database.Error {OrigErr : err , Err : "transaction start failed" }
176
186
}
@@ -198,7 +208,7 @@ func (p *Postgres) SetVersion(version int, dirty bool) error {
198
208
199
209
func (p * Postgres ) Version () (version int , dirty bool , err error ) {
200
210
query := `SELECT version, dirty FROM "` + p .config .MigrationsTable + `" LIMIT 1`
201
- err = p .db . QueryRow ( query ).Scan (& version , & dirty )
211
+ err = p .conn . QueryRowContext ( context . Background (), query ).Scan (& version , & dirty )
202
212
switch {
203
213
case err == sql .ErrNoRows :
204
214
return database .NilVersion , false , nil
@@ -219,7 +229,7 @@ func (p *Postgres) Version() (version int, dirty bool, err error) {
219
229
func (p * Postgres ) Drop () error {
220
230
// select all tables in current schema
221
231
query := `SELECT table_name FROM information_schema.tables WHERE table_schema=(SELECT current_schema())`
222
- tables , err := p .db . Query ( query )
232
+ tables , err := p .conn . QueryContext ( context . Background (), query )
223
233
if err != nil {
224
234
return & database.Error {OrigErr : err , Query : []byte (query )}
225
235
}
@@ -241,7 +251,7 @@ func (p *Postgres) Drop() error {
241
251
// delete one by one ...
242
252
for _ , t := range tableNames {
243
253
query = `DROP TABLE IF EXISTS ` + t + ` CASCADE`
244
- if _ , err := p .db . Exec ( query ); err != nil {
254
+ if _ , err := p .conn . ExecContext ( context . Background (), query ); err != nil {
245
255
return & database.Error {OrigErr : err , Query : []byte (query )}
246
256
}
247
257
}
@@ -257,7 +267,7 @@ func (p *Postgres) ensureVersionTable() error {
257
267
// check if migration table exists
258
268
var count int
259
269
query := `SELECT COUNT(1) FROM information_schema.tables WHERE table_name = $1 AND table_schema = (SELECT current_schema()) LIMIT 1`
260
- if err := p .db . QueryRow ( query , p .config .MigrationsTable ).Scan (& count ); err != nil {
270
+ if err := p .conn . QueryRowContext ( context . Background (), query , p .config .MigrationsTable ).Scan (& count ); err != nil {
261
271
return & database.Error {OrigErr : err , Query : []byte (query )}
262
272
}
263
273
if count == 1 {
@@ -266,7 +276,7 @@ func (p *Postgres) ensureVersionTable() error {
266
276
267
277
// if not, create the empty migration table
268
278
query = `CREATE TABLE "` + p .config .MigrationsTable + `" (version bigint not null primary key, dirty boolean not null)`
269
- if _ , err := p .db . Exec ( query ); err != nil {
279
+ if _ , err := p .conn . ExecContext ( context . Background (), query ); err != nil {
270
280
return & database.Error {OrigErr : err , Query : []byte (query )}
271
281
}
272
282
return nil
0 commit comments