113 lines
3.0 KiB
Go
113 lines
3.0 KiB
Go
package depot
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/jackc/pgx/v5"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
"go.jetify.com/typeid"
|
|
)
|
|
|
|
var errNotFound = errors.New("not found")
|
|
|
|
type depotIDPrefix struct{}
|
|
|
|
func (depotIDPrefix) Prefix() string { return "dpo" }
|
|
|
|
type depotID struct {
|
|
typeid.TypeID[depotIDPrefix]
|
|
}
|
|
|
|
func newDepotID() (depotID, error) {
|
|
return typeid.New[depotID]()
|
|
}
|
|
|
|
type repository interface {
|
|
create(ctx context.Context, obj *Object) (*Object, error)
|
|
getByID(ctx context.Context, id string) (*Object, error)
|
|
setContainsContent(ctx context.Context, id string, containsContent bool) error
|
|
delete(ctx context.Context, id string) error
|
|
exists(ctx context.Context, id string) (bool, error)
|
|
}
|
|
|
|
type repositoryImpl struct {
|
|
pool *pgxpool.Pool
|
|
}
|
|
|
|
func newRepository(pool *pgxpool.Pool) repository {
|
|
return &repositoryImpl{pool: pool}
|
|
}
|
|
|
|
func (r *repositoryImpl) create(ctx context.Context, obj *Object) (*Object, error) {
|
|
id, err := newDepotID()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var result Object
|
|
err = r.pool.QueryRow(ctx,
|
|
`INSERT INTO depot_objects (id, name, content_type, content_length, bucket_name, object_key, contains_content)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
RETURNING id, name, content_type, content_length, bucket_name, object_key, contains_content, created_at`,
|
|
id.String(), obj.Name, obj.ContentType, obj.ContentLength, obj.BucketName, obj.ObjectKey, obj.ContainsContent,
|
|
).Scan(&result.ID, &result.Name, &result.ContentType, &result.ContentLength,
|
|
&result.BucketName, &result.ObjectKey, &result.ContainsContent, &result.CreatedAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &result, nil
|
|
}
|
|
|
|
func (r *repositoryImpl) getByID(ctx context.Context, id string) (*Object, error) {
|
|
var obj Object
|
|
err := r.pool.QueryRow(ctx,
|
|
`SELECT id, name, content_type, content_length, bucket_name, object_key, contains_content, created_at
|
|
FROM depot_objects WHERE id = $1`,
|
|
id,
|
|
).Scan(&obj.ID, &obj.Name, &obj.ContentType, &obj.ContentLength,
|
|
&obj.BucketName, &obj.ObjectKey, &obj.ContainsContent, &obj.CreatedAt)
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return nil, errNotFound
|
|
}
|
|
return nil, err
|
|
}
|
|
return &obj, nil
|
|
}
|
|
|
|
func (r *repositoryImpl) setContainsContent(ctx context.Context, id string, containsContent bool) error {
|
|
result, err := r.pool.Exec(ctx,
|
|
`UPDATE depot_objects SET contains_content = $1 WHERE id = $2`,
|
|
containsContent, id,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if result.RowsAffected() == 0 {
|
|
return errNotFound
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *repositoryImpl) delete(ctx context.Context, id string) error {
|
|
result, err := r.pool.Exec(ctx, `DELETE FROM depot_objects WHERE id = $1`, id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if result.RowsAffected() == 0 {
|
|
return errNotFound
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *repositoryImpl) exists(ctx context.Context, id string) (bool, error) {
|
|
var exists bool
|
|
err := r.pool.QueryRow(ctx,
|
|
`SELECT EXISTS(SELECT 1 FROM depot_objects WHERE id = $1)`,
|
|
id,
|
|
).Scan(&exists)
|
|
return exists, err
|
|
}
|