Make Articles table own the various related and lookup tables.
This commit is contained in:
parent
becbf3d7b0
commit
cdb8446c86
|
@ -7,18 +7,35 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import RSCore
|
||||||
import RSDatabase
|
import RSDatabase
|
||||||
|
import RSParser
|
||||||
import Data
|
import Data
|
||||||
|
|
||||||
final class ArticlesTable: DatabaseTable {
|
final class ArticlesTable: DatabaseTable {
|
||||||
|
|
||||||
let name: String
|
let name: String
|
||||||
let databaseIDKey = DatabaseKey.articleID
|
let databaseIDKey = DatabaseKey.articleID
|
||||||
|
private let statusesTable: StatusesTable
|
||||||
|
private let authorsLookupTable: DatabaseLookupTable
|
||||||
|
private let attachmentsLookupTable: DatabaseLookupTable
|
||||||
|
private let tagsLookupTable: DatabaseLookupTable
|
||||||
|
|
||||||
// private let cachedArticles: NSMapTable<NSString, Article> = NSMapTable.weakToWeakObjects()
|
// private let cachedArticles: NSMapTable<NSString, Article> = NSMapTable.weakToWeakObjects()
|
||||||
|
|
||||||
init(name: String) {
|
init(name: String) {
|
||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
|
self.statusesTable = StatusesTable(name: DatabaseTableName.statuses)
|
||||||
|
let authorsTable = AuthorsTable(name: DatabaseTableName.authors)
|
||||||
|
self.authorsLookupTable = DatabaseLookupTable(name: DatabaseTableName.authorsLookup, objectIDKey: DatabaseKey.articleID, relatedObjectIDKey: DatabaseKey.authorID, relatedTable: authorsTable, relationshipName: RelationshipName.authors)
|
||||||
|
|
||||||
|
let tagsTable = TagsTable(name: DatabaseTableName.tags)
|
||||||
|
self.tagsLookupTable = DatabaseLookupTable(name: DatabaseTableName.tags, objectIDKey: DatabaseKey.articleID, relatedObjectIDKey: DatabaseKey.tagName, relatedTable: tagsTable, relationshipName: RelationshipName.tags)
|
||||||
|
|
||||||
|
let attachmentsTable = AttachmentsTable(name: DatabaseTableName.attachments)
|
||||||
|
self.attachmentsLookupTable = DatabaseLookupTable(name: DatabaseTableName.attachmentsLookup, objectIDKey: DatabaseKey.articleID, relatedObjectIDKey: DatabaseKey.attachmentID, relatedTable: attachmentsTable, relationshipName: RelationshipName.attachments)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: DatabaseTable Methods
|
// MARK: DatabaseTable Methods
|
||||||
|
@ -32,26 +49,49 @@ final class ArticlesTable: DatabaseTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
func save(_ objects: [DatabaseObject], in database: FMDatabase) {
|
func save(_ objects: [DatabaseObject], in database: FMDatabase) {
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Fetching
|
// MARK: Fetching
|
||||||
|
|
||||||
func fetchArticlesForFeed(_ feed: Feed) -> Set<Article> {
|
func fetchArticles(_ feed: Feed) -> Set<Article> {
|
||||||
|
|
||||||
return Set<Article>() // TODO
|
return Set<Article>() // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchArticlesForFeedAsync(_ feed: Feed, _ resultBlock: @escaping ArticleResultBlock) {
|
func fetchArticlesAsync(_ feed: Feed, _ resultBlock: @escaping ArticleResultBlock) {
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchUnreadArticlesForFeeds(_ feeds: Set<Feed>) -> Set<Article> {
|
func fetchUnreadArticles(_ feeds: Set<Feed>) -> Set<Article> {
|
||||||
|
|
||||||
return Set<Article>() // TODO
|
return Set<Article>() // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: Updating
|
||||||
|
|
||||||
|
func update(_ feed: Feed, _ parsedFeed: ParsedFeed, _ completion: @escaping RSVoidCompletionBlock) {
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Unread Counts
|
||||||
|
|
||||||
|
func fetchUnreadCounts(_ feeds: Set<Feed>, _ completion: @escaping UnreadCountCompletionBlock) {
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Status
|
||||||
|
|
||||||
|
func mark(_ articles: Set<Article>, _ statusKey: String, _ flag: Bool) {
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// func uniquedArticles(_ fetchedArticles: Set<Article>, statusesTable: StatusesTable) -> Set<Article> {
|
// func uniquedArticles(_ fetchedArticles: Set<Article>, statusesTable: StatusesTable) -> Set<Article> {
|
||||||
//
|
//
|
||||||
// var articles = Set<Article>()
|
// var articles = Set<Article>()
|
||||||
|
|
|
@ -12,46 +12,26 @@ import RSDatabase
|
||||||
import RSParser
|
import RSParser
|
||||||
import Data
|
import Data
|
||||||
|
|
||||||
private let sqlLogging = false
|
public typealias ArticleResultBlock = (Set<Article>) -> Void
|
||||||
|
public typealias UnreadCountTable = [String: Int] // feedID: unreadCount
|
||||||
|
public typealias UnreadCountCompletionBlock = (UnreadCountTable) -> Void //feedID: unreadCount
|
||||||
|
|
||||||
private func logSQL(_ sql: String) {
|
public final class Database {
|
||||||
if sqlLogging {
|
|
||||||
print("SQL: \(sql)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typealias ArticleResultBlock = (Set<Article>) -> Void
|
|
||||||
|
|
||||||
final class Database {
|
|
||||||
|
|
||||||
private let queue: RSDatabaseQueue
|
private let queue: RSDatabaseQueue
|
||||||
private let databaseFile: String
|
private let databaseFile: String
|
||||||
private let articlesTable: ArticlesTable
|
private let articlesTable: ArticlesTable
|
||||||
private let statusesTable: StatusesTable
|
|
||||||
private let authorsLookupTable: DatabaseLookupTable
|
|
||||||
private let attachmentsLookupTable: DatabaseLookupTable
|
|
||||||
private let tagsLookupTable: DatabaseLookupTable
|
|
||||||
private var articleArrivalCutoffDate = NSDate.rs_dateWithNumberOfDays(inThePast: 3 * 31)!
|
private var articleArrivalCutoffDate = NSDate.rs_dateWithNumberOfDays(inThePast: 3 * 31)!
|
||||||
private let minimumNumberOfArticles = 10
|
private let minimumNumberOfArticles = 10
|
||||||
private weak var delegate: AccountDelegate?
|
private weak var delegate: AccountDelegate?
|
||||||
|
|
||||||
init(databaseFile: String, delegate: AccountDelegate) {
|
public init(databaseFile: String, delegate: AccountDelegate) {
|
||||||
|
|
||||||
self.delegate = delegate
|
self.delegate = delegate
|
||||||
self.databaseFile = databaseFile
|
self.databaseFile = databaseFile
|
||||||
self.queue = RSDatabaseQueue(filepath: databaseFile, excludeFromBackup: false)
|
self.queue = RSDatabaseQueue(filepath: databaseFile, excludeFromBackup: false)
|
||||||
|
|
||||||
self.articlesTable = ArticlesTable(name: DatabaseTableName.articles)
|
self.articlesTable = ArticlesTable(name: DatabaseTableName.articles)
|
||||||
self.statusesTable = StatusesTable(name: DatabaseTableName.statuses)
|
|
||||||
|
|
||||||
let authorsTable = AuthorsTable(name: DatabaseTableName.authors)
|
|
||||||
self.authorsLookupTable = DatabaseLookupTable(name: DatabaseTableName.authorsLookup, objectIDKey: DatabaseKey.articleID, relatedObjectIDKey: DatabaseKey.authorID, relatedTable: authorsTable, relationshipName: RelationshipName.authors)
|
|
||||||
|
|
||||||
let tagsTable = TagsTable(name: DatabaseTableName.tags)
|
|
||||||
self.tagsLookupTable = DatabaseLookupTable(name: DatabaseTableName.tags, objectIDKey: DatabaseKey.articleID, relatedObjectIDKey: DatabaseKey.tagName, relatedTable: tagsTable, relationshipName: RelationshipName.tags)
|
|
||||||
|
|
||||||
let attachmentsTable = AttachmentsTable(name: DatabaseTableName.attachments)
|
|
||||||
self.attachmentsLookupTable = DatabaseLookupTable(name: DatabaseTableName.attachmentsLookup, objectIDKey: DatabaseKey.articleID, relatedObjectIDKey: DatabaseKey.attachmentID, relatedTable: attachmentsTable, relationshipName: RelationshipName.attachments)
|
|
||||||
|
|
||||||
let createStatementsPath = Bundle(for: type(of: self)).path(forResource: "CreateStatements", ofType: "sql")!
|
let createStatementsPath = Bundle(for: type(of: self)).path(forResource: "CreateStatements", ofType: "sql")!
|
||||||
let createStatements = try! NSString(contentsOfFile: createStatementsPath, encoding: String.Encoding.utf8.rawValue)
|
let createStatements = try! NSString(contentsOfFile: createStatementsPath, encoding: String.Encoding.utf8.rawValue)
|
||||||
|
@ -61,9 +41,9 @@ final class Database {
|
||||||
|
|
||||||
// MARK: - Fetching Articles
|
// MARK: - Fetching Articles
|
||||||
|
|
||||||
func fetchArticlesForFeed(_ feed: Feed) -> Set<Article> {
|
public func fetchArticles(for feed: Feed) -> Set<Article> {
|
||||||
|
|
||||||
return articlesTable.fetchArticlesForFeed(feed)
|
return articlesTable.fetchArticles(feed)
|
||||||
|
|
||||||
// return Set<Article>() // TODO
|
// return Set<Article>() // TODO
|
||||||
// var fetchedArticles = Set<Article>()
|
// var fetchedArticles = Set<Article>()
|
||||||
|
@ -78,9 +58,9 @@ final class Database {
|
||||||
// return filteredArticles(articles, feedCounts: [feed.feedID: fetchedArticles.count])
|
// return filteredArticles(articles, feedCounts: [feed.feedID: fetchedArticles.count])
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchArticlesForFeedAsync(_ feed: Feed, _ resultBlock: @escaping ArticleResultBlock) {
|
public func fetchArticlesAsync(for feed: Feed, _ resultBlock: @escaping ArticleResultBlock) {
|
||||||
|
|
||||||
articlesTable.fetchArticlesForFeedAsync(feed, resultBlock)
|
articlesTable.fetchArticlesAsync(feed, resultBlock)
|
||||||
|
|
||||||
// let feedID = feed.feedID
|
// let feedID = feed.feedID
|
||||||
//
|
//
|
||||||
|
@ -97,19 +77,17 @@ final class Database {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchUnreadArticlesForFolder(_ folder: Folder) -> Set<Article> {
|
public func fetchUnreadArticles(for folder: Folder) -> Set<Article> {
|
||||||
|
|
||||||
return articlesTable.fetchUnreadArticlesForFeeds(folder.flattenedFeeds())
|
return articlesTable.fetchUnreadArticles(folder.flattenedFeeds())
|
||||||
// return fetchUnreadArticlesForFeedIDs(folder.flattenedFeedIDs())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Unread Counts
|
// MARK: - Unread Counts
|
||||||
|
|
||||||
typealias UnreadCountTable = [String: Int] // feedID: unreadCount
|
|
||||||
typealias UnreadCountCompletionBlock = (UnreadCountTable) -> Void //feedID: unreadCount
|
|
||||||
|
|
||||||
func fetchUnreadCounts(for feeds: Set<Feed>, completion: @escaping UnreadCountCompletionBlock) {
|
public func fetchUnreadCounts(for feeds: Set<Feed>, completion: @escaping UnreadCountCompletionBlock) {
|
||||||
|
|
||||||
|
return articlesTable.fetchUnreadCounts(feeds, completion)
|
||||||
// let feedIDs = feeds.feedIDs()
|
// let feedIDs = feeds.feedIDs()
|
||||||
//
|
//
|
||||||
// queue.fetch { (database: FMDatabase!) -> Void in
|
// queue.fetch { (database: FMDatabase!) -> Void in
|
||||||
|
@ -127,7 +105,9 @@ final class Database {
|
||||||
|
|
||||||
// MARK: - Updating Articles
|
// MARK: - Updating Articles
|
||||||
|
|
||||||
func updateFeedWithParsedFeed(_ feed: Feed, parsedFeed: ParsedFeed, completionHandler: @escaping RSVoidCompletionBlock) {
|
public func update(feed: Feed, parsedFeed: ParsedFeed, completion: @escaping RSVoidCompletionBlock) {
|
||||||
|
|
||||||
|
return articlesTable.update(feed, parsedFeed, completion)
|
||||||
|
|
||||||
// if parsedFeed.items.isEmpty {
|
// if parsedFeed.items.isEmpty {
|
||||||
// completionHandler()
|
// completionHandler()
|
||||||
|
@ -145,8 +125,9 @@ final class Database {
|
||||||
|
|
||||||
// MARK: - Status
|
// MARK: - Status
|
||||||
|
|
||||||
func markArticles(_ articles: Set<Article>, statusKey: ArticleStatusKey, flag: Bool) {
|
public func mark(_ articles: Set<Article>, statusKey: String, flag: Bool) {
|
||||||
|
|
||||||
|
articlesTable.mark(articles, statusKey, flag)
|
||||||
// statusesTable.markArticles(articles, statusKey: statusKey, flag: flag)
|
// statusesTable.markArticles(articles, statusKey: statusKey, flag: flag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,9 +246,9 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
84E156F11F0AB83600F8CC05 /* Data.xcodeproj */,
|
84E156F11F0AB83600F8CC05 /* Data.xcodeproj */,
|
||||||
|
84E157001F0AB89B00F8CC05 /* RSDatabase.xcodeproj */,
|
||||||
84BB4B8F1F119C4900858766 /* RSCore.xcodeproj */,
|
84BB4B8F1F119C4900858766 /* RSCore.xcodeproj */,
|
||||||
8461461E1F0ABC7300870CB3 /* RSParser.xcodeproj */,
|
8461461E1F0ABC7300870CB3 /* RSParser.xcodeproj */,
|
||||||
84E157001F0AB89B00F8CC05 /* RSDatabase.xcodeproj */,
|
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|
Loading…
Reference in New Issue