2017-07-17 04:36:38 +02:00
|
|
|
//
|
|
|
|
// DatabaseTable.swift
|
|
|
|
// RSDatabase
|
|
|
|
//
|
|
|
|
// Created by Brent Simmons on 7/16/17.
|
|
|
|
// Copyright © 2017 Ranchero Software, LLC. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
|
2017-08-21 00:56:58 +02:00
|
|
|
public protocol DatabaseTable {
|
2017-07-17 05:51:08 +02:00
|
|
|
|
2017-08-21 00:56:58 +02:00
|
|
|
var name: String { get }
|
2017-08-21 02:46:15 +02:00
|
|
|
var databaseIDKey: String { get}
|
2017-07-17 05:51:08 +02:00
|
|
|
|
2017-08-20 21:41:33 +02:00
|
|
|
func fetchObjectsWithIDs(_ databaseIDs: Set<String>, in database: FMDatabase) -> [DatabaseObject]
|
2017-08-21 02:46:15 +02:00
|
|
|
func objectsWithResultSet(_ resultSet: FMResultSet) -> [DatabaseObject]
|
|
|
|
func objectWithRow(_ row: FMResultSet) -> DatabaseObject?
|
|
|
|
|
2017-08-20 21:41:33 +02:00
|
|
|
func save(_ objects: [DatabaseObject], in database: FMDatabase)
|
2017-07-17 05:51:08 +02:00
|
|
|
}
|
2017-07-17 04:36:38 +02:00
|
|
|
|
2017-07-30 20:55:46 +02:00
|
|
|
public extension DatabaseTable {
|
2017-07-29 21:50:23 +02:00
|
|
|
|
2017-08-21 02:46:15 +02:00
|
|
|
// MARK: Default implementations
|
|
|
|
|
|
|
|
func fetchObjectsWithIDs(_ databaseIDs: Set<String>, in database: FMDatabase) -> [DatabaseObject] {
|
|
|
|
|
|
|
|
guard let resultSet = selectRowsWhere(key: databaseIDKey, inValues: Array(databaseIDs), in: database) else {
|
|
|
|
return [DatabaseObject]()
|
|
|
|
}
|
|
|
|
return objectsWithResultSet(resultSet)
|
|
|
|
}
|
|
|
|
|
|
|
|
func objectsWithResultSet(_ resultSet: FMResultSet) -> [DatabaseObject] {
|
|
|
|
|
|
|
|
return resultSet.flatMap(objectWithRow)
|
|
|
|
}
|
|
|
|
|
2017-07-29 21:50:23 +02:00
|
|
|
// MARK: Fetching
|
|
|
|
|
2017-07-17 04:36:38 +02:00
|
|
|
public func selectRowsWhere(key: String, equals value: Any, in database: FMDatabase) -> FMResultSet? {
|
2017-07-17 05:51:08 +02:00
|
|
|
|
2017-07-29 21:50:23 +02:00
|
|
|
return database.rs_selectRowsWhereKey(key, equalsValue: value, tableName: name)
|
2017-07-17 05:51:08 +02:00
|
|
|
}
|
2017-07-29 21:50:23 +02:00
|
|
|
|
2017-07-30 20:55:46 +02:00
|
|
|
public func selectRowsWhere(key: String, inValues values: [Any], in database: FMDatabase) -> FMResultSet? {
|
|
|
|
|
2017-08-06 21:37:47 +02:00
|
|
|
if values.isEmpty {
|
|
|
|
return nil
|
|
|
|
}
|
2017-07-30 20:55:46 +02:00
|
|
|
return database.rs_selectRowsWhereKey(key, inValues: values, tableName: name)
|
|
|
|
}
|
|
|
|
|
2017-07-29 21:50:23 +02:00
|
|
|
// MARK: Deleting
|
|
|
|
|
2017-07-17 05:51:08 +02:00
|
|
|
public func deleteRowsWhere(key: String, equalsAnyValue values: [Any], in database: FMDatabase) {
|
|
|
|
|
|
|
|
if values.isEmpty {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
database.rs_deleteRowsWhereKey(key, inValues: values, tableName: name)
|
|
|
|
}
|
2017-07-29 21:29:05 +02:00
|
|
|
|
2017-07-29 21:50:23 +02:00
|
|
|
// MARK: Updating
|
|
|
|
|
2017-08-29 22:32:36 +02:00
|
|
|
public func updateRowsWithValue(_ value: Any, valueKey: String, whereKey: String, matches: [Any], database: FMDatabase) {
|
|
|
|
|
|
|
|
let _ = database.rs_updateRows(withValue: value, valueKey: valueKey, whereKey: whereKey, inValues: matches, tableName: self.name)
|
|
|
|
}
|
|
|
|
|
2017-07-29 21:50:23 +02:00
|
|
|
// MARK: Saving
|
|
|
|
|
2017-08-05 20:12:45 +02:00
|
|
|
public func insertRows(_ dictionaries: [NSDictionary], insertType: RSDatabaseInsertType, in database: FMDatabase) {
|
2017-07-29 21:50:23 +02:00
|
|
|
|
2017-08-05 20:12:45 +02:00
|
|
|
dictionaries.forEach { (oneDictionary) in
|
|
|
|
let _ = database.rs_insertRow(with: oneDictionary as [NSObject: AnyObject], insertType: insertType, tableName: self.name)
|
2017-07-29 21:50:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: Counting
|
2017-07-29 21:29:05 +02:00
|
|
|
|
|
|
|
func numberWithCountResultSet(_ resultSet: FMResultSet?) -> Int {
|
|
|
|
|
|
|
|
if let resultSet = resultSet, resultSet.next() {
|
|
|
|
return Int(resultSet.int(forColumnIndex: 0))
|
|
|
|
}
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func numberWithSQLAndParameters(_ sql: String, _ parameters: [Any], in database: FMDatabase) -> Int {
|
|
|
|
|
|
|
|
let resultSet = database.executeQuery(sql, withArgumentsIn: parameters)
|
|
|
|
return numberWithCountResultSet(resultSet)
|
|
|
|
}
|
2017-08-06 21:37:47 +02:00
|
|
|
|
|
|
|
// MARK: Mapping
|
|
|
|
|
|
|
|
func mapResultSet<T>(_ resultSet: FMResultSet, _ callback: (_ resultSet: FMResultSet) -> T?) -> [T] {
|
|
|
|
|
|
|
|
var objects = [T]()
|
|
|
|
while resultSet.next() {
|
|
|
|
if let obj = callback(resultSet) {
|
|
|
|
objects += [obj]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return objects
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public extension FMResultSet {
|
|
|
|
|
|
|
|
public func flatMap<T>(_ callback: (_ row: FMResultSet) -> T?) -> [T] {
|
|
|
|
|
|
|
|
var objects = [T]()
|
|
|
|
while next() {
|
|
|
|
if let obj = callback(self) {
|
|
|
|
objects += [obj]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close()
|
|
|
|
return objects
|
|
|
|
}
|
|
|
|
|
|
|
|
public func mapToSet<T>(_ callback: (_ row: FMResultSet) -> T?) -> Set<T> {
|
|
|
|
|
|
|
|
return Set(flatMap(callback))
|
|
|
|
}
|
2017-07-17 04:36:38 +02:00
|
|
|
}
|
2017-07-29 21:29:05 +02:00
|
|
|
|