github.com/quay/claircore@v1.5.28/datastore/postgres/matcher_store.go (about) 1 package postgres 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/google/uuid" 9 "github.com/jackc/pgx/v4/pgxpool" 10 "github.com/jackc/pgx/v4/stdlib" 11 "github.com/quay/zlog" 12 "github.com/remind101/migrate" 13 14 "github.com/quay/claircore/datastore" 15 "github.com/quay/claircore/datastore/postgres/migrations" 16 "github.com/quay/claircore/libvuln/driver" 17 ) 18 19 // InitPostgresMatcherStore initialize a indexer.Store given libindex.Opts 20 func InitPostgresMatcherStore(_ context.Context, pool *pgxpool.Pool, doMigration bool) (datastore.MatcherStore, error) { 21 db := stdlib.OpenDB(*pool.Config().ConnConfig) 22 defer db.Close() 23 24 // do migrations if requested 25 if doMigration { 26 migrator := migrate.NewPostgresMigrator(db) 27 migrator.Table = migrations.MatcherMigrationTable 28 err := migrator.Exec(migrate.Up, migrations.MatcherMigrations...) 29 if err != nil { 30 return nil, fmt.Errorf("failed to perform migrations: %w", err) 31 } 32 } 33 34 store := NewMatcherStore(pool) 35 return store, nil 36 } 37 38 // MatcherStore implements all interfaces in the vulnstore package 39 type MatcherStore struct { 40 pool *pgxpool.Pool 41 // Initialized is used as an atomic bool for tracking initialization. 42 initialized uint32 43 } 44 45 func NewMatcherStore(pool *pgxpool.Pool) *MatcherStore { 46 return &MatcherStore{ 47 pool: pool, 48 } 49 } 50 51 var ( 52 _ datastore.Updater = (*MatcherStore)(nil) 53 _ datastore.Vulnerability = (*MatcherStore)(nil) 54 ) 55 56 // DeleteUpdateOperations implements vulnstore.Updater. 57 func (s *MatcherStore) DeleteUpdateOperations(ctx context.Context, id ...uuid.UUID) (int64, error) { 58 const query = `DELETE FROM update_operation WHERE ref = ANY($1::uuid[]);` 59 ctx = zlog.ContextWithValues(ctx, "component", "internal/vulnstore/postgres/deleteUpdateOperations") 60 if len(id) == 0 { 61 return 0, nil 62 } 63 64 // Pgx seems unwilling to do the []uuid.UUID → uuid[] conversion, so we're 65 // forced to make some garbage here. 66 refStr := make([]string, len(id)) 67 for i := range id { 68 refStr[i] = id[i].String() 69 } 70 tag, err := s.pool.Exec(ctx, query, refStr) 71 if err != nil { 72 return 0, fmt.Errorf("failed to delete: %w", err) 73 } 74 return tag.RowsAffected(), nil 75 } 76 77 // RecordUpdaterStatus records that an updater is up to date with vulnerabilities at this time 78 func (s *MatcherStore) RecordUpdaterStatus(ctx context.Context, updaterName string, updateTime time.Time, fingerprint driver.Fingerprint, updaterError error) error { 79 return recordUpdaterStatus(ctx, s.pool, updaterName, updateTime, fingerprint, updaterError) 80 } 81 82 // RecordUpdaterSetStatus records that all updaters from a updater set are up to date with vulnerabilities at this time 83 func (s *MatcherStore) RecordUpdaterSetStatus(ctx context.Context, updaterSet string, updateTime time.Time) error { 84 return recordUpdaterSetStatus(ctx, s.pool, updaterSet, updateTime) 85 }