blob: 3910b1585f6cf5041c710df149c2e84ed03e06a4 [file] [log] [blame] [edit]
package sqlutil
import (
"strconv"
"strings"
)
// ValuesPlaceholders returns a set of SQL placeholder numbers grouped for use in an INSERT
// statement. For example, ValuesPlaceholders(2,3) returns ($1, $2), ($3, $4), ($5, $6)
// It panics if either param is <= 0.
func ValuesPlaceholders(valuesPerRow, numRows int) string {
if valuesPerRow <= 0 || numRows <= 0 {
panic("Cannot make ValuesPlaceholder with 0 rows or 0 values per row")
}
values := strings.Builder{}
// There are at most 5 bytes per value that need to be written
values.Grow(5 * valuesPerRow * numRows)
// All WriteString calls below return nil errors, as specified in the documentation of
// strings.Builder, so it is safe to ignore them.
for argIdx := 1; argIdx <= valuesPerRow*numRows; argIdx += valuesPerRow {
if argIdx != 1 {
_, _ = values.WriteString(",")
}
_, _ = values.WriteString("(")
for i := 0; i < valuesPerRow; i++ {
if i != 0 {
_, _ = values.WriteString(",")
}
_, _ = values.WriteString("$")
_, _ = values.WriteString(strconv.Itoa(argIdx + i))
}
_, _ = values.WriteString(")")
}
return values.String()
}
// Returns a where clause with placeholders where each column value
// is ANDed and each row is ORed
// Args:
//
// cols: List of column names
// numRows: Number of rows
//
// For example, if cols = ["name", "city"] and numRows = 2, return value
// would be (name=$1 AND city=$2) OR (name=$3 AND city=$4)
func WherePlaceholders(cols []string, numRows int) string {
if len(cols) <= 0 || numRows <= 0 {
panic("Cannot make WherePlaceHolders with 0 cols or 0 rows")
}
response := strings.Builder{}
for rowIdx := 1; rowIdx <= numRows; rowIdx += 1 {
response.WriteString("(")
for colIdx := 1; colIdx <= len(cols); colIdx++ {
response.WriteString(cols[colIdx-1])
response.WriteString("=")
response.WriteString("$")
response.WriteString(strconv.Itoa((rowIdx-1)*len(cols) + colIdx))
if colIdx != len(cols) {
response.WriteString(" AND ")
}
}
response.WriteString(")")
if rowIdx < numRows {
response.WriteString(" OR ")
}
}
return response.String()
}