summaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/guiSQLiteStudio/dbtree
diff options
context:
space:
mode:
Diffstat (limited to 'SQLiteStudio3/guiSQLiteStudio/dbtree')
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreeitem.cpp15
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreeitem.h6
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.cpp224
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.h15
4 files changed, 174 insertions, 86 deletions
diff --git a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreeitem.cpp b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreeitem.cpp
index 6514aa8..c118eb6 100644
--- a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreeitem.cpp
+++ b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreeitem.cpp
@@ -58,6 +58,11 @@ DbTreeItem* DbTreeItem::findItem(DbTreeItem::Type type, const QString& name)
return DbTreeModel::findItem(this, type, name);
}
+DbTreeItem* DbTreeItem::findFirstItem(Type type)
+{
+ return DbTreeModel::findFirstItem(this, type);
+}
+
QStandardItem* DbTreeItem::clone() const
{
return new DbTreeItem(*this);
@@ -293,6 +298,16 @@ void DbTreeItem::setIcon(const Icon& icon)
QStandardItem::setIcon(icon);
}
+bool DbTreeItem::isSchemaReady() const
+{
+ return data(DataRole::SCHEMA_READY).toBool();
+}
+
+void DbTreeItem::setSchemaReady(bool ready)
+{
+ setData(ready, DataRole::SCHEMA_READY);
+}
+
void DbTreeItem::init()
{
Type type = getType();
diff --git a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreeitem.h b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreeitem.h
index ba230f2..7cce7a2 100644
--- a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreeitem.h
+++ b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreeitem.h
@@ -38,6 +38,7 @@ class GUI_API_EXPORT DbTreeItem : public QObject, public QStandardItem
int type() const;
DbTreeItem* findItem(Type type, const QString& name);
+ DbTreeItem* findFirstItem(Type type);
QStandardItem* clone() const;
QList<QStandardItem*> childs() const;
QStringList childNames() const;
@@ -75,6 +76,8 @@ class GUI_API_EXPORT DbTreeItem : public QObject, public QStandardItem
void setHidden(bool hidden);
bool isHidden() const;
void setIcon(const Icon& icon);
+ bool isSchemaReady() const;
+ void setSchemaReady(bool ready);
private:
struct DataRole // not 'enum class' because we need autocasting to int for this one
@@ -84,7 +87,8 @@ class GUI_API_EXPORT DbTreeItem : public QObject, public QStandardItem
TYPE = 1001,
DB = 1002,
ICON_PTR = 1003,
- HIDDEN = 1004
+ HIDDEN = 1004,
+ SCHEMA_READY = 1005
};
};
diff --git a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.cpp b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.cpp
index 6620290..29bf652 100644
--- a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.cpp
+++ b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.cpp
@@ -280,7 +280,14 @@ void DbTreeModel::expanded(const QModelIndex &index)
return;
}
- if (dynamic_cast<DbTreeItem*>(item)->getType() == DbTreeItem::Type::DIR)
+ DbTreeItem* dbTreeItem = dynamic_cast<DbTreeItem*>(item);
+ if (dbTreeItem->getType() == DbTreeItem::Type::TABLE)
+ loadTableSchema(dbTreeItem);
+
+ if (dbTreeItem->getType() == DbTreeItem::Type::VIEW)
+ loadViewSchema(dbTreeItem);
+
+ if (dbTreeItem->getType() == DbTreeItem::Type::DIR)
itemFromIndex(index)->setIcon(ICONS.DIRECTORY_OPEN);
}
@@ -443,8 +450,9 @@ QString DbTreeModel::getDbToolTip(DbTreeItem* item) const
QString DbTreeModel::getTableToolTip(DbTreeItem* item) const
{
- QStringList rows;
+ const_cast<DbTreeModel*>(this)->loadTableSchema(item); // not nice to const_cast, but nothing better we can do about this
+ QStringList rows;
rows << toolTipHdrRowTmp.arg(ICONS.TABLE.getPath()).arg(tr("Table : %1", "dbtree tooltip").arg(item->text()));
QStandardItem* columnsItem = item->child(0);
@@ -499,20 +507,33 @@ void DbTreeModel::refreshSchema(Db* db, QStandardItem *item)
// Collect all db objects and build the db branch
bool sort = CFG_UI.General.SortObjects.get();
- QStringList tables = resolver.getTables();
- QStringList virtualTables;
- for (const QString& table : tables)
+ QList<SchemaResolver::TableListItem> tableListItems = resolver.getAllTableListItems();
+ QStringList tables;
+ QStringList views;
+ QSet<QString> virtualTables;
+
+ for (SchemaResolver::TableListItem& tableListItem : tableListItems)
{
- if (resolver.isVirtualTable(table))
- virtualTables << table;
+ switch (tableListItem.type)
+ {
+ case SchemaResolver::TableListItem::VIRTUAL_TABLE:
+ virtualTables << tableListItem.name;
+ [[fallthrough]];
+ case SchemaResolver::TableListItem::TABLE:
+ case SchemaResolver::TableListItem::SHADOW_TABLE:
+ tables << tableListItem.name;
+ break;
+ case SchemaResolver::TableListItem::VIEW:
+ views << tableListItem.name;
+ break;
+ case SchemaResolver::TableListItem::UNKNOWN:
+ break;
+ }
}
QList<QStandardItem*> tableItems = refreshSchemaTables(tables, virtualTables, sort);
- StrHash<QList<QStandardItem*>> allTableColumns = refreshSchemaTableColumns(resolver.getAllTableColumns());
- StrHash<QList<QStandardItem*>> indexItems = refreshSchemaIndexes(resolver.getGroupedIndexes(), sort);
- StrHash<QList<QStandardItem*>> triggerItems = refreshSchemaTriggers(resolver.getGroupedTriggers(), sort);
- QList<QStandardItem*> viewItems = refreshSchemaViews(resolver.getViews(), sort);
- refreshSchemaBuild(item, tableItems, indexItems, triggerItems, viewItems, allTableColumns);
+ QList<QStandardItem*> viewItems = refreshSchemaViews(views, sort);
+ refreshSchemaBuild(item, tableItems, viewItems);
populateChildItemsWithDb(item, db);
restoreExpandedState(expandedState, item);
}
@@ -530,7 +551,7 @@ void DbTreeModel::collectExpandedState(QHash<QString, bool> &state, QStandardIte
collectExpandedState(state, parentItem->child(i));
}
-QList<QStandardItem *> DbTreeModel::refreshSchemaTables(const QStringList &tables, const QStringList& virtualTables, bool sort)
+QList<QStandardItem *> DbTreeModel::refreshSchemaTables(const QStringList &tables, const QSet<QString>& virtualTables, bool sort)
{
QStringList sortedTables = tables;
if (sort)
@@ -548,52 +569,44 @@ QList<QStandardItem *> DbTreeModel::refreshSchemaTables(const QStringList &table
return items;
}
-StrHash<QList<QStandardItem*>> DbTreeModel::refreshSchemaTableColumns(const StrHash<QStringList> &columns)
+QList<QStandardItem*> DbTreeModel::refreshSchemaTableColumns(const QStringList& columns)
{
- QStringList sortedColumns;
bool doSort = CFG_UI.General.SortColumns.get();
- StrHash<QList<QStandardItem*>> items;
- for (const QString& key : columns.keys())
- {
- sortedColumns = columns[key];
- if (doSort)
- ::sSort(sortedColumns);
- for (const QString& column : sortedColumns)
- items[key] += DbTreeItemFactory::createColumn(column, this);
- }
+ QStringList sortedColumns = columns;
+ if (doSort)
+ ::sSort(sortedColumns);
+
+ QList<QStandardItem*> items;
+ for (const QString& column : sortedColumns)
+ items += DbTreeItemFactory::createColumn(column, this);
+
return items;
}
-StrHash<QList<QStandardItem *> > DbTreeModel::refreshSchemaIndexes(const StrHash<QStringList> &indexes, bool sort)
+QList<QStandardItem*> DbTreeModel::refreshSchemaIndexes(const QStringList& indexes, bool sort)
{
- StrHash<QList<QStandardItem *> > items;
- QStringList sortedIndexes;
- for (const QString& key : indexes.keys())
- {
- sortedIndexes = indexes[key];
- if (sort)
- sortedIndexes.sort(Qt::CaseInsensitive);
+ QStringList sortedIndexes = indexes;
+ if (sort)
+ sortedIndexes.sort(Qt::CaseInsensitive);
+
+ QList<QStandardItem*> items;
+ for (const QString& index : sortedIndexes)
+ items += DbTreeItemFactory::createIndex(index, this);
- for (const QString& index : sortedIndexes)
- items[key] += DbTreeItemFactory::createIndex(index, this);
- }
return items;
}
-StrHash<QList<QStandardItem*>> DbTreeModel::refreshSchemaTriggers(const StrHash<QStringList> &triggers, bool sort)
+QList<QStandardItem*> DbTreeModel::refreshSchemaTriggers(const QStringList& triggers, bool sort)
{
- StrHash<QList<QStandardItem*>> items;
- QStringList sortedTriggers;
- for (const QString& key : triggers.keys())
- {
- sortedTriggers = triggers[key];
- if (sort)
- sortedTriggers.sort(Qt::CaseInsensitive);
+ QStringList sortedTriggers = triggers;
+ if (sort)
+ sortedTriggers.sort(Qt::CaseInsensitive);
+
+ QList<QStandardItem*> items;
+ for (const QString& trigger : sortedTriggers)
+ items += DbTreeItemFactory::createTrigger(trigger, this);
- for (const QString& trigger : sortedTriggers)
- items[key] += DbTreeItemFactory::createTrigger(trigger, this);
- }
return items;
}
@@ -621,12 +634,68 @@ void DbTreeModel::populateChildItemsWithDb(QStandardItem *parentItem, Db* db)
}
}
+void DbTreeModel::loadTableSchema(DbTreeItem* tableItem)
+{
+ if (tableItem->isSchemaReady())
+ return;
+
+ Db* db = tableItem->getDb();
+ QString table = tableItem->text();
+
+ SchemaResolver resolver(db);
+ resolver.setIgnoreSystemObjects(!CFG_UI.General.ShowSystemObjects.get());
+
+ bool sort = CFG_UI.General.SortObjects.get();
+
+ DbTreeItem* columnsItem = tableItem->findFirstItem(DbTreeItem::Type::COLUMNS);
+ DbTreeItem* indexesItem = tableItem->findFirstItem(DbTreeItem::Type::INDEXES);
+ DbTreeItem* triggersItem = tableItem->findFirstItem(DbTreeItem::Type::TRIGGERS);
+
+ QList<QStandardItem*> tableColumns = refreshSchemaTableColumns(resolver.getTableColumns(table));
+ QList<QStandardItem*> indexItems = refreshSchemaIndexes(resolver.getIndexesForTable(table), sort);
+ QList<QStandardItem*> triggerItems = refreshSchemaTriggers(resolver.getTriggersForTable(table), sort);
+
+ for (QStandardItem* columnItem : tableColumns)
+ columnsItem->appendRow(columnItem);
+
+ for (QStandardItem* indexItem : indexItems)
+ indexesItem->appendRow(indexItem);
+
+ for (QStandardItem* triggerItem : triggerItems)
+ triggersItem->appendRow(triggerItem);
+
+ populateChildItemsWithDb(columnsItem, db);
+ populateChildItemsWithDb(indexesItem, db);
+ populateChildItemsWithDb(triggersItem, db);
+
+ tableItem->setSchemaReady(true);
+}
+
+void DbTreeModel::loadViewSchema(DbTreeItem* viewItem)
+{
+ if (viewItem->isSchemaReady())
+ return;
+
+ Db* db = viewItem->getDb();
+ QString view = viewItem->text();
+
+ SchemaResolver resolver(db);
+ resolver.setIgnoreSystemObjects(!CFG_UI.General.ShowSystemObjects.get());
+
+ bool sort = CFG_UI.General.SortObjects.get();
+
+ DbTreeItem* triggersItem = viewItem->findFirstItem(DbTreeItem::Type::TRIGGERS);
+
+ QList<QStandardItem*> triggerItems = refreshSchemaTriggers(resolver.getTriggersForView(view), sort);
+ for (QStandardItem* triggerItem : triggerItems)
+ triggersItem->appendRow(triggerItem);
+
+ viewItem->setSchemaReady(true);
+}
+
void DbTreeModel::refreshSchemaBuild(QStandardItem *dbItem,
QList<QStandardItem*> tables,
- StrHash<QList<QStandardItem*> > indexes,
- StrHash<QList<QStandardItem*> > triggers,
- QList<QStandardItem*> views,
- StrHash<QList<QStandardItem*> > allTableColumns)
+ QList<QStandardItem*> views)
{
DbTreeItem* tablesItem = DbTreeItemFactory::createTables(this);
DbTreeItem* viewsItem = DbTreeItemFactory::createViews(this);
@@ -649,14 +718,7 @@ void DbTreeModel::refreshSchemaBuild(QStandardItem *dbItem,
tableItem->appendRow(indexesItem);
tableItem->appendRow(triggersItem);
- for (QStandardItem* columnItem : allTableColumns[tableItem->text()])
- columnsItem->appendRow(columnItem);
-
- for (QStandardItem* indexItem : indexes[tableItem->text()])
- indexesItem->appendRow(indexItem);
-
- for (QStandardItem* triggerItem : triggers[tableItem->text()])
- triggersItem->appendRow(triggerItem);
+ dynamic_cast<DbTreeItem*>(tableItem)->setSchemaReady(false);
}
for (QStandardItem* viewItem : views)
{
@@ -664,8 +726,8 @@ void DbTreeModel::refreshSchemaBuild(QStandardItem *dbItem,
triggersItem = DbTreeItemFactory::createTriggers(this);
viewItem->appendRow(triggersItem);
- for (QStandardItem* triggerItem : triggers[viewItem->text()])
- triggersItem->appendRow(triggerItem);
+
+ dynamic_cast<DbTreeItem*>(viewItem)->setSchemaReady(false);
}
}
@@ -680,22 +742,6 @@ void DbTreeModel::restoreExpandedState(const QHash<QString, bool>& expandedState
restoreExpandedState(expandedState, child);
}
-DbTreeItem* DbTreeModel::findFirstItemOfType(DbTreeItem::Type type, QStandardItem* parentItem)
-{
- DbTreeItem* child = nullptr;
- for (int i = 0; i < parentItem->rowCount(); i++)
- {
- child = dynamic_cast<DbTreeItem*>(parentItem->child(i));
- if (child->getType() == type)
- return child;
-
- child = findFirstItemOfType(type, child);
- if (child)
- return child;
- }
- return nullptr;
-}
-
void DbTreeModel::dbConnected(Db* db, bool expandItem)
{
QStandardItem* item = findItem(DbTreeItem::Type::DB, db);
@@ -819,7 +865,7 @@ DbTreeItem *DbTreeModel::findItem(DbTreeItem::Type type, Db* db)
DbTreeItem* DbTreeModel::findFirstItemOfType(DbTreeItem::Type type)
{
- return findFirstItemOfType(type, root());
+ return findFirstItem(root(), type);
}
DbTreeItem *DbTreeModel::findItemBySignature(const QString &signature)
@@ -883,7 +929,7 @@ QList<DbTreeItem*> DbTreeModel::findItems(QStandardItem* parentItem, DbTreeItem:
item = dynamic_cast<DbTreeItem*>(parentItem->child(i));
// Search recursively
- if (item->getType() == DbTreeItem::Type::DIR)
+ if (item->hasChildren())
items += findItems(item, type);
if (item->getType() != type)
@@ -895,6 +941,28 @@ QList<DbTreeItem*> DbTreeModel::findItems(QStandardItem* parentItem, DbTreeItem:
return items;
}
+DbTreeItem* DbTreeModel::findFirstItem(QStandardItem* parentItem, DbTreeItem::Type type)
+{
+ for (int i = 0; i < parentItem->rowCount(); i++)
+ {
+ DbTreeItem* item = dynamic_cast<DbTreeItem*>(parentItem->child(i));
+
+ if (item->hasChildren())
+ {
+ DbTreeItem* child = findFirstItem(item, type);
+ if (child)
+ return child;
+ }
+
+ if (item->getType() != type)
+ continue;
+
+ return item;
+ }
+
+ return nullptr;
+}
+
QStandardItem* DbTreeModel::root() const
{
return invisibleRootItem();
diff --git a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.h b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.h
index 86dc8a6..5fb91ba 100644
--- a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.h
+++ b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.h
@@ -57,6 +57,7 @@ class GUI_API_EXPORT DbTreeModel : public QStandardItemModel
static DbTreeItem* findItem(QStandardItem *parentItem, DbTreeItem::Type type, const QString &name);
static DbTreeItem* findItem(QStandardItem* parentItem, DbTreeItem::Type type, Db* db);
static QList<DbTreeItem*> findItems(QStandardItem* parentItem, DbTreeItem::Type type);
+ static DbTreeItem* findFirstItem(QStandardItem* parentItem, DbTreeItem::Type type);
static void staticInit();
static const constexpr char* MIMETYPE = "application/x-sqlitestudio-dbtreeitem";
@@ -69,16 +70,16 @@ class GUI_API_EXPORT DbTreeModel : public QStandardItemModel
void refreshSchema(Db* db, QStandardItem* item);
void collectExpandedState(QHash<QString, bool>& state, QStandardItem* parentItem = nullptr);
QStandardItem* refreshSchemaDb(Db* db);
- QList<QStandardItem*> refreshSchemaTables(const QStringList &tables, const QStringList& virtualTables, bool sort);
- StrHash<QList<QStandardItem*>> refreshSchemaTableColumns(const StrHash<QStringList>& columns);
- StrHash<QList<QStandardItem*>> refreshSchemaIndexes(const StrHash<QStringList>& indexes, bool sort);
- StrHash<QList<QStandardItem*>> refreshSchemaTriggers(const StrHash<QStringList>& triggers, bool sort);
+ QList<QStandardItem*> refreshSchemaTables(const QStringList &tables, const QSet<QString>& virtualTables, bool sort);
+ QList<QStandardItem*> refreshSchemaTableColumns(const QStringList& columns);
+ QList<QStandardItem*> refreshSchemaIndexes(const QStringList& indexes, bool sort);
+ QList<QStandardItem*> refreshSchemaTriggers(const QStringList& triggers, bool sort);
QList<QStandardItem*> refreshSchemaViews(const QStringList &views, bool sort);
void populateChildItemsWithDb(QStandardItem* parentItem, Db* db);
- void refreshSchemaBuild(QStandardItem* dbItem, QList<QStandardItem*> tables, StrHash<QList<QStandardItem*> > indexes,
- StrHash<QList<QStandardItem*> > triggers, QList<QStandardItem*> views, StrHash<QList<QStandardItem*> > allTableColumns);
+ void loadTableSchema(DbTreeItem* tableItem);
+ void loadViewSchema(DbTreeItem* viewItem);
+ void refreshSchemaBuild(QStandardItem* dbItem, QList<QStandardItem*> tables, QList<QStandardItem*> views);
void restoreExpandedState(const QHash<QString, bool>& expandedState, QStandardItem* parentItem);
- DbTreeItem* findFirstItemOfType(DbTreeItem::Type type, QStandardItem* parentItem);
QString getToolTip(DbTreeItem *item) const;
QString getDbToolTip(DbTreeItem *item) const;
QString getTableToolTip(DbTreeItem *item) const;