...
1 package pq
2
3 import (
4 "fmt"
5 "net"
6 nurl "net/url"
7 "sort"
8 "strings"
9 )
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 func ParseURL(url string) (string, error) {
33 u, err := nurl.Parse(url)
34 if err != nil {
35 return "", err
36 }
37
38 if u.Scheme != "postgres" && u.Scheme != "postgresql" {
39 return "", fmt.Errorf("invalid connection protocol: %s", u.Scheme)
40 }
41
42 var kvs []string
43 escaper := strings.NewReplacer(`'`, `\'`, `\`, `\\`)
44 accrue := func(k, v string) {
45 if v != "" {
46 kvs = append(kvs, k+"='"+escaper.Replace(v)+"'")
47 }
48 }
49
50 if u.User != nil {
51 v := u.User.Username()
52 accrue("user", v)
53
54 v, _ = u.User.Password()
55 accrue("password", v)
56 }
57
58 if host, port, err := net.SplitHostPort(u.Host); err != nil {
59 accrue("host", u.Host)
60 } else {
61 accrue("host", host)
62 accrue("port", port)
63 }
64
65 if u.Path != "" {
66 accrue("dbname", u.Path[1:])
67 }
68
69 q := u.Query()
70 for k := range q {
71 accrue(k, q.Get(k))
72 }
73
74 sort.Strings(kvs)
75 return strings.Join(kvs, " "), nil
76 }
77
View as plain text