Opening SQL with Objective-C - iphone

I have an sql file in my supporting files. How can I open this file so that I can start using SQL commands to get the information that I want? I've tried a couple different syntaxes, and the last time I tried I ended up screwing up the whole application because I couldn't remember what I had changed.

If you are using sqlite 3. Then,
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths lastObject];
NSString* dbPath = [documentsDirectory stringByAppendingPathComponent:#"database.sqlite"];
if(sqlite3_open([dbPath UTF8String], &dataBase) == SQLITE_OK)
{
NSLog(#"Opened Database");
//Your code
}
else
{
NSLog(#"Failed to open database");
sqlite3_close (database);
}

Related

Can we give hardcoded path for sqlite in Xcode?

I'm new to the iPhone development and Mac OS, please bear with the silly query. But I tried hard to get into depth but couldn't found the solution for the problem.
I have created a database in sqlite through command prompt. The database is saved in Users/DNamto/resources.db
But when am trying to open this db in my iPhone application using the following code snippet
// 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:#"resources.db"]];
The database fails to open up.
The database path which the application is searching for is :
/Users/DNamto/Library/Application Support/iPhone Simulator/6.0/Applications/C82C3DAF-4E95-49A7-9A4F-4D69B056DC9D/Documents/resources.db
Can anyone help me to get the correct database path.
Can we hard code the DB path so that my application links to it. If yes then please provide the code snippet.
Add your database in the application & check if the db is present in doc directory or not, if not then you need to copy it in doc directory and then access it.
For cppy the db in doc directory use following code snippet
- (void)copyDatabaseIfNeeded {
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:[self getDBPath]];
NSString *databasePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"dbname.sqlite"];
if(success)
{
return;// remove old one.
}
[fileManager copyItemAtPath:databasePath toPath:[self getDBPath] error:nil];
}
To open the db use following code snippet
-(void)openDatabase
{
#try
{
[self copyDatabaseIfNeeded];
if(sqlite3_open([[self getDBPath] UTF8String], &mainDatabase)==SQLITE_OK)
{
NSLog(#"Database opened");
}
}
#catch (NSException *exception)
{
NSLog(#"Exception in openDatabase %# :%#",exception.name,exception.reason);
}
}
- (NSString *)getDBPath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:#"dbname.sqlite"];
}
Use following code snippet to close the database.
-(void)closeDatabase:(sqlite3_stmt*)statement
{
#try
{
sqlite3_finalize(statement);
sqlite3_close(mainDatabase);
}
#catch (NSException *exception)
{
NSLog(#"Exception in DatabaseController closeDatabase %# :%#",exception.name,exception.reason);
}
}
You can't. In real device you can't get the hard coded path.
You need a relative path.
Here your issue is your database is not present in the document directory.
You need to add your database to your main bundle and in run time you need to check whether the db is present on document directory, if not you need to copy it to document directory using the NSFileManager.
You can use the following code to copy the database file from bundle to document directory.
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"resource.db"];
NSString *folderPath = [documentsDirectory stringByAppendingPathComponent:#"resource.db"];
NSError *error;
[[NSFileManager defaultManager] copyItemAtPath:sourcePath toPath:folderPath error:&error];

iPhone SDK: How to go about a Translator style app

i'm trying to make an app that can basically take text from one box, as entered by the user, and convert it into an equivalent of that text into another text box.
When I say equivalent, I mean another way of wording that same word, these would be my own words, and not available on some other database that's already been done somewhere.
I could do this on a small scale with something like a switch statement for all the given possibilities, but for a whole language this has practicality issues.
How would I go about doing this? Would I database all of the words and their equivalents in an SQLite database? And how would I integrate this into an app? I have very limited knowledge when it comes to programming that would include a whole database of values, i'm just used to listing separate values, and am not really aware of the short codes capable of integrating a lot of values.
Is it possible to integrate all of the values of an SQL database into a Switch or if statement, that could separate a user's text entry, into the separate words it contains, and display their equivalents as listed in the database?
Thanks
From your "these would be my own words, and not available on some other database that's already been done somewhere" comment, is it correct to assume your word-for-word replacement is a valid approach to what you want to achieve? (no separate language or precedent to what is right?)
If so, I think you would do something like:
1) take the string from the input field,
2) apply componentsSeparatedByString: to it to have it broken into an array, then,
3) take each item in the array, search your sqlite DB for it, return the equivalent word, and append that to a string (and a space)...
4) when you're done with the array, output the resulting string to the 'output' box.
SQLite is pretty easy to work with, you can just start with a big excel file, then with some sqlite manager (I use a firefox plugin), import that into a .sqlite file, and add that to your project. Have you thought about how you would handle 'word not found'?
This is untested code, just to give you something to start with:
-(void) viewWillAppear:(BOOL)animated{
[self createEditableCopyOfDatabaseIfNeeded];
}
-(sqlite3 *) getNewDBConnection{
sqlite3 *newDBconnection;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"data.sqlite"];
// Open the database. The database was prepared outside the application.
if (sqlite3_open([path UTF8String], &newDBconnection) == SQLITE_OK) {
NSLog(#"Database Successfully Opened");
} else {
NSLog(#"Error in opening database");
}
return newDBconnection;
}
-(void)translate{
//take input and break into an array
NSString *clearText = [[NSString alloc] init];
clearText=inputBox.text;
NSArray *words = [[NSArray alloc] init];
words= [clearText componentsSeparatedByString:#" "];
numOfWords=words.count;
NSString *newText=#"";
//open database
sqlite3 *db = [self getNewDBConnection];
//loop through array
for(i=0;i<numOfWords;i++){
sqlite3_stmt *resultStatement = nil;
NSString *res = [NSString stringWithFormat:#"select * from dictionary where plain='%#'",[[words objectAtIndex:i] stringByTrimmingCharactersInSet:whitespaceCharacterSet]];
if((sqlite3_prepare_v2(db, [res UTF8String], -1, &resultStatement, nil))!=SQLITE_OK){
NSLog(#"Error getting result, maybe word not found\n");
NSLog(#"error: %s", sqlite3_errmsg(db));
}
else{
if(sqlite3_step(resultStatement)==SQLITE_ROW){
//in the line below, 1 is the column number of the replacement word
NSString *add = [[NSString alloc] initWithUTF8String: (char*)sqlite3_column_text(resultStatement,1)]
newText=[newText stringByAppendingString:add];
[add release];
}
}
sqlite3_finalize(resultStatement);
}
//output result
outputBox.text=newText;
sqlite3_close(db);
}
-(void)createEditableCopyOfDatabaseIfNeeded {
// First, test for existence.
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"data.sqlite"];
success = [fileManager fileExistsAtPath:writableDBPath];
if (success) return;
// The writable database does not exist, so copy the default to the appropriate location.
//NSLog(#"Creating editable copy of database");
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"data.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success) {
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
Machine translation is an extremely complex problem, and cannot be solved simply by implementing a word-by-word dictionary translation. Wikipedia has a decent overview of the different approaches extant in the literature; note, however, that none of them are trivial to implement.
Machine translation

Xcode Sqlite persistence problem

I have a persistence problem in my application. I'm using sqlite database. when some insert queries executed results temporary added to the database. After restarting application the new values vanish! I think new values stored on RAM do not save on hard-disk.
-(IBAction)add:(id)sender
{
NSString *myDB;
NSString *query;
myDB=[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"Ssozluk.sql"];
database =[[Sqlite alloc] init];
[database open:myDB];
query=[NSString stringWithFormat:#"INSERT INTO words(col_1,col_2) VALUES('asd','asd2');"];
[database executeNonQuery:query];
[database commit];
[database close];
}
-(IBAction)show:(id)sender
{
NSString *myDB;
NSString *query;
NSArray *asdasd;
NSString *asd;
myDB=[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"Ssozluk.sql"];
database =[[Sqlite alloc] init];
[database open:myDB];
query=[NSString stringWithFormat:#"Select col_2,col_1 FROM words"];
asdasd=[database executeQuery:query];
for(NSDictionary *row in kelimeler)
{
asd=[row valueForKey:#"col_2"];
olabel1.text=asd;
}
[database commit];
[database close];
}
You need programmatically copy your database to Documents dir of application, and work with writable copy. Resources in bundle is readonly.
I use the following code to copy my database to the documents folder and than get the writable part:
- (void)createEditableCopyOfDatabaseIfNeeded {
// First, test for existence.
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"db.sqlite"];
//NSLog(writableDBPath);
success = [fileManager fileExistsAtPath:writableDBPath];
if (success) return;
// The writable database does not exist, so copy the default to the appropriate location.
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"db.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success) {
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
- (void)initializeDatabase {
// The database is stored in the application bundle.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"db.sqlite"];
// Open the database. The database was prepared outside the application.
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) {
//Add initial sql statements here
} else {
// Even though the open failed, call close to properly clean up resources.
sqlite3_close(database);
NSAssert1(0, #"Failed to open database with message '%s'.", sqlite3_errmsg(database));
// Additional error handling, as appropriate...
}
}
- (sqlite3*) getDB{
return database;
}
Insert the calls to your applicationDidFinishLaunching method
As far as I remember, when you use path to db the way you do, it should be added to project.
Sometimes, and especially with databases, just cleaning doesn't work!!!
Go to the dir: /Users/qjsi/Library/Application Support/iPhone Simulator/4.3/Applications
There, you'll find all the projects you've run. Find the folder containing the project your working on, and delete it. Then clean your project through Xcode, then run. The folder in that dir will be recreated, and so will the database.
NOTE: The database will be removed as well! If you have it saved in your bundle and copy it to an editable directory, please note that the database will be the same as the one in your bundle (so, without altered records made in the iPhone Simulator).

Accessing a database through Obj-c

I am trying to find some source code on how to access and store variables from a database to my program via obj-c(iPhone). I have look for many hours now and no one has provided a sure fire way on how to go about this. If you have any advice or recommendations please post some source code or a link to it.
Thanks for the help.
If using the sqlite3 database which your program has access to on the phone for local database storage.
#import <sqlite3.h>
And create an openDatabase() method. Also add a variable for keeping the db around.
sqlite3 *db = nil;
Just make sure you call your open database method before using the database. Check this page out http://ved-dimensions.blogspot.com/2009/03/iphone-development-sqlite3-populating.html
Might give you something that you can use.
+(sqlite3 *) getNewDBConnection{
sqlite3 *newDBconnection;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"data.sqlite"];
// Open the database. The database was prepared outside the application.
if (sqlite3_open([path UTF8String], &newDBconnection) == SQLITE_OK) {
NSLog(#"Database Successfully Opened :)");
} else {
NSLog(#"Error in opening database :(");
}
return newDBConnection;
}

warning: invalid receiver type +sqlite3

I am programming an Xcode iPhone app and utilizing sqlite. In an effort to delete all rows from a table, I receive the warning above when I build my code. Does anyone have any suggestions on how to fix this?
Thanks
- (void) deleteData {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory
stringByAppendingPathComponent:#"myDatabase.sqlite"];
if (sqlite3_open([writableDBPath UTF8String], &database) == SQLITE_OK) {
[database executeNonQuery:#"DELETE FROM test;"];
}
[database release];
}
Assuming
sqlite3 *database;
somewhere all up ins, it should be noted that sqlite3_open() doesn't create an Objective-C object; it creates an sqlite3 database handle, which is, if memory serves, a struct packed in a pointer. It can, in other words, not receive Objective-C messages. * does not an object make.