Skip to content

Commit

Permalink
Fix attached databases so that they work properly
Browse files Browse the repository at this point in the history
  • Loading branch information
rparkins999 committed Jan 21, 2016
1 parent 45af79b commit 34b531e
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 64 deletions.
3 changes: 2 additions & 1 deletion Sqliteman/sqliteman/doc/en/ch07s09.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Attached Databases</title><link rel="stylesheet" href="kde-default.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.67.2"><meta name="keywords" content="Sqliteman, SQL, Sqlite, development, database"><link rel="start" href="index.html" title="The Sqliteman Handbook"><link rel="up" href="ch07.html" title="Chapter 7. Features and Dialogs"><link rel="prev" href="ch07s08.html" title="Constraint Triggers"><link rel="next" href="ch07s10.html" title="Schema Browser"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Attached Databases</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch07s08.html">Prev</a> </td><th width="60%" align="center">Chapter 7. Features and Dialogs</th><td width="20%" align="right"> <a accesskey="n" href="ch07s10.html">Next</a></td></tr></table><hr></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="attachDatabase"></a>Attached Databases</h2></div></div></div><p>You can add and remove another database files to the current database connection.
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Attached Databases</title><link rel="stylesheet" href="kde-default.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.67.2"><meta name="keywords" content="Sqliteman, SQL, Sqlite, development, database"><link rel="start" href="index.html" title="The Sqliteman Handbook"><link rel="up" href="ch07.html" title="Chapter 7. Features and Dialogs"><link rel="prev" href="ch07s08.html" title="Constraint Triggers"><link rel="next" href="ch07s10.html" title="Schema Browser"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Attached Databases</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch07s08.html">Prev</a> </td><th width="60%" align="center">Chapter 7. Features and Dialogs</th><td width="20%" align="right"> <a accesskey="n" href="ch07s10.html">Next</a></td></tr></table><hr></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="attachDatabase"></a>Attached Databases</h2></div></div></div><p>
You can add and remove another database files to the current database connection either from the sqlite menus (see <a href="ch06s04.html">The System Menu</a> and <a href="ch06s02.html">The Context Menu</a>) or by executing SQL commands in the SQL editor (see <a href="ch05.html">Sqliteman Main Window</a>).
Every attached database is identified by its unique name (prefix). The names 'main' and 'temp' refer to the main database and the database used for temporary tables. These cannot be detached.
You should access database objects with full prefixed naming convention:</p><p><span><strong class="command">SELECT * FROM newdb.foo_table;</strong></span></p><p>It is possible to open the same database with two different names: Sqliteman cannot detect this because it cannot determine whether two different file names refer to the same file. If this occurs, Sqliteman may behave unpredictably.</p><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Important</h3><p>Consult <a href="http://www.sqlite.org/lang_attach.html" target="_top">Sqlite documentation</a>.</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch07s08.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ch07.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ch07s10.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Constraint Triggers </td><td width="20%" align="center"><a accesskey="h" href="index.html">Contents</a></td><td width="40%" align="right" valign="top"> Schema Browser</td></tr></table></div></body></html>
102 changes: 46 additions & 56 deletions Sqliteman/sqliteman/litemanwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ to the COPYING file provided with the program. Following this notice may exist
a copyright and/or license notice that predates the release of Sqliteman
for which a new license (GPL+exception) is in place.
FIXME creating empty constraint name is legal
FIXME clicking on table of database attached by sql doesn't open it
FIXME ... appears to corrupt it too!
FIXME why do we do both both ATTACH DATABASE (same connection) and addDatabase (different connection)
*/
#include <QTreeWidget>
#include <QTableView>
Expand Down Expand Up @@ -91,7 +88,6 @@ LiteManWindow::LiteManWindow(const QString & fileToOpen)
#endif

recentDocs.clear();
attachedDb.clear();
initUI();
initActions();
initMenus();
Expand Down Expand Up @@ -171,13 +167,11 @@ void LiteManWindow::closeEvent(QCloseEvent * e)
writeSettings();

dataViewer->setTableModel(new QSqlQueryModel(), false);
QMapIterator<QString, QString> i(attachedDb);
while (i.hasNext())
if (QSqlDatabase::contains(SESSION_NAME))
{
i.next();
QSqlDatabase::database(i.value()).rollback();
QSqlDatabase::database(i.value()).close();
QSqlDatabase::removeDatabase(i.value());
QSqlDatabase::database(SESSION_NAME).rollback();
QSqlDatabase::database(SESSION_NAME).close();
QSqlDatabase::removeDatabase(SESSION_NAME);
}

// It has to go after writeSettings()!
Expand Down Expand Up @@ -668,9 +662,6 @@ void LiteManWindow::openDatabase(const QString & fileName)
}
#endif

attachedDb.clear();
attachedDb["main"] = SESSION_NAME;

QFileInfo fi(fileName);
QDir::setCurrent(fi.absolutePath());
m_mainDbPath = QDir::toNativeSeparators(QDir::currentPath() + "/" + fi.fileName());
Expand Down Expand Up @@ -1339,7 +1330,7 @@ void LiteManWindow::treeItemActivated(QTreeWidgetItem * item)
}
else
{
SqlTableModel * model = new SqlTableModel(0, QSqlDatabase::database(attachedDb[item->text(1)]));
SqlTableModel * model = new SqlTableModel(0, QSqlDatabase::database(SESSION_NAME));
model->setSchema(item->text(1));
model->setTable(item->text(0));
model->select();
Expand Down Expand Up @@ -1436,7 +1427,7 @@ void LiteManWindow::updateContextMenu(QTreeWidgetItem * cur)

case TableTree::DatabaseItemType:
contextMenu->addAction(refreshTreeAct);
if (cur->text(0) != "main")
if ((cur->text(0) != "main") && (cur->text(0) != "temp"))
contextMenu->addAction(detachAct);
contextMenu->addAction(createTableAct);
contextMenu->addAction(createViewAct);
Expand Down Expand Up @@ -1495,14 +1486,35 @@ void LiteManWindow::attachDatabase()
if (ret == QMessageBox::Cancel) { return; }
}

bool ok;
QFileInfo f(fileName);
QString schema = QInputDialog::getText(this, tr("Attach Database"),
tr("Enter a Schema Alias:"),
QLineEdit::Normal,
f.baseName(), &ok);
if (!ok || schema.isEmpty())
return;
QString schema;
bool ok = false;
while (!ok)
{
schema = QInputDialog::getText(this, tr("Attach Database"),
tr("Enter a Schema Alias:"),
QLineEdit::Normal, f.baseName(), &ok);
if (!ok) { return; }
if ( schema.isEmpty()
|| (schema.compare("temp", Qt::CaseInsensitive) == 0))
{
QMessageBox::critical(this, tr("Attach Database"),
tr("\"temp\" or empty is not a valid schema name"));
ok = false;
continue;
}
QStringList databases(Database::getDatabases().keys());
foreach(QString db, databases)
{
if (db.compare(schema, Qt::CaseInsensitive) == 0)
{
QMessageBox::critical(this, tr("Attach Database"),
tr("%1 is already in use as a schema name")
.arg(Utils::q(schema)));
ok = false;
}
}
}
QString sql = QString("ATTACH DATABASE ")
+ Utils::q(fileName, "'")
+ " as "
Expand All @@ -1522,47 +1534,28 @@ void LiteManWindow::attachDatabase()
}
else
{
attachedDb[schema] = Database::sessionName(schema);
QSqlDatabase db =
QSqlDatabase::addDatabase("QSQLITE", attachedDb[schema]);
db.setDatabaseName(fileName);
if (!db.open())
QString sql = QString("select 1 from ")
+ Utils::q(schema)
+ ".sqlite_master where 1=2 ;";
QSqlQuery query(sql, QSqlDatabase::database(SESSION_NAME));
if (query.lastError().isValid())
{
dataViewer->setStatusText(
tr("Cannot open or create ")
tr("Cannot access ")
+ QFileInfo(fileName).fileName()
+ ":<br/><span style=\" color:#ff0000;\">"
+ db.lastError().text());
+ query.lastError().text()
+ "<br/></span>"
+ tr("It is probably not a database."));
QSqlQuery qundo(QString("DETACH DATABASE ")
+ Utils::q(schema)
+ ";",
db);
attachedDb.remove(schema);
QSqlDatabase::database(SESSION_NAME));
}
else
{
QSqlQuery q("select 1 from sqlite_master where 1=2", db);
if (!q.exec())
{
dataViewer->setStatusText(
tr("Cannot access ")
+ QFileInfo(fileName).fileName()
+ ":<br/><span style=\" color:#ff0000;\">"
+ db.lastError().text()
+ "<br/></span>"
+ tr("It is probably not a database."));
QSqlQuery qundo(QString("DETACH DATABASE ")
+ Utils::q(schema)
+ ";",
db);
db.close();
attachedDb.remove(schema);
}
else
{
schemaBrowser->tableTree->buildDatabase(schema);
queryEditor->treeChanged();
}
schemaBrowser->tableTree->buildDatabase(schema);
queryEditor->treeChanged();
}
}
}
Expand All @@ -1589,9 +1582,6 @@ void LiteManWindow::detachDatabase()
}
else
{
QSqlDatabase::database(attachedDb[dbname]).rollback();
QSqlDatabase::database(attachedDb[dbname]).close();
attachedDb.remove(dbname);
// this removes the item from the tree as well as deleting it
delete schemaBrowser->tableTree->currentItem();
queryEditor->treeChanged();
Expand Down
5 changes: 0 additions & 5 deletions Sqliteman/sqliteman/litemanwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,6 @@ class LiteManWindow : public QMainWindow
// \brief True if is sqlite3 binary available in the path
// bool m_sqliteBinAvailable;

/*! \brief alias name - connection name mappings
It's used for mapping of the attached databases for QSqlTableModel
as it does not support database.table naming schema */
QMap<QString,QString> attachedDb;

DataViewer * dataViewer;
QSplitter * splitter;
SchemaBrowser * schemaBrowser;
Expand Down
10 changes: 8 additions & 2 deletions Sqliteman/sqliteman/sqlmodels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,14 @@ void SqlTableModel::setTable(const QString &tableName)
m_header[colnum] = SqlTableModel::None;
++colnum;
}

QSqlTableModel::setTable(tableName);
if (m_schema.isEmpty())
{
QSqlTableModel::setTable(tableName);
}
else
{
QSqlTableModel::setTable(m_schema + "." + tableName);
}
}

void SqlTableModel::detach (SqlTableModel * model)
Expand Down

0 comments on commit 34b531e

Please sign in to comment.