Updating SQLITE query FMDB - Beginner - iphone

I could read from my SQLITE DB, but unable to update it. I wonder if the database is writable.
When i copy the SQL to the SQL console the code gets executed successfully. So there's no problem with the SQL.
-(BOOL) updateScores{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"uniques.sqlite"];
FMDatabase* db = [FMDatabase databaseWithPath:writableDBPath];
BOOL success;
if ([db open]) {
if ([db hadError]) {
NSLog(#"DB Error %d: %#", [db lastErrorCode], [db lastErrorMessage]);
}
success = [db executeUpdate:[NSString stringWithFormat:#"UPDATE Score SET answer='11' WHERE name LIKE 'jack'"]];
if (success) {
NSLog(#"OK");
}else {
NSLog(#"FAIL");
}
[db close];
}else {
NSLog(#"Problem with DB");
}
return success;
}

Always pass the arguments to SQL query as an object type, please look at the way arguments are passed to the SQL query. Even if you are passing a number, pass it as
[NSNumber numberWithInt:someValue]
Try this:
-(BOOL) updateScores
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"uniques.sqlite"];
FMDatabase* db = [FMDatabase databaseWithPath:writableDBPath];
BOOL success = NO;
if ([db open] != YES) {
NSLog(#"DB Error %d: %#", [db lastErrorCode], [db lastErrorMessage]);
return NO; //VERY IMPORTANT
}
[db beginTransaction];
success = [db executeUpdate:#"UPDATE scores SET answer = ? WHERE name like ?", #"1", #"jack"];
if (success) {
NSLog(#"OK");
[db commit];
[db close];
}else {
NSLog(#"FAIL");
}
return success;
}

Related

DropboxSDK: error making request to /1/metadata/sandbox - (401) No auth method found. Can we trace this error using any dropbox delegate?

Using below code to upload file to dropbox, only change i made is to replace the file on dropbox server. But since then faced this problem for the first time got this warning in console only and not traceable in code but when user tries again it works. Can anyone guide why this happens?
-(void)uploadToDropbox
{
NSLog(#"Upload to dropbox from local DB");
if ([[DBSession sharedSession] isLinked])
{
StartLoadingIndicator:self];
[self addLoadingView];
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *localPath=[documentsDirectory stringByAppendingPathComponent:#"/MyApp/MyApp.sqlite"];
success =[fileManager fileExistsAtPath:localPath];
if (success)
{
NSLog(#"DBX_Path %#",[NSString stringWithFormat:#"%#",[[NSUserDefaults standardUserDefaults] valueForKey:#"DBX_Path"]]);
}
else
{
NSLog(#"Not exist");
}
}
else
{
UIAlertView *Sessionalert=[[UIAlertView alloc]initWithTitle:#"You need to login first with valid credentials." message:nil delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[Sessionalert show];
Sessionalert=nil;
}
}
- (void)restClient:(DBRestClient *)client loadedMetadata:(DBMetadata *)metadata
{
NSLog(#"metadata:%#", metadata);
NSEnumerator *e= [metadata.contents objectEnumerator];
DBMetadata *dbObject;
//NSUInteger numberOfFiles = [metadata.contents count];
while ((dbObject = [e nextObject])) {
if (!dbObject.isDirectory) {
NSString *fileName = [dbObject.path lastPathComponent];
if (![fileName isEqualToString:#"MyApp.sqlite"]) {
/* call dbupload if dbObject.lastModifiedDate > than your local file*/
revName = nil;
}
else{
revName = [dbObject.rev lastPathComponent];
NSLog(#"revName:%#", revName);
}
}
}
NSString *filename = #"MyApp.sqlite";
NSString *destDir = #"/";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *localPath=[documentsDirectory stringByAppendingPathComponent:#"/MyApp/MyApp.sqlite"];
[[self restClient] uploadFile:filename toPath:destDir
withParentRev:revName fromPath:localPath];
}
Please guide why this happens and what's the reason behind this? Can this be traceable via any delegate method.
Finally i got..
- (void)restClient:(DBRestClient*)client loadMetadataFailedWithError:(NSError*)error {
NSLog(#"Error loading metadata: %#", error);
}
Got help from enter link description here

iPhone,FMDatabase : executeQuery not working

Below is the code i am using:
FMDatabaseQueue *queue = [[DataBaseHelper sharedManager] queue];
[queue inDatabase:^(FMDatabase *db) {
FMResultSet *results = [db executeQuery:#"select * from EVENT where ESTATUS='unread' and HIT_ATTEMPTS < 5 "];
if([results next])
{
[results close];
#try {
BOOL success=FALSE;
NSString *query=[NSString stringWithFormat:#"insert into EVENT (EDATA, ESTATUS ,EUSER) values('%#','%#','%#')",#"google.com",#"unread",#"xyz"];
success = [db executeUpdate:query];
NSLog(#"create edata row, %d:%#", [db lastErrorCode], [db lastErrorMessage]);
}
#catch (NSException *exception) {
NSLog(#"Exception");
}
In the above code
success = [db executeUpdate:query]; is not working. I have tried placing breakpoints. After this line of code all exits. None of the logs get printed.
I am not sure why you are using a try and Catch, anywayz follow the steps it will surely work
Creating A Database
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:#"database.sqlite"];
FMDatabase *database = [FMDatabase databaseWithPath:path];
Opening The Database And Creating Tables(optional)
[database open];
//optional
[database executeUpdate:#"create table user(name text primary key, age int)"];
Querying The Database
FMResultSet *results = [database executeQuery:#"select * from user"];
while([results next]) {
NSString *name = [results stringForColumn:#"name"];
NSInteger age = [results intForColumn:#"age"];
NSLog(#"User: %# - %d",name, age);
}
[database close];

iOS 6: SQLite db doesn't work

I always use this code to open a sqlite db in my iPhone application, but now with iOS6 this code doesn't work. The function: sqlite3_prepare_v2 fails but I don't understand why!
I also don't understand why if I try to change the name: "gamer.sqlite" of sqlite db with another name of an not existent file, the function: 'sqlite3_open' return again SQLITE_OK value.
This is my code:
-(NSMutableArray*)view_table
{
const char *sql;
NSMutableArray *content=[[NSMutableArray alloc] initWithObjects:nil];
[self msgbox:#"eseguo"];
/*elementi da visualizzare nella tabella*/
if(sqlite3_open([databasePath UTF8String],&database)==SQLITE_OK)
{
[self msgbox:#"opened"];
sql = "SELECT * FROM list_gamer";
if (sqlite3_prepare_v2(database,sql, -1, &selectstmt, NULL) == SQLITE_OK)
{
[self msgbox:#"query eseguita"];
while(sqlite3_step(selectstmt) == SQLITE_ROW)
{
[content addObject:[NSString stringWithFormat:#"%s",sqlite3_column_text(selectstmt,0)]];
}
}
}
return content;
}
- (void)viewDidLoad{
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [[documentsDir stringByAppendingPathComponent:#"gamer.sqlite"] copy];
if(![[NSFileManager defaultManager] fileExistsAtPath:databasePath])
{
NSFileManager *fileManager = [NSFileManager defaultManager];
int success = [fileManager fileExistsAtPath:databasePath];
if(success)
{
[fileManager removeItemAtPath:databasePath error:nil];
return;
}
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"gamer.sqlite"];
// Copy the database from the package to the users filesystem
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDir = [documentPaths objectAtIndex:0];
}
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning{
[super didReceiveMemoryWarning];
}
-(IBAction)start_game:(id)sender{
self.view=frmgame;
[self view_table];
}
Not exactly a direct answer but i personally really love using fmbd to help manage sqlite & error.
Fmdb is an Objective-C wrapper around SQLite: http://sqlite.org/
https://github.com/ccgus/fmdb

Trying to Fetching data from sqlite database

Below is my code, i am trying to fetch data from my.sqlite database but it is not executing my if case. It always enters in else condition. What wrong thing i am doing?
I am not able to execute my if case i.e. if(sqlite3_prepare_v2(database, sqlQuerry, -1, &querryStatement, NULL)==SQLITE_OK)
sqlite3 *database;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *databasePath = [documentsDirectory stringByAppendingPathComponent:#"my.sqlite"];
const char* dbPath=[databasePath UTF8String];
if(sqlite3_open(dbPath, &database)==SQLITE_OK)
{
const char *sqlQuerry="SELECT * FROM Contacts;";
sqlite3_stmt *querryStatement;
if(sqlite3_prepare_v2(database, sqlQuerry, -1, &querryStatement, NULL)==SQLITE_OK)
{
NSLog(#"conversion successful....");
while (sqlite3_step(querryStatement)==SQLITE_ROW)
{
NSString *addressField = [[NSString alloc] initWithUTF8String:
(const char *)
sqlite3_column_text(querryStatement, 0)];
NSString *phoneField = [[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(querryStatement, 1)];
NSLog(#"DB ID :- %#",addressField);
NSLog(#"DB NAME :- %#",phoneField);
}
sqlite3_reset(querryStatement);
}
else {
NSLog(#"error while conversion....");
}
sqlite3_close(database);
}
/////////////////////////////////////////////////////////////////////////////////
I tried using FMDB and did it as bellow:
But my *s and *results object are getting nil value and while statement is not executed
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:#"my.sqlite"];
FMDatabase* database = [FMDatabase databaseWithPath:path];
[database open];
FMResultSet *s = [database executeQuery:#"SELECT COUNT(*) FROM Contacts"];
while ([s next])
{
int totalCount = [s intForColumnIndex:0];
NSLog(#"Count : %i", totalCount);
}
FMResultSet *results = [database executeQuery:#"select * from Contacts"];
while([results next])
{
NSString *contact_id = [results stringForColumn:#"contact_id"];
NSString *name = [results stringForColumn:#"name"]; //
NSLog(#"User: %# - %#",name, contact_id);
}
[database close];
Replace your first six lines by the following code:
sqlite3 *database;
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *databasePath = [documentsDirectory stringByAppendingPathComponent:#"my.sqlite"];
NSLog(#"DATABASE PATH=%#",databasePath);
NSFileManager *fn=[NSFileManager defaultManager];
NSError *error;
BOOL success=[fn fileExistsAtPath:databasePath];
if(!success) {
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"my.sqlite"];
success = [fn copyItemAtPath:defaultDBPath toPath:databasePath error:&error];
}
const char *dbPath=[databasePath UTF8String];
if(sqlite3_open(dbPath, &database)==SQLITE_OK)
{
//. . . . your code...//
}
If you have a problem with any sqlite API then you need to report the error using sqlite3_errmsg() (reference) and this will help you track down your problem.
Change your code to report the error and update your question with the log output:
if (sqlite3_open(dbPath, &database) == SQLITE_OK)
{
...
}
else
{
NSLog("Failed to open database '%#': %s", databasePath, sqlite3_error(database));
}
According to the documentation for sqlite3_open() (here):
.... Otherwise an error code is returned. The sqlite3_errmsg() or
sqlite3_errmsg16() routines can be used to obtain an English language
description of the error following a failure of any of the
sqlite3_open() routines.
I found where I was going wrong. I created & inserted data to my database using Core Data. At the time of fetching I wanted to fire very complex queries, so I had to switch to SQLite. I was doing everything fine but getting error: Table not found.
The actual problem was that CoreData changed every table name of my database with a name prepending a "z", so my table name Contacts changed to ZContacts and column names in similar manner. When I opened my sqlite database in SQLite Manager I found where I was wrong.

Getting error while trying to fetch and insert data into SQLite database

I am creating an application where I am using SQLite database to save data. But when I run my application I get the following errors:
#interface TDatabase : NSObject {
sqlite3 *database;
}
+(TDatabase *) shareDataBase;
-(BOOL) createDataBase:(NSString *)DataBaseName;
-(NSString*) GetDatabasePath:(NSString *)database;
-(NSMutableArray *) getAllDataForQuery:(NSString *)sql forDatabase:(NSString *)database;
-(void*) inseryQuery:(NSString *) insertSql forDatabase:(NSString *)database1;
#end
#import "TDatabase.h"
#import <sqlite3.h>
#implementation TDatabase
static TDatabase *SampleDataBase =nil;
+(TDatabase*) shareDataBase{
if(!SampleDataBase){
SampleDataBase = [[TDatabase alloc] init];
}
return SampleDataBase;
}
-(NSString *)GetDatabasePath:(NSString *)database1{
[self createDataBase:database1];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:database1];
}
-(BOOL) createDataBase:(NSString *)DataBaseName{
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:DataBaseName];
success = [fileManager fileExistsAtPath:writableDBPath];
if (success) return success;
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:DataBaseName];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error!!!" message:#"Failed to create writable database" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil];
[alert show];
[alert release];
}
return success;
}
-(NSMutableArray *) getAllDataForQuery:(NSString *)sql forDatabase:(NSString *)database1{
sqlite3_stmt *statement = nil ;
NSString *path = [self GetDatabasePath:database1];
NSMutableArray *alldata;
alldata = [[NSMutableArray alloc] init];
if(sqlite3_open([path UTF8String],&database) == SQLITE_OK )
{
NSString *query = sql;
if((sqlite3_prepare_v2(database,[query UTF8String],-1, &statement, NULL)) == SQLITE_OK)
{
while(sqlite3_step(statement) == SQLITE_ROW)
{
NSMutableDictionary *currentRow = [[NSMutableDictionary alloc] init];
int count = sqlite3_column_count(statement);
for (int i=0; i < count; i++) {
char *name = (char*) sqlite3_column_name(statement, i);
char *data = (char*) sqlite3_column_text(statement, i);
NSString *columnData;
NSString *columnName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
if(data != nil)
columnData = [NSString stringWithCString:data encoding:NSUTF8StringEncoding];
else {
columnData = #"";
}
[currentRow setObject:columnData forKey:columnName];
}
[alldata addObject:currentRow];
}
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
return alldata;
}
-(void*) inseryQuery:(NSString *) insertSql forDatabase:(NSString *)database1{
sqlite3_stmt *statement = nil ;
NSString *path = [self GetDatabasePath:database1];
if(sqlite3_open([path UTF8String],&database) == SQLITE_OK )
{
if((sqlite3_prepare_v2(database,[insertSql UTF8String],-1, &statement, NULL)) == SQLITE_OK)
{
if(sqlite3_step(statement) == SQLITE_OK){
}
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
return insertSql;
}
NSString *sql = #"select * from Location";
const location = [[TDatabase shareDataBase] getAllDataForQuery:sql forDatabase:#"journeydatabase.sqlite"];//1
NSString* insertSql = [NSString stringWithFormat:#"insert into Location values ('city','name','phone')"];//2
const insert =[[TDatabase shareDataBase] inseryQuery:insertSql forDatabase:#"journeydatabase.sqlite"];//3
in line no 1,2,3 I get the same error:
initializer element is not constant
What might be the problem?
#rani writing your own methods to deal with sqlite database is very painstaking. You should use fmdb wrapper class or use core data. I personally prefer fmdb. Initially I was doing the same way you were. I found about fmdb here. After using it I had to write very little code whenever I have to deal With sqlite db.