added postgreSQL placeholders support
This commit is contained in:
@@ -3,6 +3,7 @@ package batcher
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"errors"
|
"errors"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"btchrr/models"
|
"btchrr/models"
|
||||||
)
|
)
|
||||||
@@ -23,7 +24,7 @@ func NewBatcher(batchSize int) (*Batcher, error) {
|
|||||||
batchSize: batchSize,
|
batchSize: batchSize,
|
||||||
placeholders: make(map[string]struct{}),
|
placeholders: make(map[string]struct{}),
|
||||||
}
|
}
|
||||||
for _, ph := range []string{"?", "$", ":", ":"} {
|
for _, ph := range []string{"?", "$", ":"} {
|
||||||
b.placeholders[ph] = struct{}{}
|
b.placeholders[ph] = struct{}{}
|
||||||
}
|
}
|
||||||
return b, nil
|
return b, nil
|
||||||
@@ -36,7 +37,7 @@ func (b *Batcher) BuildBatches(singleQuery string, items []any) ([]models.Batche
|
|||||||
return []models.BatchedQuery{}, err
|
return []models.BatchedQuery{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
batches, err := b.BuildBatchQuery(singleQuery, b.batchSize, batchedItems)
|
batches, err := b.BuildBatchQuery(singleQuery, b.batchSize, batchedItems, len(batchedItems))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []models.BatchedQuery{}, err
|
return []models.BatchedQuery{}, err
|
||||||
}
|
}
|
||||||
@@ -71,7 +72,7 @@ func (b *Batcher) batchItems(items []any) ([][]any, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BuildBatchQuery - builds a batch query from a single query
|
// BuildBatchQuery - builds a batch query from a single query
|
||||||
func (b *Batcher) BuildBatchQuery(singleQuery string, batchSize int, batchedItems [][]any) (batchedQueries []models.BatchedQuery, err error) {
|
func (b *Batcher) BuildBatchQuery(singleQuery string, batchSize int, batchedItems [][]any, numOfBatches int) (batchedQueries []models.BatchedQuery, err error) {
|
||||||
placeholder, err := b.detectPlaceholders(singleQuery)
|
placeholder, err := b.detectPlaceholders(singleQuery)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []models.BatchedQuery{}, err
|
return []models.BatchedQuery{}, err
|
||||||
@@ -79,9 +80,23 @@ func (b *Batcher) BuildBatchQuery(singleQuery string, batchSize int, batchedItem
|
|||||||
|
|
||||||
switch placeholder {
|
switch placeholder {
|
||||||
case "?":
|
case "?":
|
||||||
return b.buildSqliteQuery(singleQuery, batchedItems)
|
for i :=0; i < numOfBatches; i++ {
|
||||||
|
batchQuery, err := b.buildSqliteQuery(singleQuery, batchedItems[i])
|
||||||
|
if err != nil {
|
||||||
|
return []models.BatchedQuery{}, err
|
||||||
|
}
|
||||||
|
batchedQueries = append(batchedQueries, batchQuery)
|
||||||
|
}
|
||||||
|
return
|
||||||
case "$":
|
case "$":
|
||||||
return b.buildPostgresQuery(singleQuery, batchedItems)
|
for i :=0; i < numOfBatches; i++ {
|
||||||
|
batchQuery, err := b.buildPostgresQuery(singleQuery, batchedItems[i])
|
||||||
|
if err != nil {
|
||||||
|
return []models.BatchedQuery{}, err
|
||||||
|
}
|
||||||
|
batchedQueries = append(batchedQueries, batchQuery)
|
||||||
|
}
|
||||||
|
return
|
||||||
default:
|
default:
|
||||||
return b.buildQueryWithNamedPlaceholders(singleQuery, placeholder, batchedItems)
|
return b.buildQueryWithNamedPlaceholders(singleQuery, placeholder, batchedItems)
|
||||||
}
|
}
|
||||||
@@ -97,7 +112,7 @@ func (b *Batcher) detectPlaceholders(query string) (string, error) {
|
|||||||
return "", models.ErrCannotDetectPlaceholder
|
return "", models.ErrCannotDetectPlaceholder
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Batcher) buildSqliteQuery(singleQuery string, batchedItems [][]any) (batchedQueries models.BatchedQuery, err error) {
|
func (b *Batcher) buildSqliteQuery(singleQuery string, batchedItems []any) (batchedQueries models.BatchedQuery, err error) {
|
||||||
// INSERT INTO users VALUES (?, ?);
|
// INSERT INTO users VALUES (?, ?);
|
||||||
idx := strings.Index(strings.ToLower(singleQuery), "values")
|
idx := strings.Index(strings.ToLower(singleQuery), "values")
|
||||||
if idx == -1 {
|
if idx == -1 {
|
||||||
@@ -121,8 +136,39 @@ func (b *Batcher) buildSqliteQuery(singleQuery string, batchedItems [][]any) (ba
|
|||||||
return models.BatchedQuery(newQuery), nil
|
return models.BatchedQuery(newQuery), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Batcher) buildPostgresQuery(singleQuery string, batchedItems [][]any) (batchedQueries []models.BatchedQuery, err error) {
|
func (b *Batcher) buildPostgresQuery(singleQuery string, batchedItems []any) (batchedQueries models.BatchedQuery, err error) {
|
||||||
return []models.BatchedQuery{}, errors.New("not implemented")
|
// INSERT INTO users VALUES ($1, $2);
|
||||||
|
idx := strings.Index(strings.ToLower(singleQuery), "values")
|
||||||
|
if idx == -1 {
|
||||||
|
return "", errors.New("no values found in query")
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix := singleQuery[:idx+6] // +6 - values
|
||||||
|
valuesPart := singleQuery[idx+6:]
|
||||||
|
|
||||||
|
numOfInserts := strings.Count(valuesPart, "$")
|
||||||
|
if numOfInserts == 0 {
|
||||||
|
return "", errors.New("no placeholders found in query")
|
||||||
|
}
|
||||||
|
|
||||||
|
//INSERT INTO users VALUES ($1, $2), ($3, $4), ($5, $6);
|
||||||
|
placeholderNum := 1
|
||||||
|
query := ""
|
||||||
|
for i := 0; i < b.batchSize ; i++ {
|
||||||
|
if i > 0 {
|
||||||
|
query += ", "
|
||||||
|
}
|
||||||
|
query += "("
|
||||||
|
for j := 0; j < numOfInserts; j++ {
|
||||||
|
query += "$" + strconv.Itoa(placeholderNum) + ", "
|
||||||
|
placeholderNum++
|
||||||
|
}
|
||||||
|
query += ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
query = prefix + " " + query + ";"
|
||||||
|
|
||||||
|
return models.BatchedQuery(query), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Batcher) buildQueryWithNamedPlaceholders(singleQuery string, placeholder string, batchedItems [][]any) (batchedQueries []models.BatchedQuery, err error) {
|
func (b *Batcher) buildQueryWithNamedPlaceholders(singleQuery string, placeholder string, batchedItems [][]any) (batchedQueries []models.BatchedQuery, err error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user