Start DatabaseLookupTableCache.
This commit is contained in:
parent
0186aeffa2
commit
2d915a890e
@ -565,7 +565,7 @@
|
||||
INFOPLIST_FILE = RSDatabase/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||
OTHER_SWIFT_FLAGS = "-Xfrontend -warn-long-function-bodies=25";
|
||||
OTHER_SWIFT_FLAGS = "-Xfrontend -warn-long-function-bodies=75";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.RSDatabase;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
@ -586,7 +586,7 @@
|
||||
INFOPLIST_FILE = RSDatabase/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||
OTHER_SWIFT_FLAGS = "-Xfrontend -warn-long-function-bodies=25";
|
||||
OTHER_SWIFT_FLAGS = "-Xfrontend -warn-long-function-bodies=75";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.RSDatabase;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
@ -19,7 +19,7 @@ public final class DatabaseLookupTable {
|
||||
private let foreignKey: String
|
||||
private let relationshipName: String
|
||||
private weak var relatedTable: DatabaseTable?
|
||||
private var foreignIDsWithNoRelationship = Set<String>()
|
||||
private let cache: DatabaseLookupTableCache
|
||||
|
||||
public init(name: String, primaryKey: String, foreignKey: String, relatedTable: DatabaseTable, relationshipName: String) {
|
||||
|
||||
@ -28,6 +28,7 @@ public final class DatabaseLookupTable {
|
||||
self.foreignKey = foreignKey
|
||||
self.relatedTable = relatedTable
|
||||
self.relationshipName = relationshipName
|
||||
self.cache = DatabaseLookupTableCache(relationshipName)
|
||||
}
|
||||
|
||||
public func attachRelationships(to objects: [DatabaseObject], database: FMDatabase) {
|
||||
@ -53,6 +54,7 @@ public final class DatabaseLookupTable {
|
||||
}
|
||||
|
||||
removeRelationships(for: objectsWithNoRelationships, database: database)
|
||||
updateRelationships(for: objectsWithRelationships, database: database)
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,6 +65,32 @@ private extension DatabaseLookupTable {
|
||||
removeLookupsForForeignIDs(objects.databaseIDs(), database)
|
||||
}
|
||||
|
||||
func updateRelationships(for objects: [DatabaseObject], database: FMDatabase) {
|
||||
|
||||
let objectsNeedingUpdate = objects.filter { (object) -> Bool in
|
||||
return !relationshipsMatchCache(object)
|
||||
}
|
||||
}
|
||||
|
||||
func relationshipsMatchCache(_ object: DatabaseObject) -> Bool {
|
||||
|
||||
let relationships = object.relatedObjectsWithName(relationshipName)
|
||||
let cachedRelationshipIDs = cache[object.databaseID]
|
||||
|
||||
if let relationships = relationships {
|
||||
if let cachedRelationshipIDs = cachedRelationshipIDs {
|
||||
return relationships.databaseIDs() == cachedRelationshipIDs
|
||||
}
|
||||
return false // cachedRelationshipIDs == nil, relationships != nil
|
||||
}
|
||||
else { // relationships == nil
|
||||
if let cachedRelationshipIDs = cachedRelationshipIDs {
|
||||
return !cachedRelationshipIDs.isEmpty
|
||||
}
|
||||
return true // both nil
|
||||
}
|
||||
}
|
||||
|
||||
func attachRelationshipsUsingLookupTable(to objects: [DatabaseObject], lookupTable: LookupTable, database: FMDatabase) {
|
||||
|
||||
let primaryIDs = lookupTable.primaryIDs()
|
||||
@ -99,6 +127,14 @@ private extension DatabaseLookupTable {
|
||||
return LookupTable(lookupValues)
|
||||
}
|
||||
|
||||
func cacheForeignIDsWithNoRelationships(_ foreignIDs: Set<String>) {
|
||||
|
||||
foreignIDsWithNoRelationship.formUnion(foreignIDs)
|
||||
for foreignID in foreignIDs {
|
||||
cache[foreignID] = nil
|
||||
}
|
||||
}
|
||||
|
||||
func updateCache(_ lookupValues: Set<LookupValue>, _ foreignIDs: Set<String>) {
|
||||
|
||||
// Maintain foreignIDsWithNoRelationship.
|
||||
@ -106,9 +142,8 @@ private extension DatabaseLookupTable {
|
||||
// If a relationship does not exist, add the foreignID to foreignIDsWithNoRelationship.
|
||||
|
||||
let foreignIDsWithRelationship = lookupValues.foreignIDs()
|
||||
|
||||
foreignIDsWithNoRelationship.subtract(foreignIDsWithRelationship)
|
||||
|
||||
|
||||
let foreignIDs
|
||||
for foreignID in foreignIDs {
|
||||
if !foreignIDsWithRelationship.contains(foreignID) {
|
||||
foreignIDsWithNoRelationship.insert(foreignID)
|
||||
@ -210,6 +245,53 @@ struct LookupValue: Hashable {
|
||||
}
|
||||
}
|
||||
|
||||
private final class DatabaseLookupTableCache {
|
||||
|
||||
private let relationshipName: String
|
||||
private var foreignIDsWithNoRelationship = Set<String>()
|
||||
private var cachedLookups = [String: Set<String>]() // foreignID: Set<primaryID>
|
||||
|
||||
init(_ relationshipName: String) {
|
||||
|
||||
self.relationshipName = relationshipName
|
||||
}
|
||||
|
||||
func updateCacheWithIDsWithNoRelationship(_ foreignIDs: Set<String>) {
|
||||
|
||||
foreignIDsWithNoRelationship.formUnion(foreignIDs)
|
||||
for foreignID in foreignIDs {
|
||||
cachedLookups[foreignID] = nil
|
||||
}
|
||||
}
|
||||
|
||||
func updateCacheWithObjects(_ object: [DatabaseObject]) {
|
||||
|
||||
var foreignIDsWithRelationship = Set<String>()
|
||||
|
||||
for object in objects {
|
||||
|
||||
if let relatedObjects = object.relatedObjectsWithName, !relatedObjects.isEmpty {
|
||||
foreignIDsWithRelationship.insert(object.databaseID)
|
||||
}
|
||||
else {
|
||||
updateCacheWithIDsWithNoRelationship(objects.databaseIDs())
|
||||
}
|
||||
}
|
||||
|
||||
foreignIDsWithNoRelationship.subtract(foreignIDsWithRelationships)
|
||||
}
|
||||
|
||||
func foreignIDHasNoRelationship(_ foreignID: String) -> Bool {
|
||||
|
||||
return foreignIDsWithNoRelationship.contains(foreignID)
|
||||
}
|
||||
|
||||
func relationshipIDsForForeignID(_ foreignID: String) -> Set<String>? {
|
||||
|
||||
return cachedLookups[foreignID]
|
||||
}
|
||||
}
|
||||
|
||||
private extension Set where Element == LookupValue {
|
||||
|
||||
func primaryIDs() -> Set<String> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user