mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-01-19 18:40:13 -06:00
Use even less Qt containers
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <QMessageBox>
|
||||
#include <QApplication>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
|
||||
DbStructureModel::DbStructureModel(DBBrowserDB& db, QObject* parent)
|
||||
: QAbstractItemModel(parent),
|
||||
@@ -170,7 +171,7 @@ void DbStructureModel::reloadData()
|
||||
buildTree(itemAll, "main");
|
||||
|
||||
// Add the temporary database as a node if it isn't empty. Make sure it's always second if it exists.
|
||||
if(!m_db.schemata["temp"].isEmpty())
|
||||
if(!m_db.schemata["temp"].empty())
|
||||
{
|
||||
QTreeWidgetItem* itemTemp = new QTreeWidgetItem(itemAll);
|
||||
itemTemp->setIcon(ColumnName, QIcon(QString(":/icons/database")));
|
||||
@@ -180,16 +181,16 @@ void DbStructureModel::reloadData()
|
||||
}
|
||||
|
||||
// Now load all the other schemata last
|
||||
for(auto it=m_db.schemata.constBegin();it!=m_db.schemata.constEnd();++it)
|
||||
for(const auto& it : m_db.schemata)
|
||||
{
|
||||
// Don't load the main and temp schema again
|
||||
if(it.key() != "main" && it.key() != "temp")
|
||||
if(it.first != "main" && it.first != "temp")
|
||||
{
|
||||
QTreeWidgetItem* itemSchema = new QTreeWidgetItem(itemAll);
|
||||
itemSchema->setIcon(ColumnName, QIcon(QString(":/icons/database")));
|
||||
itemSchema->setText(ColumnName, QString::fromStdString(it.key()));
|
||||
itemSchema->setText(ColumnName, QString::fromStdString(it.first));
|
||||
itemSchema->setText(ColumnObjectType, "database");
|
||||
buildTree(itemSchema, it.key());
|
||||
buildTree(itemSchema, it.first);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,6 +302,15 @@ bool DbStructureModel::dropMimeData(const QMimeData* data, Qt::DropAction action
|
||||
}
|
||||
}
|
||||
|
||||
static long calc_number_of_objects_by_type(const objectMap& objmap, const std::string& type)
|
||||
{
|
||||
auto objects = objmap.equal_range(type);
|
||||
if(objects.first == objmap.end())
|
||||
return 0;
|
||||
else
|
||||
return std::distance(objects.first, objects.second) + 1;
|
||||
}
|
||||
|
||||
void DbStructureModel::buildTree(QTreeWidgetItem* parent, const std::string& schema)
|
||||
{
|
||||
// Build a map from object type to tree node to simplify finding the correct tree node later
|
||||
@@ -312,32 +322,34 @@ void DbStructureModel::buildTree(QTreeWidgetItem* parent, const std::string& sch
|
||||
// Prepare tree
|
||||
QTreeWidgetItem* itemTables = new QTreeWidgetItem(parent);
|
||||
itemTables->setIcon(ColumnName, QIcon(QString(":/icons/table")));
|
||||
itemTables->setText(ColumnName, tr("Tables (%1)").arg(objmap.values("table").count()));
|
||||
itemTables->setText(ColumnName, tr("Tables (%1)").arg(calc_number_of_objects_by_type(objmap, "table")));
|
||||
typeToParentItem.insert({"table", itemTables});
|
||||
|
||||
QTreeWidgetItem* itemIndices = new QTreeWidgetItem(parent);
|
||||
itemIndices->setIcon(ColumnName, QIcon(QString(":/icons/index")));
|
||||
itemIndices->setText(ColumnName, tr("Indices (%1)").arg(objmap.values("index").count()));
|
||||
itemIndices->setText(ColumnName, tr("Indices (%1)").arg(calc_number_of_objects_by_type(objmap, "index")));
|
||||
typeToParentItem.insert({"index", itemIndices});
|
||||
|
||||
QTreeWidgetItem* itemViews = new QTreeWidgetItem(parent);
|
||||
itemViews->setIcon(ColumnName, QIcon(QString(":/icons/view")));
|
||||
itemViews->setText(ColumnName, tr("Views (%1)").arg(objmap.values("view").count()));
|
||||
itemViews->setText(ColumnName, tr("Views (%1)").arg(calc_number_of_objects_by_type(objmap, "view")));
|
||||
typeToParentItem.insert({"view", itemViews});
|
||||
|
||||
QTreeWidgetItem* itemTriggers = new QTreeWidgetItem(parent);
|
||||
itemTriggers->setIcon(ColumnName, QIcon(QString(":/icons/trigger")));
|
||||
itemTriggers->setText(ColumnName, tr("Triggers (%1)").arg(objmap.values("trigger").count()));
|
||||
itemTriggers->setText(ColumnName, tr("Triggers (%1)").arg(calc_number_of_objects_by_type(objmap, "trigger")));
|
||||
typeToParentItem.insert({"trigger", itemTriggers});
|
||||
|
||||
// Get all database objects and sort them by their name
|
||||
QMultiMap<std::string, sqlb::ObjectPtr> dbobjs;
|
||||
for(auto it : objmap)
|
||||
dbobjs.insert(it->name(), it);
|
||||
std::map<std::string, sqlb::ObjectPtr> dbobjs;
|
||||
for(const auto& it : objmap)
|
||||
dbobjs.insert({it.second->name(), it.second});
|
||||
|
||||
// Add the database objects to the tree nodes
|
||||
for(auto it : dbobjs)
|
||||
for(const auto& obj : dbobjs)
|
||||
{
|
||||
sqlb::ObjectPtr it = obj.second;
|
||||
|
||||
// Object node
|
||||
QTreeWidgetItem* item = addNode(typeToParentItem.at(sqlb::Object::typeToString(it->type())), it, schema);
|
||||
|
||||
|
||||
@@ -22,22 +22,22 @@ EditIndexDialog::EditIndexDialog(DBBrowserDB& db, const sqlb::ObjectIdentifier&
|
||||
std::map<std::string, sqlb::ObjectIdentifier> dbobjs; // Map from display name to full object identifier
|
||||
if(newIndex) // If this is a new index, offer all tables of all database schemata
|
||||
{
|
||||
for(auto it=pdb.schemata.constBegin();it!=pdb.schemata.constEnd();++it)
|
||||
for(const auto& it : pdb.schemata)
|
||||
{
|
||||
QList<sqlb::ObjectPtr> tables = it->values("table");
|
||||
for(auto jt=tables.constBegin();jt!=tables.constEnd();++jt)
|
||||
auto tables = it.second.equal_range("table");
|
||||
for(auto jt=tables.first;jt!=tables.second;++jt)
|
||||
{
|
||||
// Only show the schema name for non-main schemata
|
||||
sqlb::ObjectIdentifier obj(it.key(), (*jt)->name());
|
||||
sqlb::ObjectIdentifier obj(it.first, jt->second->name());
|
||||
dbobjs.insert({obj.toDisplayString(), obj});
|
||||
}
|
||||
}
|
||||
} else { // If this is an existing index, only offer tables of the current database schema
|
||||
QList<sqlb::ObjectPtr> tables = pdb.schemata[curIndex.schema()].values("table");
|
||||
for(auto it : tables)
|
||||
auto tables = pdb.schemata[curIndex.schema()].equal_range("table");
|
||||
for(auto it=tables.first;it!=tables.second;++it)
|
||||
{
|
||||
// Only show the schema name for non-main schemata
|
||||
sqlb::ObjectIdentifier obj(curIndex.schema(), it->name());
|
||||
sqlb::ObjectIdentifier obj(curIndex.schema(), it->second->name());
|
||||
dbobjs.insert({obj.toDisplayString(), obj});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,16 +51,16 @@ EditTableDialog::EditTableDialog(DBBrowserDB& db, const sqlb::ObjectIdentifier&
|
||||
ui->checkWithoutRowid->setChecked(m_table.withoutRowidTable());
|
||||
ui->checkWithoutRowid->blockSignals(false);
|
||||
ui->comboSchema->blockSignals(true);
|
||||
for(const auto& n : pdb.schemata.keys()) // Load list of database schemata
|
||||
ui->comboSchema->addItem(QString::fromStdString(n));
|
||||
for(const auto& n : pdb.schemata) // Load list of database schemata
|
||||
ui->comboSchema->addItem(QString::fromStdString(n.first));
|
||||
ui->comboSchema->setCurrentText(QString::fromStdString(curTable.schema()));
|
||||
ui->comboSchema->blockSignals(false);
|
||||
|
||||
populateFields();
|
||||
populateConstraints();
|
||||
} else {
|
||||
for(const auto& n : pdb.schemata.keys()) // Load list of database schemata
|
||||
ui->comboSchema->addItem(QString::fromStdString(n));
|
||||
for(const auto& n : pdb.schemata) // Load list of database schemata
|
||||
ui->comboSchema->addItem(QString::fromStdString(n.first));
|
||||
ui->comboSchema->setCurrentText("main"); // Always create tables in the main schema by default
|
||||
ui->labelEditWarning->setVisible(false);
|
||||
}
|
||||
@@ -363,8 +363,12 @@ void EditTableDialog::itemChanged(QTreeWidgetItem *item, int column)
|
||||
if(!m_bNewTable)
|
||||
{
|
||||
sqlb::StringVector pk = m_table.primaryKey();
|
||||
for(const sqlb::ObjectPtr& fkobj : pdb.schemata[curTable.schema()].values("table"))
|
||||
const auto tables = pdb.schemata[curTable.schema()].equal_range("table");
|
||||
for(auto it=tables.first;it!=tables.second;++it)
|
||||
{
|
||||
const sqlb::ObjectPtr& fkobj = it->second;
|
||||
|
||||
|
||||
auto fks = std::dynamic_pointer_cast<sqlb::Table>(fkobj)->constraints(sqlb::StringVector(), sqlb::Constraint::ForeignKeyConstraintType);
|
||||
for(const sqlb::ConstraintPtr& fkptr : fks)
|
||||
{
|
||||
@@ -394,10 +398,10 @@ void EditTableDialog::itemChanged(QTreeWidgetItem *item, int column)
|
||||
// Update the field name in the map of old column names to new column names
|
||||
if(!m_bNewTable)
|
||||
{
|
||||
for(const auto& key : trackColumns.keys())
|
||||
for(const auto& it : trackColumns)
|
||||
{
|
||||
if(trackColumns[key] == oldFieldName)
|
||||
trackColumns[key] = QString::fromStdString(field.name());
|
||||
if(trackColumns[it.first] == oldFieldName)
|
||||
trackColumns[it.first] = QString::fromStdString(field.name());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -651,7 +655,7 @@ void EditTableDialog::addField()
|
||||
|
||||
// Add the new column to the list of tracked columns to indicate it has been added
|
||||
if(!m_bNewTable)
|
||||
trackColumns.insert(QString(), tbitem->text(kName));
|
||||
trackColumns.insert({QString(), tbitem->text(kName)});
|
||||
|
||||
checkInput();
|
||||
}
|
||||
@@ -671,10 +675,10 @@ void EditTableDialog::removeField()
|
||||
|
||||
// Update the map of tracked columns to indicate the column is deleted
|
||||
QString name = ui->treeWidget->currentItem()->text(0);
|
||||
for(const auto& key : trackColumns.keys())
|
||||
for(const auto& it : trackColumns)
|
||||
{
|
||||
if(trackColumns[key] == name)
|
||||
trackColumns[key] = QString();
|
||||
if(trackColumns[it.first] == name)
|
||||
trackColumns[it.first] = QString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
#include "sql/ObjectIdentifier.h"
|
||||
#include "sql/sqlitetypes.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QMap>
|
||||
|
||||
class DBBrowserDB;
|
||||
class QTreeWidgetItem;
|
||||
@@ -74,7 +75,7 @@ private:
|
||||
DBBrowserDB& pdb;
|
||||
ForeignKeyEditorDelegate* m_fkEditorDelegate;
|
||||
sqlb::ObjectIdentifier curTable;
|
||||
QMap<QString, QString> trackColumns;
|
||||
std::map<QString, QString> trackColumns;
|
||||
sqlb::Table m_table;
|
||||
bool m_bNewTable;
|
||||
QString m_sRestorePointName;
|
||||
|
||||
@@ -43,13 +43,20 @@ ExportDataDialog::ExportDataDialog(DBBrowserDB& db, ExportFormats format, QWidge
|
||||
if(query.isEmpty())
|
||||
{
|
||||
// Get list of tables to export
|
||||
for(auto it=pdb.schemata.constBegin();it!=pdb.schemata.constEnd();++it)
|
||||
for(const auto& it : pdb.schemata)
|
||||
{
|
||||
QList<sqlb::ObjectPtr> tables = it->values("table") + it->values("view");
|
||||
for(auto jt=tables.constBegin();jt!=tables.constEnd();++jt)
|
||||
const auto tables = it.second.equal_range("table");
|
||||
const auto views = it.second.equal_range("view");
|
||||
std::map<std::string, sqlb::ObjectPtr> objects;
|
||||
for(auto jt=tables.first;jt!=tables.second;++jt)
|
||||
objects.insert({jt->second->name(), jt->second});
|
||||
for(auto jt=views.first;jt!=views.second;++jt)
|
||||
objects.insert({jt->second->name(), jt->second});
|
||||
|
||||
for(const auto& jt : objects)
|
||||
{
|
||||
sqlb::ObjectIdentifier obj(it.key(), (*jt)->name());
|
||||
QListWidgetItem* item = new QListWidgetItem(QIcon(QString(":icons/%1").arg(QString::fromStdString(sqlb::Object::typeToString((*jt)->type())))), QString::fromStdString(obj.toDisplayString()));
|
||||
sqlb::ObjectIdentifier obj(it.first, jt.second->name());
|
||||
QListWidgetItem* item = new QListWidgetItem(QIcon(QString(":icons/%1").arg(QString::fromStdString(sqlb::Object::typeToString(jt.second->type())))), QString::fromStdString(obj.toDisplayString()));
|
||||
item->setData(Qt::UserRole, QString::fromStdString(obj.toSerialised()));
|
||||
ui->listTables->addItem(item);
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ ExportSqlDialog::ExportSqlDialog(DBBrowserDB* db, QWidget* parent, const QString
|
||||
ui->comboOldSchema->setCurrentIndex(Settings::getValue("exportsql", "oldschema").toInt());
|
||||
|
||||
// Get list of tables to export
|
||||
QList<sqlb::ObjectPtr> objects = pdb->schemata["main"].values("table");
|
||||
for(const sqlb::ObjectPtr& it : objects)
|
||||
ui->listTables->addItem(new QListWidgetItem(QIcon(QString(":icons/%1").arg(QString::fromStdString(sqlb::Object::typeToString(it->type())))), QString::fromStdString(it->name())));
|
||||
const auto objects = pdb->schemata["main"].equal_range("table");
|
||||
for(auto it=objects.first;it!=objects.second;++it)
|
||||
ui->listTables->addItem(new QListWidgetItem(QIcon(QString(":icons/%1").arg(QString::fromStdString(sqlb::Object::typeToString(it->second->type())))), QString::fromStdString(it->second->name())));
|
||||
|
||||
// Sort list of tables and select the table specified in the
|
||||
// selection parameter or all tables if table not specified
|
||||
|
||||
@@ -81,12 +81,12 @@ ForeignKeyEditorDelegate::ForeignKeyEditorDelegate(const DBBrowserDB& db, sqlb::
|
||||
, m_db(db)
|
||||
, m_table(table)
|
||||
{
|
||||
for(auto it=m_db.schemata.constBegin();it!=m_db.schemata.constEnd();++it)
|
||||
for(const auto& it : m_db.schemata)
|
||||
{
|
||||
for(auto jt=it->constBegin();jt!=it->constEnd();++jt)
|
||||
for(const auto& jt : it.second)
|
||||
{
|
||||
if((*jt)->type() == sqlb::Object::Types::Table)
|
||||
m_tablesIds.insert({(*jt)->name(), std::dynamic_pointer_cast<sqlb::Table>(*jt)->fieldNames()});
|
||||
if(jt.second->type() == sqlb::Object::Types::Table)
|
||||
m_tablesIds.insert({jt.second->name(), std::dynamic_pointer_cast<sqlb::Table>(jt.second)->fieldNames()});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -661,19 +661,19 @@ void MainWindow::populateStructure(const QString& old_table)
|
||||
|
||||
// Update table and column names for syntax highlighting
|
||||
SqlUiLexer::QualifiedTablesMap qualifiedTablesMap;
|
||||
for(auto it=db.schemata.constBegin();it!=db.schemata.constEnd();++it)
|
||||
for(const auto& it : db.schemata)
|
||||
{
|
||||
SqlUiLexer::TablesAndColumnsMap tablesToColumnsMap;
|
||||
objectMap tab = db.getBrowsableObjects(it.key());
|
||||
for(auto jt : tab)
|
||||
objectMap tab = db.getBrowsableObjects(it.first);
|
||||
for(const auto& jt : tab)
|
||||
{
|
||||
QString objectname = QString::fromStdString(jt->name());
|
||||
QString objectname = QString::fromStdString(jt.second->name());
|
||||
|
||||
sqlb::FieldInfoList fi = jt->fieldInformation();
|
||||
sqlb::FieldInfoList fi = jt.second->fieldInformation();
|
||||
for(const sqlb::FieldInfo& f : fi)
|
||||
tablesToColumnsMap[objectname].push_back(QString::fromStdString(f.name));
|
||||
}
|
||||
qualifiedTablesMap[QString::fromStdString(it.key())] = tablesToColumnsMap;
|
||||
qualifiedTablesMap[QString::fromStdString(it.first)] = tablesToColumnsMap;
|
||||
}
|
||||
SqlTextEdit::sqlLexer->setTableNames(qualifiedTablesMap);
|
||||
ui->editLogApplication->reloadKeywords();
|
||||
|
||||
@@ -15,11 +15,11 @@ VacuumDialog::VacuumDialog(DBBrowserDB* _db, QWidget* parent) :
|
||||
// Show warning if DB is dirty
|
||||
ui->labelSavepointWarning->setVisible(db->getDirty());
|
||||
|
||||
// Populate list of objects to compact. We just support vacuuming the main schema here.
|
||||
for(auto it=db->schemata.constBegin();it!=db->schemata.constEnd();++it)
|
||||
// Populate list of objects to compact. We just support vacuuming the different schemas here.
|
||||
for(const auto& it : db->schemata)
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem(ui->treeDatabases);
|
||||
item->setText(0, QString::fromStdString(it.key()));
|
||||
item->setText(0, QString::fromStdString(it.first));
|
||||
item->setIcon(0, QIcon(QString(":icons/database")));
|
||||
ui->treeDatabases->addTopLevelItem(item);
|
||||
}
|
||||
|
||||
@@ -763,19 +763,17 @@ bool DBBrowserDB::dump(const QString& filePath,
|
||||
// Count the total number of all records in all tables for the progress dialog
|
||||
size_t numRecordsTotal = 0;
|
||||
objectMap objMap = schemata["main"]; // We only always export the main database, not the attached databases
|
||||
QList<sqlb::ObjectPtr> tables = objMap.values("table");
|
||||
for(QMutableListIterator<sqlb::ObjectPtr> it(tables);it.hasNext();)
|
||||
std::vector<sqlb::ObjectPtr> tables;
|
||||
auto all_tables = objMap.equal_range("table");
|
||||
for(auto it=all_tables.first;it!=all_tables.second;++it)
|
||||
{
|
||||
it.next();
|
||||
|
||||
// Remove the sqlite_stat1 and the sqlite_sequence tables if they exist. Also remove any tables which are not selected for export.
|
||||
if(it.value()->name() == "sqlite_stat1" || it.value()->name() == "sqlite_sequence" || !tablesToDump.contains(QString::fromStdString(it.value()->name())))
|
||||
// Never export the sqlite_stat1 and the sqlite_sequence tables if they exist. Also only export any tables which are selected for export.
|
||||
if(it->second->name() != "sqlite_stat1" && it->second->name() != "sqlite_sequence" && tablesToDump.contains(QString::fromStdString(it->second->name())))
|
||||
{
|
||||
it.remove();
|
||||
} else {
|
||||
// Otherwise get the number of records in this table
|
||||
// Get the number of records in this table and remember to export it
|
||||
tables.push_back(it->second);
|
||||
numRecordsTotal += querySingleValueFromDb(QString("SELECT COUNT(*) FROM %1;")
|
||||
.arg(QString::fromStdString(sqlb::ObjectIdentifier("main", it.value()->name()).toString()))).toUInt();
|
||||
.arg(QString::fromStdString(sqlb::ObjectIdentifier("main", it->second->name()).toString()))).toUInt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -904,8 +902,10 @@ bool DBBrowserDB::dump(const QString& filePath,
|
||||
// Finally export all objects other than tables
|
||||
if(exportSchema)
|
||||
{
|
||||
for(auto it : objMap)
|
||||
for(const auto& obj : objMap)
|
||||
{
|
||||
const auto& it = obj.second;
|
||||
|
||||
// Make sure it's not a table again
|
||||
if(it->type() == sqlb::Object::Types::Table)
|
||||
continue;
|
||||
@@ -1536,11 +1536,11 @@ bool DBBrowserDB::alterTable(const sqlb::ObjectIdentifier& tablename, const sqlb
|
||||
sqlb::Table old_table = *old_table_ptr;
|
||||
|
||||
// Check if tracked fields actually exist in the old table
|
||||
for(const auto& old_name : track_columns.keys())
|
||||
for(const auto& old_it : track_columns)
|
||||
{
|
||||
if(!old_name.isNull() && sqlb::findField(old_table, old_name.toStdString()) == old_table.fields.end())
|
||||
if(!old_it.first.isNull() && sqlb::findField(old_table, old_it.first.toStdString()) == old_table.fields.end())
|
||||
{
|
||||
lastErrorMessage = tr("Cannot find column %1.").arg(old_name);
|
||||
lastErrorMessage = tr("Cannot find column %1.").arg(old_it.first);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1549,7 +1549,7 @@ bool DBBrowserDB::alterTable(const sqlb::ObjectIdentifier& tablename, const sqlb
|
||||
// We do this before checking if all tracked fields are in the new table to make sure the following check includes them.
|
||||
for(const auto& field : old_table.fields)
|
||||
{
|
||||
if(!track_columns.keys().contains(QString::fromStdString(field.name())))
|
||||
if(track_columns.find(QString::fromStdString(field.name())) == track_columns.end())
|
||||
{
|
||||
// If a field isn't tracked, add it to the list and indicate explicitly that it has the same name in the new table
|
||||
track_columns[QString::fromStdString(field.name())] = QString::fromStdString(field.name());
|
||||
@@ -1557,11 +1557,11 @@ bool DBBrowserDB::alterTable(const sqlb::ObjectIdentifier& tablename, const sqlb
|
||||
}
|
||||
|
||||
// Check if tracked fields actually exist in the new table
|
||||
for(const auto& new_name : track_columns.values())
|
||||
for(const auto& new_name_it : track_columns)
|
||||
{
|
||||
if(!new_name.isNull() && sqlb::findField(new_table, new_name.toStdString()) == new_table.fields.end())
|
||||
if(!new_name_it.second.isNull() && sqlb::findField(new_table, new_name_it.second.toStdString()) == new_table.fields.end())
|
||||
{
|
||||
lastErrorMessage = tr("Cannot find column %1.").arg(new_name);
|
||||
lastErrorMessage = tr("Cannot find column %1.").arg(new_name_it.second);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1601,14 +1601,15 @@ bool DBBrowserDB::alterTable(const sqlb::ObjectIdentifier& tablename, const sqlb
|
||||
}
|
||||
|
||||
// Add columns if necessary
|
||||
const auto new_fields = track_columns.values(QString());
|
||||
for(const auto& field : new_table.fields)
|
||||
{
|
||||
// We loop through all the fields of the new table schema and check for each of them if they are new.
|
||||
// If so, we add that field. The reason for looping through the new table schema instead of the track_columns
|
||||
// map is that this way we make sure to preserve their order which increases our chances that we are done after
|
||||
// this step.
|
||||
if(new_fields.contains(QString::fromStdString(field.name())))
|
||||
if(std::any_of(track_columns.begin(), track_columns.end(), [&field](const std::pair<QString, QString>& p) {
|
||||
return p.first.isNull() && p.second.toStdString() == field.name();
|
||||
}))
|
||||
{
|
||||
if(!addColumn(sqlb::ObjectIdentifier(tablename.schema(), new_table.name()), field))
|
||||
{
|
||||
@@ -1626,8 +1627,10 @@ bool DBBrowserDB::alterTable(const sqlb::ObjectIdentifier& tablename, const sqlb
|
||||
// map for tracking column names here which uses the update column names as the old names too. This is to
|
||||
// make sure we are using the new table layout for later updates.
|
||||
AlterTableTrackColumns new_track_columns;
|
||||
for(const auto& old_name : track_columns.keys())
|
||||
for(const auto& old_name_it : track_columns)
|
||||
{
|
||||
QString old_name = old_name_it.first;
|
||||
|
||||
QString new_name = track_columns[old_name];
|
||||
if(!old_name.isNull() && !new_name.isNull() && new_name != old_name)
|
||||
{
|
||||
@@ -1643,9 +1646,9 @@ bool DBBrowserDB::alterTable(const sqlb::ObjectIdentifier& tablename, const sqlb
|
||||
}
|
||||
|
||||
changed_something = true;
|
||||
new_track_columns.insert(new_name, new_name);
|
||||
new_track_columns.insert({new_name, new_name});
|
||||
} else {
|
||||
new_track_columns.insert(old_name, new_name);
|
||||
new_track_columns.insert({old_name, new_name});
|
||||
}
|
||||
}
|
||||
track_columns.swap(new_track_columns);
|
||||
@@ -1692,8 +1695,10 @@ bool DBBrowserDB::alterTable(const sqlb::ObjectIdentifier& tablename, const sqlb
|
||||
// Assemble list of column names to copy from in the old table and list of column names to into into in the new table
|
||||
sqlb::StringVector copy_values_from;
|
||||
sqlb::StringVector copy_values_to;
|
||||
for(const auto& from : track_columns.keys())
|
||||
for(const auto& from_it : track_columns)
|
||||
{
|
||||
const auto& from = from_it.first;
|
||||
|
||||
// Ignore new fields
|
||||
if(from.isNull())
|
||||
continue;
|
||||
@@ -1724,8 +1729,10 @@ bool DBBrowserDB::alterTable(const sqlb::ObjectIdentifier& tablename, const sqlb
|
||||
|
||||
// Save all indices, triggers and views associated with this table because SQLite deletes them when we drop the table in the next step
|
||||
QStringList otherObjectsSql;
|
||||
for(auto it : schemata[tablename.schema()])
|
||||
for(const auto& schema : schemata[tablename.schema()])
|
||||
{
|
||||
const auto& it = schema.second;
|
||||
|
||||
// If this object references the table and it's not the table itself save it's SQL string
|
||||
if(it->baseTable() == old_table.name() && it->type() != sqlb::Object::Types::Table)
|
||||
{
|
||||
@@ -1737,9 +1744,10 @@ bool DBBrowserDB::alterTable(const sqlb::ObjectIdentifier& tablename, const sqlb
|
||||
|
||||
// Loop through all changes to the table schema. For indices only the column names are relevant, so it suffices to look at the
|
||||
// list of tracked columns
|
||||
for(const auto& from : track_columns)
|
||||
for(const auto& from_it : track_columns)
|
||||
{
|
||||
QString to = track_columns[from];
|
||||
const auto& from = from_it.first;
|
||||
const auto& to = from_it.second;
|
||||
|
||||
// Are we updating the field name or are we removing the field entirely?
|
||||
if(!to.isNull())
|
||||
@@ -1867,10 +1875,11 @@ objectMap DBBrowserDB::getBrowsableObjects(const std::string& schema) const
|
||||
{
|
||||
objectMap res;
|
||||
|
||||
for(auto it=schemata[schema].constBegin();it!=schemata[schema].constEnd();++it)
|
||||
const objectMap map = schemata.at(schema);
|
||||
for(const auto& it : map)
|
||||
{
|
||||
if(it.key() == "table" || it.key() == "view")
|
||||
res.insert(it.key(), it.value());
|
||||
if(it.first == "table" || it.first == "view")
|
||||
res.insert({it.first, it.second});
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -1986,7 +1995,7 @@ void DBBrowserDB::updateSchema()
|
||||
trg->setTable(val_tblname);
|
||||
}
|
||||
|
||||
schemata[schema_name].insert(val_type, object);
|
||||
schemata[schema_name].insert({val_type, object});
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(vm);
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
#include <mutex>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <QObject>
|
||||
#include <QByteArray>
|
||||
#include <QMultiMap>
|
||||
#include <QStringList>
|
||||
|
||||
struct sqlite3;
|
||||
@@ -25,8 +25,8 @@ enum LogMessageType
|
||||
kLogMsg_ErrorLog
|
||||
};
|
||||
|
||||
using objectMap = QMultiMap<std::string, sqlb::ObjectPtr>; // Maps from object type (table, index, view, trigger) to a pointer to the object representation
|
||||
using schemaMap = QMap<std::string, objectMap>; // Maps from the schema name (main, temp, attached schemas) to the object map for that schema
|
||||
using objectMap = std::multimap<std::string, sqlb::ObjectPtr>; // Maps from object type (table, index, view, trigger) to a pointer to the object representation
|
||||
using schemaMap = std::map<std::string, objectMap>; // Maps from the schema name (main, temp, attached schemas) to the object map for that schema
|
||||
|
||||
int collCompare(void* pArg, int sizeA, const void* sA, int sizeB, const void* sB);
|
||||
|
||||
@@ -188,7 +188,7 @@ public:
|
||||
* 3) Map from an existing column name to a Null string: Delete the column.
|
||||
* 4) Map from a Null column name to a new column name: Add the column.
|
||||
*/
|
||||
using AlterTableTrackColumns = QMap<QString, QString>;
|
||||
using AlterTableTrackColumns = std::map<QString, QString>;
|
||||
|
||||
/**
|
||||
* @brief alterTable Can be used to rename, modify or drop existing columns of a given table
|
||||
@@ -205,10 +205,10 @@ public:
|
||||
template<typename T = sqlb::Object>
|
||||
const std::shared_ptr<T> getObjectByName(const sqlb::ObjectIdentifier& name) const
|
||||
{
|
||||
for(auto& it : schemata[name.schema()])
|
||||
for(auto& it : schemata.at(name.schema()))
|
||||
{
|
||||
if(it->name() == name.name())
|
||||
return std::dynamic_pointer_cast<T>(it);
|
||||
if(it.second->name() == name.name())
|
||||
return std::dynamic_pointer_cast<T>(it.second);
|
||||
}
|
||||
return std::shared_ptr<T>();
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ QColor SqliteTableModel::getMatchingCondFormatColor(int column, const QString& v
|
||||
QString sql;
|
||||
// For each conditional format for this column,
|
||||
// if the condition matches the current data, return the associated colour.
|
||||
for (const CondFormat& eachCondFormat : m_mCondFormats.value(column)) {
|
||||
for (const CondFormat& eachCondFormat : m_mCondFormats.at(column)) {
|
||||
if (isNumber && !eachCondFormat.sqlCondition().contains("'"))
|
||||
sql = QString("SELECT %1 %2").arg(value, eachCondFormat.sqlCondition());
|
||||
else
|
||||
@@ -348,7 +348,7 @@ QVariant SqliteTableModel::data(const QModelIndex &index, int role) const
|
||||
return QColor(Settings::getValue("databrowser", "null_fg_colour").toString());
|
||||
else if (nosync_isBinary(index))
|
||||
return QColor(Settings::getValue("databrowser", "bin_fg_colour").toString());
|
||||
else if (m_mCondFormats.contains(index.column())) {
|
||||
else if (m_mCondFormats.find(index.column()) != m_mCondFormats.end()) {
|
||||
QString value = cached_row->at(column);
|
||||
// Unlock before querying from DB
|
||||
lock.unlock();
|
||||
@@ -365,7 +365,7 @@ QVariant SqliteTableModel::data(const QModelIndex &index, int role) const
|
||||
return QColor(Settings::getValue("databrowser", "null_bg_colour").toString());
|
||||
else if (nosync_isBinary(index))
|
||||
return QColor(Settings::getValue("databrowser", "bin_bg_colour").toString());
|
||||
else if (m_mCondFormats.contains(index.column())) {
|
||||
else if (m_mCondFormats.find(index.column()) != m_mCondFormats.end()) {
|
||||
QString value = cached_row->at(column);
|
||||
// Unlock before querying from DB
|
||||
lock.unlock();
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <QColor>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "RowCache.h"
|
||||
#include "sql/Query.h"
|
||||
@@ -182,7 +183,7 @@ private:
|
||||
|
||||
QString m_sQuery;
|
||||
std::vector<int> m_vDataTypes;
|
||||
QMap<int, std::vector<CondFormat>> m_mCondFormats;
|
||||
std::map<int, std::vector<CondFormat>> m_mCondFormats;
|
||||
sqlb::Query m_query;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user