1 | package pq
|
---|
2 |
|
---|
3 | import (
|
---|
4 | "fmt"
|
---|
5 | "net"
|
---|
6 | nurl "net/url"
|
---|
7 | "sort"
|
---|
8 | "strings"
|
---|
9 | )
|
---|
10 |
|
---|
11 | // ParseURL no longer needs to be used by clients of this library since supplying a URL as a
|
---|
12 | // connection string to sql.Open() is now supported:
|
---|
13 | //
|
---|
14 | // sql.Open("postgres", "postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full")
|
---|
15 | //
|
---|
16 | // It remains exported here for backwards-compatibility.
|
---|
17 | //
|
---|
18 | // ParseURL converts a url to a connection string for driver.Open.
|
---|
19 | // Example:
|
---|
20 | //
|
---|
21 | // "postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full"
|
---|
22 | //
|
---|
23 | // converts to:
|
---|
24 | //
|
---|
25 | // "user=bob password=secret host=1.2.3.4 port=5432 dbname=mydb sslmode=verify-full"
|
---|
26 | //
|
---|
27 | // A minimal example:
|
---|
28 | //
|
---|
29 | // "postgres://"
|
---|
30 | //
|
---|
31 | // This will be blank, causing driver.Open to use all of the defaults
|
---|
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) // Makes testing easier (not a performance concern)
|
---|
75 | return strings.Join(kvs, " "), nil
|
---|
76 | }
|
---|