Skip to content

Commit 3e9722f

Browse files
committed
DB: Make use of the QueryBuilder
1 parent 25353d9 commit 3e9722f

File tree

1 file changed

+11
-116
lines changed

1 file changed

+11
-116
lines changed

database/db.go

Lines changed: 11 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"net"
2424
"net/url"
2525
"strconv"
26-
"strings"
2726
"sync"
2827
"time"
2928
)
@@ -222,150 +221,46 @@ func NewDbFromConfig(c *Config, logger *logging.Logger, connectorCallbacks Retry
222221
}, nil
223222
}
224223

224+
// QueryBuilder returns a fully initialised and ready to use *[QueryBuilder] instance for the given subject/struct.
225+
func (db *DB) QueryBuilder(subject any) *QueryBuilder {
226+
return &QueryBuilder{db: db, subject: subject}
227+
}
228+
225229
// GetAddr returns the database host:port or Unix socket address.
226230
func (db *DB) GetAddr() string {
227231
return db.addr
228232
}
229233

230234
// BuildDeleteStmt returns a DELETE statement for the given struct.
231235
func (db *DB) BuildDeleteStmt(from interface{}) string {
232-
return fmt.Sprintf(
233-
`DELETE FROM "%s" WHERE id IN (?)`,
234-
TableName(from),
235-
)
236+
return db.QueryBuilder(from).Delete()
236237
}
237238

238239
// BuildInsertStmt returns an INSERT INTO statement for the given struct.
239240
func (db *DB) BuildInsertStmt(into interface{}) (string, int) {
240-
columns := db.columnMap.Columns(into)
241-
242-
return fmt.Sprintf(
243-
`INSERT INTO "%s" ("%s") VALUES (%s)`,
244-
TableName(into),
245-
strings.Join(columns, `", "`),
246-
fmt.Sprintf(":%s", strings.Join(columns, ", :")),
247-
), len(columns)
241+
return db.QueryBuilder(into).Insert()
248242
}
249243

250244
// BuildInsertIgnoreStmt returns an INSERT statement for the specified struct for
251245
// which the database ignores rows that have already been inserted.
252246
func (db *DB) BuildInsertIgnoreStmt(into interface{}) (string, int) {
253-
table := TableName(into)
254-
columns := db.columnMap.Columns(into)
255-
var clause string
256-
257-
switch db.DriverName() {
258-
case MySQL:
259-
// MySQL treats UPDATE id = id as a no-op.
260-
clause = fmt.Sprintf(`ON DUPLICATE KEY UPDATE "%s" = "%s"`, columns[0], columns[0])
261-
case PostgreSQL:
262-
var constraint string
263-
if constrainter, ok := into.(PgsqlOnConflictConstrainter); ok {
264-
constraint = constrainter.PgsqlOnConflictConstraint()
265-
} else {
266-
constraint = "pk_" + table
267-
}
268-
269-
clause = fmt.Sprintf("ON CONFLICT ON CONSTRAINT %s DO NOTHING", constraint)
270-
}
271-
272-
return fmt.Sprintf(
273-
`INSERT INTO "%s" ("%s") VALUES (%s) %s`,
274-
table,
275-
strings.Join(columns, `", "`),
276-
fmt.Sprintf(":%s", strings.Join(columns, ", :")),
277-
clause,
278-
), len(columns)
247+
return db.QueryBuilder(into).InsertIgnore()
279248
}
280249

281250
// BuildSelectStmt returns a SELECT query that creates the FROM part from the given table struct
282251
// and the column list from the specified columns struct.
283252
func (db *DB) BuildSelectStmt(table interface{}, columns interface{}) string {
284-
q := fmt.Sprintf(
285-
`SELECT "%s" FROM "%s"`,
286-
strings.Join(db.columnMap.Columns(columns), `", "`),
287-
TableName(table),
288-
)
289-
290-
if scoper, ok := table.(Scoper); ok {
291-
where, _ := db.BuildWhere(scoper.Scope())
292-
q += ` WHERE ` + where
293-
}
294-
295-
return q
253+
return db.QueryBuilder(table).SetColumns(db.columnMap.Columns(columns)...).Select()
296254
}
297255

298256
// BuildUpdateStmt returns an UPDATE statement for the given struct.
299257
func (db *DB) BuildUpdateStmt(update interface{}) (string, int) {
300-
columns := db.columnMap.Columns(update)
301-
set := make([]string, 0, len(columns))
302-
303-
for _, col := range columns {
304-
set = append(set, fmt.Sprintf(`"%s" = :%s`, col, col))
305-
}
306-
307-
return fmt.Sprintf(
308-
`UPDATE "%s" SET %s WHERE id = :id`,
309-
TableName(update),
310-
strings.Join(set, ", "),
311-
), len(columns) + 1 // +1 because of WHERE id = :id
258+
return db.QueryBuilder(update).Update()
312259
}
313260

314261
// BuildUpsertStmt returns an upsert statement for the given struct.
315262
func (db *DB) BuildUpsertStmt(subject interface{}) (stmt string, placeholders int) {
316-
insertColumns := db.columnMap.Columns(subject)
317-
table := TableName(subject)
318-
var updateColumns []string
319-
320-
if upserter, ok := subject.(Upserter); ok {
321-
updateColumns = db.columnMap.Columns(upserter.Upsert())
322-
} else {
323-
updateColumns = insertColumns
324-
}
325-
326-
var clause, setFormat string
327-
switch db.DriverName() {
328-
case MySQL:
329-
clause = "ON DUPLICATE KEY UPDATE"
330-
setFormat = `"%[1]s" = VALUES("%[1]s")`
331-
case PostgreSQL:
332-
var constraint string
333-
if constrainter, ok := subject.(PgsqlOnConflictConstrainter); ok {
334-
constraint = constrainter.PgsqlOnConflictConstraint()
335-
} else {
336-
constraint = "pk_" + table
337-
}
338-
339-
clause = fmt.Sprintf("ON CONFLICT ON CONSTRAINT %s DO UPDATE SET", constraint)
340-
setFormat = `"%[1]s" = EXCLUDED."%[1]s"`
341-
}
342-
343-
set := make([]string, 0, len(updateColumns))
344-
345-
for _, col := range updateColumns {
346-
set = append(set, fmt.Sprintf(setFormat, col))
347-
}
348-
349-
return fmt.Sprintf(
350-
`INSERT INTO "%s" ("%s") VALUES (%s) %s %s`,
351-
table,
352-
strings.Join(insertColumns, `", "`),
353-
fmt.Sprintf(":%s", strings.Join(insertColumns, ",:")),
354-
clause,
355-
strings.Join(set, ","),
356-
), len(insertColumns)
357-
}
358-
359-
// BuildWhere returns a WHERE clause with named placeholder conditions built from the specified struct
360-
// combined with the AND operator.
361-
func (db *DB) BuildWhere(subject interface{}) (string, int) {
362-
columns := db.columnMap.Columns(subject)
363-
where := make([]string, 0, len(columns))
364-
for _, col := range columns {
365-
where = append(where, fmt.Sprintf(`"%s" = :%s`, col, col))
366-
}
367-
368-
return strings.Join(where, ` AND `), len(columns)
263+
return db.QueryBuilder(subject).Upsert()
369264
}
370265

371266
// OnSuccess is a callback for successful (bulk) DML operations.

0 commit comments

Comments
 (0)