83 lines
2.1 KiB
Swift
83 lines
2.1 KiB
Swift
//
|
||
// DatabaseRelatedObjectsTable.swift
|
||
// RSDatabase
|
||
//
|
||
// Created by Brent Simmons on 9/2/17.
|
||
// Copyright © 2017 Ranchero Software, LLC. All rights reserved.
|
||
//
|
||
|
||
import Foundation
|
||
|
||
// Protocol for a database table for related objects — authors, tags, and attachments in Evergreen, for instance.
|
||
|
||
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?
|
||
|
||
func save(_ objects: [DatabaseObject], in database: FMDatabase)
|
||
}
|
||
|
||
public extension DatabaseRelatedObjectsTable {
|
||
|
||
// MARK: Default implementations
|
||
|
||
func fetchObjectsWithIDs(_ databaseIDs: Set<String>, in database: FMDatabase) -> [DatabaseObject]? {
|
||
|
||
if databaseIDs.isEmpty {
|
||
return nil
|
||
}
|
||
|
||
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] {
|
||
|
||
return resultSet.flatMap(objectWithRow)
|
||
}
|
||
|
||
func save(_ objects: [DatabaseObject], in database: FMDatabase) {
|
||
|
||
// Objects in cache must already exist in database. Filter them out.
|
||
let objectsToSave = objects.filter { (object) -> Bool in
|
||
if let _ = cache[object.databaseID] {
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
cache.add(objectsToSave)
|
||
if let databaseDictionaries = objectsToSave.databaseDictionaries() {
|
||
insertRows(databaseDictionaries, insertType: .orIgnore, in: database)
|
||
}
|
||
}
|
||
|
||
}
|