github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/lib/pq/url.go (about) 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 }