So here's my goal: I need to attach a sync database to my main database and update or replace any fields into my main database. So I first attach my database. I then attempt to go through all the tables. Here's the quirky part: inside of my master query string, when I say: SELECT name FROM sqlite_master the if statement does not execute and says "Error: not an error." Now, when I tell the master query to SELECT name FROM sync_db.sqlite_master, the if statement executes. However, I get an error saying that no such table: sync_db.sqlite_master exists. Could someone perhaps walk me through the proper protocol? Thanks in advance.
//Atataching the sync db to the master db
NSString *attachSQL = [NSString stringWithFormat:@"ATTACH DATABASE \'%@\' AS sync_db", dbPathSync];
NSLog(@"Here's the arratch string: %@", attachSQL);
//
if ((errorNum = sqlite3_exec(mainOpenHandle, [attachSQL UTF8String], NULL, NULL, &errorMessage)) == SQLITE_OK) {
NSString *masterQuery = [NSString stringWithFormat:@"SELECT name FROM sync_db.sqlite_master WHERE type='table';"];
const char *masterStmt = [masterQuery UTF8String];
sqlite3_stmt *statement;
//If statement does not execute and prints error saying "not an error" when
//place SELECT from "sqlite_master" inside master query.
if (sqlite3_prepare_v2(syncOpenHandle, masterStmt, -1, &statement, NULL)) {
while (sqlite3_step(statement) == SQLITE_ROW) {
NSString * currentTable = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
NSLog(@"Here's the current table: %@",currentTable);
//This is where the magic happens. If there are any keys matching the database, it will update them. If there are no current keys in the database, the query will insert them.
if ([currentTable isEqualToString:@"USER_DATA"] == NO && [currentTable isEqualToString:@"USER_ACTIVITY"]== NO && [currentTable isEqualToString:@"USER_ITINERARY"] == NO) {
NSString *tblUpdate = [NSString stringWithFormat:@"INSERT or REPLACE INTO main.%@ SELECT * FROM sync_db.%@;",currentTable, currentTable];
const char *updateStmt = [tblUpdate UTF8String];
if ((errorNum = sqlite3_exec(mainOpenHandle, updateStmt, NULL, NULL, &errorMessage))!= SQLITE_OK) {
if (errorNum == 1) {
//A database reset is needded
self->isResetDataBase = YES;
}
dbErr = YES;
}
}
}
NSLog(@"Error sync ... '%s'", sqlite3_errmsg(syncOpenHandle));
}
NSLog(@"Erorr syncing the database: Code: %d, message: '%s'", error,sqlite3_errmsg(mainOpenHandle));
NSLog(@"Error sync ... '%s'", sqlite3_errmsg(syncOpenHandle));
sqlite3_finalize(statement);
//Detaching the database from the mainDB
NSString *detachSQL = [NSString stringWithFormat:@"DETACH DATABASE sync_db"]; // reference sync db
if ((errorNum = sqlite3_exec(mainOpenHandle, [detachSQL UTF8String], NULL, NULL, &errorMessage))!= SQLITE_OK) {
NSLog(@"Detatched syncDb Failed. ErrorMessage = %s ", errorMessage);
}
}
}
NSLog(@"Error sync ... '%s'", sqlite3_errmsg(syncOpenHandle));
//Closing the database when finished.
if (mainOpenHandle != nil) {
sqlite3_close(self.mainOpenHandle);
}
if (syncOpenHandle != nil) {
sqlite3_close(self.syncOpenHandle);
NSError *err;
int success = [fileManager fileExistsAtPath:dbPathSync];
if (success) {
[[NSFileManager defaultManager]removeItemAtPath:dbPathSync error: &error];
}
}
if (userOpenHandle != nil) {
sqlite3_close(self.userOpenHandle);
}
I then attempt to loop through all the rows. But here's the quirky part. Inside of
1 Answer 1
You should compare the result of sqlite3_prepare_v2 to SQLITE_OK.
When you simply do:
if (sqlite3_prepare_v2(syncOpenHandle, masterStmt, -1, &statement, NULL)) {
then the if statement will only succeed if there is an error. You want:
if (sqlite3_prepare_v2(syncOpenHandle, masterStmt, -1, &statement, NULL) == SQLITE_OK) {
You should also update your code to only log errors in the else block of the if statement.
if (sqlite3_prepare_v2(syncOpenHandle, masterStmt, -1, &statement, NULL) == SQLITE_OK) {
// process query
} else {
// log error here
}