Make Articles table own the various related and lookup tables.

This commit is contained in:
Brent Simmons 2017-08-23 13:23:12 -07:00
parent becbf3d7b0
commit cdb8446c86
3 changed files with 62 additions and 41 deletions

View File

@ -7,18 +7,35 @@
//
import Foundation
import RSCore
import RSDatabase
import RSParser
import Data
final class ArticlesTable: DatabaseTable {
let name: String
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()
init(name: String) {
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
@ -32,26 +49,49 @@ final class ArticlesTable: DatabaseTable {
}
func save(_ objects: [DatabaseObject], in database: FMDatabase) {
// TODO
}
// MARK: Fetching
func fetchArticlesForFeed(_ feed: Feed) -> Set<Article> {
func fetchArticles(_ feed: Feed) -> Set<Article> {
return Set<Article>() // TODO
}
func fetchArticlesForFeedAsync(_ feed: Feed, _ resultBlock: @escaping ArticleResultBlock) {
func fetchArticlesAsync(_ feed: Feed, _ resultBlock: @escaping ArticleResultBlock) {
// TODO
}
func fetchUnreadArticlesForFeeds(_ feeds: Set<Feed>) -> Set<Article> {
func fetchUnreadArticles(_ feeds: Set<Feed>) -> Set<Article> {
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> {
//
// var articles = Set<Article>()

View File

@ -12,47 +12,27 @@ import RSDatabase
import RSParser
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) {
if sqlLogging {
print("SQL: \(sql)")
}
}
typealias ArticleResultBlock = (Set<Article>) -> Void
final class Database {
public final class Database {
private let queue: RSDatabaseQueue
private let databaseFile: String
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 let minimumNumberOfArticles = 10
private weak var delegate: AccountDelegate?
init(databaseFile: String, delegate: AccountDelegate) {
public init(databaseFile: String, delegate: AccountDelegate) {
self.delegate = delegate
self.databaseFile = databaseFile
self.queue = RSDatabaseQueue(filepath: databaseFile, excludeFromBackup: false)
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 createStatements = try! NSString(contentsOfFile: createStatementsPath, encoding: String.Encoding.utf8.rawValue)
queue.createTables(usingStatements: createStatements as String)
@ -61,9 +41,9 @@ final class Database {
// 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
// var fetchedArticles = Set<Article>()
@ -78,9 +58,9 @@ final class Database {
// 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
//
@ -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 fetchUnreadArticlesForFeedIDs(folder.flattenedFeedIDs())
return articlesTable.fetchUnreadArticles(folder.flattenedFeeds())
}
// 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()
//
// queue.fetch { (database: FMDatabase!) -> Void in
@ -127,8 +105,10 @@ final class Database {
// 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 {
// completionHandler()
// return
@ -145,8 +125,9 @@ final class Database {
// 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)
}
}

View File

@ -246,9 +246,9 @@
isa = PBXGroup;
children = (
84E156F11F0AB83600F8CC05 /* Data.xcodeproj */,
84E157001F0AB89B00F8CC05 /* RSDatabase.xcodeproj */,
84BB4B8F1F119C4900858766 /* RSCore.xcodeproj */,
8461461E1F0ABC7300870CB3 /* RSParser.xcodeproj */,
84E157001F0AB89B00F8CC05 /* RSDatabase.xcodeproj */,
);
name = Frameworks;
sourceTree = "<group>";