├── docs ├── favicon.ico ├── developer-og.jpg ├── developer-og-twitter.jpg ├── img │ ├── no-image@2x.df2a0a50.png │ ├── deprecated-icon.015b4f17.svg │ ├── added-icon.d6f7e47d.svg │ └── modified-icon.f496e73d.svg ├── metadata.json ├── js │ ├── highlight-js-shell.dd7f411f.js │ ├── highlight-js-json.471128d2.js │ ├── highlight-js-diff.62d66733.js │ ├── highlight-js-http.163e45b6.js │ └── highlight-js-xml.9c3688c7.js ├── favicon.svg └── data │ └── documentation │ └── crush │ ├── userinfokey.json │ ├── entity │ ├── init().json │ ├── hashable-implementations.json │ └── readaleobject-implementations.json │ ├── entitymap │ └── init().json │ ├── relationship │ └── relationshipprotocol-implementations.json │ ├── migrationerror │ ├── error-implementations.json │ ├── notmigrated.json │ ├── incompatible.json │ └── equatable-implementations.json │ ├── coredataerror │ ├── customstringconvertible-implementations.json │ └── error-implementations.json │ ├── orderedset │ ├── init().json │ └── equatable-implementations.json │ ├── objectdriver │ ├── customdebugstringconvertible-implementations.json │ ├── hashable-implementations.json │ └── equatable-implementations.json │ ├── datacontainererror │ ├── error-implementations.json │ └── equatable-implementations.json │ ├── storage │ └── equatable-implementations.json │ ├── adhocmigrationerror │ ├── error-implementations.json │ └── equatable-implementations.json │ ├── mutableset │ ├── init().json │ └── equatable-implementations.json │ ├── entitytypedescriptor │ └── init().json │ ├── migrationmodelingerror │ └── error-implementations.json │ ├── configuration │ └── init().json │ ├── fetchsorteroption │ ├── default.json │ ├── localized.json │ ├── equatable-implementations.json │ ├── caseinsensitive.json │ └── localizedstandard.json │ ├── searchstring │ └── equatable-implementations.json │ ├── entityabstraction │ ├── concrete.json │ └── equatable-implementations.json │ ├── storageoption │ └── equatable-implementations.json │ ├── adhocmigration │ └── equatable-implementations.json │ ├── requestexecutor │ └── received.json │ ├── entityinheritance │ ├── multitable.json │ ├── singletable.json │ └── equatable-implementations.json │ ├── propertytype │ ├── managedvalue.json │ ├── runtimevalue.json │ └── predicatevalue.json │ ├── updateattribute │ ├── updatepropertymigration-implementations.json │ └── propertymigration-implementations.json │ ├── primarykey │ └── equatable-implementations.json │ ├── session │ ├── undo().json │ └── redo().json │ ├── mutableorderedset │ ├── init().json │ └── equatable-implementations.json │ ├── unsafesessionproperty │ └── safe.json │ ├── codableattributetype │ └── hashable-implementations.json │ ├── entitymigrationcallback.json │ ├── updaterelationship │ ├── updatepropertymigration-implementations.json │ └── propertymigration-implementations.json │ ├── manageddriver │ └── customdebugstringconvertible-implementations.json │ ├── migrator.json │ ├── enumerableattributetype │ └── hashable-implementations.json │ ├── modelmigration │ └── equatable-implementations.json │ ├── lazyfetchresultcollection.json │ ├── updatefetchedproperty │ └── updatepropertymigration-implementations.json │ └── selectpath │ └── path.json ├── .swiftpm └── xcode │ └── package.xcworkspace │ └── contents.xcworkspacedata ├── Sources ├── Utils │ ├── FileManager+helper.swift │ ├── NSEntityDescription+helper.swift │ ├── DispatchQueue+helper.swift │ ├── UserInfoKey.swift │ ├── Lock.swift │ ├── CollectionBuilder.swift │ ├── NSManagedObject+fetchSource.swift │ ├── Expressible.swift │ ├── Optional.swift │ ├── PersistentHash.swift │ ├── KeyPath+helper.swift │ ├── SelectPath.swift │ └── Caches.swift ├── Versioning │ ├── MigrationModelingError.swift │ ├── Migration │ │ └── AdHocMigration.swift │ ├── Migrator │ │ └── AdHocMigrator.swift │ └── MigrationChainIterator.swift ├── DataStructure │ ├── FastEnumerationIterator.swift │ ├── MapEnumerationIterator.swift │ ├── LazyMapSet.swift │ ├── LazyMapOrderedSet.swift │ └── LazyMapMutableSet.swift ├── DataModel │ └── Entity │ │ ├── Property │ │ ├── Property.swift │ │ ├── Property+Attribute.swift │ │ ├── PrimitiveAttributeType+Transformable.swift │ │ ├── CodableAttributeType.swift │ │ └── EnumerableAttributeType.swift │ │ └── PartialObject.swift ├── DataContainer │ └── DataContainer+workingDirectory.swift └── Crush.docc │ ├── Crush.md │ ├── UndoRedoInSession.md │ ├── TypesOfSessions.md │ ├── SigningSessionBlock.md │ ├── CRUDOperations.md │ ├── PropertyModifier.md │ └── IntroducingSession.md ├── Package.resolved ├── .gitignore ├── Tests ├── DataStructureTests │ ├── LazyMapMutableOrderedSetTests.swift │ ├── LazyMapSetTests.swift │ ├── LazyMapOrderedSetTests.swift │ └── LazyMapMutableSetTests.swift ├── UtilsTests │ ├── OptionalTests.swift │ └── PersistentHashTests.swift ├── QueryBuilderTests │ └── UpdateBuilderTests.swift ├── DataModelTests │ └── PartialObjectTests.swift ├── VersioningTests │ └── MigrationTests │ │ └── FethcedPropertyMigrationTests.swift ├── Measurement.swift └── Utils │ └── Publishers+helper.swift ├── LICENSE ├── Package.swift ├── README.md └── Assertions └── Assertions.swift /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ezoushen/Crush/HEAD/docs/favicon.ico -------------------------------------------------------------------------------- /docs/developer-og.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ezoushen/Crush/HEAD/docs/developer-og.jpg -------------------------------------------------------------------------------- /docs/developer-og-twitter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ezoushen/Crush/HEAD/docs/developer-og-twitter.jpg -------------------------------------------------------------------------------- /docs/img/no-image@2x.df2a0a50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ezoushen/Crush/HEAD/docs/img/no-image@2x.df2a0a50.png -------------------------------------------------------------------------------- /docs/metadata.json: -------------------------------------------------------------------------------- 1 | {"bundleDisplayName":"Crush","bundleIdentifier":"Crush","schemaVersion":{"major":0,"minor":1,"patch":0}} -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Sources/Utils/FileManager+helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FileManager+helper.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/24. 6 | // 7 | 8 | import Foundation 9 | 10 | extension FileManager { 11 | func removeItemIfExists(atPath path: String) throws { 12 | if fileExists(atPath: path) { 13 | try removeItem(atPath: path) 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Sources/Versioning/MigrationModelingError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MigrationModelingError.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/15. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum MigrationModelingError: Error { 11 | // If received this error, please file an issue 12 | case internalTypeMismatch 13 | 14 | case migrationTargetNotFound(_ message: String) 15 | 16 | case unknownMigrationType 17 | 18 | case unknownDescriptionType 19 | } 20 | -------------------------------------------------------------------------------- /Sources/Utils/NSEntityDescription+helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSEntityDescription+helper.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/24. 6 | // 7 | 8 | import CoreData 9 | import Foundation 10 | 11 | extension NSEntityDescription { 12 | var entityType: Entity.Type? { 13 | guard let entityClassName = 14 | userInfo?[UserInfoKey.entityClassName] as? String 15 | else { return nil } 16 | return NSClassFromString(entityClassName) as? Entity.Type 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Sources/Utils/DispatchQueue+helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DispatchQueue+helper.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/17. 6 | // 7 | 8 | import Foundation 9 | 10 | extension DispatchQueue { 11 | static func performMainThreadTask(_ block: @escaping () -> Void){ 12 | if Thread.isMainThread { 13 | return block() 14 | } 15 | DispatchQueue.main.async { 16 | performMainThreadTask { 17 | block() 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /docs/img/deprecated-icon.015b4f17.svg: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /Sources/DataStructure/FastEnumerationIterator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FastEnumerationIterator.swift 3 | // 4 | // 5 | // Created by ezou on 2022/2/10. 6 | // 7 | 8 | import Foundation 9 | 10 | public struct FastEnumerationIterator: IteratorProtocol { 11 | internal var iterator: NSFastEnumerationIterator 12 | 13 | internal init(_ iterator: NSFastEnumerationIterator) { 14 | self.iterator = iterator 15 | } 16 | 17 | public mutating func next() -> T? { 18 | guard let next = iterator.next() else { return nil } 19 | let result: T = next as! T 20 | return result 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Sources/DataStructure/MapEnumerationIterator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MapEnumerationIterator.swift 3 | // 4 | // 5 | // Created by EZOU on 2023/9/1. 6 | // 7 | 8 | import Foundation 9 | 10 | class MapEnumerationIterator: NSEnumerator { 11 | var iterator: NSFastEnumerationIterator 12 | let from: (T) -> U 13 | 14 | init(iterator: NSFastEnumerationIterator, from: @escaping (T) -> U) { 15 | self.iterator = iterator 16 | self.from = from 17 | } 18 | 19 | override func nextObject() -> Any? { 20 | guard let value = iterator.next() as? T else { return nil } 21 | return from(value) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Sources/Utils/UserInfoKey.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserInfoKey.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/24. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum UserInfoKey { 11 | // NSManagedObjectModel 12 | static let indexes = "Index" 13 | static let uniquenessConstraintName = "UniquenessConstraintName" 14 | 15 | // NSMappingModel 16 | static let attributeMappingFunc = "AttributeMappingFunc" 17 | static let attributeMappingFromObjectFunc = "AttributeMappingFromObjectFunc" 18 | static let defaultValueFunc = "DefaultValueFunc" 19 | 20 | // NSEntityDescription 21 | static let entityClassName = "EntityClassName" 22 | } 23 | -------------------------------------------------------------------------------- /Sources/Utils/Lock.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UnfairLock.swift 3 | // 4 | // 5 | // Created by EZOU on 2023/1/13. 6 | // 7 | 8 | import Foundation 9 | 10 | class UnfairLock { 11 | private var _lock = os_unfair_lock() 12 | 13 | func lock() { 14 | os_unfair_lock_lock(&_lock) 15 | } 16 | 17 | func unlock() { 18 | os_unfair_lock_unlock(&_lock) 19 | } 20 | 21 | func tryLock() -> Bool { 22 | os_unfair_lock_trylock(&_lock) 23 | } 24 | 25 | func assertOwner() { 26 | os_unfair_lock_assert_owner(&_lock) 27 | } 28 | 29 | func assertNotOwner() { 30 | os_unfair_lock_assert_not_owner(&_lock) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/img/added-icon.d6f7e47d.svg: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /docs/js/highlight-js-shell.dd7f411f.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * This source file is part of the Swift.org open source project 3 | * 4 | * Copyright (c) 2021 Apple Inc. and the Swift project authors 5 | * Licensed under Apache License v2.0 with Runtime Library Exception 6 | * 7 | * See https://swift.org/LICENSE.txt for license information 8 | * See https://swift.org/CONTRIBUTORS.txt for Swift project authors 9 | */ 10 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["highlight-js-shell"],{b65b:function(s,n){function e(s){return{name:"Shell Session",aliases:["console","shellsession"],contains:[{className:"meta",begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/,starts:{end:/[^\\](?=\s*$)/,subLanguage:"bash"}}]}}s.exports=e}}]); -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "SwiftDocCPlugin", 6 | "repositoryURL": "https://github.com/apple/swift-docc-plugin", 7 | "state": { 8 | "branch": null, 9 | "revision": "9b1258905c21fc1b97bf03d1b4ca12c4ec4e5fda", 10 | "version": "1.2.0" 11 | } 12 | }, 13 | { 14 | "package": "SymbolKit", 15 | "repositoryURL": "https://github.com/apple/swift-docc-symbolkit", 16 | "state": { 17 | "branch": null, 18 | "revision": "b45d1f2ed151d057b54504d653e0da5552844e34", 19 | "version": "1.0.0" 20 | } 21 | } 22 | ] 23 | }, 24 | "version": 1 25 | } 26 | -------------------------------------------------------------------------------- /Sources/Utils/CollectionBuilder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CollectionBuilder.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/16. 6 | // 7 | 8 | import Foundation 9 | 10 | @resultBuilder 11 | public struct CollectionBuilder { 12 | public static func buildBlock(_ components: T...) -> [T] { 13 | return components 14 | } 15 | } 16 | 17 | 18 | @resultBuilder 19 | public struct SetBuilder { 20 | public static func buildBlock(_ components: T...) -> Set { 21 | return Set(components) 22 | } 23 | } 24 | 25 | @resultBuilder 26 | public struct OrderedSetBuilder { 27 | public static func buildBlock(_ components: T...) -> OrderedSet { 28 | return OrderedSet(components) 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /Sources/Utils/NSManagedObject+fetchSource.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSManagedObject+FetchSource.swift 3 | // 4 | // 5 | // Created by EZOU on 2023/4/28. 6 | // 7 | 8 | import CoreData 9 | import Foundation 10 | 11 | extension NSManagedObjectID { 12 | open override func value(forUndefinedKey key: String) -> Any? { 13 | guard let fetchSource = NSManagedObject.currentFetchSource else { return nil } 14 | let value = fetchSource.value(forKey: key) 15 | return value 16 | } 17 | } 18 | 19 | extension NSManagedObject { 20 | /// This is a thread local variable. It represents the current fetch source as 21 | /// the target of `$FETCH_SOURCE` in the fetch property of a fetched property. 22 | @ThreadLocal static var currentFetchSource: NSManagedObject? = nil 23 | } 24 | -------------------------------------------------------------------------------- /Sources/DataModel/Entity/Property/Property.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Property.swift 3 | // Crush 4 | // 5 | // Created by EZOU on 2019/9/21. 6 | // Copyright © 2019 ezou. All rights reserved. 7 | // 8 | 9 | import CoreData 10 | 11 | // MARK: - Entity Property 12 | 13 | public protocol Property: AnyObject { 14 | typealias RuntimeValue = PropertyType.RuntimeValue 15 | typealias ManagedValue = PropertyType.ManagedValue 16 | typealias PredicateValue = PropertyType.PredicateValue 17 | 18 | associatedtype Description: NSPropertyDescription 19 | associatedtype PropertyType: Crush.PropertyType 20 | 21 | var name: String { get } 22 | var isAttribute: Bool { get } 23 | 24 | func createPropertyDescription() -> Description 25 | } 26 | 27 | public protocol WritableProperty: Property { } 28 | -------------------------------------------------------------------------------- /Sources/Utils/Expressible.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Expressible.swift 3 | // 4 | // 5 | // Created by EZOU on 2022/6/12. 6 | // 7 | 8 | import Foundation 9 | 10 | public protocol Expressible { 11 | func asExpression() -> Any 12 | func getHashValue() -> Int 13 | } 14 | 15 | extension Expressible { 16 | func equal(to: Expressible) -> Bool { 17 | getHashValue() == to.getHashValue() 18 | } 19 | } 20 | 21 | public struct StringExpressible: Expressible, ExpressibleByStringLiteral { 22 | let path: String 23 | 24 | public init(stringLiteral value: StringLiteralType) { 25 | path = String(value) 26 | } 27 | 28 | public func getHashValue() -> Int { 29 | path.hashValue 30 | } 31 | 32 | public func asExpression() -> Any { 33 | path 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /docs/js/highlight-js-json.471128d2.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * This source file is part of the Swift.org open source project 3 | * 4 | * Copyright (c) 2021 Apple Inc. and the Swift project authors 5 | * Licensed under Apache License v2.0 with Runtime Library Exception 6 | * 7 | * See https://swift.org/LICENSE.txt for license information 8 | * See https://swift.org/CONTRIBUTORS.txt for Swift project authors 9 | */ 10 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["highlight-js-json"],{"5ad2":function(n,e){function a(n){const e={className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/,relevance:1.01},a={match:/[{}[\],:]/,className:"punctuation",relevance:0},s={beginKeywords:["true","false","null"].join(" ")};return{name:"JSON",contains:[e,a,n.QUOTE_STRING_MODE,s,n.C_NUMBER_MODE,n.C_LINE_COMMENT_MODE,n.C_BLOCK_COMMENT_MODE],illegal:"\\S"}}n.exports=a}}]); -------------------------------------------------------------------------------- /Sources/Utils/Optional.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Optional.swift 3 | // Crush 4 | // 5 | // Created by ezou on 2020/4/18. 6 | // 7 | 8 | import Foundation 9 | 10 | public protocol OptionalProtocol { 11 | var isNil: Bool { get } 12 | static var null: Self { get } 13 | } 14 | 15 | extension Swift.Optional: OptionalProtocol { 16 | @inlinable 17 | public var isNil: Bool { 18 | switch self { 19 | case .some(let value): 20 | return (value as? OptionalProtocol)?.isNil == true 21 | default: return true 22 | } 23 | } 24 | 25 | @inlinable 26 | public static var null: Self { 27 | return .none 28 | } 29 | } 30 | 31 | extension Swift.Optional { 32 | @inlinable var contentDescription: String { 33 | switch self { 34 | case .none: return "null" 35 | case .some(let value): return "\(value)" 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | /Example-Test* 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 26 | # Carthage/Checkouts 27 | 28 | Carthage/Build 29 | 30 | # We recommend against adding the Pods directory to your .gitignore. However 31 | # you should judge for yourself, the pros and cons are mentioned at: 32 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 33 | # 34 | # Note: if you ignore the Pods directory, make sure to uncomment 35 | # `pod install` in .travis.yml 36 | # 37 | Pods/ 38 | 39 | # SPM 40 | .build/ 41 | -------------------------------------------------------------------------------- /Sources/Versioning/Migration/AdHocMigration.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AdHocMigration.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/16. 6 | // 7 | 8 | import CoreData 9 | import Foundation 10 | 11 | public enum AdHocMigrationError: Error { 12 | case sourceModelNotFound 13 | } 14 | 15 | public struct AdHocMigration: Hashable { 16 | public let sourceName: String 17 | public let migration: ModelMigration 18 | 19 | public init(_ name: String, migration: ModelMigration) { 20 | self.sourceName = name 21 | self.migration = migration 22 | } 23 | 24 | public func createMappingModel() throws -> NSMappingModel { 25 | guard let sourceModel = NSManagedObjectModel.load(name: sourceName) 26 | else { throw AdHocMigrationError.sourceModelNotFound } 27 | let destinationModel = try migration.migrateModel(sourceModel) 28 | return try migration.createMappingModel( 29 | from: sourceModel, to: destinationModel) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Sources/Utils/PersistentHash.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Hash.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/24. 6 | // 7 | 8 | import Foundation 9 | 10 | enum PersistentHash { 11 | static func ordered(_ lhs: UInt64, _ rhs: UInt64) -> UInt64 { 12 | lhs ^ (rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2)) 13 | } 14 | 15 | static func unordered(_ lhs: UInt64, _ rhs: UInt64) -> UInt64 { 16 | lhs ^ rhs 17 | } 18 | 19 | static func fromString(_ string: String) -> UInt64 { 20 | let charArray = string.utf8CString.dropLast() 21 | var hash: UInt64 = 0 22 | for i in stride(from: 0, to: charArray.count, by: 4) { 23 | var value: Int32 = 0 24 | for char in charArray[i...from(orderedSet) { 16 | "\($0)" 17 | } to: { 18 | Int($0)! 19 | } 20 | XCTAssertEqual(sut.object(at: 1) as! String, "2") 21 | } 22 | 23 | func test_isEqual_shouldCompareUnderlyingSet() { 24 | let orderedSet = NSOrderedSet(array: [1, 2, 3]) 25 | let sut = LazyMapOrderedSet.from(orderedSet) { 26 | "\($0)" 27 | } to: { 28 | Int($0)! 29 | } 30 | XCTAssertTrue(sut.isEqual(NSOrderedSet(array: ["1", "2", "3"]))) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/js/highlight-js-diff.62d66733.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * This source file is part of the Swift.org open source project 3 | * 4 | * Copyright (c) 2021 Apple Inc. and the Swift project authors 5 | * Licensed under Apache License v2.0 with Runtime Library Exception 6 | * 7 | * See https://swift.org/LICENSE.txt for license information 8 | * See https://swift.org/CONTRIBUTORS.txt for Swift project authors 9 | */ 10 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["highlight-js-diff"],{"48b8":function(e,n){function a(e){const n=e.regex;return{name:"Diff",aliases:["patch"],contains:[{className:"meta",relevance:10,match:n.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,/^\*\*\* +\d+,\d+ +\*\*\*\*$/,/^--- +\d+,\d+ +----$/)},{className:"comment",variants:[{begin:n.either(/Index: /,/^index/,/={3,}/,/^-{3}/,/^\*{3} /,/^\+{3}/,/^diff --git/),end:/$/},{match:/^\*{15}$/}]},{className:"addition",begin:/^\+/,end:/$/},{className:"deletion",begin:/^-/,end:/$/},{className:"addition",begin:/^!/,end:/$/}]}}e.exports=a}}]); -------------------------------------------------------------------------------- /Tests/UtilsTests/OptionalTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OptionalTests.swift 3 | // 4 | // 5 | // Created by ezou on 2022/2/5. 6 | // 7 | 8 | import XCTest 9 | 10 | @testable import Crush 11 | 12 | class OptionalTests: XCTestCase { 13 | func test_isNil_shouldBeTrue() { 14 | let sut = Swift.Optional.none 15 | XCTAssertTrue(sut.isNil) 16 | } 17 | 18 | func test_isNil_shouldBeFalse() { 19 | let sut = Swift.Optional.some(10) 20 | XCTAssertFalse(sut.isNil) 21 | } 22 | 23 | func test_null_shouldBeNil() { 24 | XCTAssertNil(Swift.Optional.null) 25 | } 26 | 27 | func test_contentDescription_shouldBeNull() { 28 | let sut = Swift.Optional.none 29 | XCTAssertEqual(sut.contentDescription, "null") 30 | } 31 | 32 | func test_contentDescription_shouldDescribeContent() { 33 | let sut = Swift.Optional.some(10) 34 | let result = sut.contentDescription 35 | XCTAssertEqual("\(10)", result) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 ezoushen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /docs/img/modified-icon.f496e73d.svg: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /Sources/DataContainer/DataContainer+workingDirectory.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DataContainer+workingDirectory.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/17. 6 | // 7 | 8 | import Foundation 9 | 10 | private var workingDirectoryLocked: Bool = false 11 | private var workingDirectory: URL = { 12 | workingDirectoryLocked = true 13 | #if os(macOS) 14 | return try! FileManager.default.url( 15 | for: .applicationSupportDirectory, 16 | in: .userDomainMask, 17 | appropriateFor: nil, create: true) 18 | #else 19 | return try! FileManager.default.url( 20 | for: .documentDirectory, 21 | in: .userDomainMask, 22 | appropriateFor: nil, create: true) 23 | #endif 24 | }() 25 | 26 | func CurrentWorkingDirectory() -> URL { 27 | workingDirectory 28 | } 29 | 30 | public enum DataContainerError: Error { 31 | case workingDirectoryInconsistency 32 | } 33 | 34 | extension DataContainer { 35 | public static func setWorkingDirectory(_ url: URL) throws { 36 | guard !workingDirectoryLocked else { 37 | throw DataContainerError.workingDirectoryInconsistency 38 | } 39 | workingDirectory = url 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Sources/Crush.docc/Crush.md: -------------------------------------------------------------------------------- 1 | # ``Crush`` 2 | 3 | Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality 4 | 5 | ## Overview 6 | 7 | ### Installation 8 | 9 | Make sure you've declared `Crush` as your dependency before getting started 10 | 11 | ```swift 12 | let package = Package( 13 | dependencies: [ 14 | .package( 15 | url: "https://github.com/ezoushen/Crush", 16 | from: "TARGET_VERSION" 17 | ), 18 | ], 19 | targets: [ 20 | .target( 21 | name: "", 22 | dependencies: [ 23 | "Crush" 24 | ] 25 | ) 26 | ] 27 | ) 28 | ``` 29 | 30 | ## Topics 31 | 32 | ### Getting started 33 | 34 | - 35 | - 36 | - 37 | 38 | ### Managing data schema 39 | 40 | - 41 | - 42 | - 43 | 44 | ### Working with Session 45 | 46 | - 47 | - 48 | - 49 | - 50 | 51 | ### Query builders 52 | 53 | // Fetch Builder 54 | // Aggreation Builder 55 | // Update Builder 56 | // Delete Builder 57 | -------------------------------------------------------------------------------- /Tests/DataStructureTests/LazyMapSetTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LazyMapSetTests.swift 3 | // 4 | // 5 | // Created by EZOU on 2023/9/1. 6 | // 7 | 8 | import XCTest 9 | 10 | @testable import Crush 11 | 12 | class LazyMapSetTests: XCTestCase { 13 | func test_count_shouldEqualToUnderlyingSet() { 14 | let nsset = NSSet(array: [0]) 15 | let sut = LazyMapSet.from(nsset) { 16 | "\($0)" 17 | } to: { 18 | Int($0)! 19 | } 20 | XCTAssertEqual(nsset.count, sut.count) 21 | } 22 | 23 | func test_objectEnumerator_shouldIterateAllMappedObjects() { 24 | let nsset = NSSet(array: [0]) 25 | let sut = LazyMapSet.from(nsset) { 26 | "\($0)" 27 | } to: { 28 | Int($0)! 29 | } 30 | let array = sut.objectEnumerator().allObjects as? [String] 31 | XCTAssertEqual(["0"], array) 32 | } 33 | 34 | func test_member_shouldReturnTheObject() { 35 | let nsset = NSSet(array: [0]) 36 | let sut = LazyMapSet.from(nsset) { 37 | "\($0)" 38 | } to: { 39 | Int($0)! 40 | } 41 | XCTAssertEqual(sut.member("0") as? String, "0") 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /docs/js/highlight-js-http.163e45b6.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * This source file is part of the Swift.org open source project 3 | * 4 | * Copyright (c) 2021 Apple Inc. and the Swift project authors 5 | * Licensed under Apache License v2.0 with Runtime Library Exception 6 | * 7 | * See https://swift.org/LICENSE.txt for license information 8 | * See https://swift.org/CONTRIBUTORS.txt for Swift project authors 9 | */ 10 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["highlight-js-http"],{c01d:function(e,n){function a(e){const n=e.regex,a="HTTP/(2|1\\.[01])",s=/[A-Za-z][A-Za-z0-9-]*/,t={className:"attribute",begin:n.concat("^",s,"(?=\\:\\s)"),starts:{contains:[{className:"punctuation",begin:/: /,relevance:0,starts:{end:"$",relevance:0}}]}},i=[t,{begin:"\\n\\n",starts:{subLanguage:[],endsWithParent:!0}}];return{name:"HTTP",aliases:["https"],illegal:/\S/,contains:[{begin:"^(?="+a+" \\d{3})",end:/$/,contains:[{className:"meta",begin:a},{className:"number",begin:"\\b\\d{3}\\b"}],starts:{end:/\b\B/,illegal:/\S/,contains:i}},{begin:"(?=^[A-Z]+ (.*?) "+a+"$)",end:/$/,contains:[{className:"string",begin:" ",end:" ",excludeBegin:!0,excludeEnd:!0},{className:"meta",begin:a},{className:"keyword",begin:"[A-Z]+"}],starts:{end:/\b\B/,illegal:/\S/,contains:i}},e.inherit(t,{relevance:0})]}}e.exports=a}}]); -------------------------------------------------------------------------------- /Tests/QueryBuilderTests/UpdateBuilderTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UpdateBuilderTests.swift 3 | // 4 | // 5 | // Created by EZOU on 2022/7/22. 6 | // 7 | 8 | import Foundation 9 | import XCTest 10 | 11 | @testable import Crush 12 | 13 | class UpdateBuilderTests: XCTestCase { 14 | 15 | class TestEntity: Entity { 16 | var intValue = Value.Int64("intValue") 17 | var entity = Relation.ToOne("entity") 18 | } 19 | 20 | var sut: DataContainer! 21 | 22 | override func setUpWithError() throws { 23 | sut = try?.load(storages: .sqliteInMemory(), dataModel: .init(name: "DataModel", [TestEntity()])) 24 | } 25 | 26 | func test_updateIntValue_shouldUpdateAttribute() throws { 27 | let entity: TestEntity.ReadOnly = try sut.startSession().sync { context in 28 | let entity = context.create(entity: TestEntity.self) 29 | entity.intValue = 0 30 | try context.commit() 31 | return entity 32 | } 33 | 34 | let ids = try sut 35 | .update(for: TestEntity.self) 36 | .update(\.intValue, value: 10) 37 | .exec() 38 | 39 | XCTAssertEqual(ids, [entity.objectID]) 40 | XCTAssertEqual(entity.intValue, 10) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Sources/Crush.docc/UndoRedoInSession.md: -------------------------------------------------------------------------------- 1 | # Undo/Redo In Session 2 | 3 | Core Data supports undo/redo by default. In Crush, the redo/undo stack is managed through ``Session`` 4 | 5 | ## How to enable undo/redo 6 | 7 | To enable undo/redo, you need to call ``Session/enableUndoManager()``. And the session would start tracking the change stack block by block. Also, you can disable undo/redo by calling ``Session/disableUndoManager()``. 8 | 9 | ## Example of usage 10 | 11 | ```swift 12 | let session = dataContainer.startInteractiveSession() 13 | 14 | session.enableUndoManager() 15 | 16 | let todo: Todo.ReadOnly = session.sync { context in 17 | // make changes 18 | let todo = context.create(entity: Todo.self) 19 | todo.title = "ORIGINAL TITLE" 20 | return todo 21 | } 22 | 23 | session.sync { context in 24 | let todo = context.edit(object: todo) 25 | todo.title = "NEW TITLE" 26 | } 27 | 28 | print(todo.title) // NEW TITLE 29 | 30 | session.undo() 31 | 32 | print(todo.title) // ORIGINAL TITLE 33 | 34 | session.redo() 35 | 36 | print(todo.title) // NEW TITLE 37 | 38 | ``` 39 | 40 | Please be aware of that the undo/redo stack is not enabled by default. You need to call ``Session/enableUndoManager()`` to enable it. And the undo/redo stack is flushed once the session committed. 41 | 42 | -------------------------------------------------------------------------------- /Tests/DataModelTests/PartialObjectTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PartialObjectTests.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/22. 6 | // 7 | 8 | import CoreData 9 | import Foundation 10 | import XCTest 11 | 12 | @testable import Crush 13 | 14 | class PartialObjectTests: XCTestCase { 15 | class TestEntity: Entity { 16 | var integerValue = Value.Int64("integerValue") 17 | var stringValue = Value.String("stringValue") 18 | } 19 | 20 | func test_initWithPairs_shouldMergeIntoDictionary() { 21 | let sut = PartialObject( 22 | EntityKeyValuePair(\.integerValue, 10) 23 | ) 24 | let target = [ 25 | "integerValue": Int64(10) 26 | ] 27 | XCTAssertEqual(sut.store as! [String: Int64], target) 28 | } 29 | 30 | func test_dynamicKeyPathUpdateValue_shouldWriteIntoStore() { 31 | let sut = PartialObject() 32 | sut.integerValue = 10 33 | XCTAssertEqual(sut.store["integerValue"] as? Int64, 10) 34 | } 35 | 36 | func test_dynamicKeyPathUpdateValue_shouldReadFromStore() { 37 | let sut = PartialObject( 38 | EntityKeyValuePair(\.integerValue, 10) 39 | ) 40 | let target = sut.integerValue 41 | XCTAssertEqual(target, 10) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Sources/DataStructure/LazyMapSet.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LazyMapSet.swift 3 | // 4 | // 5 | // Created by EZOU on 2023/9/1. 6 | // 7 | 8 | import Foundation 9 | 10 | final class LazyMapSet: NSSet { 11 | 12 | static func from(_ nsset: NSSet, from: @escaping (T) -> U, to: @escaping (U) -> T) -> LazyMapSet { 13 | let this = LazyMapSet() 14 | this.nsset = nsset 15 | this.from = from 16 | this.to = to 17 | return this 18 | } 19 | 20 | var from: ((T) -> U)! 21 | var to: ((U) -> T)! 22 | 23 | var nsset: NSSet! 24 | 25 | override var count: Int { 26 | nsset.count 27 | } 28 | 29 | override func member(_ object: Any) -> Any? { 30 | guard let object = object as? U, 31 | let result = nsset.member(to(object)) as? T else { return nil } 32 | return from(result) 33 | } 34 | 35 | override func objectEnumerator() -> NSEnumerator { 36 | MapEnumerationIterator(iterator: nsset.makeIterator(), from: from) 37 | } 38 | 39 | override func copy() -> Any { 40 | LazyMapSet.from(nsset.copy() as! NSSet, from: from, to: to) 41 | } 42 | 43 | override func mutableCopy() -> Any { 44 | LazyMapMutableSet.from(nsset.mutableCopy() as! NSMutableSet, from: from, to: to) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Sources/Crush.docc/TypesOfSessions.md: -------------------------------------------------------------------------------- 1 | # Types of Sessions 2 | 3 | Introduce provided session types 4 | 5 | ## General Session 6 | 7 | This is the default session type. It is suitable for most use cases. The execution context, which is derived from the writer context, is created in a background thread. And the read only objects are presented in the UI context which working on main thread. 8 | 9 | Typically, this type of session mutates data in the background and presents data in the main thread. And the data mutation is unavailable until changes are saved. 10 | 11 | ## Interactive Session 12 | 13 | This session type is suitable for interactive use cases. The execution context, which is derived from the writer context, is created in the main thread and the read only objects are presented in the UI context which working on main thread. 14 | 15 | The use case of this session type is to perform data mutation in the main thread, and present data in the main thread. It is suitable for interactive use cases, such as editing data in a form. All changes are available during the session regardless . 16 | 17 | ## Table of comparison between different session types 18 | 19 | | Session Type | Execution Thread | UI Context | Use Case | 20 | | --- | --- | --- | --- | 21 | | General Session | Background thread | Main UI context | Apply data changes into the database 22 | | Interactive Session | Main thread | The writer context | Interactive data editing 23 | -------------------------------------------------------------------------------- /Tests/DataStructureTests/LazyMapOrderedSetTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LazyMapOrderedSetTests.swift 3 | // 4 | // 5 | // Created by EZOU on 2023/9/1. 6 | // 7 | 8 | import XCTest 9 | 10 | @testable import Crush 11 | 12 | class LazyMapMutableOrderedSetTests: XCTestCase { 13 | func test_insert_shouldInsertMappedObject() { 14 | let orderedSet = NSMutableOrderedSet(array: [1, 2, 3]) 15 | let sut = LazyMapMutableOrderedSet.from(orderedSet) { 16 | "\($0)" 17 | } to: { 18 | Int($0)! 19 | } 20 | sut.insert("0", at: 0) 21 | XCTAssertEqual(["0", "1", "2", "3"], sut.array as! [String]) 22 | } 23 | 24 | func test_remove_shouldRemoveMappedObjectAtIndexSet() { 25 | let orderedSet = NSMutableOrderedSet(array: [1, 2, 3]) 26 | let sut = LazyMapMutableOrderedSet.from(orderedSet) { 27 | "\($0)" 28 | } to: { 29 | Int($0)! 30 | } 31 | sut.removeObjects(at: [0, 1]) 32 | XCTAssertEqual(["3"], sut.array as! [String]) 33 | } 34 | 35 | func test_isEqual_shouldCompareUnderlyingSet() { 36 | let orderedSet = NSMutableOrderedSet(array: [1, 2, 3]) 37 | let sut = LazyMapMutableOrderedSet.from(orderedSet) { 38 | "\($0)" 39 | } to: { 40 | Int($0)! 41 | } 42 | XCTAssertTrue(sut.isEqual(NSOrderedSet(array: ["1", "2", "3"]))) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Sources/Crush.docc/SigningSessionBlock.md: -------------------------------------------------------------------------------- 1 | # Signing Execution Block in Session 2 | 3 | Enable signing `transactionAuthor` for the code block 4 | 5 | ## What is transactionAuthor 6 | 7 | `transactionAuthor` is a property of `NSManagedObjectContext` that identifies the author of the transaction. It is used to track the changes made by each user in persistent history tracking. 8 | 9 | ## When to sign the transactionAuthor 10 | 11 | You should sign the `transactionAuthor` when you are performing a data mutation operation in a session. 12 | 13 | ## How to sign the transactionAuthor 14 | 15 | You can sign the `transactionAuthor` by providing `name` parameter of the execution method, both of sync and async methods, in `Session`: 16 | 17 | ```swift 18 | 19 | try session.sync(name: "John") { context in 20 | let entity = try context.create(MyEntity.self) 21 | entity.stringValue = "Hello world!" 22 | try context.commit() 23 | } 24 | 25 | ``` 26 | ## Where would the transactionAuthor be used 27 | 28 | The `transactionAuthor` will be used in the `NSPersistentHistoryChange` object, which is used to track the changes made by each user. You can load the `NSPersistentHistoryChange` object by calling ``DataContainer/loadTransactionHistory(since:)``. 29 | 30 | ```swift 31 | let transactions = try dataContainer.loadTransactionHistory(since: targetDate) 32 | 33 | for transaction in transactions { 34 | let author = transction.author // signed author name 35 | } 36 | ``` 37 | -------------------------------------------------------------------------------- /Sources/DataModel/Entity/Property/Property+Attribute.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Property+Attribute.swift 3 | // Crush 4 | // 5 | // Created by ezou on 2019/9/26. 6 | // Copyright © 2019 ezou. All rights reserved. 7 | // 8 | 9 | import CoreData 10 | 11 | // MARK: - EntityAttribute 12 | 13 | public protocol AttributeProtocol: WritableProperty 14 | where 15 | PropertyType: AttributeType, 16 | Description: NSAttributeDescription 17 | { } 18 | 19 | extension AttributeProtocol { 20 | public var isAttribute: Bool { true } 21 | 22 | public var attributeType: NSAttributeType { 23 | PropertyType.nativeType 24 | } 25 | } 26 | 27 | public protocol ConcreteAttriuteProcotol: AttributeProtocol { } 28 | 29 | 30 | // MARK: - EntityAttributeType 31 | public class Attribute: 32 | ConcreteAttriuteProcotol, 33 | TransformableAttributeInitProtocol, 34 | TransientProperty 35 | { 36 | public typealias PredicateValue = PropertyType.PredicateValue 37 | public typealias PropertyValue = PropertyType.RuntimeValue 38 | 39 | public let name: String 40 | 41 | public required init(_ name: String) { 42 | self.name = name 43 | } 44 | 45 | public func createPropertyDescription() -> NSAttributeDescription { 46 | let description = NSAttributeDescription() 47 | description.name = name 48 | description.attributeType = attributeType 49 | return description 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /docs/favicon.svg: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /Tests/VersioningTests/MigrationTests/FethcedPropertyMigrationTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FethcedPropertyMigrationTests.swift 3 | // 4 | // 5 | // Created by EZOU on 2023/4/26. 6 | // 7 | 8 | import CoreData 9 | import Foundation 10 | import XCTest 11 | 12 | @testable import Crush 13 | 14 | class AddFetchedPropertyTests: XCTestCase { 15 | func test_createProperty_shouldSetupNameAndFetchRequest() { 16 | let fetchRequest = NSFetchRequest() 17 | let sut = AddFetchedProperty("NAME", fetchRequest: fetchRequest) 18 | var callback: [EntityMigrationCallback] = [] 19 | let description = sut.createProperty(callbackStore: &callback) 20 | XCTAssertTrue(description is NSFetchedPropertyDescription) 21 | XCTAssertEqual(description.name, "NAME") 22 | XCTAssertIdentical((description as! NSFetchedPropertyDescription).fetchRequest, fetchRequest) 23 | } 24 | } 25 | 26 | class UpdateFetchedPropertyTests: XCTestCase { 27 | func test_migrateProperty_shouldUpdateNameAndFetchRequest() throws { 28 | let fetchRequest = NSFetchRequest() 29 | let sut = UpdateFetchedProperty("origin", name: "NAME", fetchRequest: fetchRequest) 30 | let description = NSFetchedPropertyDescription() 31 | var callback: [EntityMigrationCallback] = [] 32 | _ = try sut.migrateProperty(description, callbackStore: &callback) 33 | XCTAssertEqual(description.name, "NAME") 34 | XCTAssertIdentical(description.fetchRequest, fetchRequest) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.5 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "Crush", 8 | platforms: [ 9 | .macOS(.v10_13), 10 | .iOS(.v11), 11 | .watchOS(.v4), 12 | .tvOS(.v11), 13 | ], 14 | products: [ 15 | // Products define the executables and libraries produced by a package, and make them visible to other packages. 16 | .library( 17 | name: "Crush", 18 | type: .`static`, 19 | targets: ["Crush"]), 20 | .library( 21 | name: "Crush-dynamic", 22 | type: .dynamic, 23 | targets: ["Crush"]), 24 | ], 25 | dependencies: [ 26 | // Dependencies declare other packages that this package depends on. 27 | // .package(url: /* package url */, from: "1.0.0"), 28 | .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"), 29 | ], 30 | targets: [ 31 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 32 | // Targets can depend on other targets in this package, and on products in packages which this package depends on. 33 | .target( 34 | name: "Crush", 35 | dependencies: [], 36 | path: "./Sources"), 37 | .testTarget( 38 | name: "CrushTests", 39 | dependencies: ["Crush"], 40 | path: "./Tests"), 41 | ]) 42 | -------------------------------------------------------------------------------- /Sources/Versioning/Migrator/AdHocMigrator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AdHocMigrator.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/15. 6 | // 7 | 8 | import CoreData 9 | import Foundation 10 | 11 | internal final class AdHocMigrator: Migrator { 12 | internal let lastActiveModel: NSManagedObjectModel? 13 | internal let migration: ModelMigration 14 | 15 | internal init( 16 | storage: ConcreteStorage, 17 | sourceModelName: String, 18 | migration: ModelMigration, 19 | dataModel: DataModel) 20 | { 21 | self.migration = migration 22 | self.lastActiveModel = .load(name: sourceModelName) 23 | super.init(storage: storage, dataModel: dataModel) 24 | } 25 | 26 | @discardableResult 27 | internal override func migrate() throws -> Bool { 28 | guard let sourceModel = lastActiveModel else { return false } 29 | 30 | let currentModel = dataModel.managedObjectModel 31 | let destinationModel = try migration.migrateModel(sourceModel) 32 | let isCompatible = currentModel.isCompactible(with: destinationModel) 33 | 34 | guard isCompatible else { 35 | throw MigrationError.incompatible 36 | } 37 | 38 | let mappingModel = try migration 39 | .createMappingModel(from: sourceModel, to: destinationModel) 40 | 41 | try migrateStore( 42 | name: dataModel.name, 43 | from: sourceModel, 44 | to: destinationModel, 45 | mappingModel: mappingModel) 46 | 47 | return true 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Sources/DataStructure/LazyMapOrderedSet.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // 4 | // 5 | // Created by EZOU on 2023/9/1. 6 | // 7 | 8 | import Foundation 9 | 10 | final class LazyMapOrderedSet: NSOrderedSet { 11 | 12 | static func from(_ orderedSet: NSOrderedSet, from: @escaping (T) -> U, to: @escaping (U) -> T) -> LazyMapOrderedSet { 13 | let this = LazyMapOrderedSet() 14 | this.orderedSet = orderedSet 15 | this.from = from 16 | this.to = to 17 | return this 18 | } 19 | 20 | var from: ((T) -> U)! 21 | var to: ((U) -> T)! 22 | 23 | var orderedSet: NSOrderedSet! 24 | 25 | override var count: Int { 26 | orderedSet.count 27 | } 28 | 29 | override func contains(_ object: Any) -> Bool { 30 | guard let object = object as? U else { return false } 31 | return orderedSet.contains(object) 32 | } 33 | 34 | override func objectEnumerator() -> NSEnumerator { 35 | MapEnumerationIterator(iterator: orderedSet.makeIterator(), from: from) 36 | } 37 | 38 | override func object(at idx: Int) -> Any { 39 | let object = orderedSet.object(at: idx) as! T 40 | return from(object) 41 | } 42 | 43 | override func copy() -> Any { 44 | LazyMapOrderedSet.from(orderedSet.copy() as! NSOrderedSet, from: from, to: to) 45 | } 46 | 47 | override func mutableCopy() -> Any { 48 | LazyMapMutableOrderedSet 49 | .from(orderedSet.mutableCopy() as! NSMutableOrderedSet, from: from, to: to) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Sources/Versioning/MigrationChainIterator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MigrationChainIterator.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/15. 6 | // 7 | 8 | import CoreData 9 | import Foundation 10 | 11 | internal class MigrationChainIterator: IteratorProtocol { 12 | internal struct Node { 13 | internal let name: String 14 | internal let mappingModel: NSMappingModel 15 | internal let destinationManagedObjectModel: NSManagedObjectModel 16 | } 17 | 18 | private var index: Int = 0 19 | 20 | internal let chain: MigrationChain 21 | 22 | internal init(_ chain: MigrationChain) { 23 | self.chain = chain 24 | } 25 | 26 | internal func next() -> Node? { 27 | guard let mappingModels = try? chain.mappingModels(), 28 | let managedObjectModels = try? chain.managedObjectModels(), 29 | mappingModels.count > index else { return nil } 30 | defer { index += 1 } 31 | return Node( 32 | name: chain.migrations[index+1].name, 33 | mappingModel: mappingModels[index], 34 | destinationManagedObjectModel: managedObjectModels[index+1]) 35 | } 36 | 37 | internal func setActiveVersion(managedObjectModel: NSManagedObjectModel?) { 38 | guard let managedObjectModels = try? chain.managedObjectModels(), 39 | let managedObjectModel = managedObjectModel else { 40 | return index = 0 41 | } 42 | index = managedObjectModels.firstIndex(of: managedObjectModel) ?? 0 43 | } 44 | 45 | internal func reset() { 46 | index = 0 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Tests/UtilsTests/PersistentHashTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PersistentHashTests.swift 3 | // 4 | // 5 | // Created by ezou on 2022/2/5. 6 | // 7 | 8 | import Foundation 9 | import XCTest 10 | 11 | @testable import Crush 12 | 13 | public class PersistentHashTests: XCTestCase { 14 | func test_hashOrderedNumbers_shouldBeEqual() { 15 | let value = PersistentHash.ordered(10, 11) 16 | let sut = PersistentHash.ordered(10, 11) 17 | XCTAssertEqual(value, sut) 18 | } 19 | 20 | func test_hashReverseOrderedNumbers_shouldNotBeEqual() { 21 | let value = PersistentHash.ordered(10, 11) 22 | let sut = PersistentHash.ordered(11, 10) 23 | XCTAssertNotEqual(value, sut) 24 | } 25 | 26 | func test_hashUnorderedNumbers_shouldBeEqual() { 27 | let value = PersistentHash.unordered(10, 11) 28 | let sut = PersistentHash.unordered(10, 11) 29 | XCTAssertEqual(value, sut) 30 | } 31 | 32 | func test_hashReversedUnorderedNumbers_shouldBeEqual() { 33 | let value = PersistentHash.unordered(10, 11) 34 | let sut = PersistentHash.unordered(11, 10) 35 | XCTAssertEqual(value, sut) 36 | } 37 | 38 | func test_hashFromString_shouldBeEqual() { 39 | let value = PersistentHash.fromString("STRING") 40 | let sut = PersistentHash.fromString("STRING") 41 | XCTAssertEqual(value, sut) 42 | } 43 | 44 | func test_hashFromString_shouldNotBeEqual() { 45 | let value = PersistentHash.fromString("STRING") 46 | let sut = PersistentHash.fromString("ANOTHER STRING") 47 | XCTAssertNotEqual(value, sut) 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /docs/data/documentation/crush/userinfokey.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"UserInfoKey"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/userinfokey"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/UserInfoKey","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"UserInfoKey"}],"title":"UserInfoKey","roleHeading":"Enumeration","role":"symbol","symbolKind":"enum","externalID":"s:5Crush11UserInfoKeyO","modules":[{"name":"Crush"}],"navigatorTitle":[{"kind":"identifier","text":"UserInfoKey"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush"]]},"references":{"doc://Crush/documentation/Crush/UserInfoKey":{"role":"symbol","title":"UserInfoKey","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"UserInfoKey"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UserInfoKey","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"UserInfoKey"}],"url":"\/documentation\/crush\/userinfokey"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /Sources/DataModel/Entity/PartialObject.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PartialObject.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/16. 6 | // 7 | 8 | import Foundation 9 | 10 | @dynamicMemberLookup 11 | public final class PartialObject { 12 | internal var store: [String: Any] = [:] 13 | 14 | internal init(store: [String: Any]) { 15 | self.store = store 16 | } 17 | } 18 | 19 | extension PartialObject where T: Entity { 20 | public convenience init(_ pairs: EntityKeyValuePair...) { 21 | let store = pairs.reduce(into: [String: Any]()) { 22 | $0[$1.key] = $1.value 23 | } 24 | self.init(store: store) 25 | } 26 | 27 | public subscript( 28 | dynamicMember keyPath: KeyPath) -> S.RuntimeValue 29 | { 30 | get { 31 | let value = store[keyPath.propertyName] 32 | guard let result = value as? S.PropertyType.ManagedValue 33 | else { return .null } 34 | return S.PropertyType.convert(managedValue: result) 35 | } 36 | set { 37 | let value: S.PropertyType.ManagedValue = 38 | S.PropertyType.convert(runtimeValue: newValue) 39 | store[keyPath.propertyName] = value 40 | } 41 | } 42 | } 43 | 44 | public struct EntityKeyValuePair { 45 | public let key: String 46 | public let value: Any 47 | 48 | public init( 49 | _ keyPath: KeyPath, 50 | _ value: S.PropertyType.RuntimeValue) 51 | { 52 | self.key = keyPath.propertyName 53 | self.value = S.PropertyType.convert(runtimeValue: value) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Sources/DataModel/Entity/Property/PrimitiveAttributeType+Transformable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PrimitiveAttributeType+Transformable.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/18. 6 | // 7 | 8 | import CoreData 9 | import Foundation 10 | 11 | public protocol TransformableAttributeType: NSObject, NSCoding, PrimitiveAttributeType 12 | where 13 | RuntimeValue == PrimitiveType?, 14 | ManagedValue == PrimitiveType?, 15 | PredicateValue == PrimitiveType 16 | { 17 | associatedtype PrimitiveType = Self 18 | 19 | associatedtype RuntimeValue = PrimitiveType? 20 | associatedtype ManagedValue = PrimitiveType? 21 | associatedtype PredicateValue = PrimitiveType 22 | 23 | static var attributeValueClassName: String? { get } 24 | static var valueTransformerName: String? { get } 25 | } 26 | 27 | extension TransformableAttributeType { 28 | @inlinable public static var valueTransformerName: String? { nil } 29 | } 30 | 31 | extension TransformableAttributeType { 32 | @inlinable public static var nativeType: NSAttributeType { .transformableAttributeType } 33 | @inlinable public static var attributeValueClassName: String? { String(describing: Self.self) } 34 | } 35 | 36 | #if os(iOS) || os(watchOS) 37 | import UIKit.UIImage 38 | extension UIImage: PrimitiveAttributeType { 39 | public typealias PrimitiveType = UIImage 40 | } 41 | 42 | extension UIColor: PrimitiveAttributeType { 43 | public typealias PrimitiveType = UIColor 44 | } 45 | #endif 46 | 47 | extension NSCoding where Self: PrimitiveAttributeType & NSObject { 48 | @inlinable public static var nativeType: NSAttributeType { .transformableAttributeType } 49 | @inlinable public var predicateValue: NSObject { self } 50 | } 51 | -------------------------------------------------------------------------------- /Sources/DataStructure/LazyMapMutableSet.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LazyMapMutableSet.swift 3 | // 4 | // 5 | // Created by EZOU on 2023/9/1. 6 | // 7 | 8 | import Foundation 9 | 10 | final class LazyMapMutableSet: NSMutableSet { 11 | 12 | static func from(_ mutableSet: NSMutableSet, from: @escaping (T) -> U, to: @escaping (U) -> T) -> LazyMapMutableSet { 13 | let this = LazyMapMutableSet() 14 | this.mutableSet = mutableSet 15 | this.from = from 16 | this.to = to 17 | return this 18 | } 19 | 20 | var from: ((T) -> U)! 21 | var to: ((U) -> T)! 22 | 23 | var mutableSet: NSMutableSet! 24 | 25 | override var count: Int { 26 | mutableSet.count 27 | } 28 | 29 | override func member(_ object: Any) -> Any? { 30 | guard let object = object as? U, 31 | let result = mutableSet.member(to(object)) as? T else { return nil } 32 | return from(result) 33 | } 34 | 35 | override func objectEnumerator() -> NSEnumerator { 36 | MapEnumerationIterator(iterator: mutableSet.makeIterator(), from: from) 37 | } 38 | 39 | override func add(_ object: Any) { 40 | guard let object = object as? U else { return } 41 | mutableSet.add(to(object)) 42 | } 43 | 44 | override func remove(_ object: Any) { 45 | guard let object = object as? U else { return } 46 | mutableSet.remove(to(object)) 47 | } 48 | 49 | override func copy() -> Any { 50 | LazyMapSet.from(mutableSet.copy() as! NSSet, from: from, to: to) 51 | } 52 | 53 | override func mutableCopy() -> Any { 54 | LazyMapMutableSet 55 | .from(mutableSet.mutableCopy() as! NSMutableSet, from: from, to: to) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Sources/DataModel/Entity/Property/CodableAttributeType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CodableAttributeType.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/18. 6 | // 7 | 8 | import CoreData 9 | import Foundation 10 | 11 | public protocol CodableAttributeType: AttributeType, PredicateEquatable, Codable, Hashable 12 | where 13 | RuntimeValue == Self?, 14 | ManagedValue == Data?, 15 | PredicateValue == Data 16 | { 17 | var data: Data { get set } 18 | 19 | static var encoder: JSONEncoder { get } 20 | static var decoder: JSONDecoder { get } 21 | } 22 | 23 | extension CodableAttributeType { 24 | @inlinable public static var defaultRuntimeValue: RuntimeValue { nil } 25 | @inlinable public static var defaultManagedValue: ManagedValue { nil } 26 | 27 | @inlinable 28 | public static func convert(managedValue: Data?) -> Self? { 29 | guard let value = managedValue else { return nil } 30 | return try! Self.decoder.decode(Self.self, from: value) 31 | } 32 | 33 | @inlinable 34 | public static func convert(runtimeValue: Self?) -> Data? { 35 | guard let value = runtimeValue else { return nil } 36 | return try! Self.encoder.encode(value) 37 | } 38 | 39 | public func hash(into hasher: inout Hasher) { 40 | hasher.combine(data) 41 | } 42 | 43 | @inlinable public static var encoder: JSONEncoder { JSONEncoder() } 44 | @inlinable public static var decoder: JSONDecoder { JSONDecoder() } 45 | @inlinable public static var nativeType: NSAttributeType { .binaryDataAttributeType } 46 | 47 | @inlinable public var predicateValue: NSObject { data as NSData } 48 | @inlinable public var data: Data { 49 | get { try! Self.encoder.encode(self) } 50 | mutating set { self = try! Self.decoder.decode(Self.self, from: newValue) } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Tests/Measurement.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Measurement.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/14. 6 | // 7 | 8 | import Foundation 9 | 10 | struct Measurement { 11 | let name: String 12 | let duration: Double 13 | let memoryConsumptionInBytes: UInt64 14 | } 15 | 16 | internal func measurement(name: String? = nil, block: () -> Void) -> Measurement { 17 | let startMemory = memory_usage() 18 | let startTime = mach_absolute_time() 19 | block() 20 | let endTime = mach_absolute_time() 21 | let endMemory = memory_usage() 22 | return Measurement( 23 | name: name ?? "untitled", 24 | duration: mach_to_milliseconds(endTime - startTime), 25 | memoryConsumptionInBytes: endMemory - startMemory) 26 | } 27 | 28 | private var timebase_info: mach_timebase_info = { 29 | var info = mach_timebase_info_data_t() 30 | mach_timebase_info(&info) 31 | return info 32 | }() 33 | 34 | private func mach_to_milliseconds(_ time: UInt64) -> Double { 35 | return Double(time * UInt64(timebase_info.numer)) / Double(timebase_info.denom) / 1_000_000 36 | } 37 | 38 | private func memory_usage() -> UInt64 { 39 | var taskInfo = mach_task_basic_info() 40 | var count = mach_msg_type_number_t(MemoryLayout.size)/4 41 | let kerr: kern_return_t = withUnsafeMutablePointer(to: &taskInfo) { 42 | $0.withMemoryRebound(to: integer_t.self, capacity: 1) { 43 | task_info(mach_task_self_, task_flavor_t(MACH_TASK_BASIC_INFO), $0, &count) 44 | } 45 | } 46 | 47 | if kerr == KERN_SUCCESS { 48 | return taskInfo.resident_size 49 | } 50 | else { 51 | fatalError("Error with task_info(): " + 52 | (String(cString: mach_error_string(kerr), encoding: String.Encoding.ascii) ?? "unknown error")) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Sources/DataModel/Entity/Property/EnumerableAttributeType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EnumerableAttributeType.swift 3 | // 4 | // 5 | // Created by ezou on 2021/10/18. 6 | // 7 | 8 | import CoreData 9 | import Foundation 10 | 11 | public protocol EnumerableAttributeType: 12 | RawRepresentable, 13 | AttributeType, 14 | PredicateEquatable, 15 | Hashable 16 | where 17 | RawValue: PredicateEquatable & Hashable, 18 | ManagedValue == RawAttributeType.ManagedValue, 19 | RuntimeValue == Self?, 20 | PredicateValue == RawAttributeType.PredicateValue, 21 | PredicateType == RawValue.PredicateType 22 | { 23 | associatedtype RawAttributeType: PrimitiveAttributeType 24 | associatedtype PredicateValue = RawValue 25 | associatedtype ManagedValue = RawValue? 26 | associatedtype RuntimeValue = Self? 27 | } 28 | 29 | extension EnumerableAttributeType { 30 | @inlinable public static var defaultRuntimeValue: RuntimeValue { nil } 31 | @inlinable public static var defaultManagedValue: ManagedValue { nil } 32 | 33 | public static func convert(managedValue: RawValue?) -> Self? { 34 | guard let value = managedValue else { return nil } 35 | return Self.init(rawValue: value) 36 | } 37 | 38 | @inlinable public static func convert(runtimeValue: Self?) -> RawValue? { 39 | runtimeValue?.rawValue 40 | } 41 | 42 | @inlinable public static var nativeType: NSAttributeType { RawAttributeType.nativeType } 43 | @inlinable public var predicateValue: PredicateType { self.rawValue.predicateValue } 44 | 45 | public func hash(into hasher: inout Hasher) { 46 | hasher.combine(rawValue) 47 | } 48 | } 49 | 50 | public protocol ComparableEnumerableAttributeType: 51 | EnumerableAttributeType, PredicateComparable 52 | where 53 | RawValue: PredicateComparable { } 54 | -------------------------------------------------------------------------------- /docs/data/documentation/crush/entity/init().json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"required"},{"kind":"text","text":" "},{"kind":"keyword","text":"init"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/entity\/init()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Entity\/init()","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"title":"init()","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:5Crush6EntityCACycfc","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/Entity"]]},"references":{"doc://Crush/documentation/Crush/Entity/init()":{"role":"symbol","title":"init()","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Entity\/init()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entity\/init()"},"doc://Crush/documentation/Crush/Entity":{"role":"symbol","title":"Entity","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Entity"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Entity","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Entity"}],"url":"\/documentation\/crush\/entity"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/entitymap/init().json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"init"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/entitymap\/init()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EntityMap\/init()","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"title":"init()","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:5Crush9EntityMapCACycfc","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/EntityMap"]]},"references":{"doc://Crush/documentation/Crush/EntityMap/init()":{"role":"symbol","title":"init()","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityMap\/init()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entitymap\/init()"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/EntityMap":{"role":"symbol","title":"EntityMap","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityMap"}],"abstract":[{"type":"text","text":"Declare a map that describes relationships between entities."}],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityMap","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EntityMap"}],"url":"\/documentation\/crush\/entitymap"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/relationship/relationshipprotocol-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/relationship\/relationshipprotocol-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Relationship\/RelationshipProtocol-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/Relationship\/isAttribute"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"RelationshipProtocol Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/Relationship"]]},"references":{"doc://Crush/documentation/Crush/Relationship":{"role":"symbol","title":"Relationship","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Relationship"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Relationship","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Relationship"}],"url":"\/documentation\/crush\/relationship"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/Relationship/isAttribute":{"role":"symbol","title":"isAttribute","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"isAttribute"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Relationship\/isAttribute","kind":"symbol","type":"topic","url":"\/documentation\/crush\/relationship\/isattribute"}}} -------------------------------------------------------------------------------- /Sources/Crush.docc/CRUDOperations.md: -------------------------------------------------------------------------------- 1 | # CRUD Operations 2 | 3 | Simple example of CRUD Operations in Crush 4 | 5 | ## Start with Session 6 | 7 | All data mutation in Crush must be completed through a ``Session``. You can create a session by calling ``DataContainer/startSession(name:)``. All data mutation would not be persisted until you call ``Session/commit()``. 8 | 9 | 10 | ```swift 11 | let session = dataContainer.startSession() 12 | 13 | try session.sync { context in 14 | /* 15 | Do something 16 | */ 17 | try context.commit() // Persist the changes 18 | } 19 | ``` 20 | 21 | ## Create Operation 22 | 23 | You can create an entity by calling ``SessionContext/create(entity:)`` 24 | 25 | ```swift 26 | try session.sync { context in 27 | let todo = context.create(entity: Todo.self) 28 | todo.title = "todo title" 29 | // setup the entity here 30 | try context.commit() 31 | } 32 | ``` 33 | 34 | ## Read Operation 35 | 36 | ### Load by NSManagedObjectID 37 | 38 | You can load an entity by calling ``SessionContext/load(objectID:isFault:)`` 39 | 40 | ```swift 41 | session.sync { context in 42 | let todo = context.load(objectID: injectedObjectID) 43 | } 44 | ``` 45 | 46 | ### Fetch objects 47 | 48 | You can fetch objects by building a fetch request through ``SessionContext/fetch(for:)`` 49 | 50 | ```swift 51 | session.sync { context in 52 | let todo = context.fetch(for: Todo.self) 53 | .where(\.title == "target title") 54 | .findOne() 55 | } 56 | ``` 57 | 58 | ## Update Operation 59 | 60 | You can edit a readonly object by ``SessionContext/edit(object:)`` 61 | 62 | ```swift 63 | try session.sync { context in 64 | let editableTodo = context.edit(object: todo) 65 | editableTodo.title = "new title" 66 | try context.commit() 67 | } 68 | ``` 69 | 70 | ## Delete Operation 71 | 72 | You can delete an object by ``SessionContext/delete(_:)`` 73 | 74 | ```swift 75 | try session.sync { context in 76 | context.delete(todo) 77 | try context.commit() 78 | } 79 | ``` 80 | -------------------------------------------------------------------------------- /docs/data/documentation/crush/entity/hashable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/entity\/hashable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Entity\/Hashable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/Entity\/hash(into:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Hashable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/Entity"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/Entity":{"role":"symbol","title":"Entity","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Entity"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Entity","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Entity"}],"url":"\/documentation\/crush\/entity"},"doc://Crush/documentation/Crush/Entity/hash(into:)":{"role":"symbol","title":"hash(into:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"hash"},{"kind":"text","text":"("},{"kind":"externalParam","text":"into"},{"kind":"text","text":": "},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"Hasher","preciseIdentifier":"s:s6HasherV"},{"kind":"text","text":")"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Entity\/hash(into:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entity\/hash(into:)"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/migrationerror/error-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/migrationerror\/error-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MigrationError\/Error-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/MigrationError\/localizedDescription"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Error Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MigrationError"]]},"references":{"doc://Crush/documentation/Crush/MigrationError/localizedDescription":{"role":"symbol","title":"localizedDescription","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"localizedDescription"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationError\/localizedDescription","kind":"symbol","type":"topic","url":"\/documentation\/crush\/migrationerror\/localizeddescription"},"doc://Crush/documentation/Crush/MigrationError":{"role":"symbol","title":"MigrationError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"MigrationError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MigrationError"}],"url":"\/documentation\/crush\/migrationerror"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/coredataerror/customstringconvertible-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/coredataerror\/customstringconvertible-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/CoreDataError\/CustomStringConvertible-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/CoreDataError\/description"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"CustomStringConvertible Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/CoreDataError"]]},"references":{"doc://Crush/documentation/Crush/CoreDataError":{"role":"symbol","title":"CoreDataError","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"CoreDataError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/CoreDataError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"CoreDataError"}],"url":"\/documentation\/crush\/coredataerror"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/CoreDataError/description":{"role":"symbol","title":"description","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"description"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/CoreDataError\/description","kind":"symbol","type":"topic","url":"\/documentation\/crush\/coredataerror\/description"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/coredataerror/error-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/coredataerror\/error-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/CoreDataError\/Error-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/CoreDataError\/localizedDescription-15imi"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Error Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/CoreDataError"]]},"references":{"doc://Crush/documentation/Crush/CoreDataError/localizedDescription-15imi":{"role":"symbol","title":"localizedDescription","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"localizedDescription"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/CoreDataError\/localizedDescription-15imi","kind":"symbol","type":"topic","url":"\/documentation\/crush\/coredataerror\/localizeddescription-15imi"},"doc://Crush/documentation/Crush/CoreDataError":{"role":"symbol","title":"CoreDataError","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"CoreDataError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/CoreDataError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"CoreDataError"}],"url":"\/documentation\/crush\/coredataerror"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/orderedset/init().json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"init"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/orderedset\/init()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/OrderedSet\/init()","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Inherited from "},{"type":"codeVoice","code":"SetAlgebra.init()"},{"type":"text","text":"."}],"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"title":"init()","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:5Crush10OrderedSetVACyxGycfc","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/OrderedSet"]]},"references":{"doc://Crush/documentation/Crush/OrderedSet/init()":{"role":"symbol","title":"init()","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/OrderedSet\/init()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/orderedset\/init()"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/OrderedSet":{"role":"symbol","title":"OrderedSet","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"OrderedSet"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/OrderedSet","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"OrderedSet"}],"url":"\/documentation\/crush\/orderedset"}}} -------------------------------------------------------------------------------- /Sources/Utils/KeyPath+helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeyPath+helper.swift 3 | // Crush 4 | // 5 | // Created by ezou on 2019/9/20. 6 | // Copyright © 2019 ezou. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreData 11 | 12 | extension AnyKeyPath { 13 | fileprivate static var lock = UnfairLock() 14 | fileprivate static var propertyNameCache: [AnyHashable: String] = [:] 15 | 16 | fileprivate var propertyNameCache: [AnyHashable: String] { 17 | get { Self.propertyNameCache } 18 | set { Self.propertyNameCache = newValue } 19 | } 20 | } 21 | 22 | extension PartialKeyPath where Root: Entity { 23 | var optionalPropertyName: String? { 24 | Self.lock.lock() 25 | defer { Self.lock.unlock() } 26 | return propertyNameCache[ObjectIdentifier(self)] ?? { 27 | let name = (Root()[keyPath: self] as? (any Property))?.name 28 | defer { if let name = name { propertyNameCache[ObjectIdentifier(self)] = name } } 29 | return name 30 | }() 31 | } 32 | } 33 | 34 | extension KeyPath where Root: Entity, Value: Property { 35 | var propertyName: String { 36 | Self.lock.lock() 37 | defer { Self.lock.unlock() } 38 | let key = AnyHashable(self) 39 | return propertyNameCache[key] ?? { 40 | let name = Root()[keyPath: self].name 41 | defer { propertyNameCache[key] = name } 42 | return name 43 | }() 44 | } 45 | } 46 | 47 | extension KeyPath: Expressible where Root: Entity, Value: Property { 48 | public func getHashValue() -> Int { 49 | propertyName.hashValue 50 | } 51 | 52 | public func asExpression() -> Any { 53 | propertyName 54 | } 55 | } 56 | 57 | extension KeyPath where Root: Entity, Value: RelationshipProtocol { 58 | public func extend( 59 | _ keyPath: KeyPath) -> String 60 | where 61 | Property: Crush.Property, 62 | Value.Destination == Target 63 | { 64 | "\(propertyName).\(keyPath.propertyName)" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /docs/data/documentation/crush/objectdriver/customdebugstringconvertible-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/objectdriver\/customdebugstringconvertible-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/CustomDebugStringConvertible-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/debugDescription"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"CustomDebugStringConvertible Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/ObjectDriver"]]},"references":{"doc://Crush/documentation/Crush/ObjectDriver":{"role":"symbol","title":"ObjectDriver","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"ObjectDriver"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ObjectDriver"}],"url":"\/documentation\/crush\/objectdriver"},"doc://Crush/documentation/Crush/ObjectDriver/debugDescription":{"role":"symbol","title":"debugDescription","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"debugDescription"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/debugDescription","kind":"symbol","type":"topic","url":"\/documentation\/crush\/objectdriver\/debugdescription"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/datacontainererror/error-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/datacontainererror\/error-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/DataContainerError\/Error-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/DataContainerError\/localizedDescription"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Error Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/DataContainerError"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/DataContainerError/localizedDescription":{"role":"symbol","title":"localizedDescription","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"localizedDescription"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/DataContainerError\/localizedDescription","kind":"symbol","type":"topic","url":"\/documentation\/crush\/datacontainererror\/localizeddescription"},"doc://Crush/documentation/Crush/DataContainerError":{"role":"symbol","title":"DataContainerError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"DataContainerError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/DataContainerError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"DataContainerError"}],"url":"\/documentation\/crush\/datacontainererror"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/storage/equatable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/storage\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Storage\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/Storage\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/Storage"]]},"references":{"doc://Crush/documentation/Crush/Storage":{"role":"symbol","title":"Storage","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Storage"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Storage","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Storage"}],"url":"\/documentation\/crush\/storage"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/Storage/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Storage\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/storage\/!=(_:_:)"}}} -------------------------------------------------------------------------------- /Sources/Utils/SelectPath.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CoreData.swift 3 | // 4 | // 5 | // Created by EZOU on 2022/6/11. 6 | // 7 | 8 | import CoreData 9 | 10 | public final class SelectPath: Expressible, ExpressibleByStringLiteral { 11 | 12 | private(set) 13 | public var name: String 14 | public let path: String 15 | 16 | lazy var expression: NSExpressionDescription = { 17 | let desc = NSExpressionDescription() 18 | desc.name = name 19 | desc.expressionResultType = resolveResultType(from: path) 20 | desc.expression = NSExpression(forKeyPath: path) 21 | return desc 22 | }() 23 | 24 | public init(stringLiteral value: StringLiteralType) { 25 | name = value 26 | path = value 27 | } 28 | 29 | public init(_ keyPath: PartialKeyPath & Expressible, as asName: String? = nil) { 30 | path = keyPath.optionalPropertyName! 31 | name = asName ?? path 32 | } 33 | 34 | public init(_ keyPath: String, as asName: String? = nil) { 35 | name = asName ?? keyPath 36 | path = keyPath 37 | } 38 | 39 | public func getHashValue() -> Int { 40 | expression.hashValue 41 | } 42 | 43 | public func asExpression() -> Any { 44 | expression 45 | } 46 | 47 | public func `as`(name: String) -> Self { 48 | self.name = name 49 | return self 50 | } 51 | 52 | private func resolveResultType(from path: String) -> NSAttributeType { 53 | var desc = Entity.entity() 54 | 55 | for component in path.split(separator: ".") { 56 | let property = desc.propertiesByName[String(component)] 57 | 58 | switch property { 59 | case let attribute as NSAttributeDescription: 60 | return attribute.attributeType 61 | case let relation as NSRelationshipDescription: 62 | desc = relation.destinationEntity! 63 | continue 64 | default: 65 | break 66 | } 67 | } 68 | 69 | return .undefinedAttributeType 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /docs/data/documentation/crush/adhocmigrationerror/error-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/adhocmigrationerror\/error-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError\/Error-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError\/localizedDescription"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Error Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/AdHocMigrationError":{"role":"symbol","title":"AdHocMigrationError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"AdHocMigrationError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"AdHocMigrationError"}],"url":"\/documentation\/crush\/adhocmigrationerror"},"doc://Crush/documentation/Crush/AdHocMigrationError/localizedDescription":{"role":"symbol","title":"localizedDescription","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"localizedDescription"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError\/localizedDescription","kind":"symbol","type":"topic","url":"\/documentation\/crush\/adhocmigrationerror\/localizeddescription"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/mutableset/init().json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"required"},{"kind":"text","text":" "},{"kind":"keyword","text":"init"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/mutableset\/init()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MutableSet\/init()","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Inherited from "},{"type":"codeVoice","code":"SetAlgebra.init()"},{"type":"text","text":"."}],"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"title":"init()","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:5Crush10MutableSetCACyxGycfc","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MutableSet"]]},"references":{"doc://Crush/documentation/Crush/MutableSet/init()":{"role":"symbol","title":"init()","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MutableSet\/init()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/mutableset\/init()"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/MutableSet":{"role":"symbol","title":"MutableSet","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"MutableSet"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MutableSet","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MutableSet"}],"url":"\/documentation\/crush\/mutableset"}}} -------------------------------------------------------------------------------- /Sources/Crush.docc/PropertyModifier.md: -------------------------------------------------------------------------------- 1 | # Property Modifier 2 | 3 | Crush provides multiple ways to modify the properties of an entity. This helps you separate concerns and configure a property by composition. 4 | 5 | ## Overview 6 | 7 | In Crush, declaring properties is straightforward. You can define a property using the following syntax: 8 | 9 | ``` swift 10 | let property = Value.Int16("property") 11 | ``` 12 | 13 | By default, properties are declared without requiring extensive configuration. However, if you need to fine-tune the behavior of a property, you can achieve this through the use of property modifiers. 14 | 15 | ### Using Property Modifiers 16 | 17 | Property modifiers allow you to apply specific configurations to your properties. For instance, consider a scenario where you want to adjust the behavior of a property to make it optional and also mark it for indexing. You can achieve this using property modifiers. 18 | 19 | Here's an example of declaring a property with property modifiers: 20 | 21 | ``` swift 22 | @Indexed 23 | @Optional 24 | var property = Value.Int16("property") 25 | ``` 26 | 27 | In this example, the `@Indexed` modifier indicates that the property should be indexed, which can improve query performance. The `@Optional` modifier specifies that the property is optional, meaning it does not need to have a value. 28 | 29 | By utilizing property modifiers, you can easily tailor the behavior of your properties to suit your specific needs, ensuring flexibility and efficiency in your codebase. 30 | 31 | ### General Modifers 32 | 33 | - ``Optional`` 34 | - ``Required`` 35 | - ``Transient`` 36 | - ``Indexed`` 37 | - ``IndexedBySpotlight`` 38 | - ``Unique`` 39 | 40 | ### Attribute Modifiers 41 | 42 | - ``Default`` 43 | - ``ExternalBinaryDataStorage`` 44 | - ``Validation`` 45 | - ``PreservesValueInHistoryOnDeletion`` 46 | 47 | ### Relationship Modifiers 48 | 49 | - ``Inverse`` 50 | - ``MaxCount`` 51 | - ``MinCount`` 52 | - ``DeleteRule`` 53 | - ``UnidirectionalInverse`` 54 | 55 | > Tips: You can access all modifiers using ``PropertyModifiers``, ``AttributeModifiers``, and ``RelationshipModifiers`` 56 | -------------------------------------------------------------------------------- /docs/data/documentation/crush/entitytypedescriptor/init().json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"required"},{"kind":"text","text":" "},{"kind":"keyword","text":"init"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/entitytypedescriptor\/init()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EntityTypeDescriptor\/init()","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"title":"init()","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:5Crush20EntityTypeDescriptorCACyxGycfc","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/EntityTypeDescriptor"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/EntityTypeDescriptor/init()":{"role":"symbol","title":"init()","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityTypeDescriptor\/init()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entitytypedescriptor\/init()"},"doc://Crush/documentation/Crush/EntityTypeDescriptor":{"role":"symbol","title":"EntityTypeDescriptor","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityTypeDescriptor"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityTypeDescriptor","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EntityTypeDescriptor"}],"url":"\/documentation\/crush\/entitytypedescriptor"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/objectdriver/hashable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/objectdriver\/hashable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/Hashable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/hash(into:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Hashable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/ObjectDriver"]]},"references":{"doc://Crush/documentation/Crush/ObjectDriver/hash(into:)":{"role":"symbol","title":"hash(into:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"hash"},{"kind":"text","text":"("},{"kind":"externalParam","text":"into"},{"kind":"text","text":": "},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"Hasher","preciseIdentifier":"s:s6HasherV"},{"kind":"text","text":")"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/hash(into:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/objectdriver\/hash(into:)"},"doc://Crush/documentation/Crush/ObjectDriver":{"role":"symbol","title":"ObjectDriver","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"ObjectDriver"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ObjectDriver"}],"url":"\/documentation\/crush\/objectdriver"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /Tests/DataStructureTests/LazyMapMutableSetTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LazyMapMutableSetTests.swift 3 | // 4 | // 5 | // Created by EZOU on 2023/9/1. 6 | // 7 | 8 | import XCTest 9 | 10 | @testable import Crush 11 | 12 | class LazyMapMutableSetTests: XCTestCase { 13 | 14 | func test_add_shouldMapAddedObject() { 15 | let mutableSet = NSMutableSet() 16 | let sut = LazyMapMutableSet.from(mutableSet) { 17 | "\($0)" 18 | } to: { 19 | Int($0)! 20 | } 21 | sut.add("0") 22 | XCTAssertTrue(mutableSet.contains(0)) 23 | } 24 | 25 | func test_remove_shouldMapRemovedObject() { 26 | let mutableSet = NSMutableSet(array: [0]) 27 | let sut = LazyMapMutableSet.from(mutableSet) { 28 | "\($0)" 29 | } to: { 30 | Int($0)! 31 | } 32 | sut.remove("0") 33 | XCTAssertEqual(mutableSet.count, 0) 34 | } 35 | 36 | func test_count_shouldEqualToUnderlyingSet() { 37 | let mutableSet = NSMutableSet(array: [0]) 38 | let sut = LazyMapMutableSet.from(mutableSet) { 39 | "\($0)" 40 | } to: { 41 | Int($0)! 42 | } 43 | XCTAssertEqual(mutableSet.count, sut.count) 44 | } 45 | 46 | func test_objectEnumerator_shouldIterateAllMappedObjects() { 47 | let mutableSet = NSMutableSet(array: [0]) 48 | let sut = LazyMapMutableSet.from(mutableSet) { 49 | "\($0)" 50 | } to: { 51 | Int($0)! 52 | } 53 | let array = sut.objectEnumerator().allObjects as? [String] 54 | XCTAssertEqual(["0"], array) 55 | } 56 | 57 | func test_mutableCopy_oldInstanceShouldRemainUnchanged() { 58 | let mutableSet = NSMutableSet(array: [0]) 59 | let sut = LazyMapMutableSet.from(mutableSet) { 60 | "\($0)" 61 | } to: { 62 | Int($0)! 63 | } 64 | let result = sut.mutableCopy() as! NSMutableSet 65 | result.add("1") 66 | XCTAssertFalse(sut.contains("1")) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /docs/data/documentation/crush/mutableset/equatable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/mutableset\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MutableSet\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/MutableSet\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MutableSet"]]},"references":{"doc://Crush/documentation/Crush/MutableSet":{"role":"symbol","title":"MutableSet","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"MutableSet"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MutableSet","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MutableSet"}],"url":"\/documentation\/crush\/mutableset"},"doc://Crush/documentation/Crush/MutableSet/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MutableSet\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/mutableset\/!=(_:_:)"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/orderedset/equatable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/orderedset\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/OrderedSet\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/OrderedSet\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/OrderedSet"]]},"references":{"doc://Crush/documentation/Crush/OrderedSet/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/OrderedSet\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/orderedset\/!=(_:_:)"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/OrderedSet":{"role":"symbol","title":"OrderedSet","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"OrderedSet"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/OrderedSet","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"OrderedSet"}],"url":"\/documentation\/crush\/orderedset"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/entity/readaleobject-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/entity\/readaleobject-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Entity\/ReadaleObject-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Type Aliases","identifiers":["doc:\/\/Crush\/documentation\/Crush\/Entity\/ReadOnly"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"ReadaleObject Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/Entity"]]},"references":{"doc://Crush/documentation/Crush/Entity/ReadOnly":{"conformance":{"constraints":[{"type":"codeVoice","code":"Self"},{"type":"text","text":" inherits "},{"type":"codeVoice","code":"Entity"},{"type":"text","text":"."}],"availabilityPrefix":[{"type":"text","text":"Available when"}],"conformancePrefix":[{"type":"text","text":"Conforms when"}]},"role":"symbol","title":"Entity.ReadOnly","fragments":[{"kind":"keyword","text":"typealias"},{"kind":"text","text":" "},{"kind":"identifier","text":"ReadOnly"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Entity\/ReadOnly","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ReadOnly"}],"url":"\/documentation\/crush\/entity\/readonly"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/Entity":{"role":"symbol","title":"Entity","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Entity"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Entity","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Entity"}],"url":"\/documentation\/crush\/entity"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/migrationmodelingerror/error-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/migrationmodelingerror\/error-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MigrationModelingError\/Error-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/MigrationModelingError\/localizedDescription"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Error Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MigrationModelingError"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/MigrationModelingError":{"role":"symbol","title":"MigrationModelingError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"MigrationModelingError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationModelingError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MigrationModelingError"}],"url":"\/documentation\/crush\/migrationmodelingerror"},"doc://Crush/documentation/Crush/MigrationModelingError/localizedDescription":{"role":"symbol","title":"localizedDescription","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"localizedDescription"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationModelingError\/localizedDescription","kind":"symbol","type":"topic","url":"\/documentation\/crush\/migrationmodelingerror\/localizeddescription"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/configuration/init().json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"required"},{"kind":"text","text":" "},{"kind":"keyword","text":"init"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/configuration\/init()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Configuration\/init()","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"title":"init()","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:5Crush13ConfigurationCACyxGycfc","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/Configuration"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/Configuration":{"role":"symbol","title":"Configuration","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Configuration"}],"abstract":[{"type":"text","text":"Assign "},{"type":"codeVoice","code":"T"},{"type":"text","text":" entity to specified configuration group"}],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Configuration","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Configuration"}],"url":"\/documentation\/crush\/configuration"},"doc://Crush/documentation/Crush/Configuration/init()":{"role":"symbol","title":"init()","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Configuration\/init()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/configuration\/init()"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/migrationerror/notmigrated.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"notMigrated"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/migrationerror\/notmigrated"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MigrationError\/notMigrated","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"notMigrated"}],"title":"MigrationError.notMigrated","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush14MigrationErrorO11notMigratedyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MigrationError"]]},"references":{"doc://Crush/documentation/Crush/MigrationError/notMigrated":{"role":"symbol","title":"MigrationError.notMigrated","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"notMigrated"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationError\/notMigrated","kind":"symbol","type":"topic","url":"\/documentation\/crush\/migrationerror\/notmigrated"},"doc://Crush/documentation/Crush/MigrationError":{"role":"symbol","title":"MigrationError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"MigrationError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MigrationError"}],"url":"\/documentation\/crush\/migrationerror"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/fetchsorteroption/default.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"`default`"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/fetchsorteroption\/default"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/default","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"`default`"}],"title":"FetchSorterOption.default","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush17FetchSorterOptionO7defaultyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption"]]},"references":{"doc://Crush/documentation/Crush/FetchSorterOption":{"role":"symbol","title":"FetchSorterOption","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"FetchSorterOption"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"FetchSorterOption"}],"url":"\/documentation\/crush\/fetchsorteroption"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/FetchSorterOption/default":{"role":"symbol","title":"FetchSorterOption.default","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"`default`"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/default","kind":"symbol","type":"topic","url":"\/documentation\/crush\/fetchsorteroption\/default"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/objectdriver/equatable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/objectdriver\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/==(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/ObjectDriver"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/ObjectDriver":{"role":"symbol","title":"ObjectDriver","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"ObjectDriver"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ObjectDriver"}],"url":"\/documentation\/crush\/objectdriver"},"doc://Crush/documentation/Crush/ObjectDriver/==(_:_:)":{"role":"symbol","title":"==(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"=="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ObjectDriver\/==(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/objectdriver\/==(_:_:)"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/searchstring/equatable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/searchstring\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/SearchString\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/SearchString\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/SearchString"]]},"references":{"doc://Crush/documentation/Crush/SearchString":{"role":"symbol","title":"SearchString","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"SearchString"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/SearchString","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"SearchString"}],"url":"\/documentation\/crush\/searchstring"},"doc://Crush/documentation/Crush/SearchString/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/SearchString\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/searchstring\/!=(_:_:)"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/entityabstraction/concrete.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"concrete"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/entityabstraction\/concrete"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction\/concrete","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"concrete"}],"title":"EntityAbstraction.concrete","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush17EntityAbstractionO8concreteyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction"]]},"references":{"doc://Crush/documentation/Crush/EntityAbstraction/concrete":{"role":"symbol","title":"EntityAbstraction.concrete","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"concrete"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction\/concrete","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entityabstraction\/concrete"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/EntityAbstraction":{"role":"symbol","title":"EntityAbstraction","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityAbstraction"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EntityAbstraction"}],"url":"\/documentation\/crush\/entityabstraction"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/migrationerror/incompatible.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"incompatible"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/migrationerror\/incompatible"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MigrationError\/incompatible","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"incompatible"}],"title":"MigrationError.incompatible","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush14MigrationErrorO12incompatibleyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MigrationError"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/MigrationError":{"role":"symbol","title":"MigrationError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"MigrationError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MigrationError"}],"url":"\/documentation\/crush\/migrationerror"},"doc://Crush/documentation/Crush/MigrationError/incompatible":{"role":"symbol","title":"MigrationError.incompatible","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"incompatible"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationError\/incompatible","kind":"symbol","type":"topic","url":"\/documentation\/crush\/migrationerror\/incompatible"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/storageoption/equatable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/storageoption\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/StorageOption\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/StorageOption\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/StorageOption"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/StorageOption":{"role":"symbol","title":"StorageOption","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"StorageOption"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/StorageOption","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"StorageOption"}],"url":"\/documentation\/crush\/storageoption"},"doc://Crush/documentation/Crush/StorageOption/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/StorageOption\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/storageoption\/!=(_:_:)"}}} -------------------------------------------------------------------------------- /Sources/Crush.docc/IntroducingSession.md: -------------------------------------------------------------------------------- 1 | # Introducing Session 2 | 3 | This article explains what a `Crush/Session` is and how to use it. 4 | 5 | ## What is Session? 6 | 7 | A ``Session`` is a lightweight object that represents a single unit of work with the database. It provides a collection of methods that allow you to create, fetch, and delete objects in the database. More importantly, it manages the lifecycle of the `NSManagedObjectContext` and ensures that all data mutations are thread-safe. 8 | 9 | ### Structure of a Session 10 | 11 | A session is composed of three `NSManagedObjectContext`s, each with a different purpose: 12 | 13 | - **Execution context**: This context is responsible for performing data mutations. 14 | - **UI context**: This context is responsible for presenting data on the main thread. 15 | 16 | By separating the execution context and the UI context, we can ensure that the main thread is free from direct communication with the database. This separation of concerns allows for a smoother user experience and helps prevent issues such as UI lag or freezes. 17 | 18 | You don't need to worry about the lifecycle of these contexts. The ``Session`` will automatically create and dispose of them for you, and also, data mutation methods are exposed through ``SessionContext`` APIs. The only decision to make is whether to execute these commands synchronously or asynchronously. 19 | 20 | ### Data isolation 21 | 22 | Each ``Session`` is isolated from other ``Session``s. This means that changes made in one session will not be visible to other sessions until they are committed. This allows you to perform multiple operations in parallel without worrying about data conflicts. However, you still need to be aware of data conflicts between different ``Session``s and make sure they are handled properly by the merge policy or error handler. 23 | 24 | ## How to use Session 25 | 26 | Using ``Session``, you can easily perform CRUD operations on the database: 27 | 28 | ```swift 29 | let session = try dataContainer.startSession() 30 | try session.sync { context in 31 | let todo = try context.create(Todo.self) 32 | todo.title = "Hello world!" 33 | try context.commit() 34 | } 35 | ``` 36 | 37 | -------------------------------------------------------------------------------- /docs/data/documentation/crush/fetchsorteroption/localized.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"localized"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/fetchsorteroption\/localized"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/localized","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"localized"}],"title":"FetchSorterOption.localized","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush17FetchSorterOptionO9localizedyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/FetchSorterOption":{"role":"symbol","title":"FetchSorterOption","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"FetchSorterOption"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"FetchSorterOption"}],"url":"\/documentation\/crush\/fetchsorteroption"},"doc://Crush/documentation/Crush/FetchSorterOption/localized":{"role":"symbol","title":"FetchSorterOption.localized","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"localized"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/localized","kind":"symbol","type":"topic","url":"\/documentation\/crush\/fetchsorteroption\/localized"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/adhocmigration/equatable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/adhocmigration\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigration\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/AdHocMigration\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/AdHocMigration"]]},"references":{"doc://Crush/documentation/Crush/AdHocMigration/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigration\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/adhocmigration\/!=(_:_:)"},"doc://Crush/documentation/Crush/AdHocMigration":{"role":"symbol","title":"AdHocMigration","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"AdHocMigration"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigration","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"AdHocMigration"}],"url":"\/documentation\/crush\/adhocmigration"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/migrationerror/equatable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/migrationerror\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MigrationError\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/MigrationError\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MigrationError"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/MigrationError/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationError\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/migrationerror\/!=(_:_:)"},"doc://Crush/documentation/Crush/MigrationError":{"role":"symbol","title":"MigrationError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"MigrationError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MigrationError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MigrationError"}],"url":"\/documentation\/crush\/migrationerror"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/requestexecutor/received.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"Received"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/requestexecutor\/received"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/RequestExecutor\/Received","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"role":"symbol","title":"Received","roleHeading":"Associated Type","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"Received"}],"symbolKind":"associatedtype","externalID":"s:5Crush15RequestExecutorP8ReceivedQa","required":true,"modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/RequestExecutor"]]},"references":{"doc://Crush/documentation/Crush/RequestExecutor":{"role":"symbol","title":"RequestExecutor","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"RequestExecutor"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/RequestExecutor","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"RequestExecutor"}],"url":"\/documentation\/crush\/requestexecutor"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/RequestExecutor/Received":{"role":"symbol","title":"Received","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"Received"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/RequestExecutor\/Received","kind":"symbol","required":true,"type":"topic","url":"\/documentation\/crush\/requestexecutor\/received"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/entityinheritance/multitable.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"multiTable"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/entityinheritance\/multitable"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance\/multiTable","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"multiTable"}],"title":"EntityInheritance.multiTable","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush17EntityInheritanceO10multiTableyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/EntityInheritance"]]},"references":{"doc://Crush/documentation/Crush/EntityInheritance":{"role":"symbol","title":"EntityInheritance","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityInheritance"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EntityInheritance"}],"url":"\/documentation\/crush\/entityinheritance"},"doc://Crush/documentation/Crush/EntityInheritance/multiTable":{"role":"symbol","title":"EntityInheritance.multiTable","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"multiTable"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance\/multiTable","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entityinheritance\/multitable"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/propertytype/managedvalue.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"ManagedValue"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/propertytype\/managedvalue"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/PropertyType\/ManagedValue","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"role":"symbol","title":"ManagedValue","roleHeading":"Associated Type","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"ManagedValue"}],"symbolKind":"associatedtype","externalID":"s:5Crush12PropertyTypeP12ManagedValueQa","required":true,"modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/PropertyType"]]},"references":{"doc://Crush/documentation/Crush/PropertyType/ManagedValue":{"role":"symbol","title":"ManagedValue","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"ManagedValue"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/PropertyType\/ManagedValue","kind":"symbol","required":true,"type":"topic","url":"\/documentation\/crush\/propertytype\/managedvalue"},"doc://Crush/documentation/Crush/PropertyType":{"role":"symbol","title":"PropertyType","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"PropertyType"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/PropertyType","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"PropertyType"}],"url":"\/documentation\/crush\/propertytype"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/propertytype/runtimevalue.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"RuntimeValue"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/propertytype\/runtimevalue"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/PropertyType\/RuntimeValue","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"role":"symbol","title":"RuntimeValue","roleHeading":"Associated Type","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"RuntimeValue"}],"symbolKind":"associatedtype","externalID":"s:5Crush12PropertyTypeP12RuntimeValueQa","required":true,"modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/PropertyType"]]},"references":{"doc://Crush/documentation/Crush/PropertyType/RuntimeValue":{"role":"symbol","title":"RuntimeValue","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"RuntimeValue"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/PropertyType\/RuntimeValue","kind":"symbol","required":true,"type":"topic","url":"\/documentation\/crush\/propertytype\/runtimevalue"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/PropertyType":{"role":"symbol","title":"PropertyType","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"PropertyType"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/PropertyType","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"PropertyType"}],"url":"\/documentation\/crush\/propertytype"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/updateattribute/updatepropertymigration-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/updateattribute\/updatepropertymigration-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute\/UpdatePropertyMigration-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute\/versionHashModifier(_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"UpdatePropertyMigration Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute"]]},"references":{"doc://Crush/documentation/Crush/UpdateAttribute/versionHashModifier(_:)":{"role":"symbol","title":"versionHashModifier(_:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"versionHashModifier"},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"},{"kind":"text","text":"?) -> "},{"kind":"typeIdentifier","text":"Self"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute\/versionHashModifier(_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/updateattribute\/versionhashmodifier(_:)"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/UpdateAttribute":{"role":"symbol","title":"UpdateAttribute","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"UpdateAttribute"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"UpdateAttribute"}],"url":"\/documentation\/crush\/updateattribute"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/entityinheritance/singletable.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"singleTable"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/entityinheritance\/singletable"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance\/singleTable","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"singleTable"}],"title":"EntityInheritance.singleTable","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush17EntityInheritanceO11singleTableyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/EntityInheritance"]]},"references":{"doc://Crush/documentation/Crush/EntityInheritance/singleTable":{"role":"symbol","title":"EntityInheritance.singleTable","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"singleTable"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance\/singleTable","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entityinheritance\/singletable"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/EntityInheritance":{"role":"symbol","title":"EntityInheritance","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityInheritance"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EntityInheritance"}],"url":"\/documentation\/crush\/entityinheritance"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/primarykey/equatable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/primarykey\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/PrimaryKey\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/PrimaryKey\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/PrimaryKey"]]},"references":{"doc://Crush/documentation/Crush/PrimaryKey":{"role":"symbol","title":"PrimaryKey","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"PrimaryKey"}],"abstract":[{"type":"text","text":"Represents a primary key for an entity in Core Data."}],"identifier":"doc:\/\/Crush\/documentation\/Crush\/PrimaryKey","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"PrimaryKey"}],"url":"\/documentation\/crush\/primarykey"},"doc://Crush/documentation/Crush/PrimaryKey/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/PrimaryKey\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/primarykey\/!=(_:_:)"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/session/undo().json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"undo"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/session\/undo()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Session\/undo()","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Undoes the last change made to the session."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"undo"},{"kind":"text","text":"()"}],"title":"undo()","roleHeading":"Instance Method","role":"symbol","symbolKind":"method","externalID":"s:5Crush7SessionC4undoyyF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/Session"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/Session/undo()":{"role":"symbol","title":"undo()","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"undo"},{"kind":"text","text":"()"}],"abstract":[{"type":"text","text":"Undoes the last change made to the session."}],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Session\/undo()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/session\/undo()"},"doc://Crush/documentation/Crush/Session":{"role":"symbol","title":"Session","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Session"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Session","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Session"}],"url":"\/documentation\/crush\/session"}}} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Crush 2 | 3 | Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality 4 | 5 | ## Overview 6 | 7 | 🕹️ Take full control of your CoreData management.
8 | 🧑‍💻 100% managed code, no code generation required.
9 | 📖 Free from Xcode GUI, and human-friendly diff records on git. 10 | 11 | ### Installation 12 | 13 | Make sure you've declared `Crush` as your dependency before getting started 14 | 15 | ```swift 16 | let package = Package( 17 | dependencies: [ 18 | .package( 19 | url: "https://github.com/ezoushen/Crush", 20 | from: "TARGET_VERSION" 21 | ), 22 | ], 23 | targets: [ 24 | .target( 25 | name: "", 26 | dependencies: [ 27 | "Crush" 28 | ] 29 | ) 30 | ] 31 | ) 32 | ``` 33 | 34 | ## Usage 35 | 36 | Only three steps to start using Crush 37 | 38 | **1. Define your schema** 39 | 40 | ```swift 41 | class Todo: Entity { 42 | @Required 43 | var title = Value.String("title") // A required string property named "title" 44 | 45 | @Optional 46 | var memo = Value.String("memo") // An optional string property named "memo" 47 | 48 | @Required 49 | @Default(false) 50 | var finished = Value.Bool("finished") 51 | 52 | @Optional 53 | var parent = Relation.ToOne("parent") // An optional relationship to another Todo 54 | 55 | @Optional 56 | @Inverse(\.parent) 57 | var children = Relation.ToMany("children") 58 | } 59 | ``` 60 | 61 | **2. Create your DataContainer** 62 | 63 | ```swift 64 | let container = try DataContainer.load( 65 | storages: .sqlite(url: targetURL), 66 | dataModel: DataModel(name: "V1", [ Todo() ])) 67 | ``` 68 | 69 | **3. Start coding 🔥🔥🔥** 70 | 71 | ```swift 72 | try container.startSession().sync { context in 73 | let todo = context.create(Todo.self) 74 | todo.title = "Hello Crush" 75 | try context.commit() 76 | } 77 | ``` 78 | 79 | ## Documentation 80 | 81 | Swift DocC style documentation is available [here](https://ezoushen.github.io/Crush/documentation/crush) 82 | 83 | ## Coorporation 84 | 85 | If you want to contribute to the project, please feel free to open a pull request/issue. 86 | -------------------------------------------------------------------------------- /docs/data/documentation/crush/mutableorderedset/init().json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"required"},{"kind":"text","text":" "},{"kind":"keyword","text":"init"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/mutableorderedset\/init()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet\/init()","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Inherited from "},{"type":"codeVoice","code":"RangeReplaceableCollection.init()"},{"type":"text","text":"."}],"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"title":"init()","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:5Crush17MutableOrderedSetCACyxGycfc","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet"]]},"references":{"doc://Crush/documentation/Crush/MutableOrderedSet/init()":{"role":"symbol","title":"init()","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"()"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet\/init()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/mutableorderedset\/init()"},"doc://Crush/documentation/Crush/MutableOrderedSet":{"role":"symbol","title":"MutableOrderedSet","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"MutableOrderedSet"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MutableOrderedSet"}],"url":"\/documentation\/crush\/mutableorderedset"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/propertytype/predicatevalue.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"PredicateValue"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/propertytype\/predicatevalue"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/PropertyType\/PredicateValue","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"role":"symbol","title":"PredicateValue","roleHeading":"Associated Type","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"PredicateValue"}],"symbolKind":"associatedtype","externalID":"s:5Crush12PropertyTypeP14PredicateValueQa","required":true,"modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/PropertyType"]]},"references":{"doc://Crush/documentation/Crush/PropertyType":{"role":"symbol","title":"PropertyType","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"PropertyType"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/PropertyType","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"PropertyType"}],"url":"\/documentation\/crush\/propertytype"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/PropertyType/PredicateValue":{"role":"symbol","title":"PredicateValue","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"PredicateValue"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/PropertyType\/PredicateValue","kind":"symbol","required":true,"type":"topic","url":"\/documentation\/crush\/propertytype\/predicatevalue"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/unsafesessionproperty/safe.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"Safe"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/unsafesessionproperty\/safe"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/UnsafeSessionProperty\/Safe","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"role":"symbol","title":"Safe","roleHeading":"Associated Type","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"Safe"}],"symbolKind":"associatedtype","externalID":"s:5Crush21UnsafeSessionPropertyP4SafeQa","required":true,"modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/UnsafeSessionProperty"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/UnsafeSessionProperty":{"role":"symbol","title":"UnsafeSessionProperty","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"UnsafeSessionProperty"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UnsafeSessionProperty","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"UnsafeSessionProperty"}],"url":"\/documentation\/crush\/unsafesessionproperty"},"doc://Crush/documentation/Crush/UnsafeSessionProperty/Safe":{"role":"symbol","title":"Safe","fragments":[{"kind":"keyword","text":"associatedtype"},{"kind":"text","text":" "},{"kind":"identifier","text":"Safe"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UnsafeSessionProperty\/Safe","kind":"symbol","required":true,"type":"topic","url":"\/documentation\/crush\/unsafesessionproperty\/safe"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/entityabstraction/equatable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/entityabstraction\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction"]]},"references":{"doc://Crush/documentation/Crush/EntityAbstraction/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entityabstraction\/!=(_:_:)"},"doc://Crush/documentation/Crush/EntityAbstraction":{"role":"symbol","title":"EntityAbstraction","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityAbstraction"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityAbstraction","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EntityAbstraction"}],"url":"\/documentation\/crush\/entityabstraction"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/entityinheritance/equatable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/entityinheritance\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/EntityInheritance\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/EntityInheritance"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/EntityInheritance/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/entityinheritance\/!=(_:_:)"},"doc://Crush/documentation/Crush/EntityInheritance":{"role":"symbol","title":"EntityInheritance","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityInheritance"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityInheritance","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EntityInheritance"}],"url":"\/documentation\/crush\/entityinheritance"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/fetchsorteroption/equatable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/fetchsorteroption\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption"]]},"references":{"doc://Crush/documentation/Crush/FetchSorterOption":{"role":"symbol","title":"FetchSorterOption","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"FetchSorterOption"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"FetchSorterOption"}],"url":"\/documentation\/crush\/fetchsorteroption"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/FetchSorterOption/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/fetchsorteroption\/!=(_:_:)"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/mutableorderedset/equatable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/mutableorderedset\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet"]]},"references":{"doc://Crush/documentation/Crush/MutableOrderedSet/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/mutableorderedset\/!=(_:_:)"},"doc://Crush/documentation/Crush/MutableOrderedSet":{"role":"symbol","title":"MutableOrderedSet","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"MutableOrderedSet"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/MutableOrderedSet","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"MutableOrderedSet"}],"url":"\/documentation\/crush\/mutableorderedset"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/session/redo().json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"redo"},{"kind":"text","text":"()"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/session\/redo()"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Session\/redo()","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Redoes the last change that was undone in the session."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"redo"},{"kind":"text","text":"()"}],"title":"redo()","roleHeading":"Instance Method","role":"symbol","symbolKind":"method","externalID":"s:5Crush7SessionC4redoyyF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/Session"]]},"references":{"doc://Crush/documentation/Crush/Session":{"role":"symbol","title":"Session","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Session"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Session","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Session"}],"url":"\/documentation\/crush\/session"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/Session/redo()":{"role":"symbol","title":"redo()","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"redo"},{"kind":"text","text":"()"}],"abstract":[{"type":"text","text":"Redoes the last change that was undone in the session."}],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Session\/redo()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/session\/redo()"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/codableattributetype/hashable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/codableattributetype\/hashable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/CodableAttributeType\/Hashable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/CodableAttributeType\/hash(into:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Hashable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/CodableAttributeType"]]},"references":{"doc://Crush/documentation/Crush/CodableAttributeType/hash(into:)":{"role":"symbol","title":"hash(into:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"hash"},{"kind":"text","text":"("},{"kind":"externalParam","text":"into"},{"kind":"text","text":": "},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"Hasher","preciseIdentifier":"s:s6HasherV"},{"kind":"text","text":")"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/CodableAttributeType\/hash(into:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/codableattributetype\/hash(into:)"},"doc://Crush/documentation/Crush/CodableAttributeType":{"role":"symbol","title":"CodableAttributeType","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"CodableAttributeType"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/CodableAttributeType","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"CodableAttributeType"}],"url":"\/documentation\/crush\/codableattributetype"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/datacontainererror/equatable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/datacontainererror\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/DataContainerError\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/DataContainerError\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/DataContainerError"]]},"references":{"doc://Crush/documentation/Crush/DataContainerError":{"role":"symbol","title":"DataContainerError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"DataContainerError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/DataContainerError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"DataContainerError"}],"url":"\/documentation\/crush\/datacontainererror"},"doc://Crush/documentation/Crush/DataContainerError/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/DataContainerError\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/datacontainererror\/!=(_:_:)"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/entitymigrationcallback.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"typealias"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityMigrationCallback"},{"kind":"text","text":" = (["},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"},{"kind":"text","text":" : "},{"kind":"typeIdentifier","text":"NSEntityDescription","preciseIdentifier":"c:objc(cs)NSEntityDescription"},{"kind":"text","text":"]) "},{"kind":"keyword","text":"throws"},{"kind":"text","text":" -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/entitymigrationcallback"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EntityMigrationCallback","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"typealias"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityMigrationCallback"}],"title":"EntityMigrationCallback","roleHeading":"Type Alias","role":"symbol","symbolKind":"typealias","externalID":"s:5Crush23EntityMigrationCallbacka","modules":[{"name":"Crush"}],"navigatorTitle":[{"kind":"identifier","text":"EntityMigrationCallback"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/EntityMigrationCallback":{"role":"symbol","title":"EntityMigrationCallback","fragments":[{"kind":"keyword","text":"typealias"},{"kind":"text","text":" "},{"kind":"identifier","text":"EntityMigrationCallback"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EntityMigrationCallback","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EntityMigrationCallback"}],"url":"\/documentation\/crush\/entitymigrationcallback"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/updaterelationship/updatepropertymigration-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/updaterelationship\/updatepropertymigration-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/UpdateRelationship\/UpdatePropertyMigration-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/UpdateRelationship\/versionHashModifier(_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"UpdatePropertyMigration Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/UpdateRelationship"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/UpdateRelationship/versionHashModifier(_:)":{"role":"symbol","title":"versionHashModifier(_:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"versionHashModifier"},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"},{"kind":"text","text":"?) -> "},{"kind":"typeIdentifier","text":"Self"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UpdateRelationship\/versionHashModifier(_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/updaterelationship\/versionhashmodifier(_:)"},"doc://Crush/documentation/Crush/UpdateRelationship":{"role":"symbol","title":"UpdateRelationship","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"UpdateRelationship"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UpdateRelationship","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"UpdateRelationship"}],"url":"\/documentation\/crush\/updaterelationship"}}} -------------------------------------------------------------------------------- /Assertions/Assertions.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// drop-in replacements 4 | #if DEBUG 5 | func assert(_ condition: @autoclosure () -> Bool,_ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) { 6 | Assertions.assertClosure(condition(), message(), file, line) 7 | } 8 | 9 | func assertionFailure(_ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) { 10 | Assertions.assertionFailureClosure(message(), file, line) 11 | } 12 | 13 | func precondition(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) { 14 | Assertions.preconditionClosure(condition(), message(), file, line) 15 | } 16 | 17 | func preconditionFailure(_ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) -> Never { 18 | Assertions.preconditionFailureClosure(message(), file, line) 19 | } 20 | 21 | func fatalError(_ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) -> Never { 22 | Assertions.fatalErrorClosure(message(), file, line) 23 | } 24 | 25 | /// Stores custom assertions closures, by default it points to Swift functions. But test target can override them. 26 | public class Assertions { 27 | 28 | public static var assertClosure = swiftAssertClosure 29 | public static var assertionFailureClosure = swiftAssertionFailureClosure 30 | public static var preconditionClosure = swiftPreconditionClosure 31 | public static var preconditionFailureClosure = swiftPreconditionFailureClosure 32 | public static var fatalErrorClosure = swiftFatalErrorClosure 33 | 34 | public static let swiftAssertClosure = { Swift.assert($0, $1, file: $2, line: $3) } 35 | public static let swiftAssertionFailureClosure = { Swift.assertionFailure($0, file: $1, line: $2) } 36 | public static let swiftPreconditionClosure = { Swift.precondition($0, $1, file: $2, line: $3) } 37 | public static let swiftPreconditionFailureClosure = { Swift.preconditionFailure($0, file: $1, line: $2) } 38 | public static let swiftFatalErrorClosure = { Swift.fatalError($0, file: $1, line: $2) } 39 | } 40 | #endif 41 | -------------------------------------------------------------------------------- /Tests/Utils/Publishers+helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Publisher+helper.swift 3 | // 4 | // 5 | // Created by ezou on 2022/1/29. 6 | // 7 | 8 | #if canImport(Combine) 9 | import Combine 10 | import XCTest 11 | 12 | // Reference: https://www.swiftbysundell.com/articles/unit-testing-combine-based-swift-code/ 13 | @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) 14 | extension XCTestCase { 15 | func awaitPublisher( 16 | _ publisher: T, 17 | timeout: TimeInterval = 1, 18 | file: StaticString = #file, 19 | line: UInt = #line, 20 | completion: () throws -> Void = { } 21 | ) throws -> T.Output { 22 | // This time, we use Swift's Result type to keep track 23 | // of the result of our Combine pipeline: 24 | var result: Result? 25 | let expectation = self.expectation(description: "Awaiting publisher") 26 | 27 | let cancellable = publisher.sink( 28 | receiveCompletion: { completion in 29 | switch completion { 30 | case .failure(let error): 31 | result = .failure(error) 32 | case .finished: 33 | break 34 | } 35 | 36 | expectation.fulfill() 37 | }, 38 | receiveValue: { value in 39 | result = .success(value) 40 | } 41 | ) 42 | 43 | try completion() 44 | 45 | // Just like before, we await the expectation that we 46 | // created at the top of our test, and once done, we 47 | // also cancel our cancellable to avoid getting any 48 | // unused variable warnings: 49 | waitForExpectations(timeout: timeout) 50 | cancellable.cancel() 51 | 52 | // Here we pass the original file and line number that 53 | // our utility was called at, to tell XCTest to report 54 | // any encountered errors at that original call site: 55 | let unwrappedResult = try XCTUnwrap( 56 | result, 57 | "Awaited publisher did not produce any output", 58 | file: file, 59 | line: line 60 | ) 61 | 62 | return try unwrappedResult.get() 63 | } 64 | } 65 | #endif 66 | -------------------------------------------------------------------------------- /docs/data/documentation/crush/fetchsorteroption/caseinsensitive.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"caseInsensitive"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/fetchsorteroption\/caseinsensitive"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/caseInsensitive","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"caseInsensitive"}],"title":"FetchSorterOption.caseInsensitive","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush17FetchSorterOptionO15caseInsensitiveyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption"]]},"references":{"doc://Crush/documentation/Crush/FetchSorterOption/caseInsensitive":{"role":"symbol","title":"FetchSorterOption.caseInsensitive","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"caseInsensitive"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/caseInsensitive","kind":"symbol","type":"topic","url":"\/documentation\/crush\/fetchsorteroption\/caseinsensitive"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/FetchSorterOption":{"role":"symbol","title":"FetchSorterOption","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"FetchSorterOption"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"FetchSorterOption"}],"url":"\/documentation\/crush\/fetchsorteroption"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/updateattribute/propertymigration-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/updateattribute\/propertymigration-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute\/PropertyMigration-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute\/customize(_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"PropertyMigration Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/UpdateAttribute":{"role":"symbol","title":"UpdateAttribute","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"UpdateAttribute"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"UpdateAttribute"}],"url":"\/documentation\/crush\/updateattribute"},"doc://Crush/documentation/Crush/UpdateAttribute/customize(_:)":{"role":"symbol","title":"customize(_:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"customize"},{"kind":"text","text":"(("},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Self"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UpdateAttribute\/customize(_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/updateattribute\/customize(_:)"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/adhocmigrationerror/equatable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/adhocmigrationerror\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError"]]},"references":{"doc://Crush/documentation/Crush/AdHocMigrationError/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/adhocmigrationerror\/!=(_:_:)"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/AdHocMigrationError":{"role":"symbol","title":"AdHocMigrationError","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"AdHocMigrationError"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/AdHocMigrationError","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"AdHocMigrationError"}],"url":"\/documentation\/crush\/adhocmigrationerror"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/manageddriver/customdebugstringconvertible-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/manageddriver\/customdebugstringconvertible-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/ManagedDriver\/CustomDebugStringConvertible-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Crush\/documentation\/Crush\/ManagedDriver\/debugDescription"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"CustomDebugStringConvertible Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/ManagedDriver"]]},"references":{"doc://Crush/documentation/Crush/ManagedDriver":{"role":"symbol","title":"ManagedDriver","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"ManagedDriver"}],"abstract":[{"type":"text","text":"Access "},{"type":"codeVoice","code":"NSManagedObject"},{"type":"text","text":" data flexibly, especially when dealing with inheritance relationships."}],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ManagedDriver","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ManagedDriver"}],"url":"\/documentation\/crush\/manageddriver"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/ManagedDriver/debugDescription":{"role":"symbol","title":"debugDescription","fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"debugDescription"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ManagedDriver\/debugDescription","kind":"symbol","type":"topic","url":"\/documentation\/crush\/manageddriver\/debugdescription"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/migrator.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Migrator"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/migrator"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/Migrator","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/Migrator\/migrate()"]}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Migrator"}],"title":"Migrator","roleHeading":"Class","role":"symbol","symbolKind":"class","externalID":"s:5Crush8MigratorC","modules":[{"name":"Crush"}],"navigatorTitle":[{"kind":"identifier","text":"Migrator"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush"]]},"references":{"doc://Crush/documentation/Crush/Migrator":{"role":"symbol","title":"Migrator","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"Migrator"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Migrator","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Migrator"}],"url":"\/documentation\/crush\/migrator"},"doc://Crush/documentation/Crush/Migrator/migrate()":{"role":"symbol","title":"migrate()","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"migrate"},{"kind":"text","text":"() "},{"kind":"keyword","text":"throws"},{"kind":"text","text":" -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/Migrator\/migrate()","kind":"symbol","type":"topic","url":"\/documentation\/crush\/migrator\/migrate()"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/js/highlight-js-xml.9c3688c7.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * This source file is part of the Swift.org open source project 3 | * 4 | * Copyright (c) 2021 Apple Inc. and the Swift project authors 5 | * Licensed under Apache License v2.0 with Runtime Library Exception 6 | * 7 | * See https://swift.org/LICENSE.txt for license information 8 | * See https://swift.org/CONTRIBUTORS.txt for Swift project authors 9 | */ 10 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["highlight-js-xml"],{"8dcb":function(e,n){function a(e){const n=e.regex,a=n.concat(/[A-Z_]/,n.optional(/[A-Z0-9_.-]*:/),/[A-Z0-9_.-]*/),s=/[A-Za-z0-9._:-]+/,t={className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},i={begin:/\s/,contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]},c=e.inherit(i,{begin:/\(/,end:/\)/}),l=e.inherit(e.APOS_STRING_MODE,{className:"string"}),r=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),g={endsWithParent:!0,illegal:/`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,contains:[{className:"meta",begin://,relevance:10,contains:[i,r,l,c,{begin:/\[/,end:/\]/,contains:[{className:"meta",begin://,contains:[i,c,r,l]}]}]},e.COMMENT(//,{relevance:10}),{begin://,relevance:10},t,{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:/)/,end:/>/,keywords:{name:"style"},contains:[g],starts:{end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:/)/,end:/>/,keywords:{name:"script"},contains:[g],starts:{end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{className:"tag",begin:/<>|<\/>/},{className:"tag",begin:n.concat(//,/>/,/\s/)))),end:/\/?>/,contains:[{className:"name",begin:a,relevance:0,starts:g}]},{className:"tag",begin:n.concat(/<\//,n.lookahead(n.concat(a,/>/))),contains:[{className:"name",begin:a,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}}e.exports=a}}]); -------------------------------------------------------------------------------- /docs/data/documentation/crush/enumerableattributetype/hashable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/enumerableattributetype\/hashable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/EnumerableAttributeType\/Hashable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/EnumerableAttributeType\/hash(into:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Hashable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/EnumerableAttributeType"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/EnumerableAttributeType/hash(into:)":{"role":"symbol","title":"hash(into:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"hash"},{"kind":"text","text":"("},{"kind":"externalParam","text":"into"},{"kind":"text","text":": "},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"Hasher","preciseIdentifier":"s:s6HasherV"},{"kind":"text","text":")"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EnumerableAttributeType\/hash(into:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/enumerableattributetype\/hash(into:)"},"doc://Crush/documentation/Crush/EnumerableAttributeType":{"role":"symbol","title":"EnumerableAttributeType","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"EnumerableAttributeType"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/EnumerableAttributeType","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"EnumerableAttributeType"}],"url":"\/documentation\/crush\/enumerableattributetype"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/modelmigration/equatable-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/modelmigration\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/ModelMigration\/Equatable-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Crush\/documentation\/Crush\/ModelMigration\/!=(_:_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/ModelMigration"]]},"references":{"doc://Crush/documentation/Crush/ModelMigration":{"role":"symbol","title":"ModelMigration","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"ModelMigration"}],"abstract":[{"type":"text","text":"It defined how will entities change within a model migration"}],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ModelMigration","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ModelMigration"}],"url":"\/documentation\/crush\/modelmigration"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/ModelMigration/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/ModelMigration\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/modelmigration\/!=(_:_:)"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/fetchsorteroption/localizedstandard.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"localizedStandard"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/fetchsorteroption\/localizedstandard"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/localizedStandard","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"localizedStandard"}],"title":"FetchSorterOption.localizedStandard","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:5Crush17FetchSorterOptionO17localizedStandardyA2CmF","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption"]]},"references":{"doc://Crush/documentation/Crush/FetchSorterOption/localizedStandard":{"role":"symbol","title":"FetchSorterOption.localizedStandard","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"localizedStandard"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption\/localizedStandard","kind":"symbol","type":"topic","url":"\/documentation\/crush\/fetchsorteroption\/localizedstandard"},"doc://Crush/documentation/Crush/FetchSorterOption":{"role":"symbol","title":"FetchSorterOption","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"FetchSorterOption"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/FetchSorterOption","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"FetchSorterOption"}],"url":"\/documentation\/crush\/fetchsorteroption"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/lazyfetchresultcollection.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"typealias"},{"kind":"text","text":" "},{"kind":"identifier","text":"LazyFetchResultCollection"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"T"},{"kind":"text","text":"> = "},{"kind":"typeIdentifier","text":"LazyMapSequence","preciseIdentifier":"s:s15LazyMapSequenceV"},{"kind":"text","text":"<["},{"kind":"typeIdentifier","text":"NSManagedObject","preciseIdentifier":"c:objc(cs)NSManagedObject"},{"kind":"text","text":"], "},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/lazyfetchresultcollection"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/LazyFetchResultCollection","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"typealias"},{"kind":"text","text":" "},{"kind":"identifier","text":"LazyFetchResultCollection"}],"title":"LazyFetchResultCollection","roleHeading":"Type Alias","role":"symbol","symbolKind":"typealias","externalID":"s:5Crush25LazyFetchResultCollectiona","modules":[{"name":"Crush"}],"navigatorTitle":[{"kind":"identifier","text":"LazyFetchResultCollection"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush"]]},"references":{"doc://Crush/documentation/Crush/LazyFetchResultCollection":{"role":"symbol","title":"LazyFetchResultCollection","fragments":[{"kind":"keyword","text":"typealias"},{"kind":"text","text":" "},{"kind":"identifier","text":"LazyFetchResultCollection"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/LazyFetchResultCollection","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"LazyFetchResultCollection"}],"url":"\/documentation\/crush\/lazyfetchresultcollection"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /Sources/Utils/Caches.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Cahces.swift 3 | // Crush 4 | // 5 | // Created by EZOU on 2019/9/22. 6 | // Copyright © 2019 ezou. All rights reserved. 7 | // 8 | 9 | import CoreData 10 | 11 | // MARK: - Cache type protocol 12 | 13 | class Cache { 14 | var cache: [Key: Element] = [:] 15 | var callbackStore: [Key: [Callback]] = [:] 16 | 17 | typealias Callback = (Element) -> Void 18 | 19 | func set(_ key: Key, value: Element) { 20 | cache[key] = value 21 | guard let callbacks = callbackStore.removeValue(forKey: key) else { return } 22 | callbacks.forEach{ $0(value) } 23 | } 24 | 25 | func get(_ key: Key) -> Element? { 26 | cache[key] 27 | } 28 | 29 | func get(_ key: Key, completion: @escaping Callback) { 30 | let value = get(key) 31 | 32 | if let value = value { 33 | completion(value) 34 | } else { 35 | let callbacks = callbackStore[key] 36 | callbackStore[key] = (callbacks ?? []) + [completion] 37 | } 38 | } 39 | 40 | func clean() { 41 | cache = [:] 42 | callbackStore = [:] 43 | } 44 | } 45 | 46 | class ThreadSafeCache: Cache { 47 | private let lock = UnfairLock() 48 | 49 | override func set(_ key: Key, value: Element) { 50 | lock.lock() 51 | defer { lock.unlock() } 52 | super.set(key, value: value) 53 | } 54 | 55 | override func get(_ key: Key) -> Element? { 56 | lock.lock() 57 | defer { lock.unlock() } 58 | return super.get(key) 59 | } 60 | 61 | override func get(_ key: Key, completion: @escaping Cache.Callback) { 62 | lock.lock() 63 | defer { lock.unlock() } 64 | super.get(key, completion: completion) 65 | } 66 | 67 | override func clean() { 68 | lock.lock() 69 | defer { lock.unlock() } 70 | super.clean() 71 | } 72 | } 73 | 74 | // MARK: - Define all caches 75 | 76 | typealias EntityCache = Cache 77 | typealias ManagedObjectModelCache = ThreadSafeCache 78 | 79 | internal enum Caches { 80 | static let managedObjectModel: ManagedObjectModelCache = .init() 81 | } 82 | -------------------------------------------------------------------------------- /docs/data/documentation/crush/updatefetchedproperty/updatepropertymigration-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/updatefetchedproperty\/updatepropertymigration-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/UpdateFetchedProperty\/UpdatePropertyMigration-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/UpdateFetchedProperty\/versionHashModifier(_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"UpdatePropertyMigration Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/UpdateFetchedProperty"]]},"references":{"doc://Crush/documentation/Crush/UpdateFetchedProperty":{"role":"symbol","title":"UpdateFetchedProperty","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"UpdateFetchedProperty"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UpdateFetchedProperty","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"UpdateFetchedProperty"}],"url":"\/documentation\/crush\/updatefetchedproperty"},"doc://Crush/documentation/Crush/UpdateFetchedProperty/versionHashModifier(_:)":{"role":"symbol","title":"versionHashModifier(_:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"versionHashModifier"},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"},{"kind":"text","text":"?) -> "},{"kind":"typeIdentifier","text":"Self"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UpdateFetchedProperty\/versionHashModifier(_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/updatefetchedproperty\/versionhashmodifier(_:)"},"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/selectpath/path.json: -------------------------------------------------------------------------------- 1 | {"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"path"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/crush\/selectpath\/path"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/SelectPath\/path","interfaceLanguage":"swift"},"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"path"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"title":"path","roleHeading":"Instance Property","role":"symbol","symbolKind":"property","externalID":"s:5Crush10SelectPathC4pathSSvp","modules":[{"name":"Crush"}]},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/SelectPath"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/SelectPath":{"role":"symbol","title":"SelectPath","fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"SelectPath"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/SelectPath","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"SelectPath"}],"url":"\/documentation\/crush\/selectpath"},"doc://Crush/documentation/Crush/SelectPath/path":{"role":"symbol","title":"path","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"path"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/SelectPath\/path","kind":"symbol","type":"topic","url":"\/documentation\/crush\/selectpath\/path"}}} -------------------------------------------------------------------------------- /docs/data/documentation/crush/updaterelationship/propertymigration-implementations.json: -------------------------------------------------------------------------------- 1 | {"variants":[{"paths":["\/documentation\/crush\/updaterelationship\/propertymigration-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Crush\/documentation\/Crush\/UpdateRelationship\/PropertyMigration-Implementations","interfaceLanguage":"swift"},"topicSections":[{"title":"Instance Methods","identifiers":["doc:\/\/Crush\/documentation\/Crush\/UpdateRelationship\/customize(_:)"],"generated":true}],"kind":"article","metadata":{"modules":[{"name":"Crush"}],"role":"collectionGroup","title":"PropertyMigration Implementations"},"hierarchy":{"paths":[["doc:\/\/Crush\/documentation\/Crush","doc:\/\/Crush\/documentation\/Crush\/UpdateRelationship"]]},"references":{"doc://Crush/documentation/Crush":{"role":"collection","title":"Crush","abstract":[{"type":"text","text":"Enhance the development experience with CoreData by providing greater type-safety and intuitive functionality"}],"identifier":"doc:\/\/Crush\/documentation\/Crush","kind":"symbol","type":"topic","url":"\/documentation\/crush"},"doc://Crush/documentation/Crush/UpdateRelationship":{"role":"symbol","title":"UpdateRelationship","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"UpdateRelationship"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UpdateRelationship","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"UpdateRelationship"}],"url":"\/documentation\/crush\/updaterelationship"},"doc://Crush/documentation/Crush/UpdateRelationship/customize(_:)":{"role":"symbol","title":"customize(_:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"customize"},{"kind":"text","text":"(("},{"kind":"keyword","text":"inout"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Void","preciseIdentifier":"s:s4Voida"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Self"}],"abstract":[],"identifier":"doc:\/\/Crush\/documentation\/Crush\/UpdateRelationship\/customize(_:)","kind":"symbol","type":"topic","url":"\/documentation\/crush\/updaterelationship\/customize(_:)"}}} --------------------------------------------------------------------------------