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  }