support compound indexes and unique constraints on CoreStore properties

This commit is contained in:
John Rommel Estropia
2018-03-17 23:56:42 +09:00
parent 0c29e07ddb
commit 7b1075b759
9 changed files with 159 additions and 105 deletions

View File

@@ -57,7 +57,7 @@ import ObjectiveC
- SeeAlso: CoreStoreSchema
- SeeAlso: CoreStoreObject
*/
public final class Entity<O: DynamicObject>: DynamicEntity {
public final class Entity<O: CoreStoreObject>: DynamicEntity {
/**
Initializes an `Entity`. Always provide a concrete generic type to `Entity`.
@@ -66,11 +66,20 @@ public final class Entity<O: DynamicObject>: DynamicEntity {
```
- parameter entityName: the `NSEntityDescription` name to use for the entity
- parameter isAbstract: set to `true` if the entity is meant to be an abstract class and can only be initialized with subclass types.
- parameter versionHashModifier: The version hash modifier for the entity. Used to mark or denote an entity as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where, for example, the structure of an entity is unchanged but the format or content of data has changed.)
- parameter versionHashModifier: the version hash modifier for the entity. Used to mark or denote an entity as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where, for example, the structure of an entity is unchanged but the format or content of data has changed.)
- parameter indexes: the compound indexes for the entity as an array of arrays. The arrays contained in the returned array contain `KeyPath`s to properties of the entity.
- parameter uniqueConstraints: sets uniqueness constraints for the entity. A uniqueness constraint is a set of one or more `KeyPath`s whose value must be unique over the set of instances of that entity. This value forms part of the entity's version hash. Uniqueness constraint violations can be computationally expensive to handle. It is highly suggested that there be only one uniqueness constraint per entity hierarchy. Uniqueness constraints must be defined at the highest level possible, and CoreStore will raise an assertion failure if unique constraints are added to a sub entity.
*/
public convenience init(_ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil) {
public convenience init(_ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = [], uniqueConstraints: [[PartialKeyPath<O>]] = []) {
self.init(O.self, entityName, isAbstract: isAbstract, versionHashModifier: versionHashModifier)
self.init(
O.self,
entityName,
isAbstract: isAbstract,
versionHashModifier: versionHashModifier,
indexes: indexes,
uniqueConstraints: uniqueConstraints
)
}
/**
@@ -81,11 +90,28 @@ public final class Entity<O: DynamicObject>: DynamicEntity {
- parameter type: the `DynamicObject` type associated with the entity
- parameter entityName: the `NSEntityDescription` name to use for the entity
- parameter isAbstract: set to `true` if the entity is meant to be an abstract class and can only be initialized with subclass types.
- parameter versionHashModifier: The version hash modifier for the entity. Used to mark or denote an entity as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where, for example, the structure of an entity is unchanged but the format or content of data has changed.)
- parameter versionHashModifier: the version hash modifier for the entity. Used to mark or denote an entity as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where, for example, the structure of an entity is unchanged but the format or content of data has changed.)
- parameter indexes: the compound indexes for the entity as an array of arrays. The arrays contained in the returned array contain KeyPath's to properties of the entity.
- parameter uniqueConstraints: sets uniqueness constraints for the entity. A uniqueness constraint is a set of one or more `KeyPath`s whose value must be unique over the set of instances of that entity. This value forms part of the entity's version hash. Uniqueness constraint violations can be computationally expensive to handle. It is highly suggested that there be only one uniqueness constraint per entity hierarchy. Uniqueness constraints must be defined at the highest level possible, and CoreStore will raise an assertion failure if unique constraints are added to a sub entity.
*/
public init(_ type: O.Type, _ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil) {
public init(_ type: O.Type, _ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = [], uniqueConstraints: [[PartialKeyPath<O>]] = []) {
super.init(type: type, entityName: entityName, isAbstract: isAbstract, versionHashModifier: versionHashModifier)
let meta = O.meta
let toStringArray: ([PartialKeyPath<O>]) -> [KeyPathString] = {
return $0.map {
return (meta[keyPath: $0] as! AnyDynamicKeyPath).cs_keyPathString
}
}
super.init(
type: type,
entityName: entityName,
isAbstract: isAbstract,
versionHashModifier: versionHashModifier,
indexes: indexes.map(toStringArray),
uniqueConstraints: uniqueConstraints.map(toStringArray)
)
}
}
@@ -117,6 +143,16 @@ public /*abstract*/ class DynamicEntity: Hashable {
*/
public let versionHashModifier: String?
/**
Do not use directly.
*/
public let indexes: [[KeyPathString]]
/**
Do not use directly.
*/
public let uniqueConstraints: [[KeyPathString]]
// MARK: Equatable
@@ -126,6 +162,8 @@ public /*abstract*/ class DynamicEntity: Hashable {
&& lhs.entityName == rhs.entityName
&& lhs.isAbstract == rhs.isAbstract
&& lhs.versionHashModifier == rhs.versionHashModifier
&& lhs.indexes == rhs.indexes
&& lhs.uniqueConstraints == rhs.uniqueConstraints
}
// MARK: Hashable
@@ -136,16 +174,20 @@ public /*abstract*/ class DynamicEntity: Hashable {
^ self.entityName.hashValue
^ self.isAbstract.hashValue
^ (self.versionHashModifier ?? "").hashValue
// ^ self.indexes.hashValue
// ^ self.uniqueConstraints.hashValue
}
// MARK: Internal
internal init(type: DynamicObject.Type, entityName: String, isAbstract: Bool = false, versionHashModifier: String?) {
internal init(type: DynamicObject.Type, entityName: String, isAbstract: Bool, versionHashModifier: String?, indexes: [[KeyPathString]], uniqueConstraints: [[KeyPathString]]) {
self.type = type
self.entityName = entityName
self.isAbstract = isAbstract
self.versionHashModifier = versionHashModifier
self.indexes = indexes
self.uniqueConstraints = uniqueConstraints
}
}