diff --git a/src/DbStructureModel.cpp b/src/DbStructureModel.cpp index 4726d54d..e0b616d2 100644 --- a/src/DbStructureModel.cpp +++ b/src/DbStructureModel.cpp @@ -40,7 +40,13 @@ QVariant DbStructureModel::data(const QModelIndex& index, int role) const switch(role) { case Qt::DisplayRole: - return Settings::getValue("db", "hideschemalinebreaks").toBool() ? item->text(index.column()).replace("\n", " ").simplified() : item->text(index.column()); + // For the display role and the browsabled branch of the tree we want to show the column name including the schema name if necessary (i.e. + // for schemata != "main"). For the normal structure branch of the tree we don't want to add the schema name because it's already obvious from + // the position of the item in the tree. + if(index.column() == ColumnName && item->parent() == browsablesRootItem) + return sqlb::ObjectIdentifier(item->text(ColumnSchema), item->text(ColumnName)).toDisplayString(); + else + return Settings::getValue("db", "hideschemalinebreaks").toBool() ? item->text(index.column()).replace("\n", " ").simplified() : item->text(index.column()); case Qt::EditRole: case Qt::ToolTipRole: // Don't modify the text when it's supposed to be shown in a tooltip return item->text(index.column()); @@ -138,14 +144,14 @@ void DbStructureModel::reloadData() // In the root node there are two nodes: 'browsables' and 'all'. The first node contains a list of a all browsable objects, i.e. views and tables. // The seconds node contains four sub-nodes (tables, indices, views and triggers), each containing a list of objects of that type. // This way we only have to have and only have to update one model and can use it in all sorts of places, just by setting a different root node. - QTreeWidgetItem* itemBrowsables = new QTreeWidgetItem(rootItem); - itemBrowsables->setIcon(ColumnName, QIcon(QString(":/icons/view"))); - itemBrowsables->setText(ColumnName, tr("Browsables")); + browsablesRootItem = new QTreeWidgetItem(rootItem); + browsablesRootItem->setIcon(ColumnName, QIcon(QString(":/icons/view"))); + browsablesRootItem->setText(ColumnName, tr("Browsables")); QTreeWidgetItem* itemAll = new QTreeWidgetItem(rootItem); itemAll->setIcon(ColumnName, QIcon(QString(":/icons/database"))); itemAll->setText(ColumnName, tr("All")); - buildTree(itemAll, itemBrowsables, "main"); + buildTree(itemAll, "main"); // Add the temporary database as a node if it isn't empty if(!m_db.schemata["temp"].isEmpty()) @@ -153,7 +159,7 @@ void DbStructureModel::reloadData() QTreeWidgetItem* itemTemp = new QTreeWidgetItem(itemAll); itemTemp->setIcon(ColumnName, QIcon(QString(":/icons/database"))); itemTemp->setText(ColumnName, tr("Temporary")); - buildTree(itemTemp, itemBrowsables, "temp"); + buildTree(itemTemp, "temp"); } // Refresh the view @@ -232,7 +238,7 @@ bool DbStructureModel::dropMimeData(const QMimeData* data, Qt::DropAction action } } -void DbStructureModel::buildTree(QTreeWidgetItem* parent, QTreeWidgetItem* browsables, const QString& schema) +void DbStructureModel::buildTree(QTreeWidgetItem* parent, const QString& schema) { // Build a map from object type to tree node to simplify finding the correct tree node later QMap typeToParentItem; @@ -274,12 +280,7 @@ void DbStructureModel::buildTree(QTreeWidgetItem* parent, QTreeWidgetItem* brows // If it is a table or view add the field nodes, add an extra node for the browsable section if((*it)->type() == sqlb::Object::Types::Table || (*it)->type() == sqlb::Object::Types::View) - { - // TODO We're currently only adding objects in the main schema to the list of browsable objects because browsing non-main objects - // isn't really supported in the main window yet. As soon as this is implemented the following if statement can be removed. - if(schema == "main") - addNode(browsables, *it, schema); - } + addNode(browsablesRootItem, *it, schema); // Add field nodes if there are any sqlb::FieldInfoList fieldList = (*it)->fieldInformation(); diff --git a/src/DbStructureModel.h b/src/DbStructureModel.h index f1bb764a..691d3a69 100644 --- a/src/DbStructureModel.h +++ b/src/DbStructureModel.h @@ -39,10 +39,11 @@ public: }; private: - QTreeWidgetItem* rootItem; DBBrowserDB& m_db; + QTreeWidgetItem* rootItem; + QTreeWidgetItem* browsablesRootItem; - void buildTree(QTreeWidgetItem* parent, QTreeWidgetItem* browsables, const QString& schema); + void buildTree(QTreeWidgetItem* parent, const QString& schema); QTreeWidgetItem* addNode(QTreeWidgetItem* parent, const sqlb::ObjectPtr& object, const QString& schema); }; diff --git a/src/ExtendedTableWidget.cpp b/src/ExtendedTableWidget.cpp index 1ff1e952..2b93e9c3 100644 --- a/src/ExtendedTableWidget.cpp +++ b/src/ExtendedTableWidget.cpp @@ -433,7 +433,9 @@ void ExtendedTableWidget::cellClicked(const QModelIndex& index) sqlb::ForeignKeyClause fk = m->getForeignKeyClause(index.column()-1); if(fk.isSet()) - emit foreignKeyClicked(fk.table(), fk.columns().size() ? fk.columns().at(0) : "", m->data(index, Qt::EditRole).toByteArray()); + emit foreignKeyClicked(sqlb::ObjectIdentifier(m->currentTableName().schema(), fk.table()), + fk.columns().size() ? fk.columns().at(0) : "", + m->data(index, Qt::EditRole).toByteArray()); } } diff --git a/src/ExtendedTableWidget.h b/src/ExtendedTableWidget.h index 3b4512e7..4d5c86da 100644 --- a/src/ExtendedTableWidget.h +++ b/src/ExtendedTableWidget.h @@ -8,6 +8,7 @@ class QMenu; class FilterTableHeader; +namespace sqlb { class ObjectIdentifier; } class ExtendedTableWidget : public QTableView { @@ -26,7 +27,7 @@ public slots: void reloadSettings(); signals: - void foreignKeyClicked(const QString& table, const QString& column, const QByteArray& value); + void foreignKeyClicked(const sqlb::ObjectIdentifier& table, const QString& column, const QByteArray& value); void switchTable(bool next); // 'next' parameter is set to true if next table should be selected and to false if previous table should be selected private: diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 0ab918a8..8a20f69c 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -439,7 +439,7 @@ void MainWindow::populateTable() QApplication::setOverrideCursor(Qt::WaitCursor); // Get current table name - QString tablename = ui->comboBrowseTable->currentText(); + sqlb::ObjectIdentifier tablename = currentlyBrowsedTableName(); // Set model bool reconnectSelectionSignals = false; @@ -450,8 +450,7 @@ void MainWindow::populateTable() connect(ui->dataTable->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(dataTableSelectionChanged(QModelIndex))); // Search stored table settings for this table - auto settingsIt = browseTableSettings.constFind(tablename); - bool storedDataFound = settingsIt != browseTableSettings.constEnd(); + bool storedDataFound = browseTableSettings.contains(tablename); // Set new table if(!storedDataFound) @@ -459,7 +458,7 @@ void MainWindow::populateTable() // No stored settings found. // Set table name and apply default display format settings - m_browseTableModel->setTable(sqlb::ObjectIdentifier("main", tablename), 0, Qt::AscendingOrder); + m_browseTableModel->setTable(tablename, 0, Qt::AscendingOrder); // There aren't any information stored for this table yet, so use some default values @@ -480,17 +479,17 @@ void MainWindow::populateTable() m_browseTableModel->setEncoding(defaultBrowseTableEncoding); // Plot - plotDock->updatePlot(m_browseTableModel, &browseTableSettings[ui->comboBrowseTable->currentText()]); + plotDock->updatePlot(m_browseTableModel, &browseTableSettings[tablename]); // The filters can be left empty as they are } else { // Stored settings found. Retrieve them. - BrowseDataTableSettings storedData = settingsIt.value(); + BrowseDataTableSettings storedData = browseTableSettings[tablename]; // Load display formats and set them along with the table name QVector v; bool only_defaults = true; - const sqlb::FieldInfoList& tablefields = db.getObjectByName(sqlb::ObjectIdentifier("main", tablename))->fieldInformation(); + const sqlb::FieldInfoList& tablefields = db.getObjectByName(tablename)->fieldInformation(); for(int i=0; isetTable(sqlb::ObjectIdentifier("main", tablename), storedData.sortOrderIndex, storedData.sortOrderMode); + m_browseTableModel->setTable(tablename, storedData.sortOrderIndex, storedData.sortOrderMode); else - m_browseTableModel->setTable(sqlb::ObjectIdentifier("main", tablename), storedData.sortOrderIndex, storedData.sortOrderMode, v); + m_browseTableModel->setTable(tablename, storedData.sortOrderIndex, storedData.sortOrderMode, v); // There is information stored for this table, so extract it and apply it @@ -532,11 +531,11 @@ void MainWindow::populateTable() m_browseTableModel->setEncoding(storedData.encoding); // Plot - plotDock->updatePlot(m_browseTableModel, &browseTableSettings[ui->comboBrowseTable->currentText()], true, false); + plotDock->updatePlot(m_browseTableModel, &browseTableSettings[tablename], true, false); } // Show/hide menu options depending on whether this is a table or a view - if(db.getObjectByName(sqlb::ObjectIdentifier("main", ui->comboBrowseTable->currentText()))->type() == sqlb::Object::Table) + if(db.getObjectByName(currentlyBrowsedTableName())->type() == sqlb::Object::Table) { // Table ui->actionUnlockViewEditing->setVisible(false); @@ -859,7 +858,7 @@ void MainWindow::doubleClickTable(const QModelIndex& index) // * Don't allow editing of other objects than tables (on the browse table) * bool isEditingAllowed = (m_currentTabTableModel == m_browseTableModel) && - (db.getObjectByName(sqlb::ObjectIdentifier("main", ui->comboBrowseTable->currentText()))->type() == sqlb::Object::Types::Table); + (db.getObjectByName(currentlyBrowsedTableName())->type() == sqlb::Object::Types::Table); // Enable or disable the Apply, Null, & Import buttons in the Edit Cell // dock depending on the value of the "isEditingAllowed" bool above @@ -883,7 +882,7 @@ void MainWindow::dataTableSelectionChanged(const QModelIndex& index) } bool editingAllowed = (m_currentTabTableModel == m_browseTableModel) && - (db.getObjectByName(sqlb::ObjectIdentifier("main", ui->comboBrowseTable->currentText()))->type() == sqlb::Object::Types::Table); + (db.getObjectByName(currentlyBrowsedTableName())->type() == sqlb::Object::Types::Table); // Don't allow editing of other objects than tables editDock->setReadOnly(!editingAllowed); @@ -1176,7 +1175,7 @@ void MainWindow::exportTableToCSV() current_table = sqlb::ObjectIdentifier(schema, name); } } else if(ui->mainTab->currentIndex() == BrowseTab) { - current_table = sqlb::ObjectIdentifier("main", ui->comboBrowseTable->currentText()); + current_table = currentlyBrowsedTableName(); } // Open dialog @@ -1198,7 +1197,7 @@ void MainWindow::exportTableToJson() current_table = sqlb::ObjectIdentifier(schema, name); } } else if(ui->mainTab->currentIndex() == BrowseTab) { - current_table = sqlb::ObjectIdentifier("main", ui->comboBrowseTable->currentText()); + current_table = currentlyBrowsedTableName(); } // Open dialog @@ -1529,7 +1528,7 @@ void MainWindow::browseTableHeaderClicked(int logicalindex) return; // instead of the column name we just use the column index, +2 because 'rowid, *' is the projection - BrowseDataTableSettings& settings = browseTableSettings[ui->comboBrowseTable->currentText()]; + BrowseDataTableSettings& settings = browseTableSettings[currentlyBrowsedTableName()]; settings.sortOrderIndex = logicalindex; settings.sortOrderMode = settings.sortOrderMode == Qt::AscendingOrder ? Qt::DescendingOrder : Qt::AscendingOrder; ui->dataTable->sortByColumn(settings.sortOrderIndex, settings.sortOrderMode); @@ -1910,7 +1909,8 @@ void MainWindow::on_actionWebsite_triggered() void MainWindow::updateBrowseDataColumnWidth(int section, int /*old_size*/, int new_size) { QSet selectedCols(ui->dataTable->selectedCols()); - QString tableName(ui->comboBrowseTable->currentText()); + sqlb::ObjectIdentifier tableName = currentlyBrowsedTableName(); + if (!selectedCols.contains(section)) { browseTableSettings[tableName].columnWidths[section] = new_size; @@ -2021,10 +2021,11 @@ bool MainWindow::loadProject(QString filename, bool readOnly) if(ui->mainTab->currentIndex() == BrowseTab) { populateTable(); // Refresh view - ui->dataTable->sortByColumn(browseTableSettings[ui->comboBrowseTable->currentText()].sortOrderIndex, - browseTableSettings[ui->comboBrowseTable->currentText()].sortOrderMode); - showRowidColumn(browseTableSettings[ui->comboBrowseTable->currentText()].showRowid); - unlockViewEditing(!browseTableSettings[ui->comboBrowseTable->currentText()].unlockViewPk.isEmpty(), browseTableSettings[ui->comboBrowseTable->currentText()].unlockViewPk); + sqlb::ObjectIdentifier current_table = currentlyBrowsedTableName(); + ui->dataTable->sortByColumn(browseTableSettings[current_table].sortOrderIndex, + browseTableSettings[current_table].sortOrderMode); + showRowidColumn(browseTableSettings[current_table].showRowid); + unlockViewEditing(!browseTableSettings[current_table].unlockViewPk.isEmpty(), browseTableSettings[current_table].unlockViewPk); } xml.skipCurrentElement(); } @@ -2176,7 +2177,7 @@ void MainWindow::fileAttach() void MainWindow::updateFilter(int column, const QString& value) { m_browseTableModel->updateFilter(column, value); - browseTableSettings[ui->comboBrowseTable->currentText()].filterValues[column] = value; + browseTableSettings[currentlyBrowsedTableName()].filterValues[column] = value; setRecordsetLabel(); } @@ -2252,7 +2253,9 @@ void MainWindow::switchToBrowseDataTab(QString tableToBrowse) if(!ui->dbTreeWidget->selectionModel()->hasSelection()) return; - tableToBrowse = ui->dbTreeWidget->model()->data(ui->dbTreeWidget->currentIndex().sibling(ui->dbTreeWidget->currentIndex().row(), 0)).toString(); + sqlb::ObjectIdentifier obj(ui->dbTreeWidget->model()->data(ui->dbTreeWidget->currentIndex().sibling(ui->dbTreeWidget->currentIndex().row(), DbStructureModel::ColumnSchema)).toString(), + ui->dbTreeWidget->model()->data(ui->dbTreeWidget->currentIndex().sibling(ui->dbTreeWidget->currentIndex().row(), DbStructureModel::ColumnName)).toString()); + tableToBrowse = obj.toDisplayString(); } ui->comboBrowseTable->setCurrentIndex(ui->comboBrowseTable->findText(tableToBrowse)); @@ -2277,10 +2280,10 @@ void MainWindow::copyCurrentCreateStatement() QApplication::clipboard()->setText(stmt); } -void MainWindow::jumpToRow(const QString& table, QString column, const QByteArray& value) +void MainWindow::jumpToRow(const sqlb::ObjectIdentifier& table, QString column, const QByteArray& value) { // First check if table exists - sqlb::TablePtr obj = db.getObjectByName(sqlb::ObjectIdentifier("main", table)).dynamicCast(); + sqlb::TablePtr obj = db.getObjectByName(table).dynamicCast(); if(!obj) return; @@ -2294,7 +2297,7 @@ void MainWindow::jumpToRow(const QString& table, QString column, const QByteArra return; // Jump to table - ui->comboBrowseTable->setCurrentIndex(ui->comboBrowseTable->findText(table)); + ui->comboBrowseTable->setCurrentIndex(ui->comboBrowseTable->findText(table.toDisplayString())); populateTable(); // Set filter @@ -2316,8 +2319,7 @@ void MainWindow::showDataColumnPopupMenu(const QPoint& pos) void MainWindow::showRecordPopupMenu(const QPoint& pos) { - const QString sCurrentTable = ui->comboBrowseTable->currentText(); - if(!(db.getObjectByName(sqlb::ObjectIdentifier("main", sCurrentTable))->type() == sqlb::Object::Types::Table && !db.readOnly())) + if(!(db.getObjectByName(currentlyBrowsedTableName())->type() == sqlb::Object::Types::Table && !db.readOnly())) return; int row = ui->dataTable->verticalHeader()->logicalIndexAt(pos); @@ -2340,9 +2342,9 @@ void MainWindow::editDataColumnDisplayFormat() // Get the current table name and fetch its table object, then retrieve the fields of that table and look up the index of the clicked table header // section using it as the table field array index. Subtract one from the header index to get the column index because in the the first (though hidden) // column is always the rowid column. Ultimately, get the column name from the column object - QString current_table = ui->comboBrowseTable->currentText(); + sqlb::ObjectIdentifier current_table = currentlyBrowsedTableName(); int field_number = sender()->property("clicked_column").toInt(); - QString field_name = db.getObjectByName(sqlb::ObjectIdentifier("main", current_table)).dynamicCast()->fields().at(field_number-1)->name(); + QString field_name = db.getObjectByName(current_table).dynamicCast()->fields().at(field_number-1)->name(); // Get the current display format of the field QString current_displayformat = browseTableSettings[current_table].displayFormats[field_number]; @@ -2384,7 +2386,7 @@ void MainWindow::showRowidColumn(bool show) ui->actionShowRowidColumn->setChecked(show); // Save settings for this table - QString current_table = ui->comboBrowseTable->currentText(); + sqlb::ObjectIdentifier current_table = currentlyBrowsedTableName(); browseTableSettings[current_table].showRowid = show; // Update the filter row @@ -2429,7 +2431,7 @@ void MainWindow::browseDataSetTableEncoding(bool forAllTables) m_browseTableModel->setEncoding(encoding); // Save encoding for this table - browseTableSettings[ui->comboBrowseTable->currentText()].encoding = encoding; + browseTableSettings[currentlyBrowsedTableName()].encoding = encoding; // Set default encoding if requested to and change all stored table encodings if(forAllTables) @@ -2455,10 +2457,10 @@ void MainWindow::fileOpenReadOnly() void MainWindow::unlockViewEditing(bool unlock, QString pk) { - QString currentTable = ui->comboBrowseTable->currentText(); + sqlb::ObjectIdentifier currentTable = currentlyBrowsedTableName(); // If this isn't a view just unlock editing and return - if(db.getObjectByName(sqlb::ObjectIdentifier("main", currentTable))->type() != sqlb::Object::View) + if(db.getObjectByName(currentTable)->type() != sqlb::Object::View) { m_browseTableModel->setPseudoPk(QString()); enableEditing(true, true); @@ -2479,7 +2481,7 @@ void MainWindow::unlockViewEditing(bool unlock, QString pk) return; // Do some basic testing of the input and if the input appears to be good, go on - if(db.executeSQL(QString("SELECT %1 FROM %2 LIMIT 1;").arg(sqlb::escapeIdentifier(pk)).arg(sqlb::escapeIdentifier(currentTable)), false, true)) + if(db.executeSQL(QString("SELECT %1 FROM %2 LIMIT 1;").arg(sqlb::escapeIdentifier(pk)).arg(currentTable.toString()), false, true)) break; } } else if(!unlock) { @@ -2497,3 +2499,12 @@ void MainWindow::unlockViewEditing(bool unlock, QString pk) // Save settings for this table browseTableSettings[currentTable].unlockViewPk = pk; } + +sqlb::ObjectIdentifier MainWindow::currentlyBrowsedTableName() const +{ + return sqlb::ObjectIdentifier(ui->comboBrowseTable->model()->data(dbStructureModel->index(ui->comboBrowseTable->currentIndex(), + DbStructureModel::ColumnSchema, + ui->comboBrowseTable->rootModelIndex())).toString(), + ui->comboBrowseTable->currentData(Qt::EditRole).toString()); // Use the edit role here to make sure we actually get the + // table name without the schema bit in front of it. +} diff --git a/src/MainWindow.h b/src/MainWindow.h index 8218cd51..4448c282 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -144,7 +144,7 @@ private: QAction *recentFileActs[MaxRecentFiles]; QAction *recentSeparatorAct; - QMap browseTableSettings; + QMap browseTableSettings; RemoteDatabase* m_remoteDb; @@ -167,6 +167,8 @@ private: void enableEditing(bool enable_edit, bool enable_insertdelete); void loadExtensionsFromSettings(); + sqlb::ObjectIdentifier currentlyBrowsedTableName() const; + protected: void closeEvent(QCloseEvent *); void dragEnterEvent(QDragEnterEvent *event); @@ -179,7 +181,7 @@ public slots: void logSql(const QString &sql, int msgtype); void dbState(bool dirty); void refresh(); - void jumpToRow(const QString& table, QString column, const QByteArray& value); + void jumpToRow(const sqlb::ObjectIdentifier& table, QString column, const QByteArray& value); void switchToBrowseDataTab(QString tableToBrowse = QString()); void populateStructure(); diff --git a/src/MainWindow.ui b/src/MainWindow.ui index d6d2d460..012c4773 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -1791,7 +1791,7 @@ QTableWidget
ExtendedTableWidget.h
- foreignKeyClicked(QString,QString,QByteArray) + foreignKeyClicked(sqlb::ObjectIdentifier,QString,QByteArray) @@ -2687,9 +2687,9 @@ dataTable - foreignKeyClicked(QString,QString,QByteArray) + foreignKeyClicked(sqlb::ObjectIdentifier,QString,QByteArray) MainWindow - jumpToRow(QString,QString,QByteArray) + jumpToRow(sqlb::ObjectIdentifier,QString,QByteArray) 70 @@ -2884,7 +2884,7 @@ saveSqlFileAs() switchToBrowseDataTab() copyCurrentCreateStatement() - jumpToRow(QString,QString,QByteArray) + jumpToRow(sqlb::ObjectIdentifier,QString,QByteArray) editDataColumnDisplayFormat() showRowidColumn(bool) browseDataSetTableEncoding() diff --git a/src/sqlitetablemodel.h b/src/sqlitetablemodel.h index cc188b2c..e7547a62 100644 --- a/src/sqlitetablemodel.h +++ b/src/sqlitetablemodel.h @@ -42,6 +42,7 @@ public: void setTable(const sqlb::ObjectIdentifier& table, int sortColumn = 0, Qt::SortOrder sortOrder = Qt::AscendingOrder, const QVector &display_format = QVector()); void setChunkSize(size_t chunksize); void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); + const sqlb::ObjectIdentifier& currentTableName() const { return m_sTable; } Qt::ItemFlags flags(const QModelIndex& index) const; diff --git a/src/sqlitetypes.cpp b/src/sqlitetypes.cpp index 8b1fce14..04893d9e 100644 --- a/src/sqlitetypes.cpp +++ b/src/sqlitetypes.cpp @@ -22,6 +22,28 @@ QStringList fieldVectorToFieldNames(const FieldVector& vector) return result; } +QDataStream& operator<<(QDataStream& ds, const ObjectIdentifier& objid) +{ + ds << objid.toVariant(); + return ds; +} + +QDataStream & operator>>(QDataStream& ds, ObjectIdentifier& objid) +{ + // Read in the item + QVariant v; + ds >> v; + + // If it is a string list, we can treat it as an object identifier. If it isn't, we assume it's just a + // single string and use interpret it as the table name in the main schema. This is done for backwards + // compatability with old project file formats. + if(v.toStringList().isEmpty()) + objid = sqlb::ObjectIdentifier("main", v.toString()); + else + objid = sqlb::ObjectIdentifier(v); + return ds; +} + /** * @brief The CreateTableWalker class * Goes trough the createtable AST and returns diff --git a/src/sqlitetypes.h b/src/sqlitetypes.h index aa4da038..9706cc4d 100644 --- a/src/sqlitetypes.h +++ b/src/sqlitetypes.h @@ -49,6 +49,11 @@ public: return (rhs.m_schema == m_schema && rhs.m_name == m_name); } + bool operator<(const ObjectIdentifier& rhs) const + { + return toDisplayString() < rhs.toDisplayString(); + } + const QString& schema() const { return m_schema; } const QString& name() const { return m_name; } void setSchema(const QString& schema) { m_schema = schema; } @@ -92,6 +97,9 @@ private: QString m_name; }; +QDataStream& operator<<(QDataStream& ds, const ObjectIdentifier& objid); +QDataStream & operator>>(QDataStream& ds, ObjectIdentifier& objid); + class Object; class Table; class Index;