Make DatabaseTable a protocol.

This commit is contained in:
Brent Simmons 2017-07-16 20:51:08 -07:00
parent 8fc4c3041d
commit f293d5715c
4 changed files with 60 additions and 39 deletions

View File

@ -1,5 +1,5 @@
// //
// AttachmentsManager.swift // AttachmentsTable.swift
// Database // Database
// //
// Created by Brent Simmons on 7/15/17. // Created by Brent Simmons on 7/15/17.
@ -29,12 +29,11 @@ import Data
// * They dont take up much space. // * They dont take up much space.
// * It seriously cuts down on the number of database reads and writes. // * It seriously cuts down on the number of database reads and writes.
final class AttachmentsManager { final class AttachmentsTable: DatabaseTable {
private var cachedAttachments = [String: Attachment]() // Attachment.databaseID key private var cachedAttachments = [String: Attachment]() // Attachment.databaseID key
private var cachedAttachmentsByArticle = [String: Set<Attachment>]() // Article.databaseID key private var cachedAttachmentsByArticle = [String: Set<Attachment>]() // Article.databaseID key
private var articlesWithNoAttachments = Set<String>() // Article.databaseID private var articlesWithNoAttachments = Set<String>() // Article.databaseID
private let table = DatabaseTable(name: DatabaseTableName.attachments)
func fetchAttachmentsForArticles(_ articles: Set<Article>, database: FMDatabase) { func fetchAttachmentsForArticles(_ articles: Set<Article>, database: FMDatabase) {
@ -101,21 +100,41 @@ final class AttachmentsManager {
} }
} }
if !articlesWithPossiblyAllAttachmentsDeleted.isEmpty { deleteAttachmentsForArticles(articlesWithPossiblyAllAttachmentsDeleted, database)
deleteAttachmentsForArticles(articlesWithPossiblyAllAttachmentsDeleted) deleteAttachments(attachmentsToDelete, database)
} saveAttachments(attachmentsToSave, database)
} }
} }
private extension AttachmentsManager { private extension AttachmentsManager {
func deleteAttachmentsForArticles(_ articles: Set<Article>, database: FMDatabase) { func deleteAttachmentsForArticles(_ articles: Set<Article>, _ database: FMDatabase) {
if articles.isEmpty {
return
}
articles.forEach { uncacheAttachmentsForArticle($0) }
let articleIDs = articles.map { $0.databaseID } let articleIDs = articles.map { $0.databaseID }
articlesWithNoAttachments.formUnion(Set(articleIDs)) deleteRowsWhere(key: DatabaseKey.articleID, equalsAnyValue: articlesIDs, in: database)
articleIDs.forEach { cachedAttachmentsByArticle[$0] = nil } }
func deleteAttachments(_ attachments: Set<Attachment>, _ database: FMDatabase) {
if attachments.isEmpty {
return
}
let databaseIDs = attachments.map { $0.databaseID }
deleteRowsWhere(key: DatabaseKey.databaseID, equalsAnyValue: databaseIDs, in: database)
}
func saveAttachments(_ attachments: Set<Attachment>, _ database: FMDatabase) {
if attachments.isEmpty {
return
}
let _ = database.rs_deleteRowsWhereKey(DatabaseKey.articleID, inValues: articleIDs, tableName: DatabaseTableName.attachments)
} }
func addCachedAttachmentsToArticle(_ article: Article) { func addCachedAttachmentsToArticle(_ article: Article) {
@ -149,14 +168,6 @@ private extension AttachmentsManager {
assert(article.attachments == nil || article.attachments.isEmpty) assert(article.attachments == nil || article.attachments.isEmpty)
articlesWithNoAttachments.insert(article.databaseID) articlesWithNoAttachments.insert(article.databaseID)
cachedAttachmentsByArticle[article.databaseID] = nil cachedAttachmentsByArticle[article.databaseID] = nil
var attachmentDatabaseIDsToUncache = Set<String>()
for (databaseID, attachment) in cachedAttachments {
if attachment.articleID == article.databaseID {
attachmentDatabaseIDsToUncache.insert(databaseID)
}
}
attachmentDatabaseIDsToUncache.forEach { uncacheAttachmentWithDatabaseID($0) }
} }
func cacheAttachmentsForArticle(_ article: Article) { func cacheAttachmentsForArticle(_ article: Article) {

View File

@ -7,7 +7,7 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
840405CF1F1A963700DF0296 /* AttachmentsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840405CE1F1A963700DF0296 /* AttachmentsManager.swift */; }; 840405CF1F1A963700DF0296 /* AttachmentsTable..swift in Sources */ = {isa = PBXBuildFile; fileRef = 840405CE1F1A963700DF0296 /* AttachmentsTable..swift */; };
844BEE411F0AB3AB004AB7CD /* Database.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 844BEE371F0AB3AA004AB7CD /* Database.framework */; }; 844BEE411F0AB3AB004AB7CD /* Database.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 844BEE371F0AB3AA004AB7CD /* Database.framework */; };
844BEE461F0AB3AB004AB7CD /* DatabaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE451F0AB3AB004AB7CD /* DatabaseTests.swift */; }; 844BEE461F0AB3AB004AB7CD /* DatabaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE451F0AB3AB004AB7CD /* DatabaseTests.swift */; };
845580671F0AEBCD003CCFA1 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845580661F0AEBCD003CCFA1 /* Constants.swift */; }; 845580671F0AEBCD003CCFA1 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845580661F0AEBCD003CCFA1 /* Constants.swift */; };
@ -109,7 +109,7 @@
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
840405CE1F1A963700DF0296 /* AttachmentsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentsManager.swift; sourceTree = "<group>"; }; 840405CE1F1A963700DF0296 /* AttachmentsTable..swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentsTable..swift; sourceTree = "<group>"; };
844BEE371F0AB3AA004AB7CD /* Database.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Database.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 844BEE371F0AB3AA004AB7CD /* Database.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Database.framework; sourceTree = BUILT_PRODUCTS_DIR; };
844BEE401F0AB3AB004AB7CD /* DatabaseTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DatabaseTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 844BEE401F0AB3AB004AB7CD /* DatabaseTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DatabaseTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
844BEE451F0AB3AB004AB7CD /* DatabaseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseTests.swift; sourceTree = "<group>"; }; 844BEE451F0AB3AB004AB7CD /* DatabaseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseTests.swift; sourceTree = "<group>"; };
@ -165,7 +165,7 @@
84E156EB1F0AB80E00F8CC05 /* ArticlesManager.swift */, 84E156EB1F0AB80E00F8CC05 /* ArticlesManager.swift */,
84E156ED1F0AB81400F8CC05 /* StatusesManager.swift */, 84E156ED1F0AB81400F8CC05 /* StatusesManager.swift */,
84F20F8E1F180D8700D8E682 /* AuthorsManager.swift */, 84F20F8E1F180D8700D8E682 /* AuthorsManager.swift */,
840405CE1F1A963700DF0296 /* AttachmentsManager.swift */, 840405CE1F1A963700DF0296 /* AttachmentsTable..swift */,
84BB4BA81F11A32800858766 /* TagsManager.swift */, 84BB4BA81F11A32800858766 /* TagsManager.swift */,
8461462A1F0AC44100870CB3 /* Extensions */, 8461462A1F0AC44100870CB3 /* Extensions */,
84E156EF1F0AB81F00F8CC05 /* CreateStatements.sql */, 84E156EF1F0AB81F00F8CC05 /* CreateStatements.sql */,
@ -466,7 +466,7 @@
8455807C1F0C0DBD003CCFA1 /* Attachment+Database.swift in Sources */, 8455807C1F0C0DBD003CCFA1 /* Attachment+Database.swift in Sources */,
84F20F8F1F180D8700D8E682 /* AuthorsManager.swift in Sources */, 84F20F8F1F180D8700D8E682 /* AuthorsManager.swift in Sources */,
845580671F0AEBCD003CCFA1 /* Constants.swift in Sources */, 845580671F0AEBCD003CCFA1 /* Constants.swift in Sources */,
840405CF1F1A963700DF0296 /* AttachmentsManager.swift in Sources */, 840405CF1F1A963700DF0296 /* AttachmentsTable..swift in Sources */,
845580781F0AF678003CCFA1 /* Folder+Database.swift in Sources */, 845580781F0AF678003CCFA1 /* Folder+Database.swift in Sources */,
845580761F0AF670003CCFA1 /* Article+Database.swift in Sources */, 845580761F0AF670003CCFA1 /* Article+Database.swift in Sources */,
845580721F0AEE49003CCFA1 /* AccountInfo.swift in Sources */, 845580721F0AEE49003CCFA1 /* AccountInfo.swift in Sources */,

View File

@ -8,18 +8,26 @@
import Foundation import Foundation
public struct DatabaseTable { public protocol DatabaseTable {
public let name: String public var name: String {get}
public init(name: String) { public init(name: String)
}
self.name = name extension DatabaseTable {
}
public func selectRowsWhere(key: String, equals value: Any, in database: FMDatabase) -> FMResultSet? { public func selectRowsWhere(key: String, equals value: Any, in database: FMDatabase) -> FMResultSet? {
return database.rs_selectRowsWhereKey(key, equalsValue: value, tableName: self.name) return database.rs_selectRowsWhereKey(key, equalsValue: value, tableName: self.name)
} }
public func deleteRowsWhere(key: String, equalsAnyValue values: [Any], in database: FMDatabase) {
if values.isEmpty {
return
}
database.rs_deleteRowsWhereKey(key, inValues: values, tableName: name)
}
} }

View File

@ -488,6 +488,8 @@
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.0;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = ""; VERSION_INFO_PREFIX = "";
}; };
@ -529,6 +531,8 @@
MACOSX_DEPLOYMENT_TARGET = 10.11; MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.0;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = ""; VERSION_INFO_PREFIX = "";
}; };
@ -551,7 +555,6 @@
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
}; };
name = Debug; name = Debug;
}; };
@ -571,7 +574,6 @@
PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.RSDatabase; PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.RSDatabase;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
}; };
name = Release; name = Release;
}; };