feat: use sqlite for jikan api cache with hourly cleanup

This commit is contained in:
2026-04-08 16:19:59 +02:00
parent 13b0128c38
commit d25426eda9
13 changed files with 172 additions and 51 deletions

View File

@@ -35,6 +35,13 @@ type AnimeRelation struct {
RelationType string `json:"relation_type"`
}
type JikanCache struct {
Key string `json:"key"`
Data string `json:"data"`
ExpiresAt time.Time `json:"expires_at"`
CreatedAt time.Time `json:"created_at"`
}
type NotificationPreference struct {
ID string `json:"id"`
UserID string `json:"user_id"`

View File

@@ -11,11 +11,13 @@ import (
type Querier interface {
CreateSession(ctx context.Context, arg CreateSessionParams) (Session, error)
CreateUser(ctx context.Context, arg CreateUserParams) (User, error)
DeleteExpiredJikanCache(ctx context.Context) error
DeleteSession(ctx context.Context, id string) error
DeleteUserSessions(ctx context.Context, userID string) error
DeleteWatchListEntry(ctx context.Context, arg DeleteWatchListEntryParams) error
GetAnime(ctx context.Context, id int64) (Anime, error)
GetAnimeNeedingRelationSync(ctx context.Context) ([]GetAnimeNeedingRelationSyncRow, error)
GetJikanCache(ctx context.Context, key string) (string, error)
GetSession(ctx context.Context, id string) (Session, error)
GetUpcomingSeasons(ctx context.Context, userID string) ([]GetUpcomingSeasonsRow, error)
GetUser(ctx context.Context, id string) (User, error)
@@ -24,6 +26,7 @@ type Querier interface {
GetWatchListEntry(ctx context.Context, arg GetWatchListEntryParams) (WatchListEntry, error)
GetWatchingAnime(ctx context.Context, userID string) ([]GetWatchingAnimeRow, error)
MarkRelationsSynced(ctx context.Context, id int64) error
SetJikanCache(ctx context.Context, arg SetJikanCacheParams) error
UpdateAnimeStatus(ctx context.Context, arg UpdateAnimeStatusParams) error
UpsertAnime(ctx context.Context, arg UpsertAnimeParams) (Anime, error)
UpsertAnimeRelation(ctx context.Context, arg UpsertAnimeRelationParams) error

View File

@@ -151,3 +151,18 @@ WHERE related.status IN ('Not yet aired', 'Currently Airing')
WHERE we.user_id = sc.user_id AND we.anime_id = related.id
)
ORDER BY related.id DESC;
-- name: GetJikanCache :one
SELECT data FROM jikan_cache
WHERE key = ? AND expires_at > CURRENT_TIMESTAMP LIMIT 1;
-- name: SetJikanCache :exec
INSERT INTO jikan_cache (key, data, expires_at)
VALUES (?, ?, ?)
ON CONFLICT (key) DO UPDATE SET
data = excluded.data,
expires_at = excluded.expires_at,
created_at = CURRENT_TIMESTAMP;
-- name: DeleteExpiredJikanCache :exec
DELETE FROM jikan_cache WHERE expires_at <= CURRENT_TIMESTAMP;

View File

@@ -59,6 +59,15 @@ func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (User, e
return i, err
}
const deleteExpiredJikanCache = `-- name: DeleteExpiredJikanCache :exec
DELETE FROM jikan_cache WHERE expires_at <= CURRENT_TIMESTAMP
`
func (q *Queries) DeleteExpiredJikanCache(ctx context.Context) error {
_, err := q.db.ExecContext(ctx, deleteExpiredJikanCache)
return err
}
const deleteSession = `-- name: DeleteSession :exec
DELETE FROM session WHERE id = ?
`
@@ -164,6 +173,18 @@ func (q *Queries) GetAnimeNeedingRelationSync(ctx context.Context) ([]GetAnimeNe
return items, nil
}
const getJikanCache = `-- name: GetJikanCache :one
SELECT data FROM jikan_cache
WHERE key = ? AND expires_at > CURRENT_TIMESTAMP LIMIT 1
`
func (q *Queries) GetJikanCache(ctx context.Context, key string) (string, error) {
row := q.db.QueryRowContext(ctx, getJikanCache, key)
var data string
err := row.Scan(&data)
return data, err
}
const getSession = `-- name: GetSession :one
SELECT id, user_id, expires_at, created_at FROM session WHERE id = ? LIMIT 1
`
@@ -468,6 +489,26 @@ func (q *Queries) MarkRelationsSynced(ctx context.Context, id int64) error {
return err
}
const setJikanCache = `-- name: SetJikanCache :exec
INSERT INTO jikan_cache (key, data, expires_at)
VALUES (?, ?, ?)
ON CONFLICT (key) DO UPDATE SET
data = excluded.data,
expires_at = excluded.expires_at,
created_at = CURRENT_TIMESTAMP
`
type SetJikanCacheParams struct {
Key string `json:"key"`
Data string `json:"data"`
ExpiresAt time.Time `json:"expires_at"`
}
func (q *Queries) SetJikanCache(ctx context.Context, arg SetJikanCacheParams) error {
_, err := q.db.ExecContext(ctx, setJikanCache, arg.Key, arg.Data, arg.ExpiresAt)
return err
}
const updateAnimeStatus = `-- name: UpdateAnimeStatus :exec
UPDATE anime SET status = ? WHERE id = ?
`