YapDatabase
YapDatabase copied to clipboard
Calling -[YapDatabaseViewMapping updateWithTransaction:] before calling -[YapDatabaseReadTransaction ext:] results in YapDatabaseViewTransactions never being created
Is this expected behavior:
NSString* viewName = [[self class] viewName];
YapDatabaseViewGrouping* grouping = [YapDatabaseViewGrouping withObjectBlock:^NSString* _Nullable (YapDatabaseReadTransaction* _Nonnull transaction, NSString* _Nonnull collection, NSString* _Nonnull key, MWKHistoryEntry* _Nonnull object) {
if (![collection isEqualToString:[MWKHistoryEntry databaseCollectionName]]) {
return nil;
}
if (object.dateViewed == nil) {
return nil;
}
NSDate* date = [[object dateViewed] dateAtStartOfDay];
return [NSString stringWithFormat:@"%f", [date timeIntervalSince1970]];
}];
YapDatabaseViewSorting* sorting = [YapDatabaseViewSorting withObjectBlock:^NSComparisonResult (YapDatabaseReadTransaction* _Nonnull transaction, NSString* _Nonnull group, NSString* _Nonnull collection1, NSString* _Nonnull key1, MWKHistoryEntry* _Nonnull object1, NSString* _Nonnull collection2, NSString* _Nonnull key2, MWKHistoryEntry* _Nonnull object2) {
return -[object1.dateViewed compare:object2.dateViewed];
}];
YapDatabaseView* databaseView = [[YapDatabaseView alloc] initWithGrouping:grouping sorting:sorting];
[self.database registerView:databaseView withName:viewName];
YapDatabaseViewMappings* mappings = [[YapDatabaseViewMappings alloc] initWithGroupFilterBlock:^BOOL (NSString* _Nonnull group, YapDatabaseReadTransaction* _Nonnull transaction) {
return YES;
} sortBlock:^NSComparisonResult (NSString* _Nonnull group1, NSString* _Nonnull group2, YapDatabaseReadTransaction* _Nonnull transaction) {
if ([group1 doubleValue] < [group2 doubleValue]) {
return NSOrderedDescending;
} else if ([group1 doubleValue] > [group2 doubleValue]) {
return NSOrderedAscending;
} else {
return NSOrderedSame;
}
} view:viewName];
[self.readConnection readWithBlock:^(YapDatabaseReadTransaction* _Nonnull transaction) {
//This line is required to be called before calling [self.groupSortMappings updateWithTransaction:transaction] for the read block below to work
//IOW, If I comment out this line, the assertion below will fail.
YapDatabaseViewTransaction* view = [transaction ext:viewName];
[self.groupSortMappings updateWithTransaction:transaction];
}];
[self.readConnection readWithBlock:^(YapDatabaseReadTransaction* _Nonnull transaction) {
YapDatabaseViewTransaction* view = [transaction ext:viewName];
//This will fail if I comment out YapDatabaseViewTransaction* view = [transaction ext:viewName]; in the read block above
//From here on the connection will never be able to create a YapDatabaseViewTransaction for the viewName
NSParameterAssert(view);
}];
I traced the problem to the extension: method of YapDatabaseConnection.
If I call updateWithTransaction: on the mappings before calling ext: the connection, extensionsReady will be YES which causes the connection to never check registeredExtensions. Thus always returning nil for the YapDatabaseViewTransaction:
- (id)extension:(NSString *)extName
{
// This method is PUBLIC.
//
// This method returns a subclass of YapDatabaseExtensionConnection.
// To get:
// - YapDatabaseExtension => [database registeredExtension:@"registeredNameOfExtension"]
// - YapDatabaseExtensionConnection => [databaseConnection extension:@"registeredNameOfExtension"]
// - YapDatabaseExtensionTransaction => [databaseTransaction extension:@"registeredNameOfExtension"]
__block id extConnection = nil;
dispatch_block_t block = ^{
extConnection = [extensions objectForKey:extName];
if (!extConnection && !extensionsReady)
{
// We don't have an existing connection for the extension.
// Create one (if we can).
YapDatabaseExtension *ext = [registeredExtensions objectForKey:extName];
if (ext)
{
extConnection = [ext newConnection:self];
[extensions setObject:extConnection forKey:extName];
}
}
};
if (dispatch_get_specific(IsOnConnectionQueueKey))
block();
else
dispatch_sync(connectionQueue, block);
return extConnection;
}
Basically this puts the connection in an inconsistent state where it thinks extensions are ready, but they are not. Any thoughts here? Am I just using the API wrong?