Название: Удалить соединение с БД
Отправлено: pro100skif от Июнь 25, 2014, 02:13
Доброго времени суток облазил гугл но не смог найти решение для мой проблемы.В программе пользователь должен иметь возможность открывать несколько баз данных.Проблема в том,что если я закрываю текущую базу данных то в логе говорит что QSqlDatabasePrivate::removeDatabase: connection 'new123' is still in use, all queries will cease to work. вот код(он большой но все работает кроме удаления подключения,возможно проблема в других виджетах).Заранее спасибо за помощь: #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include<QtSql/QSqlDatabase> #include<QtSql/QSqlQuery> #include<QTreeWidgetItem> #include<QSqlTableModel> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); QStringList columnList; int columnCount; private: QSqlDatabase db; Ui::MainWindow *ui; QString dbName; QString tableName; QString fieldName; QString typeName; QTreeWidgetItem *itm; QSqlTableModel *model; QString conName; void showButtons(int); private slots: void newDB(); void openDB(); void newTable(); void openTable(); void addRecord(); void addField(); void deleteRecord(); void deleteFieldname(); void removeDB(); }; #endif // MAINWINDOW_H #include "mainwindow.h" #include "ui_mainwindow.h" #include<dbdialog.h> #include<QFileDialog> #include<QDebug> #include<tabledialog.h> #include<delegate.cpp> #include<QSqlRecord> #include<fielddialog.h> #include<deletefield.h> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); itm=new QTreeWidgetItem; conName="new123"; connect(ui->newDBaction,SIGNAL(triggered()),this,SLOT(newDB())); connect(ui->openAction,SIGNAL(triggered()),this,SLOT(openDB())); connect(ui->newTableacrion,SIGNAL(triggered()),this,SLOT(newTable())); connect(ui->openTableAction,SIGNAL(triggered()),this,SLOT(openTable())); connect(ui->addRecordaction,SIGNAL(triggered()),this,SLOT(addRecord())); connect(ui->addFieldAction,SIGNAL(triggered()),this,SLOT(addField())); connect(ui->deleteRecordaction,SIGNAL(triggered()),this,SLOT(deleteRecord())); connect(ui->deleteFieldAction,SIGNAL(triggered()),this,SLOT(deleteFieldname())); connect(ui->removeDBname,SIGNAL(triggered()),this,SLOT(removeDB())); NonEditTableColumnDelegate *delegate=new NonEditTableColumnDelegate(this); DateEditTableColumnDelegate *delegate1=new DateEditTableColumnDelegate(ui->tableView); ui->tableView->setItemDelegateForColumn(0,delegate); ui->tableView->setItemDelegateForColumn(1,delegate1); ui->tableView->setSortingEnabled(true); } MainWindow::~MainWindow() { delete ui; } void MainWindow::newDB() { ui->treeWidget->clear(); dbdialog dialog; dialog.setModal(true); dialog.setWindowTitle("Создать новую БД"); dialog.exec(); dbName=dialog.name; db=QSqlDatabase::addDatabase("QSQLITE",conName); db.setDatabaseName(dbName+".sqlite"); if(db.open()) { qDebug()<<"Database open "+dbName; itm->setText(0,dbName); ui->treeWidget->addTopLevelItem(itm); } QSqlQuery query("CREATE TABLE "+dbName+"(ID integer PRIMARY KEY NOT NULL);"); query.exec(); } void MainWindow::openDB() { ui->treeWidget->clear(); QString fileName = QFileDialog::getOpenFileName(this, tr("Открыть БД"), "", tr("DB (*.sqlite);;All Files (*)")); dbName=fileName; db=QSqlDatabase::addDatabase("QSQLITE",conName); db.setDatabaseName(dbName); if(db.open()) { QStringList list=db.tables(); qDebug()<<"Database open "+dbName; itm->setText(0,list[0]); ui->treeWidget->addTopLevelItem(itm); int j=db.tables().count(); for(int i=1;i<=j-1;i++) { QTreeWidgetItem*itm1=new QTreeWidgetItem; itm1->setText(0,list.at(i)); itm->addChild(itm1); } } } void MainWindow::newTable() { tabledialog dialog; dialog.setModal(true); dialog.setWindowTitle("Создание таблицы"); dialog.exec(); QSqlQuery query; tableName=dialog.name; qDebug()<<"tableName"<<tableName; if(query.exec("CREATE TABLE "+tableName+" (ID integer PRIMARY KEY NOT NULL);")) { QTreeWidgetItem *itm0=new QTreeWidgetItem; itm0->setText(0,tableName); itm->addChild(itm0); } qDebug()<<db.tables(); } void MainWindow::openTable() { qDebug()<<"openTable"; tableName=ui->treeWidget->currentItem()->text(0); model = new QSqlTableModel(this); model->setTable(tableName); model->setEditStrategy(QSqlTableModel::OnFieldChange); model->select(); ui->tableView->setModel(model); ui->tableView->resizeColumnsToContents(); } void MainWindow::addRecord() { QSqlQuery query; QSqlRecord recordCount; QSqlRecord rec; query.exec("select count(*) as pc_count from "+tableName); query.next(); recordCount=query.record(); int cSize=query.value(recordCount.indexOf("pc_count")).toInt(); QModelIndex index = model->index(cSize-1, 0); QString text = index.data(Qt::DisplayRole).toString(); QString str=QString::number(cSize); int i=text.toInt(); i++; str=QString::number(i); rec=model->record(); rec.setValue("id",str); model->insertRecord(-1,rec); } void MainWindow::addField() { fielddialog dialog; dialog.setModal(true); dialog.setWindowTitle("Создание нового поля"); dialog.exec(); QSqlQuery query; QString fieldName; QString typeName; fieldName=dialog.fieldName; typeName=dialog.fieldType; query.exec("alter table "+tableName+" add "+fieldName+" "+typeName); qDebug()<<fieldName; qDebug()<<typeName; model->setTable(tableName); model->select(); ui->tableView->setModel(model); } void MainWindow::deleteRecord() { QSqlQuery query; QString str; int id; QModelIndexList indexes = ui->tableView->selectionModel()->selection().indexes(); foreach(QModelIndex index, indexes) { QSqlRecord record = model->record(index.row()); id = record.value("ID").toInt(); qDebug()<<id; } str=QString::number(id); query.exec("delete from "+tableName+" where ID="+str); model->setTable(tableName); model->select(); ui->tableView->setModel(model); } void MainWindow::deleteFieldname() { QSqlRecord record1; record1=db.record(tableName); int i=0; QString x=record1.fieldName(i); columnList.insert(i,x); i++; while(x!="") { x=record1.fieldName(i); columnList.insert(i,x); if(x=="") break; i++; } columnCount=i; columnList.removeLast(); QSqlQuery query; deleteField dialog(this,columnList,columnCount); dialog.setWindowTitle("Удалить поле"); dialog.setModal(true); dialog.exec(); qDebug()<<dialog.columnName; QString first="create table newtable5 as select "; for(int i=0;i<columnCount;i++) { if(columnList[i]!=dialog.columnName) first=first+columnList[i]+","; } first.remove(first.length()-1,1); first=first+" from "+tableName+";"; query.exec(first); query.exec("DROP TABLE IF EXISTS "+tableName+";"); query.exec("ALTER TABLE newtable5 RENAME TO "+tableName+";"); model->setTable(tableName); model->select(); ui->tableView->setModel(model); } void MainWindow::removeDB() { if(db.isOpen()==true) { ui->treeWidget->clear(); db.close(); db.removeDatabase(db.connectionName()); QSqlDatabase::removeDatabase(db.connectionName()); } }
Название: Re: Удалить соединение с БД
Отправлено: gil9red от Июнь 25, 2014, 04:18
conName="new123"; ... db=QSqlDatabase::addDatabase("QSQLITE",conName); conName, вообще, меняется? :)
Название: Re: Удалить соединение с БД
Отправлено: VPS от Июнь 25, 2014, 09:01
Посмотрите внимательнее документацию (http://qt-project.org/doc/qt-4.8/qsqldatabase.html#removeDatabase). В Вашем случае член класса - "db" (типа QSqlDatabase) существует всё время существования объекта этого класса. Либо уходите от использования это члена (в реализациях методов получайте объект типа QSqlDatabase через имя соединения), либо в заголовочном файле используйте указатель (а перед вызовом "QSqlDatabase::removeDatabase" удаляйте указатель).
Я бы выбрал первый вариант.
П.С.: немного запутанно написал...
|