Skip to content

Commit 41c8e77

Browse files
committed
Fix for assertion crash in YapDatabaseView. Bug caused by recent commit. Unit test added.
1 parent e3ff0dc commit 41c8e77

File tree

3 files changed

+326
-121
lines changed

3 files changed

+326
-121
lines changed

Testing/UnitTesting/TestYapDatabaseView.m

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2876,6 +2876,28 @@ - (void)_testInsertAndDelete_withPath:(NSString *)databasePath options:(YapDatab
28762876

28772877
XCTAssertTrue(registerResult, @"Failure registering extension");
28782878

2879+
[connection1 readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
2880+
2881+
NSString *key = @"someKey";
2882+
NSString *value = @"someValue";
2883+
2884+
[transaction setObject:value forKey:key inCollection:nil];
2885+
2886+
[transaction removeObjectForKey:key inCollection:nil];
2887+
2888+
XCTAssert([[transaction ext:@"order"] numberOfItemsInGroup:@""] == 0, @"Oops");
2889+
}];
2890+
2891+
[connection1 readWithBlock:^(YapDatabaseReadTransaction *transaction) {
2892+
2893+
XCTAssert([[transaction ext:@"order"] numberOfItemsInGroup:@""] == 0, @"Oops");
2894+
}];
2895+
2896+
[connection2 readWithBlock:^(YapDatabaseReadTransaction *transaction) {
2897+
2898+
XCTAssert([[transaction ext:@"order"] numberOfItemsInGroup:@""] == 0, @"Oops");
2899+
}];
2900+
28792901
[connection1 readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
28802902

28812903
NSUInteger count = 10;
@@ -2907,4 +2929,166 @@ - (void)_testInsertAndDelete_withPath:(NSString *)databasePath options:(YapDatab
29072929
}];
29082930
}
29092931

2932+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2933+
#pragma mark -
2934+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2935+
2936+
- (void)testDoubleDelete_persistent
2937+
{
2938+
NSString *databasePath = [self databasePath:NSStringFromSelector(_cmd)];
2939+
2940+
YapDatabaseViewOptions *options = [[YapDatabaseViewOptions alloc] init];
2941+
options.isPersistent = YES;
2942+
2943+
[self _testDoubleDelete_withPath:databasePath options:options];
2944+
}
2945+
2946+
- (void)testDoubleDelete_nonPersistent
2947+
{
2948+
NSString *databasePath = [self databasePath:NSStringFromSelector(_cmd)];
2949+
2950+
YapDatabaseViewOptions *options = [[YapDatabaseViewOptions alloc] init];
2951+
options.isPersistent = NO;
2952+
2953+
[self _testDoubleDelete_withPath:databasePath options:options];
2954+
}
2955+
2956+
- (void)_testDoubleDelete_withPath:(NSString *)databasePath options:(YapDatabaseViewOptions *)options
2957+
{
2958+
[[NSFileManager defaultManager] removeItemAtPath:databasePath error:NULL];
2959+
YapDatabase *database = [[YapDatabase alloc] initWithPath:databasePath];
2960+
2961+
XCTAssertNotNil(database, @"Oops");
2962+
2963+
YapDatabaseConnection *connection1 = [database newConnection];
2964+
YapDatabaseConnection *connection2 = [database newConnection];
2965+
2966+
YapDatabaseViewGrouping *grouping = [YapDatabaseViewGrouping withObjectBlock:
2967+
^NSString *(NSString *collection, NSString *key, id obj)
2968+
{
2969+
if ([obj isKindOfClass:[NSString class]])
2970+
return @"";
2971+
else
2972+
return nil;
2973+
}];
2974+
2975+
YapDatabaseViewSorting *sorting = [YapDatabaseViewSorting withObjectBlock:
2976+
^(NSString *group, NSString *collection1, NSString *key1, id obj1,
2977+
NSString *collection2, NSString *key2, id obj2)
2978+
{
2979+
__unsafe_unretained NSNumber *number1 = (NSNumber *)obj1;
2980+
__unsafe_unretained NSNumber *number2 = (NSNumber *)obj2;
2981+
2982+
return [number1 compare:number2];
2983+
}];
2984+
2985+
YapDatabaseView *databaseView =
2986+
[[YapDatabaseView alloc] initWithGrouping:grouping
2987+
sorting:sorting
2988+
versionTag:@"1"
2989+
options:options];
2990+
2991+
BOOL registerResult = [database registerExtension:databaseView withName:@"order"];
2992+
2993+
XCTAssertTrue(registerResult, @"Failure registering extension");
2994+
2995+
NSUInteger count = 10;
2996+
NSMutableArray *keys = [NSMutableArray arrayWithCapacity:count];
2997+
2998+
for (int i = 0; i < count; i++)
2999+
{
3000+
[keys addObject:[NSString stringWithFormat:@"key-%d", i]];
3001+
}
3002+
3003+
[connection1 readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
3004+
3005+
for (int i = 0; i < count; i++)
3006+
{
3007+
[transaction setObject:@"someValue" forKey:keys[i] inCollection:nil];
3008+
}
3009+
}];
3010+
3011+
// Test #1
3012+
3013+
[connection1 readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
3014+
3015+
[transaction removeObjectForKey:keys[0] inCollection:nil]; // remove 1
3016+
[transaction removeObjectForKey:keys[0] inCollection:nil]; // remove it again
3017+
3018+
XCTAssert([[transaction ext:@"order"] numberOfItemsInGroup:@""] == (count - 1), @"Oops");
3019+
}];
3020+
3021+
[connection1 readWithBlock:^(YapDatabaseReadTransaction *transaction) {
3022+
3023+
XCTAssert([[transaction ext:@"order"] numberOfItemsInGroup:@""] == (count - 1), @"Oops");
3024+
}];
3025+
3026+
[connection2 readWithBlock:^(YapDatabaseReadTransaction *transaction) {
3027+
3028+
XCTAssert([[transaction ext:@"order"] numberOfItemsInGroup:@""] == (count - 1), @"Oops");
3029+
}];
3030+
3031+
// Test #2
3032+
3033+
[connection1 readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
3034+
3035+
[transaction setObject:@(0) forKey:keys[1] inCollection:nil]; // remove from view
3036+
[transaction removeObjectForKey:keys[1] inCollection:nil]; // and then remove from database
3037+
3038+
XCTAssert([[transaction ext:@"order"] numberOfItemsInGroup:@""] == (count - 2), @"Oops");
3039+
}];
3040+
3041+
[connection1 readWithBlock:^(YapDatabaseReadTransaction *transaction) {
3042+
3043+
XCTAssert([[transaction ext:@"order"] numberOfItemsInGroup:@""] == (count - 2), @"Oops");
3044+
}];
3045+
3046+
[connection2 readWithBlock:^(YapDatabaseReadTransaction *transaction) {
3047+
3048+
XCTAssert([[transaction ext:@"order"] numberOfItemsInGroup:@""] == (count - 2), @"Oops");
3049+
}];
3050+
3051+
// Test #3
3052+
3053+
[connection1 readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
3054+
3055+
NSArray *keysToRemove = @[ keys[2], keys[3], keys[4] ];
3056+
3057+
[transaction setObject:@(0) forKey:keys[2] inCollection:nil]; // remove from view
3058+
[transaction removeObjectsForKeys:keysToRemove inCollection:nil]; // and then remove from database
3059+
3060+
XCTAssert([[transaction ext:@"order"] numberOfItemsInGroup:@""] == (count - 5), @"Oops");
3061+
}];
3062+
3063+
[connection1 readWithBlock:^(YapDatabaseReadTransaction *transaction) {
3064+
3065+
XCTAssert([[transaction ext:@"order"] numberOfItemsInGroup:@""] == (count - 5), @"Oops");
3066+
}];
3067+
3068+
[connection2 readWithBlock:^(YapDatabaseReadTransaction *transaction) {
3069+
3070+
XCTAssert([[transaction ext:@"order"] numberOfItemsInGroup:@""] == (count - 5), @"Oops");
3071+
}];
3072+
3073+
// Test #4
3074+
3075+
[connection1 readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
3076+
3077+
[transaction removeObjectForKey:keys[5] inCollection:nil]; // remove single item
3078+
[transaction removeObjectsForKeys:keys inCollection:nil]; // and then remove all
3079+
3080+
XCTAssert([[transaction ext:@"order"] numberOfItemsInGroup:@""] == 0, @"Oops");
3081+
}];
3082+
3083+
[connection1 readWithBlock:^(YapDatabaseReadTransaction *transaction) {
3084+
3085+
XCTAssert([[transaction ext:@"order"] numberOfItemsInGroup:@""] == 0, @"Oops");
3086+
}];
3087+
3088+
[connection2 readWithBlock:^(YapDatabaseReadTransaction *transaction) {
3089+
3090+
XCTAssert([[transaction ext:@"order"] numberOfItemsInGroup:@""] == 0, @"Oops");
3091+
}];
3092+
}
3093+
29103094
@end

YapDatabase/Extensions/Views/Internal/YapDatabaseViewState.m

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,14 @@ - (NSArray *)removePageMetadataAtIndex:(NSUInteger)index inGroup:(NSString *)gro
186186
- (void)removeGroup:(NSString *)group
187187
{
188188
AssertIsMutable();
189-
NSAssert([[group_pagesMetadata_dict objectForKey:group] count] == 0, @"Attempting to remove non-empty group");
190189

191-
[group_pagesMetadata_dict removeObjectForKey:group];
190+
NSUInteger count = [[group_pagesMetadata_dict objectForKey:group] count];
191+
NSAssert(count == 0, @"Attempting to remove non-empty group");
192+
193+
if (count == 0)
194+
{
195+
[group_pagesMetadata_dict removeObjectForKey:group];
196+
}
192197
}
193198

194199
- (void)removeAllGroups

0 commit comments

Comments
 (0)