github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/go-xorm/xorm/pq_driver.go (about) 1 // Copyright 2015 The Xorm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package xorm 6 7 import ( 8 "errors" 9 "fmt" 10 "net/url" 11 "sort" 12 "strings" 13 14 "github.com/insionng/yougam/libraries/go-xorm/core" 15 ) 16 17 type pqDriver struct { 18 } 19 20 type values map[string]string 21 22 func (vs values) Set(k, v string) { 23 vs[k] = v 24 } 25 26 func (vs values) Get(k string) (v string) { 27 return vs[k] 28 } 29 30 func errorf(s string, args ...interface{}) { 31 panic(fmt.Errorf("pq: %s", fmt.Sprintf(s, args...))) 32 } 33 34 func parseURL(connstr string) (string, error) { 35 u, err := url.Parse(connstr) 36 if err != nil { 37 return "", err 38 } 39 40 if u.Scheme != "postgresql" && u.Scheme != "postgres" { 41 return "", fmt.Errorf("invalid connection protocol: %s", u.Scheme) 42 } 43 44 var kvs []string 45 escaper := strings.NewReplacer(` `, `\ `, `'`, `\'`, `\`, `\\`) 46 accrue := func(k, v string) { 47 if v != "" { 48 kvs = append(kvs, k+"="+escaper.Replace(v)) 49 } 50 } 51 52 if u.User != nil { 53 v := u.User.Username() 54 accrue("user", v) 55 56 v, _ = u.User.Password() 57 accrue("password", v) 58 } 59 60 i := strings.Index(u.Host, ":") 61 if i < 0 { 62 accrue("host", u.Host) 63 } else { 64 accrue("host", u.Host[:i]) 65 accrue("port", u.Host[i+1:]) 66 } 67 68 if u.Path != "" { 69 accrue("dbname", u.Path[1:]) 70 } 71 72 q := u.Query() 73 for k := range q { 74 accrue(k, q.Get(k)) 75 } 76 77 sort.Strings(kvs) // Makes testing easier (not a performance concern) 78 return strings.Join(kvs, " "), nil 79 } 80 81 func parseOpts(name string, o values) { 82 if len(name) == 0 { 83 return 84 } 85 86 name = strings.TrimSpace(name) 87 88 ps := strings.Split(name, " ") 89 for _, p := range ps { 90 kv := strings.Split(p, "=") 91 if len(kv) < 2 { 92 errorf("invalid option: %q", p) 93 } 94 o.Set(kv[0], kv[1]) 95 } 96 } 97 98 func (p *pqDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) { 99 db := &core.Uri{DbType: core.POSTGRES} 100 o := make(values) 101 var err error 102 if strings.HasPrefix(dataSourceName, "postgresql://") || strings.HasPrefix(dataSourceName, "postgres://") { 103 dataSourceName, err = parseURL(dataSourceName) 104 if err != nil { 105 return nil, err 106 } 107 } 108 parseOpts(dataSourceName, o) 109 110 db.DbName = o.Get("dbname") 111 if db.DbName == "" { 112 return nil, errors.New("dbname is empty") 113 } 114 /*db.Schema = o.Get("schema") 115 if len(db.Schema) == 0 { 116 db.Schema = "public" 117 }*/ 118 return db, nil 119 }