github.com/quay/claircore@v1.5.28/datastore/postgres/persistmanifest.go (about) 1 package postgres 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/prometheus/client_golang/prometheus" 9 "github.com/prometheus/client_golang/prometheus/promauto" 10 11 "github.com/quay/claircore" 12 ) 13 14 var ( 15 persistManifestCounter = promauto.NewCounterVec( 16 prometheus.CounterOpts{ 17 Namespace: "claircore", 18 Subsystem: "indexer", 19 Name: "persistmanifest_total", 20 Help: "Total number of database queries issued in the PersistManifest method.", 21 }, 22 []string{"query"}, 23 ) 24 25 persistManifestDuration = promauto.NewHistogramVec( 26 prometheus.HistogramOpts{ 27 Namespace: "claircore", 28 Subsystem: "indexer", 29 Name: "persistmanifest_duration_seconds", 30 Help: "The duration of all queries issued in the PersistManifest method", 31 }, 32 []string{"query"}, 33 ) 34 ) 35 36 func (s *IndexerStore) PersistManifest(ctx context.Context, manifest claircore.Manifest) error { 37 const ( 38 insertManifest = ` 39 INSERT INTO manifest (hash) 40 VALUES ($1) 41 ON CONFLICT DO NOTHING; 42 ` 43 insertLayer = ` 44 INSERT INTO layer (hash) 45 VALUES ($1) 46 ON CONFLICT DO NOTHING; 47 ` 48 insertManifestLayer = ` 49 WITH manifests AS ( 50 SELECT id AS manifest_id 51 FROM manifest 52 WHERE hash = $1 53 ), 54 layers AS ( 55 SELECT id AS layer_id 56 FROM layer 57 WHERE hash = $2 58 ) 59 INSERT 60 INTO manifest_layer (manifest_id, layer_id, i) 61 VALUES ((SELECT manifest_id FROM manifests), 62 (SELECT layer_id FROM layers), 63 $3) 64 ON CONFLICT DO NOTHING; 65 ` 66 ) 67 68 tx, err := s.pool.Begin(ctx) 69 if err != nil { 70 return fmt.Errorf("failed to create transaction: %w", err) 71 } 72 defer tx.Rollback(ctx) 73 74 start := time.Now() 75 _, err = tx.Exec(ctx, insertManifest, manifest.Hash) 76 if err != nil { 77 return fmt.Errorf("failed to insert manifest: %w", err) 78 } 79 persistManifestCounter.WithLabelValues("insertManifest").Add(1) 80 persistManifestDuration.WithLabelValues("insertManifest").Observe(time.Since(start).Seconds()) 81 82 for i, layer := range manifest.Layers { 83 start := time.Now() 84 _, err = tx.Exec(ctx, insertLayer, layer.Hash) 85 if err != nil { 86 return fmt.Errorf("failed to insert layer: %w", err) 87 } 88 persistManifestCounter.WithLabelValues("insertLayer").Add(1) 89 persistManifestDuration.WithLabelValues("insertLayer").Observe(time.Since(start).Seconds()) 90 91 start = time.Now() 92 _, err = tx.Exec(ctx, insertManifestLayer, manifest.Hash, layer.Hash, i) 93 if err != nil { 94 return fmt.Errorf("failed to insert manifest -> layer link: %w", err) 95 } 96 persistManifestCounter.WithLabelValues("insertManifestLayer").Add(1) 97 persistManifestDuration.WithLabelValues("insertManifestLayer").Observe(time.Since(start).Seconds()) 98 } 99 100 err = tx.Commit(ctx) 101 if err != nil { 102 return fmt.Errorf("failed to commit tx: %w", err) 103 } 104 return nil 105 }