mirror of
https://github.com/nkanaev/yarr.git
synced 2026-06-15 12:35:04 +00:00
move structs to model
This commit is contained in:
@@ -1,22 +1,27 @@
|
|||||||
package storage
|
package factory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/nkanaev/yarr/src/storage/model"
|
||||||
|
)
|
||||||
|
|
||||||
type Storage interface {
|
type Storage interface {
|
||||||
Close() error
|
Close() error
|
||||||
|
Migrate() error
|
||||||
CountItems() int
|
CountItems() int
|
||||||
CreateFeed(params CreateFeedParams) *Feed
|
CreateFeed(params model.CreateFeedParams) *model.Feed
|
||||||
CreateFolder(title string) *Folder
|
CreateFolder(title string) *Folder
|
||||||
CreateItems(items []Item) bool
|
CreateItems(items []Item) bool
|
||||||
DeleteFeed(feedId int64) bool
|
DeleteFeed(feedId int64) bool
|
||||||
DeleteFolder(folderId int64) bool
|
DeleteFolder(folderId int64) bool
|
||||||
DeleteOldItems()
|
DeleteOldItems()
|
||||||
FeedStats() []FeedStat
|
FeedStats() []FeedStat
|
||||||
GetFeed(id int64) *Feed
|
GetFeed(id int64) *model.Feed
|
||||||
GetFeedState(feedID int64) (*FeedState, error)
|
GetFeedState(feedID int64) (*FeedState, error)
|
||||||
GetItem(id int64) *Item
|
GetItem(id int64) *Item
|
||||||
GetSettings() Settings
|
GetSettings() Settings
|
||||||
ListFeedStates() ([]FeedState, error)
|
ListFeedStates() ([]FeedState, error)
|
||||||
ListFeeds() []Feed
|
ListFeeds() []model.Feed
|
||||||
ListFolders() []Folder
|
ListFolders() []model.Folder
|
||||||
ListItems(filter ItemFilter, limit int, newestFirst bool, withContent bool) []Item
|
ListItems(filter ItemFilter, limit int, newestFirst bool, withContent bool) []Item
|
||||||
MarkItemsRead(filter MarkFilter) bool
|
MarkItemsRead(filter MarkFilter) bool
|
||||||
UpdateFeed(feedId int64, params UpdateFeedParams) (bool, error)
|
UpdateFeed(feedId int64, params UpdateFeedParams) (bool, error)
|
||||||
@@ -25,4 +30,3 @@ type Storage interface {
|
|||||||
UpdateItemStatus(item_id int64, status ItemStatus) bool
|
UpdateItemStatus(item_id int64, status ItemStatus) bool
|
||||||
UpdateSettings(params UpdateSettingsParams) bool
|
UpdateSettings(params UpdateSettingsParams) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
182
src/storage/model/model.go
Normal file
182
src/storage/model/model.go
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Feed struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
FolderId *int64 `json:"folder_id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Link string `json:"link"`
|
||||||
|
FeedLink string `json:"feed_link"`
|
||||||
|
Icon *[]byte `json:"icon,omitempty"`
|
||||||
|
HasIcon bool `json:"has_icon"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateFeedParams struct {
|
||||||
|
Title string
|
||||||
|
Description string
|
||||||
|
Link string
|
||||||
|
FeedLink string
|
||||||
|
FolderID *int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type Item struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
GUID string `json:"guid"`
|
||||||
|
FeedId int64 `json:"feed_id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Link string `json:"link"`
|
||||||
|
Content string `json:"content,omitempty"`
|
||||||
|
Date time.Time `json:"date"`
|
||||||
|
Status ItemStatus `json:"status"`
|
||||||
|
MediaLinks MediaLinks `json:"media_links"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ItemStatus int
|
||||||
|
|
||||||
|
const (
|
||||||
|
UNREAD ItemStatus = 0
|
||||||
|
READ ItemStatus = 1
|
||||||
|
STARRED ItemStatus = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
var StatusRepresentations = map[ItemStatus]string{
|
||||||
|
UNREAD: "unread",
|
||||||
|
READ: "read",
|
||||||
|
STARRED: "starred",
|
||||||
|
}
|
||||||
|
|
||||||
|
var StatusValues = map[string]ItemStatus{
|
||||||
|
"unread": UNREAD,
|
||||||
|
"read": READ,
|
||||||
|
"starred": STARRED,
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s ItemStatus) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(StatusRepresentations[s])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ItemStatus) UnmarshalJSON(b []byte) error {
|
||||||
|
var str string
|
||||||
|
if err := json.Unmarshal(b, &str); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*s = StatusValues[str]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type MediaLink struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MediaLinks []MediaLink
|
||||||
|
|
||||||
|
type ItemFilter struct {
|
||||||
|
FolderID *int64
|
||||||
|
FeedID *int64
|
||||||
|
Status *ItemStatus
|
||||||
|
Search *string
|
||||||
|
After *int64
|
||||||
|
IDs *[]int64
|
||||||
|
SinceID *int64
|
||||||
|
MaxID *int64
|
||||||
|
Before *time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type MarkFilter struct {
|
||||||
|
FolderID *int64
|
||||||
|
FeedID *int64
|
||||||
|
|
||||||
|
Before *time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type Folder struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
IsExpanded bool `json:"is_expanded"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateFolderParams struct {
|
||||||
|
Title *string
|
||||||
|
IsExpanded *bool
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type Settings struct {
|
||||||
|
Filter string `json:"filter"`
|
||||||
|
Feed string `json:"feed"`
|
||||||
|
FeedListWidth int `json:"feed_list_width"`
|
||||||
|
ItemListWidth int `json:"item_list_width"`
|
||||||
|
SortNewestFirst bool `json:"sort_newest_first"`
|
||||||
|
ThemeName string `json:"theme_name"`
|
||||||
|
ThemeFont string `json:"theme_font"`
|
||||||
|
ThemeSize int `json:"theme_size"`
|
||||||
|
RefreshRate int64 `json:"refresh_rate"`
|
||||||
|
Language string `json:"language"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateSettingsParams struct {
|
||||||
|
Filter *string `json:"filter"`
|
||||||
|
Feed *string `json:"feed"`
|
||||||
|
FeedListWidth *int `json:"feed_list_width"`
|
||||||
|
ItemListWidth *int `json:"item_list_width"`
|
||||||
|
SortNewestFirst *bool `json:"sort_newest_first"`
|
||||||
|
ThemeName *string `json:"theme_name"`
|
||||||
|
ThemeFont *string `json:"theme_font"`
|
||||||
|
ThemeSize *int `json:"theme_size"`
|
||||||
|
RefreshRate *int64 `json:"refresh_rate"`
|
||||||
|
Language *string `json:"language"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Settings) Map() map[string]any {
|
||||||
|
return map[string]any{
|
||||||
|
"filter": s.Filter,
|
||||||
|
"feed": s.Feed,
|
||||||
|
"feed_list_width": s.FeedListWidth,
|
||||||
|
"item_list_width": s.ItemListWidth,
|
||||||
|
"sort_newest_first": s.SortNewestFirst,
|
||||||
|
"theme_name": s.ThemeName,
|
||||||
|
"theme_font": s.ThemeFont,
|
||||||
|
"theme_size": s.ThemeSize,
|
||||||
|
"refresh_rate": s.RefreshRate,
|
||||||
|
"language": s.Language,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type FeedState struct {
|
||||||
|
FeedID int64
|
||||||
|
LastRefreshed time.Time
|
||||||
|
LastError string
|
||||||
|
HTTPLastModified string
|
||||||
|
HTTPEtag string
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateFeedStateParams struct {
|
||||||
|
LastRefreshed *time.Time
|
||||||
|
LastError *string
|
||||||
|
HTTPLastModified *string
|
||||||
|
HTTPEtag *string
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateFeedParams struct {
|
||||||
|
Title *string
|
||||||
|
FeedLink *string
|
||||||
|
FolderID Nullable[int64]
|
||||||
|
Icon Nullable[[]byte]
|
||||||
|
}
|
||||||
|
|
||||||
|
type Nullable[T any] struct {
|
||||||
|
Set bool
|
||||||
|
Value *T
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetNullable[T any](v *T) Nullable[T] {
|
||||||
|
return Nullable[T]{Set: true, Value: v}
|
||||||
|
}
|
||||||
@@ -3,28 +3,11 @@ package sqlite
|
|||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
"github.com/nkanaev/yarr/src/storage/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Feed struct {
|
func (s *SQLiteStorage) CreateFeed(params model.CreateFeedParams) *model.Feed {
|
||||||
Id int64 `json:"id"`
|
|
||||||
FolderId *int64 `json:"folder_id"`
|
|
||||||
Title string `json:"title"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Link string `json:"link"`
|
|
||||||
FeedLink string `json:"feed_link"`
|
|
||||||
Icon *[]byte `json:"icon,omitempty"`
|
|
||||||
HasIcon bool `json:"has_icon"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreateFeedParams struct {
|
|
||||||
Title string
|
|
||||||
Description string
|
|
||||||
Link string
|
|
||||||
FeedLink string
|
|
||||||
FolderID *int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SQLiteStorage) CreateFeed(params CreateFeedParams) *Feed {
|
|
||||||
title := params.Title
|
title := params.Title
|
||||||
if title == "" {
|
if title == "" {
|
||||||
title = params.FeedLink
|
title = params.FeedLink
|
||||||
@@ -73,13 +56,6 @@ func (s *SQLiteStorage) DeleteFeed(feedId int64) bool {
|
|||||||
return nrows == 1
|
return nrows == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateFeedParams struct {
|
|
||||||
Title *string
|
|
||||||
FeedLink *string
|
|
||||||
FolderID Nullable[int64]
|
|
||||||
Icon Nullable[[]byte]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SQLiteStorage) UpdateFeed(feedId int64, params UpdateFeedParams) (bool, error) {
|
func (s *SQLiteStorage) UpdateFeed(feedId int64, params UpdateFeedParams) (bool, error) {
|
||||||
_, err := s.db.Exec(`
|
_, err := s.db.Exec(`
|
||||||
update feeds set
|
update feeds set
|
||||||
@@ -104,8 +80,8 @@ func (s *SQLiteStorage) UpdateFeed(feedId int64, params UpdateFeedParams) (bool,
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SQLiteStorage) ListFeeds() []Feed {
|
func (s *SQLiteStorage) ListFeeds() []model.Feed {
|
||||||
result := make([]Feed, 0)
|
result := make([]model.Feed, 0)
|
||||||
rows, err := s.db.Query(`
|
rows, err := s.db.Query(`
|
||||||
select id, folder_id, title, description, link, feed_link,
|
select id, folder_id, title, description, link, feed_link,
|
||||||
ifnull(length(icon), 0) > 0 as has_icon
|
ifnull(length(icon), 0) > 0 as has_icon
|
||||||
@@ -117,7 +93,7 @@ func (s *SQLiteStorage) ListFeeds() []Feed {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var f Feed
|
var f model.Feed
|
||||||
err = rows.Scan(
|
err = rows.Scan(
|
||||||
&f.Id,
|
&f.Id,
|
||||||
&f.FolderId,
|
&f.FolderId,
|
||||||
|
|||||||
@@ -5,14 +5,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FeedState struct {
|
|
||||||
FeedID int64
|
|
||||||
LastRefreshed time.Time
|
|
||||||
LastError string
|
|
||||||
HTTPLastModified string
|
|
||||||
HTTPEtag string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SQLiteStorage) ListFeedStates() ([]FeedState, error) {
|
func (s *SQLiteStorage) ListFeedStates() ([]FeedState, error) {
|
||||||
rows, err := s.db.Query(`
|
rows, err := s.db.Query(`
|
||||||
select
|
select
|
||||||
@@ -72,13 +64,6 @@ func (s *SQLiteStorage) GetFeedState(feedID int64) (*FeedState, error) {
|
|||||||
return &state, nil
|
return &state, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateFeedStateParams struct {
|
|
||||||
LastRefreshed *time.Time
|
|
||||||
LastError *string
|
|
||||||
HTTPLastModified *string
|
|
||||||
HTTPEtag *string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SQLiteStorage) UpdateFeedState(feedID int64, params UpdateFeedStateParams) (bool, error) {
|
func (s *SQLiteStorage) UpdateFeedState(feedID int64, params UpdateFeedStateParams) (bool, error) {
|
||||||
lastError := params.LastError
|
lastError := params.LastError
|
||||||
if lastError != nil && *lastError == "" {
|
if lastError != nil && *lastError == "" {
|
||||||
|
|||||||
@@ -5,12 +5,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Folder struct {
|
|
||||||
Id int64 `json:"id"`
|
|
||||||
Title string `json:"title"`
|
|
||||||
IsExpanded bool `json:"is_expanded"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SQLiteStorage) CreateFolder(title string) *Folder {
|
func (s *SQLiteStorage) CreateFolder(title string) *Folder {
|
||||||
expanded := true
|
expanded := true
|
||||||
row := s.db.QueryRow(`
|
row := s.db.QueryRow(`
|
||||||
@@ -38,11 +32,6 @@ func (s *SQLiteStorage) DeleteFolder(folderId int64) bool {
|
|||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateFolderParams struct {
|
|
||||||
Title *string
|
|
||||||
IsExpanded *bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SQLiteStorage) UpdateFolder(folderId int64, params UpdateFolderParams) (bool, error) {
|
func (s *SQLiteStorage) UpdateFolder(folderId int64, params UpdateFolderParams) (bool, error) {
|
||||||
_, err := s.db.Exec(`
|
_, err := s.db.Exec(`
|
||||||
update folders set
|
update folders set
|
||||||
|
|||||||
@@ -1,57 +1,20 @@
|
|||||||
package sqlite
|
package sqlite
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmp"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"sort"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/nkanaev/yarr/src/storage/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ItemStatus int
|
// TODO: serialize/deserialize
|
||||||
|
|
||||||
const (
|
|
||||||
UNREAD ItemStatus = 0
|
|
||||||
READ ItemStatus = 1
|
|
||||||
STARRED ItemStatus = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
var StatusRepresentations = map[ItemStatus]string{
|
|
||||||
UNREAD: "unread",
|
|
||||||
READ: "read",
|
|
||||||
STARRED: "starred",
|
|
||||||
}
|
|
||||||
|
|
||||||
var StatusValues = map[string]ItemStatus{
|
|
||||||
"unread": UNREAD,
|
|
||||||
"read": READ,
|
|
||||||
"starred": STARRED,
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s ItemStatus) MarshalJSON() ([]byte, error) {
|
|
||||||
return json.Marshal(StatusRepresentations[s])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ItemStatus) UnmarshalJSON(b []byte) error {
|
|
||||||
var str string
|
|
||||||
if err := json.Unmarshal(b, &str); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*s = StatusValues[str]
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type MediaLink struct {
|
|
||||||
URL string `json:"url"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type MediaLinks []MediaLink
|
|
||||||
|
|
||||||
func (m *MediaLinks) Scan(src any) error {
|
func (m *MediaLinks) Scan(src any) error {
|
||||||
switch data := src.(type) {
|
switch data := src.(type) {
|
||||||
case []byte:
|
case []byte:
|
||||||
@@ -67,55 +30,6 @@ func (m MediaLinks) Value() (driver.Value, error) {
|
|||||||
return json.Marshal(m)
|
return json.Marshal(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Item struct {
|
|
||||||
Id int64 `json:"id"`
|
|
||||||
GUID string `json:"guid"`
|
|
||||||
FeedId int64 `json:"feed_id"`
|
|
||||||
Title string `json:"title"`
|
|
||||||
Link string `json:"link"`
|
|
||||||
Content string `json:"content,omitempty"`
|
|
||||||
Date time.Time `json:"date"`
|
|
||||||
Status ItemStatus `json:"status"`
|
|
||||||
MediaLinks MediaLinks `json:"media_links"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ItemFilter struct {
|
|
||||||
FolderID *int64
|
|
||||||
FeedID *int64
|
|
||||||
Status *ItemStatus
|
|
||||||
Search *string
|
|
||||||
After *int64
|
|
||||||
IDs *[]int64
|
|
||||||
SinceID *int64
|
|
||||||
MaxID *int64
|
|
||||||
Before *time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
type MarkFilter struct {
|
|
||||||
FolderID *int64
|
|
||||||
FeedID *int64
|
|
||||||
|
|
||||||
Before *time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
type ItemList []Item
|
|
||||||
|
|
||||||
func (list ItemList) Len() int {
|
|
||||||
return len(list)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (list ItemList) SortKey(i int) string {
|
|
||||||
return list[i].Date.Format(time.RFC3339) + "::" + list[i].GUID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (list ItemList) Less(i, j int) bool {
|
|
||||||
return list.SortKey(i) < list.SortKey(j)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (list ItemList) Swap(i, j int) {
|
|
||||||
list[i], list[j] = list[j], list[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SQLiteStorage) CreateItems(items []Item) bool {
|
func (s *SQLiteStorage) CreateItems(items []Item) bool {
|
||||||
tx, err := s.db.Begin()
|
tx, err := s.db.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -125,10 +39,13 @@ func (s *SQLiteStorage) CreateItems(items []Item) bool {
|
|||||||
|
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
|
|
||||||
itemsSorted := ItemList(items)
|
slices.SortStableFunc(items, func(a, b model.Item) int {
|
||||||
sort.Sort(itemsSorted)
|
sa := a.Date.Format(time.RFC3339) + "::" + a.GUID
|
||||||
|
sb := b.Date.Format(time.RFC3339) + "::" + b.GUID
|
||||||
|
return cmp.Compare(sa, sb)
|
||||||
|
})
|
||||||
|
|
||||||
for _, item := range itemsSorted {
|
for _, item := range items {
|
||||||
_, err = tx.Exec(`
|
_, err = tx.Exec(`
|
||||||
insert into items (
|
insert into items (
|
||||||
guid, feed_id, title, link, date,
|
guid, feed_id, title, link, date,
|
||||||
@@ -151,7 +68,7 @@ func (s *SQLiteStorage) CreateItems(items []Item) bool {
|
|||||||
sql.Named("media_links", item.MediaLinks),
|
sql.Named("media_links", item.MediaLinks),
|
||||||
sql.Named("date_arrived", now),
|
sql.Named("date_arrived", now),
|
||||||
sql.Named("last_arrived", now),
|
sql.Named("last_arrived", now),
|
||||||
sql.Named("status", UNREAD),
|
sql.Named("status", model.UNREAD),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
|
|||||||
@@ -6,34 +6,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Settings struct {
|
|
||||||
Filter string `json:"filter"`
|
|
||||||
Feed string `json:"feed"`
|
|
||||||
FeedListWidth int `json:"feed_list_width"`
|
|
||||||
ItemListWidth int `json:"item_list_width"`
|
|
||||||
SortNewestFirst bool `json:"sort_newest_first"`
|
|
||||||
ThemeName string `json:"theme_name"`
|
|
||||||
ThemeFont string `json:"theme_font"`
|
|
||||||
ThemeSize int `json:"theme_size"`
|
|
||||||
RefreshRate int64 `json:"refresh_rate"`
|
|
||||||
Language string `json:"language"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Settings) Map() map[string]any {
|
|
||||||
return map[string]any{
|
|
||||||
"filter": s.Filter,
|
|
||||||
"feed": s.Feed,
|
|
||||||
"feed_list_width": s.FeedListWidth,
|
|
||||||
"item_list_width": s.ItemListWidth,
|
|
||||||
"sort_newest_first": s.SortNewestFirst,
|
|
||||||
"theme_name": s.ThemeName,
|
|
||||||
"theme_font": s.ThemeFont,
|
|
||||||
"theme_size": s.ThemeSize,
|
|
||||||
"refresh_rate": s.RefreshRate,
|
|
||||||
"language": s.Language,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func settingsDefaults() Settings {
|
func settingsDefaults() Settings {
|
||||||
return Settings{
|
return Settings{
|
||||||
Filter: "",
|
Filter: "",
|
||||||
@@ -89,19 +61,6 @@ func (s *SQLiteStorage) GetSettings() Settings {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateSettingsParams struct {
|
|
||||||
Filter *string `json:"filter"`
|
|
||||||
Feed *string `json:"feed"`
|
|
||||||
FeedListWidth *int `json:"feed_list_width"`
|
|
||||||
ItemListWidth *int `json:"item_list_width"`
|
|
||||||
SortNewestFirst *bool `json:"sort_newest_first"`
|
|
||||||
ThemeName *string `json:"theme_name"`
|
|
||||||
ThemeFont *string `json:"theme_font"`
|
|
||||||
ThemeSize *int `json:"theme_size"`
|
|
||||||
RefreshRate *int64 `json:"refresh_rate"`
|
|
||||||
Language *string `json:"language"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SQLiteStorage) UpdateSettings(params UpdateSettingsParams) bool {
|
func (s *SQLiteStorage) UpdateSettings(params UpdateSettingsParams) bool {
|
||||||
tx, err := s.db.Begin()
|
tx, err := s.db.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -21,15 +21,6 @@ type SQLiteStorage struct {
|
|||||||
db *sql.DB
|
db *sql.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
type Nullable[T any] struct {
|
|
||||||
Set bool
|
|
||||||
Value *T
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetNullable[T any](v *T) Nullable[T] {
|
|
||||||
return Nullable[T]{Set: true, Value: v}
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(path string) (*SQLiteStorage, error) {
|
func New(path string) (*SQLiteStorage, error) {
|
||||||
if pos := strings.IndexRune(path, '?'); pos == -1 {
|
if pos := strings.IndexRune(path, '?'); pos == -1 {
|
||||||
params := "_journal=WAL&_sync=NORMAL&_busy_timeout=5000&cache=shared"
|
params := "_journal=WAL&_sync=NORMAL&_busy_timeout=5000&cache=shared"
|
||||||
|
|||||||
Reference in New Issue
Block a user