Adopt DatabaseQueue.
This commit is contained in:
parent
6fdaf773cd
commit
9dc3ed03c7
@ -22,21 +22,29 @@ public typealias UpdateArticlesCompletionBlock = (Set<Article>?, Set<Article>?)
|
|||||||
|
|
||||||
public final class ArticlesDatabase {
|
public final class ArticlesDatabase {
|
||||||
|
|
||||||
|
/// When ArticlesDatabase is suspended, database calls will crash the app.
|
||||||
|
public var isSuspended: Bool {
|
||||||
|
return queue.isSuspended
|
||||||
|
}
|
||||||
|
|
||||||
private let articlesTable: ArticlesTable
|
private let articlesTable: ArticlesTable
|
||||||
|
private let queue: DatabaseQueue
|
||||||
|
|
||||||
public init(databaseFilePath: String, accountID: String) {
|
public init(databaseFilePath: String, accountID: String) {
|
||||||
let queue = RSDatabaseQueue(filepath: databaseFilePath, excludeFromBackup: false)
|
let queue = DatabaseQueue(databasePath: databaseFilePath)
|
||||||
|
self.queue = queue
|
||||||
self.articlesTable = ArticlesTable(name: DatabaseTableName.articles, accountID: accountID, queue: queue)
|
self.articlesTable = ArticlesTable(name: DatabaseTableName.articles, accountID: accountID, queue: queue)
|
||||||
|
|
||||||
queue.createTables(usingStatements: ArticlesDatabase.tableCreationStatements)
|
queue.runCreateStatements(ArticlesDatabase.tableCreationStatements)
|
||||||
queue.update { (database) in
|
queue.runInDatabase { database in
|
||||||
if !self.articlesTable.containsColumn("searchRowID", in: database) {
|
if !self.articlesTable.containsColumn("searchRowID", in: database) {
|
||||||
database.executeStatements("ALTER TABLE articles add column searchRowID INTEGER;")
|
database.executeStatements("ALTER TABLE articles add column searchRowID INTEGER;")
|
||||||
}
|
}
|
||||||
database.executeStatements("CREATE INDEX if not EXISTS articles_searchRowID on articles(searchRowID);")
|
database.executeStatements("CREATE INDEX if not EXISTS articles_searchRowID on articles(searchRowID);")
|
||||||
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;")
|
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()
|
|
||||||
|
queue.vacuumIfNeeded(daysBetweenVacuums: 9)
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.articlesTable.indexUnindexedArticles()
|
self.articlesTable.indexUnindexedArticles()
|
||||||
}
|
}
|
||||||
@ -145,6 +153,19 @@ public final class ArticlesDatabase {
|
|||||||
return articlesTable.mark(articles, statusKey, flag)
|
return articlesTable.mark(articles, statusKey, flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Suspend and Resume (for iOS)
|
||||||
|
|
||||||
|
/// Close the database and stop running database calls.
|
||||||
|
/// Any pending calls will complete first.
|
||||||
|
public func suspend() {
|
||||||
|
queue.suspend()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Open the database and allow for running database calls again.
|
||||||
|
public func resume() {
|
||||||
|
queue.resume()
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Caches
|
// MARK: - Caches
|
||||||
|
|
||||||
/// Call to free up some memory. Should be done when the app is backgrounded, for instance.
|
/// Call to free up some memory. Should be done when the app is backgrounded, for instance.
|
||||||
|
@ -16,7 +16,7 @@ final class ArticlesTable: DatabaseTable {
|
|||||||
|
|
||||||
let name: String
|
let name: String
|
||||||
private let accountID: String
|
private let accountID: String
|
||||||
private let queue: RSDatabaseQueue
|
private let queue: DatabaseQueue
|
||||||
private let statusesTable: StatusesTable
|
private let statusesTable: StatusesTable
|
||||||
private let authorsLookupTable: DatabaseLookupTable
|
private let authorsLookupTable: DatabaseLookupTable
|
||||||
private let attachmentsLookupTable: DatabaseLookupTable
|
private let attachmentsLookupTable: DatabaseLookupTable
|
||||||
@ -32,7 +32,7 @@ final class ArticlesTable: DatabaseTable {
|
|||||||
|
|
||||||
private typealias ArticlesFetchMethod = (FMDatabase) -> Set<Article>
|
private typealias ArticlesFetchMethod = (FMDatabase) -> Set<Article>
|
||||||
|
|
||||||
init(name: String, accountID: String, queue: RSDatabaseQueue) {
|
init(name: String, accountID: String, queue: DatabaseQueue) {
|
||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
self.accountID = accountID
|
self.accountID = accountID
|
||||||
@ -149,7 +149,7 @@ final class ArticlesTable: DatabaseTable {
|
|||||||
|
|
||||||
func fetchArticlesMatching(_ searchString: String, _ feedIDs: Set<String>) -> Set<Article> {
|
func fetchArticlesMatching(_ searchString: String, _ feedIDs: Set<String>) -> Set<Article> {
|
||||||
var articles: Set<Article> = Set<Article>()
|
var articles: Set<Article> = Set<Article>()
|
||||||
queue.fetchSync { (database) in
|
queue.runInDatabaseSync { (database) in
|
||||||
articles = self.fetchArticlesMatching(searchString, database)
|
articles = self.fetchArticlesMatching(searchString, database)
|
||||||
}
|
}
|
||||||
articles = articles.filter{ feedIDs.contains($0.feedID) }
|
articles = articles.filter{ feedIDs.contains($0.feedID) }
|
||||||
@ -229,7 +229,7 @@ final class ArticlesTable: DatabaseTable {
|
|||||||
articleIDs.formUnion(parsedItems.articleIDs())
|
articleIDs.formUnion(parsedItems.articleIDs())
|
||||||
}
|
}
|
||||||
|
|
||||||
self.queue.update { (database) in
|
self.queue.runInTransaction { (database) in
|
||||||
let statusesDictionary = self.statusesTable.ensureStatusesForArticleIDs(articleIDs, read, database) //1
|
let statusesDictionary = self.statusesTable.ensureStatusesForArticleIDs(articleIDs, read, database) //1
|
||||||
assert(statusesDictionary.count == articleIDs.count)
|
assert(statusesDictionary.count == articleIDs.count)
|
||||||
|
|
||||||
@ -273,7 +273,7 @@ final class ArticlesTable: DatabaseTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ensureStatuses(_ articleIDs: Set<String>, _ defaultRead: Bool, _ statusKey: ArticleStatus.Key, _ flag: Bool) {
|
func ensureStatuses(_ articleIDs: Set<String>, _ defaultRead: Bool, _ statusKey: ArticleStatus.Key, _ flag: Bool) {
|
||||||
self.queue.update { (database) in
|
self.queue.runInTransaction { (database) in
|
||||||
let statusesDictionary = self.statusesTable.ensureStatusesForArticleIDs(articleIDs, defaultRead, database)
|
let statusesDictionary = self.statusesTable.ensureStatusesForArticleIDs(articleIDs, defaultRead, database)
|
||||||
let statuses = Set(statusesDictionary.values)
|
let statuses = Set(statusesDictionary.values)
|
||||||
self.statusesTable.mark(statuses, statusKey, flag, database)
|
self.statusesTable.mark(statuses, statusKey, flag, database)
|
||||||
@ -290,7 +290,7 @@ final class ArticlesTable: DatabaseTable {
|
|||||||
|
|
||||||
var unreadCountDictionary = UnreadCountDictionary()
|
var unreadCountDictionary = UnreadCountDictionary()
|
||||||
|
|
||||||
queue.fetch { (database) in
|
queue.runInDatabase { (database) in
|
||||||
for feedID in feedIDs {
|
for feedID in feedIDs {
|
||||||
unreadCountDictionary[feedID] = self.fetchUnreadCount(feedID, database)
|
unreadCountDictionary[feedID] = self.fetchUnreadCount(feedID, database)
|
||||||
}
|
}
|
||||||
@ -309,7 +309,7 @@ final class ArticlesTable: DatabaseTable {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
queue.fetch { (database) in
|
queue.runInDatabase { (database) in
|
||||||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))!
|
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))!
|
||||||
let sql = "select count(*) from articles natural join statuses where feedID in \(placeholders) and (datePublished > ? or (datePublished is null and dateArrived > ?)) and read=0 and userDeleted=0;"
|
let sql = "select count(*) from articles natural join statuses where feedID in \(placeholders) and (datePublished > ? or (datePublished is null and dateArrived > ?)) and read=0 and userDeleted=0;"
|
||||||
|
|
||||||
@ -331,7 +331,7 @@ final class ArticlesTable: DatabaseTable {
|
|||||||
|
|
||||||
let cutoffDate = articleCutoffDate
|
let cutoffDate = articleCutoffDate
|
||||||
|
|
||||||
queue.fetch { (database) in
|
queue.runInDatabase { (database) in
|
||||||
let sql = "select distinct feedID, count(*) from articles natural join statuses where read=0 and userDeleted=0 and (starred=1 or dateArrived>?) group by feedID;"
|
let sql = "select distinct feedID, count(*) from articles natural join statuses where read=0 and userDeleted=0 and (starred=1 or dateArrived>?) group by feedID;"
|
||||||
|
|
||||||
guard let resultSet = database.executeQuery(sql, withArgumentsIn: [cutoffDate]) else {
|
guard let resultSet = database.executeQuery(sql, withArgumentsIn: [cutoffDate]) else {
|
||||||
@ -361,7 +361,7 @@ final class ArticlesTable: DatabaseTable {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
queue.fetch { (database) in
|
queue.runInDatabase { (database) in
|
||||||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))!
|
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))!
|
||||||
let sql = "select count(*) from articles natural join statuses where feedID in \(placeholders) and read=0 and starred=1 and userDeleted=0;"
|
let sql = "select count(*) from articles natural join statuses where feedID in \(placeholders) and read=0 and starred=1 and userDeleted=0;"
|
||||||
let parameters = Array(feedIDs) as [Any]
|
let parameters = Array(feedIDs) as [Any]
|
||||||
@ -390,7 +390,7 @@ final class ArticlesTable: DatabaseTable {
|
|||||||
|
|
||||||
func mark(_ articles: Set<Article>, _ statusKey: ArticleStatus.Key, _ flag: Bool) -> Set<ArticleStatus>? {
|
func mark(_ articles: Set<Article>, _ statusKey: ArticleStatus.Key, _ flag: Bool) -> Set<ArticleStatus>? {
|
||||||
var statuses: Set<ArticleStatus>?
|
var statuses: Set<ArticleStatus>?
|
||||||
self.queue.updateSync { (database) in
|
self.queue.runInTransactionSync { (database) in
|
||||||
statuses = self.statusesTable.mark(articles.statuses(), statusKey, flag, database)
|
statuses = self.statusesTable.mark(articles.statuses(), statusKey, flag, database)
|
||||||
}
|
}
|
||||||
return statuses
|
return statuses
|
||||||
@ -399,7 +399,7 @@ final class ArticlesTable: DatabaseTable {
|
|||||||
// MARK: - Indexing
|
// MARK: - Indexing
|
||||||
|
|
||||||
func indexUnindexedArticles() {
|
func indexUnindexedArticles() {
|
||||||
queue.fetch { (database) in
|
queue.runInDatabase { (database) in
|
||||||
let sql = "select articleID from articles where searchRowID is null limit 500;"
|
let sql = "select articleID from articles where searchRowID is null limit 500;"
|
||||||
guard let resultSet = database.executeQuery(sql, withArgumentsIn: nil) else {
|
guard let resultSet = database.executeQuery(sql, withArgumentsIn: nil) else {
|
||||||
return
|
return
|
||||||
@ -419,7 +419,7 @@ final class ArticlesTable: DatabaseTable {
|
|||||||
// MARK: - Caches
|
// MARK: - Caches
|
||||||
|
|
||||||
func emptyCaches() {
|
func emptyCaches() {
|
||||||
queue.run { _ in
|
queue.runInDatabase { _ in
|
||||||
self.databaseArticlesCache = [String: DatabaseArticle]()
|
self.databaseArticlesCache = [String: DatabaseArticle]()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -433,7 +433,7 @@ final class ArticlesTable: DatabaseTable {
|
|||||||
if feedIDs.isEmpty {
|
if feedIDs.isEmpty {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
queue.run { (database) in
|
queue.runInDatabase { (database) in
|
||||||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))!
|
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))!
|
||||||
let sql = "select articleID from articles where feedID not in \(placeholders);"
|
let sql = "select articleID from articles where feedID not in \(placeholders);"
|
||||||
let parameters = Array(feedIDs) as [Any]
|
let parameters = Array(feedIDs) as [Any]
|
||||||
@ -458,14 +458,14 @@ private extension ArticlesTable {
|
|||||||
|
|
||||||
private func fetchArticles(_ fetchMethod: @escaping ArticlesFetchMethod) -> Set<Article> {
|
private func fetchArticles(_ fetchMethod: @escaping ArticlesFetchMethod) -> Set<Article> {
|
||||||
var articles = Set<Article>()
|
var articles = Set<Article>()
|
||||||
queue.fetchSync { (database) in
|
queue.runInDatabaseSync { (database) in
|
||||||
articles = fetchMethod(database)
|
articles = fetchMethod(database)
|
||||||
}
|
}
|
||||||
return articles
|
return articles
|
||||||
}
|
}
|
||||||
|
|
||||||
private func fetchArticlesAsync(_ fetchMethod: @escaping ArticlesFetchMethod, _ callback: @escaping ArticleSetBlock) {
|
private func fetchArticlesAsync(_ fetchMethod: @escaping ArticlesFetchMethod, _ callback: @escaping ArticleSetBlock) {
|
||||||
queue.fetch { (database) in
|
queue.runInDatabase { (database) in
|
||||||
let articles = fetchMethod(database)
|
let articles = fetchMethod(database)
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
callback(articles)
|
callback(articles)
|
||||||
|
@ -61,10 +61,10 @@ final class ArticleSearchInfo: Hashable {
|
|||||||
final class SearchTable: DatabaseTable {
|
final class SearchTable: DatabaseTable {
|
||||||
|
|
||||||
let name = "search"
|
let name = "search"
|
||||||
private let queue: RSDatabaseQueue
|
private let queue: DatabaseQueue
|
||||||
private weak var articlesTable: ArticlesTable?
|
private weak var articlesTable: ArticlesTable?
|
||||||
|
|
||||||
init(queue: RSDatabaseQueue, articlesTable: ArticlesTable) {
|
init(queue: DatabaseQueue, articlesTable: ArticlesTable) {
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
self.articlesTable = articlesTable
|
self.articlesTable = articlesTable
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ final class SearchTable: DatabaseTable {
|
|||||||
if articleIDs.isEmpty {
|
if articleIDs.isEmpty {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
queue.update { (database) in
|
queue.runInTransaction { (database) in
|
||||||
self.ensureIndexedArticles(articleIDs, database)
|
self.ensureIndexedArticles(articleIDs, database)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,9 @@ final class StatusesTable: DatabaseTable {
|
|||||||
|
|
||||||
let name = DatabaseTableName.statuses
|
let name = DatabaseTableName.statuses
|
||||||
private let cache = StatusCache()
|
private let cache = StatusCache()
|
||||||
private let queue: RSDatabaseQueue
|
private let queue: DatabaseQueue
|
||||||
|
|
||||||
init(queue: RSDatabaseQueue) {
|
init(queue: DatabaseQueue) {
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ final class StatusesTable: DatabaseTable {
|
|||||||
|
|
||||||
func fetchArticleIDs(_ sql: String) -> Set<String> {
|
func fetchArticleIDs(_ sql: String) -> Set<String> {
|
||||||
var articleIDs = Set<String>()
|
var articleIDs = Set<String>()
|
||||||
queue.fetchSync { (database) in
|
queue.runInDatabaseSync { (database) in
|
||||||
guard let resultSet = database.executeQuery(sql, withArgumentsIn: nil) else {
|
guard let resultSet = database.executeQuery(sql, withArgumentsIn: nil) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -9,20 +9,27 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RSDatabase
|
import RSDatabase
|
||||||
|
|
||||||
public final class SyncDatabase {
|
public struct SyncDatabase {
|
||||||
|
|
||||||
|
/// When SyncDatabase is suspended, database calls will crash the app.
|
||||||
|
public var isSuspended: Bool {
|
||||||
|
return queue.isSuspended
|
||||||
|
}
|
||||||
|
|
||||||
private let syncStatusTable: SyncStatusTable
|
private let syncStatusTable: SyncStatusTable
|
||||||
|
private let queue: DatabaseQueue
|
||||||
|
|
||||||
public init(databaseFilePath: String) {
|
public init(databaseFilePath: String) {
|
||||||
|
let queue = DatabaseQueue(databasePath: databaseFilePath)
|
||||||
|
queue.runCreateStatements(SyncDatabase.tableCreationStatements)
|
||||||
|
queue.vacuumIfNeeded(daysBetweenVacuums: 11)
|
||||||
|
self.queue = queue
|
||||||
|
|
||||||
let queue = RSDatabaseQueue(filepath: databaseFilePath, excludeFromBackup: false)
|
|
||||||
self.syncStatusTable = SyncStatusTable(queue: queue)
|
self.syncStatusTable = SyncStatusTable(queue: queue)
|
||||||
|
|
||||||
queue.createTables(usingStatements: SyncDatabase.tableCreationStatements)
|
|
||||||
queue.vacuumIfNeeded()
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - API
|
||||||
|
|
||||||
public func insertStatuses(_ statuses: [SyncStatus]) {
|
public func insertStatuses(_ statuses: [SyncStatus]) {
|
||||||
syncStatusTable.insertStatuses(statuses)
|
syncStatusTable.insertStatuses(statuses)
|
||||||
}
|
}
|
||||||
@ -43,6 +50,18 @@ public final class SyncDatabase {
|
|||||||
syncStatusTable.deleteSelectedForProcessing(articleIDs)
|
syncStatusTable.deleteSelectedForProcessing(articleIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Suspend and Resume (for iOS)
|
||||||
|
|
||||||
|
/// Close the database and stop running database calls.
|
||||||
|
/// Any pending calls will complete first.
|
||||||
|
public func suspend() {
|
||||||
|
queue.suspend()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Open the database and allow for running database calls again.
|
||||||
|
public func resume() {
|
||||||
|
queue.resume()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
@ -10,21 +10,19 @@ import Foundation
|
|||||||
import Articles
|
import Articles
|
||||||
import RSDatabase
|
import RSDatabase
|
||||||
|
|
||||||
final class SyncStatusTable: DatabaseTable {
|
struct SyncStatusTable: DatabaseTable {
|
||||||
|
|
||||||
let name = DatabaseTableName.syncStatus
|
let name = DatabaseTableName.syncStatus
|
||||||
private let queue: RSDatabaseQueue
|
private let queue: DatabaseQueue
|
||||||
|
|
||||||
init(queue: RSDatabaseQueue) {
|
init(queue: DatabaseQueue) {
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
}
|
}
|
||||||
|
|
||||||
func selectForProcessing() -> [SyncStatus] {
|
func selectForProcessing() -> [SyncStatus] {
|
||||||
|
|
||||||
var statuses: Set<SyncStatus>? = nil
|
var statuses: Set<SyncStatus>? = nil
|
||||||
|
|
||||||
self.queue.updateSync { database in
|
queue.runInDatabaseSync { database in
|
||||||
|
|
||||||
let updateSQL = "update syncStatus set selected = true"
|
let updateSQL = "update syncStatus set selected = true"
|
||||||
database.executeUpdate(updateSQL, withArgumentsIn: nil)
|
database.executeUpdate(updateSQL, withArgumentsIn: nil)
|
||||||
|
|
||||||
@ -32,32 +30,26 @@ final class SyncStatusTable: DatabaseTable {
|
|||||||
if let resultSet = database.executeQuery(selectSQL, withArgumentsIn: nil) {
|
if let resultSet = database.executeQuery(selectSQL, withArgumentsIn: nil) {
|
||||||
statuses = resultSet.mapToSet(self.statusWithRow)
|
statuses = resultSet.mapToSet(self.statusWithRow)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return statuses != nil ? Array(statuses!) : [SyncStatus]()
|
return statuses != nil ? Array(statuses!) : [SyncStatus]()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func selectPendingCount() -> Int {
|
func selectPendingCount() -> Int {
|
||||||
|
|
||||||
var count: Int = 0
|
var count: Int = 0
|
||||||
|
|
||||||
self.queue.fetchSync { (database) in
|
queue.runInDatabaseSync { database in
|
||||||
let sql = "select count(*) from syncStatus"
|
let sql = "select count(*) from syncStatus"
|
||||||
if let resultSet = database.executeQuery(sql, withArgumentsIn: nil) {
|
if let resultSet = database.executeQuery(sql, withArgumentsIn: nil) {
|
||||||
resultSet.next()
|
count = numberWithCountResultSet(resultSet)
|
||||||
count = Int(resultSet.int(forColumnIndex: 0))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return count
|
return count
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func resetSelectedForProcessing(_ articleIDs: [String]) {
|
func resetSelectedForProcessing(_ articleIDs: [String]) {
|
||||||
self.queue.update { database in
|
queue.runInTransaction { database in
|
||||||
let parameters = articleIDs.map { $0 as AnyObject }
|
let parameters = articleIDs.map { $0 as AnyObject }
|
||||||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(articleIDs.count))!
|
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(articleIDs.count))!
|
||||||
let updateSQL = "update syncStatus set selected = false where articleID in \(placeholders)"
|
let updateSQL = "update syncStatus set selected = false where articleID in \(placeholders)"
|
||||||
@ -66,7 +58,7 @@ final class SyncStatusTable: DatabaseTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func deleteSelectedForProcessing(_ articleIDs: [String]) {
|
func deleteSelectedForProcessing(_ articleIDs: [String]) {
|
||||||
self.queue.update { database in
|
queue.runInTransaction { database in
|
||||||
let parameters = articleIDs.map { $0 as AnyObject }
|
let parameters = articleIDs.map { $0 as AnyObject }
|
||||||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(articleIDs.count))!
|
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(articleIDs.count))!
|
||||||
let deleteSQL = "delete from syncStatus where articleID in \(placeholders)"
|
let deleteSQL = "delete from syncStatus where articleID in \(placeholders)"
|
||||||
@ -75,18 +67,16 @@ final class SyncStatusTable: DatabaseTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func insertStatuses(_ statuses: [SyncStatus]) {
|
func insertStatuses(_ statuses: [SyncStatus]) {
|
||||||
self.queue.update { database in
|
queue.runInTransaction { database in
|
||||||
let statusArray = statuses.map { $0.databaseDictionary() }
|
let statusArray = statuses.map { $0.databaseDictionary() }
|
||||||
self.insertRows(statusArray, insertType: .orReplace, in: database)
|
self.insertRows(statusArray, insertType: .orReplace, in: database)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension SyncStatusTable {
|
private extension SyncStatusTable {
|
||||||
|
|
||||||
func statusWithRow(_ row: FMResultSet) -> SyncStatus? {
|
func statusWithRow(_ row: FMResultSet) -> SyncStatus? {
|
||||||
|
|
||||||
guard let articleID = row.string(forColumn: DatabaseKey.articleID),
|
guard let articleID = row.string(forColumn: DatabaseKey.articleID),
|
||||||
let rawKey = row.string(forColumn: DatabaseKey.key),
|
let rawKey = row.string(forColumn: DatabaseKey.key),
|
||||||
let key = ArticleStatus.Key(rawValue: rawKey) else {
|
let key = ArticleStatus.Key(rawValue: rawKey) else {
|
||||||
@ -97,6 +87,5 @@ private extension SyncStatusTable {
|
|||||||
let selected = row.bool(forColumn: DatabaseKey.selected)
|
let selected = row.bool(forColumn: DatabaseKey.selected)
|
||||||
|
|
||||||
return SyncStatus(articleID: articleID, key: key, flag: flag, selected: selected)
|
return SyncStatus(articleID: articleID, key: key, flag: flag, selected: selected)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user