Problem fetching more than the first row from SQLite DB - objective-c

I am creating an application which first checks whether the user is valid or not by checking data from an SQLite database. I have created a table named loginchk in the database with three rows and two columns in it, uname and pass.
When I run the application and enter the username and password values in my text fields, it checks if the username and password are in the database. If they are not, it will present an alert view that says "Please enter correct username".
In my code there is a problem: it reads only the first row, i.e., when I enter the username and password values that are in the first row it succeeds, and all the other values that I enter do not work.
What could be the problem?
Thanks.
#import "loginAppDelegate.h"
#import "global.h"
#import <sqlite3.h>
#import "logincontroller.h"
#implementation loginAppDelegate
#synthesize window;
#synthesize loginView;
//databaseName=#"login.sqlite";
-(void) chekAndCreateDatabase
{
BOOL success;
//sqlite3 *databaseName=#"login.sqlite";
NSFileManager *fileManager=[NSFileManager defaultManager];
NSArray *documentPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir =[documentPaths objectAtIndex:0];
NSString *databasePath=[documentsDir stringByAppendingPathComponent"login.sqlite"]; success=[fileManager fileExistsAtPathatabasePath];
if(success)return;
NSString *databasePathFromApp=[[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent"login.sqlite"];
[fileManager copyItemAtPathatabasePathFromApp toPathatabasePath error:nil]; [fileManager release];
}
-(void) Data
{
Gpass=#"";
Guname=#"";
sqlite3_stmt *detailStmt=nil;
//sqlite3 *databaseName;
NSArray *documentPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir =[documentPaths objectAtIndex:0];
NSString *databasePath=[documentsDir stringByAppendingPathComponent{angry_smile}"login.sqlite"];
[self chekAndCreateDatabase];
sqlite3 *database;
if (sqlite3_open([databasePath UTF8String],&database)==SQLITE_OK)
{
if (detailStmt==nil)
{
const char *sql= "select *from Loginchk"; //where uname='%?'and password='%?'"; //NSString *sql = [[NSString alloc] initWithFormat{angry_smile}"SELECT * FROM Loginchk WHERE uname ='%#' and password ='%#' ",Uname.text,Password.text];
if (sqlite3_prepare_v2(database,sql,-1,&detailStmt,NULL)==SQLITE_OK)
{
sqlite3_bind_text(detailStmt,1,[Gunameq UTF8String],-1,SQLITE_TRANSIENT);
sqlite3_bind_text(detailStmt,2,[Gpassq UTF8String],-1,SQLITE_TRANSIENT);
if (SQLITE_DONE!= sqlite3_step(detailStmt))
{
Guname=[NSString stringWithUTF8Stringchar*)sqlite3_column_text(detailStmt,0)];
Gpass =[NSString stringWithUTF8Stringchar*)sqlite3_column_text(detailStmt,1)];
NSLog(#"'%#'",Guname);
NSLog(#"'%#'",Gpass); }
} sqlite3_finalize(detailStmt);
}
} sqlite3_close(database);
}
This my login controller; here I am calling my app delegate's function data:
-(IBAction)buttonPressed:(id)sender
{
Gpassq=Password.text;
Gunameq=Uname.text;
NSLog(#"%#%#",Gunameq,Gpassq);
loginAppDelegate *appDelegate =(loginAppDelegate *)[[UIApplication sharedApplication]delegate];
[appDelegate Data];
if ([Uname.text isEqualToString:Guname]&&[Password.text isEqualToString:Gpass])
{
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"UIAlertView" message:#"Success" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
else
{
UIAlertView *alert =[[UIAlertView alloc]initWithTitle:#"UIAlertView" message:#"PleaseEnterCorrectUserName and password" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
}

change
if (SQLITE_DONE!= sqlite3_step(detailStmt))
with
while (SQLITE_DONE!= sqlite3_step(detailStmt))
Update 1
use this code -
-(void) Data
{
Gpass=#"";
Guname=#"";
sqlite3_stmt *detailStmt=nil;
//sqlite3 *databaseName;
NSArray *documentPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir =[documentPaths objectAtIndex:0];
NSString *databasePath=[documentsDir stringByAppendingPathComponent:#"login.sqlite"];
[self chekAndCreateDatabase];
sqlite3 *database;
if (sqlite3_open([databasePath UTF8String],&database)==SQLITE_OK)
{
const char *sql= "select *from Loginchk"; //where uname='%?'and password='%?'"; //NSString *sql = [[NSString alloc] initWithFormat{angry_smile}"SELECT * FROM Loginchk WHERE uname ='%#' and password ='%#' ",Uname.text,Password.text];
sqlite3_stmt *detailStmt;
if (sqlite3_prepare_v2(database,sql,-1,&detailStmt,NULL)==SQLITE_OK)
{
while(sqlite3_step(detailStmt) == SQLITE_ROW)
{
Guname=[NSString stringWithUTF8String:(char *)sqlite3_column_text(detailStmt,0)];
Gpass =[NSString stringWithUTF8String:(char *)sqlite3_column_text(detailStmt,1)];
NSLog(#"'%#'",Guname);
NSLog(#"'%#'",Gpass);
}
}
sqlite3_finalize(detailStmt);
sqlite3_close(database);
}
}

Try this
\-(void) Data
{
Gpass=#"";
Guname=#"";
sqlite3_stmt *detailStmt=nil;
//sqlite3 *databaseName;
NSArray *documentPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir =[documentPaths objectAtIndex:0];
NSString *databasePath=[documentsDir stringByAppendingPathComponent{angry_smile}"login.sqlite"];
[self chekAndCreateDatabase];
sqlite3 *database;
if (sqlite3_open([databasePath UTF8String],&database)==SQLITE_OK)
{
if (detailStmt==nil)
{
const char *sql= "select *from Loginchk"; //where uname='%?'and password='%?'"; //NSString *sql = [[NSString alloc] initWithFormat{angry_smile}"SELECT * FROM Loginchk WHERE uname ='%#' and password ='%#' ",Uname.text,Password.text];
if (sqlite3_prepare_v2(database,sql,-1,&detailStmt,NULL)==SQLITE_OK)
{
sqlite3_bind_text(detailStmt,1,[Gunameq UTF8String],-1,SQLITE_TRANSIENT);
sqlite3_bind_text(detailStmt,2,[Gpassq UTF8String],-1,SQLITE_TRANSIENT);
// Loop through the results
while(sqlite3_step(detailStmt) == SQLITE_ROW) {
{
Guname=[NSString stringWithUTF8Stringchar*)sqlite3_column_text(detailStmt,0)];
Gpass =[NSString stringWithUTF8Stringchar*)sqlite3_column_text(detailStmt,1)];
NSLog(#"'%#'",Guname);
NSLog(#"'%#'",Gpass); }
} sqlite3_finalize(detailStmt);
}
} sqlite3_close(database);
}

Related

SQLite Problems when using NSFileManager

I am using SQLite and previous answers state that I should use this code:
#import "ViewController.h"
#interface ViewController ()
{
NSMutableArray *arrayOfPerson;
sqlite3 *personDB;
NSString *dbPathString;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
arrayOfPerson = [[NSMutableArray alloc]init];
[[self myTableView]setDelegate:self];
[[self myTableView]setDataSource:self];
[self createOrOpenDB];
}
- (void)createOrOpenDB
{
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [path objectAtIndex:0];
dbPathString = [docPath stringByAppendingPathComponent:#"persons.db"];
char *error;
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL success = [fileManager fileExistsAtPath:dbPathString];
NSLog(#"here 0");
if (!success) {// THIS IS MY CONCERN
const char *dbPath = [dbPathString UTF8String];
NSLog(#"here 1");
//creat db here
NSLog(#"sqlite3 = %d",sqlite3_open(dbPath, &personDB));
NSLog(#"OK= %d", SQLITE_OK);
if (sqlite3_open(dbPath, &personDB)==SQLITE_OK) {
NSLog(#"here 2");
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS PERSONS (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, AGE INTEGER)";
sqlite3_exec(personDB, sql_stmt, NULL, NULL, &error);
sqlite3_close(personDB);
}
}
}
However, when I run this code my app does not gets into this loop:
if(!success) {
....
}
I tried using
if(success) {
....
}
and it works. But I do not think that is correct. Please help me.

How to Compare two rows in Sqlite3 table?

Here i m trying to compare details of rows values in consisting table.here my table contents [here my table
][1]
and also here my code
`-
(IBAction)LogIn:(id)sender {
sqlite3 *dbConnection;
const char *dbpath = [[sharedobj getSandboxPath] UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &dbConnection) == SQLITE_OK)
{
NSString *querySQL = #"SELECT USERNAME, PASSWORD FROM NEWVALUES";
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(dbConnection,
query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
if (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *emailId = [[NSString alloc]
initWithUTF8String:
(const char *) sqlite3_column_text(statement,0)];
NSString *password = [[NSString alloc]
initWithUTF8String:(const char *)
sqlite3_column_text(statement, 1)];
if ([emailId isEqualToString:self.userNameField.text] || [password isEqualToString:self.passwordField.text]) {
NSLog(#"Login Credentials Correct");
CHECKViewController *checkobj=[self.storyboard instantiateViewControllerWithIdentifier:#"CHECK"];
[self.navigationController pushViewController:checkobj animated:YES];
}
else{
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Error"
message:#"Login Credentials are Incorrect"
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"OK ", nil];
[alert show];
}
}
NSLog(#"Login Details %# %#",self.userNameField.text ,self.passwordField.text );
}
sqlite3_finalize(statement);
}
else{
NSLog(#"SQLITE NOT OK");
NSLog(#"Error %s ", sqlite3_errmsg(dbConnection));
}
sqlite3_close(dbConnection);
}
imgur.com/QW6KX.png
when enter first row values it working but when i enter second row values it not comparing .what i m doing wrong here?
Please give suggestions to fix this issue.
thanks in advance.

How much data available in table using row count not working

I want to check at the load time of application whether data is available or not in the table so for that I using following code on the viewload of my first file if available then move to other file else retain same but it can't give perfect result mainly row count is not working
NSString *dbPath;
NSString *docsDir;
NSArray *dirPath;
int count=0;
dirPath=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir=[dirPath objectAtIndex:0];
dbPath=[[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent:#"TimerDataBaseMain.db"]];
NSFileManager *fileManager=[NSFileManager defaultManager];
if([fileManager fileExistsAtPath: dbPath] == YES)
{
const char *databsPath=[dbPath UTF8String];
NSLog(#"from created;");
if(sqlite3_open(databsPath,&sqlDatabase) == SQLITE_OK)
{
const char *query="SELECT COUNT(*) FROM PRJDATA";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(sqlDatabase, query, -1, &statement, NULL)==SQLITE_OK) {
while(sqlite3_step(statement)==SQLITE_ROW)
{
count++;
NSLog(#"from count");
}
NSLog(#"from row count");
}
sqlite3_finalize(statement);
}
sqlite3_close(sqlDatabase);
}
if (count>0) {
ListEventCreated *listObject=[[ListEventCreated alloc] initWithNibName:#"ListEventCreated" bundle:[NSBundle mainBundle]];
listObject.title=#"List of event";
NSLog(#"from if condition");
NSLog(#"%i",count);
[self.navigationController pushViewController:listObject animated:YES];
[listObject release];
listObject=nil;
}
I believe , this is WRONG
SELECT COUNT(*) PRJDATA
You should use this
SELECT COUNT(*) FROM PRJDATA

Cannot achieve a successful sqlite query to display in my text view

I'm trying to display a string of text in a text view. According to NSLog the database is found but, I cannot retrieve the data from the table. Could someone point out what is wrong with my query? (I may need this explained in very simple terms. I've been sing objective-c for only a few days.)
- (void)viewDidLoad {
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
// Build the path to the database file
databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent:#"trivia_game.db"]];
NSLog(#"Full DB path: %#", databasePath);
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: databasePath ] == NO)
{
const char *dbpath = [databasePath UTF8String];
NSLog(#"[SQLITE] DB not found");
} else {
NSLog(#"[SQLITE] trivia_game.db found");
}
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &questionsForGame) == SQLITE_OK)
{
NSLog(#"[SQLITE] db opened");
NSString *querySQL = [NSString stringWithFormat: #"SELECT question, answer0, answer1, answer2, answer3 FROM questions"];
NSLog(#"[SQLITE] string is: %#", querySQL);
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(questionsForGame, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
NSLog(#"[SQLITE] written!");
if (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *textField = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
questHolder.text = textField;
NSLog(#"[SQLITE] string is: %#",textField);
[textField release];
} else {
questHolder.text = #"query not found";
NSLog(#"[SQLITE] Unable to open database!");
}
sqlite3_finalize(statement);
sqlite3_close(questionsForGame);
} else {
NSLog(#"[SQLITE] Screwed up query!");
questHolder.text = #"query not found";
}
}
[filemgr release];
[super viewDidLoad];
}
log:
[Session started at 2012-05-28 12:27:19 -0300.]
2012-05-28 12:27:20.547 ans[9374:207] Full DB path: /Users/admin/Library/Application Support/iPhone Simulator/4.3/Applications/0B4C50FB-5A3F-4371-83D6-1A2AF95B9F66/Documents/trivia_game.db
2012-05-28 12:27:20.549 ans[9374:207] [SQLITE] trivia_game.db found
2012-05-28 12:27:20.550 ans[9374:207] [SQLITE] db opened
2012-05-28 12:27:20.551 ans[9374:207] [SQLITE] string is: SELECT question, answer0, answer1, answer2, answer3 FROM questions
2012-05-28 12:27:20.553 ans[9374:207] [SQLITE] Screwed up query!
I am not familiar with the SQLite library you're using but I would recommend to switch to Core Data. cf. http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/coredata/cdprogrammingguide.html

Code is bypassing Array creation Loop from a sqlite database

my NSMutableArray creation code is being bypassed altogether for some reason. in theory it is supposed to create an NSMutableArray based on an sqlite database. There is only one warning message and no errors. what am I missing?
the implementation file is:
#import "iProspectFresno LiteAppDelegate.h"
#import "MainViewController.h"
#import "Mine.h"
#import <Foundation/Foundation.h>
#implementation iProspectFresno_LiteAppDelegate
#synthesize window;
#synthesize mainViewController;
#synthesize mines;
-(void) checkAndCreateDatabase {
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) readMinesFromDatabase
{
sqlite3 *database;
mines = [[NSMutableArray alloc] init];
NSLog(#"readMinesFromDatabase initialized");
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = "select * from MinesoftheMotherLode";
sqlite3_stmt *compiledStatement;
NSLog(#"first if statement");
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK)
{
NSLog(#" second if statement initialized");
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
NSNumber *aentryNumber = [NSNumber numberWithInt:(int)sqlite3_column_int(compiledStatement, 1)];
NSString *amineName = [NSString stringWithUTF8String:(char*)sqlite3_column_text(compiledStatement, 2)];
NSString *amineType = [NSString stringWithUTF8String:(char*)sqlite3_column_text(compiledStatement, 3)];
NSString *astatus = [NSString stringWithUTF8String:(char*)sqlite3_column_text(compiledStatement, 4)];
NSNumber *alatitude = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 5)];
NSNumber *alongitude = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 6)];
NSString *ametal =[NSString stringWithUTF8String:(char*)sqlite3_column_text(compiledStatement, 7)];
BOOL *adisplay = NO;
NSNumber *acoverRegion =[NSNumber numberWithInt:(int)sqlite3_column_int(compiledStatement, 9)];
NSLog(#"mine", aentryNumber, amineName, amineType, astatus, alatitude, alongitude, ametal, adisplay, acoverRegion);
Mine *mine = [[Mine alloc] initWithEntryNumber:aentryNumber mineName:amineName mineType:amineType status:astatus latitudeInitial:alatitude longitudeInitial:alongitude metal:ametal display:adisplay coverRegion:acoverRegion];
[mines addobject:mine];
[mine release];
}
}
NSLog(#"created database successfully");
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
- (void)applicationDidFinishLaunching:(UIApplication *)application {
databaseName = #"MinesoftheMotherLode.sql";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
[self checkAndCreateDatabase];
[self readMinesFromDatabase];
MainViewController *aController = [[MainViewController alloc] initWithNibName:#"MainView" bundle:nil];
self.mainViewController = aController;
[aController release];
mainViewController.view.frame = [UIScreen mainScreen].applicationFrame;
[window addSubview:[mainViewController view]];
[window makeKeyAndVisible];
}
The implementation file for Mines is here:
#import "Mine.h"
#implementation Mine
#synthesize entryNumber, mineName, mineType, status, latitudeInitial, longitudeInitial, metal, display, coverRegion;
-(id)initWithEntryNumber:(NSNumber *)e mineName:(NSString *)n mineType:(NSString *)t status:(NSString *)s latitudeInitial:(NSNumber *)l longitudeInitial:(NSNumber *)o metal:(NSString *)m display:(BOOL *)d coverRegion:(NSNumber *)c
{
self.entryNumber = e;
self.mineName = n;
self.mineType = t;
self.status = s;
self.latitudeInitial = l;
self.longitudeInitial = o;
self.metal = m;
self.display = d;
self.coverRegion = c;
return self;
}
#end
The NSLog "Second if statement initialized" is not showing up on the console. any ideas as to what needs to be fixed here? and yes I know, I should be using core data.
It seems you've answered your initial question about it loading. For your secondary question regarding the crash about the null string, you should be loading strings like this:
if (sqlite3_column_text(init_statement, 0) != NULL) {
self.someString = [NSString stringWithUTF8String:(char *)sqlite3_column_text(init_statement, 0)];
} else {
self.someString = #"";
}