Skip to content

Commit 9442ebc

Browse files
yuyicgweiguoz
authored andcommitted
support database name in connection url (#28)
* support database name in connection url * code format
1 parent 3b92514 commit 9442ebc

File tree

5 files changed

+122
-24
lines changed

5 files changed

+122
-24
lines changed

driver.go

+5
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ func (d drv) Open(dsn string) (driver.Conn, error) {
3939
s.Password = &cfg.Passwd
4040
}
4141
}
42+
if cfg.DBName != "" {
43+
config := make(map[string]string)
44+
config["use:database"] = cfg.DBName
45+
s.Configuration = config
46+
}
4247
session, _ := client.OpenSession(s)
4348
if err != nil {
4449
return nil, err

driver_test.go

+49-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func TestOpenConnection(t *testing.T) {
1616

1717
func TestQuery(t *testing.T) {
1818
db, _ := sql.Open("hive", "127.0.0.1:10000/churn")
19-
rows, err := db.Query("SELECT customerID, gender FROM churn.train")
19+
rows, err := db.Query("SELECT customerID, gender FROM train")
2020
assert.Nil(t, err)
2121
defer db.Close()
2222
defer rows.Close()
@@ -36,7 +36,7 @@ func TestQuery(t *testing.T) {
3636
func TestColumnName(t *testing.T) {
3737
a := assert.New(t)
3838
db, _ := sql.Open("hive", "127.0.0.1:10000/churn")
39-
rows, err := db.Query("SELECT customerID, gender FROM churn.train")
39+
rows, err := db.Query("SELECT customerID, gender FROM train")
4040
assert.Nil(t, err)
4141
defer db.Close()
4242
defer rows.Close()
@@ -49,7 +49,7 @@ func TestColumnName(t *testing.T) {
4949
func TestColumnTypeName(t *testing.T) {
5050
a := assert.New(t)
5151
db, _ := sql.Open("hive", "127.0.0.1:10000/churn")
52-
rows, err := db.Query("SELECT customerID, gender FROM churn.train")
52+
rows, err := db.Query("SELECT customerID, gender FROM train")
5353
assert.Nil(t, err)
5454
defer db.Close()
5555
defer rows.Close()
@@ -64,7 +64,52 @@ func TestColumnTypeName(t *testing.T) {
6464
func TestColumnType(t *testing.T) {
6565
a := assert.New(t)
6666
db, _ := sql.Open("hive", "127.0.0.1:10000/churn")
67-
rows, err := db.Query("SELECT customerID, gender FROM churn.train")
67+
rows, err := db.Query("SELECT customerID, gender FROM train")
68+
69+
defer db.Close()
70+
defer rows.Close()
71+
72+
cts, err := rows.ColumnTypes()
73+
a.NoError(err)
74+
for _, ct := range cts {
75+
assert.Equal(t, reflect.TypeOf("string"), ct.ScanType())
76+
}
77+
}
78+
79+
func TestShowCreateTable(t *testing.T) {
80+
a := assert.New(t)
81+
db, _ := sql.Open("hive", "127.0.0.1:10000/churn")
82+
rows, err := db.Query("show create table train")
83+
84+
defer db.Close()
85+
defer rows.Close()
86+
87+
cts, err := rows.ColumnTypes()
88+
a.NoError(err)
89+
for _, ct := range cts {
90+
assert.Equal(t, reflect.TypeOf("string"), ct.ScanType())
91+
}
92+
}
93+
94+
func TestDescribeTable(t *testing.T) {
95+
a := assert.New(t)
96+
db, _ := sql.Open("hive", "127.0.0.1:10000/churn")
97+
rows, err := db.Query("describe train")
98+
99+
defer db.Close()
100+
defer rows.Close()
101+
102+
cts, err := rows.ColumnTypes()
103+
a.NoError(err)
104+
for _, ct := range cts {
105+
assert.Equal(t, reflect.TypeOf("string"), ct.ScanType())
106+
}
107+
}
108+
109+
func TestShowDatabases(t *testing.T) {
110+
a := assert.New(t)
111+
db, _ := sql.Open("hive", "127.0.0.1:10000")
112+
rows, err := db.Query("show databases")
68113

69114
defer db.Close()
70115
defer rows.Close()

dsn.go

+21-7
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@ package gohive
33
import (
44
"fmt"
55
"regexp"
6+
"strings"
67
)
78

89
type Config struct {
910
User string
1011
Passwd string
1112
Addr string
13+
DBName string
1214
}
1315

1416
var (
1517
// Regexp syntax: https://github.com/google/re2/wiki/Syntax
16-
reDSN = regexp.MustCompile(`(.+@)?([^@/]+)`)
18+
reDSN = regexp.MustCompile(`(.+@)?([^@]+)`)
1719
reUserPasswd = regexp.MustCompile(`([^:@]+)(:[^:@]+)?@`)
1820
)
1921

@@ -22,20 +24,32 @@ func ParseDSN(dsn string) (*Config, error) {
2224
// Please read https://play.golang.org/p/_CSLvl1AxOX before code review.
2325
sub := reDSN.FindStringSubmatch(dsn)
2426
if len(sub) != 3 {
25-
return nil, fmt.Errorf("The DSN %s doesn't match [user[:password]@]addr", dsn)
27+
return nil, fmt.Errorf("The DSN %s doesn't match [user[:password]@]addr[/dbname]", dsn)
28+
}
29+
addr := ""
30+
dbname := ""
31+
loc := strings.IndexRune(sub[2], '/')
32+
if loc > -1 {
33+
addr = sub[2][:loc]
34+
dbname = sub[2][loc+1:]
35+
} else {
36+
addr = sub[2]
2637
}
27-
2838
up := reUserPasswd.FindStringSubmatch(sub[1])
2939
if len(up) == 3 {
3040
if len(up[2]) > 0 {
31-
return &Config{User: up[1], Passwd: up[2][1:], Addr: sub[2]}, nil
41+
return &Config{User: up[1], Passwd: up[2][1:], Addr: addr, DBName: dbname}, nil
3242
}
33-
return &Config{User: up[1], Addr: sub[2]}, nil
43+
return &Config{User: up[1], Addr: addr, DBName: dbname}, nil
3444
}
35-
return &Config{Addr: sub[2]}, nil
45+
return &Config{Addr: addr, DBName: dbname}, nil
3646
}
3747

3848
// FormatDSN outputs a string in the format "user:password@address"
3949
func (cfg *Config) FormatDSN() string {
40-
return fmt.Sprintf("%s:%s@%s", cfg.User, cfg.Passwd, cfg.Addr)
50+
if len(cfg.DBName) > 0 {
51+
return fmt.Sprintf("%s:%s@%s/%s", cfg.User, cfg.Passwd, cfg.Addr, cfg.DBName)
52+
} else {
53+
return fmt.Sprintf("%s:%s@%s", cfg.User, cfg.Passwd, cfg.Addr)
54+
}
4155
}

dsn_test.go

+45-13
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,59 @@ import (
66
"github.com/stretchr/testify/assert"
77
)
88

9-
func TestParseDSN(t *testing.T) {
9+
func TestParseDSNWithDBName(t *testing.T) {
10+
cfg, e := ParseDSN("root:[email protected]/mnist")
11+
assert.Nil(t, e)
12+
assert.Equal(t, cfg.User, "root")
13+
assert.Equal(t, cfg.Passwd, "root")
14+
assert.Equal(t, cfg.Addr, "127.0.0.1")
15+
assert.Equal(t, cfg.DBName, "mnist")
16+
17+
cfg, e = ParseDSN("[email protected]/mnist")
18+
assert.Nil(t, e)
19+
assert.Equal(t, cfg.User, "root")
20+
assert.Equal(t, cfg.Passwd, "")
21+
assert.Equal(t, cfg.Addr, "127.0.0.1")
22+
assert.Equal(t, cfg.DBName, "mnist")
23+
24+
cfg, e = ParseDSN("127.0.0.1/mnist")
25+
assert.Nil(t, e)
26+
assert.Equal(t, cfg.User, "")
27+
assert.Equal(t, cfg.Passwd, "")
28+
assert.Equal(t, cfg.Addr, "127.0.0.1")
29+
assert.Equal(t, cfg.DBName, "mnist")
30+
}
31+
32+
func TestParseDSNWithoutDBName(t *testing.T) {
1033
cfg, e := ParseDSN("root:[email protected]")
1134
assert.Nil(t, e)
1235
assert.Equal(t, cfg.User, "root")
1336
assert.Equal(t, cfg.Passwd, "root")
1437
assert.Equal(t, cfg.Addr, "127.0.0.1")
1538

16-
// cfg, e = parseDSN("[email protected]")
17-
// assert.Nil(t, e)
18-
// assert.Equal(t, cfg.User, "root")
19-
// assert.Equal(t, cfg.Passwd, "")
20-
// assert.Equal(t, cfg.Addr, "127.0.0.1")
21-
22-
// cfg, e = parseDSN("127.0.0.1")
23-
// assert.Nil(t, e)
24-
// assert.Equal(t, cfg.User, "")
25-
// assert.Equal(t, cfg.Passwd, "")
26-
// assert.Equal(t, cfg.Addr, "127.0.0.1")
39+
cfg, e = ParseDSN("[email protected]")
40+
assert.Nil(t, e)
41+
assert.Equal(t, cfg.User, "root")
42+
assert.Equal(t, cfg.Passwd, "")
43+
assert.Equal(t, cfg.Addr, "127.0.0.1")
44+
45+
cfg, e = ParseDSN("127.0.0.1")
46+
assert.Nil(t, e)
47+
assert.Equal(t, cfg.User, "")
48+
assert.Equal(t, cfg.Passwd, "")
49+
assert.Equal(t, cfg.Addr, "127.0.0.1")
50+
}
51+
52+
func TestFormatDSNWithDBName(t *testing.T) {
53+
ds := "user:[email protected]/mnist"
54+
cfg, e := ParseDSN(ds)
55+
assert.Nil(t, e)
56+
57+
ds2 := cfg.FormatDSN()
58+
assert.Equal(t, ds2, ds)
2759
}
2860

29-
func TestFormatDSN(t *testing.T) {
61+
func TestFormatDSNWithoutDBName(t *testing.T) {
3062
ds := "user:[email protected]"
3163
cfg, e := ParseDSN(ds)
3264
assert.Nil(t, e)

rows.go

+2
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ var (
107107
func (r *rowSet) ColumnTypeScanType(i int) reflect.Type {
108108
ct := r.columns[i].TypeDesc.Types[0].PrimitiveEntry.Type
109109
switch ct {
110+
case hiveserver2.TTypeId_STRING_TYPE:
111+
return scanTypeVarchar
110112
case hiveserver2.TTypeId_VARCHAR_TYPE:
111113
return scanTypeVarchar
112114
case hiveserver2.TTypeId_BOOLEAN_TYPE:

0 commit comments

Comments
 (0)