77 "github.com/icinga/icinga-go-library/database"
88 "github.com/icinga/icinga-go-library/types"
99 "github.com/icinga/icinga-notifications/internal/utils"
10+ "github.com/jmoiron/sqlx"
1011 "github.com/pkg/errors"
1112 "golang.org/x/sync/errgroup"
1213 "sync"
@@ -30,14 +31,34 @@ func DeleteFromCache(id types.Binary) {
3031//
3132// Returns an error on any database failure and panics when trying to cache an object that's already in the cache store.
3233func RestoreMutedObjects (ctx context.Context , db * database.DB ) error {
34+ query := db .BuildSelectStmt (new (Object ), new (Object )) + " WHERE mute_reason IS NOT NULL " +
35+ "AND NOT EXISTS((SELECT 1 FROM incident WHERE object_id = object.id AND recovered_at IS NULL))"
36+ return restoreObjectsFromQuery (ctx , db , query )
37+ }
38+
39+ // RestoreObjects restores all objects and their (extra)tags matching the given IDs from the database.
40+ // Returns error on any database failures and panics when trying to cache an object that's already in the cache store.
41+ func RestoreObjects (ctx context.Context , db * database.DB , ids []types.Binary ) error {
42+ var obj * Object
43+ query , args , err := sqlx .In (db .BuildSelectStmt (obj , obj )+ " WHERE id IN (?)" , ids )
44+ if err != nil {
45+ return errors .Wrapf (err , "cannot build placeholders for %q" , query )
46+ }
47+
48+ return restoreObjectsFromQuery (ctx , db , query , args ... )
49+ }
50+
51+ // restoreObjectsFromQuery takes a query that returns rows of the object table, executes it and loads the returned
52+ // objects into the local cache.
53+ //
54+ // Returns an error on any database failure and panics when trying to cache an object that's already in the cache store.
55+ func restoreObjectsFromQuery (ctx context.Context , db * database.DB , query string , args ... any ) error {
3356 objects := make (chan * Object )
3457 g , ctx := errgroup .WithContext (ctx )
3558 g .Go (func () error {
3659 defer close (objects )
3760
38- clause := `WHERE mute_reason IS NOT NULL AND NOT EXISTS((SELECT 1 FROM incident WHERE object_id = object.id AND recovered_at IS NULL))`
39- query := fmt .Sprintf ("%s %s" , db .BuildSelectStmt (new (Object ), new (Object )), clause )
40- err := utils .ExecAndApply [Object ](ctx , db , query , nil , func (o * Object ) {
61+ err := utils .ExecAndApply [Object ](ctx , db , query , args , func (o * Object ) {
4162 o .db = db
4263 o .Tags = map [string ]string {}
4364 o .ExtraTags = map [string ]string {}
@@ -64,8 +85,8 @@ func RestoreMutedObjects(ctx context.Context, db *database.DB) error {
6485 }
6586
6687 g .Go (func () error {
67- var ids []types.Binary
68- objectsMap := map [string ]* Object {}
88+ ids := make ( []types.Binary , 0 , len ( bulk ))
89+ objectsMap := make ( map [string ]* Object , len ( bulk ))
6990 for _ , obj := range bulk {
7091 objectsMap [obj .ID .String ()] = obj
7192 ids = append (ids , obj .ID )
@@ -87,7 +108,16 @@ func RestoreMutedObjects(ctx context.Context, db *database.DB) error {
87108 return errors .Wrap (err , "cannot restore objects extra tags" )
88109 }
89110
90- addObjectsToCache (objectsMap )
111+ cacheMu .Lock ()
112+ defer cacheMu .Unlock ()
113+
114+ for _ , o := range objectsMap {
115+ if obj , ok := cache [o .ID .String ()]; ok {
116+ panic (fmt .Sprintf ("Object %q is already in the cache" , obj .DisplayName ()))
117+ }
118+
119+ cache [o .ID .String ()] = o
120+ }
91121
92122 return nil
93123 })
@@ -97,18 +127,3 @@ func RestoreMutedObjects(ctx context.Context, db *database.DB) error {
97127
98128 return g .Wait ()
99129}
100-
101- // addObjectsToCache adds the objects from the given map to the global object cache store.
102- // Panics when trying to cache an object that's already in the cache store.
103- func addObjectsToCache (objects map [string ]* Object ) {
104- cacheMu .Lock ()
105- defer cacheMu .Unlock ()
106-
107- for _ , o := range objects {
108- if obj , ok := cache [o .ID .String ()]; ok {
109- panic (fmt .Sprintf ("Object %q is already in the cache" , obj .DisplayName ()))
110- }
111-
112- cache [o .ID .String ()] = o
113- }
114- }
0 commit comments