package database import ( "context" "database/sql" "fmt" ) type BlobChunkRepository struct { db *DB } func NewBlobChunkRepository(db *DB) *BlobChunkRepository { return &BlobChunkRepository{db: db} } func (r *BlobChunkRepository) Create(ctx context.Context, tx *sql.Tx, bc *BlobChunk) error { query := ` INSERT INTO blob_chunks (blob_hash, chunk_hash, offset, length) VALUES (?, ?, ?, ?) ` var err error if tx != nil { _, err = tx.ExecContext(ctx, query, bc.BlobHash, bc.ChunkHash, bc.Offset, bc.Length) } else { _, err = r.db.ExecWithLock(ctx, query, bc.BlobHash, bc.ChunkHash, bc.Offset, bc.Length) } if err != nil { return fmt.Errorf("inserting blob_chunk: %w", err) } return nil } func (r *BlobChunkRepository) GetByBlobHash(ctx context.Context, blobHash string) ([]*BlobChunk, error) { query := ` SELECT blob_hash, chunk_hash, offset, length FROM blob_chunks WHERE blob_hash = ? ORDER BY offset ` rows, err := r.db.conn.QueryContext(ctx, query, blobHash) if err != nil { return nil, fmt.Errorf("querying blob chunks: %w", err) } defer CloseRows(rows) var blobChunks []*BlobChunk for rows.Next() { var bc BlobChunk err := rows.Scan(&bc.BlobHash, &bc.ChunkHash, &bc.Offset, &bc.Length) if err != nil { return nil, fmt.Errorf("scanning blob chunk: %w", err) } blobChunks = append(blobChunks, &bc) } return blobChunks, rows.Err() } func (r *BlobChunkRepository) GetByChunkHash(ctx context.Context, chunkHash string) (*BlobChunk, error) { query := ` SELECT blob_hash, chunk_hash, offset, length FROM blob_chunks WHERE chunk_hash = ? LIMIT 1 ` var bc BlobChunk err := r.db.conn.QueryRowContext(ctx, query, chunkHash).Scan( &bc.BlobHash, &bc.ChunkHash, &bc.Offset, &bc.Length, ) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, fmt.Errorf("querying blob chunk: %w", err) } return &bc, nil }