Am using SQLite3. and am updating row which is already present by using following code
- (BOOL)updateTableData :(NSString *) num
{
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
dbPath = [self getDBPath:#"studentslist.sqlite"];
if(sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
sqlite3_stmt *updateStmt;
const char *sql = "update studentInfo set sAge=?, sAddrs1=?, sAddrs2=?, sMobile =?, sClass =? where sRollNumber=?;";
if(sqlite3_prepare_v2(database, sql, -1, &updateStmt, NULL) != SQLITE_OK)
{
NSLog(#"updateTableData: Error while creating delete statement. '%s'", sqlite3_errmsg(database));
return;
}
NSLog(#"appDelegate.updateArray %#",appDelegate.updateArray);
sqlite3_bind_int(updateStmt, 1,[[appDelegate.updateArray objectAtIndex:0] intValue]);
sqlite3_bind_text(updateStmt, 2,[[appDelegate.updateArray objectAtIndex:1] UTF8String], -1,SQLITE_TRANSIENT);
sqlite3_bind_text(updateStmt, 3,[[appDelegate.updateArray objectAtIndex:2] UTF8String], -1,SQLITE_TRANSIENT);
sqlite3_bind_text(updateStmt, 4,[[appDelegate.updateArray objectAtIndex:3] UTF8String], -1,SQLITE_TRANSIENT);
sqlite3_bind_text(updateStmt, 5,[[appDelegate.updateArray objectAtIndex:4] UTF8String], -1,SQLITE_TRANSIENT);
if (SQLITE_DONE != sqlite3_step(updateStmt))
{
NSLog(#"updateTableData: Error while updating. '%s'", sqlite3_errmsg(database));
sqlite3_finalize(updateStmt);
sqlite3_reset(updateStmt);
sqlite3_close(database);
return NO;
}
else
{
NSLog(#"updateTableData: Updated");
sqlite3_finalize(updateStmt);
sqlite3_close(database);
return YES;
}
}
else
{
NSLog(#"updateTableData :Database Not Opened");
sqlite3_close(database);
return NO;
}
in main class am calling this method as follows
-(IBAction)updateButtonAction:(id)sender
{
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
db = [[Database alloc]init];
if ([ageTxtFld.text length]>0 && [address1TxtFld.text length]>0 && [address2TxtFld.text length]>0 && [mobileTxtFld.text length]>0 && [classTxtFld.text length]>0)
{
[appDelegate.updateArray addObject:ageTxtFld.text];
[appDelegate.updateArray addObject:address1TxtFld.text];
[appDelegate.updateArray addObject:address2TxtFld.text];
[appDelegate.updateArray addObject:mobileTxtFld.text];
[appDelegate.updateArray addObject:classTxtFld.text];
NSLog(#"appDelegate.updateArray %#",appDelegate.updateArray);
NSString *num = rollNumberTxtFld.text;
BOOL is = [db updateTableData:num];
if (is == YES)
{
updateAlert = [[UIAlertView alloc] initWithTitle:#"Success" message:#"Updated" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[updateAlert show];
}
else
{
updateAlert = [[UIAlertView alloc] initWithTitle:#"Fail" message:#"Not Updated" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[updateAlert show];
}
}
else
{
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Enter all values" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[errorAlert show];
}
}
But it always printing NSLog(#"updateTableData: Updated"); but not updating
Any one can suggest me or help with code.
Thanks in Advance
- (void)createEditableCopyOfDatabaseIfNeeded {
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"studentslist.sqlite"];
dbPath =writableDBPath;
[databasePath retain];
success = [fileManager fileExistsAtPath:writableDBPath];
if (success) return;
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"studentslist.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success) {
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
writableDBPath = nil;
documentsDirectory = nil;
paths = nil;
}
Write this method in your code and call it. surely this was a problem in your code.
Related
Hi i am trying to create a login and password for my app by using SQLite,, every thing is fine but the once the login button is pressed it is not entering in to home page!!!!
please find my code below:
-(void)checkindatabase{
NSArray *dirPath =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir =[dirPath objectAtIndex:0];
NSString *databasePath =[[NSString alloc] initWithString:[docDir stringByAppendingPathComponent:#"login.db"]];
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
NSLog(#"open");
NSString *sql = [[NSString alloc] initWithFormat:#"select * from UserInformation where Username='%#' and Password='%#'",loginName.text,password.text]; //[sql UTF8String];
//NSLog(#"'%s'",[sql UTF8String]);
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [sql UTF8String], -1, &statement, NULL) == SQLITE_OK)
{ if(sqlite3_step(statement) == SQLITE_ROW)
{
//user name is correct
//if u want to print in log use below code
homepage *hvc = [[homepage alloc]initWithNibName: nil bundle: nil];
hvc.modalTransitionStyle=UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:hvc animated: YES];
}
else {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Login Failed!!!"
message:#"Check your PId and Password" delegate:nil
cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}}
sqlite3_finalize(statement);
}
sqlite3_close(database);
}
-(IBAction)homePage: (id)sender
{
[self checkindatabase];
}
Please find the code, as you asked.
-(BOOL)checkindatabase
{
NSArray *dirPath =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir =[dirPath objectAtIndex:0];
NSString *databasePath =[[NSString alloc] initWithString:[docDir stringByAppendingPathComponent:#"login.db"]];
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
NSLog(#"open");
NSString *sql = [[NSString alloc] initWithFormat:#"select * from UserInformation where Username='%#' and Password='%#'",loginName.text,password.text]; //[sql UTF8String];
//NSLog(#"'%s'",[sql UTF8String]);
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [sql UTF8String], -1, &statement, NULL) == SQLITE_OK)
{ if(sqlite3_step(statement) == SQLITE_ROW)
{
//user name is correct
//if u want to print in log use below code
return YES;
}
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
return NO;
}
-(IBAction)homePage: (id)sender
{
if( [self checkindatabase] )
{
homepage *hvc = [[homepage alloc]initWithNibName: nil bundle: nil];
hvc.modalTransitionStyle=UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:hvc animated: YES];
[hvc release];
}
else
{
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Login Failed!!!"
message:#"Check your PId and Password" delegate:nil
cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
As suggested by Aadhira...
Make checkindatabase with return type BOOL and return TRUE if Login successful and FALSE otherwise.
Then on the basis of BOOL value navigate to Home Page.
you cannot let other function to navigate the view, while performing IBAction method.
EDIT :
I am not looking to your database code.. i have simply shown you way how to use the BOOL return values.... Also mention errors if any you faced.
-(BOOL)checkindatabase{
NSArray *dirPath =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir =[dirPath objectAtIndex:0];
NSString *databasePath =[[NSString alloc] initWithString:[docDir stringByAppendingPathComponent:#"login.db"]];
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
NSLog(#"open");
NSString *sql = [[NSString alloc] initWithFormat:#"select * from UserInformation where Username='%#' and Password='%#'",loginName.text,password.text]; //[sql UTF8String];
//NSLog(#"'%s'",[sql UTF8String]);
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [sql UTF8String], -1, &statement, NULL) == SQLITE_OK)
{ if(sqlite3_step(statement) == SQLITE_ROW)
{
//user name is correct
//if u want to print in log use below code
flag = YES;
}
else {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Login Failed!!!"
message:#"Check your PId and Password" delegate:nil
cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
flag = NO;
}}
sqlite3_finalize(statement);
}
sqlite3_close(database);
return flag;
}
-(IBAction)homePage: (id)sender
{
BOOL newFlag = [self checkindatabase];
if(newFlag)
{
homepage *hvc = [[homepage alloc]initWithNibName: nil bundle: nil]
hvc.modalTransitionStyle=UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:hvc animated: YES];
}
}
I'm having trouble updating my database. I believe it's due to it possibly being read only, however I am unsure. I created my database in my console, and the code below adds the database to the project folder rather than referencing it externally. Here is the code to transfer the file to the project folder
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
databaseName = #"databasenew.sql";
/* copy over to phone code */
NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0];
NSString *sqlFile =[documentDirectory stringByAppendingPathComponent:#"databasenew.sql"];
if (![[NSFileManager defaultManager] fileExistsAtPath:sqlFile]) {
NSString *bundleSql = [[NSBundle mainBundle] pathForResource:#"databasenew" ofType:#"sql"];
NSError *error = nil;
[[NSFileManager defaultManager] copyItemAtPath:bundleSql toPath:sqlFile error:&error];
if (error) {
NSLog(#"Could not copy json file: %#", error);
}
else{
NSLog(#"yea");
}
}
else{
NSLog(#"transfer complete");
}
NSString *bundleSql = [[NSBundle mainBundle] pathForResource:#"databasenew" ofType:#"sql"];
databasePath = bundleSql;
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
Here is the code where I try to update
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qName
attributes: (NSDictionary *)attributeDict
{
if ([elementName isEqualToString:#"Message"])
{
NSLog(soapResults);
NSString *convertString = soapResults;
check = [convertString intValue];
NSLog(#"user is");
NSLog(user);
if(check > 0){
databaseName = #"databasenew.sql";
NSString *bundleSql = [[NSBundle mainBundle] pathForResource:#"databasenew" ofType:#"sql"];
databasePath = bundleSql;
sqlite3 *database;
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = "UPDATE people set user = 'munch'";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
NSLog(#"success");
NSLog(soapResults);
BOOL success = sqlite3_step(compiledStatement);
if (success != SQLITE_DONE) {
BOOL myBool=YES;
NSLog([NSString stringWithFormat:#"My Bool value : %d",success]);
}
}else{
NSLog(#"the fail ispreparing something");
NSAssert1(0, #"Error while creating update statement. '%s'", sqlite3_errmsg(database));
}
sqlite3_finalize(compiledStatement);
}else{
NSLog(#"fail");
}
sqlite3_close(database);
NSString *string = [NSString stringWithFormat:#"%d", check];
NSLog(string);
NSLog(#"lolololol");
check = 0;
[self Bootup];
}else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Problem!" message:#"Incorrect Username or Password"
delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:#"Yes", nil];
[alert show];
[alert release];
}
// gotoContent = checkConfirm;
}
if( [elementName isEqualToString:#"ValidateUserResponse"])
{
if(!soapResults)
{
soapResults = [[NSMutableString alloc] init];
NSLog(soapResults);
NSLog(#"above is soap validate user");
}
recordResults = TRUE;
}
}
I've done my NDlog debugging and it says "success" as it should if the code for updating is successful, however the database itself does not update. What is the reason for this?
You are forgeting some code for update statement
//the binding part is missing in your code , you need to write after Prepare statement.
sqlite3_bind_text(compiledStatement, 1, [string UTF8String], -1, SQLITE_TRANSIENT);
if(SQLITE_DONE != sqlite3_step(compiledStatement))
NSAssert1(0, #"Error while updating. '%s'", sqlite3_errmsg(database));
sqlite3_reset(compiledStatement);
Via iphonesdkarticles.com.
This will resolve your error.
-(BOOL) someUpdateFunction {
BOOL updatedSuccessfully = NO;
// Open the database.
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
NSString *updateQuery = [[NSString alloc] initWithFormat:#"UPDATE people SET user = 'terror' WHERE user = 'greg'"];
const char *query = [updateQuery UTF8String];
[updateQuery release];
sqlite3_stmt *statement;
int res = (sqlite3_prepare_v2( database, query, -1, &statement, NULL));
if(res == SQLITE_OK) {
int result = sqlite3_step(statement);
if(result == SQLITE_DONE) {
updatedSuccessfully = YES;
sqlite3_finalize(statement);
}else {
NSLog(#"Failed with error code: %d", result);
}
}else {
NSLog(#"Failed to prepare the update query with error code: %d", res);
}
}else {
NSLog(#"Failed to open the database");
}
sqlite3_close(database);
//NSLog(updatedSuccessfully);
//NSLog(#"The value of the bool is %#\n", updatedSuccessfully);
return updatedSuccessfully;
}
I was supplied this in the chat room. Thanks lads.
Remember to copy the DB over to the device else. You can find the DB path with this code:
- (NSString *) dataFilePath:(NSString *) dbName {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dbPath = [documentsDirectory stringByAppendingPathComponent:dbName];
return dbPath;
}
-(BOOL)buildtheDB{
BOOL updatedSuccessfully = NO;
NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0];
NSString *sqlFile =[documentDirectory stringByAppendingPathComponent:kDatabaseFileName];
if ([[NSFileManager defaultManager] fileExistsAtPath:sqlFile] == NO) {
NSString *bundleSql = [[NSBundle mainBundle] pathForResource:#"database" ofType:#"sqlite"];
NSError *error = nil;
BOOL databaseCopied = [[NSFileManager defaultManager] copyItemAtPath:bundleSql toPath:sqlFile error:&error];
if (databaseCopied == NO) {
if (error) {
NSLog(#"Could not copy database file with error: %#", [error localizedDescription]);
}
}else {
NSLog(#"Database copied successfully");
}
}
else{
NSLog(#"Database already copied");
}
return updatedSuccessfully;
}
I'm having trouble updating my database. I believe it's due to it possibly being read only, however I am unsure. I created my database in my console, and the code below adds the database to the project folder rather than referencing it externally. Here is the code to transfer the file to the project folder
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
databaseName = #"databasenew.sql";
/* copy over to phone code */
NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0];
NSString *sqlFile =[documentDirectory stringByAppendingPathComponent:#"databasenew.sql"];
if (![[NSFileManager defaultManager] fileExistsAtPath:sqlFile]) {
NSString *bundleSql = [[NSBundle mainBundle] pathForResource:#"databasenew" ofType:#"sql"];
NSError *error = nil;
[[NSFileManager defaultManager] copyItemAtPath:bundleSql toPath:sqlFile error:&error];
if (error) {
NSLog(#"Could not copy json file: %#", error);
}
else{
NSLog(#"yea");
}
}
else{
NSLog(#"transfer complete");
}
NSString *bundleSql = [[NSBundle mainBundle] pathForResource:#"databasenew" ofType:#"sql"];
databasePath = bundleSql;
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
Here is the code where I try to update
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qName
attributes: (NSDictionary *)attributeDict
{
if ([elementName isEqualToString:#"Message"])
{
NSLog(soapResults);
NSString *convertString = soapResults;
check = [convertString intValue];
NSLog(#"user is");
NSLog(user);
if(check > 0){
databaseName = #"databasenew.sql";
NSString *bundleSql = [[NSBundle mainBundle] pathForResource:#"databasenew" ofType:#"sql"];
databasePath = bundleSql;
sqlite3 *database;
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = "UPDATE people set user = 'munch'";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
NSLog(#"success");
NSLog(soapResults);
BOOL success = sqlite3_step(compiledStatement);
if (success != SQLITE_DONE) {
BOOL myBool=YES;
NSLog([NSString stringWithFormat:#"My Bool value : %d",success]);
}
}else{
NSLog(#"the fail ispreparing something");
NSAssert1(0, #"Error while creating update statement. '%s'", sqlite3_errmsg(database));
}
sqlite3_finalize(compiledStatement);
}else{
NSLog(#"fail");
}
sqlite3_close(database);
NSString *string = [NSString stringWithFormat:#"%d", check];
NSLog(string);
NSLog(#"lolololol");
check = 0;
[self Bootup];
}else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Problem!" message:#"Incorrect Username or Password"
delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:#"Yes", nil];
[alert show];
[alert release];
}
// gotoContent = checkConfirm;
}
if( [elementName isEqualToString:#"ValidateUserResponse"])
{
if(!soapResults)
{
soapResults = [[NSMutableString alloc] init];
NSLog(soapResults);
NSLog(#"above is soap validate user");
}
recordResults = TRUE;
}
}
I've done my NDlog debugging and it says "success" as it should if the code for updating is successful, however the database itself does not update. What is the reason for this?
You are forgeting some code for update statement
//the binding part is missing in your code , you need to write after Prepare statement.
sqlite3_bind_text(compiledStatement, 1, [string UTF8String], -1, SQLITE_TRANSIENT);
if(SQLITE_DONE != sqlite3_step(compiledStatement))
NSAssert1(0, #"Error while updating. '%s'", sqlite3_errmsg(database));
sqlite3_reset(compiledStatement);
Via iphonesdkarticles.com.
This will resolve your error.
-(BOOL) someUpdateFunction {
BOOL updatedSuccessfully = NO;
// Open the database.
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
NSString *updateQuery = [[NSString alloc] initWithFormat:#"UPDATE people SET user = 'terror' WHERE user = 'greg'"];
const char *query = [updateQuery UTF8String];
[updateQuery release];
sqlite3_stmt *statement;
int res = (sqlite3_prepare_v2( database, query, -1, &statement, NULL));
if(res == SQLITE_OK) {
int result = sqlite3_step(statement);
if(result == SQLITE_DONE) {
updatedSuccessfully = YES;
sqlite3_finalize(statement);
}else {
NSLog(#"Failed with error code: %d", result);
}
}else {
NSLog(#"Failed to prepare the update query with error code: %d", res);
}
}else {
NSLog(#"Failed to open the database");
}
sqlite3_close(database);
//NSLog(updatedSuccessfully);
//NSLog(#"The value of the bool is %#\n", updatedSuccessfully);
return updatedSuccessfully;
}
I was supplied this in the chat room. Thanks lads.
Remember to copy the DB over to the device else. You can find the DB path with this code:
- (NSString *) dataFilePath:(NSString *) dbName {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dbPath = [documentsDirectory stringByAppendingPathComponent:dbName];
return dbPath;
}
-(BOOL)buildtheDB{
BOOL updatedSuccessfully = NO;
NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0];
NSString *sqlFile =[documentDirectory stringByAppendingPathComponent:kDatabaseFileName];
if ([[NSFileManager defaultManager] fileExistsAtPath:sqlFile] == NO) {
NSString *bundleSql = [[NSBundle mainBundle] pathForResource:#"database" ofType:#"sqlite"];
NSError *error = nil;
BOOL databaseCopied = [[NSFileManager defaultManager] copyItemAtPath:bundleSql toPath:sqlFile error:&error];
if (databaseCopied == NO) {
if (error) {
NSLog(#"Could not copy database file with error: %#", [error localizedDescription]);
}
}else {
NSLog(#"Database copied successfully");
}
}
else{
NSLog(#"Database already copied");
}
return updatedSuccessfully;
}
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.
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.