I have created a dictionary application with several data bases , everything works fine except saving columns in bookmark ! , I know , it's not possible change files in NSBundle but I don't know how can I fix it . I would be grateful if you help me out here is the code :
- (NSString *) getDBPath {
NSString *path;
if ( [[[NSUserDefaults standardUserDefaults] stringForKey:#"Bv"] intValue] == 2)
{
path = [[NSBundle mainBundle]pathForResource:#"pr-eng" ofType:#"sqlite"];
} else {
path = [[NSBundle mainBundle]pathForResource:#"eg-pr" ofType:#"sqlite"];
}
if ( [[[NSUserDefaults standardUserDefaults] stringForKey:#"Bv"] intValue] == 3)
{
path = [[NSBundle mainBundle]pathForResource:#"german" ofType:#"sqlite"];
}
return path;
}
Here is bookmarking function :
-(void) setBookMark:(NSInteger)oid {
sqlite3_stmt *statement;
const char *dbpath = [[self getDBPath] UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *SetFavSQL = [NSString stringWithFormat: #"UPDATE DIC SET bookmark=1 WHERE id=\"%d\"", oid];
// NSLog(#"%#",SetFavSQL);
const char *SetFav_stmt = [SetFavSQL UTF8String];
sqlite3_prepare_v2(database, SetFav_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) != SQLITE_DONE)
{
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
}
Reading database :
-(void) read_Database{
NSMutableArray *DB_Array = [[NSMutableArray alloc] init];
NSMutableArray *word_Array = [[NSMutableArray alloc] init];
if(sqlite3_open([[self getDBPath]UTF8String], &database) == SQLITE_OK) {
NSString *sql =#"SELECT * FROM DIC";
// NSLog(#"%#",sql);
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, [sql UTF8String] , -1, &compiledStatement, NULL) == SQLITE_OK) {
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
NSInteger oid = sqlite3_column_int(compiledStatement, 0);
const char* f1 = (const char*)sqlite3_column_text(compiledStatement, 1);
NSString *oName = f1 == NULL ? nil : [[NSString alloc] initWithUTF8String:f1];
const char* f2 = (const char*)sqlite3_column_text(compiledStatement, 2);
NSString *oMean = f2 == NULL ? nil : [[NSString alloc] initWithUTF8String:f2];
const char* f3 = (const char*)sqlite3_column_text(compiledStatement, 3);
NSString *oPron = f3 == NULL ? nil : [[NSString alloc] initWithUTF8String:f3];
NSInteger bm = sqlite3_column_int(compiledStatement, 5);
readerClass = [[Reader alloc]initWithReadDB:oid Name:oName Mean:oMean Pron:oPron bookMark:bm];
[DB_Array addObject:readerClass];
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
AppDelegate *appDelegateClass = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegateClass.wordList removeAllObjects];
appDelegateClass.wordList=[word_Array mutableCopy];
[appDelegateClass.dictionaryArray removeAllObjects];
appDelegateClass.dictionaryArray=[DB_Array mutableCopy];
}
I know , it's not possible change files in NSBundle
Great, at least you made the effort to google the issue. Then, why not just copy these files to be updated upon the very first launch of the application to some writable path, like NSDocumentsDirectory?
NSArray *paths = NSSearchPathsForDirectoriesInDomains(NSDocumentsDirectory, NSUserDomainMask, YES);
NSString *docsDir = [paths objectAtIndex:0];
[[NSFileManager defaultManager] copyItemAtPath:path toPath:[docsDir stringByAppendingPathComponent:#"db.sql"] error:NULL];
etc.
For further improvement in #H2CO3's answer and for more clarification I post my answer :)
Here is what I do to save data to database on iPhone or iPad (iOS). All data is been kept in device locally. So if app is uninstalled all data will lost, if user hasn't take backup of the app and restored if from backup.
NSFileManager *fileMgr;
NSString *homeDir;
These are the ivar I use in below functions all functions are in my .m file which is contains all my db related functions like update, insert, select, delete.
-(void)CopyDbToDocumentsFolder
{
NSError *err=nil;
fileMgr = [NSFileManager defaultManager];
NSString *dbpath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"res_in_mil.sqlite"];
NSString *copydbpath = [self.GetDocumentDirectory stringByAppendingPathComponent:#"res_in_mil.sqlite"];
[fileMgr removeItemAtPath:copydbpath error:&err];
if(![fileMgr copyItemAtPath:dbpath toPath:copydbpath error:&err])
{
UIAlertView *tellErr = [[UIAlertView alloc] initWithTitle:title message:#"Unable to copy database." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[tellErr show];
}
}
-(NSString *) GetDocumentDirectory
{
fileMgr = [NSFileManager defaultManager];
homeDir = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
return homeDir;
}
As the name is self-explains there is no need to explain what these functions are for.
And in appDelegate.m I use the below code to copy my DB to the specified location where I can edit my DB. This code is in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method.
NSFileManager *fileMgr;
myDB *dbObj = [[myDB alloc]init];
fileMgr = [NSFileManager defaultManager];
NSString *dbPath = [[dbObj GetDocumentDirectory] stringByAppendingPathComponent:#"res_in_mil.sqlite"];
BOOL success = [fileMgr fileExistsAtPath:dbPath];
if(!success)
[dbObj CopyDbToDocumentsFolder];
I use this for one DB as I have only one DB. But I think you can extend these functions to copy more then one DB.
Even you can make one function to identify that the required DB is in DocumentDirectory or not using the code of - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method given above.
And for insert, update, delete, select operation I use the below code to open the DB for any access.
fileMgr = [NSFileManager defaultManager];
NSString *dbPath = [[self GetDocumentDirectory] stringByAppendingPathComponent:#"res_in_mil.sqlite"];
BOOL success = [fileMgr fileExistsAtPath:dbPath];
if(!success)
{
NSLog(#"Cannot locate database file '%#'",dbPath);
[self CopyDbToDocumentsFolder];
}
Happy Coding :)
I think you have to make only one master database and can have multiple tables in it. That can resolve your problem.
Related
I want to update records from several textfiels in detail viewcontroller, but when I cliCk on update button, its goes to failed to update database. pls suggest me.
-(IBAction)updateQuery:(id)sender
{
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &Information) == SQLITE_OK)
{
NSString *updateSQL = [NSString stringWithFormat: #"update CONTACTS set address=\"%#\",phone=\"%#\",imageUrl=\"%#\" WHERE name=\"%#\"",daddress.text,dphone.text,durl.text,dname.text];
const char *update_stmt = [updateSQL UTF8String];
sqlite3_prepare_v2(Information, update_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
dstatuslabel.text=#"updated successfully";
}
else
{
dstatuslabel.text = #"Failed to update contact";
}
sqlite3_finalize(statement);
sqlite3_close(Information);
}
}
NSString *updateSQL = [NSString stringWithFormat: #"update CONTACTS set address='%#',phone='%#',imageUrl='%#' WHERE name='%#'",daddress.text,dphone.text,durl.text,dname.text];
In my method i use following way its working :
-(BOOL)updateProfileFromCreatorId:(int)creatorProfileId{
char *st,*errorMsg;
NSLog(#"profile.creatorProfileId:%d",creatorProfileId);
st = sqlite3_mprintf("UPDATE Profile SET `CreatorID`=%d WHERE `CreatorID`= 1"
,creatorProfileId //username
);
NSLog(#"updateQUERY: %#",[NSString stringWithUTF8String:st]);
int ret = sqlite3_exec(rlraDb, st, NULL, NULL, &errorMsg);
if (ret != SQLITE_OK) {
sqlite3_free(errorMsg);
sqlite3_free(st);
return NO;
}
sqlite3_free(st);
return YES;
}
Add the Sqlite DB like any other file in your application bundle
Copy it to documents directory via code and use it (Method :checkAndCreateDatabase ) .The purpose of this is that updating content in sqlite is possible in Documents directory only
-(void) checkAndCreateDatabase
{
// Check if the SQL database has already been saved to the users phone, if not then copy it over
BOOL success;
// Create a FileManager object, we will use this to check the status
// of the database and to copy it over if required
NSFileManager *fileManager = [NSFileManager defaultManager];
// Check if the database has already been created in the users filesystem
success = [fileManager fileExistsAtPath:_databasePath];
// If the database already exists then return without doing anything
if(success) return;
// If not then proceed to copy the database from the application to the users filesystem
// Get the path to the database in the application package
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:_databaseName];
// Copy the database from the package to the users filesystem
[fileManager copyItemAtPath:databasePathFromApp toPath:_databasePath error:nil];
}
- (id)init {
if ((self = [super init]))
{
_databaseName = DB_NAME;
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
_databasePath = [documentsDir stringByAppendingPathComponent:_databaseName];
if (sqlite3_open([[self dbPath] UTF8String], &_database) != SQLITE_OK)
{
[[[UIAlertView alloc]initWithTitle:#"Missing"
message:#"Database file not found"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil]show];
}
}
return self;
}
Try this...It should work...
1) Please make sure you are copying the db from your bundle to documents directory before updating the db...
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:#"YOUR DBNAME.sqlite"];
// Check if the SQL database has already been saved to the users phone, if not then copy it over
BOOL success;
// Create a FileManager object, we will use this to check the status
// of the database and to copy it over if required
NSFileManager *fileManager = [NSFileManager defaultManager];
// Check if the database has already been created in the users filesystem
success = [fileManager fileExistsAtPath:filePath];
// If the database already exists then return without doing anything
if(success) return;
// If not then proceed to copy the database from the application to the users filesystem
// Get the path to the database in the application package
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:_databaseName];
// Copy the database from the package to the users filesystem
[fileManager copyItemAtPath:databasePathFromApp toPath:_databasePath error:nil];
}
2)Step 2: Update
sqlite3 *database;
sqlite3_stmt *updateStmt=nil;
const char *dbpath = [filePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *updateSQL = [NSString stringWithFormat: #"update CONTACTS set address=\"%#\",phone=\"%#\",imageUrl=\"%#\" WHERE name=\"%#\"",daddress.text,dphone.text,durl.text,dname.text];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(database, insert_stmt,-1, &updateStmt, NULL);
if (sqlite3_step(updateStmt) == SQLITE_DONE)
{
NSLog(#"updated");
}
}
I am trying out SQLite in iPhone for the very first time. The error I am facing is that the statement sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK in th ecode below is returning false and nothing is displayed.
Below is my code:
+ (void) getInitialDataToDisplay:(NSString *)dbPath {
dbTryAppDelegate *appDelegate = (dbTryAppDelegate *)[[UIApplication sharedApplication] delegate];
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
const char *sql = "select name,id from studtry";
sqlite3_stmt *selectstmt;
//below line is never executed and its else part is also not executed.
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
NSInteger primaryKey = sqlite3_column_int(selectstmt, 0);
stud *coffeeObj = [[stud alloc] initWithPrimaryKey:primaryKey];
coffeeObj.studName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 0)];
//coffeeObj.isDirty = NO;
[appDelegate.studArray addObject:coffeeObj];
// [coffeeObj release];
}
}
}
else
sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory.
}
Where am I getting wrong? How do I solve it?
Check Database Path, Database extension and also same table & fields.
Anyways,
Use This instead of using directly const string::
NSString *sqlStr = [NSString stringWithFormat:#"select name,id from studtry"];
const char *sql = [sqlStr UTF8String];
After while loop finalize statement,
sqlite3_finalize(selectstmt);
Then, after If condition,
sqlite3_close(database);
No need to write in else part.
Hopefully, it'll work for you.
Thanks.
First delete your application from Application & Simulator Folder.
Then create Database named :: Practise.sqlite3 (Type of SQLite3)
Then write this methods for Copying:
- (void) copyDatabaseIfNeeded {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
dbPath = [self getDBPath];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success) {
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"Practise.sqlite3"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
- (NSString *) getDBPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:#"Practise.sqlite3"];
}
You can copy this whenever you want by,
[self copyDatabaseIfNeeded];
Then, check for your results. Hopefully it'll work.
As per your code, all thing is abs right but I think you are passing the wrong DBPath or maybe DB file is not on the right place
please check this both point and try again.
I have created a multi lingual dictionary app which reads several databases , I have a problem with bookmaring... In the app's MainViewController I have an action menu which users select dictionaries. so I have created a key for these dictionaries to recognizing which dictionary is selected . Here is my code :
Reading Data Base
- (NSString *) getDBPath
{
NSInteger kValue = [[[NSUserDefaults standardUserDefaults] stringForKey:#"Bv"] intValue];
NSString *documentsDir = [[NSString alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
documentsDir = [paths objectAtIndex:0];
switch (kValue) {
case 1:
documentsDir = [[NSBundle mainBundle]pathForResource:#"eg-pr" ofType:#"sqlite"];
break;
case 2:
documentsDir = [[NSBundle mainBundle]pathForResource:#"pr-eng" ofType:#"sqlite"];
default:
break;
}
return documentsDir;
}
the problem is I can not bookmark any word on the device !! what is the problem ???
here is dictionary changing function :
- (void)eng_pr
{
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:1] forKey:#"Bv"];
[[NSUserDefaults standardUserDefaults] synchronize];
dbClass.viewController = self;
self.searchbar.placeholder = #"Search";
[myTable reloadData];
}
and bookmarking :
-(void) setBookMark:(NSInteger)oid {
sqlite3_stmt *statement;
const char *dbpath = [[self getDBPath] UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *SetFavSQL = [NSString stringWithFormat: #"UPDATE DIC SET bookmark=1 WHERE id=\"%d\"", oid];
// NSLog(#"%#",SetFavSQL);
const char *SetFav_stmt = [SetFavSQL UTF8String];
sqlite3_prepare_v2(database, SetFav_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) != SQLITE_DONE)
{
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
}
EDITED :
SEARCHING FUNCTION
- (void)searchWord:(NSString *)txt{
NSMutableArray *DB_Array = [[NSMutableArray alloc] init];
NSString *dbPath = [[NSString alloc] initWithString: [self getDBPath]];
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
NSString *sql =[NSString stringWithFormat:#"SELECT * FROM DIC Where Name LIKE \'%#%%\' order by NAME LIMIT 30",txt];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, [sql UTF8String] , -1, &compiledStatement, NULL) == SQLITE_OK) {
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
NSInteger oid = sqlite3_column_int(compiledStatement, 0);
const char* f1 = (const char*)sqlite3_column_text(compiledStatement, 1);
NSString *oName = f1 == NULL ? nil : [[NSString alloc] initWithUTF8String:f1];
const char* f2 = (const char*)sqlite3_column_text(compiledStatement, 2);
NSString *oMean = f2 == NULL ? nil : [[NSString alloc] initWithUTF8String:f2];
const char* f3 = (const char*)sqlite3_column_text(compiledStatement, 3);
NSString *oPron = f3 == NULL ? nil : [[NSString alloc] initWithUTF8String:f3];
NSInteger bm = sqlite3_column_int(compiledStatement, 5);
readerClass = [[Reader alloc]initWithReadDB:oid Name:oName Mean:oMean Pron:oPron bookMark:bm];
[DB_Array addObject:readerClass];
}
}
else {
NSLog(#"Error retrieving data from database.");
}
sqlite3_close(database);
}
else {
NSLog(#"Error: Can't open database!");
}
AppDelegate *appDelegateClass = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegateClass.wordList removeAllObjects];
[appDelegateClass.wordList=DB_Array mutableCopy];
}
OK, the problem is that your database (.sqlite) are located in the Resources Folder and all data/files int the resources folder can be read but cannot be written.
And when you call the bookmark method your do a query (UPDATE ...) so it try to modify data in the sqlite and it just can't because your .sqlite is in the Resources Folder.
The solution to your problem is to put your .sqlite file in the Document directory and not in the resource directory ;)
Edit : If I were you, at the first application start, copy all your .sqlite from the Resources folder to the Document folder, and work with the .sqlite located in the Document folder.
Some useful tips : Copy file from Resources folder to Document folder
Edit 2:
When you do this :
switch (kValue) {
case 1:
documentsDir = [[NSBundle mainBundle]pathForResource:#"eg-pr" ofType:#"sqlite"];
break;
case 2:
documentsDir = [[NSBundle mainBundle]pathForResource:#"pr-eng" ofType:#"sqlite"];
default:
break;
}
You are reading the files from the Resource folder, you should read the sqlite from the docuemnt directory :
switch (kValue) {
case 1:
documentsDir = [NSString stringWithFormat:#"%#/eg-pr.sqlite", documentsDir];
break;
case 2:
documentsDir = [NSString stringWithFormat:#"%#/pr-eng.sqlite", documentsDir];
default:
break;
}
Moreover if kValue is not equals to 1 or 2 the documentDir equals [paths objectAtIndex:0]; (so it will return the Document directory itself and not the sqlite files located in the document directory) does it should be something like that ? :
documentsDir = [NSString stringWithFormat:#"%#/filename.sqlite", documentsDir];
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.
how to created an application that records a series of longitude and latitude values in a SQLite database and display them as a coloured track on a MapActivity.
I need help. How can store the map coordinates in sqlite database and display like journey details in table .For example I have done one journey from mumbai to Pune .Then how can store the data into database that can available for future reference .when user click on journey name it should give all details
If you are new to Sqlite Then look into this class for data base
Create two database file as the following
---->>>>
Database.h
Write the following code in this file
#import <Foundation/Foundation.h>
#import <sqlite3.h>
#interface DataBase : NSObject {
sqlite3 *database;
}
+(DataBase *) shareDataBase;
-(BOOL) createDataBase:(NSString *)DataBaseName;
-(NSString*) GetDatabasePath:(NSString *)database;
-(NSMutableArray *) getAllDataForQuery:(NSString *)sql forDatabase:(NSString *)database;
-(void) inseryQuery:(NSString *) insertSql forDatabase:(NSString *)database1;
-(void) deleteQuery:(NSString *) deleteSql forDatabase:(NSString *)database1;
-(void) updateQuery:(NSString *) updateSql forDatabase:(NSString *)database1;
#end
---->>>>
Database.m
Write the following code in this file
#import "DataBase.h"
#implementation DataBase
static DataBase *SampleDataBase =nil;
+(DataBase*) shareDataBase{
if(!SampleDataBase){
SampleDataBase = [[DataBase 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);
}
-(void) updateQuery:(NSString *) updateSql 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,[updateSql UTF8String],-1, &statement, NULL)) == SQLITE_OK)
{
if(sqlite3_step(statement) == SQLITE_OK){
}
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
}
-(void) deleteQuery:(NSString *) deleteSql 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,[deleteSql UTF8String],-1, &statement, NULL)) == SQLITE_OK)
{
if(sqlite3_step(statement) == SQLITE_OK){
}
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
}
#end
Now to get data use the following code
NSString *sql = #"select * from UserInfo"; <br>
userInfo = [[DataBase shareDataBase] getAllDataForQuery:sql forDatabase:#"Sample.db"];
It will return array of all the row in form of NSDictionary.
To add new record use the following code
NSString *sql = [NSString stringWithFormat:#"insert into userInfo values ('city','name','phone')"];
[[DataBase shareDataBase] inseryQuery:sql forDatabase:#"Sample.db"];
In the same way there is also method to update and delete record.
so This is the best example I have seen we just need to call one method to for fetch, insert , update or delete.
Thanks for seeing the question,
To get location import corelocation framework in your project.
follow this link
http://developer.apple.com/library/ios/#samplecode/LocateMe/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007801 to get sample for getting location.
This is the format to set location in json
[{"Longitude":"45.2655","Latitude":"23.2655"},{"Longitude":"45.2655","Latitude":"23.2655"},{"Longitude":"45.2655","Latitude":"23.2655"}]
Thanks.
You need to create a table with fields ...... Source,Destination,SourceLat,SourceLong,DestinationLat,DestinationLong....... and in this you will pass
Source - Mumbai,(or other) - text - varchar type
Destinatino - Pune, (or other) -text - varchar type
SourceLat - coordinate.latitude; - number with decimal precison upto 10 points.
SourceLong - coordinate.longitude - number with decimal precison upto 10 points.
DestinationLat - coordinate.latitude; - number with decimal precison upto 10 points.
DestinationLong - coordinate.longitude - number with decimal precison upto 10 points.
Thanks,
First you need to create object of NSMutableArray *arrayOflocation; in .h file,
Then in you locationUpdate method write the following code
NSMutableDictionary *LocationDic = [[NSMutableDictionary alloc] init];
[LocationDic setObject:[NSString stringWithFormat:#"%f",c.latitude] forKey:#"Latitude"];
[LocationDic setObject:[NSString stringWithFormat:#"%f",c.longitude] forKey:#"Longitude"];
[arrayOflocation addObject:LocationDic];
now when you save the trip you need to create the string for the json format for that you need to use json API you can get it using google easily . write the following code when you want to save the string in file.
NSString *dataString = [arrayOflocation JSONRepresentation];
//// code to write dataString in txt file.
and at finally need to store the file name in sqlite along with other detail for the trip.