How to use sqlite in ios 7? - iphone

How to use sqlite in ios 7? I'm trying to use code ios 6 and it does not work in ios 7
UPDATE!
I export a database, to desktop, change name and drag and drop to xcode
Add the code:
// SQLite
// Conexion DB
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [paths objectAtIndex:0];
_databasePath = [documentDirectory stringByAppendingPathComponent:#"ambisi_test.sqlite"];
[self loadDB];
// --> End SQLite
-(void)loadDB{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentDirectory stringByAppendingPathComponent:#"ambisi_test.sqlite"];
BOOL exito = [fileManager fileExistsAtPath:writableDBPath];
if(exito) return;
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"ambisi_test.sqlite"];
BOOL exit = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if(!exit) NSLog(#"%#",[error localizedDescription]);
}
- (void) clickFavorites{
sqlite3 *database = NULL;
sqlite3_stmt *sentencia = NULL;
// Si la BD se ha abierto bien
if(sqlite3_open([appDelegate.databasePath UTF8String], &database) == SQLITE_OK){
// Genero la query
NSString *sql = [NSString stringWithFormat:#"INSERT INTO estaciones (\"id_number\", \"name\",\"addres\",\"latitude\",\"longitude\") VALUES (\"%i\",\"%#\",\"%#\",\"%f\",\"%f\")", self.modelAnnotation.number, self.modelAnnotation.name,self.modelAnnotation.address, self.modelAnnotation.lat,self.modelAnnotation.lng];
NSLog(#"%#",sql);
// Si esta no contien errores
if(sqlite3_prepare_v2(database, [sql UTF8String], -1, &sentencia, NULL)==SQLITE_OK){
// Si la estación no existe ya como favorita, la almacenaré, o en el caso contrario la elimnaré
if(![self isFavoriteWithIdStation:self.modelAnnotation.number database:database]){
// Insisto hasta que se inserte
if (sqlite3_step(sentencia) != SQLITE_DONE){
NSLog(#"Error in INSERT step: %s", sqlite3_errmsg(database));
}else{
// Ademas de cambiarle la imagen
UIImage *image = [UIImage imageNamed:#"quitar-favorito"];
[_button setBackgroundImage:image forState:UIControlStateNormal];
}
}else{ // La elimino de favoritas
// Genero la query
NSString *sql = [NSString stringWithFormat:#"DELETE FROM estaciones WHERE id_number = \"%i\"",self.modelAnnotation.number];
// Si esta no contien errores
if(sqlite3_prepare_v2(database, [sql UTF8String], -1, &sentencia, NULL)==SQLITE_OK){
// Insisto hasta que se inserte
if (sqlite3_step(sentencia) != SQLITE_DONE){
NSLog(#"Error in DELETE step: %s", sqlite3_errmsg(database));
}else{
// Ademas de cambiarle la imagen
UIImage *image = [UIImage imageNamed:#"addfav"];
[_button setBackgroundImage:image forState:UIControlStateNormal];
}
}
}
}else{
NSLog(#"Error making INSERT: %s",sqlite3_errmsg(database));
}
sqlite3_finalize(sentencia);
}else{
NSLog(#"Doesn't open Database: %s",sqlite3_errmsg(database));
}
sqlite3_close(database);
}
- (BOOL) isFavoriteWithIdStation:(int) idStation database:(sqlite3 *)db{
sqlite3_stmt *sentencia = NULL;
NSString *sql = [NSString stringWithFormat:#"SELECT id_number FROM estaciones"];
NSLog(#"%i",idStation);
NSString * ide = [NSString stringWithFormat:#"%i",idStation];
if(sqlite3_prepare_v2(db, [sql UTF8String], -1, &sentencia, NULL)==SQLITE_OK){
while(sqlite3_step(sentencia) == SQLITE_ROW){
NSLog(#"%i",idStation);
NSString *number = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sentencia, 0)];
//NSString *id_tutorialString = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
if([number isEqualToString:ide]){
NSLog(#"NUMBER:%#",number);
NSLog(#"NUMBER:%i",idStation);
sqlite3_finalize(sentencia);
return YES;
}else{
NSLog(#"Error en el condicional");
}
}
}else{
NSLog(#"Error making SELCET: %s",sqlite3_errmsg(db));
}
sqlite3_finalize(sentencia);
return NO;
}
The error is triggered in the
NSLog (# "Error making INSERT:% s", sqlite3_errmsg (database));
and the response has been making INSERT Error: file is encrypted or is not a database
I've also tried to recreate the DB and import it several times, but still with the same error..
In the iOS simulator iOS 6 if it works but in iOS7 is not working ... is rare, someone tried to use SQLite in iOS7? ..
I hope you can help me, thanks!

You should look at error codes.
Thus, the line that says:
NSLog(#"Error making INSERT");
should say:
NSLog(#"Error making INSERT: %s", sqlite3_errmsg(database));
Likewise the line that says:
NSLog(#"Error la SELECT");
should say:
NSLog(#"Error la SELECT: %s", sqlite3_errmsg(database));
Only by looking at those error messages can you effectively diagnose the problem.
You report that it says: "file is encrypted or is not a database"
That suggests that your database has gotten corrupted somehow (assuming you never used encryption). You'll want to recreate it.
Unrelated to your broader problem, your code for the INSERT statement bears a line that says:
// Insisto hasta que se inserte
while(sqlite3_step(sentencia) == SQLITE_OK);
That should be:
if (sqlite3_step(sentencia) != SQLITE_DONE)
NSLog(#"Error in INSERT step: %s", sqlite3_errmsg(database));

Solved!
The main mistake I committed in exporting the database using firefox plugin ..
The solution is to store the desired location without export, at the time of the creation of the database ..
I hope if someone happens to have the same, here is the solution, thanks for your interest for #Rob and #Hot Licks..

Related

sqlite 3 opening issue

I'm getting my data ,with several similar methods, from sqlite3 file like in following code:
-(NSMutableArray *) getCountersByID:(NSString *) championID{
NSMutableArray *arrayOfCounters;
arrayOfCounters = [[NSMutableArray alloc] init];
#try {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *databasePath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"DatabaseCounters.sqlite"];
BOOL success = [fileManager fileExistsAtPath:databasePath];
if (!success) {
NSLog(#"cannot connect to Database! at filepath %#",databasePath);
}
else{
NSLog (#"SUCCESS getCountersByID!!");
}
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK){
NSString *tempString = [NSString stringWithFormat:#"SELECT COUNTER_ID FROM COUNTERS WHERE CHAMPION_ID = %#",championID];
const char *sql = [tempString cStringUsingEncoding:NSASCIIStringEncoding];
sqlite3_stmt *sqlStatement;
int ret = sqlite3_prepare(database, sql, -1, &sqlStatement, NULL);
if (ret != SQLITE_OK) {
NSLog(#"Error calling sqlite3_prepare: %d", ret);
}
if(sqlite3_prepare_v2(database, sql, -1, &sqlStatement, NULL) == SQLITE_OK){
while (sqlite3_step(sqlStatement)==SQLITE_ROW) {
counterList *CounterList = [[counterList alloc]init];
CounterList.counterID = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,0)];
[arrayOfCounters addObject:CounterList];
}
}
else{
NSLog(#"problem with database prepare");
}
sqlite3_finalize(sqlStatement);
}
else{
NSLog(#"problem with database openning %s",sqlite3_errmsg(database));
}
}
#catch (NSException *exception){
NSLog(#"An exception occured: %#", [exception reason]);
}
#finally{
sqlite3_close(database);
return arrayOfCounters;
}
//end
}
then i'm getting access to data with this and other similar lines of code:
myCounterList *MyCounterList = [[myCounterList alloc] init];
countersTempArray = [MyCounterList getCountersByID:"2"];
[countersArray addObject:[NSString stringWithFormat:#"%#",(((counterList *) [countersTempArray objectAtIndex:i]).counterID)]];
I'm getting a lot of data like image name and showing combination of them that depends on users input with such code:
UIImage *tempImage = [UIImage imageNamed:[NSString stringWithFormat:#"%#_0.jpg",[countersArray objectAtIndex:0]]];
[championSelection setBackgroundImage:tempImage forState:UIControlStateNormal];
My problem:
When i'm run my app for some time and get a lot of data it throws error: " problem with database openning unable to open database file - error = 24 (Too many open files)"
My guess is that i'm opening my database every time when getCountersByID is called but not closing it.
My question:
Am i using right approach to open and close database that i use?
Similar questions that did not helped me to solve this problem:
unable to open database
Sqlite Opening Error : Unable to open database
UPDATE:
I made assumption that error is showing up because i use this lines of code too much:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *databasePath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"DatabaseCounters.sqlite"];
BOOL success = [fileManager fileExistsAtPath:databasePath];
and ending up with error 24.
So i made them global but sqlite3_errmsg shows same err 24, but app runs much faster now
You should open your DB only once basically when you are in the initialization phase but not when you are requesting some info to your DB. Your code shouldn't failed though since you seems to open then close the DB after each request. Make sure this is happening by either logging those events or debugging through your code.
The code you've shown does close the database, so it's likely that you forget to close it in some other place, or that some other file is opened repeatedly but never closed.

Universal application DB question

I'm making an universal application for both iPhone and iPad and I was wondering if there is an specific location where I have to put my sqlite database? Because apperently he can't find it and giving a result of not being able to open the database! = app not working :/
Currently I have my database in the "Other Sources" folder.
//Maakt een lijst van path strings voor de specifieke directories voor de specifieke domains.
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//Eerste object van paths wordt in de string gezet!
NSString *documentsDir = [documentPaths objectAtIndex:0];
//er wordt gezocht naar todo.sqlite in het opgegeven path!
NSString *databasePath = [documentsDir stringByAppendingPathComponent:#"todo.sqlite"];
pad = databasePath;
if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
status = TRUE; //DEBUG PURPOSES ONLY!
const char *sql = "SELECT pk FROM todo";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
int primaryKey = sqlite3_column_int(statement, 0);
Taak *taak = [[Taak alloc] initWithPrimaryKey:primaryKey database:database];
[taken addObject:taak];
[taak release];
}
}
sqlite3_finalize(statement);
}else {
status = FALSE; //DEBUG PURPOSES ONLY!
sqlite3_close(database);
NSAssert1(0, #"Failed to open database with message '%s'.", sqlite3_errmsg(database));
}
This is my connection code and I searched a lot of forums and tutorials and everyone is doing it like that!
if(sqlite3_open([databasepath UTF8String], &database) == SQLITE_OK) {
const char* sqlStatement;
sqlStatement="select fld_carromdescription from tbl_carrom where fld_carromdetails like?";
sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL);
printf( "could not prepare statemnt: %s\n", sqlite3_errmsg(database));
if( sqlite3_prepare_v2(database, sqlStatement, -1, & compiledStatement, NULL) == SQLITE_OK ) {
sqlite3_bind_text(compiledStatement,1,[[usdflt objectForKey:#"phone"] UTF8String] , -1,SQLITE_STATIC);
NSLog(#"Database check111");
// [tablearray removeAllObjects];
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
printf("in loop");
#try {
NSLog(#"Database check");
txtview.text=[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement,0)];
toplbl.text=[usdflt valueForKey:#"phone"];
[txtview scrollRangeToVisible:NSMakeRange(0, 0)];
}
#catch (NSException * e) {
}
#finally {
}
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
Try this out.
I am also using the sqliteDB in other sources only. I have done 3 universal applications. I have no difficulties to get the access.

How to use sqlite3_column_blob with NSData

How to use sqlite3_column_blob with NSData what parameter I need to pass
In my iPhone App I want to retrive image stored in NSData format in sqlite database in BLOB datatype
for retriving it
//select query
NSString *selectQuery = [NSString stringWithFormat:#"select image_column from tbl_image where id=1"];
NSArray *arraySelect = [database executeQuery:selectQuery];
//displaying image
NSData *imageData = [[arraySelect objectAtIndex:0] valueForKey:#"image_column"];
self.img3=[UIImage imageWithData:imageData];
imageView.image=img3;
from above code I am not able to display image
so please help and suggest
thanks
sqlite *database;
sqlite3_stmt *Stmt;
sqlite3_open([[self getDBPath] UTF8String],&database)
- (NSString *) getDBPath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:#"XXX.sqlite"];
}
NSData*thumbnailData;
//Inserting Thumbnail Data
NSString *lSQL = [NSString stringWithFormat:#"insert into Table(Thumbnail1) values(?)"];
if(sqlite3_prepare_v2(database, [lSQL UTF8String], -1, &Stmt, NULL) == SQLITE_OK)
{
sqlite3_bind_blob(Stmt, 1,[thumbnailData bytes], [thumbnailData length], NULL);
sqlite3_step(Stmt);
sqlite3_reset(Stmt);
if(Stmt)
sqlite3_finalize(Stmt);
}
//Fetching Thumbnail Data
NSString *lSQL = [NSString stringWithFormat:#"select Thumbnail1 from table"];
if(sqlite3_prepare_v2(database, [lSQL UTF8String], -1, &Stmt, NULL) == SQLITE_OK)
{
while(sqlite3_step(Stmt) == SQLITE_ROW)
{
NSString *myColNameNSString = [NSString stringWithFormat:#"%s", sqlite3_column_name(Stmt)];
if ([myColNameNSString isEqualToString:#"Thumbnail1"])
{
thumbnailData = [[NSData alloc] initWithBytes:sqlite3_column_blob(Stmt) length:sqlite3_column_bytes(Stmt)];
}
}
}
Hey, I don't what are your project requirements. I would not use BLOB unless it's required to.
reason is you are storing image file into sqlite, everytime you have to use the file you have access the database, process the file and use. which will be fairly easy and simple in terms of number of threads you are running if you use images directly form the disk. give a thought about it. Good Luck

SQLite Out of Memory when preparing insert statement

I have a problem with my app it opens this database and selects rows from it ok,
Then when I want to add new rows using the following code and I always get the following problem at the execution of the prepare_V2.
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error while creating add statement. 'out of memory''
code is .....
static sqlite3 *database = nil;
static sqlite3_stmt *addStmt = nil;
- (BOOL)addUserprofile {
addStmt = nil; // set to force open for testing
database = nil; // set to force creation of addstmt for testing
if (database == nil) { // first time then open database
NSString *databaseName = #"UserProfile.db";
// Use editable database paths
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
NSLog(#"path = %#",databasePath);
NSLog(#"opening Database");
sqlite3 *database;
// Open the database from the users filessytem
if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
NSLog(#"Database Open");
}
else {
NSLog(#"Database did not open");
}
}
if(addStmt == nil) {
NSLog(#"Creating add stmt");
const char *sql = "INSERT INTO Profile (ProfileName) VALUES(?)";
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK) {
NSAssert1(0, #"** Error while creating add statement. '%s'", sqlite3_errmsg(database));
success = NO;
return success;
}
}
sqlite3_bind_text(addStmt, 1, [ProfileName UTF8String], -1, SQLITE_TRANSIENT);
Sometime, your database is being SQLITE_BUSY or SQLITE_LOCKED.
You can refer this framework to know how to do:
https://github.com/ccgus/fmdb
Good luck!:)

iphone sqlite3 object allocation memory up but no leaks

i've been trying to figure out wh. sqy my object allocation keeps rigth up every time i call this function, Instruments reports no leaks but I get a heck of a lot of object coming from
sqlite3_exec --> sqlite3Prepare --> sqlite3Parser --> yy_reduce --> malloc & also a whole bunch from
& from
sqlite3Step --> sqlite3VdbeExec --> sqlite3BtreeInsert --> malloc
I tried solving it by following the suggestions posted here: http://www.iphonedevsdk.com/forum/iphone-sdk-development/7092-sqlite3-database-gobbling-up-memory.html but haven't been able to fix it
ANY HELP is appreciated, my code is below
+(void)getDesignationsInLibrary:(NSString *)library
{
NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];
NSString *dbName = #"s8.sqlite";
NSArray *documentPaths = \
NSSearchPathForDirectoriesInDomains \
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = \
[documentPaths objectAtIndex:0];
NSString *databasePath = \
[documentsDir stringByAppendingPathComponent:dbName];
[[DT sharedDT].designationsInLibrary removeAllObjects];
NSString *sqlString;
for(int i=0;i<[[DT sharedDT].typesInLibrary count];i++)
{
if(sqlite3_open([databasePath UTF8String], &db)==SQLITE_OK)
{
if (sqlite3_exec(db, "PRAGMA CACHE_SIZE=50;", NULL, NULL, NULL) != SQLITE_OK) {
NSAssert1(0, #"Error: failed to set cache size with message '%s'.", sqlite3_errmsg(db));
}
NSMutableString *lib=[NSMutableString stringWithString:library];
[lib appendString:#"-"];
[lib appendString:[[DT sharedDT].typesInLibrary objectAtIndex:i]];
if([DT sharedDT].sortedBy==#"AISC Default")
{
sqlString = [NSString stringWithFormat:#"select DESIGNATION from \"%#\";",lib];
}
else
{
sqlString = [NSString stringWithFormat:#"select DESIGNATION from \"%#\" order by cast(%# as numeric) %#;",lib, [DT sharedDT].sortedBy, [DT sharedDT].sortAscDesc];
}
const char *sql = [sqlString cStringUsingEncoding:NSASCIIStringEncoding];
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(db,sql,-1,&selectstmt, NULL)==SQLITE_OK)
{
while(sqlite3_step(selectstmt)==SQLITE_ROW)
{
[[DT sharedDT].designationsInLibrary addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt,0)]];
}
sqlite3_finalize(selectstmt);
selectstmt=nil;
}
}
}
sqlite3_close(db);
[localPool release];
}
It seems, that you're opening db on every loop cycle, but close only once, before function exit
So try to change:
}
sqlite3_close(db);
[localPool release];
}
to
sqlite3_close(db);
}
[localPool release];
}
Or even better change:
for(int i=0;i [[DT sharedDT].typesInLibrary count];i++)
{
if(sqlite3_open([databasePath UTF8String], &db)==SQLITE_OK)
{
if (sqlite3_exec(db, "PRAGMA CACHE_SIZE=50;", NULL, NULL, NULL) != SQLITE_OK) {
NSAssert1(0, #"Error: failed to set cache size with message '%s'.", sqlite3_errmsg(db));
}
to:
if(sqlite3_open([databasePath UTF8String], &db)==SQLITE_OK)
{
if (sqlite3_exec(db, "PRAGMA CACHE_SIZE=50;", NULL, NULL, NULL) != SQLITE_OK) {
NSAssert1(0, #"Error: failed to set cache size with message '%s'.", sqlite3_errmsg(db));
}
for(int i=0;i [[DT sharedDT].typesInLibrary count];i++)
{
...
because you're always open the same database
Try invoking sqlite3_exec with:
pragma cache_size=1
Sqlite seems to gobble up memory for caching.