Modify YapDatabase to read converted database.

pull/1/head
Matthew Chen 7 years ago
parent 0a2439937b
commit 9801689c0e

@ -164,7 +164,6 @@ const NSUInteger kSqliteHeaderLength = 32;
{ {
NSData *keyData = databasePassword; NSData *keyData = databasePassword;
// Setting the encrypted database page size
status = sqlite3_key(db, [keyData bytes], (int)[keyData length]); status = sqlite3_key(db, [keyData bytes], (int)[keyData length]);
if (status != SQLITE_OK) { if (status != SQLITE_OK) {
DDLogError(@"Error setting SQLCipher key: %d %s", status, sqlite3_errmsg(db)); DDLogError(@"Error setting SQLCipher key: %d %s", status, sqlite3_errmsg(db));
@ -177,10 +176,11 @@ const NSUInteger kSqliteHeaderLength = 32;
// //
// This block was derived from [Yapdatabase configureDatabase]. // This block was derived from [Yapdatabase configureDatabase].
{ {
status = sqlite3_exec(db, "PRAGMA journal_mode = WAL;", NULL, NULL, NULL); NSError *_Nullable error = [self executeSql:@"PRAGMA journal_mode = WAL;"
if (status != SQLITE_OK) { db:db
DDLogError(@"Error setting PRAGMA journal_mode: %d %s", status, sqlite3_errmsg(db)); label:@"PRAGMA journal_mode = WAL"];
return OWSErrorWithCodeDescription(OWSErrorCodeDatabaseConversionFatalError, @"Failed to set WAL mode"); if (error) {
return error;
} }
// TODO verify we need to do this. // TODO verify we need to do this.
@ -197,11 +197,11 @@ const NSUInteger kSqliteHeaderLength = 32;
// (This sqlite db is also used to perform checkpoints. // (This sqlite db is also used to perform checkpoints.
// But a normal value won't affect these operations, // But a normal value won't affect these operations,
// as they will perform sync operations whether the connection is normal or full.) // as they will perform sync operations whether the connection is normal or full.)
status = sqlite3_exec(db, "PRAGMA synchronous = NORMAL;", NULL, NULL, NULL);
if (status != SQLITE_OK) { error = [self executeSql:@"PRAGMA synchronous = NORMAL;"
DDLogError(@"Error setting PRAGMA synchronous: %d %s", status, sqlite3_errmsg(db)); db:db
// This isn't critical, so we can continue. label:@"PRAGMA synchronous = NORMAL"];
} // Any error isn't critical, so we can continue.
// Set journal_size_imit. // Set journal_size_imit.
// //
@ -211,12 +211,10 @@ const NSUInteger kSqliteHeaderLength = 32;
NSInteger defaultPragmaJournalSizeLimit = 0; NSInteger defaultPragmaJournalSizeLimit = 0;
NSString *pragma_journal_size_limit = NSString *pragma_journal_size_limit =
[NSString stringWithFormat:@"PRAGMA journal_size_limit = %ld;", (long)defaultPragmaJournalSizeLimit]; [NSString stringWithFormat:@"PRAGMA journal_size_limit = %ld;", (long)defaultPragmaJournalSizeLimit];
error = [self executeSql:pragma_journal_size_limit
status = sqlite3_exec(db, [pragma_journal_size_limit UTF8String], NULL, NULL, NULL); db:db
if (status != SQLITE_OK) { label:@"PRAGMA journal_size_limit"];
DDLogError(@"Error setting PRAGMA journal_size_limit: %d %s", status, sqlite3_errmsg(db)); // Any error isn't critical, so we can continue.
// This isn't critical, so we can continue.
}
// Disable autocheckpointing. // Disable autocheckpointing.
// //
@ -257,7 +255,7 @@ const NSUInteger kSqliteHeaderLength = 32;
OWSAssert(valueBytes != NULL); OWSAssert(valueBytes != NULL);
NSString *saltString = NSString *saltString =
[[NSString alloc] initWithBytes:valueBytes length:valueLength encoding:NSUTF8StringEncoding]; [[NSString alloc] initWithBytes:valueBytes length:(NSUInteger) valueLength encoding:NSUTF8StringEncoding];
sqlite3_finalize(statement); sqlite3_finalize(statement);
statement = NULL; statement = NULL;
@ -273,29 +271,34 @@ const NSUInteger kSqliteHeaderLength = 32;
// SQLCipher migration // SQLCipher migration
{ {
NSString *setPlainTextHeaderPragma = NSString *setPlainTextHeaderPragma =
[NSString stringWithFormat:@"PRAGMA cipher_plaintext_header_size = %zd;", kSqliteHeaderLength]; [NSString stringWithFormat:@"PRAGMA cipher_plaintext_header_size = %zd;", kSqliteHeaderLength];
NSError *_Nullable error = [self executeSql:setPlainTextHeaderPragma
db:db
label:setPlainTextHeaderPragma];
if (error) {
return error;
}
status = sqlite3_exec(db, [setPlainTextHeaderPragma UTF8String], NULL, NULL, NULL); NSString *setDefaultPlainTextHeaderPragma =
if (status != SQLITE_OK) { [NSString stringWithFormat:@"PRAGMA cipher_default_plaintext_header_size = %zd;", kSqliteHeaderLength];
DDLogError(@"Error setting PRAGMA cipher_plaintext_header_size = %zd: status: %d, error: %s", error = [self executeSql:setDefaultPlainTextHeaderPragma
kSqliteHeaderLength, db:db
status, label:setDefaultPlainTextHeaderPragma];
sqlite3_errmsg(db)); if (error) {
return OWSErrorWithCodeDescription( return error;
OWSErrorCodeDatabaseConversionFatalError, @"Failed to set PRAGMA cipher_plaintext_header_size");
} }
// Modify the first page, so that SQLCipher will overwrite, respecting our new cipher_plaintext_header_size // Modify the first page, so that SQLCipher will overwrite, respecting our new cipher_plaintext_header_size
NSString *tableName = [NSString stringWithFormat:@"signal-migration-%@", [NSUUID new].UUIDString]; NSString *tableName = [NSString stringWithFormat:@"signal-migration-%@", [NSUUID new].UUIDString];
NSString *modificationSQL = NSString *modificationSQL =
[NSString stringWithFormat:@"CREATE TABLE \"%@\"(a integer); INSERT INTO \"%@\"(a) VALUES (1);", [NSString stringWithFormat:@"CREATE TABLE \"%@\"(a integer); INSERT INTO \"%@\"(a) VALUES (1);",
tableName, tableName,
tableName]; tableName];
DDLogInfo(@"%@ modificationSQL: %@", self.logTag, modificationSQL); error = [self executeSql:modificationSQL
status = sqlite3_exec(db, [modificationSQL UTF8String], NULL, NULL, NULL); db:db
if (status != SQLITE_OK) { label:modificationSQL];
DDLogError(@"%@ Error modifying first page: %d, error: %s", self.logTag, status, sqlite3_errmsg(db)); if (error) {
return OWSErrorWithCodeDescription(OWSErrorCodeDatabaseConversionFatalError, @"Error modifying first page"); return error;
} }
// Force a checkpoint so that the plaintext is written to the actual DB file, not just living in the WAL. // Force a checkpoint so that the plaintext is written to the actual DB file, not just living in the WAL.
@ -308,6 +311,27 @@ const NSUInteger kSqliteHeaderLength = 32;
return nil; return nil;
} }
+ (nullable NSError *)executeSql:(NSString *)sql
db:(sqlite3 *)db
label:(NSString *)label
{
OWSAssert(db);
OWSAssert(sql.length > 0);
DDLogVerbose(@"%@ %@", self.logTag, sql);
int status = sqlite3_exec(db, [sql UTF8String], NULL, NULL, NULL);
if (status != SQLITE_OK) {
DDLogError(@"Error %@: status: %d, error: %s",
label,
status,
sqlite3_errmsg(db));
return OWSErrorWithCodeDescription(
OWSErrorCodeDatabaseConversionFatalError, [NSString stringWithFormat:@"Failed to set %@", label]);
}
return nil;
}
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

Loading…
Cancel
Save