Skip to content

Commit

Permalink
Finish main part of the recent refactoring effort
Browse files Browse the repository at this point in the history
This finally gets rid of the DBBrowserObject class entirely and moves
all its functionality to the newer classes in the sqlb namespace.

I'm still not entirely happy with this but at least things should be a
little more consistent now.
  • Loading branch information
MKleusberg committed Jan 23, 2017
1 parent 3839256 commit 38144bb
Show file tree
Hide file tree
Showing 14 changed files with 79 additions and 98 deletions.
37 changes: 11 additions & 26 deletions src/DbStructureModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,40 +170,32 @@ void DbStructureModel::reloadData()
typeToParentItem.insert("trigger", itemTriggers);

// Get all database objects and sort them by their name
QMultiMap<QString, DBBrowserObject> dbobjs;
QMultiMap<QString, sqlb::ObjectPtr> dbobjs;
for(auto it=m_db.objMap.constBegin(); it != m_db.objMap.constEnd(); ++it)
dbobjs.insert((*it).getname(), (*it));
dbobjs.insert((*it)->name(), (*it));

// Add the actual table objects
for(auto it=dbobjs.constBegin();it!=dbobjs.constEnd();++it)
{
// Object node
QString type;
switch((*it).gettype())
{
case sqlb::Object::Types::Table: type = "table"; break;
case sqlb::Object::Types::Index: type = "index"; break;
case sqlb::Object::Types::Trigger: type = "trigger"; break;
case sqlb::Object::Types::View: type = "view"; break;
}
QTreeWidgetItem* item = addNode(typeToParentItem.value(type), *it);
QTreeWidgetItem* item = addNode(typeToParentItem.value(sqlb::Object::typeToString((*it)->type())), *it);

// If it is a table or view add the field nodes
if((*it).gettype() == sqlb::Object::Types::Table || (*it).gettype() == sqlb::Object::Types::View)
if((*it)->type() == sqlb::Object::Types::Table || (*it)->type() == sqlb::Object::Types::View)
{
// Add extra node for browsable section
addNode(typeToParentItem.value("browsable"), *it);

// Add field nodes
QStringList pk_columns;
if(it->gettype() == sqlb::Object::Types::Table)
if((*it)->type() == sqlb::Object::Types::Table)
{
sqlb::FieldVector pk = it->object.dynamicCast<sqlb::Table>()->primaryKey();
sqlb::FieldVector pk = (*it).dynamicCast<sqlb::Table>()->primaryKey();
foreach(sqlb::FieldPtr pk_col, pk)
pk_columns.push_back(pk_col->name());

}
sqlb::FieldInfoList fieldList = it->object->fieldInformation();
sqlb::FieldInfoList fieldList = (*it)->fieldInformation();
foreach(const sqlb::FieldInfo& field, fieldList)
{
QTreeWidgetItem *fldItem = new QTreeWidgetItem(item);
Expand Down Expand Up @@ -293,22 +285,15 @@ bool DbStructureModel::dropMimeData(const QMimeData* data, Qt::DropAction action
}
}

QTreeWidgetItem* DbStructureModel::addNode(QTreeWidgetItem* parent, const DBBrowserObject& object)
QTreeWidgetItem* DbStructureModel::addNode(QTreeWidgetItem* parent, const sqlb::ObjectPtr& object)
{
QString type;
switch(object.gettype())
{
case sqlb::Object::Types::Table: type = "table"; break;
case sqlb::Object::Types::Index: type = "index"; break;
case sqlb::Object::Types::Trigger: type = "trigger"; break;
case sqlb::Object::Types::View: type = "view"; break;
}
QString type = sqlb::Object::typeToString(object->type());

QTreeWidgetItem *item = new QTreeWidgetItem(parent);
item->setIcon(0, QIcon(QString(":/icons/%1").arg(type)));
item->setText(0, object.getname());
item->setText(0, object->name());
item->setText(1, type);
item->setText(3, object.getsql());
item->setText(3, object->originalSql());

return item;
}
4 changes: 2 additions & 2 deletions src/DbStructureModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
#include <QAbstractItemModel>

class DBBrowserDB;
class DBBrowserObject;
class QTreeWidgetItem;
namespace sqlb { class Object; typedef QSharedPointer<Object> ObjectPtr; }

class DbStructureModel : public QAbstractItemModel
{
Expand Down Expand Up @@ -33,7 +33,7 @@ class DbStructureModel : public QAbstractItemModel
QTreeWidgetItem* rootItem;
DBBrowserDB& m_db;

QTreeWidgetItem* addNode(QTreeWidgetItem* parent, const DBBrowserObject& object);
QTreeWidgetItem* addNode(QTreeWidgetItem* parent, const sqlb::ObjectPtr& object);
};

#endif
8 changes: 4 additions & 4 deletions src/EditIndexDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ EditIndexDialog::EditIndexDialog(DBBrowserDB& db, const QString& indexName, bool
ui->setupUi(this);

// Get list of tables, sort it alphabetically and fill the combobox
QMultiMap<QString, DBBrowserObject> dbobjs;
QList<DBBrowserObject> tables = pdb.objMap.values("table");
objectMap dbobjs;
QList<sqlb::ObjectPtr> tables = pdb.objMap.values("table");
for(auto it=tables.constBegin();it!=tables.constEnd();++it)
dbobjs.insert((*it).getname(), (*it));
dbobjs.insert((*it)->name(), (*it));
ui->comboTableName->blockSignals(true);
for(auto it=dbobjs.constBegin();it!=dbobjs.constEnd();++it)
ui->comboTableName->addItem(QIcon(QString(":icons/table")), (*it).getname());
ui->comboTableName->addItem(QIcon(QString(":icons/table")), (*it)->name());
ui->comboTableName->blockSignals(false);

QHeaderView *tableHeaderView = ui->tableIndexColumns->horizontalHeader();
Expand Down
6 changes: 3 additions & 3 deletions src/EditTableDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,9 @@ void EditTableDialog::itemChanged(QTreeWidgetItem *item, int column)
if(!m_bNewTable)
{
sqlb::FieldVector pk = m_table.primaryKey();
foreach(const DBBrowserObject& fkobj, pdb.objMap.values("table"))
foreach(const sqlb::ObjectPtr& fkobj, pdb.objMap.values("table"))
{
QList<sqlb::ConstraintPtr> fks = fkobj.object.dynamicCast<sqlb::Table>()->constraints(sqlb::FieldVector(), sqlb::Constraint::ForeignKeyConstraintType);
QList<sqlb::ConstraintPtr> fks = fkobj.dynamicCast<sqlb::Table>()->constraints(sqlb::FieldVector(), sqlb::Constraint::ForeignKeyConstraintType);
foreach(sqlb::ConstraintPtr fkptr, fks)
{
QSharedPointer<sqlb::ForeignKeyClause> fk = fkptr.dynamicCast<sqlb::ForeignKeyClause>();
Expand All @@ -284,7 +284,7 @@ void EditTableDialog::itemChanged(QTreeWidgetItem *item, int column)
{
QMessageBox::warning(this, qApp->applicationName(), tr("This column is referenced in a foreign key in table %1 and thus "
"its name cannot be changed.")
.arg(fkobj.getname()));
.arg(fkobj->name()));
// Reset the name to the old value but avoid calling this method again for that automatic change
ui->treeWidget->blockSignals(true);
item->setText(column, oldFieldName);
Expand Down
4 changes: 2 additions & 2 deletions src/ExportDataDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ ExportDataDialog::ExportDataDialog(DBBrowserDB& db, ExportFormats format, QWidge
{
// Get list of tables to export
objectMap objects = pdb.getBrowsableObjects();
foreach(const DBBrowserObject& obj, objects)
ui->listTables->addItem(new QListWidgetItem(QIcon(QString(":icons/%1").arg(obj.gettype())), obj.getname()));
foreach(const sqlb::ObjectPtr& obj, objects)
ui->listTables->addItem(new QListWidgetItem(QIcon(QString(":icons/%1").arg(sqlb::Object::typeToString(obj->type()))), obj->name()));

// Sort list of tables and select the table specified in the selection parameter or alternatively the first one
ui->listTables->model()->sort(0);
Expand Down
2 changes: 1 addition & 1 deletion src/ExportSqlDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ ExportSqlDialog::ExportSqlDialog(DBBrowserDB* db, QWidget* parent, const QString
// Get list of tables to export
objectMap objects = pdb->getBrowsableObjects();
for(auto it=objects.constBegin();it!=objects.constEnd();++it) {
ui->listTables->addItem(new QListWidgetItem(QIcon(QString(":icons/%1").arg(it.value().gettype())), it.value().getname()));
ui->listTables->addItem(new QListWidgetItem(QIcon(QString(":icons/%1").arg((*it)->type())), (*it)->name()));
}

// Sort list of tables and select the table specified in the
Expand Down
6 changes: 3 additions & 3 deletions src/ForeignKeyEditorDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ ForeignKeyEditorDelegate::ForeignKeyEditorDelegate(const DBBrowserDB& db, sqlb::
{
const auto objects = m_db.getBrowsableObjects();
for (auto& obj : objects) {
if (obj.gettype() == sqlb::Object::Types::Table) {
QString tableName = obj.object->name();
m_tablesIds.insert(tableName, obj.object.dynamicCast<sqlb::Table>()->fieldNames());
if (obj->type() == sqlb::Object::Types::Table) {
QString tableName = obj->name();
m_tablesIds.insert(tableName, obj.dynamicCast<sqlb::Table>()->fieldNames());
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/ImportCsvDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@ void ImportCsvDialog::accept()
objectMap objects = pdb->getBrowsableObjects();
for(auto it=objects.constBegin();it!=objects.constEnd();++it)
{
if(it.value().gettype() == sqlb::Object::Types::Table && it.value().getname() == ui->editName->text())
if((*it)->type() == sqlb::Object::Types::Table && (*it)->name() == ui->editName->text())
{
if((size_t)it.value().object.dynamicCast<sqlb::Table>()->fields().size() != csv.columns())
if((size_t)(*it).dynamicCast<sqlb::Table>()->fields().size() != csv.columns())
{
QMessageBox::warning(this, QApplication::applicationName(),
tr("There is already a table of that name and an import into an existing table is only possible if the number of columns match."));
Expand Down
4 changes: 2 additions & 2 deletions src/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,9 @@ void MainWindow::populateStructure()
SqlUiLexer::TablesAndColumnsMap tablesToColumnsMap;
for(auto it=tab.constBegin();it!=tab.constEnd();++it)
{
QString objectname = it.value().getname();
QString objectname = (*it)->name();

sqlb::FieldInfoList fi = it->object->fieldInformation();
sqlb::FieldInfoList fi = (*it)->fieldInformation();
foreach(const sqlb::FieldInfo& f, fi)
tablesToColumnsMap[objectname].append(f.name);
}
Expand Down
8 changes: 4 additions & 4 deletions src/VacuumDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ VacuumDialog::VacuumDialog(DBBrowserDB* _db, QWidget* parent) :
ui->labelSavepointWarning->setVisible(db->getDirty());

// Populate list of objects to compact
QList<DBBrowserObject> objects = db->objMap.values("table");
QList<sqlb::ObjectPtr> objects = db->objMap.values("table");
objects.append(db->objMap.values("index"));
for(QList<DBBrowserObject>::const_iterator i=objects.constBegin();i!=objects.constEnd();++i)
for(QList<sqlb::ObjectPtr>::const_iterator i=objects.constBegin();i!=objects.constEnd();++i)
{
QTreeWidgetItem* item = new QTreeWidgetItem(ui->treeSelectedObjects);
item->setText(0, (*i).getname());
item->setIcon(0, QIcon(QString(":icons/%1").arg((*i).gettype())));
item->setText(0, (*i)->name());
item->setIcon(0, QIcon(QString(":icons/%1").arg(sqlb::Object::typeToString((*i)->type()))));
ui->treeSelectedObjects->addTopLevelItem(item);
}

Expand Down
56 changes: 30 additions & 26 deletions src/sqlitedb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,20 +458,20 @@ bool DBBrowserDB::dump(const QString& filename,
QApplication::setOverrideCursor(Qt::WaitCursor);

size_t numRecordsTotal = 0, numRecordsCurrent = 0;
QList<DBBrowserObject> tables = objMap.values("table");
QMutableListIterator<DBBrowserObject> it(tables);
QList<sqlb::ObjectPtr> tables = objMap.values("table");
QMutableListIterator<sqlb::ObjectPtr> it(tables);
while(it.hasNext())
{
it.next();

// Remove the sqlite_stat1 table if there is one
if(it.value().getname() == "sqlite_stat1" || it.value().getname() == "sqlite_sequence")
if(it.value()->name() == "sqlite_stat1" || it.value()->name() == "sqlite_sequence")
{
it.remove();
} else {
// Otherwise get the number of records in this table
SqliteTableModel tableModel(*this);
tableModel.setTable(it.value().getname());
tableModel.setTable(it.value()->name());
numRecordsTotal += tableModel.totalRowCount();
}
}
Expand All @@ -491,21 +491,21 @@ bool DBBrowserDB::dump(const QString& filename,
// Loop through all tables first as they are required to generate views, indices etc. later
for(auto it=tables.constBegin();it!=tables.constEnd();++it)
{
if (tablesToDump.indexOf(it->getname()) == -1)
if (tablesToDump.indexOf((*it)->name()) == -1)
continue;

// Write the SQL string used to create this table to the output file
if(exportSchema)
stream << it->getsql() << ";\n";
stream << (*it)->originalSql() << ";\n";

// If the user doesn't want the data to be exported skip the rest of the loop block here
if(!exportData)
continue;

// get columns
QStringList cols(it->object.dynamicCast<sqlb::Table>()->fieldNames());
QStringList cols((*it).dynamicCast<sqlb::Table>()->fieldNames());

QString sQuery = QString("SELECT * FROM %1;").arg(sqlb::escapeIdentifier(it->getname()));
QString sQuery = QString("SELECT * FROM %1;").arg(sqlb::escapeIdentifier((*it)->name()));
QByteArray utf8Query = sQuery.toUtf8();
sqlite3_stmt *stmt;
QString lineSep(QString(")%1\n").arg(insertNewSyntx?',':';'));
Expand All @@ -522,7 +522,7 @@ bool DBBrowserDB::dump(const QString& filename,

if (!insertNewSyntx || !counter)
{
stream << "INSERT INTO " << sqlb::escapeIdentifier(it->getname());
stream << "INSERT INTO " << sqlb::escapeIdentifier((*it)->name());
if (insertColNames)
stream << " (" << cols.join(",") << ")";
stream << " VALUES (";
Expand Down Expand Up @@ -594,12 +594,12 @@ bool DBBrowserDB::dump(const QString& filename,
for(auto it=objMap.constBegin();it!=objMap.constEnd();++it)
{
// Make sure it's not a table again
if(it.value().gettype() == sqlb::Object::Types::Table)
if(it.value()->type() == sqlb::Object::Types::Table)
continue;

// Write the SQL string used to create this object to the output file
if(!it->getsql().isEmpty())
stream << it->getsql() << ";\n";
if(!(*it)->originalSql().isEmpty())
stream << (*it)->originalSql() << ";\n";
}
}

Expand Down Expand Up @@ -1076,13 +1076,13 @@ bool DBBrowserDB::renameColumn(const QString& tablename, const sqlb::Table& tabl
for(auto it=objMap.constBegin();it!=objMap.constEnd();++it)
{
// If this object references the table and it's not the table itself save it's SQL string
if((*it).getTableName() == tablename && (*it).gettype() != sqlb::Object::Types::Table)
if((*it)->baseTable() == tablename && (*it)->type() != sqlb::Object::Types::Table)
{
// If this is an index, update the fields first. This highly increases the chance that the SQL statement won't throw an
// error later on when we try to recreate it.
if((*it).gettype() == sqlb::Object::Types::Index)
if((*it)->type() == sqlb::Object::Types::Index)
{
sqlb::IndexPtr idx = (*it).object.dynamicCast<sqlb::Index>();
sqlb::IndexPtr idx = (*it).dynamicCast<sqlb::Index>();
for(int i=0;i<idx->columns().size();i++)
{
if(idx->column(i)->name() == name)
Expand All @@ -1092,7 +1092,7 @@ bool DBBrowserDB::renameColumn(const QString& tablename, const sqlb::Table& tabl
} else {
// If it's a view or a trigger we don't have any chance to corrections yet. Just store the statement as is and
// hope for the best.
otherObjectsSql << (*it).getsql().trimmed() + ";";
otherObjectsSql << (*it)->originalSql().trimmed() + ";";
}
}
}
Expand Down Expand Up @@ -1183,8 +1183,8 @@ const sqlb::ObjectPtr DBBrowserDB::getObjectByName(const QString& name) const
{
for(auto it=objMap.constBegin();it!=objMap.constEnd();++it)
{
if((*it).getname() == name)
return it->object;
if((*it)->name() == name)
return *it;
}
return sqlb::ObjectPtr(nullptr);
}
Expand Down Expand Up @@ -1252,35 +1252,39 @@ void DBBrowserDB::updateSchema( )
else
continue;

DBBrowserObject obj(val_name, val_sql, type, val_tblname);
if(!val_sql.isEmpty())
{
obj.object = sqlb::Object::parseSQL(type, val_sql);
sqlb::ObjectPtr object = sqlb::Object::parseSQL(type, val_sql);
if(val_temp == "1")
obj.object->setTemporary(true);
object->setTemporary(true);

// If parsing wasn't successful set the object name manually, so that at least the name is going to be correct
if(!object->fullyParsed())
object->setName(val_name);

// For virtual tables and views query the column list using the SQLite pragma because for both we can't yet rely on our grammar parser
if((type == sqlb::Object::Types::Table && obj.object.dynamicCast<sqlb::Table>()->isVirtual()) || type == sqlb::Object::Types::View)
if((type == sqlb::Object::Types::Table && object.dynamicCast<sqlb::Table>()->isVirtual()) || type == sqlb::Object::Types::View)
{
auto columns = queryColumnInformation(val_name);

if(type == sqlb::Object::Types::Table)
{
sqlb::TablePtr tab = obj.object.dynamicCast<sqlb::Table>();
sqlb::TablePtr tab = object.dynamicCast<sqlb::Table>();
foreach(const auto& column, columns)
tab->addField(sqlb::FieldPtr(new sqlb::Field(column.first, column.second)));
} else {
sqlb::ViewPtr view = obj.object.dynamicCast<sqlb::View>();
sqlb::ViewPtr view = object.dynamicCast<sqlb::View>();
foreach(const auto& column, columns)
view->addField(sqlb::FieldPtr(new sqlb::Field(column.first, column.second)));
}
} else if(type == sqlb::Object::Types::Trigger) {
// For triggers set the name of the table the trigger operates on here because we don't have a parser for trigger statements yet.
sqlb::TriggerPtr trg = obj.object.dynamicCast<sqlb::Trigger>();
sqlb::TriggerPtr trg = object.dynamicCast<sqlb::Trigger>();
trg->setTable(val_tblname);
}

objMap.insert(val_type, object);
}
objMap.insert(val_type, obj);
}
sqlite3_finalize(vm);
}else{
Expand Down
23 changes: 1 addition & 22 deletions src/sqlitedb.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,7 @@ enum
kLogMsg_App
};

typedef QMultiMap<QString, class DBBrowserObject> objectMap;

class DBBrowserObject
{
public:
DBBrowserObject() : name( "" ) { }
DBBrowserObject(const QString& wname, const QString& wsql, sqlb::Object::Types wtype, const QString& tbl_name)
: name( wname), sql( wsql ), type(wtype), table_name(tbl_name)
{ }

QString getname() const { return name; }
QString getsql() const { return sql; }
sqlb::Object::Types gettype() const { return type; }
QString getTableName() const { return table_name; }

sqlb::ObjectPtr object;
private:
QString name;
QString sql;
sqlb::Object::Types type;
QString table_name; // The name of the table this object references, interesting for views, triggers and indices
};
typedef QMultiMap<QString, sqlb::ObjectPtr> objectMap;

class DBBrowserDB : public QObject
{
Expand Down
Loading

0 comments on commit 38144bb

Please sign in to comment.