Skip to content

Commit 532fcd3

Browse files
committed
Add initial support for multiple database schemata
This adds initial basic support for handling different database schemata at once to the backend code. This is still far from working properly but shouldn't break much either - mostly because it's not really used yet in the user interface code.
1 parent 4339119 commit 532fcd3

16 files changed

Lines changed: 266 additions & 186 deletions

src/DbStructureModel.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ void DbStructureModel::reloadData()
142142

143143
QTreeWidgetItem* itemBrowsables = new QTreeWidgetItem(rootItem);
144144
itemBrowsables->setIcon(0, QIcon(QString(":/icons/view")));
145-
itemBrowsables->setText(0, tr("Browsables (%1)").arg(m_db.objMap.values("table").count() + m_db.objMap.values("view").count()));
145+
itemBrowsables->setText(0, tr("Browsables (%1)").arg(m_db.schemata["main"].values("table").count() + m_db.schemata["main"].values("view").count()));
146146
typeToParentItem.insert("browsable", itemBrowsables);
147147

148148
QTreeWidgetItem* itemAll = new QTreeWidgetItem(rootItem);
@@ -151,27 +151,27 @@ void DbStructureModel::reloadData()
151151

152152
QTreeWidgetItem* itemTables = new QTreeWidgetItem(itemAll);
153153
itemTables->setIcon(0, QIcon(QString(":/icons/table")));
154-
itemTables->setText(0, tr("Tables (%1)").arg(m_db.objMap.values("table").count()));
154+
itemTables->setText(0, tr("Tables (%1)").arg(m_db.schemata["main"].values("table").count()));
155155
typeToParentItem.insert("table", itemTables);
156156

157157
QTreeWidgetItem* itemIndices = new QTreeWidgetItem(itemAll);
158158
itemIndices->setIcon(0, QIcon(QString(":/icons/index")));
159-
itemIndices->setText(0, tr("Indices (%1)").arg(m_db.objMap.values("index").count()));
159+
itemIndices->setText(0, tr("Indices (%1)").arg(m_db.schemata["main"].values("index").count()));
160160
typeToParentItem.insert("index", itemIndices);
161161

162162
QTreeWidgetItem* itemViews = new QTreeWidgetItem(itemAll);
163163
itemViews->setIcon(0, QIcon(QString(":/icons/view")));
164-
itemViews->setText(0, tr("Views (%1)").arg(m_db.objMap.values("view").count()));
164+
itemViews->setText(0, tr("Views (%1)").arg(m_db.schemata["main"].values("view").count()));
165165
typeToParentItem.insert("view", itemViews);
166166

167167
QTreeWidgetItem* itemTriggers = new QTreeWidgetItem(itemAll);
168168
itemTriggers->setIcon(0, QIcon(QString(":/icons/trigger")));
169-
itemTriggers->setText(0, tr("Triggers (%1)").arg(m_db.objMap.values("trigger").count()));
169+
itemTriggers->setText(0, tr("Triggers (%1)").arg(m_db.schemata["main"].values("trigger").count()));
170170
typeToParentItem.insert("trigger", itemTriggers);
171171

172172
// Get all database objects and sort them by their name
173173
QMultiMap<QString, sqlb::ObjectPtr> dbobjs;
174-
for(auto it=m_db.objMap.constBegin(); it != m_db.objMap.constEnd(); ++it)
174+
for(auto it=m_db.schemata["main"].constBegin(); it != m_db.schemata["main"].constEnd(); ++it)
175175
dbobjs.insert((*it)->name(), (*it));
176176

177177
// Add the actual table objects
@@ -238,7 +238,7 @@ QMimeData* DbStructureModel::mimeData(const QModelIndexList& indices) const
238238
if(data(index.sibling(index.row(), 1), Qt::DisplayRole).toString() == "table")
239239
{
240240
SqliteTableModel tableModel(m_db);
241-
tableModel.setTable(data(index.sibling(index.row(), 0), Qt::DisplayRole).toString());
241+
tableModel.setTable(sqlb::ObjectIdentifier("main", data(index.sibling(index.row(), 0), Qt::DisplayRole).toString()));
242242
for(int i=0; i < tableModel.rowCount(); ++i)
243243
{
244244
QString insertStatement = "INSERT INTO " + sqlb::escapeIdentifier(data(index.sibling(index.row(), 0), Qt::DisplayRole).toString()) + " VALUES(";

src/EditIndexDialog.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ EditIndexDialog::EditIndexDialog(DBBrowserDB& db, const QString& indexName, bool
1919

2020
// Get list of tables, sort it alphabetically and fill the combobox
2121
objectMap dbobjs;
22-
QList<sqlb::ObjectPtr> tables = pdb.objMap.values("table");
22+
QList<sqlb::ObjectPtr> tables = pdb.schemata["main"].values("table");
2323
for(auto it=tables.constBegin();it!=tables.constEnd();++it)
2424
dbobjs.insert((*it)->name(), (*it));
2525
ui->comboTableName->blockSignals(true);
@@ -34,7 +34,7 @@ EditIndexDialog::EditIndexDialog(DBBrowserDB& db, const QString& indexName, bool
3434
if(!newIndex)
3535
{
3636
// Load the current layout and fill in the dialog fields
37-
index = *(pdb.getObjectByName(curIndex).dynamicCast<sqlb::Index>());
37+
index = *(pdb.getObjectByName(sqlb::ObjectIdentifier("main", curIndex)).dynamicCast<sqlb::Index>());
3838

3939
ui->editIndexName->blockSignals(true);
4040
ui->editIndexName->setText(index.name());
@@ -94,7 +94,7 @@ void EditIndexDialog::tableChanged(const QString& new_table, bool initialLoad)
9494
void EditIndexDialog::updateColumnLists()
9595
{
9696
// Fill the table column list
97-
sqlb::FieldInfoList tableFields = pdb.getObjectByName(index.table()).dynamicCast<sqlb::Table>()->fieldInformation();
97+
sqlb::FieldInfoList tableFields = pdb.getObjectByName(sqlb::ObjectIdentifier("main", index.table())).dynamicCast<sqlb::Table>()->fieldInformation();
9898
ui->tableTableColumns->setRowCount(tableFields.size());
9999
int tableRows = 0;
100100
for(int i=0;i<tableFields.size();++i)

src/EditTableDialog.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ EditTableDialog::EditTableDialog(DBBrowserDB& db, const QString& tableName, bool
3333
if(m_bNewTable == false)
3434
{
3535
// Existing table, so load and set the current layout
36-
m_table = *(pdb.getObjectByName(curTable).dynamicCast<sqlb::Table>());
36+
m_table = *(pdb.getObjectByName(sqlb::ObjectIdentifier("main", curTable)).dynamicCast<sqlb::Table>());
3737
ui->labelEditWarning->setVisible(!m_table.fullyParsed());
3838

3939
// Set without rowid and temporary checkboxex. No need to trigger any events here as we're only loading a table exactly as it is stored by SQLite, so no need
@@ -163,7 +163,7 @@ void EditTableDialog::accept()
163163
// Rename table if necessary
164164
if(ui->editTableName->text() != curTable)
165165
{
166-
if(!pdb.renameTable(curTable, ui->editTableName->text()))
166+
if(!pdb.renameTable("main", curTable, ui->editTableName->text()))
167167
{
168168
QMessageBox::warning(this, QApplication::applicationName(), pdb.lastError());
169169
return;
@@ -210,7 +210,7 @@ void EditTableDialog::checkInput()
210210
if (oldTableName == fk->table()) {
211211
fk->setTable(normTableName);
212212
if(!fksEnabled)
213-
pdb.renameColumn(curTable, m_table, f->name(), f, 0);
213+
pdb.renameColumn(sqlb::ObjectIdentifier("main", curTable), m_table, f->name(), f, 0);
214214
}
215215
}
216216
}
@@ -239,7 +239,7 @@ void EditTableDialog::updateTypes()
239239

240240
m_table.fields().at(index)->setType(type);
241241
if(!m_bNewTable)
242-
pdb.renameColumn(curTable, m_table, column, m_table.fields().at(index));
242+
pdb.renameColumn(sqlb::ObjectIdentifier("main", curTable), m_table, column, m_table.fields().at(index));
243243
checkInput();
244244
}
245245
}
@@ -279,7 +279,7 @@ void EditTableDialog::itemChanged(QTreeWidgetItem *item, int column)
279279
if(!m_bNewTable)
280280
{
281281
sqlb::FieldVector pk = m_table.primaryKey();
282-
foreach(const sqlb::ObjectPtr& fkobj, pdb.objMap.values("table"))
282+
foreach(const sqlb::ObjectPtr& fkobj, pdb.schemata["main"].values("table"))
283283
{
284284
QList<sqlb::ConstraintPtr> fks = fkobj.dynamicCast<sqlb::Table>()->constraints(sqlb::FieldVector(), sqlb::Constraint::ForeignKeyConstraintType);
285285
foreach(sqlb::ConstraintPtr fkptr, fks)
@@ -352,8 +352,9 @@ void EditTableDialog::itemChanged(QTreeWidgetItem *item, int column)
352352
// we need to check for this case and cancel here. Maybe we can think of some way to modify the INSERT INTO ... SELECT statement
353353
// to at least replace all troublesome NULL values by the default value
354354
SqliteTableModel m(pdb, this);
355-
m.setQuery(QString("SELECT COUNT(%1) FROM %2 WHERE %3 IS NULL;")
356-
.arg(sqlb::escapeIdentifier(pdb.getObjectByName(curTable).dynamicCast<sqlb::Table>()->rowidColumn()))
355+
m.setQuery(QString("SELECT COUNT(%1) FROM %2.%3 WHERE %4 IS NULL;")
356+
.arg(sqlb::escapeIdentifier(pdb.getObjectByName(sqlb::ObjectIdentifier("main", curTable)).dynamicCast<sqlb::Table>()->rowidColumn()))
357+
.arg(sqlb::escapeIdentifier("main"))
357358
.arg(sqlb::escapeIdentifier(curTable))
358359
.arg(sqlb::escapeIdentifier(field->name())));
359360
if(m.data(m.index(0, 0)).toInt() > 0)
@@ -489,7 +490,7 @@ void EditTableDialog::itemChanged(QTreeWidgetItem *item, int column)
489490

490491
if(callRenameColumn)
491492
{
492-
if(!pdb.renameColumn(curTable, m_table, oldFieldName, field))
493+
if(!pdb.renameColumn(sqlb::ObjectIdentifier("main", curTable), m_table, oldFieldName, field))
493494
QMessageBox::warning(this, qApp->applicationName(), tr("Modifying this column failed. Error returned from database:\n%1").arg(pdb.lastError()));
494495
}
495496
}
@@ -548,7 +549,7 @@ void EditTableDialog::addField()
548549

549550
// Actually add the new column to the table if we're editing an existing table
550551
if(!m_bNewTable)
551-
pdb.addColumn(curTable, f);
552+
pdb.addColumn(sqlb::ObjectIdentifier("main", curTable), f);
552553

553554
checkInput();
554555
}
@@ -576,12 +577,12 @@ void EditTableDialog::removeField()
576577
QString msg = tr("Are you sure you want to delete the field '%1'?\nAll data currently stored in this field will be lost.").arg(ui->treeWidget->currentItem()->text(0));
577578
if(QMessageBox::warning(this, QApplication::applicationName(), msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes)
578579
{
579-
if(!pdb.renameColumn(curTable, m_table, ui->treeWidget->currentItem()->text(0), sqlb::FieldPtr()))
580+
if(!pdb.renameColumn(sqlb::ObjectIdentifier("main", curTable), m_table, ui->treeWidget->currentItem()->text(0), sqlb::FieldPtr()))
580581
{
581582
QMessageBox::warning(0, QApplication::applicationName(), pdb.lastError());
582583
} else {
583584
//relayout
584-
m_table = *(pdb.getObjectByName(curTable).dynamicCast<sqlb::Table>());
585+
m_table = *(pdb.getObjectByName(sqlb::ObjectIdentifier("main", curTable)).dynamicCast<sqlb::Table>());
585586
populateFields();
586587
}
587588
}
@@ -654,7 +655,7 @@ void EditTableDialog::moveCurrentField(bool down)
654655

655656
// Move the actual column
656657
if(!pdb.renameColumn(
657-
curTable,
658+
sqlb::ObjectIdentifier("main", curTable),
658659
m_table,
659660
ui->treeWidget->currentItem()->text(0),
660661
m_table.fields().at(ui->treeWidget->indexOfTopLevelItem(ui->treeWidget->currentItem())),
@@ -664,7 +665,7 @@ void EditTableDialog::moveCurrentField(bool down)
664665
QMessageBox::warning(0, QApplication::applicationName(), pdb.lastError());
665666
} else {
666667
// Reload table SQL
667-
m_table = *(pdb.getObjectByName(curTable).dynamicCast<sqlb::Table>());
668+
m_table = *(pdb.getObjectByName(sqlb::ObjectIdentifier("main", curTable)).dynamicCast<sqlb::Table>());
668669
populateFields();
669670

670671
// Select old item at new position
@@ -710,7 +711,7 @@ void EditTableDialog::setWithoutRowid(bool without_rowid)
710711
// Update table if we're editing an existing table
711712
if(!m_bNewTable)
712713
{
713-
if(!pdb.renameColumn(curTable, m_table, QString(), sqlb::FieldPtr(), 0))
714+
if(!pdb.renameColumn(sqlb::ObjectIdentifier("main", curTable), m_table, QString(), sqlb::FieldPtr(), 0))
714715
{
715716
QMessageBox::warning(this, QApplication::applicationName(),
716717
tr("Setting the rowid column for the table failed. Error message:\n%1").arg(pdb.lastError()));
@@ -729,7 +730,7 @@ void EditTableDialog::setTemporary(bool is_temp)
729730
// Update table if we're editing an existing table
730731
if(!m_bNewTable)
731732
{
732-
if(!pdb.renameColumn(curTable, m_table, QString(), sqlb::FieldPtr(), 0))
733+
if(!pdb.renameColumn(sqlb::ObjectIdentifier("main", curTable), m_table, QString(), sqlb::FieldPtr(), 0))
733734
{
734735
QMessageBox::warning(this, QApplication::applicationName(),
735736
tr("Setting the temporary flag for the table failed. Error message:\n%1").arg(pdb.lastError()));

src/ExportDataDialog.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ ExportDataDialog::ExportDataDialog(DBBrowserDB& db, ExportFormats format, QWidge
4242
if(query.isEmpty())
4343
{
4444
// Get list of tables to export
45-
objectMap objects = pdb.getBrowsableObjects();
45+
objectMap objects = pdb.getBrowsableObjects("main");
4646
foreach(const sqlb::ObjectPtr& obj, objects)
4747
ui->listTables->addItem(new QListWidgetItem(QIcon(QString(":icons/%1").arg(sqlb::Object::typeToString(obj->type()))), obj->name()));
4848

src/ExportSqlDialog.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,9 @@ ExportSqlDialog::ExportSqlDialog(DBBrowserDB* db, QWidget* parent, const QString
3434
ui->comboOldSchema->setCurrentIndex(settings.value(sSettingsOldSchema, 0).toInt());
3535

3636
// Get list of tables to export
37-
objectMap objects = pdb->getBrowsableObjects();
38-
for(auto it=objects.constBegin();it!=objects.constEnd();++it) {
37+
objectMap objects = pdb->getBrowsableObjects("main");
38+
for(auto it=objects.constBegin();it!=objects.constEnd();++it)
3939
ui->listTables->addItem(new QListWidgetItem(QIcon(QString(":icons/%1").arg((*it)->type())), (*it)->name()));
40-
}
4140

4241
// Sort list of tables and select the table specified in the
4342
// selection parameter or all tables if table not specified

src/ForeignKeyEditorDelegate.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ ForeignKeyEditorDelegate::ForeignKeyEditorDelegate(const DBBrowserDB& db, sqlb::
8181
, m_db(db)
8282
, m_table(table)
8383
{
84-
const auto objects = m_db.getBrowsableObjects();
84+
const auto objects = m_db.getBrowsableObjects("main");
8585
for (auto& obj : objects) {
8686
if (obj->type() == sqlb::Object::Types::Table) {
8787
QString tableName = obj->name();

src/ImportCsvDialog.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ void ImportCsvDialog::importCsv(const QString& fileName, const QString &name)
394394

395395
// Are we importing into an existing table?
396396
bool importToExistingTable = false;
397-
const sqlb::ObjectPtr obj = pdb->getObjectByName(tableName);
397+
const sqlb::ObjectPtr obj = pdb->getObjectByName(sqlb::ObjectIdentifier("main", tableName));
398398
if(obj && obj->type() == sqlb::Object::Types::Table)
399399
{
400400
if((size_t)obj.dynamicCast<sqlb::Table>()->fields().size() != csv.columns())
@@ -425,14 +425,14 @@ void ImportCsvDialog::importCsv(const QString& fileName, const QString &name)
425425
QStringList nullValues;
426426
if(!importToExistingTable)
427427
{
428-
if(!pdb->createTable(tableName, fieldList))
428+
if(!pdb->createTable(sqlb::ObjectIdentifier("main", tableName), fieldList))
429429
return rollback(this, pdb, progress, restorepointName, 0, tr("Creating the table failed: %1").arg(pdb->lastError()));
430430
} else {
431431
// Importing into an existing table. So find out something about it's structure.
432432

433433
// Prepare the values for each table column that are to be inserted if the field in the CSV file is empty. Depending on the data type
434434
// and the constraints of a field, we need to handle this case differently.
435-
sqlb::TablePtr tbl = pdb->getObjectByName(tableName).dynamicCast<sqlb::Table>();
435+
sqlb::TablePtr tbl = pdb->getObjectByName(sqlb::ObjectIdentifier("main", tableName)).dynamicCast<sqlb::Table>();
436436
if(tbl)
437437
{
438438
foreach(const sqlb::FieldPtr& f, tbl->fields())

0 commit comments

Comments
 (0)