I am making a small iPhone application in which I have implemented the database concept which is used to store name, contact no, email id. I Want that whenever I user save any contact It get displayed on table view. In -(IBAction)retriveall:(id)sender action I am retriving all the data from database and storing it into array. Now I want to display all the data in tableview.
How can I do this? Please help me.
-(IBAction)retriveall:(id)sender
{
[self retrive2];
for (int i =0; i< [namearray count]; i++)
{
NSLog(#"Name is:%#",[namearray objectAtIndex:i]);
NSLog(#"Password is:%#",[passarray objectAtIndex:i]);
}
}
-(IBAction)retrive:(id)sender
{
[self retrive1];
two.text = databasecolorvalue;
UIAlertView *favAlert=[[UIAlertView alloc] initWithTitle:#"" message:#"Retrived" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[favAlert show];
[favAlert release];
}
-(void)retrive1
{
databaseName = #"med.sqlite";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
#try {
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement="select pswd from Login where username = ? ";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
// Create a new animal object with the data from the database
sqlite3_bind_text(compiledStatement, 1, [one.text UTF8String], -1, SQLITE_TRANSIENT);
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
databasecolorvalue =[NSString stringWithUTF8String:(char*)sqlite3_column_text(compiledStatement,0)];
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
#catch (NSException * ex) {
#throw ex;
}
#finally {
}
}
You should declare an mutable array as an instance variable something like,
NSMutableArray * colors;
Initialize it in the viewDidLoad method and later alter your retrive1 method to add to the colors array.
-(void)retrive1
{
/* Clearing existing values for newer ones */
[colors removeAllObjects]
/* Get database path */
#try {
[..]
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
[colors addObject:[NSString stringWithUTF8String:(char*)sqlite3_column_text(compiledStatement,0)]];
}
[..]
}
#catch (NSException * ex) { #throw ex; }
#finally { }
}
And you'll have to implement the rest of the table view methods in the usual manner using the array as the source.
You have to create object with all data and implementation of UITableViewDataSource protocol for table view and set it in TableView property dataSource. After you havecall UITableView method
-(void)reloadData;
Related
I have Sequence of Queries that need to be performed with database..
Most of time its working fine.. but some time it failed to insert query.
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
for (int i=0;i<[queries count]; i++)
{
NSString *query = [queries objectAtIndex:i];
const char *Insert_query = [query UTF8String];
sqlite3_prepare(contactDB, Insert_query, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
//NSLog(#" \n\n\n\n %# done query",query);
}
else {
NSLog(#" \n\n\n\n %# not done query",query);
}
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
Above is code which i have implemented to perform insert operation...
Can any one help me to find if it fails then for what reason it failed to insert to database so i can handle error..
Use this method to execute query on sqlite
//-----------------------------------------------------------------------------------------------------//
#pragma mark - Helper methods
//-----------------------------------------------------------------------------------------------------//
-(BOOL)dbOpenedSuccessfully
{
if(sqlite3_open([[self dbPath] UTF8String], &_database) == SQLITE_OK)
{
return YES;
}
else
{
[[[UIAlertView alloc]initWithTitle:#"Error"
message:#"Error on opening the DB"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil]show];
return NO;
}
}
//-----------------------------------------------------------------------------------------------------//
#pragma mark - Query
//-----------------------------------------------------------------------------------------------------//
- (void) executeQuery:(NSString *)strQuery
{
char *error = NULL;
if([self dbOpenedSuccessfully])
{
NSLog(#"%#",strQuery);
sqlite3_exec(_database, [strQuery UTF8String], NULL, NULL,&error);
if (error!=nil) {
NSLog(#"%s",error);
}
sqlite3_close(_database);
}
}
Also If insert not works properly the reason may be the file is not in the documents directory and if it is there in bundle it will fetch tha data but cannot update or insert value if db is in bundle ,Copy it to the documents directory and then try using it
-(void) checkAndCreateDatabase
{
// Check if the SQL database has already been saved to the users phone, if not then copy it over
BOOL success;
// Create a FileManager object, we will use this to check the status
// of the database and to copy it over if required
NSFileManager *fileManager = [NSFileManager defaultManager];
// Check if the database has already been created in the users filesystem
success = [fileManager fileExistsAtPath:_databasePath];
// If the database already exists then return without doing anything
if(success) return;
// If not then proceed to copy the database from the application to the users filesystem
// Get the path to the database in the application package
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:_databaseName];
// Copy the database from the package to the users filesystem
[fileManager copyItemAtPath:databasePathFromApp toPath:_databasePath error:nil];
}
For more info see this
You can try printing the error in the following way, Based on the error you can make decision.
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
for (int i=0;i<[queries count]; i++)
{
NSString *query = [queries objectAtIndex:i];
const char *Insert_query = [query UTF8String];
sqlite3_prepare(contactDB, Insert_query, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
//NSLog(#" \n\n\n\n %# done query",query);
}
else {
NSLog(#"sqlite3_step error: '%s'", sqlite3_errcode(contactDB));
NSLog(#" \n\n\n\n %# not done query",query);
}
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
Additionally,
SQLITE_DONE means that the statement has finished executing
successfully. sqlite3_step() should not be called again on this
virtual machine without first calling sqlite3_reset() to reset the
virtual machine back to its initial state.
You can use, SQLITE_OK instead of SQLITE_DONE.
I am writing a simple query as below
const char *sql = "insert into abc(name) values ('Royal')";
and this will insert each time 'Royal' into my 'name', so now I want to take input from user each time as names of hotel and wants to save them instead of 'Royal', so what should I do?
If you are not clear to my question, you may as me again,,,,,
this code is very simple for insert the value in sqlite3 table
-(void)writeValueInSettings:(NSMutableArray *)arrayvalue
{
if(sqlite3_open([databasePath UTF8String],&myDatabase)==SQLITE_OK)
{
database *objectDatabase=[[database alloc]init];
NSString *stringvalue2=[objectDatabase countValue];
[objectDatabase release];
NSLog(#"opened");
NSString *sql1;
sql1=[[NSString alloc] initWithFormat:#"insert into setting values('%i','%i','%i','%#','%i','%i','%#','%i','%i','%i','%i','%i','%i','%#');",intvalue1,
[[arrayvalue objectAtIndex:0] intValue],[[arrayvalue objectAtIndex:1] intValue],[arrayvalue objectAtIndex:2],[[arrayvalue objectAtIndex:3] intValue],[[arrayvalue objectAtIndex:4]intValue ],[arrayvalue objectAtIndex:5],[[arrayvalue objectAtIndex:6]intValue],[[arrayvalue objectAtIndex:7]intValue ],[[arrayvalue objectAtIndex:8] intValue],[[arrayvalue objectAtIndex:9] intValue],[[arrayvalue objectAtIndex:10]intValue ],[[arrayvalue objectAtIndex:11]intValue],[arrayvalue objectAtIndex:12]];
char *err1;
if (sqlite3_exec(myDatabase,[sql1 UTF8String],NULL,NULL,&err1)==SQLITE_OK)
{
NSLog(#"value inserted:");
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Attention" message:#"You inserted successfully" delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok", nil];
[alert show];
[alert release];
}
[sql1 release];
sqlite3_close(myDatabase);
}
}
you need to connect to a database
- (sqlite3 *)database {
if (nil == db) {
NSString *path = <path to your database>;
int res = sqlite3_open([path UTF8String], &db);
if (res != SQLITE_OK){
// handle the error.
db = nil;
return nil;
}
}
return db;
}
then you can call this with the query
-(void)executeQuery:(NSString *)query{
sqlite3_stmt *statement;
if (sqlite3_prepare_v2([self database], [query UTF8String], -1, &statement, NULL) == SQLITE_OK) {
sqlite3_step(statement);
}else{
// handle the error.
}
sqlite3_finalize(statement);
}
-(void)dealloc {
//close database connection
sqlite3_close(db);
db = nil;
[super dealloc];
}
-(NSArray *) executeSelect:(NSString *)query {
//Data search block****************************************
char *zErrMsg;
char **result;
int nrow, ncol;
sqlite3_get_table(
[self database], /* An open database */
[query UTF8String], /* SQL to be executed */
&result, /* Result written to a char *[] that this points to */
&nrow, /* Number of result rows written here */
&ncol, /* Number of result columns written here */
&zErrMsg /* Error msg written here */
);
NSMutableArray *returnArray = [NSMutableArray arrayWithCapacity:3];
for (int i=0; i<nrow; i++){
[returnArray addObject:[NSString stringWithUTF8String:result[ncol + i]]];
}
sqlite3_free_table(result);
return returnArray;
}
Hi
if Your getting user inputs in userinput textfield
NSString *qry=[NSString stringwithformat:#"insert into abc(name) values (\"%#\")",userinput.text];
const char *sql = [qry UTF8string];
sqlite3 *contactDB;
const char *dbpath = [databasePath UTF8String]; // Convert NSString to UTF-8
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
if (sqlite3_exec(contactDB, sql_stmt, NULL, NULL, &errMsg) == SQLITE_OK)
{ // SQL statement execution succeeded
}
} else {
//Failed to open database
}
a noob here asking for help after a day of head-banging....
I am working on an app with sqlite3 database with one database and two tables. I have now come to a step where I want to select from the table with an argument. The code is here:
-(NSMutableArray*) getGroupsPeopleWhoseGroupName:(NSString*)gn;{
NSMutableArray *groupedPeopleArray = [[NSMutableArray alloc] init];
const char *sql = "SELECT * FROM Contacts WHERE groupName='?'";
#try {
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *docsDir = [paths objectAtIndex:0];
NSString *theDBPath = [docsDir stringByAppendingPathComponent:#"ContactBook.sqlite"];
if (!(sqlite3_open([theDBPath UTF8String], &database) == SQLITE_OK))
{ NSLog(#"An error opening database."); }
sqlite3_stmt *st;
NSLog(#"debug004 - sqlite3_stmt success.");
if (sqlite3_prepare_v2(database, sql, -1, &st, NULL) != SQLITE_OK)
{ NSLog(#"Error, failed to prepare statement."); }
//DB is ready for accessing, now start getting all the info.
while (sqlite3_step(st) == SQLITE_ROW)
{
MyContacts * aContact = [[MyContacts alloc] init];
//get contactID from DB.
aContact.contactID = sqlite3_column_int(st, 0);
if (sqlite3_column_text(st, 1) != NULL)
{ aContact.firstName = [NSString stringWithUTF8String:(char *) sqlite3_column_text(st, 1)]; }
else { aContact.firstName = #""; }
// here retrieve other columns data ....
//store these info retrieved into the newly created array.
[groupedPeopleArray addObject:aContact];
[aContact release];
}
if(sqlite3_finalize(st) != SQLITE_OK)
{ NSLog(#"Failed to finalize data statement."); }
if (sqlite3_close(database) != SQLITE_OK)
{ NSLog(#"Failed to close database."); }
}
#catch (NSException *e) {
NSLog(#"An exception occurred: %#", [e reason]);
return nil; }
return groupedPeopleArray;}
MyContacts is the class where I put up all the record variables.
My problem is sqlite3_step(st) always return SQLITE_DONE, so that it i can never get myContacts. (i verified this by checking the return value).
What am I doing wrong here?
Many thanks in advance!
I think you are not binding the value, if not use this
sqlite3_bind_text(stmt, 1, [groupName UTF8String], -1, SQLITE_STATIC);
You're not binding any value to your statement.
You're literally executing SELECT * FROM Contacts WHERE groupName='?' as is.
And that likely returns an empty set, which is why sqlite3_step returns SQLITE_DONE, there's nothing to read in the set, you're done.
This page has an example of binding parameters to a statement..
EDIT: Also, you don't need the quotes around ?
SELECT * FROM Contacts WHERE
groupName=?
then use sqlite3_bind_text
small clarification is this possible to open two tables from one sqlite db in one iphone class??? but i can't open it please give me the solution i'm a beginner
here i tried coding
- (void)viewDidLoad {
[super viewDidLoad];
list = [[NSMutableArray alloc] init];
if ([material isEqualToString:#"Derlin"]) {
[self sel1];
}
else if([material isEqualToString:#"Helers"]){
[self sel2];
}
}
-(void)sel1 {
[self createEditableCopyOfDatabaseIfNeeded];
NSLog(#"numberOfRowsInSection");
sqlite3_stmt *statement = nil; // create a statement
const char *sql = "Select * from material"; //create a query to display in the tableView
if(sqlite3_open([writableDBPath UTF8String], &database) == SQLITE_OK)
{
NSLog(#"sqlite3_open");
if(sqlite3_prepare_v2(database, sql,-1, &statement, NULL)!=SQLITE_OK)
NSAssert1(0,#"Error Preparing Statement",sqlite3_errcode(database));
else
{
while(sqlite3_step(statement) == SQLITE_ROW) // if the connection exists return the row of the query table
{
achemical = [NSString stringWithFormat:#"%s",(char *)sqlite3_column_text(statement,0)];
arates = [NSString stringWithFormat:#"%s",(char *)sqlite3_column_text(statement,1)];
anotes = [NSString stringWithFormat:#"%s",(char *)sqlite3_column_text(statement,2)];
Chemical * chemic = [[Chemical alloc] initWithName:achemical rates:arates notes:anotes];
[list addObject:chemic];
[chemic release];
}
}
}
sqlite3_finalize(statement);
}
-(void)sel2 {
[self createEditableCopyOfDatabaseIfNeeded];
NSLog(#"numberOfRowsInSection");
sqlite3_stmt *statement = nil; // create a statement
const char *sql = "Select * from material1"; //create a query to display in the tableView
if(sqlite3_open([writableDBPath UTF8String], &database) == SQLITE_OK)
{
NSLog(#"sqlite3_open");
if(sqlite3_prepare_v2(database, sql,-1, &statement, NULL)!=SQLITE_OK)
NSAssert1(0,#"Error Preparing Statement",sqlite3_errcode(database));
else
{
while(sqlite3_step(statement) == SQLITE_ROW) // if the connection exists return the row of the query table
{
achemical = [NSString stringWithFormat:#"%s",(char *)sqlite3_column_text(statement,0)];
arates = [NSString stringWithFormat:#"%s",(char *)sqlite3_column_text(statement,1)];
anotes = [NSString stringWithFormat:#"%s",(char *)sqlite3_column_text(statement,2)];
Chemical * chemic = [[Chemical alloc] initWithName:achemical rates:arates notes:anotes];
[list addObject:chemic];
[chemic release];
}
}
}
sqlite3_finalize(statement);
}
thanks in advance
Sure, it's easy. Download FMDB, add it to your project, and add two FMResultSet objects in your class, one for each (query against each) table.
I was successfully accessing my database to get a list of cities on the App launch. I tried running a second query against it right afterward to get the list of States but all that happens is that my app blows up with no usable error in the console (simply says "Program received signal: EXEC_BAD_ACCESS" and nothing more).
Here is the code, I was hoping someone could potentially explain to me what I'm doing wrong:
-(void) initializeDatabase{
// The database is stored in the application bundle
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"mydatabase.sqlite"];
// Open the database. The database was prepared outside the application.
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK){
[self initializeCities:database];
[self initializeStates:database];
} else {
// Even though the open failed, call close to properly clean up resources.
sqlite3_close(database);
NSAssert1(0, #"Failed to open database with message '%s'.", sqlite3_errmsg(database));
// Additional error handling, as appropriate...
}
}
-(void) initializeCities:(sqlite3 *)db {
NSMutableArray *cityArray = [[NSMutableArray alloc] init];
self.cities = cityArray;
[cityArray release];
// Get the primary key for all cities.
const char *sql = "SELECT id FROM my_table ORDER BY state";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(db, sql, -1, &statement, NULL) == SQLITE_OK){
while (sqlite3_step(statement) == SQLITE_ROW){
int primaryKey = sqlite3_column_int(statement, 0);
City *city = [[City alloc] initWithPrimaryKey:primaryKey database:db];
[cities addObject:city];
[city release];
}
}
// "Finalize" the statement - releases the resources associated with the statement.
sqlite3_finalize(statement);
}
-(void) initializeStates:(sqlite3 *)db {
NSMutableArray *statesArray = [[NSMutableArray alloc] init];
self.states = statesArray;
[statesArray release];
// Get the primary key for all cities.
const char *sql = "SELECT DISTINCT state FROM my_table ORDER BY state";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(db, sql, -1, &statement, NULL) == SQLITE_OK){
// We "step" through the results - once for each row
while (sqlite3_step(statement) == SQLITE_ROW){
NSString *state;
state = (NSString *)sqlite3_column_text(statement, 0);
[states addObject:state];
[state release];
}
}
// "Finalize" the statement - releases the resources associated with the statement.
sqlite3_finalize(statement);
}
I can't debug this code as the debugger never hits my breakpoints at all.
If I remove the initializeStates method the app works as expected (albiet without a list of states).
You are releasing "state" without having allocated it. Try something like this:
while (sqlite3_step(statement) == SQLITE_ROW){
NSString *state = [[NSString alloc] initWithCString:(char*)sqlite3_column_text(statement, 0) encoding:NSASCIIStringEncoding];
//state = (NSString *)sqlite3_column_text(statement, 0);
[states addObject:state];
[state release];
}
Update: add cast above to fix compiler warning
Your problem is this:
NSString *state = (NSString *)sqlite3_column_text(statement, 0);
According to the documentation, sqlite3_column_text() returns a char*, not an NSString*.
Edit: You wouldn't have had this problem if you'd have used a wrapper ;)