miniflux/storage/cache.go

63 lines
1.8 KiB
Go

// Copyright 2020 Dave Marquard. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.
package storage // import "miniflux.app/storage"
import (
"context"
"database/sql"
"golang.org/x/crypto/acme/autocert"
)
// Making sure that we're adhering to the autocert.Cache interface.
var _ autocert.Cache = (*Cache)(nil)
// Cache provides a SQL backend to the autocert cache.
type Cache struct {
storage *Storage
}
// NewCache creates an cache instance that can be used with autocert.Cache.
// It returns any errors that could happen while connecting to SQL.
func NewCache(storage *Storage) *Cache {
return &Cache{
storage: storage,
}
}
// Get returns a certificate data for the specified key.
// If there's no such key, Get returns ErrCacheMiss.
func (c *Cache) Get(ctx context.Context, key string) ([]byte, error) {
query := `SELECT data::bytea FROM acme_cache WHERE key = $1`
var data []byte
err := c.storage.db.QueryRowContext(ctx, query, key).Scan(&data)
if err == sql.ErrNoRows {
return nil, autocert.ErrCacheMiss
}
return data, err
}
// Put stores the data in the cache under the specified key.
func (c *Cache) Put(ctx context.Context, key string, data []byte) error {
query := `INSERT INTO acme_cache (key, data, updated_at) VALUES($1, $2::bytea, now())
ON CONFLICT (key) DO UPDATE SET data = $2::bytea, updated_at = now()`
_, err := c.storage.db.ExecContext(ctx, query, key, data)
if err != nil {
return err
}
return nil
}
// Delete removes a certificate data from the cache under the specified key.
// If there's no such key in the cache, Delete returns nil.
func (c *Cache) Delete(ctx context.Context, key string) error {
query := `DELETE FROM acme_cache WHERE key = $1`
_, err := c.storage.db.ExecContext(ctx, query, key)
if err != nil {
return err
}
return nil
}