diff --git a/Classes/CoreData.swift b/Classes/CoreData.swift index 1a75b37..77c9174 100644 --- a/Classes/CoreData.swift +++ b/Classes/CoreData.swift @@ -22,6 +22,11 @@ public class CoreData { /// Default implementation, should be sufficient in most cases public static let `default` = CoreData() + /// Fallback container name, overrides bundle name globally + /// Use in multitarget apps with shared model + public static var fallbackContainerName: String? + + /// Container name let containerName: String // MARK: Initialization @@ -29,7 +34,7 @@ public class CoreData { /// Initialize CoreData with an optional NSPersistentContainer name. /// App name will be used as default if nil public init(containerName: String? = nil) { - guard let containerName = containerName ?? Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String) as? String else { + guard let containerName = containerName ?? CoreData.fallbackContainerName ?? Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String) as? String else { fatalError("CoreData container name is not set and can not be inferred") } self.containerName = containerName @@ -83,6 +88,7 @@ public class CoreData { // MARK: Private interface + /// Save context, private helper private static func save(context: NSManagedObjectContext) throws { if context.hasChanges { try context.save() diff --git a/Classes/Libs/Filter/QueryFilter.swift b/Classes/Libs/Filter/QueryFilter.swift index b889872..75d3c4f 100644 --- a/Classes/Libs/Filter/QueryFilter.swift +++ b/Classes/Libs/Filter/QueryFilter.swift @@ -37,6 +37,7 @@ public struct QueryFilter { extension QueryFilter { + /// Convert filter to predicate public func asPredicate() -> NSPredicate { if let value = value as? String { let predicate = NSPredicate(format: "\(field.name) \(type.interpretation)\(caseSensitive ? "" : "[c]") %@", value) @@ -47,6 +48,9 @@ extension QueryFilter { } else if let value = value as? LosslessStringConvertible { let predicate = NSPredicate(format: "\(field.name) \(type.interpretation) \(value)") return predicate + } else if let value = value as? Date { + let predicate = NSPredicate(format: "\(field.name) \(type.interpretation) %@", value as CVarArg) + return predicate } fatalError("Not implemented") } diff --git a/Classes/Libs/Filter/QueryFilterType.swift b/Classes/Libs/Filter/QueryFilterType.swift index 93bb90b..2e223ce 100644 --- a/Classes/Libs/Filter/QueryFilterType.swift +++ b/Classes/Libs/Filter/QueryFilterType.swift @@ -13,6 +13,7 @@ public struct QueryFilterType: Equatable { enum Storage: Equatable { case equals + case equalEquals case contains case beginsWith case endsWith @@ -27,6 +28,8 @@ public struct QueryFilterType: Equatable { public var interpretation: String { switch storage { case .equals: + return "=" + case .equalEquals: return "==" case .contains: return "CONTAINS" @@ -52,8 +55,10 @@ public struct QueryFilterType: Equatable { /// Internal storage. let storage: Storage - /// == + /// = public static var equals: QueryFilterType { return .init(storage: .equals) } + /// == + public static var equalEquals: QueryFilterType { return .init(storage: .equalEquals) } /// CONTAINS public static var contains: QueryFilterType { return .init(storage: .contains) } /// BEGINSWITH diff --git a/Classes/Libs/Filter/QueryFilterValue.swift b/Classes/Libs/Filter/QueryFilterValue.swift index f416c77..af3d7b4 100644 --- a/Classes/Libs/Filter/QueryFilterValue.swift +++ b/Classes/Libs/Filter/QueryFilterValue.swift @@ -29,35 +29,15 @@ public struct QueryFilterValue { } } -// /// Returns the `QueryData` value if it exists. -// public func data() -> [QueryData]? { -// switch storage { -// case .data(let data): return [data] -// case .array(let a): return a -// default: return nil -// } -// } - - /// Another query field. + /// Query field. public static func field(_ field: QueryField) -> QueryFilterValue { return .init(storage: .field(field)) } - -// /// A single value. -// public static func data(_ data: T) throws -> QueryFilterValue { -// return try .init(storage: .data(queryDataSerialize(data: data))) -// } -// /// A single value. -// public static func array(_ array: [T]) throws -> QueryFilterValue { -// let array = try array.map { try queryDataSerialize(data: $0) } -// return .init(storage: .array(array)) -// } - -// /// A sub query. -// public static func subquery(_ subquery: DatabaseQuery) -> QueryFilterValue { -// return .init(storage: .subquery(subquery)) -// } + /// An array of supported values + public static func array(_ array: [T]) throws -> QueryFilterValue where T: QueryDataRepresentable { + return .init(storage: .array(array)) + } /// No value. public static func none() -> QueryFilterValue { diff --git a/Classes/Protocols/QueryDataRepresentable.swift b/Classes/Protocols/QueryDataRepresentable.swift index 2945920..5ead9eb 100644 --- a/Classes/Protocols/QueryDataRepresentable.swift +++ b/Classes/Protocols/QueryDataRepresentable.swift @@ -28,6 +28,7 @@ extension QueryDataRepresentable { } +/// Internal substitute for struct NULL: ExactQueryDataRepresentable { var value: String { diff --git a/Reloaded.podspec b/Reloaded.podspec index 1f6f256..a698584 100644 --- a/Reloaded.podspec +++ b/Reloaded.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = 'Reloaded' - s.version = '1.0.0' + s.version = '1.0.1' s.summary = 'Reloaded! Swift "ORM like" abstraction layer for CoreData' s.swift_version = '4.0'