Skip to content

Commit 34b531e

Browse files
committed
Fix attached databases so that they work properly
1 parent 45af79b commit 34b531e

File tree

4 files changed

+56
-64
lines changed

4 files changed

+56
-64
lines changed
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
<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.
1+
<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>
2+
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>).
23
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.
34
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>

Sqliteman/sqliteman/litemanwindow.cpp

Lines changed: 46 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ to the COPYING file provided with the program. Following this notice may exist
44
a copyright and/or license notice that predates the release of Sqliteman
55
for which a new license (GPL+exception) is in place.
66
FIXME creating empty constraint name is legal
7-
FIXME clicking on table of database attached by sql doesn't open it
8-
FIXME ... appears to corrupt it too!
9-
FIXME why do we do both both ATTACH DATABASE (same connection) and addDatabase (different connection)
107
*/
118
#include <QTreeWidget>
129
#include <QTableView>
@@ -91,7 +88,6 @@ LiteManWindow::LiteManWindow(const QString & fileToOpen)
9188
#endif
9289

9390
recentDocs.clear();
94-
attachedDb.clear();
9591
initUI();
9692
initActions();
9793
initMenus();
@@ -171,13 +167,11 @@ void LiteManWindow::closeEvent(QCloseEvent * e)
171167
writeSettings();
172168

173169
dataViewer->setTableModel(new QSqlQueryModel(), false);
174-
QMapIterator<QString, QString> i(attachedDb);
175-
while (i.hasNext())
170+
if (QSqlDatabase::contains(SESSION_NAME))
176171
{
177-
i.next();
178-
QSqlDatabase::database(i.value()).rollback();
179-
QSqlDatabase::database(i.value()).close();
180-
QSqlDatabase::removeDatabase(i.value());
172+
QSqlDatabase::database(SESSION_NAME).rollback();
173+
QSqlDatabase::database(SESSION_NAME).close();
174+
QSqlDatabase::removeDatabase(SESSION_NAME);
181175
}
182176

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

671-
attachedDb.clear();
672-
attachedDb["main"] = SESSION_NAME;
673-
674665
QFileInfo fi(fileName);
675666
QDir::setCurrent(fi.absolutePath());
676667
m_mainDbPath = QDir::toNativeSeparators(QDir::currentPath() + "/" + fi.fileName());
@@ -1339,7 +1330,7 @@ void LiteManWindow::treeItemActivated(QTreeWidgetItem * item)
13391330
}
13401331
else
13411332
{
1342-
SqlTableModel * model = new SqlTableModel(0, QSqlDatabase::database(attachedDb[item->text(1)]));
1333+
SqlTableModel * model = new SqlTableModel(0, QSqlDatabase::database(SESSION_NAME));
13431334
model->setSchema(item->text(1));
13441335
model->setTable(item->text(0));
13451336
model->select();
@@ -1436,7 +1427,7 @@ void LiteManWindow::updateContextMenu(QTreeWidgetItem * cur)
14361427

14371428
case TableTree::DatabaseItemType:
14381429
contextMenu->addAction(refreshTreeAct);
1439-
if (cur->text(0) != "main")
1430+
if ((cur->text(0) != "main") && (cur->text(0) != "temp"))
14401431
contextMenu->addAction(detachAct);
14411432
contextMenu->addAction(createTableAct);
14421433
contextMenu->addAction(createViewAct);
@@ -1495,14 +1486,35 @@ void LiteManWindow::attachDatabase()
14951486
if (ret == QMessageBox::Cancel) { return; }
14961487
}
14971488

1498-
bool ok;
14991489
QFileInfo f(fileName);
1500-
QString schema = QInputDialog::getText(this, tr("Attach Database"),
1501-
tr("Enter a Schema Alias:"),
1502-
QLineEdit::Normal,
1503-
f.baseName(), &ok);
1504-
if (!ok || schema.isEmpty())
1505-
return;
1490+
QString schema;
1491+
bool ok = false;
1492+
while (!ok)
1493+
{
1494+
schema = QInputDialog::getText(this, tr("Attach Database"),
1495+
tr("Enter a Schema Alias:"),
1496+
QLineEdit::Normal, f.baseName(), &ok);
1497+
if (!ok) { return; }
1498+
if ( schema.isEmpty()
1499+
|| (schema.compare("temp", Qt::CaseInsensitive) == 0))
1500+
{
1501+
QMessageBox::critical(this, tr("Attach Database"),
1502+
tr("\"temp\" or empty is not a valid schema name"));
1503+
ok = false;
1504+
continue;
1505+
}
1506+
QStringList databases(Database::getDatabases().keys());
1507+
foreach(QString db, databases)
1508+
{
1509+
if (db.compare(schema, Qt::CaseInsensitive) == 0)
1510+
{
1511+
QMessageBox::critical(this, tr("Attach Database"),
1512+
tr("%1 is already in use as a schema name")
1513+
.arg(Utils::q(schema)));
1514+
ok = false;
1515+
}
1516+
}
1517+
}
15061518
QString sql = QString("ATTACH DATABASE ")
15071519
+ Utils::q(fileName, "'")
15081520
+ " as "
@@ -1522,47 +1534,28 @@ void LiteManWindow::attachDatabase()
15221534
}
15231535
else
15241536
{
1525-
attachedDb[schema] = Database::sessionName(schema);
1526-
QSqlDatabase db =
1527-
QSqlDatabase::addDatabase("QSQLITE", attachedDb[schema]);
1528-
db.setDatabaseName(fileName);
1529-
if (!db.open())
1537+
QString sql = QString("select 1 from ")
1538+
+ Utils::q(schema)
1539+
+ ".sqlite_master where 1=2 ;";
1540+
QSqlQuery query(sql, QSqlDatabase::database(SESSION_NAME));
1541+
if (query.lastError().isValid())
15301542
{
15311543
dataViewer->setStatusText(
1532-
tr("Cannot open or create ")
1544+
tr("Cannot access ")
15331545
+ QFileInfo(fileName).fileName()
15341546
+ ":<br/><span style=\" color:#ff0000;\">"
1535-
+ db.lastError().text());
1547+
+ query.lastError().text()
1548+
+ "<br/></span>"
1549+
+ tr("It is probably not a database."));
15361550
QSqlQuery qundo(QString("DETACH DATABASE ")
15371551
+ Utils::q(schema)
15381552
+ ";",
1539-
db);
1540-
attachedDb.remove(schema);
1553+
QSqlDatabase::database(SESSION_NAME));
15411554
}
15421555
else
15431556
{
1544-
QSqlQuery q("select 1 from sqlite_master where 1=2", db);
1545-
if (!q.exec())
1546-
{
1547-
dataViewer->setStatusText(
1548-
tr("Cannot access ")
1549-
+ QFileInfo(fileName).fileName()
1550-
+ ":<br/><span style=\" color:#ff0000;\">"
1551-
+ db.lastError().text()
1552-
+ "<br/></span>"
1553-
+ tr("It is probably not a database."));
1554-
QSqlQuery qundo(QString("DETACH DATABASE ")
1555-
+ Utils::q(schema)
1556-
+ ";",
1557-
db);
1558-
db.close();
1559-
attachedDb.remove(schema);
1560-
}
1561-
else
1562-
{
1563-
schemaBrowser->tableTree->buildDatabase(schema);
1564-
queryEditor->treeChanged();
1565-
}
1557+
schemaBrowser->tableTree->buildDatabase(schema);
1558+
queryEditor->treeChanged();
15661559
}
15671560
}
15681561
}
@@ -1589,9 +1582,6 @@ void LiteManWindow::detachDatabase()
15891582
}
15901583
else
15911584
{
1592-
QSqlDatabase::database(attachedDb[dbname]).rollback();
1593-
QSqlDatabase::database(attachedDb[dbname]).close();
1594-
attachedDb.remove(dbname);
15951585
// this removes the item from the tree as well as deleting it
15961586
delete schemaBrowser->tableTree->currentItem();
15971587
queryEditor->treeChanged();

Sqliteman/sqliteman/litemanwindow.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,6 @@ class LiteManWindow : public QMainWindow
177177
// \brief True if is sqlite3 binary available in the path
178178
// bool m_sqliteBinAvailable;
179179

180-
/*! \brief alias name - connection name mappings
181-
It's used for mapping of the attached databases for QSqlTableModel
182-
as it does not support database.table naming schema */
183-
QMap<QString,QString> attachedDb;
184-
185180
DataViewer * dataViewer;
186181
QSplitter * splitter;
187182
SchemaBrowser * schemaBrowser;

Sqliteman/sqliteman/sqlmodels.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,14 @@ void SqlTableModel::setTable(const QString &tableName)
350350
m_header[colnum] = SqlTableModel::None;
351351
++colnum;
352352
}
353-
354-
QSqlTableModel::setTable(tableName);
353+
if (m_schema.isEmpty())
354+
{
355+
QSqlTableModel::setTable(tableName);
356+
}
357+
else
358+
{
359+
QSqlTableModel::setTable(m_schema + "." + tableName);
360+
}
355361
}
356362

357363
void SqlTableModel::detach (SqlTableModel * model)

0 commit comments

Comments
 (0)