github.com/shuguocloud/go-zero@v1.3.0/core/stores/sqlx/utils.go (about) 1 package sqlx 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 8 "github.com/shuguocloud/go-zero/core/logx" 9 "github.com/shuguocloud/go-zero/core/mapping" 10 ) 11 12 func desensitize(datasource string) string { 13 // remove account 14 pos := strings.LastIndex(datasource, "@") 15 if 0 <= pos && pos+1 < len(datasource) { 16 datasource = datasource[pos+1:] 17 } 18 19 return datasource 20 } 21 22 func escape(input string) string { 23 var b strings.Builder 24 25 for _, ch := range input { 26 switch ch { 27 case '\x00': 28 b.WriteString(`\x00`) 29 case '\r': 30 b.WriteString(`\r`) 31 case '\n': 32 b.WriteString(`\n`) 33 case '\\': 34 b.WriteString(`\\`) 35 case '\'': 36 b.WriteString(`\'`) 37 case '"': 38 b.WriteString(`\"`) 39 case '\x1a': 40 b.WriteString(`\x1a`) 41 default: 42 b.WriteRune(ch) 43 } 44 } 45 46 return b.String() 47 } 48 49 func format(query string, args ...interface{}) (string, error) { 50 numArgs := len(args) 51 if numArgs == 0 { 52 return query, nil 53 } 54 55 var b strings.Builder 56 var argIndex int 57 bytes := len(query) 58 59 for i := 0; i < bytes; i++ { 60 ch := query[i] 61 switch ch { 62 case '?': 63 if argIndex >= numArgs { 64 return "", fmt.Errorf("error: %d ? in sql, but less arguments provided", argIndex) 65 } 66 67 writeValue(&b, args[argIndex]) 68 argIndex++ 69 case '$': 70 var j int 71 for j = i + 1; j < bytes; j++ { 72 char := query[j] 73 if char < '0' || '9' < char { 74 break 75 } 76 } 77 if j > i+1 { 78 index, err := strconv.Atoi(query[i+1 : j]) 79 if err != nil { 80 return "", err 81 } 82 83 // index starts from 1 for pg 84 if index > argIndex { 85 argIndex = index 86 } 87 index-- 88 if index < 0 || numArgs <= index { 89 return "", fmt.Errorf("error: wrong index %d in sql", index) 90 } 91 92 writeValue(&b, args[index]) 93 i = j - 1 94 } 95 default: 96 b.WriteByte(ch) 97 } 98 } 99 100 if argIndex < numArgs { 101 return "", fmt.Errorf("error: %d arguments provided, not matching sql", argIndex) 102 } 103 104 return b.String(), nil 105 } 106 107 func logInstanceError(datasource string, err error) { 108 datasource = desensitize(datasource) 109 logx.Errorf("Error on getting sql instance of %s: %v", datasource, err) 110 } 111 112 func logSqlError(stmt string, err error) { 113 if err != nil && err != ErrNotFound { 114 logx.Errorf("stmt: %s, error: %s", stmt, err.Error()) 115 } 116 } 117 118 func writeValue(buf *strings.Builder, arg interface{}) { 119 switch v := arg.(type) { 120 case bool: 121 if v { 122 buf.WriteByte('1') 123 } else { 124 buf.WriteByte('0') 125 } 126 case string: 127 buf.WriteByte('\'') 128 buf.WriteString(escape(v)) 129 buf.WriteByte('\'') 130 default: 131 buf.WriteString(mapping.Repr(v)) 132 } 133 }