Files
yarr/src/storage/feedstate.go
2026-05-18 20:18:33 +01:00

120 lines
2.4 KiB
Go

package storage
import (
"database/sql"
"time"
)
type FeedState struct {
FeedID int64
LastRefreshed time.Time
LastError string
HTTPLastModified string
HTTPEtag string
}
func (s *Storage) ListFeedStates() ([]FeedState, error) {
rows, err := s.db.Query(`
select
feed_id
, last_refreshed
, last_error
, http_lmod
, http_etag
from feed_states
`)
if err != nil {
return nil, err
}
defer rows.Close()
states := make([]FeedState, 0)
for rows.Next() {
var state FeedState
err := rows.Scan(
&state.FeedID,
&state.LastRefreshed,
&state.LastError,
&state.HTTPLastModified,
&state.HTTPEtag,
)
if err != nil {
return nil, err
}
states = append(states, state)
}
return states, nil
}
func (s *Storage) GetFeedState(feedID int64) (*FeedState, error) {
var state FeedState
err := s.db.QueryRow(`
select
feed_id
, last_refreshed
, last_error
, http_lmod
, http_etag
from feed_states where feed_id = :id
`, sql.Named("id", feedID)).Scan(
&state.FeedID,
&state.LastRefreshed,
&state.LastError,
&state.HTTPLastModified,
&state.HTTPEtag,
)
if err == sql.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
return &state, nil
}
type UpdateFeedStateParams struct {
LastRefreshed *time.Time
LastError *string
HTTPLastModified *string
HTTPEtag *string
}
func (s *Storage) UpdateFeedState(feedID int64, params UpdateFeedStateParams) (bool, error) {
lastError := params.LastError
if lastError != nil && *lastError == "" {
lastError = nil
}
_, err := s.db.Exec(`
insert into feed_states (
feed_id
, last_refreshed
, last_error
, http_lmod
, http_etag
)
values (
:id
, coalesce(:last_refreshed, 0)
, coalesce(:last_error, '')
, coalesce(:http_lmod, '')
, coalesce(:http_etag, '')
)
on conflict (feed_id) do update set
last_refreshed = coalesce(:last_refreshed, last_refreshed),
last_error = coalesce(:last_error, last_error),
http_lmod = coalesce(:http_lmod, http_lmod),
http_etag = coalesce(:http_etag, http_etag)
`,
sql.Named("id", feedID),
sql.Named("last_refreshed", params.LastRefreshed),
sql.Named("last_error", params.LastError),
sql.Named("http_lmod", params.HTTPLastModified),
sql.Named("http_etag", params.HTTPEtag),
)
if err != nil {
return false, err
}
return true, nil
}