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  }