I have an app, that stores some info about account, including the image. Everything is great: tables are created, data can be saved, but the image is not (I can't understand if the image is not saving or it can't be retrieved from db). My code:
database table:
static const char *accountsTable = "CREATE TABLE IF NOT EXISTS tbl_accounts (unique_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, provider_id INTEGER, login TEXT, password TEXT, threshold INTEGER, is_need_push INTEGER, comment TEXT, image BLOB)";
my insert method:
-(BOOL) createAccountWithAccountData:(AccountsData *) accountData
{
NSInteger pushNotifications = accountData.isNeedPushNotifications ? 1 : 0;
const char *dbPath = [dataBasePath UTF8String];
if (sqlite3_open(dbPath, &database) == SQLITE_OK) {
NSString *insertSqlStatement = [NSString stringWithFormat: #"INSERT INTO tbl_accounts (provider_id, login, password, threshold, is_need_push, comment, image) values ('%d', '%#', '%#', '%d', '%d', '%#', '?')", accountData.providerId, accountData.logIn, accountData.password, accountData.threshold, pushNotifications, accountData.comment];
const char *insertStmt = [insertSqlStatement UTF8String];
if (sqlite3_prepare_v2(database, insertStmt, -1, &sqlStatement, NULL) == SQLITE_OK ) {
if (accountData.image != nil) {
NSLog(#"Image not null");
NSData *imageData = UIImageJPEGRepresentation(accountData.image, 1.0);
sqlite3_bind_blob(sqlStatement, 7, [imageData bytes], [imageData length], nil);
} else {
NSLog(#"image is nil");
}
if (sqlite3_step(sqlStatement) == SQLITE_DONE)
{
NSLog(#"Successfully created account data");
sqlite3_reset(sqlStatement);
sqlite3_close(database);
return YES;
} else {
NSLog(#"Unable to create account data");
sqlite3_reset(sqlStatement);
sqlite3_close(database);
return NO;
}
}
}
return NO;
}
and my get all accounts method:
-(NSArray *) getAllAccounts
{
const char *dbPath = [dataBasePath UTF8String];
NSMutableArray *allAccounts = [[NSMutableArray alloc] init];
if (sqlite3_open(dbPath, &database) == SQLITE_OK) {
NSLog(#"DB Opened");
NSString *findSqlStatement = [NSString stringWithFormat: #"SELECT * FROM tbl_accounts"];
const char *findStmt = [findSqlStatement UTF8String];
if (sqlite3_prepare_v2(database, findStmt, -1, &sqlStatement, NULL) == SQLITE_OK)
{
NSLog(#"statement was prepared");
while (sqlite3_step(sqlStatement) == SQLITE_ROW)
{
NSLog(#"Into the while loop");
NSInteger uniqueId = [[NSString stringWithUTF8String:(const char *) sqlite3_column_text(sqlStatement, 0)] integerValue];
NSInteger providerId = [[NSString stringWithUTF8String:(const char *) sqlite3_column_text(sqlStatement, 1)] integerValue];
NSString *logIn = [NSString stringWithUTF8String:
(const char *) sqlite3_column_text(sqlStatement, 2)];
NSString *password = [NSString stringWithUTF8String:
(const char *) sqlite3_column_text(sqlStatement, 3)];
NSInteger threshold = [[NSString stringWithUTF8String:(const char *) sqlite3_column_text(sqlStatement, 4)] integerValue];
NSInteger pushNotif = [[NSString stringWithUTF8String:(const char *) sqlite3_column_text(sqlStatement, 5)] integerValue];
NSString *comment = [NSString stringWithUTF8String:
(const char *) sqlite3_column_text(sqlStatement, 6)];
BOOL isNeedNotif = [self convertNSInteger:pushNotif];
int length = sqlite3_column_bytes(sqlStatement, 7);
NSData *data = [[NSData alloc] initWithBytes:sqlite3_column_blob(sqlStatement, 7) length:length];
NSLog(#"itemLogin: %#", logIn);
NSLog(#"password : %#", password);
NSLog(#"data is: %#", data);
NSLog(#"comment is: %#", comment);
NSLog(#"isNeedNotif: %hhd", isNeedNotif);
UIImage *imageFromDb = nil;
if (data != nil)
imageFromDb = [[UIImage alloc] initWithData:data];
else
NSLog(#"No image");
if (imageFromDb) {
NSLog(#"Image");
} else {
NSLog(#"NoImage");
}
AccountsData *item = [[AccountsData alloc] initWithProviderId:providerId logIn:logIn password:password threshold:threshold isNeedPushNotifications:isNeedNotif comment:comment image:imageFromDb];
item.unique_id = uniqueId;
[allAccounts addObject:item];
NSLog(#"Item added to array");
NSLog(#"Array count: %d", [allAccounts count]);
}
}
sqlite3_reset(sqlStatement);
sqlite3_close(database);
}
return allAccounts;
}
I've tested it on the emulator and the Image data is (NSDATA, according to NSLog):
data is: <3f>
Please, help me!!!
INSERT INTO tbl_accounts (..., image) values (..., '?')
You are inserting a string that consists of the single character ?.
Parameter markers must not be quoted:
INSERT INTO tbl_accounts (..., image) values (..., ?)
Furthermore, the second parameter of sqlite3_bind_blob is the parameter number, and the statement has only one parameter; it must be 1, not 7.
Additionally, sqlite3_reset is necessary only if you want to reuse the statement (but harmless otherwise).
What you must never forget is to call sqlite3_finalize when you're done with the statement, and before you close the database.
In this code, just replace sqlite3_reset with sqlite3_finalize.
Related
- (BOOL)addloginprofile:(NSString *)username andPassword:(NSString *)password
{
//XYZAppDelegate *appDelegate = (XYZAppDelegate *)[UIApplication sharedApplication].delegate;
//const char *sql = "select Name='%#',EnterPassword='%#' from ProfileTable";
NSString *sql = [[NSString alloc] initWithFormat:#"select Name='%#',EnterPassword='%#' from ProfileTable",username,password];
//NSString *sql = [NSString stringWithFormat:#"select Name='%#',EnterPassword='%#' from ProfileTable",username,password];
NSLog(#"sql statment %#",sql);
sqlite3_stmt *statment;
if(sqlite3_prepare_v2(database, [sql UTF8String] , -1, &statment, NULL) == SQLITE_OK)
//if(sqlite3_prepare_v2(database, [sql UTF8String] , -1, &statment, NULL) == SQLITE_OK)
{
if(sqlite3_step(statment) == SQLITE_ROW)
{
NSString *username=[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statment,0)];
NSString *password=[[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment,1)];
// NSString *username = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statment, 1)];
// NSString *password=[NSString stringWithUTF8String:(char *)sqlite3_column_text(statment, 2)];
NSLog(#"User name %#,",username);
NSLog(#"password %#",password);
if ([username isEqualToString:#"0"]&&[password isEqualToString:#"0"]) {
return NO;
}
else return YES;
}
}
I think the query is not properly formated it should be like this #"select * from ProfileTable where Name='%#' and EnterPassword='%#'",username,password.
i am iPhone application developer, and now we understood the concept of database.
i want to print all data from database. but i m not getting how can i print all data. here is i pest some code. please give me correct direction to print all data..
for example in sql we print all data as "select * from contact5;" we fire this string. can we done in iPhone coding?
-(IBAction)PrintData:(id)sender
{
NSLog(#"Button Pressed");
sqlite3_stmt *statement1;
NSString *querySQL=#"SELECT * FROM CONTACT5";
const char *query_stmt = [querySQL UTF8String];
sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement1, NULL);
while (sqlite3_step(statement1) == SQLITE_ROW)
{
NSLog(#"Enter in the denger zone");
NSString *idField = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement1, 0)];
NSString *addressField = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement1, 2)];
NSString *NameField = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement1, 1)];
NSString *phoneFiels = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement1, 3)];
NSLog(#"ID is=%#",idField);
NSLog(#"Name is=%#",NameField);
NSLog(#"Address is=%#",addressField);
NSLog(#"Phone No. is=%#",phoneFiels);
[idField release];
[NameField release];
[phoneFiels release];
[addressField release];
}
sqlite3_finalize(statement1);
sqlite3_close(contactDB);
}
thanks in advance.
We are sharing Some come which is using NSMutableDictionary to store your data and you can easily use that code to print your data,where do you want
if(sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
const char *sql = "Select * from CalculateTime";
sqlite3_stmt *insertStmt;
if(sqlite3_prepare_v2(database, sql, -1, &insertStmt, NULL) != SQLITE_OK)
NSAssert1(0,#"Error: Failed to prepare statement with message '%s'.",sqlite3_errmsg(database));
arrayCountry = nil;
arrayCountry = [[NSMutableArray alloc]init];
arrayCity = nil;
arrayCity = [[NSMutableArray alloc]init];
arrayFlag = nil;
arrayFlag = [[NSMutableArray alloc]init];
arrayZone = nil;
arrayZone = [[NSMutableArray alloc]init];
NSString *str2;
while(sqlite3_step(insertStmt)==SQLITE_ROW)
{
char *row;
row = (char*)sqlite3_column_text(insertStmt, 0);
if(row != NULL)
{
str2 = [NSString stringWithUTF8String:row];
[arrayCountry addObject:str2];
}
row = (char*)sqlite3_column_text(insertStmt, 1);
if(row != NULL)
{
str2 = [NSString stringWithUTF8String:row];
[arrayCity addObject:str2];
}
row = (char*)sqlite3_column_text(insertStmt, 2);
if(row != NULL)
{
str2 = [NSString stringWithUTF8String:row];
[arrayFlag addObject:str2];
}
row = (char*)sqlite3_column_text(insertStmt, 3);
if(row != NULL)
{
str2 = [NSString stringWithUTF8String:row];
[arrayZone addObject:str2];
}
}
}
Access these dictionary data to print anywhere..
//===================================================================================
- ( NSMutableDictionary * ) getDataToDisplayTierTwo:(NSString*)dbPath:(NSString*)iD{
//===================================================================================
NSMutableDictionary *aTierTwoTemplateData = [[NSMutableDictionary alloc]init];
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
NSString *selectSQL = [NSString stringWithFormat: #"select * from sub_categories_reference scr inner join storyboard_sub_categories ssc on ssc.id = scr.sub_category_id inner join subcategory_order as sco on sco.sub_category_id = scr.sub_category_id where scr.main_category_id = %# and sco.main_category_id = %# order by sco.position asc",iD,iD];
NSLog(#"%#", selectSQL);
const char *sql_query_stmt = [selectSQL UTF8String];
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, sql_query_stmt, -1, &selectstmt, NULL) == SQLITE_OK)
{
while(sqlite3_step(selectstmt) == SQLITE_ROW)
{
NSString *aValue = [[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(selectstmt, 6)];
NSString *aId = [[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(selectstmt, 5)];
[aTierTwoTemplateData setObject:aId forKey:aValue];
[aValue release];
[aId release];
NSLog(#"%# %# ^^^^^^^^^^^^^^^^^^^^picker value id ", aValue, aId);
}
}
}
sqlite3_close(database);
return aTierTwoTemplateData;
}
I am able to get the resultset when i assign this to array , but it loses the order in which , i have stored in the dictionery.
Actually , i have stored the result set based on the position field .
When i assign the resultset into array , the order gets changed.
Please let me know how can i handle this situation.
This is not a duplicate, as i have a coulmn in the db as "position"
If you want to store data as key-value pair and maintain the order, then you can use combination of NSArray and NSDictionary.The same code will be:
//===================================================================================
- ( NSArray * ) getDataToDisplayTierTwo:(NSString*)dbPath:(NSString*)iD{
//===================================================================================
NSMutableArray *aTierTwoTemplateData = [[NSMutableArray alloc]init];
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
NSString *selectSQL = [NSString stringWithFormat: #"select * from sub_categories_reference scr inner join storyboard_sub_categories ssc on ssc.id = scr.sub_category_id inner join subcategory_order as sco on sco.sub_category_id = scr.sub_category_id where scr.main_category_id = %# and sco.main_category_id = %# order by sco.position asc",iD,iD];
NSLog(#"%#", selectSQL);
const char *sql_query_stmt = [selectSQL UTF8String];
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, sql_query_stmt, -1, &selectstmt, NULL) == SQLITE_OK)
{
while(sqlite3_step(selectstmt) == SQLITE_ROW)
{
NSString *aValue = [[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(selectstmt, 6)];
NSString *aId = [[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(selectstmt, 5)];
[aTierTwoTemplateData addObject:[NSDictionary dictionaryWithObject:aId forKey:aValue]];
[aValue release];
[aId release];
NSLog(#"%# %# ^^^^^^^^^^^^^^^^^^^^picker value id ", aValue, aId);
}
}
}
sqlite3_close(database);
return [aTierTwoTemplateData autorelease];
}
In this way you'll be having an array of dictionaries, where your values will be stored in the dictionary and the order of the data also will be preserved.
I am trying fetch the value from data base But it is not getting
I am trying this code but didn't get the value ,When i use the Break point on the program
I am having Longitude,Latitude his data type is double in data base
if(sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
NSString *sqlStr = [NSString stringWithFormat:#"select Longitude,Latitude from Location"];
const char *sqlStatement = [sqlStr UTF8String];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
locations = [NSMutableArray array];
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
int i = sqlite3_step(compiledStatement);
NSLog(#"%i",i); **//over here i am getting the 101 value in console** And my pointer getting out from here
NSString *dLongitude = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
NSString *dLatitude = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 4)];
[locations addObject:[NSString stringWithFormat:#"%# ,%#",dLongitude,dLatitude]];
NSLog(#"%#",locations);
}
result = [locations componentsJoinedByString:#" "]; // same as `fake_location`
// Get file path here
NSError *error;
if ( [result writeToFile:dbPath atomically:YES encoding:NSUTF8StringEncoding error:&error] ) {
NSLog(#"%#", [error localizedDescription]);
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
int i = sqlite3_step(compiledStatement);
NSLog(#"%i",i); **//over here i am getting the 101 value in console** And my pointer getting out from here
double longitude = sqlite3_column_double(compiledStatement, 3);
double latitude = sqlite3_column_double(compiledStatement, 4);
NSString *coords = [[[NSString alloc] initWithFormat:#"%f,%f",longitude,latitude] autorelease];
[locations addObject:coords];
NSLog(#"%#",locations);
}
Change the code to the following :
if(sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
NSString *sqlStr = [NSString stringWithFormat:#"select Longitude,Latitude from UserJourneyLocation"];
const char *sqlStatement = [sqlStr UTF8String];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
locations = [NSMutableArray array];
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
int i = sqlite3_step(compiledStatement);
// NSLog(#"%i",i); / comment this line or use NSLog(#"%d",i);
// Make sure your longitude is double in database. else change the fetching value declaration
// We use 0 for dLongitude instead of 3 because in the select statement, it is the first value to be fetched irrespective of your table structure
// and same for dLatitude.
double dLongitude = sqlite3_column_double(compiledStatement, 0);
double dLatitude = sqlite3_column_double(compiledStatement, 1);
[locations addObject:[NSString stringWithFormat:#"%d ,%d",dLongitude,dLatitude]];
NSLog(#"%#",locations);
}
result = [locations componentsJoinedByString:#" "]; // same as `fake_location`
// Get file path here
NSError *error;
if ( [result writeToFile:dbPath atomically:YES encoding:NSUTF8StringEncoding error:&error] ) {
NSLog(#"%#", [error localizedDescription]);
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
I have a method, which generates a dictionary of returned values from database:
- (NSDictionary *)getParametersForPreset:(NSUInteger)presetID plants:(NSArray *)plants
{
NSString *loggers = #"";
NSString *invertors = #"";
NSString *plantsList = #"";
const char *sql = "SELECT loggerID, invertorID FROM records WHERE presetID IN (?) AND plantID IN (?)";
BOOL isEmpty = YES;
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) != SQLITE_OK)
{
NSLog(#"Error: '%s'.", sqlite3_errmsg(database));
}
for (int i = 0; i < [plants count]; i++) {
if (i == 0)
{
plantsList = [NSString stringWithFormat:#"'%#'",[[plants objectAtIndex:0] valueForKey:#"id"]];
}
else
{
plantsList = [plantsList stringByAppendingFormat:#",'%#'",[[plants objectAtIndex:i] valueForKey:#"id"]];
}
}
NSLog(#"plants: %#", plantsList);
NSLog(#"preset: %d", presetID);
sqlite3_bind_int(statement, 1, presetID);
sqlite3_bind_text(statement, 2, [plantsList UTF8String], -1, SQLITE_TRANSIENT);
NSMutableDictionary *dictionary = [[[NSMutableDictionary alloc] init] autorelease];
int i = 0;
while (sqlite3_step(statement) == SQLITE_ROW)
{
if (i == 0)
{
loggers = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
invertors = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)];
isEmpty = NO;
i++;
}
else
{
loggers = [loggers stringByAppendingFormat:#",%#",[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)]];
invertors = [invertors stringByAppendingFormat:#",%#",[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)]];
}
}
sqlite3_reset(statement);
if (isEmpty == YES)
{
return nil;
}
[dictionary setValue:[NSString stringWithString:[plantsList stringByReplacingOccurrencesOfString:#"'" withString:#""]] forKey:#"plants"];
[dictionary setValue:loggers forKey:#"loggers"];
[dictionary setValue:invertors forKey:#"invertors"];
return dictionary;
}
This query returns me nothing in the code, but then I do the same query in the SQLite Manager in Firefox for the same database, it returns me the correct data. Please, help me find my mistakes, I'm really exhausted of this.
Here is the query I do in Manager:
SELECT loggerID, invertorID FROM records WHERE presetID=1 AND plantID IN ('3','2','1','6','5','4')
And here are logged values from the code:
preset: 1
plants: '3','2','1','6','5','4'
Thanks a lot!
I have recently been working on similar query.
I had a NSMutableArray which stored a list of ID's. I joined them as a string using the function componentsJoinedByString.
I then had a NSString object which held my SQL statement, using the stringWithFormat function.
So your code to generate the SQLite query could be along the lines of:
NSString * query = [NSString stringWithFormat:#"SELECT loggerID, invertorID FROM records WHERE presetID IN (%d) AND plantID IN (%#)",presetID,[plantsList componentsJoinedByString:#","]];
Hope this helps.