| 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() | |
| } |