PDA

View Full Version : How remove database in right way



Tarko1976
25th July 2016, 20:37
Hi everybody, when I run my program, I've got this message:
QSqlDatabasePrivate removeDatabase connection qt_sql_default_connection is still in use all queries will cease to work.

this is my class for connection:

ConnectDB.h


#ifndef CONNECTDB_H
#define CONNECTDB_H

#include <QString>
#include <QSqlDatabase>

class ConnectDB
{
public:
ConnectDB(const QString sHostName, const QString sDatabaseName, const QString sUserName, const QString sPassword, int iPort, const QString connectionName);
~ConnectDB();
bool openConnection();
void closeConnection();

private:
QSqlDatabase *db;
QString sHostName, sDatabaseName, sUserName, sPassword, sConnectionName;
int iPort;
};

#endif // CONNECTDB_H


ConnectDB.cpp


#include "connectdb.h"
#include <QString>
#include <QSqlDatabase>
#include <QSqlError>
#include <QDebug>

ConnectDB::ConnectDB(const QString sHostName, const QString sDatabaseName, const QString sUserName, const QString sPassword, int iPort, const QString connectionName)
{
this->sHostName = sHostName;
this->sDatabaseName = sDatabaseName;
this->sUserName = sUserName;
this->sPassword = sPassword;
this->iPort = iPort;
this->sConnectionName = connectionName;

db = new QSqlDatabase(QSqlDatabase::addDatabase("QPSQL",sConnectionName));
db->setHostName(sHostName);
db->setDatabaseName(sDatabaseName);
db->setUserName(sUserName);
db->setPassword(sPassword);
db->setPort(iPort);
qDebug() << "Openning...";
}

bool ConnectDB::openConnection()
{
if(!db->open())
{
qDebug() << db->lastError().text();
return false;
}
return true;
}

void ConnectDB::closeConnection()
{
if (db->isOpen() && db->isValid()) {
db->close();
qDebug() << "Closing ...";
QStringList lsConnectionName = QSqlDatabase::connectionNames();
for (int i = 0; i < lsConnectionName.count(); ++i) {
qDebug() << "CONEXION: " << lsConnectionName[i];
QSqlDatabase::removeDatabase(lsConnectionName[i]);
}
}
}

ConnectDB::~ConnectDB()
{
delete db;
}



So, this is the class where i use class ConnectDB:
frmmantenimiento.h


#ifndef FRMMANTENIMIENTO_H
#define FRMMANTENIMIENTO_H

#include <QWidget>

class QLabel;
class QLineEdit;
class QPushButton;
class QHBoxLayout;
class QVBoxLayout;
class QGridLayout;
class QSqlQuery;

class FrmMantenimiento : public QWidget
{
Q_OBJECT
public:
explicit FrmMantenimiento(const QString strUserName, const QString strTableName, QWidget *parent = 0);
~FrmMantenimiento();
void setUserName(const QString strUserName);
QString getUserName();
void setTableName(const QString strTableName);
QString getTableName();
void setEnableInput();
void setDisableInput();
void setFirstStatusDMLButtons();
void setSecondStatusDMLButtons();
void loadData();

private:
QLabel *lbCode;
QLineEdit *leCode;
QLabel *lbDescription;
QLineEdit *leDescription;
QPushButton *pbNew;
QPushButton *pbEdit;
QPushButton *pbSave;
QPushButton *pbDelete;
QPushButton *pbFind;
QPushButton *pbClose;
QGridLayout *glInput;
QVBoxLayout *vlInput;
QVBoxLayout *vlDML;
QHBoxLayout *hlMantenimiento;
QString strUserName;
QString strTableName;

signals:

private slots:
void pbNewClicked();
void pbEditClicked();
void pbSaveClicked();
void pbDeleteClicked();
void actionDML(int iStatusDML);
};

#endif // FRMMANTENIMIENTO_H


and this is the implementation frmmantenimiento.cpp


#include "frmmantenimiento.h"
#include "connectdb.h"

#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QSqlQuery>
#include <QSqlError>
#include <QMessageBox>
#include <QCloseEvent>
#include <QDebug>

int iStatusDML = 9;

FrmMantenimiento::FrmMantenimiento(const QString strUserName, const QString strTableName, QWidget *parent) : QWidget(parent)
{
lbCode = new QLabel("Codigo");
leCode = new QLineEdit;
leCode->setFixedWidth(30);
lbDescription = new QLabel("Descripcion");
leDescription = new QLineEdit;
leDescription->setFixedWidth(200);

pbNew = new QPushButton("Nuevo");
pbNew->setIcon(QIcon("../images/new_48.png"));
pbEdit = new QPushButton("Editar");
pbEdit->setIcon(QIcon("../images/edit_48.png"));
pbSave = new QPushButton("Guardar");
pbSave->setIcon(QIcon("../images/save_48.png"));
pbDelete = new QPushButton("Eliminar");
pbDelete->setIcon(QIcon("../images/delete_48.png"));
pbFind = new QPushButton("Buscar");
pbFind->setIcon(QIcon("../images/find_48.png"));
pbClose = new QPushButton("Cerrar");
pbClose->setIcon(QIcon("../images/exit_48.png"));

glInput = new QGridLayout;
glInput->addWidget(lbCode, 0, 0);
glInput->addWidget(leCode, 0, 1);
glInput->addWidget(lbDescription, 1, 0);
glInput->addWidget(leDescription, 1, 1);

vlInput = new QVBoxLayout;
vlInput->addLayout(glInput);
vlInput->addStretch();

vlDML = new QVBoxLayout;
vlDML->addWidget(pbNew);
vlDML->addWidget(pbEdit);
vlDML->addWidget(pbSave);
vlDML->addWidget(pbDelete);
vlDML->addStretch();
vlDML->addWidget(pbFind);
vlDML->addStretch();
vlDML->addWidget(pbClose);

hlMantenimiento = new QHBoxLayout;
hlMantenimiento->addLayout(vlInput);
hlMantenimiento->addSpacing(20);
hlMantenimiento->addLayout(vlDML);

this->setLayout(hlMantenimiento);
this->setWindowTitle("Tabla[" + getUserName() + "]");

setUserName(strUserName);
setTableName(strTableName);
setDisableInput();
setFirstStatusDMLButtons();

loadData();

connect(pbNew, SIGNAL(clicked(bool)), this, SLOT(pbNewClicked()));
connect(pbEdit, SIGNAL(clicked(bool)), this, SLOT(pbEditClicked()));
connect(pbSave, SIGNAL(clicked(bool)), this, SLOT(pbSaveClicked()));
connect(pbDelete, SIGNAL(clicked(bool)), this, SLOT(pbDeleteClicked()));
connect(pbClose, SIGNAL(clicked(bool)), this, SLOT(close()));


this->setAttribute(Qt::WA_DeleteOnClose);


}

void FrmMantenimiento::loadData()
{
ConnectDB *wlfConnectDB = new ConnectDB("localhost","zcdevelopment","cp21021976","cp21021976",5432, "cnSelect");
wlfConnectDB->openConnection();

QSqlQuery *wlfQuery = new QSqlQuery;

wlfQuery->prepare("SELECT sexo_codigo, sexo_descripcion FROM cp21021976.tb_sexo ORDER BY sexo_codigo");
wlfQuery->exec();

wlfQuery->seek(0);
QString strCodigo = wlfQuery->value(0).toString();
QString strDescripcion = wlfQuery->value(1).toString();
leCode->setText(strCodigo);
leDescription->setText(strDescripcion);

wlfConnectDB->closeConnection();
}


I don't know how to resolve this problem...

jefftee
25th July 2016, 20:52
More than likely, you have a QSqlQuery that is still active. When you're done with your QSqlQuery items, you should do a QSqlQuery::finish().

Edit: I didn't study your code thoroughly, but are you leaking code in frmmantenimiento.cpp on lines 89 and 92?

Tarko1976
26th July 2016, 00:56
Sorry jefftee, but, i don't understand, that's all my code.

jefftee
26th July 2016, 02:32
Sorry jefftee, but, i don't understand, that's all my code.
I understand it's all your code, but if you wrote that code, you should understand my reply... :)

Add a
wlfQuery->finish(); before line 103. To see if that's the cause of your connection still in use, as well as fix the memory leak below...

You also allocate your connection and query objects on the heap ("new" keyword) but you don't free that memory anywhere, so you should just allocate them on the stack and they'll go out of scope at the end of your loadData() method or make them class variables where they can be used in other parts of your code if needed.

Tarko1976
26th July 2016, 06:36
Hi jefftee, i added:


wlfQuery->finish();


but, i got the same message, i wrote in loadData() method:


delete wlfQuery;
delete wlfConnectDB;


and that's not work.

jefftee
26th July 2016, 15:30
Please re-post your code as tested with the additions in your last post.