mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-01-20 11:00:44 -06:00
Merge pull request #1246 from sqlitebrowser/save_filter_as_view
Save current filter, sort column and display formats as a new view
This commit is contained in:
@@ -1861,7 +1861,7 @@ void MainWindow::saveSqlResultsAsCsv()
|
||||
|
||||
void MainWindow::saveSqlResultsAsView()
|
||||
{
|
||||
qobject_cast<SqlExecutionArea*>(ui->tabSqlAreas->currentWidget())->saveAsView();
|
||||
saveAsView(qobject_cast<SqlExecutionArea*>(ui->tabSqlAreas->currentWidget())->getModel()->query());
|
||||
}
|
||||
|
||||
void MainWindow::loadExtension()
|
||||
@@ -2719,3 +2719,35 @@ void MainWindow::openFindReplaceDialog()
|
||||
findReplaceDialog->show();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::saveAsView(QString query)
|
||||
{
|
||||
// Let the user select a name for the new view and make sure it doesn't already exist
|
||||
QString name;
|
||||
while(true)
|
||||
{
|
||||
name = QInputDialog::getText(this, qApp->applicationName(), tr("Please specify the view name")).trimmed();
|
||||
if(name.isNull())
|
||||
return;
|
||||
if(db.getObjectByName(sqlb::ObjectIdentifier("main", name)) != nullptr)
|
||||
QMessageBox::warning(this, qApp->applicationName(), tr("There is already an object with that name. Please choose a different name."));
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// Create the view
|
||||
if(db.executeSQL(QString("CREATE VIEW %1 AS %2;").arg(sqlb::escapeIdentifier(name)).arg(query)))
|
||||
QMessageBox::information(this, qApp->applicationName(), tr("View successfully created."));
|
||||
else
|
||||
QMessageBox::warning(this, qApp->applicationName(), tr("Error creating view: %1").arg(db.lastError()));
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::saveFilterAsView()
|
||||
{
|
||||
if (m_browseTableModel->filterCount() > 0)
|
||||
// Save as view a custom query without rowid
|
||||
saveAsView(m_browseTableModel->customQuery(false));
|
||||
else
|
||||
QMessageBox::information(this, qApp->applicationName(), tr("There is no filter set for this table. View will not be created."));
|
||||
}
|
||||
|
||||
@@ -190,6 +190,7 @@ private:
|
||||
void activateFields(bool enable = true);
|
||||
void enableEditing(bool enable_edit, bool enable_insertdelete);
|
||||
void loadExtensionsFromSettings();
|
||||
void saveAsView(QString query);
|
||||
|
||||
sqlb::ObjectIdentifier currentlyBrowsedTableName() const;
|
||||
|
||||
@@ -291,6 +292,7 @@ private slots:
|
||||
void renameSqlTab(int index);
|
||||
void setFindFrameVisibility(bool show);
|
||||
void openFindReplaceDialog();
|
||||
void saveFilterAsView();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -158,6 +158,20 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonSaveFilterAsView">
|
||||
<property name="toolTip">
|
||||
<string>Save the current filter as a view</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="icons/icons.qrc">
|
||||
<normaloff>:/icons/save_table</normaloff>:/icons/save_table</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
@@ -3021,6 +3035,22 @@
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonSaveFilterAsView</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>MainWindow</receiver>
|
||||
<slot>saveFilterAsView()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>290</x>
|
||||
<y>127</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>518</x>
|
||||
<y>314</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>fileOpen()</slot>
|
||||
|
||||
@@ -103,28 +103,6 @@ void SqlExecutionArea::saveAsCsv()
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void SqlExecutionArea::saveAsView()
|
||||
{
|
||||
// Let the user select a name for the new view and make sure it doesn't already exist
|
||||
QString name;
|
||||
while(true)
|
||||
{
|
||||
name = QInputDialog::getText(this, qApp->applicationName(), tr("Please specify the view name")).trimmed();
|
||||
if(name.isEmpty())
|
||||
return;
|
||||
if(db.getObjectByName(sqlb::ObjectIdentifier("main", name)) != nullptr)
|
||||
QMessageBox::warning(this, qApp->applicationName(), tr("There is already an object with that name. Please choose a different name."));
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// Create the view
|
||||
if(db.executeSQL(QString("CREATE VIEW %1 AS %2;").arg(sqlb::escapeIdentifier(name)).arg(model->query())))
|
||||
QMessageBox::information(this, qApp->applicationName(), tr("View successfully created."));
|
||||
else
|
||||
QMessageBox::warning(this, qApp->applicationName(), tr("Error creating view: %1").arg(db.lastError()));
|
||||
}
|
||||
|
||||
void SqlExecutionArea::reloadSettings()
|
||||
{
|
||||
// Reload editor and table settings
|
||||
|
||||
@@ -33,7 +33,6 @@ public:
|
||||
public slots:
|
||||
virtual void finishExecution(const QString& result, const bool ok);
|
||||
virtual void saveAsCsv();
|
||||
virtual void saveAsView();
|
||||
virtual void reloadSettings();
|
||||
void fetchedData();
|
||||
void setFindFrameVisibility(bool show);
|
||||
|
||||
@@ -216,6 +216,11 @@ int SqliteTableModel::columnCount(const QModelIndex&) const
|
||||
return m_headers.size();
|
||||
}
|
||||
|
||||
int SqliteTableModel::filterCount() const
|
||||
{
|
||||
return m_mWhere.size();
|
||||
}
|
||||
|
||||
QVariant SqliteTableModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
@@ -590,7 +595,7 @@ void SqliteTableModel::fetchData(unsigned int from, unsigned to)
|
||||
});
|
||||
}
|
||||
|
||||
void SqliteTableModel::buildQuery()
|
||||
QString SqliteTableModel::customQuery(bool withRowid)
|
||||
{
|
||||
QString where;
|
||||
|
||||
@@ -600,12 +605,10 @@ void SqliteTableModel::buildQuery()
|
||||
|
||||
for(QMap<int, QString>::const_iterator i=m_mWhere.constBegin();i!=m_mWhere.constEnd();++i)
|
||||
{
|
||||
QString column;
|
||||
if(m_vDisplayFormat.size())
|
||||
column = QString("col%1").arg(i.key());
|
||||
else
|
||||
column = m_headers.at(i.key());
|
||||
where.append(QString("%1 %2 AND ").arg(sqlb::escapeIdentifier(column)).arg(i.value()));
|
||||
QString columnId = sqlb::escapeIdentifier(m_headers.at(i.key()));
|
||||
if(m_vDisplayFormat.size() && m_vDisplayFormat.at(i.key()-1) != columnId)
|
||||
columnId = sqlb::escapeIdentifier(m_headers.at(i.key()) + "_");
|
||||
where.append(QString("%1 %2 AND ").arg(columnId).arg(i.value()));
|
||||
}
|
||||
|
||||
// Remove last 'AND '
|
||||
@@ -613,12 +616,21 @@ void SqliteTableModel::buildQuery()
|
||||
}
|
||||
|
||||
QString selector;
|
||||
if (withRowid)
|
||||
selector = sqlb::escapeIdentifier(m_headers.at(0)) + ",";
|
||||
|
||||
if(m_vDisplayFormat.empty())
|
||||
{
|
||||
selector = "*";
|
||||
selector += "*";
|
||||
} else {
|
||||
for(int i=0;i<m_vDisplayFormat.size();i++)
|
||||
selector += m_vDisplayFormat.at(i) + " AS " + QString("col%1").arg(i+1) + ",";
|
||||
QString columnId;
|
||||
for(int i=0;i<m_vDisplayFormat.size();i++) {
|
||||
columnId = sqlb::escapeIdentifier(m_headers.at(i+1));
|
||||
if (columnId != m_vDisplayFormat.at(i))
|
||||
selector += m_vDisplayFormat.at(i) + " AS " + sqlb::escapeIdentifier(m_headers.at(i+1) + "_") + ",";
|
||||
else
|
||||
selector += columnId + ",";
|
||||
}
|
||||
selector.chop(1);
|
||||
}
|
||||
|
||||
@@ -626,15 +638,18 @@ void SqliteTableModel::buildQuery()
|
||||
// The reason is that we're adding '%' characters automatically around search terms (and even if we didn't the user could add
|
||||
// them manually) which means that e.g. searching for '1' results in another '%1' in the string which then totally confuses
|
||||
// the QString::arg() function, resulting in an invalid SQL.
|
||||
QString sql = QString("SELECT %1,%2 FROM %3 ")
|
||||
.arg(sqlb::escapeIdentifier(m_headers.at(0)))
|
||||
return QString("SELECT %1 FROM %2 ")
|
||||
.arg(selector)
|
||||
.arg(m_sTable.toString())
|
||||
+ where
|
||||
+ QString("ORDER BY %1 %2")
|
||||
.arg(sqlb::escapeIdentifier(m_headers.at(m_iSortColumn)))
|
||||
.arg(m_sSortOrder);
|
||||
setQuery(sql, true);
|
||||
}
|
||||
|
||||
void SqliteTableModel::buildQuery()
|
||||
{
|
||||
setQuery(customQuery(true), true);
|
||||
}
|
||||
|
||||
void SqliteTableModel::removeCommentsFromQuery(QString& query) {
|
||||
|
||||
@@ -26,6 +26,7 @@ public:
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int totalRowCount() const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int filterCount() const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
|
||||
@@ -40,6 +41,7 @@ public:
|
||||
|
||||
void setQuery(const QString& sQuery, bool dontClearHeaders = false);
|
||||
QString query() const { return m_sQuery; }
|
||||
QString customQuery(bool withRowid);
|
||||
void setTable(const sqlb::ObjectIdentifier& table, int sortColumn = 0, Qt::SortOrder sortOrder = Qt::AscendingOrder, const QVector<QString> &display_format = QVector<QString>());
|
||||
void setChunkSize(size_t chunksize);
|
||||
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
|
||||
|
||||
Reference in New Issue
Block a user