@@ -18,6 +18,7 @@ import (
18
18
"database/sql"
19
19
"encoding/json"
20
20
"fmt"
21
+ "net/url"
21
22
"os"
22
23
"strconv"
23
24
"strings"
@@ -109,7 +110,7 @@ func GetDBConfigFromEnv(schema string) DBConfig {
109
110
}
110
111
111
112
// OpenDB opens a mysql connection FD
112
- func OpenDB (cfg DBConfig ) (* sql.DB , error ) {
113
+ func OpenDB (cfg DBConfig , vars map [ string ] string ) (* sql.DB , error ) {
113
114
var dbDSN string
114
115
if len (cfg .Snapshot ) != 0 {
115
116
log .Info ("create connection with snapshot" , zap .String ("snapshot" , cfg .Snapshot ))
@@ -118,6 +119,11 @@ func OpenDB(cfg DBConfig) (*sql.DB, error) {
118
119
dbDSN = fmt .Sprintf ("%s:%s@tcp(%s:%d)/?charset=utf8mb4" , cfg .User , cfg .Password , cfg .Host , cfg .Port )
119
120
}
120
121
122
+ for key , val := range vars {
123
+ // key='val'. add single quote for better compatibility.
124
+ dbDSN += fmt .Sprintf ("&%s=%%27%s%%27" , key , url .QueryEscape (val ))
125
+ }
126
+
121
127
dbConn , err := sql .Open ("mysql" , dbDSN )
122
128
if err != nil {
123
129
return nil , errors .Trace (err )
@@ -286,6 +292,47 @@ func GetMinMaxValue(ctx context.Context, db *sql.DB, schema, table, column strin
286
292
return min .String , max .String , errors .Trace (rows .Err ())
287
293
}
288
294
295
+ func GetTimeZoneOffset (ctx context.Context , db * sql.DB ) (time.Duration , error ) {
296
+ var timeStr string
297
+ err := db .QueryRowContext (ctx , "SELECT cast(TIMEDIFF(NOW(6), UTC_TIMESTAMP(6)) as time);" ).Scan (& timeStr )
298
+ if err != nil {
299
+ return 0 , errors .Trace (err )
300
+ }
301
+ factor := time .Duration (1 )
302
+ if timeStr [0 ] == '-' || timeStr [0 ] == '+' {
303
+ if timeStr [0 ] == '-' {
304
+ factor *= - 1
305
+ }
306
+ timeStr = timeStr [1 :]
307
+ }
308
+ t , err := time .Parse ("15:04:05" , timeStr )
309
+ if err != nil {
310
+ return 0 , errors .Trace (err )
311
+ }
312
+
313
+ if t .IsZero () {
314
+ return 0 , nil
315
+ }
316
+
317
+ hour , minute , second := t .Clock ()
318
+
319
+ d := time .Duration (hour * 3600 + minute * 60 + second ) * time .Second * factor
320
+ return d , nil
321
+ }
322
+
323
+ func FormatTimeZoneOffset (offset time.Duration ) string {
324
+ prefix := "+"
325
+ if offset < 0 {
326
+ prefix = "-"
327
+ offset *= - 1
328
+ }
329
+ hours := offset / time .Hour
330
+ minutes := (offset % time .Hour ) / time .Minute
331
+
332
+ return fmt .Sprintf ("%s%02d:%02d" , prefix , hours , minutes )
333
+
334
+ }
335
+
289
336
func queryTables (ctx context.Context , db * sql.DB , q string ) (tables []string , err error ) {
290
337
log .Debug ("query tables" , zap .String ("query" , q ))
291
338
rows , err := db .QueryContext (ctx , q )
0 commit comments