I have a view having a Database which has a 'word' table (stores words) and I want to retrieve and send the data to another ViewController, but instead of receiving the actual word, I am getting the id.
Here is my code:
(void)getListData {
//tableData = [[NSMutableArray alloc]init];
sqlite3_stmt *statement;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"dexternotedb.sqlite"];
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) {
WordListViewController *temp = APP_DELEGATE.wordListViewController;
NSLog(#"word id %ld",(long)[temp.wordId integerValue]);
NSString *sql=[NSString stringWithFormat:#"SELECT * FROM words WHERE word_id=\"%#\"",APP_DELEGATE.wordListViewController.wordId];
const char *read_stmt = [sql UTF8String];
NSLog(#"select query%#",sql);
if(sqlite3_prepare_v2(database, read_stmt, -1, &statement, NULL) == SQLITE_OK){
sqlite3_bind_int(statement, 1, [temp.wordId integerValue]);
while(sqlite3_step(statement) == SQLITE_ROW) {
NSString *word1 = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
[word addObject:word1];
NSString *meaning1 = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
[meaning addObject:meaning1];
NSString *sentence1 = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
[Sentence addObject:sentence1];
}
sqlite3_finalize(statement);
} else {
sqlite3_close(database);
NSAssert1(0, #"Failed to open database with message '%s'.", sqlite3_errmsg(database));
}
First:
Don't use "Select *", because you don't really know the order of the columns, and you are using column index to access them.
So you should use the real names "Select, id, word...."
Second:
All your column retrieval are pointing to the same index 0:
[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
that is why you are getting the same data (the id), because it has the first index only. So change it to the correct indexes 1, 2, 3... and you will get the correct datas..
Using this SQL (check if the column names are correct)
SELECT word_id, word, meaning, sentence FROM words WHERE word_id=\"%#\"
Then you can use the correct indexes for the sqlite3_column_text:
NSString *word1 = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)];
[word addObject:word1];
NSString *meaning1 = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 2)];
[meaning addObject:meaning1];
NSString *sentence1 = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 3)];
[Sentence addObject:sentence1];
Related
This is my code for my test app where I want to show users on the next view controller but when I run and try to retrieve the values it is giving me repeated values. I have used NSMutableDictionary and NSMutableArray.
#import "DBManager.h"
static DBManager *sharedInstance = nil;
static sqlite3 *database = nil;
static sqlite3_stmt *statement = nil;
#implementation DBManager
-(void) getsaveData:(NSString *)Username
{
const char *dbpath = [newFileAtPath UTF8String];
NSMutableArray *userArray = [[NSMutableArray alloc]init];
if (sqlite3_open(dbpath, &database)==SQLITE_OK) {
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
NSString *getSQL = [NSString stringWithFormat:#"SELECT * FROM USERS WHERE USERNAME != \"%#\"",Username];
const char *retrievestmt = [getSQL UTF8String];
if(sqlite3_prepare_v2(database, retrievestmt, -1, &statement, NULL)==SQLITE_OK)
{
while(sqlite3_step(statement)==SQLITE_ROW)//in this while loop i am getting repeated values
{
NSString *User_ID = [[NSString alloc] initWithUTF8String: (const char *) sqlite3_column_text(statement, 0)];
[userInfo setObject:User_ID forKey:#"ID"];
//[userArray addObject:User_ID];
NSString *User_Email = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
[userInfo setObject:User_Email forKey:#"Email"];
//[userArray addObject:User_Email];
NSString *Password = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)];
[userInfo setObject:Password forKey:#"Email"];
//[userArray addObject:Password];
NSString *User_name = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 3)];
[userInfo setObject:User_name forKey:#"Username"];
//[userArray addObject:User_name];
NSString *User_Avatar = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 4)];
[userInfo setObject:User_Avatar forKey:#"Avatar"];
//[userArray addObject:User_Avatar];
[userArray addObject:userInfo];
NSLog(#"userArray %#",userArray);
}
sqlite3_reset(statement);
}
}
}
#end
In the while loop I am geeting the error.
I tried multiple times with multiple solutions please help me fix this.
The problem is simple - you are incorrectly reusing the userInfo dictionary. You need to create a new instance in each loop iteration.
Move the line:
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
to just after the while loop line.
You also have many other issues with your code:
You never close the database.
You never finalize the prepared statement.
You needlessly reset the prepared statement.
You have insufficient error checking/logging.
You are not using standard naming conventions.
You are not using standard whitespacing which makes your code harder to read.
You don't use consistent curly brace placement. Pick a style and use it everywhere.
You are using static variables when you should not be.
Never build SQL statements using stringWithFormat:. Properly bind values to the query.
Never use SELECT * in a query. Explicitly list out the columns to ensure you get consistent and expected column values.
Here's is your code updated for these issues:
#import "DBManager.h"
static DBManager *sharedInstance = nil;
#implementation DBManager
- (void)getsaveData:(NSString *)username {
const char *dbpath = [newFileAtPath UTF8String];
NSMutableArray *userArray = [[NSMutableArray alloc] init];
sqlite3 *database;
if (sqlite3_open(dbpath, &database) == SQLITE_OK) {
const char *retrievestmt = "SELECT USER_ID, USER_EMAIL, PASSWORD, USER_NAME, USER_AVATAR FROM USERS WHERE USERNAME != ?"; // replace * with actual column names
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, retrievestmt, -1, &statement, NULL) == SQLITE_OK) {
sqlite3_bind_text(statement, 1, [username UTF8String], -1, SQLITE_TRANSIENT);
while (sqlite3_step(statement) == SQLITE_ROW) {
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
NSString *userID = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 0)];
userInfo[#"ID"] = userID;
NSString *userEmail = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 1)];
userInfo[#"Email"] = userEmail;
NSString *password = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 2)];
userInfo[#"Password"] = password;
NSString *username = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 3)];
userInfo[#"Username"] = username;
NSString *userAvatar = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 4)];
userInfo[#"Avatar"] = userAvatar;
[userArray addObject:userInfo];
}
sqlite3_finalize(statement);
NSLog(#"userArray %#",userArray);
} else {
NSLog(#"Unable to prepare the statement at %s: %s", retrievestmt, sqlite3_errmsg(database));
}
sqlite3_close(database);
} else {
NSLog(#"Unable to open the database at %#: %s", dbpath, sqlite3_errmsg(database));
}
}
#end
I'm saving an image in the document directory and then I save its path inside a SQLite DB. After the process finishes I try to retrieve the image path from the db but I can't get it working and I really have no Idea why. On the simulator the code works but on a real device it doesn't.
This is the code I've used to save the img path and to retrieve the img path and display the image inside an UIImageView
This is the code to save the image:
NSString *stringURL = #"http://addons.cdn.mozilla.net/user-media/addon_icons/80/80205-64.png?modified=1317416463";
NSURL *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
NSString *filePath;
if ( urlData )
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"test.png"];
[urlData writeToFile:filePath atomically:YES];
}
NSLog(#"path:%#",filePath);
[self saveImgPath:filePath];
This is the saveImgPath method:
-(void) saveImgPath:(NSString*)path{
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &ImgDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO ImgPath (path) VALUES (\"%#\")",path];
const char *insert_stmt = [insertSQL UTF8String];
if(sqlite3_prepare_v2(ImgDB, insert_stmt, -1, &statement, NULL) == SQLITE_OK)
{
sqlite3_step(statement);
}
sqlite3_finalize(statement);
sqlite3_close(ImgDB);
}
[self performSegueWithIdentifier:#"sfondo" sender:self];
}
And this is how I retrieve it:
-(NSString*)getImgPath{
NSString* imgPath;
const char *dbpath = [[self GetDatabasePath] UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &ImgDB) == SQLITE_OK)
{
NSString *checkSQL = [NSString stringWithFormat: #"SELECT * FROM ImgPath"];
const char *insert_stmt = [checkSQL UTF8String];
sqlite3_prepare_v2(ImgDB, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_ERROR)
NSAssert1(0,#"Errore %s",sqlite3_errmsg(ImgDB));
else
sqlite3_step(statement);
sqlite3_finalize(statement);
sqlite3_close(ImgDB);
}
return imgPath;
}
The DB is initialized correctly and the NSLog of the paths are correct but I get 0 results when I try to retrieve the image path
the first view is word list view controller and it has a word table containing word_id,word meaning and sentence and this data i need to pass on the other view having 1 text field which i add to display the word and two text views to display meaning and sentence.
Here is the code-
- (void)getListData
{
//tableData = [[NSMutableArray alloc]init];
sqlite3_stmt *statement;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"dexternotedb.sqlite"];
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) {
WordListViewController *temp = APP_DELEGATE.wordListViewController;
NSLog(#"word id %ld",(long)[temp.wordId integerValue]);
NSString *sql=[NSString stringWithFormat:#"SELECT word_id, word ,meaning,sentence FROM words WHERE word_id=\"%#\"",APP_DELEGATE.wordListViewController.wordId];
const char *read_stmt = [sql UTF8String];
NSLog(#"select query%#",sql);
if(sqlite3_prepare_v2(database, read_stmt, -1, &statement, NULL) == SQLITE_OK){
//sqlite3_bind_int(statement, 1, [temp.wordId integerValue]);
while(sqlite3_step(statement) == SQLITE_ROW) {
NSString *word1 = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)];
word.text = word1;
NSString *meaning1 = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 2)];
meaning.text = meaning1;
NSString *sentence1 = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 3)];
Sentence.text = sentence1;
}
sqlite3_finalize(statement);
} else
{
sqlite3_close(database);
NSAssert1(0, #"Failed to open database with message '%s'.", sqlite3_errmsg(database));
}
}
Simply Store Value in NSUserDefaults
[[NSUserDefaults standardUserDefaults] setObject:#"String" forKey:#"KeyName"];
[[NSUserDefaults standardUserDefaults] synchronize];
and whenever data is required fetch data from NSUserDefaults in entire app
NSString *str= [[NSUserDefaults standardUserDefaults] valueForKey:#"KeyName"];
I need to loop through a sqlite db but the function i'm using doesn't work at all,
this is the code i'm using:
NSString *docsDir;
NSArray *dirPaths;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: #"CarrelloMese.sqlite"]];
NSUInteger helper;
helper = 0;
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &Carrello) == SQLITE_OK) {
NSString *checkSQL = [NSString stringWithFormat: #"SELECT FROM CarrelloMese"];
const char *insert_stmt = [checkSQL UTF8String];
if(sqlite3_prepare_v2(Carrello, insert_stmt, -1, &statement, NULL)) {
while(sqlite3_step(statement) == SQLITE_ROW) {
[indexProdotti insertObject:[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)] atIndex:helper];
}
}
sqlite3_finalize(statement);
sqlite3_close(Carrello);
}
When it reaches the While it doesn't enter, but I can't understand what's the problem.. The values are stored correctly on the DB (I checked with SqliteManager) and If I use a Count function within the app the count is correct, is there a problem with the code?
Your code seems to be correct. You forgot to add * in query.
Try this:
NSString *checkSQL = [NSString stringWithFormat: #"SELECT * FROM CarrelloMese"];
I am trying to get all row details for a particular row type.
Select * from MainTable where JOB1=#Paint
It's not working. I tried with more options but not got succes. Can anyone tell me what is the correct format in Objective-C?
complete code is like
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
//const char *sqlStatement = "SELECT * FROM MainTable"; ??it is working
const char *sqlStatement = "SELECT * FROM MainTable where JOB1='Paint'";//but not this one
sqlite3_stmt *compiledStatement;
NSLog(#"query set");
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
NSString *job = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
NSString *image = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *tools = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString *materials = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
NSString *people = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 4)];
NSString *safety = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 5)];
NSLog(#"%#",job);
NSLog(#"image %#",image);
NSLog(#"tools %#",tools);
NSLog(#"materials %#",materials);
NSLog(#"people %#",people);
NSLog(#"safety %#",safety);
you can fire queries for SQLite db using firefox addon SQLite manager
https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/
same query you can write in program. If still it is not running please post your code snippet.