iphone xcode sqlite3_open remote host - iphone

i try to get a connection my server, with the sqlite3_open command!
my question...is it possible to that? i got the following code...
// Get the path to the documents directory and append the databaseName
databaseName = #"AnimalDatabase.sql";
NSString *serverpath = #"http://localhost/app/";
databasePath = [serverpath stringByAppendingPathComponent:databaseName];
and then this here
-(void) readAnimalsFromDatabase {
// Setup the database object
sqlite3 *database;
// Init the animals Array
animals = [[NSMutableArray alloc] init];
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
const char *sqlStatement = "select * from animals";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *aDescription = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString *aImageUrl = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
// Create a new animal object with the data from the database
Animal *animal = [[Animal alloc] initWithName:aName description:aDescription url:aImageUrl];
// Add the animal object to the animals Array
[animals addObject:animal];
[animal release];
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
any suggestion??

Where you get the idea that SQLite can open database from URL??
It can open files only (or, create temporary db in memory).

The answer is just NO, there are lot of mistakes in your code anyway. For example:
databaseName = #"AnimalDatabase.sql";
Where did you get this. iPhone is working with sqlite database, it has nothing in common with sql files:)

Related

Update value in sqlite iphone sdk

I have a simple program that update a record of a table
The table is "person" with two columns "name" and "age";
some records have been inserted, as follows:
name age
tom 20
andy 30
han 25
Now I am writing a program to update a row in the table:
NSString *database=[[NSBundle mainBundle] pathForResource:#"mytable" ofType:#"sqlite"];
sqlite3_open([database UTF8String],&contactDB);
NSString *text=#"andy";
NSString *query=[NSString stringWithFormat:#"UPDATE person SET age=%d WHERE name='%#'",30,text];
sqlite3_stmt *statement;
sqlite3_prepare_v2(contactDB,[query UTF8String],-1,&statement,NULL);
sqlite3_finalize(statement);
sqlite3_close(contactDB);
The program works fine, but the database is not updated (I am using SQLite Manager to browser the database)
When I try reading from database, it works well:
NSString *database=[[NSBundle mainBundle] pathForResource:#"mytable" ofType:#"sqlite"];
sqlite3_open([database UTF8String],&contactDB);
NSString *query1=[NSString stringWithFormat:#"SELECT * FROM person WHERE age=%d;",30];
sqlite3_stmt *statement;
sqlite3_prepare_v2(contactDB,[query1 UTF8String],-1,&statement,NULL);
sqlite3_step(statement);
NSString *result=[[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 0)];
label.text=result;
sqlite3_finalize(statement);
sqlite3_close(contactDB);
-(void)updateSetting:(NSArray *)arr
{
if(sqlite3_open([databasePath UTF8String],&myDatabase)==SQLITE_OK)
{
sqlite3_stmt *compiledStmt;
NSString *sqlStmt=[NSString stringWithFormat:#"UPDATE setting SET flow='%#',formate='%#' WHERE primaryKey=%i;",[arr objectAtIndex:0],[arr objectAtIndex:1],1];
if(sqlite3_prepare_v2(myDatabase, [sqlStmt UTF8String],-1,&compiledStmt, NULL)==SQLITE_OK)
{
NSLog(#"Successful update");
}
sqlite3_step(compiledStmt);
sqlite3_close(myDatabase);
}
}
I already faced this issues. Whats the problem behind this is you passed the query as a string format so you have to use the ; at the end of the query statement.
NSString *query=[NSString stringWithFormat:#"UPDATE questionbank SET age=%d WHERE name='%#';",30,text];
Please make a checking like below before you perform your sqlite3_step method.
const char *sqlQuery = "UPDATE SETTINGS SET someFlag = 0";
sqlite3_stmt *insertStatement = nil;
int success = 0;
if(sqlite3_prepare_v2(sqliteDatabase, sqlQuery, -1, &insertStatement, NULL) == SQLITE_OK)
{
success = sqlite3_step(insertStatement);
if(insertStatement)
{
sqlite3_finalize(insertStatement);
}
if(success == SQLITE_ERROR)
{
return NO;
}
return YES;
}
return NO;
So that you can figure out, where the problem is.
You need to check whether you could access and open the database or not. Simply place your update segment in a if-statement like this: if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK).
Also try to add NSLog(#"%s", sqlite3_errmsg(database)); after your prepare to see if there was any errors.
The answer for this problem is that the database in the main bundle is read-only
I can not insert data into sqlite3 file on XCode

iPhone - Trying to Copy sqlite Database to Documents Directory - copies blank version

I have an sqlite database called 'ProductDatabase.sql', which I have copied into my applications project directory:
/Users/jacknutkins/Documents/TabbedDietApp/TabbedDietApp/ProductDatabase.sql
In the applications app delegate class I have this piece of code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//Set-up some globals
m_DatabaseName = #"ProductDatabase.sql";
//Get the path to the documents directory and append the databaseName
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
m_DatabasePath = [documentsDirectory stringByAppendingPathComponent:#"ProductDatabase.sql"];
//Execute the "checkAndCreateDatabase" function
[self checkAndCreateDatabase];
//Query the databse for all animal records and construct the "animals" array
[self readProductsFromDatabase];
....
At this point:
m_DatabasePath = '/Users/jacknutkins/Library/Application Support/iPhone Simulator/5.0/Applications/6D5BBE3A-BC9A-4C44-B089-FABA27CFFF4B/Library/ProductDatabase.sql'
Here is the code for the other 2 methods:
- (void) checkAndCreateDatabase {
NSError * error;
//Check if the database has been saved to the users phone, if not then copy it over
BOOL l_Success;
//Create a file manager object, we will use this to check the status
//of the databse and to copy it over if required
NSFileManager *l_FileManager = [NSFileManager defaultManager];
//Check if the database has already been created in the users filesystem
l_Success = [l_FileManager fileExistsAtPath:m_DatabasePath];
//If the database already exists then return without doing anything
if(l_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 *l_DatabasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:m_DatabaseName];
//Copy the database from the package to the usrrs filesystem
[l_FileManager copyItemAtPath:l_DatabasePathFromApp toPath:m_DatabasePath error:&error];
}
If I perform some NSLogs here:
l_DatabasePathFromApp = /Users/jacknutkins/Library/Application Support/iPhone Simulator/5.0/Applications/6D5BBE3A-BC9A-4C44-B089-FABA27CFFF4B/TabbedDietApp.app/ProductDatabase.sql
and:
error = Error Domain=NSCocoaErrorDomain Code=260 "The operation couldn’t be completed. (Cocoa error 260.)" UserInfo=0x6b6d060 {NSFilePath=/Users/jacknutkins/Library/Application Support/iPhone Simulator/5.0/Applications/6D5BBE3A-BC9A-4C44-B089-FABA27CFFF4B/TabbedDietApp.app/ProductDatabase.sql, NSUnderlyingError=0x6b6cfa0 "The operation couldn’t be completed. No such file or directory"}
I'm not sure what file it is it can't find here..
- (void) readProductsFromDatabase {
//Init the products array
m_Products = [[NSMutableArray alloc] init];
NSLog(#"%#", m_DatabasePath);
//Open the database from the users filessystem
if(sqlite3_open([m_DatabasePath UTF8String], &database) == SQLITE_OK) {
//Set-up the SQL statement and compile it for faster access
const char *sqlStatement = "select * from products";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK)
{
NSLog(#"Success..");
//Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
//Read the data from the results row
NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *aCategory = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString *aCalories = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
NSString *aFat = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 4)];
NSString *aSaturates = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 5)];
NSString *aSugar = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 6)];
NSString *aFibre = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 7)];
NSString *aSalt = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 8)];
NSString *aImageURL = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 9)];
NSLog(#"Delegate");
NSString *aNote = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 10)];
NSUInteger myInt = sqlite3_column_int(compiledStatement, 11);
NSString *aServes = [NSString stringWithFormat:#"%d", myInt];
//Create a new animal object with the data from the database
Product *l_Product = [[Product alloc] initWithName:aName category:aCategory calories:aCalories fat:aFat saturates:aSaturates sugar:aSugar fibre:aFibre salt:aSalt imageURL:aImageURL note:aNote serves:aServes];
//Add the animal object to the animals array
[m_Products addObject:l_Product];
}
}
//Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
database is declared in the .h file as follows:
//Setup the database object
sqlite3 *database;
In the above method, the line:
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK)
does not evaluate to SQLITE_OK, because the database I try to copy to the documents directory is blank.
I have tried cleaning and building, deleting the blank copy of the database and re-running etc but it continues to copy a blank database every time.
I've googled this several times and I've tried everything I can find with no success..
Any help would be hugely appreciated.
Jack
EDIT
If I perform 'select * from products' from the terminal window on the database in the project directory I return the expected results.
I had forgotten to include the database file in the target membership by clicking on the check box in the file inspector tab.

How to insert only one username and password in SQLite database?

I have an application where I have two textfields and a button. In the first textfield I am entering the username of the user and in the second textfield I am entering the password of the user. When the user enters the username and password and click on create user button a backend api is called which will register the username and password of the user and at the time I want to enter the username and password of the user in local SQLite databse in encrypted format.
When a user is registered the username of that particular user should get displayed in the first textfield and it should not be editable and password field should be editable. Only one user is allowed to be registered for the entire application.
Don't use a sqlite dbs to store user credentials. With reverse engineering it is fairly simple to get to the data. This because you probably have some value in your program you use to encrypt/decrypt the password. For security purposes, please use the keychain. There are several projects on github which makes it very easy to use the keychain. There is no more secure way for saving credentials then the keychain, so please use that to store your credentials!!!
If I understood your requirement correctly, You can follow the below guideline.
Before inserting the data to the table, You can check if any record is added to the table.
If the count is 0, you can proceed to insert the record, else you can prompt the error.
I think this will be the simplest way to do this.
First step is to check the database exist in resource folder and create database:-
1)
-(void)checkAndCreateDatabase{
databaseName = #"databasename.sql";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
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];
}
2) call the function to retrieve the data:-
-(NSMutableArray *) readFromDatabase:(NSString *)query{
// Setup the database object
sqlite3 *database;
// Init the animals Array
returnArray = [[NSMutableArray alloc] init];
NSString *readCommand= query;
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
const char *sqlStatement = [readCommand UTF8String];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
[returnArray addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)]];
[returnArray addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)]];
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
return returnArray;
}
3) check for the retrun array is empty or nil then call the insert function defined at step
4) Insert into the database
-(void)insertIntoDatabase:(NSString *)username:(NSString *)password{
// Setup the database object
sqlite3 *database;
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
NSString *insertCommand=#"Insert into tableName values(username,password)";
const char *sqlStatement = [insertCommand UTF8String];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {}
sqlite3_finalize(compiledStatement);
}
// Release the compiled statement from memory
}
sqlite3_close(database);
}
You can use NSUserDefaults saving locally it. following code is for saving data.
perf = [NSUserDefaults standardUserDefaults];
[perf setObject:#"1" forKey:#"remember"];
[perf setObject:emailAddresTextField.text forKey:#"email"];
[perf setObject:passwordTextField.text forKey:#"password"];
[perf synchronize];
And for retrieving data use following code
perf=[NSUserDefaults standardUserDefaults];
NSString *remString = [perf stringForKey:#"remember"];
if ([remString isEqualToString:#"1"]) {
emailAddresTextField.text=[perf stringForKey:#"email"];
passwordTextField.text = [perf stringForKey:#"password"];
[rememberBtn setTag:1];
[rememberBtn setImage:[UIImage imageNamed:#"on_radioButton.png"] forState:0];
}

BAD_ACCESS on SQLITE selection

I am getting EXC_BAD_ACCESS when I attempt to do anything with the value I'm selecting from the local SQLITE database on an iPhone development. The code for my function is
-(void) updateFromDB {
// Setup the database object
sqlite3 *database;
// Open DB
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
NSString *query = [NSString stringWithFormat:#"SELECT MOD_ID FROM MODULE;"];
//NSLog(#"QUERY: %#",query);
// Prepare statement
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, NULL) == SQLITE_OK) {
// Execute SQL
while (sqlite3_step(statement) == SQLITE_ROW) {
// Get MOD_IDs
NSInteger MOD_ID = sqlite3_column_int(statement, 0);
NSString *ID = [NSString stringWithFormat:#"%#",MOD_ID];
//=======================
// Get Notice Module Data
//=======================
if (MOD_ID == 1) {
self.noticeModule = [[ModuleSetting alloc] initWithID:ID];
}
}
} else {
NSAssert1(0,#"Error: failed to prepare statement. '%s'", sqlite3_errmsg(database));
}
// Release the compiled statement from memory
sqlite3_finalize(statement);
} else {
sqlite3_close(database);
NSAssert1(0,#"Failed to open database. '%s'",sqlite3_errmsg(database));
}
sqlite3_close(database);
}
The bad access occurs on the line
NSString *ID = [NSString stringWithFormat:#"%#",MOD_ID];
Thanks for any help you can offer!
%# denotes objects. But MOD_ID seems to be an integer. So your format should be %d,
NSString *ID = [NSString stringWithFormat:#"%d", MOD_ID];
You can't use %# in format strings for integers, only for Obj-C objects. For integers, use %d (or for NSInteger, I think it is recommended to use %ld).
Have a look at the String Format Specifiers guide.
MOD_ID is not a pointer, so %# isn't correct.
Use below
NSInteger MOD_ID = sqlite3_column_int(statement, 0);
NSString *ID = [NSString stringWithFormat:#"%d",MOD_ID];

Variables/parameters in Sqlite query for Iphone App

In my Iphone App I have created this query:
"SELECT * FROM visuel where id_visuel = 1"
And so I have this function that works very well:
- (void)getVisuel {
visuelArray = [[NSMutableArray alloc] init];
sqlite3 *database;
if(sqlite3_open([self.databasePath UTF8String], &database) == SQLITE_OK) {
sqlite3_reset(getVisuelStatement);
while(sqlite3_step(getVisuelParcStatement) == SQLITE_ROW) {
NSString *aTitle = [NSString stringWithUTF8String:(char *)sqlite3_column_text(getVisuelStatement , 2)];
NSString *aLpath = [NSString stringWithUTF8String:(char *)sqlite3_column_text(getVisuelStatement , 3)];
Visuel *aVisuel = [[Visuel alloc] initWithName:aTitle lpath:aLpath];
[visuelArray addObject:aVisuel];
}
}
sqlite3_close(database);
}
What I want is to change the query like this: "SELECT * FROM visuel where id_visuel = ?"
I don't want to have a static id, but I don't know how to do that.
Thanks,
Well, first change your query to your parameterized query like you have there. Then, just before you call sqlite3_step bind the right id to the parameter:
sqlite3_reset(getVisuelStatement);
//Add these two lines
int visuelId = 1; //Put whatever id you want in here.
sqlite3_bind_int(getVisuelParcStatement, 1, visuelId);
while(sqlite3_step(getVisuelParcStatement) == SQLITE_ROW) {