I am facing a problem in Xcode : I tried many weeks to add data into sqlite database and I surf Google for many results but none of them can give a complete and clear tutorial, most of them are using .db but not sqlite, I suspect that sqlite is not able to insert or update, just can read data, or is there any other way to do it?
Please attach the link with tutorial in the answer if you guys have any. Thank you
I suspect that sqlite is not able to insert or update, just can read
data
Of course you can insert data in SQLite. This is a database just as other ones, just a little lighter and embedded in the same process as your application instead of a different one as is usually the case (this both means SQLite can't answer to more than one client, and that you don't have to install anything on the computer apart your application).
Here's the INSERT documentation : http://www.sqlite.org/lang_insert.html
And here's a tutorial among many other ones : http://www.techotopia.com/index.php/An_Example_SQLite_based_iPhone_Application
(in fact I just googled for "sqlite xcode insert", I didn't knew this tutorial before)
Sunny it's been two days that im working to find out how to insert data to sqlite on iOS. First thing you should do is to tell SQLite to where save the data. By default if you run ur app on ur phone it will put the sqlite file in a readonly root. to solve it you should do this :
-(NSString *)GetDocumentDirectory{
fileMgr = [NSFileManager defaultManager];
homeDir = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
return homeDir;
}
which fileMgr is NSFileManager and homeDir is NSString next when you wanna insert yout data, first u should give ur SQLite root to it, which is the first line, and it checks if sqlite3_open and will start to insert your data:
-(void)InsertRecords:(NSMutableString *)myData{
NSString *dbPath = [self.GetDocumentDirectory stringByAppendingPathComponent:#"YOUR SQLITE FILE NAME.sqlite"];
const char *dbpath = [dbPath UTF8String];
sqlite3 *contactDB;
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO tableName (tableColumn) VALUES (\"%#\")", myData];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
sqlite3_bind_text(statement, 1, [myData UTF8String], -1, SQLITE_TRANSIENT);
}
else {
NSLog(#"error");
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
}
hope it helps :)
Related
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);
}
I want to saving entire array into SQLite. I am getting an array having many other arrays in that.
Is it possible ? If so please let tell me.
I have tried this - But "ERROR TO SAVE DATA"
NSArray *array = [dict objectForKey:#"events_data"];
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO CONTACTS (event_array) VALUES (\"%#\")", array];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"DATA SAVED TO DB");
} else {
NSLog(#"ERROR TO SAVE DATA");
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
If it is possible please tell me how to retrieve it also.
You need not use sqlite directly in iOS. Indeed, you should wrap the persistent object in an NSManagedObject. To retrieve the object, simply create an NSFetchRequest, set its entity, and have the context execute it, which will return a standard NSArray of NSManagedObjects, which you can iterate over. Hope this helped, please leave a comment if you have further issues.
i have a UIWebView over a UIScrollView. i use some js files to draw some graph like line that will update when the time value changes.
The Problem
Im not able to scroll when the points goes out of the screen.
I'm new to IOS Development so please help me.
thank in advance
After Completion the QUERY, You need to close transaction.
Here's the sample code for you...
// 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: #"YOURDB.db"]];
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &DB) == SQLITE_OK)
{
NSString *query=[NSString stringWithFormat:#"insert into studentDetails (NAME,Email,adressL1,adressL2,phone,landline,department,DoB,fatherName) values (\"%#\",\"%#\",\"%#\",\"%#\",\"%#\",\"%#\",\"%#\",\"%#\",\"%#\")",
name.text,
email.text,
addressLine1.text,
addressLine2.text,
phone.text,
Landline.text,
Department.text,
DoB.text,
fname.text];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(YOURDB, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#" Successfully added");
} else {
NSLog(#" Failed added");
NSLog(#"Error %s",sqlite3_errmsg(ExplorejaipurDB));
}
}
sqlite3_finalize(statement);
sqlite3_close(YOURDB);
}
The database could be locked because of several reasons:
Multiple queries running
multiple threads running
opened the database multiple times
Check your code and see if you have closed the connections to the database sqlite3_close(). A good idea would also be to use sqlite3_finalize() after each SQL statement when you are done with it.
So try try to match all your sqlite3_open() with sqlite3_close() and sqlite3_prepare() (if you are using it) with sqlite3_finalize()
I've been developing an enterprise iPad app for a while now. Since the app development started almost 2 years ago, I needed to compile my own version SQLite from source, since the default SQLite library (the sqlite3.dylib) didn't have FTS enabled by default.
Ok, everything was working fine since then. I've been always using GCC as the project compiler.
The thing is that now I'm trying to convert my whole project to use ARC. To do so, I need to use Apple's LLVM compiler.
That's it. When I change the compiler (from GCC 4.2 to LLVM 3.1 or 4.0, without converting to ARC, and without changing anything else), my app builds fine, everything runs ok, except by my FTS queries, which don't work at all Even the simplest ones. They run and return always with no result (with a SQLITE_OK code, though).
I'm stuck here. I have already talked to an Apple engineer at WWDC'12 but we couldn't find any solution.
I guarantee that it is unlikely to be a malformed query or something like that since the app is working fine with GCC. Also, I'm able to run the queries on the Terminal version of SQLite (or using other apps, like Base)
I was also using an old version of SQLite, but I've updated to the most recent version to date (3.7.13). Everything stays the same. I've also noticed that, now (I don't know since when) the sqlite that comes with the mac supports FTS (!!!) and I was able to remove my own version and use Apple's one. The thing is, I'm having the exact same behavior.
I've been looking for a solution, but couldn't find one. I've found some bugs related to armv6 and compiler optimisations (which can be fixed by using the -mno-thumb flag), but it's not my case. I also noticed that when I analyse my custom sqlite files using Clang it points out many, many "potencial errors".
I have this non-skeptical view and I (still) don't believe that it's a LLVM or SQLite bug. I prefer to check everything that is possible before addressing them a bug. Maybe I'm forgetting to configure something or need to add some flag to the compiler that I'm not doing.
I appreciate any help. Again, the bug only occurs on projects compiled with LLVM (even with the default sqlite). If I run the same queries on the Terminal version of sqlite3, everything goes fine.
UPDATE:
This code works. It creates a new database, a new virtual table using fts, insert a couple of items and then execute the select. I'll try more complex queries later, but, for now, it seems that the issue with my app might be, as expected, a bug in my code.
NSArray *dirPaths = dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
sqlite3 *database;
// Build the path to the database file
NSString *databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: #"test.db"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
NSError *error = nil;
[filemgr removeItemAtPath:databasePath error:&error];
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt = "CREATE VIRTUAL TABLE IF NOT EXISTS pages USING fts3(title, body);";
if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
NSLog(#"Failed to create table");
} else {
sql_stmt = "INSERT INTO pages(docid, title, body) VALUES(53, 'Home Page', 'SQLite is a software...');";
if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
NSLog(#"Failed to insert");
}
sql_stmt = "INSERT INTO pages(title, body) VALUES('Download', 'All SQLite source code...');";
if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
NSLog(#"Failed to insert");
}
}
sqlite3_stmt *statement;
const char *query_stmt = "select * from pages where body match 'soft*';";
if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
if (sqlite3_step(statement) == SQLITE_ROW)
{
NSLog(#"%# - %#", [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)],
[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)]);
} else {
NSLog(#"no results");
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
} else {
NSLog(#"Failed to open/create database");
}
After all, I've found the bug. It was in my code. In summary, that what I've found out:
If I have something like that (I know it's weird/wrong):
int a = 0;
a = a++;
NSLog(#"%d", a);
the logged value will be 1 if this code is compiled with gcc and 0 if compiled with llvm.
I don't know why, but that's another question :)
I am currently trying to simply insert a new row into my SQLite3 database on my iPad. I have done it multiple times before in other apps and just copied the code. The copied SELECT queries work fine, but if I try to INSERT, it fails at == SQLITE_DONE
This is how I try to insert into the database:
NSString *databaseName = #"Waypoints.sql";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
NSString *databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
sqlite3 *database;
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
NSString *statement = [NSString stringWithFormat:
#"INSERT INTO Waypoints (id, name, alt, ias, temp, tas, wd, ws, gs, mt, mh, dist, time, fuel, fuelrate) VALUES (%d,'New...','','','','','','','','','','','','','');", [self numberOfWaypoints]];
NSLog(#"Statement: %#", statement);
const char *sqlStatement = [statement cStringUsingEncoding:NSASCIIStringEncoding];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK)
{
if(sqlite3_step(compiledStatement) == SQLITE_DONE)
NSLog(#"DATABASE: Adding: Success");
else
NSLog(#"DATABASE: Adding: Failed");
}
else
NSLog(#"Error. Could not add Waypoint.");
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
If I run this code on the press of a button, it outputs DATABASE: Adding: Failed in the console.
The NSLogged statement looks like this:
INSERT INTO Waypoints (id, name, alt, ias, temp, tas, wd, ws, gs, mt, mh, dist, time, fuel, fuelrate) VALUES (2,'New...','','','','','','','','','','','','','');
Which works perfectly fine if I paste it in the terminal (connected to same database file).
This brings me to the conclusion: what could be causing this problem?
I thought of maybe write permissions to the file. Could be it, but it's not in the bundle but already copied to the documents folder on the device.
Please help to how I can get this to work?
Try using NSUTF8StringEncoding for your cStringUsingEncoding or printing
NSLog(#"%#", [NSString stringWithUTF8String:(char*)sqlite3_errmsg(database)]);
Glad to see you could find your error with this.
By following the tip from #IgnacioInglese by printing out the error with NSLog(#"%#", [NSString stringWithUTF8String:(char*)sqlite3_errmsg(database)]); I found that the database is locked.
I found that I made a rookie-error by return a value in a method before closing the database. Fixing that solved my problem.