mirror of
https://github.com/Ranchero-Software/NetNewsWire.git
synced 2025-02-02 20:16:54 +01:00
Cache statuses when fetching articles — since articles are fetched using a join statement with the statuses table.
This commit is contained in:
parent
80c8a848e9
commit
72cfc84001
@ -166,26 +166,15 @@ private extension ArticlesTable {
|
||||
|
||||
// MARK: Fetching
|
||||
|
||||
func articleWithRow(_ row: FMResultSet) -> Article? {
|
||||
|
||||
guard let article = Article(row: row, accountID: accountID) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Note: the row is a result of a JOIN query with the statuses table,
|
||||
// so we can get the status at the same time and avoid additional database lookups.
|
||||
|
||||
// article.status = statusesTable.statusWithRow(row)
|
||||
return article
|
||||
}
|
||||
|
||||
func articlesWithResultSet(_ resultSet: FMResultSet, _ database: FMDatabase) -> Set<Article> {
|
||||
|
||||
// Create set of stub Articles without related objects.
|
||||
// Then fetch the related objects, given the set of articleIDs.
|
||||
// Then create set of Articles *with* related objects and return it.
|
||||
|
||||
let (stubArticles, statuses) = stubArticlesAndStatuses(with: resultSet)
|
||||
|
||||
let stubArticles = resultSet.mapToSet(articleWithRow)
|
||||
statusesTable.addIfNotCached(statuses)
|
||||
if stubArticles.isEmpty {
|
||||
return stubArticles
|
||||
}
|
||||
@ -202,23 +191,44 @@ private extension ArticlesTable {
|
||||
}
|
||||
|
||||
// Create articles with related objects.
|
||||
|
||||
var articles = Set<Article>()
|
||||
for stubArticle in articles {
|
||||
|
||||
let articleID = stubArticle.articleID
|
||||
|
||||
let authors = authorsMap?.authors(for: articleID)
|
||||
let attachments = attachmentsMap?.attachments(for: articleID)
|
||||
let tags = tagsMap?.tags(for: articleID)
|
||||
|
||||
let realArticle = stubArticle.articleByAttaching(authors, attachments, tags)
|
||||
articles.insert(realArticle)
|
||||
}
|
||||
|
||||
|
||||
let articles = Set(stubArticles.map { articleWithAttachedRelatedObjects($0, authorsMap, attachmentsMap, tagsMap) })
|
||||
return articles
|
||||
}
|
||||
|
||||
func stubArticlesAndStatuses(with resultSet: FMResultSet) -> (Set<Article>, Set<ArticleStatus>) {
|
||||
|
||||
var stubArticles = Set<Article>()
|
||||
var statuses = Set<ArticleStatus>()
|
||||
|
||||
// Note: the resultSet is a result of a JOIN query with the statuses table,
|
||||
// so we can get the statuses at the same time and avoid additional database lookups.
|
||||
|
||||
while resultSet.next() {
|
||||
if let stubArticle = Article(row: resultSet, accountID: accountID) {
|
||||
stubArticles.insert(stubArticle)
|
||||
}
|
||||
if let status = statusesTable.statusWithRow(resultSet) {
|
||||
statuses.insert(status)
|
||||
}
|
||||
}
|
||||
resultSet.close()
|
||||
|
||||
return (stubArticles, statuses)
|
||||
}
|
||||
|
||||
func articleWithAttachedRelatedObjects(_ stubArticle: Article, _ authorsMap: RelatedObjectsMap?, _ attachmentsMap: RelatedObjectsMap?, _ tagsMap: RelatedObjectsMap?) -> Article {
|
||||
|
||||
let articleID = stubArticle.articleID
|
||||
|
||||
let authors = authorsMap?.authors(for: articleID)
|
||||
let attachments = attachmentsMap?.attachments(for: articleID)
|
||||
let tags = tagsMap?.tags(for: articleID)
|
||||
|
||||
let realArticle = stubArticle.articleByAttaching(authors, attachments, tags)
|
||||
return realArticle
|
||||
}
|
||||
|
||||
func fetchArticlesWithWhereClause(_ database: FMDatabase, whereClause: String, parameters: [AnyObject], withLimits: Bool) -> Set<Article> {
|
||||
|
||||
// Don’t fetch articles that shouldn’t appear in the UI. The rules:
|
||||
|
@ -27,7 +27,9 @@ final class StatusesTable: DatabaseTable {
|
||||
|
||||
self.queue = queue
|
||||
}
|
||||
|
||||
|
||||
// MARK: Cache
|
||||
|
||||
func cachedStatus(for articleID: String) -> ArticleStatus? {
|
||||
|
||||
assert(Thread.isMainThread)
|
||||
@ -35,6 +37,22 @@ final class StatusesTable: DatabaseTable {
|
||||
return cache[articleID]
|
||||
}
|
||||
|
||||
func addIfNotCached(_ statuses: Set<ArticleStatus>) {
|
||||
|
||||
if statuses.isEmpty {
|
||||
return
|
||||
}
|
||||
|
||||
if Thread.isMainThread {
|
||||
self.cache.addIfNotCached(statuses)
|
||||
}
|
||||
else {
|
||||
DispatchQueue.main.async {
|
||||
self.cache.addIfNotCached(statuses)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Creating/Updating
|
||||
|
||||
func ensureStatusesForArticleIDs(_ articleIDs: Set<String>, _ completion: @escaping StatusesCompletionBlock) {
|
||||
@ -71,11 +89,6 @@ final class StatusesTable: DatabaseTable {
|
||||
|
||||
updateRowsWithValue(NSNumber(value: flag), valueKey: statusKey, whereKey: DatabaseKey.articleID, matches: Array(articleIDs), database: database)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private extension StatusesTable {
|
||||
|
||||
// MARK: Fetching
|
||||
|
||||
@ -91,6 +104,11 @@ private extension StatusesTable {
|
||||
let articleStatus = ArticleStatus(articleID: articleID, dateArrived: dateArrived, row: row)
|
||||
return articleStatus
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private extension StatusesTable {
|
||||
|
||||
// MARK: Cache
|
||||
|
||||
|
13
ToDo.opml
13
ToDo.opml
@ -6,12 +6,12 @@
|
||||
</editor> -->
|
||||
<title>ToDo</title>
|
||||
<dateCreated>Tue, 12 Sep 2017 20:15:17 GMT</dateCreated>
|
||||
<expansionState>11,16,17,20,24,29,31,34,37,39,40,44,49,52,54,56,58,67,72,78,83</expansionState>
|
||||
<vertScrollState>59</vertScrollState>
|
||||
<windowTop>248</windowTop>
|
||||
<windowLeft>30</windowLeft>
|
||||
<windowRight>762</windowRight>
|
||||
<windowBottom>1007</windowBottom>
|
||||
<expansionState>11,16,17,20,24,29,31,34,37,39,40,44,48,51,53,55,57,66,71,77,82</expansionState>
|
||||
<vertScrollState>0</vertScrollState>
|
||||
<windowTop>523</windowTop>
|
||||
<windowLeft>40</windowLeft>
|
||||
<windowRight>772</windowRight>
|
||||
<windowBottom>1282</windowBottom>
|
||||
</head>
|
||||
<body>
|
||||
<outline text="App">
|
||||
@ -72,7 +72,6 @@
|
||||
<outline text="mark articles"/>
|
||||
<outline text="Delete old articles"/>
|
||||
<outline text="Update cutoff date periodically"/>
|
||||
<outline text="Do something with statuses on fetching articles"/>
|
||||
</outline>
|
||||
<outline text="StatusesTable">
|
||||
<outline text="Update cached statuses on marking"/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user