Searching SQLite3 DB in iPhone from input given in UITextfield - iphone

I am fairly new to iOS development. I am trying to build application which searches given search term in sqllite3 DB. I am having trouble with binding parameter to that sql statement.Following is my code to read data from database.
-(void) readPlayersFromDatabase
{
NSString * strTemp=[[NSString alloc]init];
strTemp=#"ben";
sqlite3 *database;
players = [[NSMutableArray alloc] init];
if(sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
char *sqlStatement = "SELECT * FROM Player WHERE LENGTH (lastname)>0 AND LENGTH (firstname)>0 AND ( lastname LIKE '%?%' OR firstname LIKE'%?%' OR Height LIKE '%?%' OR Weight LIKE '%?%') ORDER BY lastname,firstname";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK)
{
sqlite3_bind_text(compiledStatement, 1, [strTemp UTF8String],-1, SQLITE_TRANSIENT );
sqlite3_bind_text(compiledStatement, 2, [strTemp UTF8String],-1, SQLITE_TRANSIENT );
sqlite3_bind_text(compiledStatement, 3, [strTemp UTF8String],-1, SQLITE_TRANSIENT );
sqlite3_bind_text(compiledStatement, 4, [strTemp UTF8String],-1, SQLITE_TRANSIENT );
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
NSString *playerId = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
NSString *playerName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
Player *temp = [[Player alloc] initWithID:playerId name:playerName];
[players addObject:temp];
[temp release];
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
All I am getting at the end is name of player which has ? in their name. Can anyone help me out here. Can you also tell me how can I connect UITextfield input to the strTemp in above code ?
Thanks.

What do you want to do exactly? You can send as a parameter to your readPlayersFromDatabase method to your UITextfield input.
Here is my method to select command: I had a class which is called DBOperations. I hope that helps
+ (int) getUserID{
//check DB
if (![DBOperations checkDB])
{
NSString *msgAlert = #"can not access db file.";
UIAlertView *alert = [[UIAlertView alloc] initWithTitle: #"Connection error" message:msgAlert
delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
[alert release];
return 0;
}
[DBOperations open];
int _userID = 1;
const char* sql = " select id from Oyuncu ORDER BY id desc";
if (sqlite3_prepare_v2(database, sql, -1, &hydrate_statement, NULL) != SQLITE_OK) {
NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
if (sqlite3_step(hydrate_statement)==SQLITE_ROW)
{
_userID= sqlite3_column_int(hydrate_statement,0);
NSLog(#"%d",_userID);
}
// Execute the query.
sqlite3_finalize(hydrate_statement);
return _userID;
[DBOperations close];
}
+(BOOL) checkDB {
NSError *error;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"dbOyun.db"];
BOOL success = [fileManager fileExistsAtPath:writableDBPath];
success = [fileManager fileExistsAtPath:writableDBPath];
if (success) return true;
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"dbOyun.db"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
return success;
}
+ (void) open{
//check db validity
NSString *dbPath;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
dbPath = [documentsDirectory stringByAppendingPathComponent:#"dbOyun.db"];
if (sqlite3_open([dbPath UTF8String], &database) != SQLITE_OK) {
sqlite3_close(database);
NSAssert1(0, #"Failed to open database with message '%s'.", sqlite3_errmsg(database));
}
}

Related

how to insert values in sqlite

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dbPath =[documentsDir stringByAppendingPathComponent:#"register.sqlite"];
BOOL success = [fileManager fileExistsAtPath:dbPath];
sqlite3_stmt *selectstmt;
if(!success)
{
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"register.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
sql = "select lastname,email,firstname from reg_FORM";
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
lastname = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 0)];
email=[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)];
firstname=[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 2)];
NSLog(#"----%#",lastname);
NSLog(#"----%#",email);
NSLog(#"----%#",firstname);
}
sqlite3_finalize(selectstmt);
}
sqlite3_close(database);
}
I am using this code to retrieve the values in db, but I did know how to insert data in db. I am trying this below code but it does not work
const char *sql = "insert into reg_FORM (firstname,lastname,email,company,phone) VALUES (aaa,aaa,aaa,aaaa,1223)";
sqlite3_exec(database, [[NSString stringWithFormat:#"insert into reg_FORM (firstname,lastname,email,company,phone) VALUES (aaa,aaa,aaa,aaaa,1223)"] UTF8String], NULL, NULL, NULL);
//give code for insert values in db
{
BOOL returnValue = YES;
sqlite3_stmt *insertStmt = nil;
sqlite3 *UserDB ;
if (sqlite3_config(SQLITE_CONFIG_SERIALIZED) == SQLITE_OK)
{
NSLog(#"Can now use sqlite on multiple threads, using the same connection");
}
int ret = sqlite3_enable_shared_cache(1);
if(ret != SQLITE_OK)
{
}
// Open the database. The database was prepared outside the application.
if (sqlite3_open([app.dataBasePath UTF8String], &UserDB) == SQLITE_OK)
{
if(insertStmt == nil)
{
NSString *strValue = [NSString stringWithFormat:#"insert into languagemaster Values(?,?)"];
const char *sql = [strValue UTF8String];
if(sqlite3_prepare_v2(UserDB, sql, -1, &insertStmt, NULL) != SQLITE_OK)
{
NSLog(#"Error while creating insertStmt in tblUserAccount %#", [NSString stringWithUTF8String:(char *)sqlite3_errmsg(UserDB)]);
returnValue = NO;
}
}
if(sqlite3_bind_int(insertStmt, 1, langid) ) // langid is int
{
return NO;
}
if(sqlite3_bind_text(insertStmt, 2, [strLanguageName UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK) // strLanguageName is string
{
return NO;
}
if(SQLITE_DONE != sqlite3_step(insertStmt))
{
NSLog(#"Error while Executing insertStmt in tblLocation %#", [NSString stringWithUTF8String:(char *)sqlite3_errmsg(UserDB)]);
returnValue = NO;
}
sqlite3_reset(insertStmt);
if (insertStmt)
{
sqlite3_finalize(insertStmt);
insertStmt = nil;
}
}
sqlite3_close(UserDB);
return returnValue;
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dbPath =[documentsDir stringByAppendingPathComponent:#"register.sqlite"];
BOOL success = [fileManager fileExistsAtPath:dbPath];
sqlite3_stmt *selectstmt;
if(!success)
{
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"register.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
const char *sql = "insert into reg_FORM (firstname,lastname,email,company,phone) VALUES ('sdcbb','bbbb','bbbb','bbbb',1111122)";
sqlite3_prepare_v2(database,sql, -1, &selectstmt, NULL);
if(sqlite3_step(selectstmt)==SQLITE_DONE)
{
NSLog(#"insert successfully");
}
else
{
NSLog(#"insert not successfully");
}
sqlite3_finalize(selectstmt);
sqlite3_close(database);
}

SQLite issue: sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) not working

-(void)myDatabaseFunction
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"HHAuditToolDatabase.sqlite"];
if (sqlite3_open([writableDBPath UTF8String], &database) == SQLITE_OK){
NSLog(#"opening db");
NSString *keyValue;
NSString *sqlStr = #"SELECT * FROM HHAuditTable";
//following if() not working dude!!!!
//its working with !=SQLITE_OK
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
sqlite3_stmt *addStmt = nil;
if(sqlite3_prepare_v2(database,[sqlStr UTF8String], -1, &addStmt, NULL) != SQLITE_OK){
NSLog(#"%#",sqlStr);
while (sqlite3_step(addStmt) == SQLITE_ROW) {
const unsigned char *querry_returns = sqlite3_column_text(addStmt, 0);
keyValue = [[NSString alloc]initWithUTF8String:(char *) sqlite3_column_text(addStmt, 0)];
}
NSLog(#"value from DB = %#",keyValue);
That if() with comment doesn't work....Some have a cure!!! i have been on it for last 3 hrs....please come up with a soln
You are opening the database twice. You should have to close the database connection and then you have to open the database again. That is why it is not working.
Hay you can use my code its working fine for me:-
(void)myDatabaseFunction {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
dbPath = [self getDBPath];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success) {
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"flipsy.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
NSString *sql = #"SELECT * FROM HHAuditTable";
NSInteger *intvalue;
result = [[NSMutableArray alloc] init];
// NSLog(#"sql--------->%#",sql);
const char *sqlStatement = [sql UTF8String];
//if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
if(sqlite3_prepare_v2(database, sqlStatement, -1, &selectstmt , NULL)!= SQLITE_OK) {
}
else {
//NSLog(#"%#",dataTypeArray);
for(int i=0;i<[dataTypeArray count];i++) {
temp = [[NSMutableArray alloc] init];
[result addObject:temp];
// [temp release];
}
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
for(int i=0;i<[dataTypeArray count];i++) {
switch( [[dataTypeArray objectAtIndex:i] integerValue] ) {
case 0:
intvalue = (NSInteger *)sqlite3_column_int(selectstmt,i);
strvalue = [NSString stringWithFormat:#"%d",intvalue];
[[result objectAtIndex:i] addObject:(NSNumber *)strvalue];
break;
case 1:
[[result objectAtIndex:i] addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, i)]];
break;
case 2:
blob = [[NSData alloc] initWithBytes:sqlite3_column_blob(selectstmt, i) length:sqlite3_column_bytes(selectstmt, i)];
[[result objectAtIndex:i] addObject:blob];
[blob autorelease];
break;
default:
defaultValue=[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, i)];
break;
}//switch
}//for(int i=0;i<[dataTypeArray count];i++)
}//while(sqlite3_step(selectstmt) == SQLITE_ROW)
//}//else
//sqlite3_close(database);
sqlite3_finalize(selectstmt);
[temp release];
}//if (sqlite3_open([dbPath UTF
}
- (NSString *) getDBPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:#"flipsy.sqlite"];
}
Please let me know if any clarification needed

how to check in database for new row insert or not in iphone and simulator

hi friend please help some one i want to see in my data base in table were my new row was add or not how can i see that
please some one give me demo code or chek my code in proper what my mistak
here my appdeleget class method
-(void)checkAndCreateDB {
NSString* databaseName = #"demo.sqlite";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
NSString *databasePath=[documentsDir stringByAppendingPathComponent:#"demo.sqlite"];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:databasePath];
if(success) return;
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}
-(void)insertData{
sqlite3 *database;
sqlite3_stmt *statement=nil;
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
NSString *databasePath=[documentsDir stringByAppendingPathComponent:#"demo.sqlite"];
if (sqlite3_open([databasePath UTF8String], &database) != SQLITE_OK)
{
sqlite3_close(database); NSAssert(0, #"Failed to open database");
}
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO User (uname,id,password,message) VALUES (\"%#\",\"%d\", \"%#\", \"%#\")",Gmessage,1 ,Glocation,Gjourney];
if(sqlite3_prepare_v2(database, [insertSQL UTF8String], -1, &statement, NULL)!= SQLITE_OK)
{
sqlite3_bind_text(statement, 1, [Gjourney UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 2, [Glocation UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 3, [Gmessage UTF8String], -1, SQLITE_TRANSIENT);
if (SQLITE_DONE !=sqlite3_step(statement))
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Add Record" message:#"Contact Added" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
alert=nil;
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"record" message:#"record not created" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
alert=nil;
}
sqlite3_reset(statement);
}
sqlite3_finalize(statement);
}
Here is my controller class button code
-(IBAction)Start:(id)sender{
Gjourney=mTextJourney.text;
Glocation=mTextLocation.text;
Gmessage=mDescription.text;
AddListAppDelegate *appDelegate =(AddListAppDelegate *)[[UIApplication sharedApplication]delegate];
[appDelegate insertData];
}
You can use the sqlite3_last_insert_rowid function to check if the row was added or not, as long as you're not accessing the database from multiple threads, etc.

the SQLiteBooks sample code is missing

I find this link everywhere for SQLite sample code (http://developer.apple.com/library/ios/#samplecode/SQLiteBooks/index.html) but either it has been removed or changed to another location.. I couldn't find it in google searches.. Does anyone know any other link to the code or any other good sample code for SQLite?
May be this is useful to you.
http://www.switchonthecode.com/tutorials/using-sqlite-on-the-iphone
http://dblog.com.au/iphone-development-tutorials/iphone-sdk-tutorial-reading-data-from-a-sqlite-database/
http://www.icodeblog.com/2008/08/19/iphone-programming-tutorial-creating-a-todo-list-using-sqlite-part-1/
You can use this class and send query in this class and get all functionality of sqlite using this class
.h
#import <Foundation/Foundation.h>
#import "sqlite3.h"
#interface DBLib : NSObject {
sqlite3 *database;
NSString *path;
}
- (NSString *)getDatabasePath:(NSString*)DBName;
- (void)createEditableCopyOfDatabaseIfNeeded:(NSString*)DBName;
- (void)initializeDatabase:(NSString*)DBName;
-(NSMutableArray*)GetListBySQL:(NSString*)SQL;
-(BOOL)UpdateData:(NSMutableDictionary*)objDic :(NSString*)PrimaryKey :(NSString*)TABLE_NAME;
-(BOOL)deleteQuery:(NSString *)query;
#end
.m
#import "DBLib.h"
#implementation DBLib
#pragma mark Database methods
- (NSString *)getDatabasePath:(NSString*)DBName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) ;
NSString *documentsDirectory = [paths objectAtIndex:0] ;
return [documentsDirectory stringByAppendingPathComponent:DBName];
}
// Creates a writable copy of the bundled default database in the application Documents directory.
- (void)createEditableCopyOfDatabaseIfNeeded:(NSString*)DBName {
// 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:DBName];
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:DBName];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success) {
NSString *errString = [NSString stringWithFormat:#"%#", [#"Fail" stringByReplacingOccurrencesOfString:#"#" withString:[error localizedDescription] ]];
NSAssert1(0, #"%#", errString);
}
}
// Open the database connection and retrieve minimal information for all objects.
- (void)initializeDatabase:(NSString*)DBName {
// The database is stored in the application bundle.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
path = [documentsDirectory stringByAppendingPathComponent:DBName];
NSStringEncoding enc = [NSString defaultCStringEncoding];
// Open the database. The database was prepared outside the application.
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK)
{
//TRUE
NSLog(#"Successfully opened-sqlite3");
}
else
{
// Even though the open failed, call close to properly clean up resources.
sqlite3_close(database);
NSLog(#"closed");
NSString *errString = [NSString stringWithFormat:#"%#", [#"Fail" stringByReplacingOccurrencesOfString:#"#" withString:[NSString stringWithCString:sqlite3_errmsg(database) encoding:enc] ]];
NSAssert1(0, #"%#", errString);
// Additional error handling, as appropriate...
}
}
-(NSMutableArray*)GetListBySQL:(NSString*)SQL
{
[self initializeDatabase:#"DBNAME"];
NSMutableArray* Array;
Array=[[NSMutableArray alloc]init];
NSStringEncoding enc = [NSString defaultCStringEncoding];
sqlite3_stmt *select_statement=nil;
if (sqlite3_prepare_v2(database, [SQL UTF8String], -1, &select_statement, NULL) != SQLITE_OK) {
NSString *errString = [NSString stringWithFormat:#"%#", [#"Fail" stringByReplacingOccurrencesOfString:#"#" withString:[NSString stringWithCString:sqlite3_errmsg(database) encoding:enc] ]];
NSAssert1(0, #"%#", errString);
}
int columncount=sqlite3_column_count(select_statement);
NSMutableDictionary* dic;
while (sqlite3_step(select_statement) == SQLITE_ROW)
{
dic=[[NSMutableDictionary alloc]init];
for(int j=0;j<columncount;j++)
{
if(sqlite3_column_text(select_statement, j)!=nil)
[dic setObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(select_statement, j)] forKey:[NSString stringWithUTF8String:(char *)sqlite3_column_name(select_statement,j)]];
else
[dic setObject:#"" forKey:[NSString stringWithUTF8String:(char *)sqlite3_column_name(select_statement,j)]];
}
[Array addObject:dic];
[dic release];
}
sqlite3_finalize(select_statement);
NSMutableArray *arr = [[NSMutableArray alloc] initWithArray: Array];
[Array release];
return arr;
}
//Method for Datbase
-(BOOL)UpdateData:(NSMutableDictionary*)objDic :(NSString*)PrimaryKey :(NSString*)TABLE_NAME
{
NSAutoreleasePool* pool=[[NSAutoreleasePool alloc]init];
[self initializeDatabase:DBNAME];
NSString* SQLColumns=#"";
NSString* SQLValues=#"";
NSString* SQL=#"";
//Chekc Wheather Insert or update?
BOOL IsNew=NO;;
if([[objDic valueForKey:PrimaryKey] intValue]==0)
{
IsNew=YES;
}
NSArray* Keys=[objDic allKeys];
NSLog(#"%#",Keys);
if(IsNew)
{
for(int i=0;i<Keys.count;i++)
{
if(![[Keys objectAtIndex:i] isEqual:PrimaryKey])
{
SQLColumns=[NSString stringWithFormat:#"%#%#,",SQLColumns,[Keys objectAtIndex:i]];
SQLValues=[NSString stringWithFormat:#"%#?,",SQLValues];
}
}
if([SQLColumns length]>0)
{
SQLColumns=[SQLColumns substringToIndex:[SQLColumns length]-1];
SQLValues=[SQLValues substringToIndex:[SQLValues length]-1];
}
SQL=[NSString stringWithFormat:#"INSERT INTO %# (%#) Values(%#)",TABLE_NAME,SQLColumns,SQLValues];
}
else
{
for(int i=0;i<Keys.count;i++)
{
if(![[Keys objectAtIndex:i] isEqual:PrimaryKey])
{
SQLColumns=[NSString stringWithFormat:#"%#%#=?,",SQLColumns,[Keys objectAtIndex:i]];
}
}
if([SQLColumns length]>0)
{
SQLColumns=[SQLColumns substringToIndex:[SQLColumns length]-1];
}
SQL=[NSString stringWithFormat:#"UPDATE %# SET %# WHERE %#=?",TABLE_NAME,SQLColumns,PrimaryKey];
//NSLog(sql);
}
sqlite3_stmt *insert_statement=nil;
if (sqlite3_prepare_v2(database, [SQL UTF8String], -1, &insert_statement, NULL) != SQLITE_OK) {
//NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
NSLog(#"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
int intBindIndex=1;
for(int i=0;i<Keys.count;i++)
{
if(![[Keys objectAtIndex:i] isEqual:PrimaryKey])
{
sqlite3_bind_text(insert_statement,intBindIndex,[[objDic valueForKey:[Keys objectAtIndex:i]] UTF8String],-1, SQLITE_STATIC);
intBindIndex++;
}
}
if(!IsNew)
{
sqlite3_bind_text(insert_statement,Keys.count,[[objDic valueForKey:PrimaryKey] UTF8String],-1, SQLITE_STATIC);
}
int result;
result=sqlite3_step(insert_statement);
if(IsNew)
{
[objDic setObject:[NSString stringWithFormat:#"%d",sqlite3_last_insert_rowid(database)] forKey:PrimaryKey];
}
sqlite3_finalize(insert_statement);
[pool release];
NSLog(#"result:%d",result);
if(result==SQLITE_DONE)
return YES;
else
return NO;
}
-(BOOL)deleteQuery:(NSString *)query
{
NSAutoreleasePool* pool=[[NSAutoreleasePool alloc]init];
[self initializeDatabase:DBNAME];
NSString* SQL=#"";
SQL=[NSString stringWithString:query];
sqlite3_stmt *insert_statement=nil;
if (sqlite3_prepare_v2(database, [SQL UTF8String], -1, &insert_statement, NULL) != SQLITE_OK) {
//NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
NSLog(#"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
int result;
result=sqlite3_step(insert_statement);
sqlite3_finalize(insert_statement);
[pool release];
NSLog(#"result:%d",result);
if(result==SQLITE_DONE)
return YES;
else
return NO;
}
#end

iphone sdk: Adding data to sqlite database not working?

I use the code below to insert data into my sqlite-database but for some reason the application always crashes as soon as the method gets called and the problem seems to be the "sqlite3_open" statement. Does anyone have any idea what I might be doing wrong?
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Animals";
animalsArray = [[NSMutableArray alloc] init];
animalDetailController = [[AnimalDetailViewController alloc] init];
addAnimalController = [[AddAnimalViewController alloc] init];
addAnimalController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
UIBarButtonItem *addItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addAction)];
self.navigationItem.rightBarButtonItem = addItem;
databaseName = #"AnimalDatabase.sql";
NSArray *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentsPath objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
[self checkAndCreateDatabase];
[self readDataFromDatabase];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)addAction{
[self presentModalViewController:addAnimalController animated:YES];
}
- (void)checkAndCreateDatabase{
BOOL databaseIsSaved;
NSFileManager *fileManager = [NSFileManager defaultManager];
databaseIsSaved = [fileManager fileExistsAtPath:databasePath];
if (databaseIsSaved == YES) {
return;
}
else {
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}
[fileManager release];
}
- (void)readDataFromDatabase{
sqlite3 *database;
if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = "select * from animals";
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
while (sqlite3_step(compiledStatement) == SQLITE_ROW) {
[animalsArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)], #"name", [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)], #"description", nil]];
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
- (void)writeToDatabase{
sqlite3 *database;
if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = "insert into animals(name, description) VALUES(?, ?)";
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK){
sqlite3_bind_text(compiledStatement, 1, [addAnimalController.animalName UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(compiledStatement, 2, [addAnimalController.animalDescription UTF8String], -1, SQLITE_TRANSIENT);
}
if(sqlite3_step(compiledStatement) != SQLITE_DONE ) {
NSLog( #"Error: %s", sqlite3_errmsg(database) );
} else {
NSLog( #"Insert into row id = %d", sqlite3_last_insert_rowid(database));
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (addAnimalController.saveButtonPressed == YES && [addAnimalController.animalName length] != 0 && [addAnimalController.animalDescription length] != 0) {
[animalsArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:addAnimalController.animalName, #"name", addAnimalController.animalDescription, #"description", nil]];
[self.tableView reloadData];
[self writeToDatabase];
addAnimalController.saveButtonPressed = NO;
}
}
You need a retain when you set databasePath.
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
Should be
databasePath = [[documentsDir stringByAppendingPathComponent:databaseName] retain];
Make sure you release it in your viewDidUnload and dealloc implementations. (It's probably smart to release it before you set it as well.)
Probably has nothing to do with this function. I wrote this blog to help understand EXC_BAD_ACCESS
http://www.loufranco.com/blog/files/Understanding-EXC_BAD_ACCESS.html
You should turn on Zombies and see if you are over-releasing any objects.