Continue progress on relationships.
This commit is contained in:
parent
7edc76cd6e
commit
7f573c2b14
|
@ -11,11 +11,8 @@ import Foundation
|
|||
public protocol DatabaseTable {
|
||||
|
||||
var name: String {get}
|
||||
var queue: RSDatabaseQueue {get}
|
||||
|
||||
init(name: String, queue: RSDatabaseQueue)
|
||||
|
||||
func fetchObjectsWithIDs<T>(_ databaseIDs: Set<String>, _ database: FMDatabase) -> [T]
|
||||
func fetchObjectsWithIDs(_ databaseIDs: Set<String>, _ database: FMDatabase) -> [DatabaseObject]
|
||||
}
|
||||
|
||||
public extension DatabaseTable {
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
849BF8C61C94FB8E0071D1DA /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 849BF8C51C94FB8E0071D1DA /* libsqlite3.tbd */; };
|
||||
84ABC1D11F364B07000DCC55 /* LookupTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84ABC1D01F364B07000DCC55 /* LookupTable.swift */; };
|
||||
84ABC1D21F364B07000DCC55 /* LookupTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84ABC1D01F364B07000DCC55 /* LookupTable.swift */; };
|
||||
84C6DD011F395C13009AFB47 /* DatabaseObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C6DD001F395C13009AFB47 /* DatabaseObject.swift */; };
|
||||
84DDF1961C94FC45005E6CF5 /* FMDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = 84DDF18B1C94FC45005E6CF5 /* FMDatabase.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
84DDF1971C94FC45005E6CF5 /* FMDatabase.m in Sources */ = {isa = PBXBuildFile; fileRef = 84DDF18C1C94FC45005E6CF5 /* FMDatabase.m */; };
|
||||
84DDF1981C94FC45005E6CF5 /* FMDatabaseAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 84DDF18D1C94FC45005E6CF5 /* FMDatabaseAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
|
@ -74,6 +75,7 @@
|
|||
844D97401F2D32F300CEDDEA /* ObjectCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ObjectCache.swift; path = RSDatabase/ObjectCache.swift; sourceTree = "<group>"; };
|
||||
849BF8C51C94FB8E0071D1DA /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
|
||||
84ABC1D01F364B07000DCC55 /* LookupTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LookupTable.swift; path = RSDatabase/LookupTable.swift; sourceTree = "<group>"; };
|
||||
84C6DD001F395C13009AFB47 /* DatabaseObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DatabaseObject.swift; path = RSDatabase/DatabaseObject.swift; sourceTree = "<group>"; };
|
||||
84DDF18B1C94FC45005E6CF5 /* FMDatabase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FMDatabase.h; sourceTree = "<group>"; };
|
||||
84DDF18C1C94FC45005E6CF5 /* FMDatabase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FMDatabase.m; sourceTree = "<group>"; };
|
||||
84DDF18D1C94FC45005E6CF5 /* FMDatabaseAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FMDatabaseAdditions.h; sourceTree = "<group>"; };
|
||||
|
@ -159,6 +161,7 @@
|
|||
84419AD81B5ABD7400C26BB2 /* NSString+RSDatabase.h */,
|
||||
84419AD91B5ABD7400C26BB2 /* NSString+RSDatabase.m */,
|
||||
840405DA1F1C158C00DF0296 /* DatabaseTable.swift */,
|
||||
84C6DD001F395C13009AFB47 /* DatabaseObject.swift */,
|
||||
84ABC1D01F364B07000DCC55 /* LookupTable.swift */,
|
||||
844D97401F2D32F300CEDDEA /* ObjectCache.swift */,
|
||||
84DDF18A1C94FC45005E6CF5 /* FMDB */,
|
||||
|
@ -370,6 +373,7 @@
|
|||
files = (
|
||||
84419AE71B5ABD7F00C26BB2 /* RSDatabaseQueue.m in Sources */,
|
||||
84419AD71B5ABD6D00C26BB2 /* FMDatabase+RSExtras.m in Sources */,
|
||||
84C6DD011F395C13009AFB47 /* DatabaseObject.swift in Sources */,
|
||||
84419ADB1B5ABD7400C26BB2 /* NSString+RSDatabase.m in Sources */,
|
||||
840405DB1F1C158C00DF0296 /* DatabaseTable.swift in Sources */,
|
||||
84ABC1D11F364B07000DCC55 /* LookupTable.swift in Sources */,
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
//
|
||||
// DatabaseObject.swift
|
||||
// RSDatabase
|
||||
//
|
||||
// Created by Brent Simmons on 8/7/17.
|
||||
// Copyright © 2017 Ranchero Software, LLC. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public protocol DatabaseObject {
|
||||
|
||||
var databaseID: String { get }
|
||||
|
||||
func attachRelationshipWithObjects(_ objects: [DatabaseObject], name: String)
|
||||
}
|
||||
|
||||
extension Array where Element == DatabaseObject {
|
||||
|
||||
func dictionary() -> [String: DatabaseObject] {
|
||||
|
||||
var d = [String: DatabaseObject]()
|
||||
for object in self {
|
||||
d[object.databaseID] = object
|
||||
}
|
||||
return d
|
||||
}
|
||||
}
|
|
@ -17,9 +17,9 @@ import Foundation
|
|||
|
||||
public typealias LookupTableDictionary = [String: Set<LookupValue>] // key is foreignID
|
||||
|
||||
public final class LookupTable {
|
||||
public final class LookupTable: DatabaseTable {
|
||||
|
||||
let name: String
|
||||
public let name: String
|
||||
let primaryKey: String
|
||||
let foreignKey: String
|
||||
private var foreignIDsWithNoRelationship = Set<String>()
|
||||
|
@ -32,6 +32,10 @@ public final class LookupTable {
|
|||
self.foreignKey = foreignKey
|
||||
}
|
||||
|
||||
public func fetchObjectsWithIDs(_ databaseIDs: Set<String>, _ database: FMDatabase) -> [DatabaseObject] {
|
||||
|
||||
}
|
||||
|
||||
public func fetchLookupTableDictionary(_ foreignIDs: Set<String>, _ database: FMDatabase) -> LookupTableDictionary? {
|
||||
|
||||
let foreignIDsToLookup = foreignIDs.subtracting(foreignIDsWithNoRelationship)
|
||||
|
@ -64,28 +68,28 @@ public final class LookupTable {
|
|||
return lookupTableDictionary(with: lookupValues)
|
||||
}
|
||||
|
||||
public func attachRelationships<T,U>(to objects: [T], idKeyPath: KeyPath<T,String>, relatedIDKeyPath: KeyPath<U,String>, relationshipKeyPath: KeyPath<T,[U]>, table: DatabaseTable, lookupTableDictionary: LookupTableDictionary, database: FMDatabase) {
|
||||
public func attachRelationships(to objects: [DatabaseObject], table: DatabaseTable, lookupTableDictionary: LookupTableDictionary, relationshipName: String, database: FMDatabase) {
|
||||
|
||||
let primaryIDs = primaryIDsInLookupTableDictionary(lookupTableDictionary)
|
||||
if (primaryIDs.isEmpty) {
|
||||
return
|
||||
}
|
||||
|
||||
let relatedObjects: [U] = table.fetchObjectsWithIDs(primaryIDs, database)
|
||||
let relatedObjects: [DatabaseObject] = table.fetchObjectsWithIDs(primaryIDs, database)
|
||||
if relatedObjects.isEmpty {
|
||||
return
|
||||
}
|
||||
|
||||
let relatedObjectsDictionary = createRelatedObjectsDictionary(relatedObjects, idKeyPath: relatedIDKeyPath)
|
||||
let relatedObjectsDictionary = relatedObjects.dictionary()
|
||||
|
||||
for object in objects {
|
||||
let identifier = object[keyPath: idKeyPath]
|
||||
let identifier = object.databaseID
|
||||
if let lookupValues = lookupTableDictionary[identifier], !lookupValues.isEmpty {
|
||||
let primaryIDs = lookupValues.primaryIDs()
|
||||
let oneObjectRelatedObjects = primaryIDs.flatMap{ (primaryID) -> U? in
|
||||
let oneObjectRelatedObjects = primaryIDs.flatMap{ (primaryID) -> DatabaseObject? in
|
||||
return relatedObjectsDictionary[primaryID]
|
||||
}
|
||||
object[keyPath: relationshipKeyPath] = oneObjectRelatedObjects
|
||||
object.attachRelationshipWithObjects(oneObjectRelatedObjects, name: relationshipName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,18 +123,6 @@ public final class LookupTable {
|
|||
|
||||
private extension LookupTable {
|
||||
|
||||
func createRelatedObjectsDictionary<T>(_ relatedObjects: [T], idKeyPath: KeyPath<T,String>) -> [String: T] {
|
||||
|
||||
var d = [String: T]()
|
||||
|
||||
for object in relatedObjects {
|
||||
let identifier = object[keyPath: idKeyPath]
|
||||
d[identifier] = object
|
||||
}
|
||||
|
||||
return d
|
||||
}
|
||||
|
||||
func addToLookupTableDictionary(_ lookupValues: Set<LookupValue>, _ table: inout LookupTableDictionary) {
|
||||
|
||||
for lookupValue in lookupValues {
|
||||
|
@ -174,16 +166,17 @@ private extension LookupTable {
|
|||
return resultSet.mapToSet(lookupValueWithRow)
|
||||
}
|
||||
|
||||
func lookupValueWithRow(_ resultSet: FMResultSet) -> LookupValue? {
|
||||
func lookupValueWithRow(_ row: FMResultSet) -> LookupValue? {
|
||||
|
||||
guard let primaryID = resultSet.string(forColumn: primaryKey) else {
|
||||
guard let primaryID = row.string(forColumn: primaryKey) else {
|
||||
return nil
|
||||
}
|
||||
guard let foreignID = resultSet.string(forColumn: foreignKey) else {
|
||||
guard let foreignID = row.string(forColumn: foreignKey) else {
|
||||
return nil
|
||||
}
|
||||
return LookupValue(primaryID: primaryID, foreignID: foreignID)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public struct LookupValue: Hashable {
|
||||
|
|
Loading…
Reference in New Issue