I want to insert the data in a SQLite table login when a button is clicked, the problem is that when I click on the register button data is getting stored in variable but not in database table, and When I try to statically pass the value the data will be insert but When i trying to dynamically store data then not work.
Here is my code. Please go through it and help to solve this issue.
NSString *path;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask ,YES);
path = [paths objectAtIndex:0];
dbName = [[NSString alloc] initWithString:[path stringByAppendingPathComponent:#"mnc.sqlite"]];
NSFileManager *fileMgr = [NSFileManager defaultManager];
if([fileMgr fileExistsAtPath:dbName]== NO)
{
const char *dbPath = [dbName UTF8String];
if (sqlite3_open(dbPath,&connectionDB)==SQLITE_OK)
{
char *errMsg;
const char *sql_stmt = " create table if not exists login(user_name text ,password text)";
if (sqlite3_exec(connectionDB,sql_stmt,NULL,NULL,&errMsg))
{
printf("\n fail to create table ");
}
sqlite3_close(connectionDB);
}
else
{
NSLog(#"fail to open create database");
}
}
[fileMgr release];
if(sqlite3_prepare_v2(connectionDB, query ,-1, &statment,NULL) == SQLITE_OK)
{
sqlite3_bind_text(statment,1,"cc", -1,SQLITE_TRANSIENT);
sqlite3_bind_text(statment,2,"sa",-1,SQLITE_TRANSIENT);
NSLog(#"aadd");
}
if (sqlite3_step(statment)== SQLITE_DONE)
{
NSLog(#"This should be real error checking!");
sqlite3_finalize(statment);
}
It is quite complex to work with sqlite, thats why I use fmdb this will simplify the work.
This is an Objective-c wrapper around SQLite
Hope this helps.
Related
Here's the code of a method I used to populate UITableView with the contents of a column in sqlite database. However, this is giving no errors at run-time but still does not give any data in UITableView. If anyone could help, it'll be highly appreciated.
- (void)viewDidLoad{
[super viewDidLoad];
self.title = #"Strings List";
UITableViewCell *cell;
NSString *docsDir;
NSArray *dirPaths;
sqlite3_stmt *statement;
// 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:#"strings.sqlite"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: databasePath ] == NO)
{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString * query =
#"SELECT string FROM strings";
const char * stmt = [query UTF8String];
if (sqlite3_prepare_v2(contactDB, stmt, -1,&statement, NULL)==SQLITE_OK){
if (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *string = [[NSString alloc]initWithUTF8String:(const char*)sqlite3_column_text(statement, 0)];
cell.textLabel.text = string; }
}
else NSLog(#"Failed");
sqlite3_finalize(statement);
}
sqlite3_close(contactDB);
}
}
I recommend you to read through Table View Programming Guide.
Most of the sequence you put in the viewDidLoad normally is placed in
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath;
that pretty complex method u are using, when u have all the delegate methods for table view which is just like putting butter on bread.
Try My Answer from this Link
Let me know if it worked !!!!
Cheers
if You are using simulator for testing purpose then delete your previous build and install app again. It fetch SQL file from document directory. So please try this and let me know. Thanks
Have you check if the problem is with you tableview or database?
Are you able to fetch data from database?Check if you are missing any method to connect sqlite in code.
Working on a simple TimeTracker App. You start a timer, wait a certain time, stop the clock and save spent minutes to a SQLite3 database. All is working as expected, when I tap on save I get a confirmation that record was saved but I can't get the saved entries shown on the console. As seen in the screenshot below I have a show button which should show me all my saved entries in the console including timestamp but nothing happens when I tap the button.
I think the problem is related to the search query but I can't figure our whats wrong.
From my understanding the query is looking for the timestamp (column 0) and the spent minutes (column 1) but it doesn't work, please help.
NSLog(#"Timestamp: %s - Timing: %s", sqlite3_column_text(statement, 0), sqlite3_column_text(statement, 1));
SQLite database is really simple, I only want to save one value > spent minutes.
Maybe the database is not created correctly??
Database Creation:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *docsDir;
NSArray *dirPaths;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
databasePath = [[NSString alloc]initWithString:[docsDir stringByAppendingPathComponent:#"timings.db"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath:databasePath] == NO)
{
const char *dbPath = [databasePath UTF8String];
if (sqlite3_open(dbPath, &timings) == SQLITE_OK)
{
char *errormsg;
const char *sql_stmt =
"CREATE TABLE IF NOT EXISTS TIMINGS(ID INTEGER PRIMARY KEY AUTOINCREMENT, TIME INTEGER)";
if (sqlite3_exec(timings, sql_stmt, NULL, NULL, &errormsg) != SQLITE_OK)
{
self.statusLabel.text = #"Failed to create database";
}
sqlite3_close(timings);
}
else
{
self.statusLabel.text = #"Failed to open/create database.";
}
}
}
Show saved entries on console:
-(IBAction)showButton:(id)sender
{
if (sqlite3_open([databasePath UTF8String], &timings) == SQLITE_OK)
{
NSString *queryStatement = [NSString stringWithFormat:#"SELECT TIMESTAMP, TIME FROM TIMINGS"];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(timings, [queryStatement UTF8String], -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW) {
NSLog(#"Timestamp: %s - Timing: %s", sqlite3_column_text(statement, 0), sqlite3_column_text(statement, 1));
}
sqlite3_finalize(statement);
sqlite3_close(timings);
}
}
}
Put NSLog(#"Error. '%s'", sqlite3_errmsg(database)); after each database operation completed. (ie; after, sqlite3_step, sqlite3_prepare etc). When you get data base, which was created by simulator, from Library/ApplicationSupport ....., you can open that using terminal and see the contents. Or using SQLite Manager plug in of mozilla you can open database and see contents graphically.
Do any rows get returned from your query? Open your sqlite database using a browser (http://sqlitebrowser.sourceforge.net/) and check the data is actually being saved.
Then rerun your sql in the browser to test the query, and finally put a breakpoint on
-(IBAction)showButton:(id)sender and step thru
a friend of mine just realized that I made a big mistake, I totally forgot to CREATE the column 'TIMESTAMP' I'm trying to read out here. If you look at this line: "CREATE TABLE IF NOT EXISTS TIMINGS(ID INTEGER PRIMARY KEY AUTOINCREMENT, TIME INTEGER)"; You see that I have not created the timestamp column. Last but not least is TIMESTAMP a protected keyword in SQL you are not allowed to use. To save a timestamp I just created and renamed the column and now it's working. Thanks for all your help.
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];
}
how to create a sqlite file when the application starts (didFinishLaunchingWithOptions) the test if it already or not exsist otherwise create the file sqlite
Like this... the sqlPath variable is the path to the pre-made sql database on your ressource
- (void) checkAndCreateSQL
{
if (![[NSFileManager defaultManager] fileExistsAtPath:[documentPath stringByAppendingString:#"/database.sql"]]) {
[[NSFileManager defaultManager] createFileAtPath:[documentPath stringByAppendingString:#"/database.sql"]
contents:[NSData dataWithContentsOfFile:sqlPath]
attributes:nil];
}
}
EDIT 1:
You can create the database on your mac using this command line :
sqlite3 database.sql < DATABASE_CREATION.txt
in the DATABASE_CREATION.txt something like this :
CREATE TABLE IF NOT EXISTS `group` (
`id` integer PRIMARY KEY,
`name` text,
`position` integer
);
Then put directly the database.sql file into your project resource. (like an image)
You'd probably want to use the default Core Data libraries instead of manually creating and handling a single sqlite file. Please check the official Apple Core Data Programming Guide. It will automatically handle the creation and update of the inner database in the app.
sqlite3 *reference2Database() {
if (_database == nil) {
// First, test for existence.
NSError *error;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"my.sqlite"];
if ([fileManager fileExistsAtPath:writableDBPath] == NO) {
// Database file doesnt exists. Copy the database at writable path (documents directory).
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"my.sqlite"];
[fileManager removeItemAtPath:writableDBPath error:nil];
BOOL databaseCopied = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!databaseCopied) {
// Handle the error...
}
}else {
// Open the database. The database was prepared outside the application.
if (sqlite3_open([writableDBPath UTF8String], &_database) != SQLITE_OK) {
// Even though the open failed, call close to properly clean up resources.
sqlite3_close(_database);
_database = nil;
// Additional error handling, as appropriate...
}
}
}
return _database;
}
// Sample usage.
-(void) someDatabaseFunction {
sqlite3 *database = reference2Database();
// Do something with "database"...
}
// Close the database. This should be called when the application terminates.
void closeDatabase() {
if (_database == nil) return;
// Close the database.
if (sqlite3_close(_database) != SQLITE_OK) {
// Handle the error...
}
_database = nil;
}
NOTE: At the top of the file, you should have: static sqlite3 *_database = nil;
I use Matteo Bertozzi's SQLite Wrapper to create my sqlite database with the following code:
-(void)checkDatabase
{
if([[NSFileManager defaultManager] fileExistsAtPath:DBPATH] == NO)
{
sqlite = [[Sqlite alloc] init];
if (![sqlite open:DBPATH]) return;
[sqlite executeNonQuery:#"DROP TABLE yourtable"];
[sqlite executeNonQuery:#"CREATE TABLE yourtable (record1 TEXT NOT NULL,
record2 TEXT NOT NULL,
record3 TEXT NOT NULL,
record4 TEXT NOT NULL);"];
NSArray *results = [sqlite executeQuery:#"SELECT * FROM yourtable;"];
for (NSDictionary *dictionary in results) {
for (NSString *key in [dictionary keyEnumerator])
NSLog(#" - %# %#", key, [dictionary objectForKey:key]);
}
[results release];
[sqlite release];
}
}
i have a database that is in the documents directorys of the
Application/iPhoneSimulator/3.2/Applications/etc/Documents
I have this code under my method
databaseName = #"database.sql";
NSArray *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory.NSUserDomainMask,YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
How do i do an insert with a variable/ array .
Something like
"INSERT INTO TABLE (COLUMN) VALUES ('%#'),[appDelegate.variable objectAtIndex:0];
I insist you to go through this question.
First of all copy the database from main bundle to your application's document dir.
You can follow below code to implement it.
NSString *databaseFile=[[NSBundle mainBundle] pathForResource:kDataBaseName ofType:kDataBaseExt];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString *dbPath=[basePath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.%#",kDataBaseName,kDataBaseExt]];
NSFileManager *fm=[NSFileManager defaultManager];
if(![fm fileExistsAtPath:dbPath]){
[fm copyItemAtPath:databaseFile toPath:dbPath error:nil];
}
[fm release];
self.dataBasePath=dbPath;
I am supplying you directly my project code. Please add comment if any doubts.
I have added comments for the explanation.
// function with multiple arguments which is going to be used for inserting into table.
+(void)insertBuilding:(NSString*)BName streetNo:(NSInteger)streetNo streetName:(NSString*)streetName streetDir:(NSString*)streetDir muni:(NSString*)muni province:(NSString*)province bAccess:(NSString*)bAccess bType:(NSString*)bType amnity:(NSString*)amnity latitude:(NSString*)latitude longitude:(NSString*)longitude imageName:(NSString*)imageName {
// application delegate where I have saved my database path.
BuildingLocatorAppDelegate *x=(BuildingLocatorAppDelegate *)[[UIApplication sharedApplication]delegate];
sqlite3 *database; // database pointer
// verifying if database successfully opened from path or not.
// you must open database for executing insert query
// i have supplied database path in argument
// opened database address will be assigned to database pointer.
if(sqlite3_open([[x dataBasePath] UTF8String],&database) == SQLITE_OK) {
// creating a simple insert query string with arguments.
NSString *str=[NSString stringWithFormat:#"insert into buildingDtl(b_name,streetNo,streetName,streetDir,muni,province,b_access,b_type,aminity,latitude,longitude,b_image) values('%#',%i,'%#','%#','%#','%#','%#','%#','%#','%#','%#','%#')",BName,streetNo,streetName,streetDir,muni,province,bAccess,bType,amnity,latitude,longitude,imageName];
// converting query to UTF8string.
const char *sqlStmt=[str UTF8String];
sqlite3_stmt *cmp_sqlStmt;
// preparing for execution of statement.
if(sqlite3_prepare_v2(database, sqlStmt, -1, &cmp_sqlStmt, NULL)==SQLITE_OK) {
int returnValue = sqlite3_prepare_v2(database, sqlStmt, -1, &cmp_sqlStmt, NULL);
((returnValue==SQLITE_OK) ? NSLog(#"Success") : NSLog(#"UnSuccess") );
// if NSLog -> unsuccess - that means - there is some problem with insert query.
sqlite3_step(cmp_sqlStmt);
}
sqlite3_finalize(cmp_sqlStmt);
}
sqlite3_close(database);
// please don't forget to close database.
}
+(NSString *)stringWithFormat:(NSString *)format parameters:...];
NSString sql = [NSString stringWithFormat:#"INSERT INTO table VALUES('%#')", #"Hello, world!"];
sqlite3_....
Use either prepared statements in combination with the bind_*() functions (e.g. bind_text()) or the mprintf() function to insert strings, see this question for details.
To get a raw C-string you can pass to these functions use -UTF8String or -cStringUsingEncoding: on a NSString.