/* * Copyright 2026 Oleg Borodin * * This work is published and licensed under a Creative Commons * Attribution-NonCommercial-NoDerivatives 4.0 International License. * * Distribution of this work is permitted, but commercial use and * modifications are strictly prohibited. */ package maindb import ( "context" "mstore/pkg/descr" ) func (db *Database) InsertManifest(ctx context.Context, manifest *descr.Manifest) error { var err error var request string request = `INSERT INTO manifests(id, name, reference, contentType, payload, digest, created_at, updated_at, created_by, updated_by, architecture, os, variant) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)` _, err = db.db.Exec(request, manifest.ID, manifest.Name, manifest.Reference, manifest.ContentType, manifest.Payload, manifest.Digest, manifest.CreatedAt, manifest.UpdatedAt, manifest.CreatedBy, manifest.UpdatedBy, manifest.Architecture, manifest.OS, manifest.Variant) if err != nil { return err } return err } func (db *Database) InsertManifests(ctx context.Context, manifests []*descr.Manifest) error { var err error // Begin Tx tx, err := db.db.BeginTx(ctx, nil) for _, manifest := range manifests { var request string request = `INSERT INTO manifests(id, name, reference, contentType, payload, digest, created_at, updated_at, created_by, updated_by, architecture, os, variant) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)` _, err = tx.Exec(request, manifest.ID, manifest.Name, manifest.Reference, manifest.ContentType, manifest.Payload, manifest.Digest, manifest.CreatedAt, manifest.UpdatedAt, manifest.CreatedBy, manifest.UpdatedBy, manifest.Architecture, manifest.OS, manifest.Variant) if err != nil { return err } } // Commit err = tx.Commit() if err != nil { return err } return err } func (db *Database) UpdateManifest(ctx context.Context, manifest *descr.Manifest) error { var err error var request string // Manifest request = `UPDATE manifests SET contentType = $1, payload = $2, digest = $3, updated_at = $4 WHERE name = $5 AND reference = $6, architecture = $7, os = $8, variant = $9` _, err = db.db.Exec(request, manifest.ContentType, manifest.Payload, manifest.Digest, manifest.UpdatedAt, manifest.Name, manifest.Reference, manifest.Architecture, manifest.OS, manifest.Variant) if err != nil { return err } return err } func (db *Database) InsertManifestWithLayers(ctx context.Context, manifest *descr.Manifest, layers []descr.Blob) error { var err error var request string // Begin Tx tx, err := db.db.BeginTx(ctx, nil) // Manifest request = ` INSERT INTO manifests(id, name, reference, contentType, payload, digest, created_at, updated_at, created_by, updated_by, architecture, os, variant) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);` _, err = tx.Exec(request, manifest.ID, manifest.Name, manifest.Reference, manifest.ContentType, manifest.Payload, manifest.Digest, manifest.CreatedAt, manifest.UpdatedAt, manifest.CreatedBy, manifest.UpdatedBy, manifest.Architecture, manifest.OS, manifest.Variant) if err != nil { return err } // Layers for _, layer := range layers { request = ` INSERT INTO blobs(id, name, reference, mediaType, digest, size, created_at, updated_at, created_by, updated_by) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)` _, err = tx.Exec(request, layer.ID, layer.Name, layer.Reference, layer.MediaType, layer.Digest, layer.Size, layer.CreatedAt, layer.UpdatedAt, layer.CreatedBy, layer.UpdatedBy) if err != nil { return err } } // Commit err = tx.Commit() if err != nil { return err } // TODO: tx.Rollback() return err } func (db *Database) UpdateManifestWithBlobs(ctx context.Context, manifest *descr.Manifest, newLayers []descr.Blob, oldLayers []descr.Blob) error { var err error var request string // Begin Tx tx, err := db.db.BeginTx(ctx, nil) // TODO: tx.Rollback() // Manifest request = `UPDATE manifests SET contentType = $1, payload = $2, digest = $3, updated_at = $4, updated_by = $5 WHERE name = $6 AND reference = $7 AND architecture = $8 AND os = $9 AND variant = $10` _, err = tx.Exec(request, manifest.ContentType, manifest.Payload, manifest.Digest, manifest.UpdatedAt, manifest.UpdatedBy, manifest.Name, manifest.Reference, manifest.Architecture, manifest.OS, manifest.Variant) if err != nil { return err } // New layers for _, layer := range newLayers { request = `INSERT INTO blobs(id, name, reference, mediaType, digest, size, created_at, updated_at, created_by, updated_by) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)` _, err = tx.Exec(request, layer.ID, layer.Name, layer.Reference, layer.MediaType, layer.Digest, layer.Size, layer.CreatedAt, layer.UpdatedAt) if err != nil { return err } } // Old layers for _, layer := range oldLayers { request = `DELETE FROM blobs WHERE name == $1 AND reference == $2 AND digest == $3` _, err = tx.Exec(request, layer.Name, layer.Reference, layer.Digest) } // Commit err = tx.Commit() if err != nil { return err } return err } func (db *Database) ManifestExistsByReference(ctx context.Context, name, reference string) (bool, error) { var err error var count int var exists bool request := `SELECT count(id) AS count FROM manifests WHERE name = $1 AND reference = $2 LIMIT 1` err = db.db.Get(&count, request, name, reference) if err != nil { return exists, err } if count > 0 { exists = true } return exists, err } func (db *Database) ManifestExistsByDigest(ctx context.Context, name, digest string) (bool, error) { var err error var count int var exists bool request := `SELECT count(id) AS count FROM manifests WHERE name = $1 AND digest = $2 LIMIT 1` err = db.db.Get(&count, request, name, digest) if err != nil { return exists, err } if count > 0 { exists = true } return exists, err } func (db *Database) GetManifestByDigest(ctx context.Context, name, digest string) (bool, descr.Manifest, error) { var err error manifest := descr.Manifest{} manifests := make([]descr.Manifest, 0) exists := false request := `SELECT * FROM manifests WHERE name = $1 AND digest = $2 LIMIT 1` err = db.db.Select(&manifests, request, name, digest) if err != nil { return exists, manifest, err } if len(manifests) > 0 { exists = true manifest = manifests[0] } return exists, manifest, err } func (db *Database) GetManifestsByReference(ctx context.Context, name, reference string) (bool, []descr.Manifest, error) { var err error exists := false manifests := make([]descr.Manifest, 0) request := `SELECT * FROM manifests WHERE name = $1 AND reference = $2 LIMIT 1` err = db.db.Select(&manifests, request, name, reference) if err != nil { return exists, manifests, err } if len(manifests) > 0 { exists = true } return exists, manifests, err } func (db *Database) GetManifestsByReferenceArchitecture(ctx context.Context, name, reference, architecture, os, variant string) (bool, descr.Manifest, error) { var err error exists := false manifest := descr.Manifest{} manifests := make([]descr.Manifest, 0) request := `SELECT * FROM manifests WHERE name = $1 AND reference = $2 AND architecture = $3 AND os = $4 AND variant = $5 LIMIT 1000` err = db.db.Select(&manifests, request, name, reference, architecture, os, variant) if err != nil { return exists, manifest, err } if len(manifests) > 0 { manifest = manifests[0] exists = true } return exists, manifest, err } func (db *Database) ListManifestsByName(ctx context.Context, name string) ([]descr.Manifest, error) { var err error manifests := make([]descr.Manifest, 0) request := `SELECT id, name, reference, contentType, payload FROM manifests WHERE name = $1` err = db.db.Select(&manifests, request, name) if err != nil { return manifests, err } return manifests, err } func (db *Database) ListAllManifests(ctx context.Context) ([]descr.Manifest, error) { var err error manifests := make([]descr.Manifest, 0) request := `SELECT * FROM manifests` err = db.db.Select(&manifests, request) if err != nil { return manifests, err } return manifests, err } func (db *Database) GetReferer(ctx context.Context, name, digest string) ([]descr.Manifest, error) { var err error manifests := make([]descr.Manifest, 0) request := `SELECT * FROM manifests WHERE name = $1, digest = $2` err = db.db.Select(&manifests, request, name, digest) if err != nil { return manifests, err } return manifests, err } func (db *Database) DeleteManifest(ctx context.Context, name, reference string) error { var err error var request string // Begin Tx tx, err := db.db.BeginTx(ctx, nil) // TODO: tx.Rollback() // Blobs request = `DELETE FROM blobs WHERE name = $1 AND reference = $2` _, err = tx.Exec(request, name, reference) if err != nil { return err } // Manifest request = `DELETE FROM manifests WHERE name = $1 AND reference = $2` _, err = tx.Exec(request, name, reference) if err != nil { return err } // Commit err = tx.Commit() if err != nil { return err } return err }