Qt & SqlLite inset data to database - c++

I'm doing Qt application. I am trying save data in database. I have got problem because I have got connection with sqlite3, but when i want insert data QT says that QSqlQuery::prepare: database not open.
void DodajKontakt::on_btn_add_clicked()
{
QSqlDatabase db_kon = QSqlDatabase::addDatabase("QSQLITE");
db_kon.setDatabaseName("C:/Users/Lukasz/Desktop/qt master/organizator/baza_kontakty.db");
QSqlQuery query;
query.prepare( "CREATE TABLE kontakty(ids INTEGER PRIMARY KEY, name TEXT, surname TEXT, company TEXT, email TEXT, phone TEXT");
if(!db_kon.open())
{
qDebug() << "error:" << db_kon.lastError().text();
}
else
qDebug() << "Succsess";
if(ui->lineEdit_name->text().isEmpty() && ui->lineEdit_surname->text().isEmpty()
&& ui->lineEdit_email->text().isEmpty() && ui->lineEdit_phone->text().isEmpty()
&& ui->lineEdit_company->text().isEmpty())
{
QMessageBox::critical(this, tr("Error"), tr("Uzupełnij wszystkie pola!"));
}
else
{
QString name, surname, company, email, phone;
name = ui ->lineEdit_name->text();
surname = ui ->lineEdit_surname->text();
company = ui ->lineEdit_company->text();
email = ui ->lineEdit_email->text();
phone = ui ->lineEdit_phone->text();
query.prepare("INSERT INTO kontakty(name,surname,company.email.phone) VALUES('"+name+"','"+surname+"','"+company+"','"+email+"','"+phone+"')");
if(query.exec())
QMessageBox::information(this, tr("Sukces"),tr("Dodano nowy kontakt"));
else
QMessageBox::information(this, tr("Error"),tr("Nie udalo sie dodac nowego kontaktu"));
}
}
It is results.
QSqlQuery::prepare: database not open
Succsess
Can someone help me?

Your main error is that you are trying to create the table before opening the database, that's why you get that error.
Another error that is repetitive is that even when a problem happens your logic will still want to insert data, what you should do is print an error message and return.
You also have errors in the query, for example in the creation of the table you need to close with a parenthesis.
And finally do not build the query directly if you are going to use data provided by the user since your system will be prone to SQL Injection, it is appropriate to use the bind-value.
QSqlDatabase db_kon = QSqlDatabase::addDatabase("QSQLITE");
db_kon.setDatabaseName("C:/Users/Lukasz/Desktop/qt master/organizator/baza_kontakty.db");
if(!db_kon.open()){
qDebug() << "error:" << db_kon.lastError().text();
return;
}
qDebug() << "Success";
QSqlQuery query;
query.prepare( "CREATE TABLE kontakty(ids INTEGER PRIMARY KEY, name TEXT, surname TEXT, company TEXT, email TEXT, phone TEXT)");
if(!query.exec()){
qDebug()<<"error:" << query.lastError().text();
return;
}
QString name = ui->lineEdit_name->text();
QString surname = ui->lineEdit_surname->text();
QString company = ui->lineEdit_company->text();
QString email = ui->lineEdit_email->text();
QString phone = ui->lineEdit_phone->text();
if(name.isEmpty() &&
surname.isEmpty() &&
email.isEmpty() &&
phone.isEmpty() &&
company.isEmpty())
{
QMessageBox::critical(this, tr("Error"), tr("Complete all fields!"));
return;
}
query.prepare("INSERT INTO kontakty(name, surname, company, email, phone) VALUES(?, ?, ?, ?, ?)");
query.addBindValue(name);
query.addBindValue(surname);
query.addBindValue(company);
query.addBindValue(email);
query.addBindValue(phone);
if(query.exec())
QMessageBox::information(this, tr("Success"),tr(" A new contact has been added"));
else
QMessageBox::information(this, tr("Error"),tr("It was not possible to add a new contact"));

Related

Query in QT doesn't get any data

This is rows in my table.
With this code, I get "in" in console.
QSqlQuery qry;
qry.prepare("SELECT * FROM user");
qry.exec();
if(qry.size() > 0)
qInfo() << "in";
else
qInfo() << "error";
But with this code, I get "error".
QSqlQuery qry;
qry.prepare("SELECT age FROM user");
qry.exec();
if(qry.size() > 0)
qInfo() << "in";
else
qInfo() << "error";
Try
QSqlQuery qry;
qry.prepare("SELECT age FROM \"user\"");
qry.exec();
The problem is with the table name. Since user is a reserved word, some tools (PgAdmin) automatically add double quotes to the name "user" and you have to use double quotes when applying to the table. Unfortunately user in Postgres is a function (equivalent to current_user) hence the first query returns a row without error.
The best solution is to rename the table and not use reserved words as Postgres identifiers (the name of a table, column, view, function, etc).
QSqlQuery qry;
qry.prepare("SELECT age FROM user");
if(qry.exec()) {
while(qry.next()) {
qInfo()<<"in";
}
} else {
qInfo()<<"error";
}

How to fetch a row in an sqlite database in qt using cpp

How can I access a single row in sqlite database and return the data in a list. I have tried this
QList<QVariant> DBManager::getUserData(QString usrNam, QString psswrd)
{
QSqlQuery query;
query.prepare("SELECT First_Name, Last_Name, Email, Username, Password"
" FROM Users WHERE Username = :usrNam AND Password = :psswrd");
query.bindValue(":usrNam", usrNam);
query.bindValue(":psswrd", psswrd);
query.exec();
QSqlRecord rec = query.record();
QList<QVariant> list;
int idCol = rec.indexOf("First_Name");
if(idCol == -1){
qDebug() << "Db is empty";
}else{
while(query.next()){
list.append(query.value(idCol));
list.append(query.value("Last_Name"));
list.append(query.value("Email"));
list.append(query.value("Username"));
list.append(query.value("Password"));
}
}
return list;
}
But the program crashes. Do not fully understand the use of a record here got it from the documentation. I do know that it provides details about the fields but I want the data in the fields of a particular row.
please help
thank you
If you want to access a single row, you don't need to use QSqlRecord. Just use QSqlQuery::first instead. Example:
QList<QVariant> DBManager::getUserData(QString usrNam, QString psswrd)
{
QSqlQuery query;
query.prepare("SELECT First_Name, Last_Name, Email, Username, Password"
" FROM Users WHERE Username = :usrNam AND Password = :psswrd");
query.bindValue(":usrNam", usrNam);
query.bindValue(":psswrd", psswrd);
QList<QVariant> list;
if (!query.exec()) {
qDebug() << "Query failed!";
} else {
if (query.first()) { // get the first record in the result,
list.append(query.value("First_Name"));
list.append(query.value("Last_Name"));
list.append(query.value("Email"));
list.append(query.value("Username"));
list.append(query.value("Password"));
} else {
qDebug () << "Data not found";
}
}
return list;
}
Though, I would recommend using a data structure for Users instead of using QVariant. Something like:
struct User {
QString firstName;
QString lastName;
QString email;
//...
};
And then use a QVector(instead of QList) of type User:
QVector<User> list;
QVector store its data in contiguous memory, hence it is faster than using a QList.

error in using quotation in QString

I am trying to get an input(username) from user and search for that in my sqlite to find it's password for recovery.
QString username = QInputDialog::getText(this, "Password Recovery", "please enter ur Username here:", QLineEdit::Normal,"myUsername", Q_NULLPTR, Qt::WindowFlags(), Qt::ImhNone);
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("/home/arian_press/Qt5.7.0/Projects/APQt_chat/apt.db");
if (db.open())
{
QSqlQuery query;
QString qstr="SELECT username,password,support_email FROM users WHERE username=\""+username+"\";" ;
}
if (query.exec(qstr))
{
QString password=query.value(1).toString();
QString pass = "ur password is:" + password;
Smtp *newMail = new Smtp("arian.press2015#gmail.com",query.value(2).toString()," Your Password",pass);
delete newMail;
QMessageBox messageBox;
messageBox.critical(0,"Error","ur credentials are wrong!");
messageBox.setFixedSize(500,200);
}
else
{
qDebug() << query.lastError().text();
}
db.close();
}
else
{
qDebug() << "Failed to connect to database.";
}
but when i run the program, It doesn't return anything while when I open SQLite file in terminal I can get results.
**update:
U didn't mean what I said. the problem is that I can't use \" in the above code because for the query i need: SELECT username,password,support_email FROM users WHERE username="myusername"
but when I use above code it queries for SELECT username,password,support_email FROM users WHERE username=\"myusername\"
so I can't have any results.so now how can I bring quotation marks in QString?
Never concatenate user input with your queries: that makes you vulnerable to SQL injection. Use prepared statements!
Furthermore, you must use single quotation marks '.
QSqlQuery query;
query.prepare("SELECT username,password,support_email "
"FROM users "
"WHERE username=':username';");
query.bindValue(":username", username);
The } following your QString qstr = ... should be removed.
SQL uses single quotes for strings. Try:
QString qstr="SELECT username,password,support_email FROM users WHERE username='"+username+"';";
There is also a more elegant way:
query.prepare("SELECT username,password,support_email FROM users WHERE username = :username;");
query.bindValue(":username", username);
query.exec();

QSqlQuery not working

So I have this problem basically, I cannot exec my QsqlQuery.
I am connected to a SQLite database and I have checked that it is really connected.
QString databaseName = QFileDialog::getOpenFileName(this,tr("Open database"),
"",
tr("Databáze (*.db)"));
mydb = QSqlDatabase::addDatabase("QSQLITE");
mydb.setDatabaseName("databaseName");
if (!mydb.open()) {
ui->statusBar->showMessage("Databáze nebyla připojena!",2000);
databaseCheck = false;
}
else if (mydb.open()) {
ui->statusBar->showMessage("Databáze byla úspěšně připojena.",2000);
databaseCheck = true;
}
This is part of the code from the Mainwindow.cpp which sets up the database connection. The database is declared in mainwindow.h, all is functioning in this part.
Here I got a form which returns some data about an employee that I want to create in the database. databaseCheck is a bool that tells me if the database is connected properly. And those variables name, surname etc. in this case are declared in mainwindow.h as QString.
if (databaseCheck) {
form = new Form(this);
form->setWindowTitle("Formulář informací o zaměstnanci.");
form->exec();
name = form->getName();
surname = form->getSurname();
id = form->getId();
date = form->getDate();
telephone = form->getTelephone();
salary = form->getSalary();
state = form->getState();
QSqlQuery query(mydb);
query.prepare("INSERT INTO employees (jmeno,prijmeni,datumnarozeni,telefon,plat,stav) "
"VALUES (:name, :surname, :date, :telephone, :salary , :state)");
query.bindValue(":name", name);
query.bindValue(":forename", surname);
query.bindValue(":date", date );
query.bindValue(":telephone", telephone);
query.bindValue(":salary", salary);
query.bindValue(":state", state );
query.exec();
}
After I fill up the form with some data about the employee and accept it, it does not send anything to the database. I am checking the database with DB Browser for SQLite and the table employees is totally empty. Can anybody help me?
Your SQL seems correct, the best approach is probably to write something like this.
if (!query.exec())
qDebug() << query.lastError();

Qt Sqlite table column appears to be gone

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(":temp:");
if (!db.open()) {
qDebug() << "Database open error." << db.lastError();
return;
}
QSqlQuery query(db);
query.prepare("create table if not exists dew (id int, title varchar(255) not null)");
if (!query.exec()) {
qDebug() << "Query exec error. " << query.lastError();
return;
}
qDebug() << "Insert query exec OK";
if (!query.exec("insert into dew(id, title) values (1, 'hello')")) qDebug() << query.lastError();
Shows the output as
Insert query exec OK
QSqlError(1, "Unable to execute statement", "table dew has no column named id")
Insertion finished.
Table creation seems to be OK. But where is id field? I'm confused with this code. I test query.record().contains("id"); and it is false
":temp:" is not a valid name for a temporary database, this creates a regular database on disk which stays after the database connection is closed.
To create a temporary or an in-memory sqlite database, that won't be saved to a file, you need to pass respectively an empty string (*) or the special string ":memory:" as the database name.
http://www.sqlite.org/inmemorydb.html
Qt doesn't allow an empty QString as the database name, but a QString starting with a '\0' should work: db.setDatabaseName(QChar(0));