QSqlQuery with back slash - c++

I'm trying to retrieve the users from the database their names are 'DOMAIN\name'.
I've checked the query in sql console, simple select like :
select * from users where name='DOMAIN\\name'
it returns correct row if the name in the database looks like 'DOMAIN\user' (single back slash).
however QSqlQuery returns empty :
The code something like:
const QString command = QStringLiteral("select * "
"from %1 where name = '%2'")
.arg(Constants::kUsersTableName).arg(userId);
qCDebug() << "Query:" << command;
QSqlDatabase db = QSqlDatabase::database(m_connection, false);
QSqlQuery query(db);
if (!query.prepare(command) || !query.exec()) {
...
log :
Query: "select * from users where name = 'DOMAIN\\name'"
any idea why QSqlQuery returns empty at the same time when database console return valid record for the user.
dbms: MySQL

MySQL uses \ as its escape character therefore the correct query string you have to escape the slash twice, once for c++ and once for mysql:
"select * from users where name='DOMAIN\\\\name'"
The simpler solution is to use prepared statements and placeholders correctly which as a very important bonus will protect your code from SQLI.
Note that field and table names aren't allowed to be placeholders by most if not all database engines so you will still need to build that part of your string by hand:
const QString usernamePlaceholder = ":username"
const QString command = QStringLiteral("select * "
"from %1 where name = %2")
.arg(Constants::kUsersTableName).arg(usernamePlaceholder);
QSqlDatabase db = QSqlDatabase::database(m_connection, false);
QSqlQuery query(db);
if (!query.prepare(command)) {
qCDebug() << query.lastError();
return;
}
query.bindValue(usernamePlaceholder, userId);
if (!query.exec()) {
qCDebug() << query.lastError();
return;
}
bindValue will take care of whatever quoting and escaping is required for your values.

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";
}

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();

C++ QT: QSqlQuery::prepare: database not open

Sorry in advance for any apparent overlap of questions, but I have searched what feels like every possible question on this site for an answer to my problem and none of them have worked. The main issue is that I cannot seem to open my SQLITE3 database in order to search it and display to a QTableView. My code is below:
void MainWindow::on_searchBButton_clicked() {
qDebug() << QSqlDatabase::drivers();
//Setup the search query and open database
//toolboxData = QSqlDatabase::addDatabase("QSQLITE");
//toolboxData.setDatabaseName(":/Resources/Resources/ToolSearch.db");
QString searchStr;
searchStr = ui->basicSearchInput->text();
//Filter out any hyphens
for (int i = 0; i < searchStr.length(); ++i) {
if (searchStr[i] == QLatin1Char('-')) searchStr[i] = QLatin1Char(' ');
}
//Do the actual searching now
QString sQry;
QSqlQueryModel *model = new QSqlQueryModel();
QSqlDatabase toolboxDb = QSqlDatabase::addDatabase("QSQLITE");
//toolboxDb.setDatabaseName(":/Resources/Resources/ToolSearch.db");
toolboxDb.setDatabaseName("C:\\New folder\\ToolSearch.db");
bool db_ok = toolboxDb.open();
if (!QFile::exists("C:\\New folder\\ToolSearch.db"))
qDebug() << "This file does not exist";
if (!db_ok)
qDebug() << "Connection Failed\n";
QSqlQuery *qry = new QSqlQuery(toolboxDb);
sQry += "SELECT * FROM ToolSearch WHERE keywords MATCH :searchTerm UNION SELECT * FROM ToolSearch WHERE name MATCH :searchTerm UNION ";
sQry += "SELECT * FROM ToolSearch WHERE category MATCH :searchTerm UNION SELECT * FROM ToolSearch WHERE subcategory MATCH :searchTerm ";
sQry += "UNION SELECT * FROM ToolSearch WHERE sources MATCH :searchTerm UNION SELECT * FROM ToolSearch WHERE usagetype :searchTerm UNION ";
sQry += "SELECT * FROM ToolSearch WHERE cost MATCH :searchTerm";
qry->prepare(sQry);
//Add the necessary single quotes to the given string
searchStr = '\'' + searchStr + '\'';
qry->bindValue(":searchTerm", searchStr);
qry->exec();
model->setQuery(*qry);
ui->searchResults->setModel(model);
ui->searchResults->show(); }
Most of the answers that I saw on here said that to open the database you have to write something along the lines of the following:
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("C:\\SomeFolder\\SomeFile.db");
bool db_ok = db.open();
However, I have almost the exact same code in mine for opening the database and even tested it with an absolute address as opposed to the relative address I had with the ":/Resources/Resources/ToolSearch.db" line. Also, the output of qDebug() << QSqlDatabase::drivers() gives:
("QSQLITE", "QMYSQL", "QMYSQL3", "QODBC", "QODBC3", "QPSQL", "QPSQL7")
Lastly, I have also used verified that the file does exist at the location I am trying to open it at using the if (!QFile::exists()) statement. So, I am at a loss for why this is not working. The specific error message that I get when I attempt to run this code is "QSqlQuery::prepare: database not open".
Any help is greatly appreciated!

QSqlQuery forbid non-SELECT query

I'm looking for a way to forbid non-SELECT query for a QSqlQuery object.
I know QSqlQuery::isSelect is only effective after QSqlQuery::exec (damage
already done here).
So, is there any way to do that or I have to verify the query string explicitly.
Thanks.
From my experience, the QSqlQuery::isSelect function works well even before running the QSqlQuery::exec command. But only when the object is initialized with the query. i.e:
QSqlQuery query("SELECT * FROM someTable");
qDebug() << query.isSelect(); //Outputs True
OR
QString queryString = "SELECT * FROM someTable";
QSqlQuery query(queryString);
qDebug() << query.isSelect(); //Outputs True
If you are using the prepare function and passing the query string to it, then you will have to verify the query string yourself. i.e;
QSqlQuery query;
query.prepare("SELECT * FROM someTable");
qDebug() << query.isSelect(); //Outputs False
If you really want to avoid manual verification of the query string, you will have to avoid using QSqlQuery::prepare and QSqlQuery::bindValue functions and instead create the query yourself and initialize the QSqlQuery object with the QString you create.

QSqlQuery.record() is always empty

I'm editing the database in this manner:
QSqlQuery query;
query.prepare("UPDATE student "
"SET name = ? "
"WHERE id = ?");
QString name = "t";
int id = 3;
query.addBindValue(name);
query.addBindValue(id);
query.exec(); // query exec returns true
QSqlRecord record = query.record(); // but the record is empty!
mTableModel->beforeInsert(record);
The retrieved record is always empty, but the QSqlTableModel still changes! I need the record to be valid because I'm trying to synchronize an sql db with a std::vector.
I'm connecting to the database like this:
mDatabase = QSqlDatabase::addDatabase("QSQLITE");
mDatabase.setDatabaseName("database.db");
mDatabase.open();
I tried calling QSqlQuery::clear(), QSqlQuery::finish() but it didn't help. I also tried to open and close the DB, but it also didn't help. What can I do? :\
Qt is not a pain indeed.
All your code is good. The only wrong assumption is that an update request will automatically give you back the updated record. You have to make a new select request on this id to get the updates data in a QSqlRecord.
//[untested]
QSqlQuery select;
select.prepare("SELECT * from student where id = ?");
select.addBindValue(id);
if (select.exec() && select.next()) {
QSqlRecord record = select.record();
}