Skip to content

Commit ca9ecd7

Browse files
yhabteaboxzi
authored andcommitted
database: Generalize ForEachRow into ExecAndApply and ForEachRow
Imported from Icinga/icinga-notifications@f8c3125
1 parent d902b09 commit ca9ecd7

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

database/utils.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,24 +99,16 @@ func BuildInsertStmtWithout(db *DB, into interface{}, withoutColumn string) stri
9999
)
100100
}
101101

102-
// ForEachRow applies the provided restoreFunc callback for each successfully retrieved row of the specified type.
103-
// It will bulk SELECT the data from the database scoped to the specified ids and scans into the provided Row type.
102+
// ExecAndApply applies the provided restoreFunc callback for each successfully retrieved row of the specified type.
104103
// Returns error on any database failure or fails to acquire the table semaphore.
105-
func ForEachRow[Row, Id any](ctx context.Context, db *DB, idColumn string, ids []Id, restoreFunc func(*Row)) error {
106-
subject := new(Row)
107-
table := TableName(subject)
104+
func ExecAndApply[Row any](ctx context.Context, db *DB, stmt string, args []interface{}, restoreFunc func(*Row)) error {
105+
table := TableName(new(Row))
108106
sem := db.GetSemaphoreForTable(table)
109107
if err := sem.Acquire(ctx, 1); err != nil {
110108
return errors.Wrapf(err, "cannot acquire semaphore for table %q", table)
111109
}
112110
defer sem.Release(1)
113111

114-
query := fmt.Sprintf("%s WHERE %q IN (?)", db.BuildSelectStmt(subject, subject), idColumn)
115-
stmt, args, err := sqlx.In(query, ids)
116-
if err != nil {
117-
return errors.Wrapf(err, "cannot build placeholders for %q", query)
118-
}
119-
120112
rows, err := db.QueryxContext(ctx, db.Rebind(stmt), args...)
121113
if err != nil {
122114
return err
@@ -138,6 +130,20 @@ func ForEachRow[Row, Id any](ctx context.Context, db *DB, idColumn string, ids [
138130
return rows.Err()
139131
}
140132

133+
// ForEachRow applies the provided restoreFunc callback for each successfully retrieved row of the specified type.
134+
// It will bulk SELECT the data from the database scoped to the specified ids and scans into the provided Row type.
135+
// Returns error on any database failure or fails to acquire the table semaphore.
136+
func ForEachRow[Row, Id any](ctx context.Context, db *DB, idColumn string, ids []Id, restoreFunc func(*Row)) error {
137+
subject := new(Row)
138+
query := fmt.Sprintf("%s WHERE %q IN (?)", db.BuildSelectStmt(subject, subject), idColumn)
139+
stmt, args, err := sqlx.In(query, ids)
140+
if err != nil {
141+
return errors.Wrapf(err, "cannot build placeholders for %q", query)
142+
}
143+
144+
return ExecAndApply(ctx, db, stmt, args, restoreFunc)
145+
}
146+
141147
// unsafeSetSessionVariableIfExists sets the given MySQL/MariaDB system variable for the specified database session.
142148
//
143149
// NOTE: It is unsafe to use this function with untrusted/user supplied inputs and poses an SQL injection,

0 commit comments

Comments
 (0)