Skip to content

Commit f19a1d2

Browse files
committed
Fixing issue with file: paths
1 parent 610d3ae commit f19a1d2

File tree

3 files changed

+87
-19
lines changed

3 files changed

+87
-19
lines changed

dburl.go

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -105,16 +105,23 @@ func Parse(urlstr string) (*URL, error) {
105105
switch {
106106
case !ok:
107107
return nil, ErrUnknownDatabaseScheme
108-
case scheme.Driver == "file" && u.Opaque != "":
108+
case scheme.Driver == "file":
109109
// determine scheme for file
110-
if typ, err := SchemeType(u.Opaque); err == nil {
111-
return Parse(typ + ":" + buildOpaque(u))
110+
s := u.opaqueOrPath()
111+
switch {
112+
case u.Transport != "tcp", strings.Index(u.OriginalScheme, "+") != -1:
113+
return nil, ErrInvalidTransportProtocol
114+
case s == "":
115+
return nil, ErrMissingPath
116+
}
117+
if typ, err := SchemeType(s); err == nil {
118+
return Parse(typ + "://" + u.buildOpaque())
112119
}
113120
return nil, ErrUnknownFileExtension
114121
case !scheme.Opaque && u.Opaque != "":
115122
// if scheme does not understand opaque URLs, retry parsing after
116123
// building fully qualified URL
117-
return Parse(u.OriginalScheme + "://" + buildOpaque(u))
124+
return Parse(u.OriginalScheme + "://" + u.buildOpaque())
118125
case scheme.Opaque && u.Opaque == "":
119126
// force Opaque
120127
u.Opaque, u.Host, u.Path, u.RawPath = u.Host+u.Path, "", "", ""
@@ -234,10 +241,35 @@ func (u *URL) Normalize(sep, empty string, cut int) string {
234241
return strings.Join(s, sep)
235242
}
236243

244+
// buildOpaque builds a opaque path.
245+
func (u *URL) buildOpaque() string {
246+
var up string
247+
if u.User != nil {
248+
up = u.User.String() + "@"
249+
}
250+
var q string
251+
if u.RawQuery != "" {
252+
q = "?" + u.RawQuery
253+
}
254+
var f string
255+
if u.Fragment != "" {
256+
f = "#" + u.Fragment
257+
}
258+
return up + u.opaqueOrPath() + q + f
259+
}
260+
261+
// opaqueOrPath returns the opaque or path value.
262+
func (u *URL) opaqueOrPath() string {
263+
if u.Opaque != "" {
264+
return u.Opaque
265+
}
266+
return u.Path
267+
}
268+
237269
// SchemeType returns the scheme type for a path.
238270
func SchemeType(name string) (string, error) {
239271
// try to resolve the path on unix systems
240-
if runtime.GOOS != "windows" /*&& !mode(name).IsRegular()*/ {
272+
if runtime.GOOS != "windows" {
241273
if typ, ok := resolveType(name); ok {
242274
return typ, nil
243275
}
@@ -315,21 +347,13 @@ var OpenFile = func(name string) (fs.File, error) {
315347
return f, nil
316348
}
317349

318-
// buildOpaque builds a opaque path from u.
319-
func buildOpaque(u *URL) string {
320-
var q string
321-
if u.RawQuery != "" {
322-
q = "?" + u.RawQuery
323-
}
324-
var f string
325-
if u.Fragment != "" {
326-
f = "#" + u.Fragment
327-
}
328-
return u.Opaque + q + f
329-
}
330-
331350
// resolveType tries to resolve a path to a Unix domain socket or directory.
332351
func resolveType(s string) (string, bool) {
352+
if i := strings.LastIndex(s, "?"); i != -1 {
353+
if _, err := Stat(s[:i]); err == nil {
354+
s = s[:i]
355+
}
356+
}
333357
dir := s
334358
for dir != "" && dir != "/" && dir != "." {
335359
// chop off :4444 port

dburl_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,10 +816,51 @@ func TestParse(t *testing.T) {
816816
`fake.dk`,
817817
``,
818818
},
819+
{
820+
`file:/var/run/mysqld/mysqld.sock/mydb?timeout=90`,
821+
`mysql`,
822+
`unix(/var/run/mysqld/mysqld.sock)/mydb?timeout=90`,
823+
`/var/run/mysqld/mysqld.sock`,
824+
},
825+
{
826+
`file:/var/run/postgresql`,
827+
`postgres`,
828+
`host=/var/run/postgresql`,
829+
`/var/run/postgresql`,
830+
},
831+
{
832+
`file:/var/run/postgresql:6666/mydb`,
833+
`postgres`,
834+
`dbname=mydb host=/var/run/postgresql port=6666`,
835+
`/var/run/postgresql`,
836+
},
837+
{
838+
`file:/var/run/postgresql/mydb`,
839+
`postgres`,
840+
`dbname=mydb host=/var/run/postgresql`,
841+
`/var/run/postgresql`,
842+
},
843+
{
844+
`file:/var/run/postgresql:7777`,
845+
`postgres`,
846+
`host=/var/run/postgresql port=7777`,
847+
`/var/run/postgresql`,
848+
},
849+
{
850+
`file://user:pass@/var/run/postgresql/mydb`,
851+
`postgres`,
852+
`dbname=mydb host=/var/run/postgresql password=pass user=user`,
853+
`/var/run/postgresql`,
854+
},
819855
}
856+
m := make(map[string]bool)
820857
for i, tt := range tests {
821858
test := tt
822859
t.Run(strconv.Itoa(i), func(t *testing.T) {
860+
if _, ok := m[test.s]; ok {
861+
t.Fatalf("%s is already tested", test.s)
862+
}
863+
m[test.s] = true
823864
testParse(t, test.s, test.d, test.exp, test.path)
824865
})
825866
}

scheme.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,10 @@ func SchemeDriverAndAliases(name string) (string, []string) {
512512

513513
// ShortAlias returns the short alias for the scheme name.
514514
func ShortAlias(name string) string {
515-
return schemeMap[name].Aliases[0]
515+
if scheme, ok := schemeMap[name]; ok {
516+
return scheme.Aliases[0]
517+
}
518+
return ""
516519
}
517520

518521
// isSqlite3Header returns true when the passed header is empty or starts with

0 commit comments

Comments
 (0)