I have this problem.... the code below don't produce errors but the table not commit change!
I've controlled all logs, all value are correct and all If test gone fine, but the value on the db not change.
someone have an idea?
thanks!!
- (void) saveData {
//database file system
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"enduroRace.sqlite"];
BOOL success = [fileMgr fileExistsAtPath:dbPath];
if(!success)
{
NSLog(#"unable to load db: '%#'.", dbPath);
}
//apro database
sqlite3 *db;
if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK))
{
NSLog(#"unable to open DB");
}
//inizio query
sqlite3_stmt *statement;
NSString *querySQL = #"UPDATE setting SET delay=?";
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(db, query_stmt, -1, &statement, NULL) == SQLITE_OK) {
int valoreAttuale = [[sharedClass sharedController] ritardoMusic];
sqlite3_bind_int(statement, 1,valoreAttuale);
}
if (sqlite3_step(statement) != SQLITE_DONE)
{
NSLog(#"Error...");
}
sqlite3_finalize(statement);
sqlite3_close(db);
}
I'm understood.... I've copied the Sqlite db into 'Documents' folder that is not only read only and now is perfect!!! thanks to me !!!
Related
I am working on something using SQLite3 and I cant exactly figure out why I am getting an error. I have looked at other SO post and no one can actually quite put a finger on that error and I have tried a number of things. the code is failing on this line (sqlite3_open(dbPath, &itemDB)==SQLITE_OK).
I have tried:
commenting that line and saying sqlite3_open(dbPath, &itemDB), when i do that my code excecutes but nothing in the folder
Error from the NSLog was "unable to open database file" so i created the datbase and placed it in the path myself to see if that would help but no difference
Verified the path by using breakpoints, path is correct but the db is just never created.
-(void)openDatabase
{
NSArray *path=NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
NSString *docPath=[path objectAtIndex:0];
// dbPathString=[docPath stringByAppendingPathComponent:#"items.db"];
dbPathString = [docPath stringByAppendingPathComponent:#"items.sqlite"];
char *error;
NSFileManager *fileManager=[NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:dbPathString]) {
const char *dbPath=[dbPathString UTF8String];
//Create DB
if (sqlite3_open(dbPath, &items)==SQLITE_OK)
// sqlite3_open(dbPath, &items);
{
const char *sql_stmt= " CREATE TABLE IF NOT EXIST PERSON (ID INTEGER PRIMARY KEY AUTOINCREMENT,NAME TEXT,PRICE INTEGER)";
sqlite3_exec(items, sql_stmt, NULL, NULL, &error);
sqlite3_close(items);
NSLog(#"Db Created");
}
NSLog(#"%s", sqlite3_errmsg(items));
}
}
You are trying to write to the documentation directory, not the document directory.
Replace NSDocumentationDirectory with NSDocumentDirectory.
Try this tutorial
NSString *docsDir;
NSArray *dirPaths;
// 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: #"contacts.db"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: databasePath ] == NO) {
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK) {
char *errMsg;
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, ADDRESS TEXT, PHONE TEXT)";
if (sqlite3_exec(contactDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK) {
status.text = #"Failed to create table";
}
sqlite3_close(contactDB);
}
else {
status.text = #"Failed to open/create database";
}
}
This will help u
#import<sqlite3.h>
-(BOOL)createTable
{
NSArray *yourArray=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath=[yourArray objectAtIndex:0];
filePath =[filePath stringByAppendingPathComponent:#"yourdatabase.sqlite"];
NSFileManager *manager=[NSFileManager defaultManager];
BOOL success = NO;
if ([manager fileExistsAtPath:filePath])
{
success =YES;
}
if (!success)
{
NSString *path2=[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"yourdatabase.sqlite"];
success =[manager copyItemAtPath:path2 toPath:filePath error:nil];
}
createStmt = nil;
NSString *tableName=#"SecondTable";
if (sqlite3_open([filePath UTF8String], &database) == SQLITE_OK) {
if (createStmt == nil) {
NSString *query=[NSString stringWithFormat:#"create table (ID INTEGER PRIMARY KEY AUTOINCREMENT,NAME TEXT,PRICE INTEGER)];
if (sqlite3_prepare_v2(database, [query UTF8String], -1, &createStmt, NULL) != SQLITE_OK) {
return NO;
}
sqlite3_exec(database, [query UTF8String], NULL, NULL, NULL);
return YES;
}
}
return YES;
}
I am passing the xml to my addRowToTheDatabase function . In this function i simply parse the xml file and and retrieved elements to the xml file. Now I am testing this application. How can I test whether the row added in the database or not in from unit test case ?
// I manipulated one of my queries real quick.. I'm assuming you're already connecting to a DB in SQLite, so much of this is un-needed. But this is the basic structure of a query.. as long as the DB resides in your application itself.
-(void) basicQuery
{
#try {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *theDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"databasename.sqlite"];
BOOL success = [fileManager fileExistsAtPath:theDBPath];
if (!success) {
NSLog(#"Failed to find database file '%#'.", theDBPath);
}
if (!(sqlite3_open([theDBPath UTF8String], &database) == SQLITE_OK)) {
NSLog(#"An error opening database, normally handle error here.");
}
const char *sql = "SELECT * FROM TABLE"; // your basic query
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) != SQLITE_OK){
NSLog(#"Error, failed to prepare statement, normally handle error here.");
}
while (sqlite3_step(statement) == SQLITE_ROW) {
NSString *value = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
NSLog(#"value = %#",value);
}
if(sqlite3_finalize(statement) != SQLITE_OK){
NSLog(#"Failed to finalize data statement, normally error handling here.");
}
if (sqlite3_close(database) != SQLITE_OK) {
NSLog(#"Failed to close database, normally error handling here.");
}
}
#catch (NSException *e) {
NSLog(#"An exception occurred: %#", [e reason]);
return nil;
}
}
I try to insert only two integer variable to my sqlite database. I created a database which name is ups.sqlite, it has a one table (upssTable) and the table have two column. But when I open /Users/ds/Library/Application Support/iPhone Simulator/5.0/Applications/FCB4B455-4B7F-4C47-81B6-AC4121874596/SqliteDeneme.app/ups.sqlite there is no data in ups.sqlite. My code is here:
- (IBAction)buttonClick:(id)sender {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dbPath = [self getDBPath];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success) {
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"ups.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
NSLog(#"database path %#",dbPath);
if(!(sqlite3_open([dbPath UTF8String], &cruddb) == SQLITE_OK))
{
NSLog(#"An error has occured.");
}
if(sqlite3_open([dbPath UTF8String], &cruddb) ==SQLITE_OK){
NSString * str1 =#"1";
NSString * str2 =#"1";
const char *sql = "INSERT INTO upssTable (column1, column2) VALUES (?,?)";
NSInteger result = sqlite3_prepare_v2(cruddb,sql, -1, &stmt, NULL);
NSLog(#"upss %s\n", sqlite3_errmsg(cruddb));
if(result == SQLITE_OK)
{
sqlite3_bind_int(stmt, 1, [str1 integerValue]);
sqlite3_bind_int(stmt, 2, [str2 integerValue]);
}
else
{
NSAssert1(0, #"Error . '%s'", sqlite3_errmsg(cruddb));
}
sqlite3_reset(stmt);
sqlite3_finalize(stmt);
sqlite3_close(cruddb);
}
}
- (NSString *) getDBPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:#"ups.sqlite"];
}
How can I solve this problem? Please help me. Thanks for your reply.
You havent used sqlite3_step() at all. Try this way...
sqlite3 *database;
dbPath=[self.databasePath UTF8String];
if(sqlite3_open(dbPath,&database)==SQLITE_OK)
{
const char *sqlstatement = "INSERT INTO upssTable (column1, column2) VALUES (?,?)";
sqlite3_stmt *compiledstatement;
if(sqlite3_prepare_v2(database,sqlstatement , -1, &compiledstatement, NULL)==SQLITE_OK)
{
NSString * str1 =#"1";
NSString * str2 =#"1";
sqlite3_bind_int(compiledstatement, 1, [str1 integerValue]);
sqlite3_bind_int(compiledstatement, 2, [str2 integerValue]);
if(sqlite3_step(compiledstatement)==SQLITE_DONE)
{
NSLog(#"done");
}
else NSLog(#"ERROR");
sqlite3_reset(compiledstatement);
}
else
{
NSAssert1(0, #"Error . '%s'", sqlite3_errmsg(cruddb));
}
sqlite3_close(database);
}
You are creating your sqlite3 statement, but you aren't actually executing it using sqlite3_step().
Also you appear to be opening the database twice?
Through the following code I am retrieving data from a Db, however I need to insert some data into a Sqlite3 database with this code before select statement. Can any one tell me where I need to put the insert query and how can I execute it.
I am selecting the datas through the following code:
sqlite3* database;
- (void)initializeDatabase
{
list=[[NSMutableArray alloc] init];
BOOL success;
NSFileManager *filemanager=[NSFileManager defaultManager];
NSError *error;
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory= [paths objectAtIndex:0];
NSString *writablePath=[documentsDirectory stringByAppendingPathComponent:#"SymbolTalk.sqlite"];
success=[filemanager fileExistsAtPath:writablePath];
if(!success)
{
NSString *defaultDBPath=[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"SymbolTalk.sqlite"];
success=[filemanager copyItemAtPath:defaultDBPath toPath:writablePath error:&error];
if(!success)
{
NSAssert1(0,#"Failed to create writable databasefile withw message %#.",[error localizedDescription]);
}
}
//Specify where to get the database from
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory= [paths objectAtIndex:0];
NSString *path=[documentsDirectory stringByAppendingPathComponent:#"SymbolTalk.sqlite"];
//Open the database
//might have to make database as property
if(sqlite3_open([path UTF8String], &dataBase) ==SQLITE_OK)
{
const char *sql="select filename from scenes";
sqlite3_stmt *statement;
if(sqlite3_prepare(dataBase, sql, -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
//NSLog(#"%#",[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)]);
[list addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)]];
}
}
}
}
sqlite3_stmt *insert_statement = nil;
const char *sql = "INSERT INTO scenes (filename) VALUES(?)";
if (sqlite3_prepare_v2(database, sql, -1, &insert_statement, NULL) != SQLITE_OK) {
NSAssert1(NO, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
sqlite3_bind_text(insert_statement, 1, [newFilename UTF8String], -1, SQLITE_TRANSIENT);
if (sqlite3_step(insert_statement) == SQLITE_DONE) {
// code if all ok
} else {
NSAssert1(NO, #"Error: failed to insert into the database with message '%s'.", sqlite3_errmsg(database));
}
sqlite3_reset(insert_statement);
sqlite3_finalize(insert_statement);
SQLite insert statement does not insert the new data
i am using this code
- (void) addN: (number *) theN
{
const char *sql = "insert into table (valueN) Values(?)";
sqlite3_stmt *addStmt = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString * docsDir = [paths objectAtIndex:0];
NSString * thePath = [docsDir stringByAppendingPathComponent: #"theDB.sqlite"];
sqlite3_open([thePath UTF8String], &database);
sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL);
sqlite3_bind_int(addStmt, 1, theN.theNumber);
sqlite3_step(addStmt);
sqlite3_finalize(addStmt);
sqlite3_close(database);
}
and the method to insert the record is
- (IBAction) saveN: (id) sender
{
numbers *theNumbers = [[numbers alloc] init];
number *theNumber = [[number alloc] init];
theNumber.theNumber = newN;
[theNumbers addN:theNumber];
[theNumbers release];
[theNumber release];
}
the code is executed but no record is inserted in the DB.
can someone please point me where is the mistake - cause there obviously is a mistake :)
You're not checking the return values of any of the sqlite3 calls. There's a good chance one of them is failing.
this code seems to work:
- (void) addN: (number *) theN
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *thePath = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:#"theDB.sqlite"];
BOOL success = [fileManager fileExistsAtPath:thePath];
if (!success)
{
NSLog(#"Failed to find database file '%#'.", thePath);
}
if (!(sqlite3_open([thePath UTF8String], &database) == SQLITE_OK))
{
NSLog(#"An error opening database, normally handle error here.");
}
const char *sql = "insert into table (valueN) Values(?)";
sqlite3_stmt *addStmt = nil;
if (sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
{
NSLog(#"Error, failed to prepare statement, normally handle error here.");
}
sqlite3_bind_int(addStmt, 1, theN.theNumber);
sqlite3_step(addStmt);
if(sqlite3_finalize(addStmt) != SQLITE_OK)
{
NSLog(#"Failed to finalize data statement, normally error handling here.");
}
if (sqlite3_close(database) != SQLITE_OK)
{
NSLog(#"Failed to close database, normally error handling here.");
}
}