Reputation:
I am using sqlite DB to save data.i want to save apps state lifecycle of the app. for that i used sqlite .i have created table with two colums . i am i am able to save data also. but some time i am getting this error DB Error: unknown error .
**DB Error: unknown error**
Could not execute the query.
-(void)executeQuery:(NSString *)query{
// Run the query and indicate that is executable.
[self runQuery:[query UTF8String] isQueryExecutable:YES];
}
-(void)runQuery:(const char *)query isQueryExecutable:(BOOL)queryExecutable{
// Create a sqlite object.
sqlite3 *sqlite3Database;
// Set the database file path.
NSString *databasePath = [self.documentsDirectory stringByAppendingPathComponent:self.databaseFilename];
// Initialize the results array.
if (self.arrResults != nil) {
[self.arrResults removeAllObjects];
self.arrResults = nil;
}
self.arrResults = [[NSMutableArray alloc] init];
// Initialize the column names array.
if (self.arrColumnNames != nil) {
[self.arrColumnNames removeAllObjects];
self.arrColumnNames = nil;
}
self.arrColumnNames = [[NSMutableArray alloc] init];
// Open the database.
BOOL openDatabaseResult = sqlite3_open([databasePath UTF8String], &sqlite3Database);
if(openDatabaseResult == SQLITE_OK) {
// Declare a sqlite3_stmt object in which will be stored the query after having been compiled into a SQLite statement.
sqlite3_stmt *compiledStatement;
// Load all data from database to memory.
BOOL prepareStatementResult = sqlite3_prepare_v2(sqlite3Database, query, -1, &compiledStatement, NULL);
if(prepareStatementResult == SQLITE_OK) {
// Check if the query is non-executable.
if (!queryExecutable){
// In this case data must be loaded from the database.
// Declare an array to keep the data for each fetched row.
NSMutableArray *arrDataRow;
// Loop through the results and add them to the results array row by row.
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Initialize the mutable array that will contain the data of a fetched row.
arrDataRow = [[NSMutableArray alloc] init];
// Get the total number of columns.
int totalColumns = sqlite3_column_count(compiledStatement);
// Go through all columns and fetch each column data.
for (int i=0; i<totalColumns; i++){
// Convert the column data to text (characters).
char *dbDataAsChars = (char *)sqlite3_column_text(compiledStatement, i);
// If there are contents in the currenct column (field) then add them to the current row array.
if (dbDataAsChars != NULL) {
// Convert the characters to string.
[arrDataRow addObject:[NSString stringWithUTF8String:dbDataAsChars]];
}
// Keep the current column name.
if (self.arrColumnNames.count != totalColumns) {
dbDataAsChars = (char *)sqlite3_column_name(compiledStatement, i);
[self.arrColumnNames addObject:[NSString stringWithUTF8String:dbDataAsChars]];
}
}
// Store each fetched data row in the results array, but first check if there is actually data.
if (arrDataRow.count > 0) {
[self.arrResults addObject:arrDataRow];
}
}
}
else {
// This is the case of an executable query (insert, update, ...).
// Execute the query.
BOOL executeQueryResults = sqlite3_step(compiledStatement);
if (executeQueryResults == SQLITE_DONE) {
// Keep the affected rows.
self.affectedRows = sqlite3_changes(sqlite3Database);
// Keep the last inserted row ID.
self.lastInsertedRowID = sqlite3_last_insert_rowid(sqlite3Database);
}
else {
// If could not execute the query show the error message on the debugger.
NSLog(@"DB Error: %s", sqlite3_errmsg(sqlite3Database));
}
}
}
else {
// In the database cannot be opened then show the error message on the debugger.
NSLog(@"%s", sqlite3_errmsg(sqlite3Database));
}
// Release the compiled statement from memory.
sqlite3_finalize(compiledStatement);
}
// Close the database.
sqlite3_close(sqlite3Database);
}
-(void)saveInfo{
// Prepare the query string.
NSString *query = [NSString stringWithFormat:@"insert into processInfo values(null, '%@', '%@')", _timeFormatter, _process];
// Execute the query.
[self.dbManager executeQuery:query];
// If the query was successfully executed then pop the view controller.
if (self.dbManager.affectedRows != 0) {
NSLog(@"Query was executed successfully. Affected rows = %d", self.dbManager.affectedRows);
}
else{
NSLog(@"Could not execute the query.");
}
}
- (void)dateAndTime {
if(!self.dateFormatter) {
self.dateFormatter = [[NSDateFormatter alloc] init];
}
[self.dateFormatter setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
}
//call back
static void displayStatusChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
// the "com.apple.springboard.lockcomplete" notification will always come after the "com.apple.springboard.lockstate" notification
CFStringRef nameCFString = (CFStringRef)name;
NSString *lockState = (__bridge NSString*)nameCFString;
NSLog(@"Darwin notification NAME = %@",name);
if([lockState isEqualToString:@"com.apple.springboard.lockcomplete"])
{
NSLog(@"DEVICE LOCKED");
//Logic to disable the GPS
}
else
{
NSLog(@"LOCK STATUS CHANGED");
//Logic to enable the GPS
}
}
-(void)registerforDeviceLockNotif
{
//Screen lock notifications
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
NULL, // observer
displayStatusChanged, // callback
CFSTR("com.apple.springboard.lockcomplete"), // event name
NULL, // object
CFNotificationSuspensionBehaviorDeliverImmediately);
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
NULL, // observer
displayStatusChanged, // callback
CFSTR("com.apple.springboard.lockstate"), // event name
NULL, // object
CFNotificationSuspensionBehaviorDeliverImmediately);
}
- (void)applicationWillResignActive:(UIApplication *)application {
NSLog(@"\t ----- App will tResignActive %@ -------",[self.dateFormatter stringFromDate:[NSDate date]]);
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(@"\t ----- App in Background at %@ -------",[self.dateFormatter stringFromDate:[NSDate date]]);
_timeFormatter=[self.dateFormatter stringFromDate:[NSDate date]];
_process=@"Background";
[self saveInfo];
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
NSLog(@"\t ----- App in Forground %@ -------",[self.dateFormatter stringFromDate:[NSDate date]]);
_timeFormatter=[self.dateFormatter stringFromDate:[NSDate date]];
_process=@"Forground";
[self saveInfo];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(@"\t ----- App will tResignActive %@ -------",[self.dateFormatter stringFromDate:[NSDate date]]);
[self saveInfo];
}
- (void)applicationWillTerminate:(UIApplication *)application {
NSLog(@"\t ----- App will terminate %@ -------",[self.dateFormatter stringFromDate:[NSDate date]]);
_timeFormatter=[self.dateFormatter stringFromDate:[NSDate date]];
_process=@"terminate";
[self saveInfo];
}
Upvotes: 1
Views: 1373
Reputation: 493
Just Go in your DBmanager file where you do all code regarding query execution.
Ow just do one change on there. write code like this
// Execute the query.
int executeQueryResults = sqlite3_step(compiledStatement);
Note : Instead of Bool just replace int.
its work fine here...i hope it will helpful to you.
Upvotes: 6