I'm developing a game where there are 4 buildings and in these buildings, there are 3 stages inside. The player can play the stages one by one, from one building to another, however, when they have finished one cycle (eg. going from building 1 stage 1 to building 4 stage 3) I keep getting this error where it's an error 14 (SQLITE_CANTOPEN) whenever the player clicks on another building. It keeps happening every single time I test the app. Can anyone help me? :S
edit: sorry, here's the code I used to open the window to access the game:
NSArray *bldgLevels = [[SQLiteManager sharedManager] fetchDataFromDatabase: MAIN_DATABASE
withQuery: SQL_STMT_GET_BUILDING_LEVELS
withValuesAndTypes: [NSArray arrayWithObjects:
[NSString stringWithFormat: @"%d", gameStateProxy.selectedArea], @"i", nil]];
NSLog(@"bldgLevels: %@", bldgLevels);
NSLog(@"getting player levels");
NSArray *playerLevels = [[SQLiteManager sharedManager] fetchDataFromDatabase: MAIN_DATABASE
withQuery: SQL_STMT_GET_PLAYER_UNLOCKED_LEVELS
withValuesAndTypes: [NSArray arrayWithObjects:
[NSString stringWithFormat: @"%d", gameStateProxy.playerId], @"i", nil]];
NSLog(@"playerLevels: %@", playerLevels);
int i = 0;
while (i < [bldgLevels count])
{
NSDictionary *bldgLevel = (NSDictionary *)[bldgLevels objectAtIndex: i];
int levelId = [(NSNumber *)[bldgLevel objectForKey: @"level_id"] intValue];
int indexOrder = [(NSNumber *)[bldgLevel objectForKey: @"index_order"] intValue];
data = [BldgLevelData createObject];
data.levelId = levelId;
data.levelName = (NSString *)[bldgLevel objectForKey: @"name"];
data.rescuedPtsRequired = [(NSNumber *)[bldgLevel objectForKey: @"rescued_required"] intValue];
data.minPtsToComplete = [(NSNumber *)[bldgLevel objectForKey: @"min_pts"] intValue];
data.lastPlayed = @"";
data.dateAdded = @"";
data.isNew = NO;
data.isCompleted = NO;
data.isLocked = YES;
// Group levels together by their index order
if (indexOrder == 1) { groupId++; }
data.groupId = groupId;
data.indexOrder = indexOrder;
int j = 0;
while (j < [playerLevels count])
{
NSDictionary *playerLevel = (NSDictionary *)[playerLevels objectAtIndex: j];
int playerLevelId = [(NSNumber *)[playerLevel objectForKey: @"level_id"] intValue];
if (levelId == playerLevelId)
{
data.rescuedHighScore = [(NSNumber *)[playerLevel objectForKey: @"rescued_highscore"] intValue];
data.rescuedScore = [(NSNumber *)[playerLevel objectForKey: @"rescued_score"] intValue];
data.lastPlayed = (NSString *)[playerLevel objectForKey: @"lastplayed"];
data.dateAdded = (NSString *)[playerLevel objectForKey: @"dateadded"];
data.isNew = ([(NSString *)[playerLevel objectForKey: @"lastplayed"] isEqualToString: @""]);
data.isCompleted = ([(NSNumber *)[playerLevel objectForKey: @"completed"] intValue] == 1);
data.isLocked = NO;
break;
}
j++;
}
if (indexOrder == 1)
{
list = [NSMutableArray arrayWithCapacity: 1];
groupData = [BldgLevelGroupData createObject];
groupData.groupId = groupId;
groupData.firstLevelId = levelId;
groupData.timeLimit = [(NSNumber *)[bldgLevel objectForKey: @"time_limit"] intValue];
groupData.list = list;
// Get SOS items
NSMutableArray *sosItems = [NSMutableArray arrayWithCapacity: 0];
//
NSLog(@"getting levelSOSItems");
NSLog(@"i: %d, j: %d", i, j);
NSLog(@"list: %@", list);
NSLog(@"levelId: %d", levelId);
NSArray *levelSOSItems = [[SQLiteManager sharedManager] fetchDataFromDatabase: MAIN_DATABASE
withQuery: SQL_STMT_GET_LEVEL_SOS
withValuesAndTypes: [NSArray arrayWithObjects:
[NSString stringWithFormat: @"%d", levelId], @"i", nil]];
NSLog(@"Levelsositems: %@", levelSOSItems);
NSLog(@"getting player sos Items");
NSArray *playerSOSItems = [[SQLiteManager sharedManager] fetchDataFromDatabase: MAIN_DATABASE
withQuery: SQL_STMT_GET_PLAYER_SOS
withValuesAndTypes: [NSArray arrayWithObjects:
[NSString stringWithFormat: @"%d", gameStateProxy.playerId], @"i",
nil]];
NSLog(@"playerSoSItems: %@", playerSOSItems);
j = 0;
while (j < [levelSOSItems count])
{
SOSItemData *sosItemData = [SOSItemData createObject];
sosItemData.itemId = [(NSNumber *)[(NSDictionary *)[levelSOSItems objectAtIndex: j] objectForKey: @"sos_id"] intValue];
sosItemData.itemName = (NSString *)[(NSDictionary *)[levelSOSItems objectAtIndex: j] objectForKey: @"name"];
sosItemData.desc = (NSString *)[(NSDictionary *)[levelSOSItems objectAtIndex: j] objectForKey: @"desc"];
sosItemData.coins = [(NSNumber *)[(NSDictionary *)[levelSOSItems objectAtIndex: j] objectForKey: @"coins_cost"] intValue];
sosItemData.cash = [(NSNumber *)[(NSDictionary *)[levelSOSItems objectAtIndex: j] objectForKey: @"cash_cost"] intValue];
sosItemData.rescuedPtsRequired = [(NSNumber *)[(NSDictionary *)[levelSOSItems objectAtIndex: j] objectForKey: @"rescued_required"] intValue];
int k = 0;
while (k < [playerSOSItems count])
{
if ([(NSNumber *)[(NSDictionary *)[playerSOSItems objectAtIndex: k] objectForKey: @"sos_id"] intValue] == sosItemData.itemId)
{
sosItemData.qty = [(NSNumber *)[(NSDictionary *)[playerSOSItems objectAtIndex: k] objectForKey: @"qty"] intValue];
break;
}
k++;
}
//NSLog(@"%@", sosItemData);
[sosItems addObject: sosItemData];
j++;
}
groupData.sosItems = sosItems;
[groupsList addObject: groupData];
}
NSLog(@"%@", data);
[list addObject: data];
i++;
}
and here's the code I used to fetch the data from the database:
-(NSArray *) fetchDataFromDatabase:(NSString *)dbPath withQuery: (NSString *)sql withValuesAndTypes: (NSArray *)params
{ /* dbPath - Name of database file sql - SQL statement. Prepared statements are allowed to be used here (refer to params params - Array containing data and its corresponding data type */
NSMutableArray *result = nil;
//make sure db is closed
NSLog(@"close database first!");
sqlite3_close(database);
NSLog(@"open database!");
int dbStatus = [self openDatabase: dbPath];
if (dbStatus == SQLITE_OK)
{
//int stmtStatus = sqlite3_prepare_v2(database, [sql UTF8String], -1, &stmt, NULL);
int stmtStatus = [self prepareStatement: sql withParams: params];
if(stmtStatus == SQLITE_OK)
{
result = [NSMutableArray arrayWithCapacity: 1];
while(sqlite3_step(stmt) == SQLITE_ROW)
{
NSMutableDictionary *row = [NSMutableDictionary dictionaryWithCapacity: 1];
int columnCount = sqlite3_column_count(stmt);
int j = 0;
while (j < columnCount)
{
/*
Possible sqlite data types:
SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB, SQLITE_NULL
*/
if (sqlite3_column_type(stmt, j) == SQLITE_INTEGER)
{
[row setObject: [NSNumber numberWithInt: sqlite3_column_int(stmt, j)]
forKey: [NSString stringWithUTF8String: sqlite3_column_name(stmt, j)]];
}
else if (sqlite3_column_type(stmt, j) == SQLITE_FLOAT)
{
[row setObject: [NSNumber numberWithDouble: sqlite3_column_double(stmt, j)]
forKey: [NSString stringWithUTF8String: sqlite3_column_name(stmt, j)]];
}
else if (sqlite3_column_type(stmt, j) == SQLITE_TEXT)
{
[row setObject: [NSString stringWithFormat: @"%s", sqlite3_column_text(stmt, j)]
forKey: [NSString stringWithUTF8String: sqlite3_column_name(stmt, j)]];
}
else if (sqlite3_column_type(stmt, j) == SQLITE_NULL)
{
[row setObject: [NSNull null]
forKey: [NSString stringWithUTF8String: sqlite3_column_name(stmt, j)]];
}
j++;
}
[result addObject: row];
}
}
else { NSLog(@"stmt error: %d", stmtStatus); }
}
else if (dbStatus == 14)
{
NSLog(@"db error: %d", dbStatus);
NSLog(@"killing app.");
exit(0);
}
else { NSLog(@"db error: %d", dbStatus); }
//Even though the open call failed, close the database connection to release all the memory.
sqlite3_close(database);
return result;
}