// // ArticlesDatabase.swift // NetNewsWire // // Created by Brent Simmons on 7/20/15. // Copyright © 2015 Ranchero Software, LLC. All rights reserved. // import Foundation import RSCore import RSDatabase import RSParser import Articles // This file and UnreadCountDictionary are the entirety of the public API for Database.framework. // Everything else is implementation. public typealias ArticleResultBlock = (Set<Article>) -> Void public typealias UnreadCountCompletionBlock = (UnreadCountDictionary) -> Void public typealias UpdateArticlesWithFeedCompletionBlock = (Set<Article>?, Set<Article>?) -> Void //newArticles, updatedArticles public final class ArticlesDatabase { private let accountID: String private let articlesTable: ArticlesTable public init(databaseFilePath: String, accountID: String) { self.accountID = accountID let queue = RSDatabaseQueue(filepath: databaseFilePath, excludeFromBackup: false) self.articlesTable = ArticlesTable(name: DatabaseTableName.articles, accountID: accountID, queue: queue) 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) queue.update { (database) in database.executeStatements("DROP TABLE if EXISTS tags;DROP INDEX if EXISTS tags_tagName_index;DROP INDEX if EXISTS articles_feedID_index;DROP INDEX if EXISTS statuses_read_index;") } queue.vacuumIfNeeded() } // MARK: - Fetching Articles public func fetchArticles(for feedID: String) -> Set<Article> { return articlesTable.fetchArticles(feedID) } public func fetchArticlesAsync(for feedID: String, _ resultBlock: @escaping ArticleResultBlock) { articlesTable.fetchArticlesAsync(feedID, withLimits: true, resultBlock) } public func fetchUnreadArticles(for feedIDs: Set<String>) -> Set<Article> { return articlesTable.fetchUnreadArticles(for: feedIDs) } public func fetchTodayArticles(for feedIDs: Set<String>) -> Set<Article> { return articlesTable.fetchTodayArticles(for: feedIDs) } public func fetchStarredArticles(for feedIDs: Set<String>) -> Set<Article> { return articlesTable.fetchStarredArticles(for: feedIDs) } // MARK: - Unread Counts public func fetchUnreadCounts(for feedIDs: Set<String>, _ completion: @escaping UnreadCountCompletionBlock) { articlesTable.fetchUnreadCounts(feedIDs, completion) } public func fetchUnreadCount(for feedIDs: Set<String>, since: Date, callback: @escaping (Int) -> Void) { articlesTable.fetchUnreadCount(feedIDs, since, callback) } public func fetchStarredAndUnreadCount(for feedIDs: Set<String>, callback: @escaping (Int) -> Void) { articlesTable.fetchStarredAndUnreadCount(feedIDs, callback) } public func fetchAllNonZeroUnreadCounts(_ completion: @escaping UnreadCountCompletionBlock) { articlesTable.fetchAllUnreadCounts(completion) } // MARK: - Saving and Updating Articles public func update(feedID: String, parsedFeed: ParsedFeed, completion: @escaping UpdateArticlesWithFeedCompletionBlock) { return articlesTable.update(feedID, parsedFeed, completion) } // MARK: - Status public func mark(_ articles: Set<Article>, statusKey: ArticleStatus.Key, flag: Bool) -> Set<ArticleStatus>? { return articlesTable.mark(articles, statusKey, flag) } public func markEverywhereAsRead() { articlesTable.markEverywhereAsRead() } }