I just start develop an ios app just like Contact.
It include Name, Birthday, Group(School, Work), BloodType, Image.. etc.
In that, other Data can insert by typing.
But, image can come from taking photo, download from facebook.. etc.
Input images into xcode is impossible. Bcoz, another images can come again and again.
How should i do? Please, advice me.
you just ADD libSqlite3.dylib to Linked FrameWork and Lilbraries and declared database varibles in .h file
//Database Variables
#property (strong, nonatomic) NSString *databasePath;
#property (nonatomic)sqlite3 *contactDB;
drag and drop UIImageView and name to that... i declared as imgView.
Goto .m file you just copy and paste that code
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
// Build the path to the database file
_databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: #"images.db"]];
//docsDir NSPathStore2 * #"/Users/gayathiridevi/Library/Application Support/iPhone Simulator/7.0.3/Applications/B5D4D2AF-C613-45F1-B414-829F38344C2A/Documents" 0x0895e160
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: _databasePath ] == NO)
{
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS IMAGETB (ID INTEGER PRIMARY KEY AUTOINCREMENT,URL TEXT UNIQUE, IMAGE BLOB)";
if (sqlite3_exec(_contactDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
NSLog( #"User table Not Created Error: %s", errMsg);
}
else
{
NSLog( #"User table Created: ");
}
sqlite3_close(_contactDB);
}
else {
NSLog( #"DB Not Created");
}
}
[self saveImage];
[self showImage];
}
- (void)saveImage
{
sqlite3_stmt *statement;
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
NSString *insertSQL=#"INSERT INTO IMAGETB(image) VALUES(?)";
if(sqlite3_prepare_v2(_contactDB, [insertSQL cStringUsingEncoding:NSUTF8StringEncoding], -1, &statement, NULL)== SQLITE_OK)
{
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"https://lh6.googleusercontent.com/-vJBBGUtpXxk/AAAAAAAAAAI/AAAAAAAAADQ/nfgVPX1n-Q8/photo.jpg"]]];
NSData *imageData=UIImagePNGRepresentation(image);
//sqlite3_bind_text(statement, 1, [#"" UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_blob(statement, 1, [imageData bytes], [imageData length], SQLITE_TRANSIENT);
NSLog(#"Length : %lu", (unsigned long)[imageData length]);
}
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog( #"Insert into row id %lld",(sqlite3_last_insert_rowid(_contactDB)));
}
else {
NSLog( #"Error IN INSERT" );
}
sqlite3_finalize(statement);
sqlite3_close(_contactDB);
}
}
- (void)showImage
{
sqlite3_stmt *statement;
const char *dbpath = [_databasePath UTF8String];
int i = 1;
if(sqlite3_open(dbpath,&_contactDB)==SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat:#"Select IMAGE FROM IMAGETB WHERE ID = %d",i];
if(sqlite3_prepare_v2(_contactDB,[insertSQL cStringUsingEncoding:NSUTF8StringEncoding], -1, &statement, NULL) == SQLITE_OK) {
while(sqlite3_step(statement) == SQLITE_ROW) {
int length = sqlite3_column_bytes(statement, 0);
NSData *imageData = [NSData dataWithBytes:sqlite3_column_blob(statement, 0) length:length];
NSLog(#"Length : %lu", (unsigned long)[imageData length]);
if(imageData == nil)
NSLog(#"No image found.");
else
_imgView.image = [UIImage imageWithData:imageData];
NSLog(#"image found.");
}
}
sqlite3_finalize(statement);
}
sqlite3_close(_contactDB);
}
Its my code. You fix back and Forward Button to get details by changing that i value in
-(void)showImage
function
Regarding taking photos or grabbing from your library, see UIImagePickerController Class Reference and the Camera Programming Topics for iOS. For grabbing photos from Facebook, you should refer to its API, as that's a whole different kettle of fish.
Related
I am new in iOS development. I am trying to do a simple todo list app. I am using xocde 8 and objective-C language . I tried several tutorial but could not create the database table. Here is my code.
-(void)createOrOpenDB{
printf("createOrOpenDB: into this function \n");
NSArray *docsDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *dirPaths = [docsDir objectAtIndex:0];
dbPathString = [[NSString alloc] initWithString: [dirPaths stringByAppendingPathComponent:#"person.db"]];
NSFileManager *fileManager = [NSFileManager defaultManager];
char *err;
printf("createOrOpenDB: into this function before if statement \n");
if(![fileManager fileExistsAtPath:dbPathString]){
const char *dbPath = [dbPathString UTF8String];
printf("createOrOpenDB: into this functions 1st if statement \n");
//create db here
if(sqlite3_open(dbPath, &personDB) ==SQLITE_OK){
const char *sql_stnt = "CREATE TABLE IF NOT EXISTS PERSONS (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, AGE INTEGER)";
if(sqlite3_exec(personDB, sql_stnt, NULL, NULL, &err) !=SQLITE_OK){
printf("Failed to create table\n");
}
sqlite3_close(personDB);
printf("createOrOpenDB: database table created\n");
}
}
}
when i press the add button , its not giving me any error. but its not adding any data. NSLog in not working in xcode 8 . so i did printf instead . and my code breaks before the if statement . can anybody tell me what i am doing wrong?
do like this,
+(DBManager*)getSharedInstance{
if (!sharedInstance) {
sharedInstance = [[super allocWithZone:NULL]init];
[sharedInstance createDB];
}
return sharedInstance;
}
-(BOOL)createDB{
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
// Build the path to the database file
databasePath = [[NSString alloc] initWithString:
[docsDir stringByAppendingPathComponent: #"student.db"]];
BOOL isSuccess = YES;
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: databasePath ] == YES)
{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt = "create table if not exists studentsDetail (regno integer primary key, name text, department text, year text)";
if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg)
!= SQLITE_OK)
{
isSuccess = NO;
NSLog(#"Failed to create table");
}
else
{
NSLog(#"Table Created Successfully");
}
sqlite3_close(database);
return isSuccess;
}
else {
isSuccess = NO;
NSLog(#"Failed to open/create database");
}
sqlite3_finalize(statement);
}
return isSuccess;
// NSLog(#"database %#", isSuccess);
}
For saving the data in this table,
- (BOOL) saveData:(NSString*)registerNumber name:(NSString*)name
department:(NSString*)department year:(NSString*)year;
{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat:#"insert into studentsDetail (regno,name, department, year) values (\"%ld\",\"%#\", \"%#\", \"%#\")",(long)[registerNumber integerValue], name, department, year];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
return YES;
}
else {
return NO;
}
sqlite3_reset(statement);
}
return NO;
}
It will create table every time when table does not exist.
Hope t will help you.
This question already has answers here:
sqlite error database is locked
(8 answers)
Closed 6 years ago.
I am getting error Database Locked.
at first attempt it adds the row but after that i am getting the error
database locked.
I am trying to make web page saver so at first time when app loads it is adding the row but when again I try to save any webpage it is not saving and I am getting the error database locked.
Even the deletion is also not happening after saving one web page.
#import "DBManager.h"
static DBManager *sharedInstance = nil;
static sqlite3 *database = nil;
static sqlite3_stmt *statement = nil;
#implementation DBManager
+(DBManager*)getSharedInstance{
if (!sharedInstance) {
sharedInstance = [[super allocWithZone:NULL]init];
[sharedInstance createDB];
}
return sharedInstance;
}
-(BOOL)createDB{
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
// Build the path to the database file
databasePath = [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent: #"browser.db"]];
BOOL isSuccess = YES;
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: databasePath ] == NO)
{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
char *errMsg;
NSLog(#"insod");
const char *sql_stmt ="create table if not exists list(sno int primary key,name varchar(50),category varchar(30),path varchar(500),fav int)";
if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg)
!= SQLITE_OK)
{
isSuccess = NO;
NSLog(#"Failed to create table");
}
sqlite3_close(database);
return isSuccess;
}
else {
isSuccess = NO;
NSLog(#"Failed to open/create database");
}
}else{
NSLog(#"File Exist");
}
return isSuccess;
}
-(BOOL) Delete:(NSString *) name{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK){
NSString *query = [NSString stringWithFormat:#"delete from list where name like '%#'",name];
const char *stmt = [query UTF8String];
sqlite3_prepare_v2(database, stmt,-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE){
sqlite3_finalize(statement);
return YES;
}else {
NSLog(#"error: %s",sqlite3_errmsg(database));
sqlite3_finalize(statement);
return NO;
}
}else{
sqlite3_close(database);
return NO;
}
}
-(NSDictionary *) CatList:(NSString *) cat{
const char *dbpath = [databasePath UTF8String];
NSDictionary *dict;
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *querySQL =[NSString stringWithFormat:#"select name,path from list where category like '%#'",cat];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
// NSLog(#"inside list");
NSMutableArray *arr1 = [[NSMutableArray alloc] init];
NSMutableArray *arr2 = [[NSMutableArray alloc] init];
// NSMutableArray *arr3 = [[NSMutableArray alloc] init];
while(sqlite3_step(statement) == SQLITE_ROW)
{
NSString *name = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
[arr1 addObject:name];
//NSLog(#"%#",name);
NSString *category = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
[arr2 addObject:category];
// //NSLog(#"%#",dept);
// NSString *path = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 3)];
// [arr3 addObject:path];
}
sqlite3_finalize(statement);
dict = #{#"name":arr1,#"path":arr2};
//NSLog(#"%#",dict);
}else{
NSLog(#"error: %s",sqlite3_errmsg(database));
}
sqlite3_close(database);
}
return dict;
}
- (BOOL) saveData:(NSString*)name category:(NSString*)category path:(NSString*)path{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *highest = #"select max(sno) from list";
const char *Query = [highest UTF8String];
if (sqlite3_prepare_v2(database, Query, -1, &statement, NULL) == SQLITE_OK){
if (sqlite3_step(statement) == SQLITE_ROW){
int sno = sqlite3_column_int(statement, 0);
NSString *insertSQL = [NSString stringWithFormat:#"insert into list values(\"%d\",\"%#\",\"%#\", \"%#\",\"%d\")",sno+1,name, category, path,0];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE){
sqlite3_finalize(statement);
return YES;
}else {
sqlite3_finalize(statement);
return NO;
}
}else{
NSString *insertSQL = [NSString stringWithFormat:#"insert into list values(\"%d\",\"%#\",\"%#\", \"%#\",\"%d\")",1,name, category, path,0];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE){
sqlite3_finalize(statement);
return YES;
}else {
sqlite3_finalize(statement);
return NO;
}
}
}
sqlite3_close(database);
}
return NO;
}
-(BOOL) Fav:(NSString *) name{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK){
NSString *query = [NSString stringWithFormat:#"update list set fav = 1 where name like '%#'",name];
const char *stmt = [query UTF8String];
sqlite3_prepare_v2(database, stmt,-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE){
sqlite3_finalize(statement);
return YES;
}else {
sqlite3_finalize(statement);
return NO;
}
}else{
return NO;
}
}
-(NSArray *) GetListFav{
const char *dbpath = [databasePath UTF8String];
NSArray *dict;
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *querySQL = #"select name from list where fav = 1";
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
NSMutableArray *arr1 = [[NSMutableArray alloc] init];
while(sqlite3_step(statement) == SQLITE_ROW)
{
NSString *name = [[NSString alloc] initWithUTF8String: (const char *) sqlite3_column_text(statement, 0)];
[arr1 addObject:name];
}
sqlite3_finalize(statement);
dict = arr1;
}else{
NSLog(#"error: %s",sqlite3_errmsg(database));
}
sqlite3_close(database);
}
return dict;
}
-(BOOL) removeFav:(NSString *) name{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK){
NSString *query = [NSString stringWithFormat:#"update list set fav = 0 where name like '%#'",name];
const char *stmt = [query UTF8String];
sqlite3_prepare_v2(database, stmt,-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE){
sqlite3_finalize(statement);
return YES;
}else {
sqlite3_finalize(statement);
return NO;
}
}else{
return NO;
}
}
-(NSArray *) GetList{
const char *dbpath = [databasePath UTF8String];
NSArray *dict;
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *querySQL = #"select name from list";
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
//NSLog(#"inside list");
NSMutableArray *arr1 = [[NSMutableArray alloc] init];
while(sqlite3_step(statement) == SQLITE_ROW)
{
NSString *name = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
[arr1 addObject:name];
}
sqlite3_finalize(statement);
dict = arr1;
}else{
NSLog(#"error: %s",sqlite3_errmsg(database));
}
sqlite3_close(database);
}
return dict;
}
#end
You can only access sqllite once at a time. If you have multiple threads, you can run in this situation. Example:
So always try to close database once it is used using:
sqlite3_close(database);
You need to make sure every sqlite3_open is balanced with a sqlite3_close before trying to do sqlite3_open again:
Your saveData method has quite a few return statements that will prevent the database from ever calling sqlite3_close. Make sure all paths out of the method close the database properly. In the end, this means that you'll try to open the database although it's already open.
Or, better, just open the database once and leave it open, eliminating the repeated opening and closing of the database.
Your Delete, Fav, and removeFav methods are also not closing the database.
A few unrelated observations:
You should be wary about using stringWithFormat to build SQL with string parameters. If the string being searched for had a apostrophe in it, your code will fail. Use ? placeholders and then use sqlite3_bind_text to bind values to those placeholders.
If you make your sno column a AUTOINCREMENT, you won't have to do that "get the max sno before inserting new row" logic. Thus, the CREATE statement might look like:
create table if not exists list (
sno integer primary key autoincrement,
name text,
category text,
path text,
fav integer)
You can then omit sno from the INSERT statements, and it will automatically be assigned a unique identifier.
I have created multiple tables in my database. And now I want insert data into those tables. How to insert multiple tables data can anyone help regarding this.
I have written this code for creating 1 table:
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO ATRG (id, name, language,imgurl) VALUES ( \"%#\",\"%#\",\"%#\",\"%#\")", ID, name, lang,imgUrl];
const char *insert_stmt = [insertSQL UTF8String]; sqlite3_prepare_v2(_globalDataBase, insert_stmt, -1, &statement, NULL); if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"Record Inserted");
} else { NSLog(#"Failed to Insert Record");
}
Try this I hope it would be helpful!! This is mine code for insert data
#import "Sqlitedatabase.h"
#implementation Sqlitedatabase
+(NSString* )getDatabasePath
{
NSString *docsDir;
NSArray *dirPaths;
sqlite3 *DB;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
NSString *databasePath = [docsDir stringByAppendingPathComponent:#"myUser.db"];
NSFileManager *filemgr = [[NSFileManager alloc]init];
if ([filemgr fileExistsAtPath:databasePath]==NO) {
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath,&DB)==SQLITE_OK) {
char *errorMessage;
const char *sql_statement = "CREATE TABLE IF NOT EXISTS users(ID INTEGER PRIMARY KEY AUTOINCREMENT,FIRSTNAME TEXT,LASTNAME TEXT,EMAILID TEXT,PASSWORD TEXT,BIRTHDATE DATE)";
if (sqlite3_exec(DB,sql_statement,NULL,NULL,&errorMessage)!=SQLITE_OK) {
NSLog(#"Failed to create the table");
}
sqlite3_close(DB);
}
else{
NSLog(#"Failded to open/create the table");
}
}
NSLog(#"database path=%#",databasePath);
return databasePath;
}
+(NSString*)encodedString:(const unsigned char *)ch
{
NSString *retStr;
if(ch == nil)
retStr = #"";
else
retStr = [NSString stringWithCString:(char*)ch encoding:NSUTF8StringEncoding];
return retStr;
}
+(BOOL)executeScalarQuery:(NSString*)str{
NSLog(#"executeScalarQuery is called =%#",str);
sqlite3_stmt *statement= nil;
sqlite3 *database;
BOOL fRet = NO;
NSString *strPath = [self getDatabasePath];
if (sqlite3_open([strPath UTF8String],&database) == SQLITE_OK) {
if (sqlite3_prepare_v2(database, [str UTF8String], -1, &statement, NULL) == SQLITE_OK) {
if (sqlite3_step(statement) == SQLITE_DONE)
fRet =YES;
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
return fRet;
}
+(NSMutableArray *)executeQuery:(NSString*)str{
sqlite3_stmt *statement= nil; // fetch data from table
sqlite3 *database;
NSString *strPath = [self getDatabasePath];
NSMutableArray *allDataArray = [[NSMutableArray alloc] init];
if (sqlite3_open([strPath UTF8String],&database) == SQLITE_OK) {
if (sqlite3_prepare_v2(database, [str UTF8String], -1, &statement, NULL) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
NSInteger i = 0;
NSInteger iColumnCount = sqlite3_column_count(statement);
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
while (i< iColumnCount) {
NSString *str = [self encodedString:(const unsigned char*)sqlite3_column_text(statement, (int)i)];
NSString *strFieldName = [self encodedString:(const unsigned char*)sqlite3_column_name(statement, (int)i)];
[dict setObject:str forKey:strFieldName];
i++;
}
[allDataArray addObject:dict];
}
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
return allDataArray;
}
#end
And called that method where you want to use!!
NSString *insertSql = [NSString stringWithFormat:#"INSERT INTO users(firstname,lastname,emailid,password,birthdate) VALUES ('%#','%#','%#','%#','%#')",_firstNameTextField.text,_lastNameTextField.text,_emailTextField.text,_passwordTextField.text,_BirthdayTextField.text];
if ([Sqlitedatabase executeScalarQuery:insertSql]==YES)
{
[self showUIalertWithMessage:#"Registration succesfully created"];
}else{
NSLog(#"Data not inserted successfully");
}
And If you want to fetch data from table then you can do this!!
NSString *insertSql = [NSString stringWithFormat:#"select emailid,password from users where emailid ='%#' and password = '%#'",[_usernameTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]],[_passwordTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
NSMutableArray *data =[Sqlitedatabase executeQuery:insertSql];
NSLog(#"Fetch data from database is=%#",data);
Multiple Execute Query!!
NSString *insertSql = [NSString stringWithFormat:#"INSERT INTO users (firstname,lastname,emailid,password,birthdate) VALUES ('%#','%#','%#','%#','%#')",_firstNameTextField.text,_lastNameTextField.text,_emailTextField.text,_passwordTextField.text,_BirthdayTextField.text];
NSString *insertSql1 = [NSString stringWithFormat:#"INSERT INTO contact (firstname,lastname,emailid,password,birthdate) VALUES ('%#','%#','%#','%#','%#')",_firstNameTextField.text,_lastNameTextField.text,_emailTextField.text,_passwordTextField.text,_BirthdayTextField.text];
NSMutableArray * array = [[NSMutableArray alloc]initWithObjects:insertSql,insertSql1,nil];
for (int i=0; i<array.count; i++)
{
[Sqlitedatabase executeScalarQuery:[array objectAtIndex:i]];
}
See this for your issue:
Insert multiple tables in same database in sqlite
or if you want
Multi-table INSERT using one SQL statement in AIR SQLite
then use this:
http://probertson.com/articles/2009/11/30/multi-table-insert-one-statement-air-sqlite/
I have an app where I take details of the user and save it to SQLite db. Also I am able to find the details and display the result.
-(void) createDB{
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
// Build the path to the database file
_databasePath = [[NSString alloc]
initWithString: [docsDir stringByAppendingPathComponent:
#"contactUnique6.db"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: _databasePath ] == NO)
{
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt =
"CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT , NAME TEXT , ADDRESS TEXT, PHONE TEXT )";
if (sqlite3_exec(_contactDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
_status.text = #"Failed to create table";
}
sqlite3_close(_contactDB);
} else {
_status.text = #"Failed to open/create database";
}
}
- (IBAction)saveData:(id)sender {
sqlite3_stmt *statement;
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat:
#"INSERT OR IGNORE INTO CONTACTS (name, address, phone) VALUES (\"%#\", \"%#\", \"%#\")",
_name.text, _address.text, _phone.text];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(_contactDB, insert_stmt,
-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
_status.text = #"Contact added";
_name.text = #"";
_address.text = #"";
_phone.text = #"";
} else {
_status.text = #"Failed to add contact";
}
sqlite3_finalize(statement);
sqlite3_close(_contactDB);
}
}
- (IBAction)findContact:(id)sender {
const char *dbpath = [_databasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat:
#"SELECT address, phone FROM contacts WHERE name=\"%#\"",
_name.text];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(_contactDB,
query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
if (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *addressField = [[NSString alloc]
initWithUTF8String:
(const char *) sqlite3_column_text(
statement, 0)];
_address.text = addressField;
NSString *phoneField = [[NSString alloc]
initWithUTF8String:(const char *)
sqlite3_column_text(statement, 1)];
_phone.text = phoneField;
_status.text = #"Match found";
} else {
_status.text = #"Match not found";
_address.text = #"";
_phone.text = #"";
}
sqlite3_finalize(statement);
}
sqlite3_close(_contactDB);
}
}
The above code is working good. However when I am trying to use an update, it is not displaying when I try to find it. It gives me a match not found even though the contact was saved.
This is the code by which I am trying to update:
- (IBAction)saveData:(id)sender {
sqlite3_stmt *statement;
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat:
#"INSERT OR IGNORE INTO CONTACTS (name, address, phone) VALUES (\"%#\", \"%#\", \"%#\")",
_name.text, _address.text, _phone.text];
insertSQL = [NSString stringWithFormat:
#"UPDATE CONTACTS SET name=\"%#\", address=\"%#\", phone=\"%#\"",
_name.text, _address.text, _phone.text];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(_contactDB, insert_stmt,
-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
_status.text = #"Contact added";
_name.text = #"";
_address.text = #"";
_phone.text = #"";
} else {
_status.text = #"Failed to add contact";
}
sqlite3_finalize(statement);
sqlite3_close(_contactDB);
}
}
Basically my aim is to be able to save-update-find. (without losing the primary key on update, as I have FK relations)
EDIT
This is my create db method
-(void) createDB{
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
// Build the path to the database file
_databasePath = [[NSString alloc]
initWithString: [docsDir stringByAppendingPathComponent:
#"contactUnique6.db"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: _databasePath ] == NO)
{
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt =
"CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT , NAME TEXT , ADDRESS TEXT, PHONE TEXT )";
if (sqlite3_exec(_contactDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
_status.text = #"Failed to create table";
}
sqlite3_close(_contactDB);
} else {
_status.text = #"Failed to open/create database";
}
}
i cant get your second -(IBAction)saveData:(id)sender {} method [ Third code block ]..
You said above 2 blocks are working properly so its ok.
i think you embedded the update's logic in insert's logic i.e. you embedded the update method in your saveData method..
Here i cant get what u have done, so instead of code here i m providing the template for update query, just put your code in it...
sqlite3_stmt *statement;
if(sqlite3_open(dbpath, &database_object) == SQLITE_OK)
{
NSString *sql = [NSString stringWithFormat:#"update table_name set column_name = \"%#\"", Your_value];
const char *sql_stmt = [sql UTF8String];
if(sqlite3_prepare_v2(database_object , sql_stmt, -1, &statement, NULL) != SQLITE_OK)
NSLog(#"Error while creating update statement. '%s'", sqlite3_errmsg(database_object));
if(SQLITE_DONE != sqlite3_step(statement))
NSLog(#"Error while updating. '%s'", sqlite3_errmsg(database_object));
sqlite3_finalize(statement);
}
Go with this template, i think it will work for you...
I am having tabbed iPhone application.In the first tab I created sqlite table and inserted values to the table,these are done successfully.In the second tab I am able to get the values from table but in third class when I am executing the select query, I am getting the no such table exception.
Even I deleted the app from simulator and cleaned the project,but I got the same problem.
Kindly give me solutions.
Coding for create and insert:
-(void)InsertLoginDetails:(NSString *)user fun:(NSString *)pwd{
sqlite3_stmt *statement;
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat:
#"INSERT INTO Login ( USERNAME, PASSWORD) VALUES (\"%#\", \"%#\")",
user, pwd];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(_contactDB, insert_stmt,
-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"Inserted");
} else {
NSLog(#"Failed to insert");
}
sqlite3_finalize(statement);
sqlite3_close(_contactDB);
}
}
-(void)createLoginTable{
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
// Build the path to the database file
_databasePath = [[NSString alloc]
initWithString: [docsDir stringByAppendingPathComponent:
#"login.db"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: _databasePath ] == NO)
{
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt =
"CREATE TABLE IF NOT EXISTS Login (ID INTEGER PRIMARY KEY AUTOINCREMENT, USERNAME TEXT, PASSWORD TEXT)";
if (sqlite3_exec(_contactDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
NSLog(#"Failed to create table");
}
sqlite3_close(_contactDB);
NSLog(#"Table created");
} else {
NSLog(#"Failed to open/create database");
}
}
}
Code for getting values:
-(void)checkLoginSession{
///////////////GET DB DATAS///////////////////////
const char *dbpath = [_databasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
NSString *querySQL = #"SELECT USERNAME, PASSWORD FROM Login";
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(_contactDB,
query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
if (sqlite3_step(statement) == SQLITE_ROW)
{
strDBUsername = [[NSString alloc]
initWithUTF8String:
(const char *) sqlite3_column_text(
statement, 0)];
strDBPwd = [[NSString alloc]
initWithUTF8String:(const char *)
sqlite3_column_text(statement, 1)];
NSLog(#"Settings page Login Details %# %#", strDBUsername , strDBPwd );
// _address.text = addressField;
//
// _phone.text = phoneField;
// _status.text = #"Match found";
} else {
// _status.text = #"Match not found";
// _address.text = #"";
// _phone.text = #"";
}
sqlite3_finalize(statement);
}
else{
NSLog(#"SQLITE NOT OK");
NSLog(#"Error %s ", sqlite3_errmsg(_contactDB));
}
sqlite3_close(_contactDB);
}