Declare only the tables and columns pixa writes and reads (closes #310)
check / check (push) Waiting to run

Removes output_content and request_cache, which nothing writes, and every
column that was written but never read: the host, path, query, content_type
and fetched_at of source_content, the content_type and created_at of
variant_content, and the status_code, error_message and fetched_at of
negative_cache.

StoreSource no longer takes the fetch result and LookupSource returns only
the source key. StoreVariant no longer takes a content type and
StoreNegative no longer takes a status code or message, so
extractStatusCode and the status constants, which only fed status_code,
are gone. Reconciliation adopts a variant file without opening it, as its
row no longer records a content type. Tests that set or checked a removed
column follow.

Model: opus-5-5
This commit is contained in:
2026-10-21 16:32:49 +00:00
parent 5f9d624d74
commit 03b11e9703
19 changed files with 105 additions and 279 deletions
+11 -32
View File
@@ -397,7 +397,7 @@ func (s *Service) processFromSourceOrFetch(
cacheKey imagerequest.VariantKey,
) (*processedVariant, error) {
// Check if we have cached source content
sourceKey, _, err := s.cache.LookupSource(ctx, req)
sourceKey, err := s.cache.LookupSource(ctx, req)
if err != nil {
s.log.Warn("source lookup failed", "error", err)
}
@@ -458,7 +458,7 @@ func (s *Service) fetchAndProcess(
if err != nil {
// Store negative cache for certain errors
if isNegativeCacheable(err) {
s.storeNegative(ctx, req, extractStatusCode(err), err)
s.storeNegative(ctx, req)
}
return nil, fmt.Errorf("upstream fetch failed: %w", err)
@@ -512,13 +512,13 @@ func (s *Service) fetchAndProcess(
s.log.Warn("source refused", "request_id", middleware.GetReqID(ctx),
"host", req.Source.Host, "path", req.Source.Path,
"content_type", fetchResult.ContentType, "error", err)
s.storeNegative(ctx, req, httpStatusUnsupportedMediaType, err)
s.storeNegative(ctx, req)
return nil, fmt.Errorf("content validation failed: %w", err)
}
// Store source content
_, err = s.cache.StoreSource(ctx, req, bytes.NewReader(sourceData), fetchResult)
_, err = s.cache.StoreSource(ctx, req, bytes.NewReader(sourceData))
if err != nil {
s.log.Warn("failed to store source content", "error", err)
// Continue even if caching fails
@@ -530,15 +530,13 @@ func (s *Service) fetchAndProcess(
}
// storeNegative stores a negative cache entry for req's source, whose fetch
// failed with err, so the source is not fetched again until the entry
// expires. A failure to store the entry is only logged.
func (s *Service) storeNegative(
ctx context.Context, req *imagerequest.Request, statusCode int, err error,
) {
storeErr := s.cache.StoreNegative(ctx, req, statusCode, err.Error())
if storeErr != nil {
// failed, so the source is not fetched again until the entry expires. A
// failure to store the entry is only logged.
func (s *Service) storeNegative(ctx context.Context, req *imagerequest.Request) {
err := s.cache.StoreNegative(ctx, req)
if err != nil {
s.log.Warn("failed to store negative cache entry",
"host", req.Source.Host, "path", req.Source.Path, "error", storeErr)
"host", req.Source.Host, "path", req.Source.Path, "error", err)
}
}
@@ -614,9 +612,7 @@ func (s *Service) processAndStore(
)
// Store variant to cache
err = s.cache.StoreVariant(
ctx, cacheKey, bytes.NewReader(processedData), processResult.ContentType,
)
err = s.cache.StoreVariant(ctx, cacheKey, bytes.NewReader(processedData))
if err != nil {
s.log.Warn("failed to store variant", "error", err)
// Continue even if caching fails
@@ -629,28 +625,11 @@ func (s *Service) processAndStore(
}, nil
}
// HTTP status codes for error responses.
const (
httpStatusBadGateway = 502
httpStatusInternalError = 500
httpStatusUnsupportedMediaType = 415
)
// isNegativeCacheable returns true if the error should be cached.
func isNegativeCacheable(err error) bool {
return errors.Is(err, httpfetcher.ErrUpstreamError)
}
// extractStatusCode extracts HTTP status code from error message.
func extractStatusCode(err error) int {
// Default to 502 Bad Gateway for upstream errors
if errors.Is(err, httpfetcher.ErrUpstreamError) {
return httpStatusBadGateway
}
return httpStatusInternalError
}
// etagHashLength is the number of hash characters to use for ETags.
const etagHashLength = 16