From 213b1d7a6fae944c632ba8492afc3c1ad63e7ee8 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 20 Aug 2017 16:03:09 -0700 Subject: [PATCH] =?UTF-8?q?Turn=20ObjectCache=20into=20DatabaseObjectCache?= =?UTF-8?q?=20=E2=80=94=C2=A0rather=20than=20a=20generic=20with=20a=20keyp?= =?UTF-8?q?ath,=20it=20works=20with=20DatabaseObject,=20which=20has=20a=20?= =?UTF-8?q?known=20databaseID=20property.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RSDatabase.xcodeproj/project.pbxproj | 8 +- .../RSDatabase/DatabaseLookupTable.swift | 3 +- .../RSDatabase/DatabaseObjectCache.swift | 81 ++++++++++++++ .../RSDatabase/RSDatabase/ObjectCache.swift | 100 ------------------ 4 files changed, 87 insertions(+), 105 deletions(-) create mode 100644 Frameworks/RSDatabase/RSDatabase/DatabaseObjectCache.swift delete mode 100644 Frameworks/RSDatabase/RSDatabase/ObjectCache.swift diff --git a/Frameworks/RSDatabase/RSDatabase.xcodeproj/project.pbxproj b/Frameworks/RSDatabase/RSDatabase.xcodeproj/project.pbxproj index e966cfd2c..335014e97 100755 --- a/Frameworks/RSDatabase/RSDatabase.xcodeproj/project.pbxproj +++ b/Frameworks/RSDatabase/RSDatabase.xcodeproj/project.pbxproj @@ -33,7 +33,7 @@ 84419AE71B5ABD7F00C26BB2 /* RSDatabaseQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 84419ADD1B5ABD7F00C26BB2 /* RSDatabaseQueue.m */; }; 84419B051B5ABFF700C26BB2 /* FMResultSet+RSExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 84419B031B5ABFF700C26BB2 /* FMResultSet+RSExtras.h */; settings = {ATTRIBUTES = (Public, ); }; }; 84419B061B5ABFF700C26BB2 /* FMResultSet+RSExtras.m in Sources */ = {isa = PBXBuildFile; fileRef = 84419B041B5ABFF700C26BB2 /* FMResultSet+RSExtras.m */; }; - 844D97411F2D32F300CEDDEA /* ObjectCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844D97401F2D32F300CEDDEA /* ObjectCache.swift */; }; + 844D97411F2D32F300CEDDEA /* DatabaseObjectCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844D97401F2D32F300CEDDEA /* DatabaseObjectCache.swift */; }; 849BF8C61C94FB8E0071D1DA /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 849BF8C51C94FB8E0071D1DA /* libsqlite3.tbd */; }; 84ABC1D11F364B07000DCC55 /* DatabaseLookupTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84ABC1D01F364B07000DCC55 /* DatabaseLookupTable.swift */; }; 84ABC1D21F364B07000DCC55 /* DatabaseLookupTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84ABC1D01F364B07000DCC55 /* DatabaseLookupTable.swift */; }; @@ -72,7 +72,7 @@ 84419ADD1B5ABD7F00C26BB2 /* RSDatabaseQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSDatabaseQueue.m; path = RSDatabase/RSDatabaseQueue.m; sourceTree = ""; }; 84419B031B5ABFF700C26BB2 /* FMResultSet+RSExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "FMResultSet+RSExtras.h"; path = "RSDatabase/FMResultSet+RSExtras.h"; sourceTree = ""; }; 84419B041B5ABFF700C26BB2 /* FMResultSet+RSExtras.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "FMResultSet+RSExtras.m"; path = "RSDatabase/FMResultSet+RSExtras.m"; sourceTree = ""; }; - 844D97401F2D32F300CEDDEA /* ObjectCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ObjectCache.swift; path = RSDatabase/ObjectCache.swift; sourceTree = ""; }; + 844D97401F2D32F300CEDDEA /* DatabaseObjectCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DatabaseObjectCache.swift; path = RSDatabase/DatabaseObjectCache.swift; sourceTree = ""; }; 849BF8C51C94FB8E0071D1DA /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; }; 84ABC1D01F364B07000DCC55 /* DatabaseLookupTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DatabaseLookupTable.swift; path = RSDatabase/DatabaseLookupTable.swift; sourceTree = ""; }; 84C6DD001F395C13009AFB47 /* DatabaseObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DatabaseObject.swift; path = RSDatabase/DatabaseObject.swift; sourceTree = ""; }; @@ -163,7 +163,7 @@ 840405DA1F1C158C00DF0296 /* DatabaseTable.swift */, 84C6DD001F395C13009AFB47 /* DatabaseObject.swift */, 84ABC1D01F364B07000DCC55 /* DatabaseLookupTable.swift */, - 844D97401F2D32F300CEDDEA /* ObjectCache.swift */, + 844D97401F2D32F300CEDDEA /* DatabaseObjectCache.swift */, 84DDF18A1C94FC45005E6CF5 /* FMDB */, 84F22C5A1B52E0D9000060CE /* Info.plist */, 849BF8C51C94FB8E0071D1DA /* libsqlite3.tbd */, @@ -381,7 +381,7 @@ 84DDF1A01C94FC45005E6CF5 /* FMResultSet.m in Sources */, 84419B061B5ABFF700C26BB2 /* FMResultSet+RSExtras.m in Sources */, 84DDF1991C94FC45005E6CF5 /* FMDatabaseAdditions.m in Sources */, - 844D97411F2D32F300CEDDEA /* ObjectCache.swift in Sources */, + 844D97411F2D32F300CEDDEA /* DatabaseObjectCache.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Frameworks/RSDatabase/RSDatabase/DatabaseLookupTable.swift b/Frameworks/RSDatabase/RSDatabase/DatabaseLookupTable.swift index b107bf00d..2e2f920ff 100644 --- a/Frameworks/RSDatabase/RSDatabase/DatabaseLookupTable.swift +++ b/Frameworks/RSDatabase/RSDatabase/DatabaseLookupTable.swift @@ -231,7 +231,8 @@ private extension DatabaseLookupTable { func fetchRelatedObjectsWithIDs(_ relatedObjectIDs: Set, _ database: FMDatabase) -> [DatabaseObject]? { - guard let relatedObjects = relatedTable?.fetchObjectsWithIDs(relatedObjectIDs, in: database), !relatedObjects.isEmpty else { + let relatedObjects = relatedTable.fetchObjectsWithIDs(relatedObjectIDs, in: database) + if relatedObjects.isEmpty { return nil } return relatedObjects diff --git a/Frameworks/RSDatabase/RSDatabase/DatabaseObjectCache.swift b/Frameworks/RSDatabase/RSDatabase/DatabaseObjectCache.swift new file mode 100644 index 000000000..06f695cda --- /dev/null +++ b/Frameworks/RSDatabase/RSDatabase/DatabaseObjectCache.swift @@ -0,0 +1,81 @@ +// +// DatabaseObjectCache.swift +// RSDatabase +// +// Created by Brent Simmons on 7/29/17. +// Copyright © 2017 Ranchero Software, LLC. All rights reserved. +// + +import Foundation + +// Not thread-safe. + +public final class DatabaseObjectCache { + + private var dictionary = [String: DatabaseObject]() + + public func addObjects(_ objects: [DatabaseObject]) { + + objects.forEach { add($0) } + } + + public func addObjectsNotCached(_ objects: [DatabaseObject]) { + + objects.forEach { addIfNotCached($0) } + } + + public func add(_ object: DatabaseObject) { + + self[object.databaseID] = object + } + + public func addIfNotCached(_ object: DatabaseObject) { + + let identifier = object.databaseID + if let _ = self[identifier] { + return + } + self[identifier] = object + } + + public func removeObjects(_ objects: [DatabaseObject]) { + + objects.forEach { removeObject($0) } + } + + public func removeObject(_ object: DatabaseObject) { + + self[object.databaseID] = nil + } + + public func uniquedObjects(_ objects: [DatabaseObject]) -> [DatabaseObject] { + + // Return cached version of each object. + // When an object is not already cached, cache it, + // then consider that version the unique version. + + return objects.map { (object) -> DatabaseObject in + + if let cachedObject = self[object.databaseID] { + return cachedObject + } + add(object) + return object + } + } + + public func objectWithIDIsCached(_ identifier: String) -> Bool { + + return self[identifier] != nil + } + + public subscript(_ identifier: String) -> DatabaseObject? { + get { + return dictionary[identifier] + } + set { + dictionary[identifier] = newValue + } + } +} + diff --git a/Frameworks/RSDatabase/RSDatabase/ObjectCache.swift b/Frameworks/RSDatabase/RSDatabase/ObjectCache.swift deleted file mode 100644 index fdf4565a4..000000000 --- a/Frameworks/RSDatabase/RSDatabase/ObjectCache.swift +++ /dev/null @@ -1,100 +0,0 @@ -// -// ObjectCache.swift -// RSDatabase -// -// Created by Brent Simmons on 7/29/17. -// Copyright © 2017 Ranchero Software, LLC. All rights reserved. -// - -import Foundation - -// Not thread-safe. - -public final class ObjectCache { - - private let keyPathForID: KeyPath - private var dictionary = [String: T]() - - public init(keyPathForID: KeyPath) { - - self.keyPathForID = keyPathForID - } - - public func addObjects(_ objects: [T]) { - - objects.forEach { add($0) } - } - - public func addObjectsNotCached(_ objects: [T]) { - - objects.forEach { addIfNotCached($0) } - } - - public func add(_ object: T) { - - let identifier = identifierForObject(object) - self[identifier] = object - } - - public func addIfNotCached(_ object: T) { - - let identifier = identifierForObject(object) - if let _ = self[identifier] { - return - } - self[identifier] = object - } - - public func removeObjects(_ objects: [T]) { - - objects.forEach { removeObject($0) } - } - - public func removeObject(_ object: T) { - - let identifier = identifierForObject(object) - self[identifier] = nil - } - - public func uniquedObjects(_ objects: [T]) -> [T] { - - // Return cached version of each object. - // When an object is not already cached, cache it, - // then consider that version the unique version. - - return objects.map { (object) -> T in - - let identifier = identifierForObject(object) - if let cachedObject = self[identifier] { - return cachedObject - } - add(object) - return object - } - } - - public func objectWithIDIsCached(_ identifier: String) -> Bool { - - if let _ = self[identifier] { - return true - } - return false - } - - public subscript(_ identifier: String) -> T? { - get { - return dictionary[identifier] - } - set { - dictionary[identifier] = newValue - } - } -} - -private extension ObjectCache { - - func identifierForObject(_ object: T) -> String { - - return object[keyPath: keyPathForID] - } -}