Open two sqlite database and execute query in iphone - ios

Here i want to execute query using two database and copy data from table of database1 to another database2. here i am able to open one database but getting problem in openning other database. Thanks in advance to all.
CurrentStatus *status = [CurrentStatus sharedCurrentStatus];
sqlite3 *database;
sqlite3 *database1;
sqlite3_stmt *statement;
sqlite3_stmt *statement1;
NSString *dbPath = [status.applicationDocumentDirectory stringByAppendingPathComponent:#"database.sqlite"];
NSString *dbPath1 = [status.applicationDocumentDirectory stringByAppendingPathComponent:#"database1.sqlite"];
if ((sqlite3_open_v2([dbPath UTF8String], &database, SQLITE_OPEN_READWRITE , NULL) == SQLITE_OK) && (sqlite3_open_v2([dbPath1 UTF8String], &database1, SQLITE_OPEN_READWRITE , NULL) == SQLITE_OK)) {
NSString *sqlStr = [[NSString alloc] initWithFormat:#"select * from Login" ];
NSString *sql = [[NSString alloc] initWithString:sqlStr];
if ((sqlite3_prepare_v2(database, [sql UTF8String], -1, &statement, NULL) == SQLITE_OK)) {
NSLog(#"DB prepare_v2 Opening successfully");
if (sqlite3_step(statement) == SQLITE_ROW) {
}
else
{
}
sqlite3_finalize(statement);
NSLog(#"DB Opening successfully");
sqlite3_close(database);
}else
{
NSLog(#"else DB Opening successfully");
}
sqlite3_close(database);
}

Try something similar to achieve your task ..
First, you are opening the "DB1" database, and then execute the following statement:
ATTACH DATABASE "2ndDB.db" AS 2ndDB;
After that, you can use the CREATE TABLE syntax:
CREATE TABLE newTableInDB1 AS SELECT * FROM 2ndDB.oldTableInMyOtherDB;
This will "copy" the data over to your new database

Copy which are the data you want it from database1 add each row in NSMutableDictionary and then add it to NSMutableArray. Close and reset your statement then open the database2 copy the data from NSMutableArray, that array act as database for you..
I hope it will work for you..

You need to You need to Attach databases and then copy tables from one database to another database. You need to do something like this:
NSString *attachSQL = [NSString stringWithFormat: #"ATTACH DATABASE \'%s\' AS %#", sourceDBPath,dbAlias];
if (sqlite3_exec(db, [attachSQL UTF8String], NULL, NULL, &errorMessage) != SQLITE_OK)
{
NSString *errorStr = [NSString stringWithFormat:#"The database could not be attached: %#",[NSString stringWithCString:errorMessage encoding:NSUTF8StringEncoding]];
return errorStr;
}
After that you need to copy table , like:
NSString *queryString=[NSString stringWithFormat:#"CREATE TABLE %# AS SELECT * FROM %#.%#;",newTableName,dbAlias,origTableName];
And you are done, you have the new copy of database.

Related

does it possible to save Db file with application and not by adding in from itunes

I want the application which work online as well as offline example WhatsApp. For that i have to sync data from web service then store it in sqlite db file.
And I want that whoever installs this application would have a slot for automatic saving data in database file. Do I have to add db file from iTunes?
I don't want to use core data concept.
Is it possible it will be there in with application?
Like in Android there is something called cache memory where db file is stored so there is any sort of provision for it in ios?
+(int)insert_In_AdverImage:(NSString *)strid ImageName:(NSString *)strimg Isshow:(NSString *)strshow LastUpdateId:(NSString *)date isdelete:(NSString *)isdelete Sortorder:(int)sortOrder{
sqlite3 *database;
int retValue = 0;
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
NSString *tempSQL = [[NSString alloc] initWithFormat:#"INSERT INTO ADVERIMAGE(advId ,advimg ,isshow ,LastUpdateId ,IsDelete ,SortorderId ) VALUES ('%#', '%#', '%#', '%#', '%#', '%d')", strid, strimg, strshow, date, isdelete, sortOrder];
const char *sqlStatement = [tempSQL cStringUsingEncoding:NSUTF8StringEncoding];
sqlite3_stmt *compiledStatement;
sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL);
sqlite3_step(compiledStatement);
retValue = (int)sqlite3_last_insert_rowid(database);
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
return retValue;
}
works well. But still the db file in app bundle is empty.i got it that whenever we insert something it will be inserted in document and if we have to see the inserted data we have to get it from document
Thanks in advance
Any Help would be appreciated.
Yes. Possible.
You can store SQlite DB in your applications's Document Directory. You need to write your own Query to Open DB, Insert Data, Retrieve Data from DB.
Check out following tutorial for your requirement : http://www.appcoda.com/sqlite-database-ios-app-tutorial/
Hope it helps.
Following function is used to Insert :
NSArray *docsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [docsDirectory objectAtIndex:0];
NSString *databasePath = [docPath stringByAppendingPathComponent:#"Database.sqlite"];
sqlite3 *dbHandler;
const char *dbPath = [databasePath UTF8String];
sqlite3_stmt *sqlStmt;
if(sqlite3_open(dbPath, &dbHandler) == SQLITE_OK)
{
if (sqlite3_prepare_v2(dbHandler, [queryString UTF8String], -1, &sqlStmt, NULL) == SQLITE_OK)
{
if (sqlite3_step(sqlStmt) == SQLITE_DONE)
{
NSLog(#"Data Inserted");
}
else
{
NSLog(#"Not inserted");
}
}
else
{
NSLog(#"Failed to Insert data -InsertDataFunc");
}
sqlite3_close(dbHandler);
}

implementing WAL in iOS?

The code I placed below works. So my scenario is I have the code below in a class. I use this class simply for merging tables and updating one table. When I call the object that this code lives in the app delegate for example, it works great! But when I call the same object after clicking a button in a tableview controller, I get a database lock error. So here's what I am wondering. After reading sqlite documentation WAL: http://www.sqlite.org/wal.html I am thinking that I cannot read and update concurrently to the sqlite db, right? I am unsure of a solution around this, so what would be a good suggestion around my problem. Remember, keep in mind this code works just fine in the app delegate, it does not work in my tableview controller when I call it using action upon clicking the button. Note: I SELECT data from the SQLITE database to display table cell names etc. Thanks ahead of time!
//Allocates a filemanager object. Ideally, this object is used for searching through the applications context
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL dbErr = NO;
//Boolean variable to tell if the database exists
BOOL error,mainDbError;
//Looks through all the databases. If there is a database that does not exist, the following error message will appear to the user. If all the databases exist on the system, the database opens respectively
error = [self checkAndOpenSyncDB];
mainDbError = [self checkAndOpenMainDB];
if (!error&&mainDbError) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Oops!"
message:#"We didn't mean for this to happen. Looks like there was a problem loading the sync database. Contact technical support for further assistance."
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
}
else{
//This is I think to check when the last time the sync occured on the system.. not quite sure though1
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSLog(#"Erorr syncing the database: Code: %d, message: '%s'", error,sqlite3_errmsg(syncOpenHandle));
char *errorMessage;
int errorNum = 0;
//Atataching the sync db to the master db
NSString *attachSQL = [NSString stringWithFormat:#"ATTACH DATABASE \'%#\' AS sync_db", self->pathForSync];
NSLog(#"PATH FOR SYNC !!!!!!! %#", pathForSync);
NSLog(#"Here's the arratch string: %#", attachSQL);
//
if (sqlite3_exec(syncOpenHandle, [attachSQL UTF8String], NULL, NULL, &errorMessage) == SQLITE_OK) {
NSString *masterQuery = [NSString stringWithFormat:#"SELECT name FROM sqlite_master WHERE type='table';"];
const char *masterStmt = [masterQuery UTF8String];
sqlite3_stmt *statement;
BOOL loopErr;
loopErr = sqlite3_prepare_v2(syncOpenHandle, masterStmt, -1, &statement, NULL);
if (sqlite3_prepare_v2(syncOpenHandle, masterStmt, -1, &statement, NULL)==SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
NSString * currentTable = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
NSLog(#"Here's the current table: %#",currentTable);
//This is where the magic happens. If there are any keys matching the database, it will update them. If there are no current keys in the database, the query will insert them.
if ([currentTable isEqualToString:#"USER_DATA"] == NO && [currentTable isEqualToString:#"USER_ACTIVITY"]== NO && [currentTable isEqualToString:#"USER_ITINERARY"] == NO) {
NSString *tblUpdate = [NSString stringWithFormat:#"INSERT or REPLACE INTO main.%# SELECT * FROM sync_db.%#;",currentTable, currentTable];
const char *updateStmt = [tblUpdate UTF8String];
//sqlite3_busy_timeout (mainOpenHandle, 60000);
bool update;
update = sqlite3_exec(syncOpenHandle, updateStmt, NULL, NULL, &errorMessage)== SQLITE_OK;
NSLog(#"Error sync ... '%s'", sqlite3_errmsg(syncOpenHandle));
if (sqlite3_exec(syncOpenHandle, updateStmt, NULL, NULL, &errorMessage)== SQLITE_OK) {
NSLog(#"Error sync ... '%s'", sqlite3_errmsg(syncOpenHandle));
if (errorNum == 1) {
//A database reset is needded
//self->isResetDataBase = YES;
}
dbErr = YES;
}
}
}
NSLog(#"Error sync ... '%s'", sqlite3_errmsg(syncOpenHandle));
}
NSLog(#"Here's the error num %d", errorNum);
NSLog(#"Erorr syncing the database: Code: %d, message: '%s'", error,sqlite3_errmsg(syncOpenHandle));
NSLog(#"Error sync ... '%s'", sqlite3_errmsg(syncOpenHandle));
sqlite3_finalize(statement);
//Detaching the database from the mainDB
NSString *detachSQL = [NSString stringWithFormat:#"DETACH DATABASE sync_db"]; // reference sync db
if ((errorNum = sqlite3_exec(syncOpenHandle, [detachSQL UTF8String], NULL, NULL, &errorMessage))!= SQLITE_OK) {
NSLog(#"Detatched syncDb Failed. ErrorMessage = %s ", errorMessage);
}
}
}
NSLog(#"Error sync ... '%s'", sqlite3_errmsg(syncOpenHandle));
//Closing the database when finished.
if (syncOpenHandle!=nil) {
sqlite3_close(syncOpenHandle);
NSError *err;
int success = [fileManager fileExistsAtPath:pathForSync];
if (success) {
[[NSFileManager defaultManager]removeItemAtPath:pathForSync error:&err];
}
}

Sqlite database cannot read column

I have a DBManager wich is fetching data from database (sqlite file). All other queries are fine, but this one seems to be somehow not working
-(NSArray *)readCountries{
NSLog(#"[DBManager] readCountries");
NSMutableArray *countriesArray = [[NSMutableArray alloc] init];
//open db from users filesystem
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
const char* sql = "SELECT DISTINCT country FROM aed ORDER BY rowid";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
//loop through results
while (sqlite3_step(statement) == SQLITE_ROW) {
//read data from record
NSString *_country;
char* tmpCountry = (char*)sqlite3_column_text(statement, 1);
NSLog(#"tmpCountry = %#", [NSString stringWithUTF8String:tmpCountry]);
if (tmpCountry != NULL) {
_country = [NSString stringWithUTF8String:tmpCountry];
}else{
_country = #"n/a";
}
NSLog(#"country = %#", _country);
[countriesArray addObject:_country];
}
}
//finalize statement
sqlite3_finalize(statement);
}
//close database
sqlite3_close(database);
NSLog(#"[DBManager] countriesArray has %d objects", [countriesArray count]);
return (NSArray*)countriesArray;
}
All I get from logs, that my array has 5 objects, which is fine - but it souldn't be only "n/a"... any idea? Other queries are good, they mostly use sqlite3_column_text so I don't get it, why it's not working here - maybe a fresh eye will help.
This is a confusing inconsistency with the sqlite C-api. When using the sqlite3_column_xxx functions, the column index is 0-based. But with the sqlite3_bind_xxx functions, the column index is 1-based.
Change this:
char* tmpCountry = (char*)sqlite3_column_text(statement, 1);
to:
char* tmpCountry = (char*)sqlite3_column_text(statement, 0);
BTW - you should add else statements to your sqlite3_open and sqlite3_prepare calls. If they fail you can log the error using the sqlite3_errmsg function.

Checking if a table exists and if it does not exist, create it... iOS/SQLite

I currently have a table that exists which I'm able to pull data from. What I would like to do is check if the table already exists in the bundle, and if it does not, I want to create the table and save it to the bundle (meaning the path would be in the main bundle). I want the database to be checked and created at the top of the setInput method. I've been scouring SO for something similar to this, but I haven't come up with anything yet. Any help is very appreciated. Here is my code:
-(IBAction)setInput:(id)sender
{
NSString *strStoreNumber;
NSString *strRegNumber;
strStoreNumber = StoreNumber.text;
strRegNumber = RegNumber.text;
lblStoreNumber.text = strStoreNumber;
lblRegNumber.text = strRegNumber;
NSString* databasePath = [[NSBundle mainBundle] pathForResource:#"tblStore" ofType:#"sqlite"];
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
NSLog(#"Opened sqlite database at %#", databasePath);
sqlite3_exec(database, "CREATE TABLE IF NOT EXISTS tblStore (ID INTEGER PRIMARY KEY AUTOINCREMENT, Message TEXT)", NULL, NULL, NULL);
//...stuff
}
else
{
NSLog(#"Failed to open database at %# with error %s", databasePath, sqlite3_errmsg(database));
sqlite3_close (database);
}
//
NSString *querystring;
// create your statement
querystring = [NSString stringWithFormat:#"SELECT strStore, strReg FROM tblStore WHERE strStore = %# AND strReg = %#;", strStoreNumber, strRegNumber];
const char *sql = [querystring UTF8String];
NSString *szStore = nil;
NSString *szReg = nil;
sqlite3_stmt *statement = nil;
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL)!=SQLITE_OK) //queryString = Statement
{
NSLog(#"sql problem occured with: %s", sql);
NSLog(#"%s", sqlite3_errmsg(database));
}
else
{
// you could handle multiple rows here
while (sqlite3_step(statement) == SQLITE_ROW)
{
szStore = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 0)];
szReg = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 1)];
}
}
sqlite3_finalize(statement);
lblStoreNumber.text = szStore;
lblRegNumber.text = szReg;
//
}
I'm still quite new to iOS and SQLite, so if I did not provide an accurate enough description of what I'm trying to do, let me know and I'll try to be more specific. Thanks!
A quick search for "iphone sql create table if not exists" gave this as the top result.
This part of the SQL is probably what you are looking for:
CREATE TABLE IF NOT EXISTS tableName( ... )
It creates a table if it does not already exist.
Create table using sqlite swift
func createTable(_ tableName:String) {
sqlStatement = "CREATE TABLE \(tableName)(Id TEXT,Details BLOB,Type TEXT)"
if sqlite3_prepare_v2(database, sqlStatement,-1, &compiledStatement, nil) == SQLITE_OK {
if sqlite3_step(compiledStatement) == SQLITE_DONE {
print("table created")
}
else {
print("table could not be created")
}
}
else {
print("Create table statement could not be prepared")
}
sqlite3_finalize(compiledStatement)
}

How to add & delete data from SQLite database?

I have tried following the guide on this page SQLite Tutorial? Deleting Data | iPhone SDK Articles but I just can't understand how to implement it in my app, because I the NSMutableArray isn't declared in the AppDelegate as it is in the tutorial
Can someone have a look and guide me through it? I want to be able to delete rows from the tableview and the database and to be able to add data as well.
Here is my app: http://ge.tt/9JNVd89?c
Even the slightest tip will be appreciated.
Will probably need a bit more information as to your current level of knowledge. How far have you gotten? Are you able to connect and read data from it? Do you understand how SQL works?
If you wanted to retrieve data from the db you could write something like the following:
+ (NSArray *)getAllUsers
{
sqlite3 *db = **However you get your db conn**
sqlite3_stmt *statement = nil;
NSMutableArray *userArray = [NSMutableArray array];
NSString *fullQuery = #"SELECT * FROM User";
const char *sql = [fullQuery UTF8String];
if(sqlite3_prepare_v2(db, sql, -1, &statement, NULL)!=SQLITE_OK)
NSAssert1(0, #"Error preparing statement '%s'", sqlite3_errmsg(db));
else
{
while(sqlite3_step(statement) == SQLITE_ROW)
{
User *currentUser = [[User alloc] init];
[User setPk:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 0)]];
[User setName:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 1)]];
[User setAge:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 2)]];
[userArray currentUser];
[currentUser release];
}
}
sqlite3_finalize(statement);
sqlite3_close(db);
return [NSArray arrayWithArray:userArray];
}
and if you wanted to insert data into it:
+ (void)insertUser:(NSString *)username
{
sqlite3 *db = **However you get your db conn**
sqlite3_stmt *statement = nil;
NSString *fullQuery = [NSString stringWithFormat:#"INSERT INTO User (userName) VALUES (%#);", username];
const char *sql = [fullQuery UTF8String];
sqlite3_prepare_v2(db, sql2, -1, &statement, NULL);
if(sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"User inserted");
}
sqlite3_finalise(statement);
sqlite3_close(db);
}
If you are having trouble getting a database into your application and connecting to it, let me know and I can post some of that code as well.
Hope that helps :)

Resources