-
Notifications
You must be signed in to change notification settings - Fork 1
/
driver.go
93 lines (75 loc) · 2.06 KB
/
driver.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
package openmldb
import (
"context"
"database/sql"
"database/sql/driver"
"fmt"
"net/url"
"strings"
)
func init() {
sql.Register("openmldb", &openmldbDriver{})
}
// compile time validation that our types implements the expected interfaces
var (
_ driver.Driver = openmldbDriver{}
_ driver.DriverContext = openmldbDriver{}
_ driver.Connector = connecter{}
)
type openmldbDriver struct{}
func parseDsn(dsn string) (host string, db string, mode queryMode, err error) {
u, err := url.Parse(dsn)
if err != nil {
return "", "", "", fmt.Errorf("invlaid URL: %w", err)
}
if u.Scheme != "openmldb" && u.Scheme != "" {
return "", "", "", fmt.Errorf("invalid URL: unknown schema '%s'", u.Scheme)
}
p := strings.Split(strings.TrimLeft(u.Path, "/"), "/")
mode = ModeOnline
if u.Query().Has("mode") {
m := u.Query().Get("mode")
if _, ok := allQueryMode[m]; !ok {
return "", "", "", fmt.Errorf("invalid mode: %s", m)
}
mode = allQueryMode[m]
}
if len(p) == 0 {
return "", "", "", fmt.Errorf("invalid URL: DB name not found")
}
return u.Host, p[0], mode, nil
}
// Open implements driver.Driver.
func (openmldbDriver) Open(name string) (driver.Conn, error) {
// name should be the URL of the api server, e.g. openmldb://localhost:6543/db
host, db, mode, err := parseDsn(name)
if err != nil {
return nil, err
}
return &conn{host: host, db: db, mode: mode, closed: false}, nil
}
// OpenConnector implements driver.DriverContext.
func (openmldbDriver) OpenConnector(name string) (driver.Connector, error) {
host, db, mode, err := parseDsn(name)
if err != nil {
return nil, err
}
return &connecter{host, db, mode}, nil
}
type connecter struct {
host string
db string
mode queryMode
}
// Connect implements driver.Connector.
func (c connecter) Connect(ctx context.Context) (driver.Conn, error) {
conn := &conn{host: c.host, db: c.db, mode: c.mode, closed: false}
if err := conn.Ping(ctx); err != nil {
return nil, err
}
return conn, nil
}
// Driver implements driver.Connector.
func (connecter) Driver() driver.Driver {
return &openmldbDriver{}
}