Move fetchObjectsWithIDs from AttachmentsTable to default protocol implementation since AuthorsTable needs the exact same thing.

This commit is contained in:
Brent Simmons 2017-09-12 21:47:04 -07:00
parent 9341515926
commit 8f12df8f5b
6 changed files with 87 additions and 49 deletions

View File

@ -14,7 +14,7 @@ final class AttachmentsTable: DatabaseRelatedObjectsTable {
let name: String
let databaseIDKey = DatabaseKey.attachmentID
var cache = [String: Attachment]()
var cache = DatabaseObjectCache()
init(name: String) {
@ -23,39 +23,6 @@ final class AttachmentsTable: DatabaseRelatedObjectsTable {
// MARK: DatabaseRelatedObjectsTable
func fetchObjectsWithIDs(_ databaseIDs: Set<String>, in database: FMDatabase) -> [DatabaseObject]? {
if databaseIDs.isEmpty {
return nil
}
var cachedAttachments = Set<Attachment>()
var databaseIDsToFetch = Set<String>()
for attachmentID in databaseIDs {
if let cachedAttachment = cache[attachmentID] {
cachedAttachments.insert(cachedAttachment)
}
else {
databaseIDsToFetch.insert(attachmentID)
}
}
if databaseIDsToFetch.isEmpty {
return cachedAttachments.databaseObjects()
}
guard let resultSet = selectRowsWhere(key: databaseIDKey, inValues: Array(databaseIDsToFetch), in: database) else {
return cachedAttachments.databaseObjects()
}
let fetchedDatabaseObjects = objectsWithResultSet(resultSet)
let fetchedAttachments = Set(fetchedDatabaseObjects.map { $0 as Attachment })
cacheAttachments(fetchedAttachments)
let allAttachments = cachedAttachments.union(fetchedAttachments)
return allAttachments.databaseObjects()
}
func objectWithRow(_ row: FMResultSet) -> DatabaseObject? {
if let attachment = attachmentWithRow(row) {
@ -76,7 +43,7 @@ final class AttachmentsTable: DatabaseRelatedObjectsTable {
return true
})
cacheAttachments(attachmentsToSave)
cache.add(attachmentsToSave.databaseObjects())
insertRows(attachmentsToSave.databaseDictionaries(), insertType: .orIgnore, in: database)
}
@ -84,13 +51,6 @@ final class AttachmentsTable: DatabaseRelatedObjectsTable {
private extension AttachmentsTable {
func cacheAttachments(_ attachments: Set<Attachment>) {
for attachment in attachments {
cache[attachment.attachmentID] = attachment
}
}
func attachmentWithRow(_ row: FMResultSet) -> Attachment? {
// attachmentID is non-null in database schema.

View File

@ -21,14 +21,15 @@ final class AuthorsTable: DatabaseRelatedObjectsTable {
let name: String
let databaseIDKey = DatabaseKey.authorID
var cache = [String: Author]()
init(name: String) {
self.name = name
}
// MARK: DatabaseTable Methods
// MARK: DatabaseRelatedObjectsTable
func objectWithRow(_ row: FMResultSet) -> DatabaseObject? {
if let author = Author.authorWithRow(row) {
@ -38,7 +39,20 @@ final class AuthorsTable: DatabaseRelatedObjectsTable {
}
func save(_ objects: [DatabaseObject], in database: FMDatabase) {
// TODO
}
let attachments = objects.map { $0 as! Author }
// Authors in cache must already exist in database. Filter them out.
let authorsToSave = Set(attachments.filter { (attachment) -> Bool in
if let _ = cache[attachment.attachmentID] {
return false
}
return true
})
cacheAttachments(attachmentsToSave)
insertRows(attachmentsToSave.databaseDictionaries(), insertType: .orIgnore, in: database)
}
}

View File

@ -21,6 +21,8 @@ final class TagsTable: DatabaseRelatedObjectsTable {
let name: String
let databaseIDKey = DatabaseKey.tagName
let cache = DatabaseObjectCache() // Unused, but protocol requires it
init(name: String) {
self.name = name

View File

@ -25,6 +25,7 @@
8400AC101E0CFD6B00AA7C57 /* RSDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F22C581B52E0D9000060CE /* RSDatabase.h */; settings = {ATTRIBUTES = (Public, ); }; };
840405DB1F1C158C00DF0296 /* DatabaseTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840405DA1F1C158C00DF0296 /* DatabaseTable.swift */; };
840405DC1F1C15EA00DF0296 /* DatabaseTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840405DA1F1C158C00DF0296 /* DatabaseTable.swift */; };
84314F4A1F68ECC600F710B2 /* DatabaseObjectCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84314F491F68ECC600F710B2 /* DatabaseObjectCache.swift */; };
84419AD61B5ABD6D00C26BB2 /* FMDatabase+RSExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 84419AD41B5ABD6D00C26BB2 /* FMDatabase+RSExtras.h */; settings = {ATTRIBUTES = (Public, ); }; };
84419AD71B5ABD6D00C26BB2 /* FMDatabase+RSExtras.m in Sources */ = {isa = PBXBuildFile; fileRef = 84419AD51B5ABD6D00C26BB2 /* FMDatabase+RSExtras.m */; };
84419ADA1B5ABD7400C26BB2 /* NSString+RSDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = 84419AD81B5ABD7400C26BB2 /* NSString+RSDatabase.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -67,6 +68,7 @@
8400ABFA1E0CFBD800AA7C57 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
8400AC0E1E0CFC5600AA7C57 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk/usr/lib/libsqlite3.tbd; sourceTree = DEVELOPER_DIR; };
840405DA1F1C158C00DF0296 /* DatabaseTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseTable.swift; sourceTree = "<group>"; };
84314F491F68ECC600F710B2 /* DatabaseObjectCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DatabaseObjectCache.swift; path = RSDatabase/DatabaseObjectCache.swift; sourceTree = "<group>"; };
84419AD41B5ABD6D00C26BB2 /* FMDatabase+RSExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "FMDatabase+RSExtras.h"; path = "RSDatabase/FMDatabase+RSExtras.h"; sourceTree = "<group>"; };
84419AD51B5ABD6D00C26BB2 /* FMDatabase+RSExtras.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "FMDatabase+RSExtras.m"; path = "RSDatabase/FMDatabase+RSExtras.m"; sourceTree = "<group>"; };
84419AD81B5ABD7400C26BB2 /* NSString+RSDatabase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSString+RSDatabase.h"; path = "RSDatabase/NSString+RSDatabase.h"; sourceTree = "<group>"; };
@ -178,6 +180,7 @@
84419AD91B5ABD7400C26BB2 /* NSString+RSDatabase.m */,
84C6DD001F395C13009AFB47 /* DatabaseObject.swift */,
840405DA1F1C158C00DF0296 /* DatabaseTable.swift */,
84314F491F68ECC600F710B2 /* DatabaseObjectCache.swift */,
848E22531F66528C0031D7C5 /* Related Objects */,
84DDF18A1C94FC45005E6CF5 /* FMDB */,
84F22C5A1B52E0D9000060CE /* Info.plist */,
@ -389,6 +392,7 @@
files = (
84419AE71B5ABD7F00C26BB2 /* RSDatabaseQueue.m in Sources */,
84419AD71B5ABD6D00C26BB2 /* FMDatabase+RSExtras.m in Sources */,
84314F4A1F68ECC600F710B2 /* DatabaseObjectCache.swift in Sources */,
84C6DD011F395C13009AFB47 /* DatabaseObject.swift in Sources */,
84419ADB1B5ABD7400C26BB2 /* NSString+RSDatabase.m in Sources */,
840405DB1F1C158C00DF0296 /* DatabaseTable.swift in Sources */,

View File

@ -0,0 +1,33 @@
//
// DatabaseObjectCache.swift
// RSDatabase
//
// Created by Brent Simmons on 9/12/17.
// Copyright © 2017 Ranchero Software, LLC. All rights reserved.
//
import Foundation
public final class DatabaseObjectCache {
private var d = [String: DatabaseObject]()
public init() {
//
}
public func add(_ databaseObjects: [DatabaseObject]) {
for databaseObject in databaseObjects {
self[databaseObject.databaseID] = databaseObject
}
}
public subscript(_ databaseID: String) -> DatabaseObject? {
get {
return d[databaseID]
}
set {
d[databaseID] = newValue
}
}
}

View File

@ -13,7 +13,8 @@ import Foundation
public protocol DatabaseRelatedObjectsTable: DatabaseTable {
var databaseIDKey: String { get}
var cache: DatabaseObjectCache { get }
func fetchObjectsWithIDs(_ databaseIDs: Set<String>, in database: FMDatabase) -> [DatabaseObject]?
func objectsWithResultSet(_ resultSet: FMResultSet) -> [DatabaseObject]
func objectWithRow(_ row: FMResultSet) -> DatabaseObject?
@ -27,10 +28,34 @@ public extension DatabaseRelatedObjectsTable {
func fetchObjectsWithIDs(_ databaseIDs: Set<String>, in database: FMDatabase) -> [DatabaseObject]? {
guard let resultSet = selectRowsWhere(key: databaseIDKey, inValues: Array(databaseIDs), in: database) else {
if databaseIDs.isEmpty {
return nil
}
return objectsWithResultSet(resultSet)
var cachedObjects = [DatabaseObject]()
var databaseIDsToFetch = Set<String>()
for databaseID in databaseIDs {
if let cachedObject = cache[databaseID] {
cachedObjects += [cachedObject]
}
else {
databaseIDsToFetch.insert(databaseID)
}
}
if databaseIDsToFetch.isEmpty {
return cachedObjects
}
guard let resultSet = selectRowsWhere(key: databaseIDKey, inValues: Array(databaseIDsToFetch), in: database) else {
return cachedObjects
}
let fetchedDatabaseObjects = objectsWithResultSet(resultSet)
cache.add(fetchedDatabaseObjects)
return cachedObjects + fetchedDatabaseObjects
}
func objectsWithResultSet(_ resultSet: FMResultSet) -> [DatabaseObject] {