I can insert my data, but I can't show them in my table view. I tried [tableview reloadData]
but with no success
Here is my code:
-(void)gButtonTapped:(id)sender
{
NSLog(#"right nav bar button is hit%# ",storePaths);
//[self readAnimalsFromDatabase2];
appDelegate = (DatabaseTestAppDelegate *)[[UIApplication sharedApplication] delegate];
sqlite3 *database;
sqlite3_stmt *compiled_statement1;
if(sqlite3_open([storePaths UTF8String], &database) == SQLITE_OK) {
//const char *sqlStatement =
NSString *newQuery = [NSString stringWithFormat:#"insert into cat_tbl (cat_id,names,imgs) values ('12','test1','r.png')"];
// NSString *newQuery = [NSString stringWithFormat:#"select * from list_tbl"];
const char *sql = [newQuery cStringUsingEncoding:NSASCIIStringEncoding];
NSLog(#"update query is %#",newQuery);
if(sqlite3_prepare_v2(database, sql, -1, &compiled_statement1, NULL) == SQLITE_OK)
{
int result = sqlite3_step(compiled_statement1);
sqlite3_reset(compiled_statement1);
NSLog(#"result %d", result);
if(result != SQLITE_ERROR) {
int lastInsertId = sqlite3_last_insert_rowid(database);
NSLog(#"x %d", lastInsertId);
}
}
}
sqlite3_finalize(compiled_statement1);
sqlite3_close(database);
[tableView reloadData];// this is also not working
}
you need to update your table view data source by calling select query or update your data source by adding new values as they got inserted successfully in the data base.
Related
This is the code I use AFSQLManager in here any help how to solve this:
this is where I get the Thread and note when I do not comment the if condition it dose not inter the inside the if condition I also try to NSLog the statement before inter the if condition and give me the same thread any help
-(void)performQuery:(NSString *)query withBlock:(completionBlock)completion {
NSString *fixedQuery = [query stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSLog(#"HERE 100d : %#",fixedQuery);
sqlite3_stmt *statement;
// if (sqlite3_prepare_v2(_database, [fixedQuery UTF8String], -1, &statement, nil) == SQLITE_OK) {
// NSLog(#"HERE 100a : %#", statement);
while (sqlite3_step(statement) == SQLITE_ROW) { //HERE WHERE I GOT THE THREAD.
NSMutableArray *row = [NSMutableArray array];
NSLog(#"HERE 100b");
for (int i = 0; i < sqlite3_column_count(statement); i++) {
NSLog(#"HERE 100c");
[row addObject:((char *)sqlite3_column_text(statement, i)) ? [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, i)] : [NSNull null]];
}
if (completion) {
NSLog(#"HERE 100e");
completion(row, nil, NO);
}
}
NSLog(#"HERE 100f");
sqlite3_finalize(statement);
completion(nil, nil, YES);
NSLog(#"HERE 100g");
// }
NSLog(#"HERE 100h");
}
sqlite3_step() crashes because statement never got initialized because you commented out the call to sqlite3_prepare_v2().
If a function such as sqlite3_prepare_v2() fails, you can call sqlite3_errmsg() to get a useful error message.
In my app, I trying to get the single id from data base using the query:
SELECT _id FROM rules where codigo_rest = 2345
I am passing that query to the following function:
-(NSString *)selectIDrest:(NSString *)query{
NSString * retval;
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, nil)
== SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
int uniqueId = sqlite3_column_int(statement, 0);
NSLog(#"int %i",uniqueId);
retval = [NSString stringWithFormat:#"%d",uniqueId];
}
sqlite3_finalize(statement);
}
NSLog(#"%#",retval);
return retval;
}
but the retval is alway 0., while table content id is different (1,2,3,4 ...etc).
By NSlogs, I realize that while (sqlite3_step(statement) == SQLITE_ROW) is never executed.
What is my fault?
You are never executing the query, you only prepared it to be executed. You need to call sqllite3_step to read the first row. The you can call sqllit3_column_int.
You can see how to call it in this tutorial: http://www.raywenderlich.com/913/sqlite-tutorial-for-ios-making-our-app
I am trying to run a query on my database in xcode, and it keeps returning 0, even though there are 5 entries. The code to call the database is shown below:
-(int)CountWins
{
int count = 0;
if (sqlite3_open([[self filepath] UTF8String], &_db) == SQLITE_OK) {
const char* query1= "SELECT COUNT(*) FROM Wins WHERE (Action LIKE 'Win');";
sqlite3_stmt *statement;
if( sqlite3_prepare_v2(_db, query1, -1, &statement, NULL) == SQLITE_OK )
{
//Loop through all the returned rows (should be just one)
while( sqlite3_step(statement) == SQLITE_ROW )
{
count = sqlite3_column_int(statement, 0);
}
}
else
{
NSLog( #"Failed from sqlite3_prepare_v2. Error is: %s", sqlite3_errmsg(_db) );
}
// Finalize and close database.
sqlite3_finalize(statement);
//sqlite3_close(articlesDB);
}
[self closeDB];
return count;
}
Basically when the user Wins a game, Win is stored in the action in the database with a timestamp. All i need to know is why my query isnt working, if i do a simple count i get the right number of rows.
Here is my code that inserts the win to the database:
-(void) addwin
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
NSDate *TimestampVal = [NSDate date];
NSString *actionVal = [NSString stringWithFormat:#"Win"];
NSString *sqlstr = [NSString stringWithFormat:#"INSERT INTO 'Wins' ('Timestamp','Action') VALUES (?,?);"];
sqlite3_stmt *statement;
const char *str = [sqlstr UTF8String];
if (sqlite3_prepare_v2(db, str, -1, &statement, NULL) == SQLITE_OK) {
sqlite3_bind_text(statement, 1, [ [dateFormatter stringFromDate:TimestampVal] UTF8String],-1, NULL);
sqlite3_bind_text(statement, 1, [actionVal UTF8String],-1, NULL);
}
if (sqlite3_step(statement) != SQLITE_DONE){
NSAssert(0,#"Error Updating Table.");
}
sqlite3_finalize(statement);
}
I have also tried to store this query as a string and convert to UTF8String, however that doesnt seem to matter as more simple queries still work.
Any help would be great, thanks.
Cheers
I get it:
SELECT COUNT(*) FROM Wins WHERE (Action LIKE 'Win')
is actually same as SELECT COUNT(*) FROM Wins WHERE Action='Win'.
If your criteria is "contain word win", then
SELECT COUNT(*) FROM Wins WHERE Action LIKE '%Win%'
is what you are looking for!
I'm working on an iOS application and I have some issues since migrating to Xcode 5 and IOS7.
I am unable to write into database when testing on ios7 device.
In simulator works fine (iOS 7) . On iOS 6 devices works fine.
Here is my code for writing into sqlite3 database.
After that I am reading from same database but the values are not change.
Tested on multiple devices.
Thanks in advance.
sqlite3 *db9;
#try {
NSFileManager *fileMgr9 = [NSFileManager defaultManager];
NSString *dbPath9 = [[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:#"db.sqlite3"];
BOOL success9 = [fileMgr9 fileExistsAtPath:dbPath9];
if (!success9) {
NSLog(#"Cannot locate database file '%#'.", dbPath9);
}
else NSLog(#"Database file located at: '%#'.", dbPath9);
if (!(sqlite3_open([dbPath9 UTF8String], &db9) == SQLITE_OK)) {
NSLog(#"An error has occured");
}
NSString *strSQL9 = [NSString stringWithFormat:#"UPDATE teste SET scor = ?, timp = ? WHERE id = ?"];
const char *sql9 = [strSQL9 UTF8String];
sqlite3_stmt *sqlStatement9;
if (sqlite3_prepare(db9, sql9, -1, &sqlStatement9, NULL) != SQLITE_OK) {
NSLog(#"Problem with prepare statement");
}else
{
NSLog(#"middle of it - scrie");
if (scordb1 == 0) {
sqlite3_bind_int(sqlStatement9, 1, scorTestTotal);
}else
sqlite3_bind_int(sqlStatement9, 1, ((scorTestTotal+scordb1)/2));
sqlite3_bind_int(sqlStatement9, 2, timeInterval);
sqlite3_bind_int(sqlStatement9, 3, vasile);
sqlite3_step(sqlStatement9);
int success = sqlite3_step(sqlStatement9);
sqlite3_reset(sqlStatement9);
if (success == SQLITE_ERROR){ NSLog(#"error write");}
else {NSLog(#"success write");}
}
sqlite3_finalize(sqlStatement9);
sqlite3_close(db9);
NSLog(#"Close db SCRIE db9");
}
#catch (NSException *exception) {
NSLog(#"An exception occured: %#", [exception reason]);
}
What i want is that if i enter an ID in the textbox and then press enter,then if the ID is present ,then it gets displayed on the table the valuesof the table are inserted with the help of map in another window from which this window Box1 is opened as map.So as far as i have an idea,we have to run find command of map and then using if loop if that entered value in textbox is presentthen will display it in the same way as dummy data is displayed.
code used
Box1::Box1(QWidget *parent)
:QDialog(parent)
{
searchgroup = new QGroupBox(tr("Data Search"));
QHBoxLayout *layout2 = new QHBoxLayout;
text = new QLineEdit(this);
searchh = new QLabel(tr("&Enter ID:"));
searchh->setBuddy(text);
layout2->addWidget(searchh);
layout2->addWidget(text);
searchgroup->setLayout(layout2);
tableegroup = new QGroupBox(tr("Searched Data"));
QVBoxLayout *layout1 = new QVBoxLayout;
tablee = new QTableView(this);
mode1 = new QStandardItemModel(1,2,this);
mode1->setHorizontalHeaderItem(0, new QStandardItem(QString("ID")));
mode1->setHorizontalHeaderItem(1, new QStandardItem(QString("DATA")));
map<int,QString>::iterator itt;
itt=dataa.begin();
for (int colu = 0; colu < 2; colu++)
{
item1 = new QStandardItem();
if (colu == 0)
{
item1->setData(((*itt).first), Qt::DisplayRole);
mode1->setItem(0,0,item1);
} else
{
item1->setData(((*itt).second), Qt::DisplayRole);
mode1->setItem(0,1,item1);
}
}
tablee->setModel(mode1);
layout1->addWidget(tablee);
tableegroup->setLayout(layout1);
QVBoxLayout *mainlayout1 = new QVBoxLayout;
//mainlayout1->addWidget(menubarr);
mainlayout1->addWidget(searchgroup);
mainlayout1->addWidget(tableegroup);
setLayout(mainlayout1);
}
Thanks for any help in advance
EDIT
what i want
void Box1::textReturn()
{
bool ok;
int id = text->text().toInt(&ok);
// map<int,QString>::iterator itt;
if (ok && dataa.contains(id))
{
// add row (id, data[id] to table
}
else
{
QMessageBox msgbox = new QMessagebox();
msgbox->setWindowTitle("Alert");
msgbox->setText("No such ID present!");
msgbox->show();
}
}
EDIT2
void Box1::textReturn()
{
int id = (text->text()).toInt();
map<int,QString>::iterator itt;
itt = dataa.find(id);
if(itt != dataa.end()) //returns 1 if we found something
{
QList<QStandardItem *> items;
items << new QStandardItem(QString("%1").arg(id));
items << new QStandardItem((*itt).second);
mode1->appendRow(items);
tablee->update();
}
else
{
QMessageBox *msgbox = new QMessageBox();
msgbox->setWindowTitle("Alert");
msgbox->setText("INVALID ID ENTERED");
msgbox->show();
}
}
As #KCiebiera said, you have to do this connection
connect(text, SIGNAL(returnPressed()), this, SLOT(textReturnPressed());
Then you need to find your key in the table using
QList<QStandardItem *> QStandardItemModel::findItems ( const QString & text,
Qt::MatchFlags flags = Qt::MatchExactly, int column = 0 )
As you have map, so elements shouldn't repeat, your QList should be NULL or contains just one element. When u'll get your element (as QStandardItem) you just need to invoke
tablee->showColumn ( int column )
tablee->showRow ( int row )
Where your column will be QStandarItem->column() and row QStandardItem->row();
EDIT
void Box1::textReturnPressed()
{
int id = (test->text()).toInt();
map<int, string>::iterator it;
it = dataa.find(id);
if(it != dataa.end()) //we found something
{
QList<QStandardItem *> items;
items << new QStandardItem(QString("%1").arg(id));
items << new QStandardItem((*it).second);
mode1->appendRow(items);
}
else
QMessageBox::information(this, "Info", "ID not found!", QMessageBox::ok);
}
Something like this;
As far as I understand your question. You need to create a new slot in the Box1 class. Let's call it textReturnPressed(). Then you have to connect it to returnPressed() signal from text
connect(text, SIGNAL(returnPressed()), this, SLOT(textReturnPressed());
and here is textReturnPressed (I hope it compiles)
void textReturnPressed()
{
bool ok;
int id = text->text().toInt(&ok);
if (ok && dataa.count(id) > 0) {
QList<QStandardItem *> items;
items << new QStandardItem(QString("%1").arg(id));
items << new QStandardItem(dataa[id]);
mode1.appendRow(items);
}
}
You don't need an iterator to check if an item is in the map. Just call map.count() function.