github.com/hashicorp/vault/sdk@v0.13.0/database/helper/dbutil/parseurl.go (about) 1 // Copyright (c) 2011-2013, 'pq' Contributors Portions Copyright (C) 2011 Blake 2 // Mizerany 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a copy 5 // of this software and associated documentation files (the "Software"), to deal 6 // in the Software without restriction, including without limitation the rights 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 // copies of the Software, and to permit persons to whom the Software is 9 // furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 // SOFTWARE. 21 22 // Copied from https://github.com/lib/pq/blob/v1.10.6/url.go#L32 23 24 package dbutil 25 26 import ( 27 "fmt" 28 "net" 29 nurl "net/url" 30 "sort" 31 "strings" 32 ) 33 34 // ParseURL no longer needs to be used by clients of this library since supplying a URL as a 35 // connection string to sql.Open() is now supported: 36 // 37 // sql.Open("postgres", "postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full") 38 // 39 // It remains exported here for backwards-compatibility. 40 // 41 // ParseURL converts a url to a connection string for driver.Open. 42 // Example: 43 // 44 // "postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full" 45 // 46 // converts to: 47 // 48 // "user=bob password=secret host=1.2.3.4 port=5432 dbname=mydb sslmode=verify-full" 49 // 50 // A minimal example: 51 // 52 // "postgres://" 53 // 54 // This will be blank, causing driver.Open to use all of the defaults 55 func ParseURL(url string) (string, error) { 56 u, err := nurl.Parse(url) 57 if err != nil { 58 return "", err 59 } 60 61 if u.Scheme != "postgres" && u.Scheme != "postgresql" { 62 return "", fmt.Errorf("invalid connection protocol: %s", u.Scheme) 63 } 64 65 var kvs []string 66 escaper := strings.NewReplacer(`'`, `\'`, `\`, `\\`) 67 accrue := func(k, v string) { 68 if v != "" { 69 kvs = append(kvs, k+"='"+escaper.Replace(v)+"'") 70 } 71 } 72 73 if u.User != nil { 74 v := u.User.Username() 75 accrue("user", v) 76 77 v, _ = u.User.Password() 78 accrue("password", v) 79 } 80 81 if host, port, err := net.SplitHostPort(u.Host); err != nil { 82 accrue("host", u.Host) 83 } else { 84 accrue("host", host) 85 accrue("port", port) 86 } 87 88 if u.Path != "" { 89 accrue("dbname", u.Path[1:]) 90 } 91 92 q := u.Query() 93 for k := range q { 94 accrue(k, q.Get(k)) 95 } 96 97 sort.Strings(kvs) // Makes testing easier (not a performance concern) 98 return strings.Join(kvs, " "), nil 99 }