Deep Trouble with values not inserting to sqlite database -iPhone - iphone

i have multiple view controllers, registrationviewcontroller , contactsviewcontroller , addnewcontactsviewcontroller, etc.
i have the below code in registrationviewcontroller
DatabaseCRUD *database = [[DatabaseCRUD alloc] init];
NSMutableString *registrationquery=[NSMutableString stringWithFormat:#"insert into BARvalues values ('%#','%#','%#','%#','%#','%#')",[name text],[emailAddress text],[mobileNumber text],[password text],[country text],#"0"];
NSLog(#"registrationquery is %#",registrationquery);
[database updatenewregistration:registrationquery];
[database release];
DatabaseCRUD *database1 = [[DatabaseCRUD alloc] init];
NSMutableString *registrationquery1=[NSMutableString stringWithFormat:#"insert into contacts values ('1234','1234')"];
NSLog(#"registrationquery is %#",registrationquery1);
[database1 updatenewregistration:registrationquery1];
[database1 release];
DatabaseCRUD *database2 = [[DatabaseCRUD alloc] init];
NSMutableString *registrationquery2=[NSMutableString stringWithFormat:#"insert into contacts values ('abcd','abcd')"];
NSLog(#"registrationquery is %#",registrationquery2);
[database2 addcontacts:registrationquery2];
[database2 release];
the above code works fine . it inserts the values into the sqlite database. Here is the problem , i have the almost same code in a different viewcontroller(contacts, addcontacts) and the values dont get inserted into the sqlite database.Here is the code.
DatabaseCRUD *database = [[DatabaseCRUD alloc] init];
NSMutableString *registrationquery=[NSMutableString stringWithFormat:#"insert into contacts values ('raja','shekar')"];
NSLog(#"registrationquery is %#",registrationquery);
[database updatenewregistration:registrationquery];
[database release];
DatabaseCRUD *database1 = [[DatabaseCRUD alloc] init];
NSMutableString *registrationquery1=[NSMutableString stringWithFormat:#"insert into contacts values ('rajesh','neelam')"];
NSLog(#"registrationquery is %#",registrationquery1);
[database1 addcontacts:registrationquery1];
[database1 release];
i dont see any reason why the database object would insertin in one viewcontroller and doesnt in the other viewcontroller. Any help will be greatly appreciated. i have tried to figure where the error is all day long and i dont want to waste anymore time. any help please????
I put breakpoints at every method of database object to see if its inserting, there is no error at all . it seems to be passing through the sqlstatment, but no insertion happens. Here is the code of saving the values in databaseHere is the code for database insertion.
-(void) addcontacts :(NSString *)query
{
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
NSLog(#"query is %#",query);
sqlStatement=[query cStringUsingEncoding:NSASCIIStringEncoding];
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK)
{
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
NSLog(#"new contact updated");
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
}

This is somewhere between an answer and a comment - interpret as necessary.
I assume that the insert statements return some error code, correct? What are their values? This will send you a long ways towards your solution.

Related

How to load uipickerview values from database in iphone?

I want to load data to uipickerview from database.
this is my code
if (sqlite3_prepare_v2(UsersDB, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
int i=0;
while (sqlite3_step(statement) == SQLITE_ROW)
{
NSLog(#"select");
self.coun=[[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
NSLog(#"Coun = %#",coun);
self.animals=[coun componentsSeparatedByString:#":"];
NSLog(#"String value=%#",self.animals);
}
sqlite3_finalize(statement);
} else
{
NSLog(#"not select");
}
and button actions code is
- (IBAction)selectAnItem:(UIControl *)sender {
//Display the ActionSheetPicker
[ActionSheetPicker displayActionPickerWithView:sender data:self.animals selectedIndex:self.selectedIndex target:self action:#selector(itemWasSelected::) title:#"Select Country"];
}
but it run load only last value. Not all values loaded in UIpickerview. How to load all values from database using this code. Anyone pls help me. Thanks in advance.
You have to do like this,
NSArray *splitedString = [coun componentsSeparatedByString: #":"];
NSString *animalName;
if ([splitedString count]>0)
{
animalName=[splitedString objectAtIndex:0];
[self.animals addObject:animalName]; //here animals should be NSMutableArray
}
In the while loop, you have to collect all the self.coun values in an array. When you come out of the loop, having all the values, populate the picker.
NSMutableArray *countries = [[NSMutableArray alloc] init];
while (sqlite3_step(statement) == SQLITE_ROW){
self.coun=[[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
NSLog(#"Coun = %#",coun);
[countries addObject:coun];
//self.animals=[coun componentsSeparatedByString:#":"];
//NSLog(#"String value=%#",self.animals);
}
// Now you can use countries to populate in picker.
You have to implement data source and delegates for the UIPickerView.
Seems, you are storing countries in DB, reading from DB you are assigning in self.animals. Thats kind of not matching things with variable names. And why are your parsing by ":"?

Need To Optimize SQLite Loading Into TableView

I have an SQLite Database with 5000 rows that is loaded into a tableview.
It takes around 5-10 sec (which is extremely long on the iPhone) to load the table. Is there a way I can load the cells in smaller batches or something else to speed this up? Also, when I go back up in hierarchy then revisit this view, it has to reload all over again. Can I cache this out instead?
- (void)viewDidLoad
{
[super viewDidLoad];
[NSThread detachNewThreadSelector:#selector(myThread:) toTarget:self withObject:nil];
}
-(void) myThread:(id) obj {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *array = [[Database sharedDatabase] getICD9DiseaseCodes];
[self performSelectorOnMainThread:#selector(dataDoneLoading:) withObject:array waitUntilDone:NO];
[pool release];
}
-(void) dataDoneLoading:(id) obj {
NSMutableArray *array = (NSMutableArray *) obj;
self.codeAray = array;
[self.myTableView reloadData];
[self dismissHUD];
NSLog(#"done");
}
In my database class:
-(NSMutableArray *) getICD9DiseaseCodes
{
sqlite3 *database = CodesDatabase();
NSMutableArray *icd9DiseaseCodes = [[[NSMutableArray alloc] init] autorelease];
NSString *nsquery = [[NSString alloc] initWithFormat:#"SELECT code, title, description FROM icd9_disease_codes ORDER BY code"];
const char *query = [nsquery UTF8String];
[nsquery release];
sqlite3_stmt *statement;
int prepareCode = (sqlite3_prepare_v2( database, query, -1, &statement, NULL));
if(prepareCode == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW)
{
ICD9DiseaseCodes *code = [[ICD9DiseaseCodes alloc] init];
code.code = [NSString stringWithCString:(char *)sqlite3_column_text(statement, 0) encoding:NSUTF8StringEncoding];
code.name = [NSString stringWithCString:(char *)sqlite3_column_text(statement, 1) encoding:NSUTF8StringEncoding];
code.description = [NSString stringWithCString:(char *)sqlite3_column_text(statement, 2) encoding:NSUTF8StringEncoding];
[icd9DiseaseCodes addObject:code];
// NSLog(#"Code: %# Short Description: %# Long Description: %#", hcpcsCode.code, hcpcsCode.name, hcpcsCode.description);
[code release];
}
sqlite3_finalize(statement);
}
return icd9DiseaseCodes;
}
My first question is why do you use SQLite directly, and not Core Data? Core Data will do fast partial fetches from the data store for you, for free with no extra code on your part.
If you want to do the same thing manually with SQLite directly, then you are in for some heavy lifting code. You will need to use LIMIT and OFFSET in your SQL queries to fetch partial data, and extend your API to fetch only smaller sub-sets at a time.
Have you considered or looked into CoreData? CoreData has a lot of optimization for large recordsets.
Thanks.
James

How to view sqlite database by button press

hye all,
i have built a SQLite database and wanna to add into iphone app. already i have add it resource->add->x.sqlite and also add libsqlite3.0.dylib.framework but i don't know what is the showing code. I wanna to show the data in the db when user pressed button.
Can anyone help me to give an example on how the db can be view when button is press??
Here's some basic code to query the database:
-(NSArray*)names
{
NSString* query = [[NSString alloc] initWithString:#"SELECT name FROM sometablename;"];
sqlite3_stmt* statement;
int retval = sqlite3_prepare_v2(yourDatabaseHandle, [query UTF8String], -1, &statement, nil);
[query release];
if (retval != SQLITE_OK)
{
sqlite3_close(yourDatabaseHandle);
NSAssert1(0, #"Error querying table: %i", (retval ^ SQLITE_ERROR));
return nil;
}
NSMutableArray* values = [[[NSMutableArray alloc] init] autorelease];
while (sqlite3_step(statement) == SQLITE_ROW)
{
const char* value = (const char*)sqlite3_column_text(statement, 0);
NSString* s = [[NSString alloc] initWithUTF8String:value];
[values addObject:s];
[s release];
}
sqlite3_finalize(statement);
return values;
}
You might want to present this in a table view. There are plenty of questions & answers here on Stack Overflow already to explain how to do that, as well as plenty of Apple sample code.

iphone - SQLite records on table not coming?

I have a table and 3 records.
and I have the code;
-(void) readScoreFromDatabase {
sqlite3 *database;
scores = [[NSMutableArray alloc] init];
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = "select name,score from game";
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
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
//if(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *aName =[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
NSString *aScore =[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
DatabaseClass *dbOBJ = [[DatabaseClass alloc] initWithName:aName score:aScore];
[scores addObject:dbOBJ];
[dbOBJ release];
}
}
sqlite3_finalize(compiledStatement);
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"No Connection"
delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
sqlite3_close(database);
}
and I am using that code to show records;
-(IBAction)refreshClick:(id)sender {
// Navigation logic -- create and push a new view controller
IDRGameAppDelegate *appDelegate = (IDRGameAppDelegate *)[[UIApplication sharedApplication] delegate];
DatabaseClass *dbOBJ = (DatabaseClass *)[appDelegate.scores objectAtIndex:1];
game1NameLabel.text = dbOBJ.name;
score1Label.text = dbOBJ.score;
}
I have 3 records, but I can take only one record. I mean changed that line "DatabaseClass *dbOBJ = (DatabaseClass *)[appDelegate.scores objectAtIndex:1];"
objectAtIndex:1 when I change this value 1 or 2 or 3 etc. the result doesn't change. It is always showing one record from 3 records. I don't understand the reason.
Thank you.
Are you able to see the table rows, when you go to the SQLite manager (from Firefox) and run the below query:
select name,score from game;
If you are able to see 3 records, then:
Go to the iPhone simulator and reset settings
(which will clear all the temp caches, database, and build files).
Go to Xcode and do a Build and GO.
This will get you latest database; put it in the Build folder.
This may not be the answer you want, but you should really consider using Core Data now that it's in iPhone OS 3.0. It handles most of this for you and is very easy to use.
Maybe you forgot to set score to your delegate?
scores = [[NSMutableArray alloc] init];
....
//I don't see this in your code
((IDRGameAppDelegate *)[[UIApplication sharedApplication] delegate]).score = score;

Accessing an SQLite DB for two separate queries on iPhone App Initialization

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 ;)