PostgreSQL opening other database failed - c++

Well, the problem is, when I close previous database and try to connect to the new one I get this:
Connection failed!
unterminated quoted string in connection info string
QPSQL:Unable to connect
Here full description of what I'am doing:
First I logging in with any avalible login and connect to the default "posgtres" database. Then I executing query select * from pg_database; to get list of all avalible databases. After that I close database.
void FdbToPg::connectToDatabase(){
database.setHostName(ui.lineIP->text());
database.setDatabaseName("postgres");
database.setUserName(ui.lineLogin->text());
database.setPassword(ui.linePassword->text());
database.setPort(ui.linePort->text().toInt());
QSqlQuery query;
if(database.open()){
QString dbOutput = "select * from pg_database;";
query.exec(dbOutput);
while(query.next()){
ui.comboBox->addItem(query.value(0).toString(),QVariant::Char);
}
database.close();
}else{
QMessageBox::information(this, "Error", "Cant' connect ot the database");
}
}
Then when on of the avalible databases been choosed I trying to connect to it. And there I get that error message
void FdbToPg::on_selectButton_clicked(){
database.setDatabaseName(ui.comboBox->itemData(ui.comboBox->currentIndex()).toString());
database.setHostName(ui.lineIP->text());
database.setUserName(ui.lineLogin->text());
database.setPassword(ui.linePassword->text());
database.setPort(ui.linePort->text().toInt());
bool ok = database.open();
if(ok != true){
QMessageBox::information(this, "Connection", "Connection failed! \n" + database.lastError().text());
} else {
QMessageBox::information(this, "Connection", "Connection worked!");
}
}
What's wrong here and how I properly suppose to close old database and open new one?

Well, the problem were here
database.setDatabaseName(ui.comboBox->itemData(ui.comboBox->currentIndex()).toString());
ui.comboBox->itemData(ui.comboBox->currentIndex()).toString() were return an empty string. I changed it to database.setDatabaseName(ui.comboBox->currentIndex()); and now it's ok.
But I still don't understand whats wrong with
ui.comboBox->itemData(ui.comboBox->currentIndex()).toString() command

Related

QT open not existing database

I've created simple function for connecting with sqlite3 database. But I've recognized that it makes connection , even if database file not exist
As you can see below : I've tried to check if file really exist and if it's really connected .
bool DatabaseConnection::make_connection(const QString &path)
{
db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(path);
#ifdef QT_DEBUG
qDebug() << "File: '" + db.databaseName() + "' exist = " << QFileInfo::exists(db.databaseName());
qDebug() << db.isValid();
#endif
if (!db.open())
{
QMessageBox::critical(nullptr,
QObject::tr("Error - Cannot open database"),
QObject::tr("Failed attempt to establish connection \n"),
QMessageBox::Close);
return false;
}
qDebug() <<"Open:" <<db.isOpen();
qDebug() << "errors:" << db.isOpenError();
return true;
}
after changing path name on first compilation - file not exist , but connection seems to be established (True).
In next compilation tells that file exist ( I've couldn't find it anywhere) , and again connection is 'established'
I had similar problem, db.open() creates new file if it doesn't exist.
Just wrap db.open() arround QFileInfo::exists(path).
I believe if you attempt to access an SQLite3 database that does not exist, it will create one. So db.open() will attempt to create a database file if one is not found. You would be best served checking if the DB file exists first using some other method before calling db.open().

Open and closing ODBC connections causing crashes

I wrote a program that used a SQLite database and it worked correctly. Now I'm trying to make it work with SQL Server. The application crashes on startup and I have worked out that it's to do with the way I am opening and closing database connections. I'm really unsure if I need to open the connection only once or if should I open and close it each time I run a query? Also is it advised to delete the pointer to the query after it executes? Removing the conn.connOpen and conn.connClose sections makes the program run, but its unstable.
Any advice on how to handle connections (since I have a lot of buttons that execute different queries) is greatly appreciated.
My connection string is stored in a header (mainwindow)
// mainwindows.h
public:
QSqlDatabase mydb;
void connClose()
{
connected = false;
mydb.close();
mydb.QSqlDatabase();
mydb.removeDatabase(QSqlDatabase::defaultConnection);
}
bool connOpen()
{
if( !connected )
{
mydb = QSqlDatabase::addDatabase("QODBC"); //uses dsn, connects fine.
mydb.setDatabaseName("Test");
if(!mydb.open())
{
qDebug() << mydb.lastError().text();
connected = false;
}
else
{
qDebug()<<"Connected";
connected = true;
}
}
return connected;
}
private:
static bool connected;
Here is an example of how I'm calling queries in my .cpp files;
Financelog::Financelog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Financelog)
{
ui->setupUi(this);
setWindowFlags( windowFlags() | Qt::WindowMinimizeButtonHint |
Qt::WindowContextHelpButtonHint | Qt::WindowMinMaxButtonsHint );
MainWindow conn; // call the connection string
if(!conn.connOpen())
ui->label_sec_status->setText("<font color='red'>Failed to Open Database</font>");
else
ui->label_sec_status->setText("<font color='green'>Connected</font>");
QSqlQueryModel * modal=new QSqlQueryModel();
conn.connOpen(); // ---- **DO I NEED THIS? REMOVING STOPS CRASHES.**
QSqlQuery* qry=new QSqlQuery(conn.mydb);
qry->prepare("select DEAL_DATE, DEAL_NUMB, CCICOMM, CCIPREM, INCOME from LOG");
qry->exec();
modal->setQuery(*qry);
ui->tableView->setModel(modal);
ui->tableView->resizeColumnsToContents();
ui->tableView->setAlternatingRowColors(true);
ui->tableView->setStyleSheet("alternate-background-color: #009900; background-color: #006600;");
//delete qry; **DO I NEED THIS TO RELEASE MEMORY?**
conn.connClose(); // **DO I NEED THIS?**
qDebug() << (modal->rowCount());
}
You should only open the connection once, and keep it open while using it. Not open and close for every query.
If you have long phases of nothing between 2 queries, you can use a QTimer to close the connection after beeing unused for a "long" time (e.g. 5 min). Do so if you see the connection timing out. But by default, not needed.
QSqlQuery, just like QSqlDatabase should be used as "value class", not as a pointer (See Qt Documentation). Instead of creating one with new, create it on the stack. Queries are copyable.
Code sample:
//only once, i.e. in your windows constructor
conn.connOpen();
//set up the model
QSqlQueryModel * modal=new QSqlQueryModel();
QSqlQuery qry(conn.mydb);
qry.prepare("...");
qry.exec();
modal->setQuery(qry);
//...
// do not delete the query or close the database connection!
qDebug() << (modal->rowCount());
You can close the connection in the destructor after the model has been destroyed:
model->deleteLater();
conn.connClose();

Syntaxe error source with QSqlQuery

I have a problem with a QSqlQuery when I execute a source command on my database.
This code works :
QString myRequest = "CREATE DATABASE MY_DATABASE;";
lQueryResult.Exec(myRequest);
if(!lQueryResult.GetMexec())
{
qDebug() << "Error in the request";
return false;
}
else
{
qDebug() << "The request is OK";
}
This code doesn't works, I have a syntax error :
You have an error in
your SQL syntax; check the manual that corresponds to your MariaDB
server version for the right syntax to use near 'source
./folder/myFile.sql' at line 1 QMYSQL: Unable to execute query
This is the code :
myRequest = "source myFile.sql";
lQueryResult.Exec(myRequest);
if(!lQueryResult.GetMexec())
{
qDebug() << "Error";
qDebug() << lQueryResult.LastError();
return false;
}
else
{
qDebug() << "OK";
}
I can successfully do my source with this command :
QString lCommand("mysql -uUsername -pPassword Data_Base -e \"source " + variablePath + variableFile + ".sql\"");
system(lCommandeProvisoire.toStdString().c_str());
I have no error. But, if I execute this code juste after, I have the error
No database selected QMYSQL: Unable to execute query
:
TheRequest = "SELECT * FROM MyTable;";
QueryResult.Exec(TheRequest);
if(!QueryResult.GetMexec())
{
qDebug() << QueryResult.LastError();
return false;
}
else
{
qDebug() << "OK";
}
But, If I execute a select * from MyTable in shell, it works.
Also, if I execute this in a shell logged in mysql, it works :
source myFile.sql
SOURCE is MySQL client command which means it is executed by MySQL shell, not by MySQL server, so you can't execute it via QSqlQuery. You can work around this by reading whole file and then sending it's contents to server.

How to deploy Qt application with an existing Sqlite db?

I want to package my Qt application with an existing Sqlite db. I have the standard Qt database code:
m_db = QSqlDatabase::addDatabase("QSQLITE");
m_db.setDatabaseName("database.sqlite");
bool connected = m_db.open();
if (!connected) {
qDebug() << "Error: connection with database failed";
} else {
qDebug() << "Database: connection success";
QSqlQuery q(m_db);
q.prepare("SELECT * FROM people");
if (q.exec()) {
qDebug() << "Yay!";
} else {
qWarning() << "Bad exec: " << q.lastError();
qWarning() << q.executedQuery();
}
}
However, the result is:
Error: connection with database failed
I know this is because it's not finding the correct database, and is instead creating a new one. If I provide the absolute path on my development machine to m_db.setDatabaseName(), it works. But my database file is in my .qrc and will not be available in that location when I deploy... so how can I get a reliable path for this database?
in the setDatabaseName-call use the right syntax for resource files:
m_db.setDatabaseName(":database.sqlite"); // <-- note the : before the name
... presuming the database file is located in the root of your resource file system.
Greetings, Thomas

Why can't I delete the SQLite database in Qt even after I call the database close function?

I'm writing a code to work with a SQLite database, all the code of the database works, but at end, when I try to delete the database, the database file is not deleted. I've called the close function, so why can't I delete the database?
The db.isOpen(); function returns false, and the QFile::remove(path); returns false too.
Note: On Windows Explorer i can delete the database only after closing the program window.
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
QString path = "path_to_db";
db.setDatabaseName(path);
if(db.open())
{
qDebug() << "Opened";
qDebug() << path;
}
else
{
qDebug() << db.lastError();
return a.exec();
}
QSqlQuery query(db);
//code to work with the database
db.close();
qDebug() << db.isOpen();
qDebug() << QFile::remove(path);
I found the solution, simply call query.clear(); before close the connection.