Fix Lint issues.

This commit is contained in:
Brent Simmons 2025-01-22 22:06:36 -08:00
parent cbea8acd9a
commit aea89148ff
8 changed files with 91 additions and 98 deletions

View File

@ -13,7 +13,7 @@ let package = Package(
.library(
name: "RSDatabaseObjC",
type: .dynamic,
targets: ["RSDatabaseObjC"]),
targets: ["RSDatabaseObjC"])
],
dependencies: [
],
@ -29,6 +29,6 @@ let package = Package(
),
.testTarget(
name: "RSDatabaseTests",
dependencies: ["RSDatabase"]),
dependencies: ["RSDatabase"])
]
)

View File

@ -20,9 +20,9 @@ public protocol DatabaseObject {
}
public extension DatabaseObject {
func relatedObjectsWithName(_ name: String) -> [DatabaseObject]? {
return nil
}
}
@ -37,14 +37,14 @@ extension Array where Element == DatabaseObject {
}
return d
}
func databaseIDs() -> Set<String> {
return Set(self.map { $0.databaseID })
}
func includesObjectWithDatabaseID(_ databaseID: String) -> Bool {
for object in self {
if object.databaseID == databaseID {
return true
@ -55,7 +55,7 @@ extension Array where Element == DatabaseObject {
func databaseDictionaries() -> [DatabaseDictionary]? {
let dictionaries = self.compactMap{ $0.databaseDictionary() }
let dictionaries = self.compactMap { $0.databaseDictionary() }
return dictionaries.isEmpty ? nil : dictionaries
}
}

View File

@ -152,7 +152,7 @@ public final class DatabaseQueue {
/// Use this to create tables, indexes, etc.
public func runCreateStatements(_ statements: String) throws {
precondition(Thread.isMainThread)
var error: DatabaseError? = nil
var error: DatabaseError?
runInDatabaseSync { result in
switch result {
case .success(let database):
@ -236,8 +236,7 @@ private extension DatabaseQueue {
autoreleasepool {
if _isSuspended {
databaseBlock(.failure(.isSuspended))
}
else {
} else {
if useTransaction {
database.beginTransaction()
}
@ -256,4 +255,3 @@ private extension DatabaseQueue {
database.setShouldCacheStatements(true)
}
}

View File

@ -15,11 +15,11 @@ public protocol DatabaseTable {
}
public extension DatabaseTable {
// MARK: Fetching
func selectRowsWhere(key: String, equals value: Any, in database: FMDatabase) -> FMResultSet? {
return database.rs_selectRowsWhereKey(key, equalsValue: value, tableName: name)
}
@ -39,7 +39,7 @@ public extension DatabaseTable {
// MARK: Deleting
func deleteRowsWhere(key: String, equalsAnyValue values: [Any], in database: FMDatabase) {
if values.isEmpty {
return
}
@ -49,21 +49,21 @@ public extension DatabaseTable {
// MARK: Updating
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)
_ = database.rs_updateRows(withValue: value, valueKey: valueKey, whereKey: whereKey, inValues: matches, tableName: self.name)
}
func updateRowsWithDictionary(_ dictionary: DatabaseDictionary, whereKey: String, matches: Any, database: FMDatabase) {
let _ = database.rs_updateRows(with: dictionary, whereKey: whereKey, equalsValue: matches, tableName: self.name)
_ = database.rs_updateRows(with: dictionary, whereKey: whereKey, equalsValue: matches, tableName: self.name)
}
// MARK: Saving
func insertRows(_ dictionaries: [DatabaseDictionary], insertType: RSDatabaseInsertType, in database: FMDatabase) {
for oneDictionary in dictionaries {
let _ = database.rs_insertRow(with: oneDictionary, insertType: insertType, tableName: self.name)
_ = database.rs_insertRow(with: oneDictionary, insertType: insertType, tableName: self.name)
}
}
@ -136,4 +136,3 @@ public extension FMResultSet {
return Set(compactMap(completion))
}
}

View File

@ -21,7 +21,7 @@ public final class DatabaseLookupTable {
private let relationshipName: String
private let relatedTable: DatabaseRelatedObjectsTable
private var objectIDsWithNoRelatedObjects = Set<String>()
public init(name: String, objectIDKey: String, relatedObjectIDKey: String, relatedTable: DatabaseRelatedObjectsTable, relationshipName: String) {
self.name = name
@ -32,47 +32,46 @@ public final class DatabaseLookupTable {
}
public func fetchRelatedObjects(for objectIDs: Set<String>, in database: FMDatabase) -> RelatedObjectsMap? {
let objectIDsThatMayHaveRelatedObjects = objectIDs.subtracting(objectIDsWithNoRelatedObjects)
if objectIDsThatMayHaveRelatedObjects.isEmpty {
return nil
}
guard let relatedObjectIDsMap = fetchRelatedObjectIDsMap(objectIDsThatMayHaveRelatedObjects, database) else {
objectIDsWithNoRelatedObjects.formUnion(objectIDsThatMayHaveRelatedObjects)
return nil
}
if let relatedObjects = fetchRelatedObjectsWithIDs(relatedObjectIDsMap.relatedObjectIDs(), database) {
let relatedObjectsMap = RelatedObjectsMap(relatedObjects: relatedObjects, relatedObjectIDsMap: relatedObjectIDsMap)
let objectIDsWithNoFetchedRelatedObjects = objectIDsThatMayHaveRelatedObjects.subtracting(relatedObjectsMap.objectIDs())
objectIDsWithNoRelatedObjects.formUnion(objectIDsWithNoFetchedRelatedObjects)
return relatedObjectsMap
}
return nil
}
public func saveRelatedObjects(for objects: [DatabaseObject], in database: FMDatabase) {
var objectsWithNoRelationships = [DatabaseObject]()
var objectsWithRelationships = [DatabaseObject]()
for object in objects {
if let relatedObjects = object.relatedObjectsWithName(relationshipName), !relatedObjects.isEmpty {
objectsWithRelationships += [object]
}
else {
} else {
objectsWithNoRelationships += [object]
}
}
removeRelationships(for: objectsWithNoRelationships, database)
updateRelationships(for: objectsWithRelationships, database)
objectIDsWithNoRelatedObjects.formUnion(objectsWithNoRelationships.databaseIDs())
objectIDsWithNoRelatedObjects.subtract(objectsWithRelationships.databaseIDs())
}
@ -83,7 +82,7 @@ public final class DatabaseLookupTable {
private extension DatabaseLookupTable {
// MARK: Removing
func removeRelationships(for objects: [DatabaseObject], _ database: FMDatabase) {
let objectIDs = objects.databaseIDs()
@ -91,52 +90,52 @@ private extension DatabaseLookupTable {
if objectIDsToRemove.isEmpty {
return
}
database.rs_deleteRowsWhereKey(objectIDKey, inValues: Array(objectIDsToRemove), tableName: name)
}
func deleteLookups(for objectID: String, _ relatedObjectIDs: Set<String>, _ database: FMDatabase) {
guard !relatedObjectIDs.isEmpty else {
assertionFailure("deleteLookups: expected non-empty relatedObjectIDs")
return
}
// delete from authorLookup where articleID=? and authorID in (?,?,?)
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(relatedObjectIDs.count))!
let sql = "delete from \(name) where \(objectIDKey)=? and \(relatedObjectIDKey) in \(placeholders)"
let parameters: [Any] = [objectID] + Array(relatedObjectIDs)
let _ = database.executeUpdate(sql, withArgumentsIn: parameters)
_ = database.executeUpdate(sql, withArgumentsIn: parameters)
}
// MARK: Saving/Updating
func updateRelationships(for objects: [DatabaseObject], _ database: FMDatabase) {
if objects.isEmpty {
return
}
if let lookupTable = fetchRelatedObjectIDsMap(objects.databaseIDs(), database) {
for object in objects {
syncRelatedObjectsAndLookupTable(object, lookupTable, database)
}
}
// Save the actual related objects.
let relatedObjectsToSave = uniqueArrayOfRelatedObjects(with: objects)
if relatedObjectsToSave.isEmpty {
assertionFailure("updateRelationships: expected relatedObjectsToSave would not be empty. This should be unreachable.")
return
}
relatedTable.save(relatedObjectsToSave, in: database)
}
func uniqueArrayOfRelatedObjects(with objects: [DatabaseObject]) -> [DatabaseObject] {
// Cant create a Set, because we cant make a Set<DatabaseObject>, because protocol-conforming objects cant be made Hashable or even Equatable.
// We still want the array to include only one copy of each object, but we have to do it the slow way. Instruments will tell us if this is a performance problem.
@ -154,48 +153,48 @@ private extension DatabaseLookupTable {
}
return relatedObjectsUniqueArray
}
func syncRelatedObjectsAndLookupTable(_ object: DatabaseObject, _ lookupTable: RelatedObjectIDsMap, _ database: FMDatabase) {
guard let relatedObjects = object.relatedObjectsWithName(relationshipName) else {
assertionFailure("syncRelatedObjectsAndLookupTable should be called only on objects with related objects.")
return
}
let relatedObjectIDs = relatedObjects.databaseIDs()
let lookupTableRelatedObjectIDs = lookupTable[object.databaseID] ?? Set<String>()
let relatedObjectIDsToDelete = lookupTableRelatedObjectIDs.subtracting(relatedObjectIDs)
if !relatedObjectIDsToDelete.isEmpty {
deleteLookups(for: object.databaseID, relatedObjectIDsToDelete, database)
}
let relatedObjectIDsToSave = relatedObjectIDs.subtracting(lookupTableRelatedObjectIDs)
if !relatedObjectIDsToSave.isEmpty {
saveLookups(for: object.databaseID, relatedObjectIDsToSave, database)
}
}
func saveLookups(for objectID: String, _ relatedObjectIDs: Set<String>, _ database: FMDatabase) {
for relatedObjectID in relatedObjectIDs {
let d: [NSObject: Any] = [(objectIDKey as NSString): objectID, (relatedObjectIDKey as NSString): relatedObjectID]
let _ = database.rs_insertRow(with: d, insertType: .orIgnore, tableName: name)
_ = database.rs_insertRow(with: d, insertType: .orIgnore, tableName: name)
}
}
// MARK: Fetching
func fetchRelatedObjectsWithIDs(_ relatedObjectIDs: Set<String>, _ database: FMDatabase) -> [DatabaseObject]? {
guard let relatedObjects = relatedTable.fetchObjectsWithIDs(relatedObjectIDs, in: database), !relatedObjects.isEmpty else {
return nil
}
return relatedObjects
}
func fetchRelatedObjectIDsMap(_ objectIDs: Set<String>, _ database: FMDatabase) -> RelatedObjectIDsMap? {
guard let lookupValues = fetchLookupValues(objectIDs, database) else {
return nil
}
@ -203,20 +202,20 @@ private extension DatabaseLookupTable {
}
func fetchLookupValues(_ objectIDs: Set<String>, _ database: FMDatabase) -> Set<LookupValue>? {
guard !objectIDs.isEmpty, let resultSet = database.rs_selectRowsWhereKey(objectIDKey, inValues: Array(objectIDs), tableName: name) else {
return nil
}
return lookupValuesWithResultSet(resultSet)
}
func lookupValuesWithResultSet(_ resultSet: FMResultSet) -> Set<LookupValue> {
return resultSet.mapToSet(lookupValueWithRow)
}
func lookupValueWithRow(_ row: FMResultSet) -> LookupValue? {
guard let objectID = row.string(forColumn: objectIDKey) else {
return nil
}
@ -226,4 +225,3 @@ private extension DatabaseLookupTable {
return LookupValue(objectID: objectID, relatedObjectID: relatedObjectID)
}
}

View File

@ -15,7 +15,7 @@ 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?
@ -39,8 +39,7 @@ public extension DatabaseRelatedObjectsTable {
for databaseID in databaseIDs {
if let cachedObject = cache[databaseID] {
cachedObjects += [cachedObject]
}
else {
} else {
databaseIDsToFetch.insert(databaseID)
}
}

View File

@ -11,46 +11,45 @@ import Foundation
// Maps objectIDs to Set<String> where the Strings are relatedObjectIDs.
struct RelatedObjectIDsMap {
private let dictionary: [String: Set<String>] // objectID: Set<relatedObjectID>
init(dictionary: [String: Set<String>]) {
self.dictionary = dictionary
}
init(lookupValues: Set<LookupValue>) {
var d = [String: Set<String>]()
for lookupValue in lookupValues {
let objectID = lookupValue.objectID
let relatedObjectID: String = lookupValue.relatedObjectID
if d[objectID] == nil {
d[objectID] = Set([relatedObjectID])
}
else {
} else {
d[objectID]!.insert(relatedObjectID)
}
}
self.init(dictionary: d)
}
func objectIDs() -> Set<String> {
return Set(dictionary.keys)
}
func relatedObjectIDs() -> Set<String> {
var ids = Set<String>()
for (_, relatedObjectIDs) in dictionary {
ids.formUnion(relatedObjectIDs)
}
return ids
}
subscript(_ objectID: String) -> Set<String>? {
return dictionary[objectID]
}

View File

@ -12,32 +12,32 @@ import Foundation
// Its used as the return value for DatabaseLookupTable.fetchRelatedObjects.
public struct RelatedObjectsMap {
private let dictionary: [String: [DatabaseObject]] // objectID: relatedObjects
init(relatedObjects: [DatabaseObject], relatedObjectIDsMap: RelatedObjectIDsMap) {
var d = [String: [DatabaseObject]]()
let relatedObjectsDictionary = relatedObjects.dictionary()
for objectID in relatedObjectIDsMap.objectIDs() {
if let relatedObjectIDs = relatedObjectIDsMap[objectID] {
let relatedObjects = relatedObjectIDs.compactMap{ relatedObjectsDictionary[$0] }
let relatedObjects = relatedObjectIDs.compactMap { relatedObjectsDictionary[$0] }
if !relatedObjects.isEmpty {
d[objectID] = relatedObjects
}
}
}
self.dictionary = d
}
public func objectIDs() -> Set<String> {
return Set(dictionary.keys)
}
public subscript(_ objectID: String) -> [DatabaseObject]? {
return dictionary[objectID]
}