diff options
Diffstat (limited to 'backend')
| -rw-r--r-- | backend/db/articles.sql.go | 70 | ||||
| -rw-r--r-- | backend/db/feeds.sql.go | 25 | ||||
| -rw-r--r-- | backend/db/models.go | 9 | ||||
| -rw-r--r-- | backend/db/queries/articles.sql | 10 | ||||
| -rw-r--r-- | backend/db/queries/feeds.sql | 15 | ||||
| -rw-r--r-- | backend/db/schema.sql | 9 | ||||
| -rw-r--r-- | backend/graphql/generated.go | 120 | ||||
| -rw-r--r-- | backend/graphql/model/generated.go | 2 | ||||
| -rw-r--r-- | backend/graphql/resolver/schema.resolvers.go | 73 |
9 files changed, 211 insertions, 122 deletions
diff --git a/backend/db/articles.sql.go b/backend/db/articles.sql.go index 9e60cb4..7492598 100644 --- a/backend/db/articles.sql.go +++ b/backend/db/articles.sql.go @@ -75,22 +75,23 @@ func (q *Queries) DeleteArticlesByFeed(ctx context.Context, feedID int64) error const getArticle = `-- name: GetArticle :one SELECT a.id, a.feed_id, a.guid, a.title, a.url, a.is_read, - f.id as feed_id_2, f.url as feed_url, f.title as feed_title + f.id as feed_id_2, f.url as feed_url, f.title as feed_title, f.is_subscribed as feed_is_subscribed FROM articles AS a INNER JOIN feeds AS f ON a.feed_id = f.id WHERE a.id = ? ` type GetArticleRow struct { - ID int64 - FeedID int64 - Guid string - Title string - Url string - IsRead int64 - FeedID2 int64 - FeedUrl string - FeedTitle string + ID int64 + FeedID int64 + Guid string + Title string + Url string + IsRead int64 + FeedID2 int64 + FeedUrl string + FeedTitle string + FeedIsSubscribed int64 } func (q *Queries) GetArticle(ctx context.Context, id int64) (GetArticleRow, error) { @@ -106,6 +107,7 @@ func (q *Queries) GetArticle(ctx context.Context, id int64) (GetArticleRow, erro &i.FeedID2, &i.FeedUrl, &i.FeedTitle, + &i.FeedIsSubscribed, ) return i, err } @@ -179,24 +181,25 @@ func (q *Queries) GetArticlesByFeed(ctx context.Context, feedID int64) ([]Articl const getReadArticles = `-- name: GetReadArticles :many SELECT a.id, a.feed_id, a.guid, a.title, a.url, a.is_read, - f.id as feed_id_2, f.url as feed_url, f.title as feed_title + f.id as feed_id_2, f.url as feed_url, f.title as feed_title, f.is_subscribed as feed_is_subscribed FROM articles AS a INNER JOIN feeds AS f ON a.feed_id = f.id -WHERE a.is_read = 1 +WHERE a.is_read = 1 AND f.is_subscribed = 1 ORDER BY a.id DESC LIMIT 100 ` type GetReadArticlesRow struct { - ID int64 - FeedID int64 - Guid string - Title string - Url string - IsRead int64 - FeedID2 int64 - FeedUrl string - FeedTitle string + ID int64 + FeedID int64 + Guid string + Title string + Url string + IsRead int64 + FeedID2 int64 + FeedUrl string + FeedTitle string + FeedIsSubscribed int64 } func (q *Queries) GetReadArticles(ctx context.Context) ([]GetReadArticlesRow, error) { @@ -218,6 +221,7 @@ func (q *Queries) GetReadArticles(ctx context.Context) ([]GetReadArticlesRow, er &i.FeedID2, &i.FeedUrl, &i.FeedTitle, + &i.FeedIsSubscribed, ); err != nil { return nil, err } @@ -235,24 +239,25 @@ func (q *Queries) GetReadArticles(ctx context.Context) ([]GetReadArticlesRow, er const getUnreadArticles = `-- name: GetUnreadArticles :many SELECT a.id, a.feed_id, a.guid, a.title, a.url, a.is_read, - f.id as feed_id_2, f.url as feed_url, f.title as feed_title + f.id as feed_id_2, f.url as feed_url, f.title as feed_title, f.is_subscribed as feed_is_subscribed FROM articles AS a INNER JOIN feeds AS f ON a.feed_id = f.id -WHERE a.is_read = 0 +WHERE a.is_read = 0 AND f.is_subscribed = 1 ORDER BY a.id DESC LIMIT 100 ` type GetUnreadArticlesRow struct { - ID int64 - FeedID int64 - Guid string - Title string - Url string - IsRead int64 - FeedID2 int64 - FeedUrl string - FeedTitle string + ID int64 + FeedID int64 + Guid string + Title string + Url string + IsRead int64 + FeedID2 int64 + FeedUrl string + FeedTitle string + FeedIsSubscribed int64 } func (q *Queries) GetUnreadArticles(ctx context.Context) ([]GetUnreadArticlesRow, error) { @@ -274,6 +279,7 @@ func (q *Queries) GetUnreadArticles(ctx context.Context) ([]GetUnreadArticlesRow &i.FeedID2, &i.FeedUrl, &i.FeedTitle, + &i.FeedIsSubscribed, ); err != nil { return nil, err } diff --git a/backend/db/feeds.sql.go b/backend/db/feeds.sql.go index 4db84af..29b26ca 100644 --- a/backend/db/feeds.sql.go +++ b/backend/db/feeds.sql.go @@ -12,7 +12,7 @@ import ( const createFeed = `-- name: CreateFeed :one INSERT INTO feeds (url, title, fetched_at) VALUES (?, ?, ?) -RETURNING id, url, title, fetched_at +RETURNING id, url, title, fetched_at, is_subscribed ` type CreateFeedParams struct { @@ -29,6 +29,7 @@ func (q *Queries) CreateFeed(ctx context.Context, arg CreateFeedParams) (Feed, e &i.Url, &i.Title, &i.FetchedAt, + &i.IsSubscribed, ) return i, err } @@ -44,7 +45,7 @@ func (q *Queries) DeleteFeed(ctx context.Context, id int64) error { } const getFeed = `-- name: GetFeed :one -SELECT id, url, title, fetched_at +SELECT id, url, title, fetched_at, is_subscribed FROM feeds WHERE id = ? ` @@ -57,12 +58,13 @@ func (q *Queries) GetFeed(ctx context.Context, id int64) (Feed, error) { &i.Url, &i.Title, &i.FetchedAt, + &i.IsSubscribed, ) return i, err } const getFeedByURL = `-- name: GetFeedByURL :one -SELECT id, url, title, fetched_at +SELECT id, url, title, fetched_at, is_subscribed FROM feeds WHERE url = ? ` @@ -75,13 +77,15 @@ func (q *Queries) GetFeedByURL(ctx context.Context, url string) (Feed, error) { &i.Url, &i.Title, &i.FetchedAt, + &i.IsSubscribed, ) return i, err } const getFeeds = `-- name: GetFeeds :many -SELECT id, url, title, fetched_at +SELECT id, url, title, fetched_at, is_subscribed FROM feeds +WHERE is_subscribed = 1 ORDER BY id ` @@ -99,6 +103,7 @@ func (q *Queries) GetFeeds(ctx context.Context) ([]Feed, error) { &i.Url, &i.Title, &i.FetchedAt, + &i.IsSubscribed, ); err != nil { return nil, err } @@ -116,6 +121,7 @@ func (q *Queries) GetFeeds(ctx context.Context) ([]Feed, error) { const getFeedsToFetch = `-- name: GetFeedsToFetch :many SELECT id, url, fetched_at FROM feeds +WHERE is_subscribed = 1 ` type GetFeedsToFetchRow struct { @@ -147,6 +153,17 @@ func (q *Queries) GetFeedsToFetch(ctx context.Context) ([]GetFeedsToFetchRow, er return items, nil } +const unsubscribeFeed = `-- name: UnsubscribeFeed :exec +UPDATE feeds +SET is_subscribed = 0 +WHERE id = ? +` + +func (q *Queries) UnsubscribeFeed(ctx context.Context, id int64) error { + _, err := q.db.ExecContext(ctx, unsubscribeFeed, id) + return err +} + const updateFeedMetadata = `-- name: UpdateFeedMetadata :exec UPDATE feeds SET title = ?, fetched_at = ? diff --git a/backend/db/models.go b/backend/db/models.go index 2f36cb4..94ab9c0 100644 --- a/backend/db/models.go +++ b/backend/db/models.go @@ -14,8 +14,9 @@ type Article struct { } type Feed struct { - ID int64 - Url string - Title string - FetchedAt string + ID int64 + Url string + Title string + FetchedAt string + IsSubscribed int64 } diff --git a/backend/db/queries/articles.sql b/backend/db/queries/articles.sql index 3f1590a..c1feaae 100644 --- a/backend/db/queries/articles.sql +++ b/backend/db/queries/articles.sql @@ -1,7 +1,7 @@ -- name: GetArticle :one SELECT a.id, a.feed_id, a.guid, a.title, a.url, a.is_read, - f.id as feed_id_2, f.url as feed_url, f.title as feed_title + f.id as feed_id_2, f.url as feed_url, f.title as feed_title, f.is_subscribed as feed_is_subscribed FROM articles AS a INNER JOIN feeds AS f ON a.feed_id = f.id WHERE a.id = ?; @@ -9,20 +9,20 @@ WHERE a.id = ?; -- name: GetUnreadArticles :many SELECT a.id, a.feed_id, a.guid, a.title, a.url, a.is_read, - f.id as feed_id_2, f.url as feed_url, f.title as feed_title + f.id as feed_id_2, f.url as feed_url, f.title as feed_title, f.is_subscribed as feed_is_subscribed FROM articles AS a INNER JOIN feeds AS f ON a.feed_id = f.id -WHERE a.is_read = 0 +WHERE a.is_read = 0 AND f.is_subscribed = 1 ORDER BY a.id DESC LIMIT 100; -- name: GetReadArticles :many SELECT a.id, a.feed_id, a.guid, a.title, a.url, a.is_read, - f.id as feed_id_2, f.url as feed_url, f.title as feed_title + f.id as feed_id_2, f.url as feed_url, f.title as feed_title, f.is_subscribed as feed_is_subscribed FROM articles AS a INNER JOIN feeds AS f ON a.feed_id = f.id -WHERE a.is_read = 1 +WHERE a.is_read = 1 AND f.is_subscribed = 1 ORDER BY a.id DESC LIMIT 100; diff --git a/backend/db/queries/feeds.sql b/backend/db/queries/feeds.sql index 6d4d172..8445532 100644 --- a/backend/db/queries/feeds.sql +++ b/backend/db/queries/feeds.sql @@ -1,11 +1,12 @@ -- name: GetFeed :one -SELECT id, url, title, fetched_at +SELECT id, url, title, fetched_at, is_subscribed FROM feeds WHERE id = ?; -- name: GetFeeds :many -SELECT id, url, title, fetched_at +SELECT id, url, title, fetched_at, is_subscribed FROM feeds +WHERE is_subscribed = 1 ORDER BY id; -- name: CreateFeed :one @@ -23,10 +24,16 @@ DELETE FROM feeds WHERE id = ?; -- name: GetFeedByURL :one -SELECT id, url, title, fetched_at +SELECT id, url, title, fetched_at, is_subscribed FROM feeds WHERE url = ?; -- name: GetFeedsToFetch :many SELECT id, url, fetched_at -FROM feeds; +FROM feeds +WHERE is_subscribed = 1; + +-- name: UnsubscribeFeed :exec +UPDATE feeds +SET is_subscribed = 0 +WHERE id = ?; diff --git a/backend/db/schema.sql b/backend/db/schema.sql index 5c2bf48..eb40dea 100644 --- a/backend/db/schema.sql +++ b/backend/db/schema.sql @@ -1,9 +1,10 @@ -- Feeds CREATE TABLE IF NOT EXISTS feeds ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - url TEXT NOT NULL, - title TEXT NOT NULL, - fetched_at TEXT NOT NULL + id INTEGER PRIMARY KEY AUTOINCREMENT, + url TEXT NOT NULL, + title TEXT NOT NULL, + fetched_at TEXT NOT NULL, + is_subscribed INTEGER NOT NULL DEFAULT 1 ); -- Articles diff --git a/backend/graphql/generated.go b/backend/graphql/generated.go index eec1a8d..b09d4d8 100644 --- a/backend/graphql/generated.go +++ b/backend/graphql/generated.go @@ -57,11 +57,12 @@ type ComplexityRoot struct { } Feed struct { - Articles func(childComplexity int) int - FetchedAt func(childComplexity int) int - ID func(childComplexity int) int - Title func(childComplexity int) int - URL func(childComplexity int) int + Articles func(childComplexity int) int + FetchedAt func(childComplexity int) int + ID func(childComplexity int) int + IsSubscribed func(childComplexity int) int + Title func(childComplexity int) int + URL func(childComplexity int) int } Mutation struct { @@ -70,7 +71,7 @@ type ComplexityRoot struct { MarkArticleUnread func(childComplexity int, id string) int MarkFeedRead func(childComplexity int, id string) int MarkFeedUnread func(childComplexity int, id string) int - RemoveFeed func(childComplexity int, id string) int + UnsubscribeFeed func(childComplexity int, id string) int } Query struct { @@ -84,7 +85,7 @@ type ComplexityRoot struct { type MutationResolver interface { AddFeed(ctx context.Context, url string) (*model.Feed, error) - RemoveFeed(ctx context.Context, id string) (bool, error) + UnsubscribeFeed(ctx context.Context, id string) (bool, error) MarkArticleRead(ctx context.Context, id string) (*model.Article, error) MarkArticleUnread(ctx context.Context, id string) (*model.Article, error) MarkFeedRead(ctx context.Context, id string) (*model.Feed, error) @@ -187,6 +188,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.Feed.ID(childComplexity), true + case "Feed.isSubscribed": + if e.complexity.Feed.IsSubscribed == nil { + break + } + + return e.complexity.Feed.IsSubscribed(childComplexity), true + case "Feed.title": if e.complexity.Feed.Title == nil { break @@ -261,17 +269,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.Mutation.MarkFeedUnread(childComplexity, args["id"].(string)), true - case "Mutation.removeFeed": - if e.complexity.Mutation.RemoveFeed == nil { + case "Mutation.unsubscribeFeed": + if e.complexity.Mutation.UnsubscribeFeed == nil { break } - args, err := ec.field_Mutation_removeFeed_args(ctx, rawArgs) + args, err := ec.field_Mutation_unsubscribeFeed_args(ctx, rawArgs) if err != nil { return 0, false } - return e.complexity.Mutation.RemoveFeed(childComplexity, args["id"].(string)), true + return e.complexity.Mutation.UnsubscribeFeed(childComplexity, args["id"].(string)), true case "Query.article": if e.complexity.Query.Article == nil { @@ -449,6 +457,11 @@ type Feed { fetchedAt: DateTime! """ + Whether the user is currently subscribed to this feed + """ + isSubscribed: Boolean! + + """ Articles belonging to this feed """ articles: [Article!]! @@ -534,9 +547,9 @@ type Mutation { addFeed(url: String!): Feed! """ - Remove a feed subscription and all its articles + Unsubscribe from a feed (preserves feed and article data) """ - removeFeed(id: ID!): Boolean! + unsubscribeFeed(id: ID!): Boolean! """ Mark an article as read @@ -706,17 +719,17 @@ func (ec *executionContext) field_Mutation_markFeedUnread_argsID( return zeroVal, nil } -func (ec *executionContext) field_Mutation_removeFeed_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { +func (ec *executionContext) field_Mutation_unsubscribeFeed_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} - arg0, err := ec.field_Mutation_removeFeed_argsID(ctx, rawArgs) + arg0, err := ec.field_Mutation_unsubscribeFeed_argsID(ctx, rawArgs) if err != nil { return nil, err } args["id"] = arg0 return args, nil } -func (ec *executionContext) field_Mutation_removeFeed_argsID( +func (ec *executionContext) field_Mutation_unsubscribeFeed_argsID( ctx context.Context, rawArgs map[string]any, ) (string, error) { @@ -1249,6 +1262,8 @@ func (ec *executionContext) fieldContext_Article_feed(_ context.Context, field g return ec.fieldContext_Feed_title(ctx, field) case "fetchedAt": return ec.fieldContext_Feed_fetchedAt(ctx, field) + case "isSubscribed": + return ec.fieldContext_Feed_isSubscribed(ctx, field) case "articles": return ec.fieldContext_Feed_articles(ctx, field) } @@ -1434,6 +1449,50 @@ func (ec *executionContext) fieldContext_Feed_fetchedAt(_ context.Context, field return fc, nil } +func (ec *executionContext) _Feed_isSubscribed(ctx context.Context, field graphql.CollectedField, obj *model.Feed) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Feed_isSubscribed(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsSubscribed, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Feed_isSubscribed(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Feed", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _Feed_articles(ctx context.Context, field graphql.CollectedField, obj *model.Feed) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Feed_articles(ctx, field) if err != nil { @@ -1541,6 +1600,8 @@ func (ec *executionContext) fieldContext_Mutation_addFeed(ctx context.Context, f return ec.fieldContext_Feed_title(ctx, field) case "fetchedAt": return ec.fieldContext_Feed_fetchedAt(ctx, field) + case "isSubscribed": + return ec.fieldContext_Feed_isSubscribed(ctx, field) case "articles": return ec.fieldContext_Feed_articles(ctx, field) } @@ -1561,8 +1622,8 @@ func (ec *executionContext) fieldContext_Mutation_addFeed(ctx context.Context, f return fc, nil } -func (ec *executionContext) _Mutation_removeFeed(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Mutation_removeFeed(ctx, field) +func (ec *executionContext) _Mutation_unsubscribeFeed(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_unsubscribeFeed(ctx, field) if err != nil { return graphql.Null } @@ -1575,7 +1636,7 @@ func (ec *executionContext) _Mutation_removeFeed(ctx context.Context, field grap }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().RemoveFeed(rctx, fc.Args["id"].(string)) + return ec.resolvers.Mutation().UnsubscribeFeed(rctx, fc.Args["id"].(string)) }) if err != nil { ec.Error(ctx, err) @@ -1592,7 +1653,7 @@ func (ec *executionContext) _Mutation_removeFeed(ctx context.Context, field grap return ec.marshalNBoolean2bool(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Mutation_removeFeed(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Mutation_unsubscribeFeed(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Mutation", Field: field, @@ -1609,7 +1670,7 @@ func (ec *executionContext) fieldContext_Mutation_removeFeed(ctx context.Context } }() ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Mutation_removeFeed_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + if fc.Args, err = ec.field_Mutation_unsubscribeFeed_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) return fc, err } @@ -1805,6 +1866,8 @@ func (ec *executionContext) fieldContext_Mutation_markFeedRead(ctx context.Conte return ec.fieldContext_Feed_title(ctx, field) case "fetchedAt": return ec.fieldContext_Feed_fetchedAt(ctx, field) + case "isSubscribed": + return ec.fieldContext_Feed_isSubscribed(ctx, field) case "articles": return ec.fieldContext_Feed_articles(ctx, field) } @@ -1872,6 +1935,8 @@ func (ec *executionContext) fieldContext_Mutation_markFeedUnread(ctx context.Con return ec.fieldContext_Feed_title(ctx, field) case "fetchedAt": return ec.fieldContext_Feed_fetchedAt(ctx, field) + case "isSubscribed": + return ec.fieldContext_Feed_isSubscribed(ctx, field) case "articles": return ec.fieldContext_Feed_articles(ctx, field) } @@ -1939,6 +2004,8 @@ func (ec *executionContext) fieldContext_Query_feeds(_ context.Context, field gr return ec.fieldContext_Feed_title(ctx, field) case "fetchedAt": return ec.fieldContext_Feed_fetchedAt(ctx, field) + case "isSubscribed": + return ec.fieldContext_Feed_isSubscribed(ctx, field) case "articles": return ec.fieldContext_Feed_articles(ctx, field) } @@ -2112,6 +2179,8 @@ func (ec *executionContext) fieldContext_Query_feed(ctx context.Context, field g return ec.fieldContext_Feed_title(ctx, field) case "fetchedAt": return ec.fieldContext_Feed_fetchedAt(ctx, field) + case "isSubscribed": + return ec.fieldContext_Feed_isSubscribed(ctx, field) case "articles": return ec.fieldContext_Feed_articles(ctx, field) } @@ -4390,6 +4459,11 @@ func (ec *executionContext) _Feed(ctx context.Context, sel ast.SelectionSet, obj if out.Values[i] == graphql.Null { out.Invalids++ } + case "isSubscribed": + out.Values[i] = ec._Feed_isSubscribed(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } case "articles": out.Values[i] = ec._Feed_articles(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4444,9 +4518,9 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { out.Invalids++ } - case "removeFeed": + case "unsubscribeFeed": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { - return ec._Mutation_removeFeed(ctx, field) + return ec._Mutation_unsubscribeFeed(ctx, field) }) if out.Values[i] == graphql.Null { out.Invalids++ diff --git a/backend/graphql/model/generated.go b/backend/graphql/model/generated.go index bd5dcca..25ed8d8 100644 --- a/backend/graphql/model/generated.go +++ b/backend/graphql/model/generated.go @@ -30,6 +30,8 @@ type Feed struct { Title string `json:"title"` // Timestamp when the feed was last fetched FetchedAt string `json:"fetchedAt"` + // Whether the user is currently subscribed to this feed + IsSubscribed bool `json:"isSubscribed"` // Articles belonging to this feed Articles []*Article `json:"articles"` } diff --git a/backend/graphql/resolver/schema.resolvers.go b/backend/graphql/resolver/schema.resolvers.go index 0ee771b..cadcd33 100644 --- a/backend/graphql/resolver/schema.resolvers.go +++ b/backend/graphql/resolver/schema.resolvers.go @@ -52,47 +52,24 @@ func (r *mutationResolver) AddFeed(ctx context.Context, url string) (*model.Feed } return &model.Feed{ - ID: strconv.FormatInt(dbFeed.ID, 10), - URL: dbFeed.Url, - Title: dbFeed.Title, - FetchedAt: dbFeed.FetchedAt, + ID: strconv.FormatInt(dbFeed.ID, 10), + URL: dbFeed.Url, + Title: dbFeed.Title, + FetchedAt: dbFeed.FetchedAt, + IsSubscribed: dbFeed.IsSubscribed == 1, }, nil } -// RemoveFeed is the resolver for the removeFeed field. -func (r *mutationResolver) RemoveFeed(ctx context.Context, id string) (bool, error) { +// UnsubscribeFeed is the resolver for the unsubscribeFeed field. +func (r *mutationResolver) UnsubscribeFeed(ctx context.Context, id string) (bool, error) { feedID, err := strconv.ParseInt(id, 10, 64) if err != nil { return false, fmt.Errorf("invalid feed ID: %w", err) } - // Start a transaction - tx, err := r.DB.Begin() + err = r.Queries.UnsubscribeFeed(ctx, feedID) if err != nil { - return false, fmt.Errorf("failed to begin transaction: %w", err) - } - defer tx.Rollback() - - qtx := r.Queries.WithTx(tx) - - // Delete articles first (foreign key constraint) - err = qtx.DeleteArticlesByFeed(ctx, feedID) - if err != nil { - return false, fmt.Errorf("failed to delete articles: %w", err) - } - - // Delete the feed - err = qtx.DeleteFeed(ctx, feedID) - if err != nil { - if err == sql.ErrNoRows { - return false, fmt.Errorf("feed not found") - } - return false, fmt.Errorf("failed to delete feed: %w", err) - } - - err = tx.Commit() - if err != nil { - return false, fmt.Errorf("failed to commit transaction: %w", err) + return false, fmt.Errorf("failed to unsubscribe from feed: %w", err) } return true, nil @@ -182,10 +159,11 @@ func (r *queryResolver) Feeds(ctx context.Context) ([]*model.Feed, error) { var feeds []*model.Feed for _, dbFeed := range dbFeeds { feeds = append(feeds, &model.Feed{ - ID: strconv.FormatInt(dbFeed.ID, 10), - URL: dbFeed.Url, - Title: dbFeed.Title, - FetchedAt: dbFeed.FetchedAt, + ID: strconv.FormatInt(dbFeed.ID, 10), + URL: dbFeed.Url, + Title: dbFeed.Title, + FetchedAt: dbFeed.FetchedAt, + IsSubscribed: dbFeed.IsSubscribed == 1, }) } @@ -209,9 +187,10 @@ func (r *queryResolver) UnreadArticles(ctx context.Context) ([]*model.Article, e URL: row.Url, IsRead: row.IsRead == 1, Feed: &model.Feed{ - ID: strconv.FormatInt(row.FeedID2, 10), - URL: row.FeedUrl, - Title: row.FeedTitle, + ID: strconv.FormatInt(row.FeedID2, 10), + URL: row.FeedUrl, + Title: row.FeedTitle, + IsSubscribed: row.FeedIsSubscribed == 1, }, }) } @@ -236,9 +215,10 @@ func (r *queryResolver) ReadArticles(ctx context.Context) ([]*model.Article, err URL: row.Url, IsRead: row.IsRead == 1, Feed: &model.Feed{ - ID: strconv.FormatInt(row.FeedID2, 10), - URL: row.FeedUrl, - Title: row.FeedTitle, + ID: strconv.FormatInt(row.FeedID2, 10), + URL: row.FeedUrl, + Title: row.FeedTitle, + IsSubscribed: row.FeedIsSubscribed == 1, }, }) } @@ -262,10 +242,11 @@ func (r *queryResolver) Feed(ctx context.Context, id string) (*model.Feed, error } return &model.Feed{ - ID: strconv.FormatInt(dbFeed.ID, 10), - URL: dbFeed.Url, - Title: dbFeed.Title, - FetchedAt: dbFeed.FetchedAt, + ID: strconv.FormatInt(dbFeed.ID, 10), + URL: dbFeed.Url, + Title: dbFeed.Title, + FetchedAt: dbFeed.FetchedAt, + IsSubscribed: dbFeed.IsSubscribed == 1, }, nil } |
