github.com/bcampbell/scrapeomat@v0.0.0-20220820232205-23e64141c89e/store/sqlstore/bind.go (about) 1 package sqlstore 2 3 import ( 4 "strconv" 5 "strings" 6 ) 7 8 // This code is from github.com/jmoiron/sqlx (MIT license) 9 // (maybe should just import sqlx and be done with it, but currently 10 // it's just rebind we need). 11 12 // Bindvar types supported by Rebind, BindMap and BindStruct. 13 const ( 14 UNKNOWN = iota 15 QUESTION 16 DOLLAR 17 NAMED 18 AT 19 ) 20 21 // bindType returns the bindtype for a given database given a drivername. 22 func bindType(driverName string) int { 23 switch driverName { 24 case "postgres", "pgx", "pq-timeouts", "cloudsqlpostgres", "ql": 25 return DOLLAR 26 case "mysql": 27 return QUESTION 28 case "sqlite3": 29 return QUESTION 30 case "oci8", "ora", "goracle": 31 return NAMED 32 case "sqlserver": 33 return AT 34 } 35 return UNKNOWN 36 } 37 38 // FIXME: this should be able to be tolerant of escaped ?'s in queries without 39 // losing much speed, and should be to avoid confusion. 40 41 // rebind a query from the default bindtype (QUESTION) to the target bindtype. 42 func rebind(bindType int, query string) string { 43 switch bindType { 44 case QUESTION, UNKNOWN: 45 return query 46 } 47 48 // Add space enough for 10 params before we have to allocate 49 rqb := make([]byte, 0, len(query)+10) 50 51 var i, j int 52 53 for i = strings.Index(query, "?"); i != -1; i = strings.Index(query, "?") { 54 rqb = append(rqb, query[:i]...) 55 56 switch bindType { 57 case DOLLAR: 58 rqb = append(rqb, '$') 59 case NAMED: 60 rqb = append(rqb, ':', 'a', 'r', 'g') 61 case AT: 62 rqb = append(rqb, '@', 'p') 63 } 64 65 j++ 66 rqb = strconv.AppendInt(rqb, int64(j), 10) 67 68 query = query[i+1:] 69 } 70 71 return string(append(rqb, query...)) 72 }