Skip to content

Commit 603812e

Browse files
yhabteaboxzi
authored andcommitted
utils: Generalize ForEachRow to ExecAndApply and ForEachRow
Imported from Icinga/icinga-notifications@f8c3125
1 parent 66e2d35 commit 603812e

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
@@ -114,24 +114,16 @@ func InsertAndFetchId(ctx context.Context, tx *sqlx.Tx, stmt string, args any) (
114114
return lastInsertId, nil
115115
}
116116

117-
// ForEachRow applies the provided restoreFunc callback for each successfully retrieved row of the specified type.
118-
// It will bulk SELECT the data from the database scoped to the specified ids and scans into the provided Row type.
117+
// ExecAndApply applies the provided restoreFunc callback for each successfully retrieved row of the specified type.
119118
// Returns error on any database failure or fails to acquire the table semaphore.
120-
func ForEachRow[Row, Id any](ctx context.Context, db *DB, idColumn string, ids []Id, restoreFunc func(*Row)) error {
121-
subject := new(Row)
122-
table := TableName(subject)
119+
func ExecAndApply[Row any](ctx context.Context, db *DB, stmt string, args []interface{}, restoreFunc func(*Row)) error {
120+
table := TableName(new(Row))
123121
sem := db.GetSemaphoreForTable(table)
124122
if err := sem.Acquire(ctx, 1); err != nil {
125123
return errors.Wrapf(err, "cannot acquire semaphore for table %q", table)
126124
}
127125
defer sem.Release(1)
128126

129-
query := fmt.Sprintf("%s WHERE %q IN (?)", db.BuildSelectStmt(subject, subject), idColumn)
130-
stmt, args, err := sqlx.In(query, ids)
131-
if err != nil {
132-
return errors.Wrapf(err, "cannot build placeholders for %q", query)
133-
}
134-
135127
rows, err := db.QueryxContext(ctx, db.Rebind(stmt), args...)
136128
if err != nil {
137129
return err
@@ -153,6 +145,20 @@ func ForEachRow[Row, Id any](ctx context.Context, db *DB, idColumn string, ids [
153145
return rows.Err()
154146
}
155147

148+
// ForEachRow applies the provided restoreFunc callback for each successfully retrieved row of the specified type.
149+
// It will bulk SELECT the data from the database scoped to the specified ids and scans into the provided Row type.
150+
// Returns error on any database failure or fails to acquire the table semaphore.
151+
func ForEachRow[Row, Id any](ctx context.Context, db *DB, idColumn string, ids []Id, restoreFunc func(*Row)) error {
152+
subject := new(Row)
153+
query := fmt.Sprintf("%s WHERE %q IN (?)", db.BuildSelectStmt(subject, subject), idColumn)
154+
stmt, args, err := sqlx.In(query, ids)
155+
if err != nil {
156+
return errors.Wrapf(err, "cannot build placeholders for %q", query)
157+
}
158+
159+
return ExecAndApply(ctx, db, stmt, args, restoreFunc)
160+
}
161+
156162
// ToDBString transforms the given string to types.String.
157163
func ToDBString(value string) types.String {
158164
str := types.String{NullString: sql.NullString{String: value}}

0 commit comments

Comments
 (0)