create sqlite db programmatically in iphone sdk - iphone

hai i a'm trying to create a sqlite database programmatically at the run time. can anybody say how to create it in iphone sdk.

Just call the sqlite3_open function it will create a database if no database exist on the path.
// generate databasePath programmatically
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
// your code here
}
post a comment if you need more code example on this

-(void)viewDidLoad
{
[super viewDidLoad];
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.sqlite"]];
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)
{
NSLog(#"if");
}
sqlite3_close(contactDB);
} else
{
NSLog(#"else");
}
}
[filemgr release];
}
-(IBAction)table
{
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.sqlite"]];
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 LIST (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, ADDRESS TEXT, PHONE TEXT)";
if (sqlite3_exec(contactDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
NSLog(#"tables failed");
// status.text = #"Failed to create table";
}
sqlite3_close(contactDB);
}
else
{
NSLog(#"tables failed");
//status.text = #"Failed to open/create database";
}
}
[filemgr release];
}

import in .m file #import sqlite3.h and add framework in ur project libsqlite3.0.dylib
firstly create NSObject class and named it Database.
in .h class
#interface database : NSObject
{
NSString *databasePath;
NSString *databaseName;
sqlite3 *myDatabase;
NSArray *documentPaths;
NSString *documentsDir;
}
//---initial methods-------
-(void)createDatabaseIfNeeded;
//-----------------path find method---------------------//
-(void)pathFind;
//-----------------write value----------------------//
-(void)writeValueInSettings:(NSMutableArray *)arrayvalue;
//-------------------fetch value from setting table------------//
-(NSMutableArray *)fetchValue;
//-------------------update value---------------------//
-(void)updateSetting:(NSArray *)arr;
.m class write
-(id)init
{
if((self=[super init]))
{
[self createDatabaseIfNeeded];
}
return self;
}
//-----------create database if needed method--------------//
-(void)createDatabaseIfNeeded
{
[self pathFind];
BOOL success;
NSFileManager *filemgr = [NSFileManager defaultManager];
success=[filemgr fileExistsAtPath:databasePath];
if (success)return;
NSLog(#"not success");
//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
[filemgr copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}
//----------------path find-----------------//
-(void)pathFind
{
databaseName = #"accDataBase.DB";
// Get the path to the documents directory and append the databaseName
documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
}
//------------------write value in setting----------------//
-(void)writeValueInSettings:(NSMutableArray *)arrayvalue
{
NSLog(#"%#",arrayvalue);
if(sqlite3_open([databasePath UTF8String],&myDatabase)==SQLITE_OK)
{
database *objectDatabase=[[database alloc]init];
NSString *stringvalue2=[objectDatabase countValue];
[objectDatabase release];
int intvalue1=[stringvalue2 intValue];
intvalue1=intvalue1+1;
NSLog(#"opened");
NSString *sql1;
sql1=[[NSString alloc] initWithFormat:#"insert into setting values('%i','%i','%i','%#','%i','%i','%#','%i','%i','%i','%i','%i','%i','%#');",intvalue1,
[[arrayvalue objectAtIndex:0] intValue],[[arrayvalue objectAtIndex:1] intValue],[arrayvalue objectAtIndex:2],[[arrayvalue objectAtIndex:3] intValue],[[arrayvalue objectAtIndex:4]intValue ],[arrayvalue objectAtIndex:5],[[arrayvalue objectAtIndex:6]intValue],[[arrayvalue objectAtIndex:7]intValue ],[[arrayvalue objectAtIndex:8] intValue],[[arrayvalue objectAtIndex:9] intValue],[[arrayvalue objectAtIndex:10]intValue ],[[arrayvalue objectAtIndex:11]intValue],[arrayvalue objectAtIndex:12]];
char *err1;
if (sqlite3_exec(myDatabase,[sql1 UTF8String],NULL,NULL,&err1)==SQLITE_OK)
{
NSLog(#"value inserted:");
}
[sql1 release];
sqlite3_close(myDatabase);
}
}
//------------fetch all value-------------//
-(NSMutableArray *)fetchValue
{
NSMutableArray *list=nil;
list=[[[NSMutableArray alloc]init] autorelease];
if(sqlite3_open([databasePath UTF8String],&myDatabase)==SQLITE_OK)
{
NSString *sql=[NSString stringWithFormat: #"select * from setting where primaryKey=1"];
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(myDatabase, [sql UTF8String], -1,&statement, NULL)==SQLITE_OK)
{
if(sqlite3_step(statement)==SQLITE_ROW)
{
for(int i=0;i<=13;i++)
{
char *pass=(char*)sqlite3_column_text(statement,i);
NSString *msg=[[NSString alloc]initWithUTF8String:pass];
[list addObject:msg];
[msg release];
}
}
sqlite3_finalize(statement);
}
sqlite3_close(myDatabase);
}
return list;
}
//----------------update setting table method---------------//
-(void)updateSetting:(NSArray *)arr
{
if(sqlite3_open([databasePath UTF8String],&myDatabase)==SQLITE_OK)
{
NSLog(#"opened");
sqlite3_stmt *compiledStmt;
// NSLog(#"%#",arr);
NSString *sqlStmt=[NSString stringWithFormat:#"UPDATE setting SET ragular=%i,cycle=%i, flow='%#', hour=%i,minute=%i,formate='%#' ,tenminute=%i ,thirtyminute=%i,sixtymin=%i, twentymin=%i, fourtyfivemin=%i ,other='%#',formatemessage ='%#' WHERE primaryKey=%i;",[[arr objectAtIndex:0]intValue],[[arr objectAtIndex:1]intValue],[arr objectAtIndex:2],[[arr objectAtIndex:3]intValue],[[arr objectAtIndex:4]intValue],[arr objectAtIndex:5],[[arr objectAtIndex:6]intValue],[[arr objectAtIndex:7]intValue],[[arr objectAtIndex:8]intValue],[[arr objectAtIndex:9]intValue],[[arr objectAtIndex:10]intValue],[arr objectAtIndex:11],[arr objectAtIndex:12],1];
// NSLog(#"%#",sqlStmt);
if(sqlite3_prepare_v2(myDatabase, [sqlStmt UTF8String],-1,&compiledStmt, NULL)==SQLITE_OK)
{
NSLog(#"updateding......cycle");
}
sqlite3_step(compiledStmt);
sqlite3_close(myDatabase);
}
}

Related

how can i update sqlite database

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");
}
}

sqlite3_prepare_v2() == SQLITE_OK returns NO and existing table is not found

I am developing an iphone application which using sqlite3 database file. and i am using following code to select from sqlite3 database ;
NSString* dbYolu = [NSString stringWithFormat:#"%#/emhdb3.sqlite3",NSHomeDirectory()];
sqlite3* db;
NSLog(#"%# dbyolu : ", dbYolu);
if (sqlite3_open([dbYolu UTF8String], &db) == SQLITE_OK)
{
NSString *query = [NSString stringWithFormat: #"SELECT username, mobile FROM peopleto WHERE namesurname=\"%#\"", name.text];
NSLog(#"%# : query", query);
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(db, [query UTF8String], -1, &stmt, nil) == SQLITE_OK) // statement stmt returns null and returns SQLITE_OK = FALSE.
{
NSLog(#"stepped in SQLITE_OK is TRUE");
while (sqlite3_step(stmt) == SQLITE_ROW)
{
NSString* ders_kodu = [NSString stringWithUTF8String:(char*)sqlite3_column_text(stmt, 0)];
double not = sqlite3_column_double(stmt, 1);
NSLog(#"%# : %f", ders_kodu, not);
}
}
else
{
NSLog(#"%# - but failed", stmt);
}
sqlite3_finalize(stmt);
}
else
NSLog(#"db could not be opened");
it fails at the "sqlite3_prepare_v2(db, [query UTF8String], -1, &stmt, nil) == SQLITE_OK" point above. and the error is : "Error:No such table : peopleto. But it successfully returns the content of table when i run this query in sql browser. I mean this query is correct and working.
btw, I get the file with pathname with the following code on viewLoad
- (void)viewDidLoad
{
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: #"emhdb3.sqlite3"]];
NSLog(#"dbpath : %#", databasePath);
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: databasePath ] == NO)
{
const char *dbpath = [databasePath UTF8String];
NSLog(#"db not found");
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSLog(#"SQLITE_OK is passed");
//.... some codes here, doesn't metter for me because SQLITE_OK = true
} else {
status.text = #"Failed to open/create database";
}
}
else if ([filemgr fileExistsAtPath:databasePath] == YES)
{
NSLog(#"i found the file here : %s",[databasePath UTF8String]);
}
NSLog(#"completed");
[super viewDidLoad];
}
I have the database file in my project folder and added to the project.
What i am missing?
Thanks
///////
i am sorry for updating my question but stackoverflow does not allow me to add new ,
please find my update below ;
Here is the updated version of the code :
viewLoad part;
- (void)viewDidLoad
{
[self createEditableCopyOfDatabaseIfNeeded];
NSString *docsDir;
NSArray *dirPaths;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
databasePath = [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent:#"emhdb3.sqlite3"]];
NSLog(#"dbpath : %#", databasePath);
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 peopleto (pId INTEGER PRIMARY KEY AUTOINCREMENT, namesurname TEXT, mobile 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";
}
}
else if ([filemgr fileExistsAtPath:databasePath] == YES)
{
NSLog(#"%s is filepath",[databasePath UTF8String]);
}
NSLog(#"checkpoint 4");
[super viewDidLoad];
}
buraya başka birşey yaz
- (void)createEditableCopyOfDatabaseIfNeeded {
NSLog(#"entered createEditableCopyOfDatabaseIfNeeded");
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"emhdb3.sqlite3"];
success = [fileManager fileExistsAtPath:writableDBPath];
if (success)
{
NSLog(#"success == YES returned");
return;
}
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"emhdb3.sqlite3"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success) {
NSLog( #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
else{
NSLog(#"checkpoint 2");
}
}
and the part that select query is performed ;
-(IBAction)findcontact2:(id)sender
{
NSString *dbYolu = databasePath;
sqlite3* db;
NSLog(#"%# dbyolu : ", dbYolu);
if (sqlite3_open([dbYolu UTF8String], &db) == SQLITE_OK)
{
NSString *query = [NSString stringWithFormat: #"SELECT namesurname, mobile FROM peopleto"]; //any query
NSLog(#"%# : query", query);
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(db, [query UTF8String], -1, &stmt, nil) == SQLITE_OK)
{
NSLog(#"SQLITE is OK");
while (sqlite3_step(stmt) == SQLITE_ROW)
{
NSString* ders_kodu = [NSString stringWithUTF8String:(char*)sqlite3_column_text(stmt, 0)];
double not = sqlite3_column_double(stmt, 1);
NSLog(#"%# : %f", namesurname, mobile);
}
}
else
{
NSLog(#"Error=%s",sqlite3_errmsg(db)); // error message : Error=no such table: peopleto
NSLog(#"%# - is stmt", stmt); //stmt is null
}
sqlite3_finalize(stmt);
}
else
NSLog(#"could not open the db");
}
As i pointed above, the error is Error=no such table: peopleto and stmt is returned null
Are you copying your SQL file to documents, if not you need to do that first. While adding SQL file to project, it is added in your bundle and not in documents directory. YOu need to copy that first
- (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:#"bookdb.sql"];
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:#"bookdb.sql"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success) {
NSLog( #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
Please check the DB which is in your main bundle contains the table then try to copy it to resource folder and apply the above

SQLite issue: sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) not working

-(void)myDatabaseFunction
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"HHAuditToolDatabase.sqlite"];
if (sqlite3_open([writableDBPath UTF8String], &database) == SQLITE_OK){
NSLog(#"opening db");
NSString *keyValue;
NSString *sqlStr = #"SELECT * FROM HHAuditTable";
//following if() not working dude!!!!
//its working with !=SQLITE_OK
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
sqlite3_stmt *addStmt = nil;
if(sqlite3_prepare_v2(database,[sqlStr UTF8String], -1, &addStmt, NULL) != SQLITE_OK){
NSLog(#"%#",sqlStr);
while (sqlite3_step(addStmt) == SQLITE_ROW) {
const unsigned char *querry_returns = sqlite3_column_text(addStmt, 0);
keyValue = [[NSString alloc]initWithUTF8String:(char *) sqlite3_column_text(addStmt, 0)];
}
NSLog(#"value from DB = %#",keyValue);
That if() with comment doesn't work....Some have a cure!!! i have been on it for last 3 hrs....please come up with a soln
You are opening the database twice. You should have to close the database connection and then you have to open the database again. That is why it is not working.
Hay you can use my code its working fine for me:-
(void)myDatabaseFunction {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
dbPath = [self getDBPath];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success) {
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"flipsy.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
NSString *sql = #"SELECT * FROM HHAuditTable";
NSInteger *intvalue;
result = [[NSMutableArray alloc] init];
// NSLog(#"sql--------->%#",sql);
const char *sqlStatement = [sql UTF8String];
//if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
if(sqlite3_prepare_v2(database, sqlStatement, -1, &selectstmt , NULL)!= SQLITE_OK) {
}
else {
//NSLog(#"%#",dataTypeArray);
for(int i=0;i<[dataTypeArray count];i++) {
temp = [[NSMutableArray alloc] init];
[result addObject:temp];
// [temp release];
}
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
for(int i=0;i<[dataTypeArray count];i++) {
switch( [[dataTypeArray objectAtIndex:i] integerValue] ) {
case 0:
intvalue = (NSInteger *)sqlite3_column_int(selectstmt,i);
strvalue = [NSString stringWithFormat:#"%d",intvalue];
[[result objectAtIndex:i] addObject:(NSNumber *)strvalue];
break;
case 1:
[[result objectAtIndex:i] addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, i)]];
break;
case 2:
blob = [[NSData alloc] initWithBytes:sqlite3_column_blob(selectstmt, i) length:sqlite3_column_bytes(selectstmt, i)];
[[result objectAtIndex:i] addObject:blob];
[blob autorelease];
break;
default:
defaultValue=[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, i)];
break;
}//switch
}//for(int i=0;i<[dataTypeArray count];i++)
}//while(sqlite3_step(selectstmt) == SQLITE_ROW)
//}//else
//sqlite3_close(database);
sqlite3_finalize(selectstmt);
[temp release];
}//if (sqlite3_open([dbPath UTF
}
- (NSString *) getDBPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:#"flipsy.sqlite"];
}
Please let me know if any clarification needed

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.

the SQLiteBooks sample code is missing

I find this link everywhere for SQLite sample code (http://developer.apple.com/library/ios/#samplecode/SQLiteBooks/index.html) but either it has been removed or changed to another location.. I couldn't find it in google searches.. Does anyone know any other link to the code or any other good sample code for SQLite?
May be this is useful to you.
http://www.switchonthecode.com/tutorials/using-sqlite-on-the-iphone
http://dblog.com.au/iphone-development-tutorials/iphone-sdk-tutorial-reading-data-from-a-sqlite-database/
http://www.icodeblog.com/2008/08/19/iphone-programming-tutorial-creating-a-todo-list-using-sqlite-part-1/
You can use this class and send query in this class and get all functionality of sqlite using this class
.h
#import <Foundation/Foundation.h>
#import "sqlite3.h"
#interface DBLib : NSObject {
sqlite3 *database;
NSString *path;
}
- (NSString *)getDatabasePath:(NSString*)DBName;
- (void)createEditableCopyOfDatabaseIfNeeded:(NSString*)DBName;
- (void)initializeDatabase:(NSString*)DBName;
-(NSMutableArray*)GetListBySQL:(NSString*)SQL;
-(BOOL)UpdateData:(NSMutableDictionary*)objDic :(NSString*)PrimaryKey :(NSString*)TABLE_NAME;
-(BOOL)deleteQuery:(NSString *)query;
#end
.m
#import "DBLib.h"
#implementation DBLib
#pragma mark Database methods
- (NSString *)getDatabasePath:(NSString*)DBName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) ;
NSString *documentsDirectory = [paths objectAtIndex:0] ;
return [documentsDirectory stringByAppendingPathComponent:DBName];
}
// Creates a writable copy of the bundled default database in the application Documents directory.
- (void)createEditableCopyOfDatabaseIfNeeded:(NSString*)DBName {
// 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:DBName];
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:DBName];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success) {
NSString *errString = [NSString stringWithFormat:#"%#", [#"Fail" stringByReplacingOccurrencesOfString:#"#" withString:[error localizedDescription] ]];
NSAssert1(0, #"%#", errString);
}
}
// Open the database connection and retrieve minimal information for all objects.
- (void)initializeDatabase:(NSString*)DBName {
// The database is stored in the application bundle.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
path = [documentsDirectory stringByAppendingPathComponent:DBName];
NSStringEncoding enc = [NSString defaultCStringEncoding];
// Open the database. The database was prepared outside the application.
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK)
{
//TRUE
NSLog(#"Successfully opened-sqlite3");
}
else
{
// Even though the open failed, call close to properly clean up resources.
sqlite3_close(database);
NSLog(#"closed");
NSString *errString = [NSString stringWithFormat:#"%#", [#"Fail" stringByReplacingOccurrencesOfString:#"#" withString:[NSString stringWithCString:sqlite3_errmsg(database) encoding:enc] ]];
NSAssert1(0, #"%#", errString);
// Additional error handling, as appropriate...
}
}
-(NSMutableArray*)GetListBySQL:(NSString*)SQL
{
[self initializeDatabase:#"DBNAME"];
NSMutableArray* Array;
Array=[[NSMutableArray alloc]init];
NSStringEncoding enc = [NSString defaultCStringEncoding];
sqlite3_stmt *select_statement=nil;
if (sqlite3_prepare_v2(database, [SQL UTF8String], -1, &select_statement, NULL) != SQLITE_OK) {
NSString *errString = [NSString stringWithFormat:#"%#", [#"Fail" stringByReplacingOccurrencesOfString:#"#" withString:[NSString stringWithCString:sqlite3_errmsg(database) encoding:enc] ]];
NSAssert1(0, #"%#", errString);
}
int columncount=sqlite3_column_count(select_statement);
NSMutableDictionary* dic;
while (sqlite3_step(select_statement) == SQLITE_ROW)
{
dic=[[NSMutableDictionary alloc]init];
for(int j=0;j<columncount;j++)
{
if(sqlite3_column_text(select_statement, j)!=nil)
[dic setObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(select_statement, j)] forKey:[NSString stringWithUTF8String:(char *)sqlite3_column_name(select_statement,j)]];
else
[dic setObject:#"" forKey:[NSString stringWithUTF8String:(char *)sqlite3_column_name(select_statement,j)]];
}
[Array addObject:dic];
[dic release];
}
sqlite3_finalize(select_statement);
NSMutableArray *arr = [[NSMutableArray alloc] initWithArray: Array];
[Array release];
return arr;
}
//Method for Datbase
-(BOOL)UpdateData:(NSMutableDictionary*)objDic :(NSString*)PrimaryKey :(NSString*)TABLE_NAME
{
NSAutoreleasePool* pool=[[NSAutoreleasePool alloc]init];
[self initializeDatabase:DBNAME];
NSString* SQLColumns=#"";
NSString* SQLValues=#"";
NSString* SQL=#"";
//Chekc Wheather Insert or update?
BOOL IsNew=NO;;
if([[objDic valueForKey:PrimaryKey] intValue]==0)
{
IsNew=YES;
}
NSArray* Keys=[objDic allKeys];
NSLog(#"%#",Keys);
if(IsNew)
{
for(int i=0;i<Keys.count;i++)
{
if(![[Keys objectAtIndex:i] isEqual:PrimaryKey])
{
SQLColumns=[NSString stringWithFormat:#"%#%#,",SQLColumns,[Keys objectAtIndex:i]];
SQLValues=[NSString stringWithFormat:#"%#?,",SQLValues];
}
}
if([SQLColumns length]>0)
{
SQLColumns=[SQLColumns substringToIndex:[SQLColumns length]-1];
SQLValues=[SQLValues substringToIndex:[SQLValues length]-1];
}
SQL=[NSString stringWithFormat:#"INSERT INTO %# (%#) Values(%#)",TABLE_NAME,SQLColumns,SQLValues];
}
else
{
for(int i=0;i<Keys.count;i++)
{
if(![[Keys objectAtIndex:i] isEqual:PrimaryKey])
{
SQLColumns=[NSString stringWithFormat:#"%#%#=?,",SQLColumns,[Keys objectAtIndex:i]];
}
}
if([SQLColumns length]>0)
{
SQLColumns=[SQLColumns substringToIndex:[SQLColumns length]-1];
}
SQL=[NSString stringWithFormat:#"UPDATE %# SET %# WHERE %#=?",TABLE_NAME,SQLColumns,PrimaryKey];
//NSLog(sql);
}
sqlite3_stmt *insert_statement=nil;
if (sqlite3_prepare_v2(database, [SQL UTF8String], -1, &insert_statement, NULL) != SQLITE_OK) {
//NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
NSLog(#"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
int intBindIndex=1;
for(int i=0;i<Keys.count;i++)
{
if(![[Keys objectAtIndex:i] isEqual:PrimaryKey])
{
sqlite3_bind_text(insert_statement,intBindIndex,[[objDic valueForKey:[Keys objectAtIndex:i]] UTF8String],-1, SQLITE_STATIC);
intBindIndex++;
}
}
if(!IsNew)
{
sqlite3_bind_text(insert_statement,Keys.count,[[objDic valueForKey:PrimaryKey] UTF8String],-1, SQLITE_STATIC);
}
int result;
result=sqlite3_step(insert_statement);
if(IsNew)
{
[objDic setObject:[NSString stringWithFormat:#"%d",sqlite3_last_insert_rowid(database)] forKey:PrimaryKey];
}
sqlite3_finalize(insert_statement);
[pool release];
NSLog(#"result:%d",result);
if(result==SQLITE_DONE)
return YES;
else
return NO;
}
-(BOOL)deleteQuery:(NSString *)query
{
NSAutoreleasePool* pool=[[NSAutoreleasePool alloc]init];
[self initializeDatabase:DBNAME];
NSString* SQL=#"";
SQL=[NSString stringWithString:query];
sqlite3_stmt *insert_statement=nil;
if (sqlite3_prepare_v2(database, [SQL UTF8String], -1, &insert_statement, NULL) != SQLITE_OK) {
//NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
NSLog(#"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
int result;
result=sqlite3_step(insert_statement);
sqlite3_finalize(insert_statement);
[pool release];
NSLog(#"result:%d",result);
if(result==SQLITE_DONE)
return YES;
else
return NO;
}
#end

Categories