Skip to content

Commit 9c813ae

Browse files
committed
Adding a bit of flexibility (in the face of failure) for core data storage implementations that can recreate data.
1 parent d1bc42d commit 9c813ae

File tree

2 files changed

+72
-22
lines changed

2 files changed

+72
-22
lines changed

Extensions/XEP-0045/HybridStorage/XMPPRoomHybridStorage.m

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
// Log levels: off, error, warn, info, verbose
3838
#if DEBUG
39-
static const int xmppLogLevel = XMPP_LOG_LEVEL_VERBOSE | XMPP_LOG_FLAG_TRACE;
39+
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN;
4040
#else
4141
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN;
4242
#endif
@@ -106,13 +106,57 @@ - (void)commonInit
106106
pausedMessageDeletion = [[NSMutableSet alloc] init];
107107
}
108108

109+
/**
110+
* Documentation from the superclass (XMPPCoreDataStorage):
111+
*
112+
* Override me, if needed, to provide customized behavior.
113+
*
114+
* This method is queried to get the name of the ManagedObjectModel within the app bundle.
115+
* It should return the name of the appropriate file (*.xdatamodel / *.mom / *.momd) sans file extension.
116+
*
117+
* The default implementation returns the name of the subclass, stripping any suffix of "CoreDataStorage".
118+
* E.g., if your subclass was named "XMPPExtensionCoreDataStorage", then this method would return "XMPPExtension".
119+
*
120+
* Note that a file extension should NOT be included.
121+
**/
109122
- (NSString *)managedObjectModelName
110123
{
111-
// This method overrides [XMPPCoreDataStorage managedObjectModelName].
124+
// Optional hook
125+
//
126+
// The default implementation would return "XMPPPRoomHybridStorage".
127+
// We prefer a slightly shorter version.
112128

113129
return @"XMPPRoomHybrid";
114130
}
115131

132+
/**
133+
* Documentation from the superclass (XMPPCoreDataStorage):
134+
*
135+
* Override me, if needed, to provide customized behavior.
136+
*
137+
* For example, if you are using the database for non-persistent data and the model changes, you may want
138+
* to delete the database file if it already exists on disk and a core data migration is not worthwhile.
139+
*
140+
* If this instance was created via initWithDatabaseFilename, then the storePath parameter will be non-nil.
141+
* If this instance was created via initWithInMemoryStore, then the storePath parameter will be nil.
142+
*
143+
* The default implementation simply writes to the XMPP error log.
144+
**/
145+
- (void)didNotAddPersistentStoreWithPath:(NSString *)storePath error:(NSError *)error
146+
{
147+
// Optional hook
148+
//
149+
// If we ever have problems opening the database file,
150+
// it's likely because the model changed or the file became corrupt.
151+
//
152+
// In this case we don't have to worry about migrating the data, because it's all stored on servers.
153+
// So we're just going to delete the sqlite file from disk, and create a new one.
154+
155+
[[NSFileManager defaultManager] removeItemAtPath:storePath error:NULL];
156+
157+
[self addPersistentStoreWithPath:storePath error:NULL];
158+
}
159+
116160
- (void)dealloc
117161
{
118162
[self destroyDeleteTimer];

Extensions/XEP-0115/CoreDataStorage/XMPPCapabilitiesCoreDataStorage.m

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -155,26 +155,32 @@ - (void)_clearAllNonPersistentCapabilitiesForXMPPStream:(XMPPStream *)stream
155155
#pragma mark Overrides
156156
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
157157

158-
- (BOOL)addPersistentStoreWithPath:(NSString *)storePath error:(NSError **)errorPtr
159-
{
160-
BOOL result = [super addPersistentStoreWithPath:storePath error:errorPtr];
161-
162-
if (!result &&
163-
[*errorPtr code] == NSMigrationMissingSourceModelError &&
164-
[[*errorPtr domain] isEqualToString:NSCocoaErrorDomain]) {
165-
// If we get this error while trying to add the persistent store, it most likely means the model changed.
166-
// Since we are caching capabilities, it is safe to delete the persistent store and create a new one.
167-
168-
if ([[NSFileManager defaultManager] fileExistsAtPath:storePath])
169-
{
170-
[[NSFileManager defaultManager] removeItemAtPath:storePath error:nil];
171-
172-
// Try creating the store again, without creating a deletion/creation loop.
173-
result = [super addPersistentStoreWithPath:storePath error:errorPtr];
174-
}
175-
}
176-
177-
return result;
158+
/**
159+
* Documentation from the superclass (XMPPCoreDataStorage):
160+
*
161+
* Override me, if needed, to provide customized behavior.
162+
*
163+
* For example, if you are using the database for non-persistent data and the model changes, you may want
164+
* to delete the database file if it already exists on disk and a core data migration is not worthwhile.
165+
*
166+
* If this instance was created via initWithDatabaseFilename, then the storePath parameter will be non-nil.
167+
* If this instance was created via initWithInMemoryStore, then the storePath parameter will be nil.
168+
*
169+
* The default implementation simply writes to the XMPP error log.
170+
**/
171+
- (void)didNotAddPersistentStoreWithPath:(NSString *)storePath error:(NSError *)error
172+
{
173+
// Optional hook
174+
//
175+
// If we ever have problems opening the database file,
176+
// it's likely because the model changed or the file became corrupt.
177+
//
178+
// In this case we don't have to worry about migrating the data, because it's all stored on servers.
179+
// So we're just going to delete the sqlite file from disk, and create a new one.
180+
181+
[[NSFileManager defaultManager] removeItemAtPath:storePath error:NULL];
182+
183+
[self addPersistentStoreWithPath:storePath error:NULL];
178184
}
179185

180186
- (void)didCreateManagedObjectContext

0 commit comments

Comments
 (0)