-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.go
95 lines (84 loc) · 2.35 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package bigquery
import (
"encoding/base64"
"fmt"
"net/url"
"strings"
"google.golang.org/api/option"
)
type Config struct {
ProjectID string
Dataset string
Location string
Options []option.ClientOption
}
// Parses DSN of the form:
// bigquery://projectID[/location][/dataset]?key=val
func parseDSN(dsn string) (Config, error) {
url, err := url.Parse(dsn)
if err != nil {
return Config{}, &invalidConnStrError{Err: err}
}
if url.Scheme != "bigquery" {
return Config{}, &invalidConnStrError{
Err: fmt.Errorf("invalid scheme: %s", url.Scheme),
}
}
location, dataset, err := parseLocationDataset(url)
if err != nil {
return Config{}, &invalidConnStrError{Err: err}
}
options, err := parseOptions(url)
if err != nil {
return Config{}, &invalidConnStrError{Err: err}
}
return Config{
ProjectID: url.Hostname(),
Location: location,
Dataset: dataset,
Options: options,
}, nil
}
func parseLocationDataset(url *url.URL) (string, string, error) {
fields := strings.Split(strings.Trim(url.Path, "/"), "/")
switch len(fields) {
case 0:
return "", "", nil
case 1:
return "", fields[0], nil
case 2:
return fields[0], fields[1], nil
default:
return "", "", fmt.Errorf("too many path segments: %s", url.Path)
}
}
func parseOptions(url *url.URL) ([]option.ClientOption, error) {
query := url.Query()
var options []option.ClientOption
if apiKey := query.Get("apiKey"); apiKey != "" {
options = append(options, option.WithAPIKey(apiKey))
}
if credentials := query.Get("credentials"); credentials != "" {
decoded, err := base64.RawURLEncoding.DecodeString(credentials)
if err != nil {
return nil, err
}
options = append(options, option.WithCredentialsJSON([]byte(decoded)))
}
if credentialsFile := query.Get("credentialsFile"); credentialsFile != "" {
options = append(options, option.WithCredentialsFile(credentialsFile))
}
if scopes := query["scopes"]; scopes != nil {
options = append(options, option.WithScopes(scopes...))
}
if endpoint := query.Get("endpoint"); endpoint != "" {
options = append(options, option.WithEndpoint(endpoint))
}
if userAgent := query.Get("userAgent"); userAgent != "" {
options = append(options, option.WithUserAgent(userAgent))
}
if disableAuth := query.Get("disableAuth"); disableAuth == "true" {
options = append(options, option.WithoutAuthentication())
}
return options, nil
}