From 1bab387b7a9eb5a1d7f3b4f40a2371522efa4d3c Mon Sep 17 00:00:00 2001 From: Martin Kleusberg Date: Tue, 18 Feb 2020 21:59:36 +0100 Subject: [PATCH] Store pointer to table object in SqliteTableModel Store a pointer to the table object of the currently browsed table in the SqliteTableModel objects. This avoids fetching the table object from the DBBrowserDB object repeatedly which in turn should speed up some functions of the model a bit. --- src/sqlitetablemodel.cpp | 43 +++++++++++++++++----------------------- src/sqlitetablemodel.h | 2 ++ 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/sqlitetablemodel.cpp b/src/sqlitetablemodel.cpp index 84eef4379..4610edc2c 100644 --- a/src/sqlitetablemodel.cpp +++ b/src/sqlitetablemodel.cpp @@ -109,6 +109,7 @@ void SqliteTableModel::reset() m_sQuery.clear(); m_query.clear(); + m_table_of_query.reset(); m_headers.clear(); m_vDataTypes.clear(); m_mCondFormats.clear(); @@ -124,20 +125,20 @@ void SqliteTableModel::setQuery(const sqlb::Query& query) // Save the query m_query = query; + m_table_of_query = m_db.getObjectByName(query.table()); // The first column is the rowid column and therefore is always of type integer m_vDataTypes.emplace_back(SQLITE_INTEGER); // Get the data types of all other columns as well as the column names - sqlb::TablePtr t = m_db.getObjectByName(query.table()); - if(t && t->fields.size()) // It is a table and parsing was OK + if(m_table_of_query && m_table_of_query->fields.size()) // It is a table and parsing was OK { - sqlb::StringVector rowids = t->rowidColumns(); + sqlb::StringVector rowids = m_table_of_query->rowidColumns(); m_query.setRowIdColumns(rowids); m_headers.push_back(sqlb::joinStringVector(rowids, ",")); // Store field names and affinity data types - for(const sqlb::Field& fld : t->fields) + for(const sqlb::Field& fld : m_table_of_query->fields) { m_headers.push_back(fld.name()); m_vDataTypes.push_back(fld.affinity()); @@ -436,21 +437,16 @@ sqlb::ForeignKeyClause SqliteTableModel::getForeignKeyClause(size_t column) cons if(m_query.table().isEmpty()) return empty_foreign_key_clause; - // Retrieve database object and check if it is a table. If it isn't stop here and don't return a foreign - // key. This happens for views which don't have foreign keys (though we might want to think about how we - // can check for foreign keys in the underlying tables for some purposes like tool tips). - sqlb::ObjectPtr obj = m_db.getObjectByName(m_query.table()); - if(obj->type() != sqlb::Object::Table) - return empty_foreign_key_clause; - - // Convert object to a table and check if the column number is in the valid range - sqlb::TablePtr tbl = std::dynamic_pointer_cast(obj); - if(tbl && tbl->name().size() && column < tbl->fields.size()) + // Check if database object is a table. If it isn't stop here and don't return a foreign key. + // This happens for views which don't have foreign keys (though we might want to think about + // how we can check for foreign keys in the underlying tables for some purposes like tool tips). + // If it is a table, heck if the column number is in the valid range. + if(m_table_of_query && m_table_of_query->name().size() && column < m_table_of_query->fields.size()) { // Note that the rowid column has number -1 here, it can safely be excluded since there will never be a // foreign key on that column. - sqlb::ConstraintPtr ptr = tbl->constraint({tbl->fields.at(column).name()}, sqlb::Constraint::ForeignKeyConstraintType); + sqlb::ConstraintPtr ptr = m_table_of_query->constraint({m_table_of_query->fields.at(column).name()}, sqlb::Constraint::ForeignKeyConstraintType); if(ptr) return *(std::dynamic_pointer_cast(ptr)); } @@ -490,11 +486,10 @@ bool SqliteTableModel::setTypedData(const QModelIndex& index, bool isBlob, const // used in a primary key. Otherwise SQLite will always output an 'datatype mismatch' error. if(newValue == "" && !newValue.isNull()) { - sqlb::TablePtr table = m_db.getObjectByName(m_query.table()); - if(table) + if(m_table_of_query) { - auto field = sqlb::findField(table, m_headers.at(column)); - const auto pk = table->primaryKey(); + auto field = sqlb::findField(m_table_of_query, m_headers.at(column)); + const auto pk = m_table_of_query->primaryKey(); if(pk && contains(pk->columnList(), field->name()) && field->isInteger()) newValue = "0"; } @@ -712,11 +707,9 @@ QModelIndex SqliteTableModel::dittoRecord(int old_row) size_t firstEditedColumn = 0; int new_row = rowCount() - 1; - sqlb::TablePtr t = m_db.getObjectByName(m_query.table()); - - const auto pk = t->primaryKey(); - for (size_t col = 0; col < t->fields.size(); ++col) { - if(!pk || !contains(pk->columnList(), t->fields.at(col).name())) { + const auto pk = m_table_of_query->primaryKey(); + for (size_t col = 0; col < m_table_of_query->fields.size(); ++col) { + if(!pk || !contains(pk->columnList(), m_table_of_query->fields.at(col).name())) { if (!firstEditedColumn) firstEditedColumn = col + 1; @@ -978,7 +971,7 @@ bool SqliteTableModel::isEditable() const { return !m_query.table().isEmpty() && m_db.isOpen() && - ((m_db.getObjectByName(m_query.table()) && m_db.getObjectByName(m_query.table())->type() == sqlb::Object::Types::Table) || m_query.hasCustomRowIdColumn()); + (m_table_of_query || m_query.hasCustomRowIdColumn()); } void SqliteTableModel::triggerCacheLoad (int row) const diff --git a/src/sqlitetablemodel.h b/src/sqlitetablemodel.h index b9e6c6aca..02214af67 100644 --- a/src/sqlitetablemodel.h +++ b/src/sqlitetablemodel.h @@ -204,7 +204,9 @@ public slots: std::vector m_vDataTypes; std::map> m_mCondFormats; std::map> m_mRowIdFormats; + sqlb::Query m_query; + std::shared_ptr m_table_of_query; // This holds a pointer to the table object which is queried in the m_query object QString m_encoding;