@@ -17,6 +17,7 @@ package database
17
17
18
18
import (
19
19
"context"
20
+ "database/sql"
20
21
"encoding/base64"
21
22
"errors"
22
23
"fmt"
@@ -32,7 +33,8 @@ import (
32
33
"go.uber.org/zap"
33
34
34
35
// ensure the postgres dialiect is compiled in.
35
- _ "github.com/jinzhu/gorm/dialects/postgres"
36
+ "contrib.go.opencensus.io/integrations/ocsql"
37
+ postgres "github.com/lib/pq"
36
38
)
37
39
38
40
// Database is a handle to the database layer for the Exposure Notifications
@@ -53,6 +55,20 @@ type Database struct {
53
55
54
56
// secretManager is used to resolve secrets.
55
57
secretManager secrets.SecretManager
58
+
59
+ statsCloser func ()
60
+ }
61
+
62
+ // Overrides the postgresql driver with
63
+ func init () {
64
+ const driverName = "ocsql"
65
+ for _ , v := range sql .Drivers () {
66
+ if v == driverName {
67
+ return
68
+ }
69
+ }
70
+ ocsql .RegisterAllViews ()
71
+ sql .Register (driverName , ocsql .Wrap (& postgres.Driver {}))
56
72
}
57
73
58
74
// SupportsPerRealmSigning returns true if the configuration supports
@@ -129,19 +145,37 @@ func (db *Database) OpenWithCacher(ctx context.Context, cacher cache.Cacher) err
129
145
130
146
// Establish a connection to the database. We use this later to register
131
147
// opencenusus stats.
148
+ var rawSQL * sql.DB
149
+ if err := withRetries (ctx , func (ctx context.Context ) error {
150
+ var err error
151
+ rawSQL , err = sql .Open ("ocsql" , c .ConnectionString ())
152
+ if err != nil {
153
+ return retry .RetryableError (err )
154
+ }
155
+ db .statsCloser = ocsql .RecordStats (rawSQL , 5 * time .Second )
156
+ return nil
157
+ }); err != nil {
158
+ return fmt .Errorf ("failed to create sql connection: %w" , err )
159
+ }
160
+ if rawSQL == nil {
161
+ return fmt .Errorf ("failed to create database connection" )
162
+ }
163
+
132
164
var rawDB * gorm.DB
133
165
if err := withRetries (ctx , func (ctx context.Context ) error {
134
166
var err error
135
- rawDB , err = gorm .Open ("postgres" , c .ConnectionString ())
167
+ // Need to give postgres dialect as otherwise gorm starts running
168
+ // in compatibility mode
169
+ rawDB , err = gorm .Open ("postgres" , rawSQL )
136
170
if err != nil {
137
171
return retry .RetryableError (err )
138
172
}
139
173
return nil
140
174
}); err != nil {
141
- return fmt .Errorf ("failed to connect to database : %w" , err )
175
+ return fmt .Errorf ("failed to initialize gorm : %w" , err )
142
176
}
143
177
if rawDB == nil {
144
- return fmt .Errorf ("failed to create database connection " )
178
+ return fmt .Errorf ("failed to initialize gorm " )
145
179
}
146
180
147
181
// Set connection configuration.
@@ -194,6 +228,7 @@ func (db *Database) OpenWithCacher(ctx context.Context, cacher cache.Cacher) err
194
228
195
229
// Close will close the database connection. Should be deferred right after Open.
196
230
func (db * Database ) Close () error {
231
+ db .statsCloser ()
197
232
return db .db .Close ()
198
233
}
199
234
0 commit comments