@@ -2,7 +2,6 @@ package database
22
33import (
44 "context"
5- "fmt"
65 "github.com/go-sql-driver/mysql"
76 "github.com/icinga/icinga-go-library/backoff"
87 "github.com/icinga/icinga-go-library/com"
@@ -19,7 +18,6 @@ import (
1918 "golang.org/x/sync/semaphore"
2019 "net/url"
2120 "strconv"
22- "strings"
2321 "sync"
2422 "time"
2523)
@@ -202,129 +200,37 @@ func (db *DB) BuildColumns(subject interface{}) []string {
202200
203201// BuildDeleteStmt returns a DELETE statement for the given struct.
204202func (db * DB ) BuildDeleteStmt (from interface {}) string {
205- return fmt .Sprintf (
206- `DELETE FROM "%s" WHERE id IN (?)` ,
207- TableName (from ),
208- )
203+ return NewQB (from ).Delete ()
209204}
210205
211206// BuildInsertStmt returns an INSERT INTO statement for the given struct.
212207func (db * DB ) BuildInsertStmt (into interface {}) (string , int ) {
213- columns := db .BuildColumns (into )
214-
215- return fmt .Sprintf (
216- `INSERT INTO "%s" ("%s") VALUES (%s)` ,
217- TableName (into ),
218- strings .Join (columns , `", "` ),
219- fmt .Sprintf (":%s" , strings .Join (columns , ", :" )),
220- ), len (columns )
208+ return NewQB (into ).Insert (db )
221209}
222210
223211// BuildInsertIgnoreStmt returns an INSERT statement for the specified struct for
224212// which the database ignores rows that have already been inserted.
225213func (db * DB ) BuildInsertIgnoreStmt (into interface {}) (string , int ) {
226- table := TableName (into )
227- columns := db .BuildColumns (into )
228- var clause string
229-
230- switch db .DriverName () {
231- case driver .MySQL :
232- // MySQL treats UPDATE id = id as a no-op.
233- clause = fmt .Sprintf (`ON DUPLICATE KEY UPDATE "%s" = "%s"` , columns [0 ], columns [0 ])
234- case driver .PostgreSQL :
235- clause = fmt .Sprintf ("ON CONFLICT ON CONSTRAINT pk_%s DO NOTHING" , table )
236- }
237-
238- return fmt .Sprintf (
239- `INSERT INTO "%s" ("%s") VALUES (%s) %s` ,
240- table ,
241- strings .Join (columns , `", "` ),
242- fmt .Sprintf (":%s" , strings .Join (columns , ", :" )),
243- clause ,
244- ), len (columns )
214+ return NewQB (into ).InsertIgnore (db )
245215}
246216
247217// BuildSelectStmt returns a SELECT query that creates the FROM part from the given table struct
248218// and the column list from the specified columns struct.
249219func (db * DB ) BuildSelectStmt (table interface {}, columns interface {}) string {
250- q := fmt .Sprintf (
251- `SELECT "%s" FROM "%s"` ,
252- strings .Join (db .BuildColumns (columns ), `", "` ),
253- TableName (table ),
254- )
255-
256- if scoper , ok := table .(Scoper ); ok {
257- where , _ := db .BuildWhere (scoper .Scope ())
258- q += ` WHERE ` + where
259- }
220+ qb := NewQB (table )
221+ qb .SetColumns (db .BuildColumns (columns )... )
260222
261- return q
223+ return qb . Select ( db )
262224}
263225
264226// BuildUpdateStmt returns an UPDATE statement for the given struct.
265227func (db * DB ) BuildUpdateStmt (update interface {}) (string , int ) {
266- columns := db .BuildColumns (update )
267- set := make ([]string , 0 , len (columns ))
268-
269- for _ , col := range columns {
270- set = append (set , fmt .Sprintf (`"%s" = :%s` , col , col ))
271- }
272-
273- return fmt .Sprintf (
274- `UPDATE "%s" SET %s WHERE id = :id` ,
275- TableName (update ),
276- strings .Join (set , ", " ),
277- ), len (columns ) + 1 // +1 because of WHERE id = :id
228+ return NewQB (update ).Update (db )
278229}
279230
280231// BuildUpsertStmt returns an upsert statement for the given struct.
281232func (db * DB ) BuildUpsertStmt (subject interface {}) (stmt string , placeholders int ) {
282- insertColumns := db .BuildColumns (subject )
283- table := TableName (subject )
284- var updateColumns []string
285-
286- if upserter , ok := subject .(Upserter ); ok {
287- updateColumns = db .BuildColumns (upserter .Upsert ())
288- } else {
289- updateColumns = insertColumns
290- }
291-
292- var clause , setFormat string
293- switch db .DriverName () {
294- case driver .MySQL :
295- clause = "ON DUPLICATE KEY UPDATE"
296- setFormat = `"%[1]s" = VALUES("%[1]s")`
297- case driver .PostgreSQL :
298- clause = fmt .Sprintf ("ON CONFLICT ON CONSTRAINT pk_%s DO UPDATE SET" , table )
299- setFormat = `"%[1]s" = EXCLUDED."%[1]s"`
300- }
301-
302- set := make ([]string , 0 , len (updateColumns ))
303-
304- for _ , col := range updateColumns {
305- set = append (set , fmt .Sprintf (setFormat , col ))
306- }
307-
308- return fmt .Sprintf (
309- `INSERT INTO "%s" ("%s") VALUES (%s) %s %s` ,
310- table ,
311- strings .Join (insertColumns , `", "` ),
312- fmt .Sprintf (":%s" , strings .Join (insertColumns , ",:" )),
313- clause ,
314- strings .Join (set , "," ),
315- ), len (insertColumns )
316- }
317-
318- // BuildWhere returns a WHERE clause with named placeholder conditions built from the specified struct
319- // combined with the AND operator.
320- func (db * DB ) BuildWhere (subject interface {}) (string , int ) {
321- columns := db .BuildColumns (subject )
322- where := make ([]string , 0 , len (columns ))
323- for _ , col := range columns {
324- where = append (where , fmt .Sprintf (`"%s" = :%s` , col , col ))
325- }
326-
327- return strings .Join (where , ` AND ` ), len (columns )
233+ return NewQB (subject ).Upsert (db )
328234}
329235
330236// OnSuccess is a callback for successful (bulk) DML operations.
0 commit comments