2016-07-22 80 views
0

我收到錯誤數據庫鎖定。 在第一次嘗試它添加行,但之後,我得到錯誤 database locked第2次添加行時出現數據庫鎖定錯誤

我想在第一次製作網頁保護程序時,應用程序加載它是添加行,但當我再次嘗試保存任何網頁,它不是保存,我得到錯誤數據庫鎖定。

即使保存一個網頁後,刪除也沒有發生。

#import "DBManager.h" 
static DBManager *sharedInstance = nil; 
static sqlite3 *database = nil; 
static sqlite3_stmt *statement = nil; 

@implementation DBManager 

+(DBManager*)getSharedInstance{ 
if (!sharedInstance) { 
    sharedInstance = [[super allocWithZone:NULL]init]; 
    [sharedInstance createDB]; 
} 
return sharedInstance; 
} 

-(BOOL)createDB{ 
NSString *docsDir; 
NSArray *dirPaths; 
// Get the documents directory 
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
docsDir = dirPaths[0]; 
// Build the path to the database file 
databasePath = [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent: @"browser.db"]]; 

BOOL isSuccess = YES; 
NSFileManager *filemgr = [NSFileManager defaultManager]; 
if ([filemgr fileExistsAtPath: databasePath ] == NO) 
{ 
    const char *dbpath = [databasePath UTF8String]; 
    if (sqlite3_open(dbpath, &database) == SQLITE_OK) 
    { 
     char *errMsg; 
     NSLog(@"insod"); 
     const char *sql_stmt ="create table if not exists list(sno int primary key,name varchar(50),category varchar(30),path varchar(500),fav int)"; 
     if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) 
      != SQLITE_OK) 
     { 
      isSuccess = NO; 
      NSLog(@"Failed to create table"); 
     } 
     sqlite3_close(database); 
     return isSuccess; 
    } 
    else { 
     isSuccess = NO; 
     NSLog(@"Failed to open/create database"); 
    } 
}else{ 
    NSLog(@"File Exist"); 
} 
return isSuccess; 
} 

-(BOOL) Delete:(NSString *) name{ 
const char *dbpath = [databasePath UTF8String]; 
if (sqlite3_open(dbpath, &database) == SQLITE_OK){ 
    NSString *query = [NSString stringWithFormat:@"delete from list where name like '%@'",name]; 
    const char *stmt = [query UTF8String]; 
    sqlite3_prepare_v2(database, stmt,-1, &statement, NULL); 
    if (sqlite3_step(statement) == SQLITE_DONE){ 
     sqlite3_finalize(statement); 
     return YES; 
    }else { 
     NSLog(@"error: %s",sqlite3_errmsg(database)); 
     sqlite3_finalize(statement); 
     return NO; 
    } 

}else{ 
    sqlite3_close(database); 
    return NO; 
} 

} 

-(NSDictionary *) CatList:(NSString *) cat{ 
const char *dbpath = [databasePath UTF8String]; 
NSDictionary *dict; 
if (sqlite3_open(dbpath, &database) == SQLITE_OK) 
{ 

    NSString *querySQL =[NSString stringWithFormat:@"select name,path from list where category like '%@'",cat]; 
    const char *query_stmt = [querySQL UTF8String]; 

    if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK) 
    { 
     // NSLog(@"inside list"); 

     NSMutableArray *arr1 = [[NSMutableArray alloc] init]; 
     NSMutableArray *arr2 = [[NSMutableArray alloc] init]; 
     //   NSMutableArray *arr3 = [[NSMutableArray alloc] init]; 
     while(sqlite3_step(statement) == SQLITE_ROW) 
     { 

      NSString *name = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)]; 
      [arr1 addObject:name]; 
      //NSLog(@"%@",name); 
      NSString *category = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)]; 
      [arr2 addObject:category]; 
      //    //NSLog(@"%@",dept); 
      //    NSString *path = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 3)]; 
      //    [arr3 addObject:path]; 
     } 
     sqlite3_finalize(statement); 
     dict = @{@"name":arr1,@"path":arr2}; 
     //NSLog(@"%@",dict); 
    }else{ 
     NSLog(@"error: %s",sqlite3_errmsg(database)); 
    } 
    sqlite3_close(database); 
} 
return dict; 
} 

- (BOOL) saveData:(NSString*)name category:(NSString*)category path:(NSString*)path{ 
const char *dbpath = [databasePath UTF8String]; 
if (sqlite3_open(dbpath, &database) == SQLITE_OK) 
{ 

    NSString *highest = @"select max(sno) from list"; 
    const char *Query = [highest UTF8String]; 

    if (sqlite3_prepare_v2(database, Query, -1, &statement, NULL) == SQLITE_OK){ 
     if (sqlite3_step(statement) == SQLITE_ROW){ 
      int sno = sqlite3_column_int(statement, 0); 
      NSString *insertSQL = [NSString stringWithFormat:@"insert into list values(\"%d\",\"%@\",\"%@\", \"%@\",\"%d\")",sno+1,name, category, path,0]; 
      const char *insert_stmt = [insertSQL UTF8String]; 
      sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL); 
      if (sqlite3_step(statement) == SQLITE_DONE){ 
       sqlite3_finalize(statement); 
       return YES; 
      }else { 
       sqlite3_finalize(statement); 
       return NO; 
      } 

     }else{ 
      NSString *insertSQL = [NSString stringWithFormat:@"insert into list values(\"%d\",\"%@\",\"%@\", \"%@\",\"%d\")",1,name, category, path,0]; 
      const char *insert_stmt = [insertSQL UTF8String]; 
      sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL); 
      if (sqlite3_step(statement) == SQLITE_DONE){ 
       sqlite3_finalize(statement); 
       return YES; 
      }else { 
       sqlite3_finalize(statement); 
       return NO; 
      } 
     } 
    } 
    sqlite3_close(database); 
} 
return NO; 
} 

-(BOOL) Fav:(NSString *) name{ 
const char *dbpath = [databasePath UTF8String]; 
if (sqlite3_open(dbpath, &database) == SQLITE_OK){ 
    NSString *query = [NSString stringWithFormat:@"update list set fav = 1 where name like '%@'",name]; 
    const char *stmt = [query UTF8String]; 
    sqlite3_prepare_v2(database, stmt,-1, &statement, NULL); 
    if (sqlite3_step(statement) == SQLITE_DONE){ 
     sqlite3_finalize(statement); 
     return YES; 
    }else { 
     sqlite3_finalize(statement); 
     return NO; 
    } 
}else{ 

    return NO; 
} 
} 

-(NSArray *) GetListFav{ 
const char *dbpath = [databasePath UTF8String]; 
NSArray *dict; 
if (sqlite3_open(dbpath, &database) == SQLITE_OK) 
{ 

    NSString *querySQL = @"select name from list where fav = 1"; 
    const char *query_stmt = [querySQL UTF8String]; 

    if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK) 
    { 
     NSMutableArray *arr1 = [[NSMutableArray alloc] init]; 
     while(sqlite3_step(statement) == SQLITE_ROW) 
     { 
      NSString *name = [[NSString alloc] initWithUTF8String:    (const char *) sqlite3_column_text(statement, 0)]; 
      [arr1 addObject:name]; 
     } 
     sqlite3_finalize(statement); 
     dict = arr1; 
    }else{ 
     NSLog(@"error: %s",sqlite3_errmsg(database)); 
    } 
    sqlite3_close(database); 
} 
return dict; 
} 

-(BOOL) removeFav:(NSString *) name{ 
const char *dbpath = [databasePath UTF8String]; 
if (sqlite3_open(dbpath, &database) == SQLITE_OK){ 
    NSString *query = [NSString stringWithFormat:@"update list set fav = 0 where name like '%@'",name]; 
    const char *stmt = [query UTF8String]; 
    sqlite3_prepare_v2(database, stmt,-1, &statement, NULL); 
    if (sqlite3_step(statement) == SQLITE_DONE){ 
     sqlite3_finalize(statement); 
     return YES; 
    }else { 
     sqlite3_finalize(statement); 
     return NO; 
    } 

}else{ 
    return NO; 
} 
} 

-(NSArray *) GetList{ 
const char *dbpath = [databasePath UTF8String]; 
NSArray *dict; 
if (sqlite3_open(dbpath, &database) == SQLITE_OK) 
{ 

    NSString *querySQL = @"select name from list"; 
    const char *query_stmt = [querySQL UTF8String]; 

    if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK) 
    { 
     //NSLog(@"inside list"); 

     NSMutableArray *arr1 = [[NSMutableArray alloc] init]; 
     while(sqlite3_step(statement) == SQLITE_ROW) 
     { 
      NSString *name = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)]; 
      [arr1 addObject:name]; 
     } 
     sqlite3_finalize(statement); 
     dict = arr1; 
    }else{ 
     NSLog(@"error: %s",sqlite3_errmsg(database)); 
    } 
    sqlite3_close(database); 
} 
return dict; 
    } 

@end 

回答

0

您一次只能訪問一次sqllite。如果你有多個線程,你可以運行在這種情況下。例如:

所以總是試圖關閉數據庫,一旦使用使用:

sqlite3_close(database); 
0

你需要嘗試再做sqlite3_open之前,爲了確保每一個sqlite3_open平衡與sqlite3_close

  1. 您的saveData方法有很多return語句會阻止數據庫曾經調用sqlite3_close。確保該方法的所有路徑都正確關閉數據庫。最後,這意味着您將嘗試打開數據庫,儘管它已經打開。或者,更好的是,只需打開一次數據庫並將其保持打開狀態,即可消除數據庫的反覆打開和關閉。

  2. 您的Delete,FavremoveFav方法也不關閉數據庫。

數無關意見:

  • 你應該警惕有關使用stringWithFormat建立與字符串參數SQL。如果正在搜索的字符串中有撇號,則代碼將失敗。使用?佔位符,然後使用sqlite3_bind_text將值綁定到這些佔位符。

  • 如果您將sno列設置爲AUTOINCREMENT,則不必在「插入新行之前獲取最大sno」邏輯。因此,CREATE語句可能看起來像:

    create table if not exists list (
        sno integer primary key autoincrement, 
        name text, 
        category text, 
        path text, 
        fav integer) 
    

    然後,您可以省略從INSERT聲明sno,它會自動分配一個唯一的標識符。