Could anyone guide me on how to make full use of CoreStore to setup, define and initialize the configuration of coreStore stack #168

Closed
opened 2025-12-29 15:26:06 +01:00 by adam · 13 comments
Owner

Originally created by @evering7 on GitHub (Sep 11, 2017).

`class SourceFeed_CoreData: NSManagedObject {
@NSManaged var url: String
@NSManaged var fileName: String

} // class SourceFeed_CoreData: CoreStoreObject 2017.9.11

func prepareCoreDataStack() {
do {
try CoreStore.addStorageAndWait()
} catch {
printLog("error = (error.localizedDescription)")
}
}`

produce the following error when I debug the code. Could any one help me?

2017-09-11 20:26:21.781230+0800 iSpeak8[8362:2276713] PBItemCollectionServicer connection disconnected.
[CoreStore: Fatal Error] BaseDataTransaction.swift:83 create
↪︎ Attempted to create an entity of type 'SourceFeed_CoreData', but a destination persistent store containing the entity type could not be found.

fatal error: file /Users/jianfeili/Documents/vip_iSpeaking/v_008/iSpeak8/Pods/CoreStore/Sources/BaseDataTransaction.swift, line 83
2017-09-11 20:27:09.681640+0800 iSpeak8[8362:2276628] fatal error: file /Users/jianfeili/Documents/vip_iSpeaking/v_008/iSpeak8/Pods/CoreStore/Sources/BaseDataTransaction.swift, line 83

Originally created by @evering7 on GitHub (Sep 11, 2017). `class SourceFeed_CoreData: NSManagedObject { @NSManaged var url: String @NSManaged var fileName: String } // class SourceFeed_CoreData: CoreStoreObject 2017.9.11 func prepareCoreDataStack() { do { try CoreStore.addStorageAndWait() } catch { printLog("error = \(error.localizedDescription)") } }` produce the following error when I debug the code. Could any one help me? 2017-09-11 20:26:21.781230+0800 iSpeak8[8362:2276713] PBItemCollectionServicer connection disconnected. ❗ [CoreStore: Fatal Error] BaseDataTransaction.swift:83 create ↪︎ Attempted to create an entity of type 'SourceFeed_CoreData', but a destination persistent store containing the entity type could not be found. fatal error: file /Users/jianfeili/Documents/vip_iSpeaking/v_008/iSpeak8/Pods/CoreStore/Sources/BaseDataTransaction.swift, line 83 2017-09-11 20:27:09.681640+0800 iSpeak8[8362:2276628] fatal error: file /Users/jianfeili/Documents/vip_iSpeaking/v_008/iSpeak8/Pods/CoreStore/Sources/BaseDataTransaction.swift, line 83
adam added the question label 2025-12-29 15:26:06 +01:00
adam closed this issue 2025-12-29 15:26:06 +01:00
Author
Owner

@JohnEstropia commented on GitHub (Sep 11, 2017):

You are relying on the implicit creation of the DataStack and the SQLiteStore, so this code will only work if and only if:

  • Your *.xcdatamodeld file is the same name as your app's CFBundleName
  • That xcdatamodeld contains a SourceFeed_CoreData entity in the "Default" configuration

To answer your question, please refer to the the README file which provides a complete example to setup both the DataStack and the SQLiteStore: https://github.com/JohnEstropia/CoreStore#setting-up

@JohnEstropia commented on GitHub (Sep 11, 2017): You are relying on the implicit creation of the `DataStack` and the `SQLiteStore`, so this code will only work if and only if: - Your `*.xcdatamodeld` file is the same name as your app's `CFBundleName` - That xcdatamodeld contains a `SourceFeed_CoreData` entity in the "Default" configuration To answer your question, please refer to the the README file which provides a complete example to setup both the `DataStack` and the `SQLiteStore`: https://github.com/JohnEstropia/CoreStore#setting-up
Author
Owner

@evering7 commented on GitHub (Sep 12, 2017):

class SourceFeed_CoreData: CoreStoreObject {
var url = Value.Required("url")

var fileName = Value.Required<String>("fileName")
} // class SourceFeed_CoreData: CoreStoreObject 2017.9.11

The focus of my problem is now on how to define the class for the entity. Could you guide me on how to correctly define the entity class and set the value of attributes. The following code would report error when building

CoreStore.perform(asynchronous: { (transaction) -> Void in
let sourceFeed = transaction.create(Into<SourceFeed_CoreData>())
sourceFeed.url = self.url.getStrValue() // report error
        // build error infomation: cannot assign value of type 'String' to type 
        // 'ValueContainer<SourceFeed_CoreData>.Required<String>'

    }, success: { _ in
        printLog("Succeed in saving an url")
    }, failure: { (coreStoreError) -> Void in
        printLog("fail to commit the action of add url in source Feed list \(coreStoreError)")
    })
@evering7 commented on GitHub (Sep 12, 2017): ``` class SourceFeed_CoreData: CoreStoreObject { var url = Value.Required("url") var fileName = Value.Required<String>("fileName") } // class SourceFeed_CoreData: CoreStoreObject 2017.9.11 ``` The focus of my problem is now on how to define the class for the entity. Could you guide me on how to correctly define the entity class and set the value of attributes. The following code would report error when building ``` CoreStore.perform(asynchronous: { (transaction) -> Void in let sourceFeed = transaction.create(Into<SourceFeed_CoreData>()) sourceFeed.url = self.url.getStrValue() // report error // build error infomation: cannot assign value of type 'String' to type // 'ValueContainer<SourceFeed_CoreData>.Required<String>' }, success: { _ in printLog("Succeed in saving an url") }, failure: { (coreStoreError) -> Void in printLog("fail to commit the action of add url in source Feed list \(coreStoreError)") }) ```
Author
Owner

@evering7 commented on GitHub (Sep 12, 2017):

I have partly solve my problem. I will explore the other aspects of the CoreStore. Now I temporarily don't need answer.

@evering7 commented on GitHub (Sep 12, 2017): I have partly solve my problem. I will explore the other aspects of the CoreStore. Now I temporarily don't need answer.
Author
Owner

@evering7 commented on GitHub (Sep 12, 2017):

I delete xcdatamodel file, and use the full CoreStoreSchema grammar.

@evering7 commented on GitHub (Sep 12, 2017): I delete xcdatamodel file, and use the full CoreStoreSchema grammar.
Author
Owner

@JohnEstropia commented on GitHub (Sep 12, 2017):

Sorry for the late reply (Japan timezone). You may have found it already, but the setup for CoreStoreSchema is outlined here: https://github.com/JohnEstropia/CoreStore#type-safe-corestoreobjects

You can also find actual working code in the Demo app and the Unit Tests.

Let me know if you have other questions :)

@JohnEstropia commented on GitHub (Sep 12, 2017): Sorry for the late reply (Japan timezone). You may have found it already, but the setup for CoreStoreSchema is outlined here: https://github.com/JohnEstropia/CoreStore#type-safe-corestoreobjects You can also find actual working code in the [Demo app](https://github.com/JohnEstropia/CoreStore/blob/develop/CoreStoreDemo/CoreStoreDemo/List%20and%20Object%20Observers%20Demo/ListObserverDemoViewController.swift#L56) and the [Unit Tests](https://github.com/JohnEstropia/CoreStore/blob/develop/CoreStoreTests/DynamicModelTests.swift#L120). Let me know if you have other questions :)
Author
Owner

@evering7 commented on GitHub (Sep 12, 2017):

I have write a function to get the data in CoreData to the memory variables. The function is just as below

    func readSourceFeed_FromCoreData_ToMem() -> Void { // purely reading, writing to memory
        guard let q = self.accessQueue else {
            sayFatal("can't unwrap accessQueue")
            fatalError()
            
        } // guard let q
        
        var sourceFeeds: [SourceFeed_CoreData]?
        let sema = DispatchSemaphore(value: 1)
        
        sema.wait()
        DispatchQueue.main.async{
            
            CoreStore.perform(asynchronous: { (transaction) -> Void in
                sourceFeeds = CoreStore.fetchAll(From<SourceFeed_CoreData>(),[])
                
            }, completion: { (result) -> Void in
                printLog("The asynchronous perform result = \(result)")
                sema.signal()
            })
        } // DispatchQueue.main.async 2017.9.12.
        
        sema.wait() // ** Debug to here the app start to 
        // show no sign to step/pause the running, may be dead lock **
        
        // My question: how to let the above CoreStore.perform
        
        q.async(flags: .barrier) {
            if let sourceFeeds_Unwrap = sourceFeeds {
                for sourceFeed in sourceFeeds_Unwrap {
                    let sourceFeed_Mem = SourceFeed_Memory_TS(queueLabel: "sourceFeed to read out coredata", inititalValue: "")
                    sourceFeed_Mem.url.setStrValue(value: sourceFeed.url.value!)
                    sourceFeed_Mem.fileName.setStrValue(value: sourceFeed.fileName.value!)
                    self.listOf_SourceFeeds_Unsafe.append(sourceFeed_Mem)
                }
            }
        } // q.async 2017.9.12
        
    } // func readSourceFeed_FromCoreData_ToMem() -> Void 2017.9.12

I know such writing is not elegant. Could you help me on how to fetchAll and pass data into the sourceFeeds and running ok?
Thank you very much!

@evering7 commented on GitHub (Sep 12, 2017): I have write a function to get the data in CoreData to the memory variables. The function is just as below ``` func readSourceFeed_FromCoreData_ToMem() -> Void { // purely reading, writing to memory guard let q = self.accessQueue else { sayFatal("can't unwrap accessQueue") fatalError() } // guard let q var sourceFeeds: [SourceFeed_CoreData]? let sema = DispatchSemaphore(value: 1) sema.wait() DispatchQueue.main.async{ CoreStore.perform(asynchronous: { (transaction) -> Void in sourceFeeds = CoreStore.fetchAll(From<SourceFeed_CoreData>(),[]) }, completion: { (result) -> Void in printLog("The asynchronous perform result = \(result)") sema.signal() }) } // DispatchQueue.main.async 2017.9.12. sema.wait() // ** Debug to here the app start to // show no sign to step/pause the running, may be dead lock ** // My question: how to let the above CoreStore.perform q.async(flags: .barrier) { if let sourceFeeds_Unwrap = sourceFeeds { for sourceFeed in sourceFeeds_Unwrap { let sourceFeed_Mem = SourceFeed_Memory_TS(queueLabel: "sourceFeed to read out coredata", inititalValue: "") sourceFeed_Mem.url.setStrValue(value: sourceFeed.url.value!) sourceFeed_Mem.fileName.setStrValue(value: sourceFeed.fileName.value!) self.listOf_SourceFeeds_Unsafe.append(sourceFeed_Mem) } } } // q.async 2017.9.12 } // func readSourceFeed_FromCoreData_ToMem() -> Void 2017.9.12 ``` I know such writing is not elegant. Could you help me on how to fetchAll and pass data into the sourceFeeds and running ok? Thank you very much!
Author
Owner

@JohnEstropia commented on GitHub (Sep 12, 2017):

Hmm there's a lot of things I'm worried about here but I'll try to comment on each separately.

  1. First, always use the transaction argument inside the transaction block to do anything inside that block. Always remember that the objects that are valid inside the transaction closure (background thread) and the completion closure (main thread) are in different worlds, so you need to fetch between them:
CoreStore.perform(
    asynchronous: { (transaction) in
        return transaction.fetchAll(From<SourceFeed_CoreData>(),[])
    },
    completion: { (feeds) in
        sourceFeeds = CoreStore.fetchExisting(feeds) // Dont forget to get instances for the main thread
        printLog("The asynchronous perform result = \(result)")
        sema.signal()
    }
)
  1. Second, I'm not sure why you are using semaphores here. If you want to fetch objects immediately, you don't need to use transactions. Transactions are for updating objects. If you just want to read objects just fetch them directly:
for sourceFeed in (CoreStore.fetchAll(From<SourceFeed_CoreData>()) ?? []) {
    let sourceFeed_Mem = SourceFeed_Memory_TS(queueLabel: "sourceFeed to read out coredata", inititalValue: "")
    sourceFeed_Mem.url.setStrValue(value: sourceFeed.url.value!)
    sourceFeed_Mem.fileName.setStrValue(value: sourceFeed.fileName.value!)
    self.listOf_SourceFeeds_Unsafe.append(sourceFeed_Mem)
}
@JohnEstropia commented on GitHub (Sep 12, 2017): Hmm there's a lot of things I'm worried about here but I'll try to comment on each separately. 1. First, always use the `transaction` argument inside the transaction block to do anything inside that block. Always remember that the objects that are valid inside the transaction closure (background thread) and the completion closure (main thread) are in different worlds, so you need to fetch between them: ```swift CoreStore.perform( asynchronous: { (transaction) in return transaction.fetchAll(From<SourceFeed_CoreData>(),[]) }, completion: { (feeds) in sourceFeeds = CoreStore.fetchExisting(feeds) // Dont forget to get instances for the main thread printLog("The asynchronous perform result = \(result)") sema.signal() } ) ``` 2. Second, I'm not sure why you are using semaphores here. If you want to fetch objects immediately, you don't need to use transactions. Transactions are for updating objects. If you just want to read objects just fetch them directly: ```swift for sourceFeed in (CoreStore.fetchAll(From<SourceFeed_CoreData>()) ?? []) { let sourceFeed_Mem = SourceFeed_Memory_TS(queueLabel: "sourceFeed to read out coredata", inititalValue: "") sourceFeed_Mem.url.setStrValue(value: sourceFeed.url.value!) sourceFeed_Mem.fileName.setStrValue(value: sourceFeed.fileName.value!) self.listOf_SourceFeeds_Unsafe.append(sourceFeed_Mem) } ```
Author
Owner

@evering7 commented on GitHub (Sep 13, 2017):

Thank you any way. I have adopted the second solution of yours. All is OK now. My original thoughts is too complex. I use semaphore because I thought I should get the asynchronous functions get results synchronously. Thank you very much. The framework of yours is very powerful and easy to use.

@evering7 commented on GitHub (Sep 13, 2017): Thank you any way. I have adopted the second solution of yours. All is OK now. My original thoughts is too complex. I use semaphore because I thought I should get the asynchronous functions get results synchronously. Thank you very much. The framework of yours is very powerful and easy to use.
Author
Owner

@evering7 commented on GitHub (Sep 13, 2017):

    func getCountOfSourceFeed_InCoreData() -> Int {
        
        let isMainThread = Thread.isMainThread
        
        if isMainThread {
            printLog("this func is on main thread. Very OK") // Here the app go.
        } else {
            printLog("this func is not on main thread")
        }
        
        // The following would let app go to Value.swift line 375, and report an error about designated queue
        let retCount: Int = CoreStore.fetchCount(From<SourceFeed_CoreData>(),[]) ?? 0
        

        return retCount

    } // func getCountOfSourceFeed_InCoreData() -> Int 2017.9.12

Hi, John. The above code is running correctly in the morning at my home, but it can't work well in my office on the same MacBook Pro of mine. I have tested that "CoreStore.fetchCount" would lead to assert error in line 375 of value.swift. Though I have tested at the beginning of the function that the code is on the main thread.

@evering7 commented on GitHub (Sep 13, 2017): ```swift func getCountOfSourceFeed_InCoreData() -> Int { let isMainThread = Thread.isMainThread if isMainThread { printLog("this func is on main thread. Very OK") // Here the app go. } else { printLog("this func is not on main thread") } // The following would let app go to Value.swift line 375, and report an error about designated queue let retCount: Int = CoreStore.fetchCount(From<SourceFeed_CoreData>(),[]) ?? 0 return retCount } // func getCountOfSourceFeed_InCoreData() -> Int 2017.9.12 ``` Hi, John. The above code is running correctly in the morning at my home, but it can't work well in my office on the same MacBook Pro of mine. I have tested that "CoreStore.fetchCount" would lead to assert error in line 375 of value.swift. Though I have tested at the beginning of the function that the code is on the main thread.
Author
Owner

@evering7 commented on GitHub (Sep 13, 2017):

So I have simulate the method 2 suggestion by you in the above. write the second version of this function as following

func getCountOfSourceFeed_InCoreData_V2() -> Int {
        let sema = DispatchSemaphore(value: 1)
        var retCount: Int
        
        sema.wait()
        
        CoreStore.perform(
            asynchronous:
            {    (transaction) in
                 return transaction.fetchCount(From<SourceFeed_CoreData>(), [])
        
            },
            completion:
            {    (count) in
                 retCount = CoreStore.fetchExisting(count)
// The above line grammar error report: No fetchExisting candidates produce the expected contextual result type int
                 printLog("the async perform result = \(result)")
// The above line grammar error report: Use of unresolved identifier 'result'
                 sema.signal()
            }
        )
        
        sema.wait()
        
        return retCount
    }

@evering7 commented on GitHub (Sep 13, 2017): So I have simulate the method 2 suggestion by you in the above. write the second version of this function as following ```swift func getCountOfSourceFeed_InCoreData_V2() -> Int { let sema = DispatchSemaphore(value: 1) var retCount: Int sema.wait() CoreStore.perform( asynchronous: { (transaction) in return transaction.fetchCount(From<SourceFeed_CoreData>(), []) }, completion: { (count) in retCount = CoreStore.fetchExisting(count) // The above line grammar error report: No fetchExisting candidates produce the expected contextual result type int printLog("the async perform result = \(result)") // The above line grammar error report: Use of unresolved identifier 'result' sema.signal() } ) sema.wait() return retCount } ```
Author
Owner

@evering7 commented on GitHub (Sep 13, 2017):

    func getCountOfSourceFeed_InCoreData_V3() -> Int {
        let retCount = CoreStore.queryValue(From<SourceFeed_CoreData>(),
                                            Select<Int>(.count("url")))
        printLog("return count = \(retCount ?? 0)")
        return (retCount ?? 0)
        
    } // func getCountOfSourceFeed_InCoreData_V3() -> Int 2017.9.13

The above code is the third version of my function. but it still report assertion errors when debugging

2017-09-13 20:21:38.177336+0800 iSpeak8[10126:2765120] 0x1701552f0 Copy matching assets reply: XPC_TYPE_DICTIONARY  <dictionary: 0x1701552f0> { count = 3, transaction: 0, voucher = 0x0, contents =
	"Assets" => <data: 0x170662600>: { length = 1237 bytes, contents = 0x62706c6973743030d4010203040506636458247665727369... }
	"Result" => <int64: 0x170424d00>: 0
	"AssetXMLMetadata" => <data: 0x1706625c0>: { length = 307 bytes, contents = 0x62706c6973743030d40102030405061f2058247665727369... }
}
2017-09-13 20:21:38.187284+0800 iSpeak8[10126:2765120] 0x170155710 Copy assets attributes reply: XPC_TYPE_DICTIONARY  <dictionary: 0x170155710> { count = 1, transaction: 0, voucher = 0x0, contents =
	"Result" => <int64: 0x170424c60>: 1
}
2017-09-13 20:21:38.187888+0800 iSpeak8[10126:2765120] [MobileAssetError:1] Unable to copy asset attributes
2017-09-13 20:21:38.190211+0800 iSpeak8[10126:2765120] Could not get attribute 'LocalURL': Error Domain=MobileAssetError Code=1 "Unable to copy asset attributes" UserInfo={NSDescription=Unable to copy asset attributes}
2017-09-13 20:22:06.599403+0800 iSpeak8[10126:2764976] n9p1C 00003 T:<NSThread: 0x17007f3c0>{number = 1, name = main} F:Data_CoreData.swift.getCountOfSourceFeed_InCoreData_V3(): 60  return count = 15
2017-09-13 20:22:24.025729+0800 iSpeak8[10126:2764976] Returning local object of class NSString
❗ [CoreStore: Assertion Failure] Value.swift:375 value
  ↪︎ Attempted to access 'SourceFeed_CoreData''s value outside it's designated queue.

fatal error: file /Users/jianfeili/Documents/vip_iSpeaking/v_008/iSpeak8/Pods/CoreStore/Sources/Value.swift, line 375
@evering7 commented on GitHub (Sep 13, 2017): ```swift func getCountOfSourceFeed_InCoreData_V3() -> Int { let retCount = CoreStore.queryValue(From<SourceFeed_CoreData>(), Select<Int>(.count("url"))) printLog("return count = \(retCount ?? 0)") return (retCount ?? 0) } // func getCountOfSourceFeed_InCoreData_V3() -> Int 2017.9.13 ``` The above code is the third version of my function. but it still report assertion errors when debugging ``` 2017-09-13 20:21:38.177336+0800 iSpeak8[10126:2765120] 0x1701552f0 Copy matching assets reply: XPC_TYPE_DICTIONARY <dictionary: 0x1701552f0> { count = 3, transaction: 0, voucher = 0x0, contents = "Assets" => <data: 0x170662600>: { length = 1237 bytes, contents = 0x62706c6973743030d4010203040506636458247665727369... } "Result" => <int64: 0x170424d00>: 0 "AssetXMLMetadata" => <data: 0x1706625c0>: { length = 307 bytes, contents = 0x62706c6973743030d40102030405061f2058247665727369... } } 2017-09-13 20:21:38.187284+0800 iSpeak8[10126:2765120] 0x170155710 Copy assets attributes reply: XPC_TYPE_DICTIONARY <dictionary: 0x170155710> { count = 1, transaction: 0, voucher = 0x0, contents = "Result" => <int64: 0x170424c60>: 1 } 2017-09-13 20:21:38.187888+0800 iSpeak8[10126:2765120] [MobileAssetError:1] Unable to copy asset attributes 2017-09-13 20:21:38.190211+0800 iSpeak8[10126:2765120] Could not get attribute 'LocalURL': Error Domain=MobileAssetError Code=1 "Unable to copy asset attributes" UserInfo={NSDescription=Unable to copy asset attributes} 2017-09-13 20:22:06.599403+0800 iSpeak8[10126:2764976] n9p1C 00003 T:<NSThread: 0x17007f3c0>{number = 1, name = main} F:Data_CoreData.swift.getCountOfSourceFeed_InCoreData_V3(): 60 return count = 15 2017-09-13 20:22:24.025729+0800 iSpeak8[10126:2764976] Returning local object of class NSString ❗ [CoreStore: Assertion Failure] Value.swift:375 value ↪︎ Attempted to access 'SourceFeed_CoreData''s value outside it's designated queue. fatal error: file /Users/jianfeili/Documents/vip_iSpeaking/v_008/iSpeak8/Pods/CoreStore/Sources/Value.swift, line 375 ```
Author
Owner

@evering7 commented on GitHub (Sep 14, 2017):

I have found the GCD is not compatible with CoreStore. So I want to give up CoreStore and manually use CoreData

@evering7 commented on GitHub (Sep 14, 2017): I have found the GCD is not compatible with CoreStore. So I want to give up CoreStore and manually use CoreData
Author
Owner

@JohnEstropia commented on GitHub (Sep 14, 2017):

I have found the GCD is not compatible with CoreStore

That's not true though. CoreStore actually uses GCD a lot in its internals. Your issue is you are fighting with the queuing that CoreStore sets up for you by creating your own queues.

That said, CoreStore have methods for synchronous and asynchronous transactions (and even unsafe transactions) so it is possible to use your own queueing as well. In fact there are several people on the CoreStore slack group who does this. The issue is you are not using the right transactions for the queues you are using (for example, using asynchronousTransaction and blocking it with a semaphore).

The assertion failure you see above is a critical warning that you are accessing the object in the wrong queue. If you use Core Data manually and continue using objects like this, you won't get assertion errors but straight up crash your app, or worse, corrupt your data.

Of course you are free to use CoreStore or not, and there are libraries out there you may find better for you. But whatever path you take, my suggestion is for you to brush up first on concurrency concepts, especially in tandem with database access, because multithreading errors will always be a danger no matter what framework you are using.

I'm closing this issue, but feel free to continue the discussion :)

@JohnEstropia commented on GitHub (Sep 14, 2017): > I have found the GCD is not compatible with CoreStore That's not true though. CoreStore actually uses GCD a lot in its internals. Your issue is you are fighting with the queuing that CoreStore sets up for you by creating your own queues. That said, CoreStore have methods for synchronous and asynchronous transactions (and even unsafe transactions) so it is possible to use your own queueing as well. In fact there are several people on the CoreStore slack group who does this. The issue is you are not using the right transactions for the queues you are using (for example, using asynchronousTransaction and blocking it with a semaphore). The assertion failure you see above is a critical warning that you are accessing the object in the wrong queue. If you use Core Data manually and continue using objects like this, you won't get assertion errors but straight up crash your app, or worse, corrupt your data. Of course you are free to use CoreStore or not, and there are libraries out there you may find better for you. But whatever path you take, my suggestion is for you to brush up first on concurrency concepts, especially in tandem with database access, because multithreading errors will always be a danger no matter what framework you are using. I'm closing this issue, but feel free to continue the discussion :)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore#168