My app has a SQLite database. I don't know how to explain, but sometimes all tables from the sqlite file gets deleted. It doesn't happen frequently but it happens. The .db file still exists but no tables.
I use this code to open and get the .db from documents directory.
#pragma mark LOCAL DATABASE
-(void)createEditableCopyOfDatabaseIfNeeded {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"Spread.sqlite"];
BOOL success = [fileManager fileExistsAtPath:writableDBPath];
if (success) {
return;
}
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"Spread.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success) {
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
} else {
NSLog(#"Spread - DB Created");
}
}
+(FMDatabase *) getDatabase {
static FMDatabase *db;
if (!db) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"Spread.sqlite"];
FMDatabase *db = [FMDatabase databaseWithPath:writableDBPath];
[db open];
return db;
} else {
return db;
}
}
Related
In my app I am doing read ,write and delete on sqlite database(in db form) and it work fine in simulator but not working in actual device (giving error: No such table found).I try very hard to look for solution but couldn't find one or may be i misread something.
My db is in the
/users/My Name/library/developer/Core
simulator/devices/devicen-id/data/application/app-id/documents/My
database.
- (NSString *) getWritableDBPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:mydaatabase];
}
I am confuse where did i need to copy my database while running in the actual iOS device and what is the core problem.Any help regarding this will be very helpful
-(void)createEditableCopyOfDatabaseIfNeeded
{
BOOL success;
NSFileManager *fileManager1 = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:mydaatabase];
NSLog(#"=======%#", writableDBPath);
success = [fileManager1 fileExistsAtPath:writableDBPath];
if (success)
return;
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:mydaatabase];
NSLog(#"=======%#", [NSBundle mainBundle]);
success = [fileManager1 copyItemAtPath:defaultDBPath
toPath:writableDBPath
error:&error];
if(!success)
{
NSAssert1(0,#"Failed to create writable database file with Message : '%#'.",
[error localizedDescription]);
}
}
Check your .sqlite file is added to your Copy Bundle Resources in Build Phases of your project. If it is not there, add it in your project.
Moreover, I can't find code for opening the database. So, in your ViewController.h file, declare Sqlite *database;
In your ViewController.m file,
-(void)databaseOpen
{
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory=[paths objectAtIndex:0];
NSString *myDBnew=[documentsDirectory stringByAppendingPathComponent:#"yourSqliteFile.sqlite"];
database =[[Sqlite alloc]init];
[database open:myDBnew];
NSLog(#"path: %#", myDBnew);
NSLog(#"Database opened");
}
and call it wherever you want as [self databaseOpen]; and then write your query.
Also, your -(void)createEditableCopyOfDatabaseIfNeeded should look something like this in your AppDelegate.m:
- (void)createEditableCopyOfDatabaseIfNeeded
{
// First, test for existence.
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"yourSqliteFile.sqlite"];
success = [fileManager fileExistsAtPath:writableDBPath];
if (success) return;
// The writable database does not exist, so copy the default to the appropriate location.
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"yourSqliteFile.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success) {
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
Call -(void)createEditableCopyOfDatabaseIfNeeded in didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[self createEditableCopyOfDatabaseIfNeeded];
return YES;
}
This should get you going.
Here are steps to working with SQLite Database.
Create your database in SQLite, add required table with well structure. and add it to your application.
Now, go to your app, select project from left panel, in middle panel -> General -> Linked Frameworks and Libraries(Last one) add libsqlite3.0.tbd (it is depend upon your Xcode version.)
Now, define below methods in your-object.h
#import <sqlite3.h>
+ (NSString *)getDBPath;
+ (void)copyDatabaseIfNeeded;
+ (void)openDatase;
Implement these in your-object.m
static sqlite3 *database;
#pragma mark - Copy and open databse
+ (NSString *)getDBPath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stirngByAppendingPathComponent:#"dbName.sqlite"];
}
+ (void)copyDatabaseIfNeeded
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dbPath = [self getDBPath];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success)
{
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"dbName.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
+ (void)openDatase
{
NSString *dbPath = [self getDBPath];
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
NSLog(#"Database Successfully Opened.");
}
else
{
NSLog(#"Error in opening database.");
}
}
Then call method in AppDelegate.m in application: didFinishLaunchingWithOptions:
[DataManager copyDatabaseIfNeeded];
Whenever you want to perform task with database, open it and check.
For inserting in database
+ (void)insertData
{
const char *dbpath = [[self getDBPath] UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *strSQL = [NSString stringWithFormat:#"INSERT INTO table name………………."];
const char *insertQuery = [strSQL UTF8String];
sqlite3_stmt *insert_stmt;
if (sqlite3_prepare_v2(database, insertQuery, -1, &insert_stmt, NULL) == SQLITE_OK)
{
if (sqlite3_step(insert_stmt) == SQLITE_DONE)
{
// Code
}
else
{
NSLog(#"error");
}
}
sqlite3_finalize(insert_stmt);
sqlite3_close(database);
}
}
7. Completed.... enjoy with database.
Everytime I run my app, database address is changed so my update or retrieval is not successfully working.
Any one can help me why this is happening with me... here my code to copy my database to the directory.
(BOOL)createDB
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dbPath = [self getDBPath];
dataPath=dbPath;
databasePath = dbPath;
NSLog(#"Path is: %#",dbPath);
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success) {
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"babynames.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
return success;
}
Here is getDBPathCode
- (NSString *)getDBPath
{`NSSearchPathForDirectoriesInDomains`
//Search for standard documents using NSSearchPathForDirectoriesInDomains
//First Param = Searching the documents directory
//Second Param = Searching the Users directory and not the System
//Expand any tildes and identify home directories.
'NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
//NSLog(#"dbpath : %#",documentsDir);
return [documentsDir stringByAppendingPathComponent:#"babynames.sqlite"];'
}
What is better way to copy sqlite database file(.db) in ios application means that in NSBundle or in Document folder.
You can try this
- (void)createEditableCopyOfDatabaseIfNeeded
{
// First, test for existence.
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"DB.sqlite"];
success = [fileManager fileExistsAtPath:writableDBPath];
if (success) return;
// The writable database does not exist, so copy the default to the appropriate location.
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"KURANDB2.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success) {
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
I am a newbie here. I am not able to insert any data into my SQLite database when running on my device. I am using the below piece of code to connect SQLite. It works perfect in my simulator but doesn't work on my iPad device. Can anyone help please? Thank you.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"DADatabase1.sqlite"];
NSLog(#"%#", writableDBPath);
FMDatabase* db = [FMDatabase databaseWithPath:writableDBPath];
/*if ([fileManager fileExistsAtPath:writableDBPath] == NO) {
NSString *resourcePath = [[NSBundle mainBundle] pathForResource:#"DADatabase1.sqlite" ofType:#"sqlite"];
[fileManager copyItemAtPath:resourcePath toPath:writableDBPath error:nil];
}*/
[db open];
[db traceExecution];
[db beginTransaction];
BOOL success = [db executeUpdate:[NSString stringWithFormat:#"insert into PatientDetails (patAge) values (?)",patAge.text]];
if(!success)
{
NSLog(#"Query not success!");
}
else {
NSLog(#"Query success!");
}
//NSString *query = [NSString stringWithFormat:];
[db commit];
[db close];
Did you put your Database with your Tables in your Projects resources folder? You have to copy your database file to your Apps Document folder.
+ (BOOL)initDB {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"sqlite.db"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path])
{
NSString *bundle = [[ NSBundle mainBundle] pathForResource:#"sqlite" ofType:#"db"];
[fileManager copyItemAtPath:bundle toPath:path error:nil];
return YES;
}
return NO;
}
The sample code provided doesn't have a CREATE TABLE statement. The INSERT has nowhere to insert to. Did you create the table manually (using the sqlite3 command line tool) while you were developing in the simulator?
NOTE that:
File names in simulator is not case sensitive, but in device is case sensitive. Make sure your file name is exactly same.
I use sqlite and fmdb wrapper. My code for load db is this:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:#"biscuit.sqlite"];
FMDatabase *db = [FMDatabase databaseWithPath:path];
I add biscuit.sqlite to my project, but this code create new file instead open existing one. How can I load this file?
If you only want to read data from your database, try to use the code below:
NSString *path = [[NSBundle mainBundle] pathForResource:#"biscuit" ofType:#"sqlite"];
If you need read/write access, you have to copy your database to a writable user folder first.
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *dbPath = [documentsDir stringByAppendingPathComponent:#"biscuit.sqlite"];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if (!success) {
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"biscuit.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success) {
NSLog(#"Failed to create writable DB. Error '%#'.", [error localizedDescription]);
} else {
NSLog(#"DB copied.");
}
}else {
NSLog(#"DB exists, no need to copy.");
}