Select data from SQLite - ios

Here is my code, and error is visible also:
In SQLite Manager from Mozzila Firefox - all queries work fine which means that DB is correct
Maybe someone can piont me out what is wrong with my code?
EDIT:
My code:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:#"stories_db.sqlite"];
FMDatabase *db = [FMDatabase databaseWithPath:path];
//[db open];
if ([db open]==true)
{
FMResultSet *resultsFavorite = [db executeQuery:#"SELECT count(*) from favorites"];
while ([resultsFavorite next])
{
Pasaka *pasaka = [[Pasaka alloc]init];
pasaka.title = [resultsFavorite stringForColumn:#"story_name"];
pasaka.image = [resultsFavorite stringForColumn:#"image_path"];
pasaka.movie = [resultsFavorite stringForColumn:#"video_path"];
[favoriteMovieList addObject:pasaka];
}
}
EDIT 2:
When i do this query:
FMResultSet *results = [db executeQuery:#"SELECT count(*) FROM sqlite_master"];
it doesn't show any errors.

You need to copy your database to your document folder first (also check if your sqlite file was properly added in the Copy Bundle Resources in Build Phases of your project setting):
//Where your original database file is
bundleDatabasePath = [[NSBundle mainBundle] pathForResource:#"stories_db" ofType:#"sqlite"];
//Where you will copy it in order to be used
documentDatabasePath = [[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"] stringByAppendingString:#"/stories_db.sqlite"];
//Using the default file manager
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
//Copy empty database into document folder
if (![fileManager copyItemAtPath:bundleDatabasePath toPath:databasePath error:&error]) {
//Error
NSLog(#"Could not copy the database into document folder. Error:%#", error);
}
//Use DB
FMDatabase *db = [FMDatabase databaseWithPath:databasePath];

Reset iOS Simulator or if you are testing on device delete app,
Clean project and run again..

Just go to your document that you have got in the dbpath. seems like you your table is not present there . Just delete your app from device or simulator and manually copy the database at dbpath or copy it using NSFileManager and run your code again .

Found a solution. Moved my database file on top of the project... O.o and it worked...

Related

File missing in iOS

I have an iOS app which locates its database in what I believe is a fairly standard manner, viz:
+ (NSString *)dbPath
{
NSArray *a =
NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
NSUserDomainMask, YES);
NSString *dir = [a objectAtIndex:0];
return [dir stringByAppendingPathComponent:[self dbFile]];
}
Here dbFile is a function that just returns the name of the database file.
Recently users have complained that the app sometimes fails to find its database. Is there anything I am doing wrong? I have not been keeping abreast of the latest changes in iOS.
I also save db in caches in current project.Whenever user run the app,it finds db correctly.Mainly I use with FMDB.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *documentsDirectory = [documentsDir stringByAppendingPathComponent:strFileName];
if (![[NSFileManager defaultManager] fileExistsAtPath:documentsDirectory])
{
NSString *backupDbPath = [[NSBundle mainBundle] pathForResource:#"DBName" ofType:#"sqlite"];
NSLog(#"Test backuppath %#",backupDbPath);
if (backupDbPath == nil)
{
NSLog(#"Database path is nil");
}
else
{
BOOL copiedBackupDb = [[NSFileManager defaultManager] copyItemAtPath:backupDbPath toPath:documentsDirectory error:nil];
if (!copiedBackupDb) NSLog(#"Copying database failed");
}
}
Now I remember.
An app store reviewer told me that I could not store the database in the directory that I originally intended to use, because its contents were downloaded from the internet. He was wrong of course, but I was having a lot of trouble with them at the time, so I just moved the database to the cache area as requested.
That is why is sometimes gets deleted.

SQLite file in project catalogue, use fmdb open it failed

I create a table in SQLite Manager and export it to desktop , its name is db_fo_dic.sqlite, and I can open the db_fo_dic.sqlite use SQLite Manager, so I copy the db_fo_dic.sqlite to my Xcode project catalogue, I try to open the sqlite file by FMDB, but it failed:
NSString *path = [[NSBundle mainBundle] pathForResource:#"db_fo_dic" ofType:#"sqlite"];
FMDatabase *db = [FMDatabase databaseWithPath:path];
The result info is :
2016-08-01 19:22:34.955 test_sqlite[15380:425242] The FMDatabase <FMDatabase: 0x7ff589c38f10> is not open.
This is the location path of my sqlite:
/Users/youpude/Library/Developer/CoreSimulator/Devices/87D0245A-47F7-4741-81B2-209625CB3C5E/data/Containers/Bundle/Application/47B3AD1F-C08E-4E34-8858-494A95FB9EA5/test_sqlite.app/db_fo_dic.sqlite
8 hours go through, I find the method to solve my problem finally.
#import "FMDatabaseQueue.h"
static FMDatabaseQueue *_queue;
in - (void)viewDidLoad:
_queue = [FMDatabaseQueue databaseQueueWithPath:path];
and I can query my database:
[_queue inDatabase:^(FMDatabase *db) {
FMResultSet *result = [db executeQuery:#"select * from dic_content limit 10;"];
while ([result next]) {
NSString *str = [result stringForColumn:#"tit"];
NSLog(#"%#",str);
}
}];
I use this method to replace the previous method.
You don't have write permission for content stored in app bundle. So you have to first copy your database to document directory. For more details about permissions of file system in iOS refer Apple documentation for file system.
So you can do something like,
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
self.documentsDirectory = [paths objectAtIndex:0];
self.databaseFilename = dbFilename;
NSString* destinationPath = [self.documentsDirectory stringByAppendingPathComponent:self.databaseFilename];
if (![[NSFileManager defaultManager]fileExistsAtPath:destinationPath]) {
NSString *sourcePath = [[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:self.databaseFilename];
NSError *error;
[[NSFileManager defaultManager]copyItemAtPath:sourcePath toPath:destinationPath error:&error];
if (error != nil) {
NSLog(#"%#",[error localizedDescription]);
}
}
here dbFilename is your database's name (in your case : db_fo_dic.sqlite).
After doing this, try to open database from destination path and it will work i think!

How to view Sqlite database ios

I am developing one iOS app in that I am using sqlite database.I have inserted records in database now I want to see that records.I searched in Library->Application Support->iPhone simulator, But in iPhone simulator folder nothing is present.So is there any another way to view sqlite database records.
Please help me,
Thank you.
This is my code for file path
-(NSString *)filePath
{
NSString *documentDir=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
return [documentDir stringByAppendingPathComponent:#"Test.sqlite"];
}
Now you can have your Simulator folder as "Core Simulator" not as "iPhone simulator"
Use the following Code.
// Get the Sqlite Data from the url in a NSData Object
NSData *sqlData = [[NSData alloc] initWithContentsOfURL:[
NSURL URLWithString:[sqlUrlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
// Store the Data locally as Sqlite File
NSString *resourceDocPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [resourceDocPath
stringByAppendingPathComponent:#"Test.sqlite"];
[sqlData writeToFile:filePath atomically:YES];
NSLog(#"File Path: %#", filePath);
In Console as:
File Path:
/Users/Library/Developer/CoreSimulator/Devices/3C0492CE-2C27-48D8-AB04-7B7EFDB77228/data/Containers/Data/Application/91AF3E65-D0C2-4CC9-A7F6-35DD32AB1FD0/Documents/Test.sqlite
Now You can easily go to your database file path and open it where ever you want.
You can achieve this by using a simple code and opening the Sqlite file in to a simple Sqlite Client like chrome extension(SqliteManager), Firefox Extension and Navicat Premium.
Code:
-(NSString *)GetDocumentDirectory
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *documentsDir = [paths objectAtIndex:0];
return documentsDir;
}
-(NSString *)getDBPath
{
NSString *documentsDir = [self GetDocumentDirectory];
return [documentsDir stringByAppendingPathComponent:#"YourSqliteFileName.sqlite"];
}
Call it like this
NSString *dbPath = [self getDBPath];
NSLog(#"Database Path = %#",dbPath);
Note: Every time you will run your application on simulator, Every time a new path is created which will be different from your previous path so you have to just copy paste this path and open it in any Sqlite Client.

SQLite database always empty (FMDB)

I'm doing a very classic routine that i've done multiple times, but in this project, its not working. When I want to work with my DB, I get " No such tables " errors. Which should be wrong. I checked the bundle database and its fine ; I checked the "result" db in the phone and its completly empty (no structure, and obviously no data).
Here is my DB creation routine. I call it every time I need the database.
+ (FMDatabase*)createAndCheckDataBase{
BOOL success;
NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [docPaths objectAtIndex:0];
NSString *databasePath = [documentsDir stringByAppendingPathComponent:#"database.sqlite"];
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:databasePath];
//The database already exist in the application folder, we don't need to create it
if(success){
return [FMDatabase databaseWithPath:databasePath];
}
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"database.sqlite"];
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
return [FMDatabase databaseWithPath:databasePath];
Then i just do FMDatabase *db = [DatabaseManager createAndCheckDatabase];and i supposedly get my db. But i don't.
I created the sqlite database using the SQLite Manager plugin from Firefox, created the structure there, then imported it into the bundle.
Note : success always return true.
Any help is most welcome!
As the comments mentioned, you need to check the copy.
Here's a snippet from my code which checks whether the copy succeeded and returns the error details to the consumer
//
// notice our method to prepare the db returns bool and doesn't lose the error details
// the consumer can log, present, whatever - this is a library function
//
- (BOOL)ensureDatabasePrepared: (NSError **)error
{
// <snip bunch of code>
// copy db from template to library
if (![[NSFileManager defaultManager] fileExistsAtPath:_dbPath])
{
NSLog(#"db not exists");
// notice how we pass in the error ref passed to this function
if (![[NSFileManager defaultManager] copyItemAtPath:dbTemplatePath toPath:_dbPath error:error])
{
return NO;
}
NSLog(#"copied");
}

FMDB Database not working on device, but it is working in Simulator

I have this database that i created, i want to load it using FMDB, but on the simulator i can query select the data, but not on the ipad.
i use this code to check it.
- (void)createDatabase{
//set reference to database here
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// Database filename can have extension db/sqlite.
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appDBPath = [documentsDirectory stringByAppendingPathComponent:#"product.db"];
success = [fileManager fileExistsAtPath:appDBPath];
if (success) {
[self getAllData];
return;
}
// The writable database does not exist, so copy the default to the appropriate location.
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"product.db"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:appDBPath error:&error];
NSAssert(success, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
[self getAllData];
}
//method used to create database and check if it exists
- (void)getAllData {
// Getting the database path.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *dbPath = [docsPath stringByAppendingPathComponent:#"product.db"];
database = [FMDatabase databaseWithPath:dbPath];
[database open];
NSString *sqlSelectQuery = #"SELECT * FROM Categories";
// Query result
FMResultSet *resultsWithNameLocation = [database executeQuery:sqlSelectQuery];
while([resultsWithNameLocation next]) {
NSString *strID = [NSString stringWithFormat:#"%d",[resultsWithNameLocation intForColumn:#"id"]];
NSString *strName = [NSString stringWithFormat:#"%#",[resultsWithNameLocation stringForColumn:#"cat"]];
NSString *strLoc = [NSString stringWithFormat:#"%#",[resultsWithNameLocation stringForColumn:#"Location"]];
// loading your data into the array, dictionaries.
NSLog(#"ID = %#, Name = %#, Location = %#",strID, strName, strLoc);
}
[database close];
}
i put the product.db in the supporting files, and i copied it in the Copy Bundle Resources for the targets. Does anyone what i am doing wrong? i am kind of at a dead end here.
Thanks in advance
The problem occurs at the selecting stage, when i select it it returns:
"DB Error: 1 "no such table"
If you ever ran the app on the device before you refined the file open/copy logic, you may have accidentally created a blank database in the documents folder (because if you open a database and it's not found, it creates a blank database). Try deleting the app (which will remove any blank database that might be lingering about) and reinstalling the app and see if that fixes it.
By the way, in the future, you can avoid this problem by using openWithFlags (rather than open) with SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE), and that will ensure that the app never creates a blank database if it doesn't find one.
You can see the SQLite documentation on sqlite3_open (which FMDB open uses) and sqlite_open_v2 (which FMDB openWithFlags uses) for a discussion of these flags.

Resources