Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/app/models/connectionconf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ void ServerConfig::setNamespaceSeparator(QString ns)
return setParam<QString>("namespace_separator", ns);
}

bool ServerConfig::namespaceSeparatorIsRegex() const
{
return param<bool>("namespace_separator_is_regex", false);
}

void ServerConfig::setNamespaceSeparatorIsRegex(bool v)
{
return setParam<bool>("namespace_separator_is_regex", v);
}

uint ServerConfig::databaseScanLimit() const
{
return param<uint>("db_scan_limit", DEFAULT_DB_SCAN_LIMIT);
Expand Down
5 changes: 5 additions & 0 deletions src/app/models/connectionconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class ServerConfig : public RedisClient::ConnectionConfig
/* Advanced settings */
Q_PROPERTY(QString keysPattern READ keysPattern WRITE setKeysPattern)
Q_PROPERTY(QString namespaceSeparator READ namespaceSeparator WRITE setNamespaceSeparator)
Q_PROPERTY(bool namespaceSeparatorIsRegex READ namespaceSeparatorIsRegex WRITE setNamespaceSeparatorIsRegex)
Q_PROPERTY(uint executeTimeout READ executeTimeout WRITE setExecutionTimeout)
Q_PROPERTY(uint connectionTimeout READ connectionTimeout WRITE setConnectionTimeout)
Q_PROPERTY(bool overrideClusterHost READ overrideClusterHost WRITE setClusterHostOverride)
Expand Down Expand Up @@ -59,6 +60,10 @@ class ServerConfig : public RedisClient::ConnectionConfig
QString namespaceSeparator() const;
void setNamespaceSeparator(QString);

bool namespaceSeparatorIsRegex() const;
void setNamespaceSeparatorIsRegex(bool v);

bool luaKeysLoading() const;
void setLuaKeysLoading(bool);

uint databaseScanLimit() const;
Expand Down
5 changes: 3 additions & 2 deletions src/app/models/treeoperations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,9 @@ void TreeOperations::resetConnection() {
QtConcurrent::run([oldConnection]() { oldConnection->disconnect(); });
}

QString TreeOperations::getNamespaceSeparator() {
return m_config.namespaceSeparator();
QRegExp TreeOperations::getNamespaceSeparator() {
return QRegExp(m_config.namespaceSeparator(), Qt::CaseSensitive,
m_config.namespaceSeparatorIsRegex()? QRegExp::RegExp : QRegExp::FixedString);
}

QString TreeOperations::defaultFilter() { return m_config.keysPattern(); }
Expand Down
2 changes: 1 addition & 1 deletion src/app/models/treeoperations.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class TreeOperations : public QObject,

void resetConnection() override;

QString getNamespaceSeparator() override;
QRegExp getNamespaceSeparator() override;

QString defaultFilter() override;

Expand Down
14 changes: 11 additions & 3 deletions src/modules/connections-tree/items/keyitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,17 @@ QString KeyItem::getDisplayName() const {
m_shortRendering) {
auto parent = parentTreeItemToNs(m_parent);

title = printableString(getFullPath().mid(
parent->getFullPath().size() +
parent->operations()->getNamespaceSeparator().size()));
auto nsRx = parent->operations()->getNamespaceSeparator();
int searchFrom = parent->getFullPath().size() > 0 ? parent->getFullPath().size() - 1 : 0;
int nsRxPos = QString::fromUtf8(getFullPath()).indexOf(nsRx, searchFrom);

int nsSize = 0;

if (nsRxPos >= 0) {
nsSize = nsRx.matchedLength();
}

title = printableString(getFullPath().mid(parent->getFullPath().size() + nsSize));
} else {
title = printableString(getFullPath(), true);
}
Expand Down
22 changes: 12 additions & 10 deletions src/modules/connections-tree/items/namespaceitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ using namespace ConnectionsTree;
NamespaceItem::NamespaceItem(const QByteArray &fullPath,
QSharedPointer<Operations> operations,
QWeakPointer<TreeItem> parent, Model &model,
uint dbIndex, QRegExp filter)
uint dbIndex, QRegExp filter, QString lastNsSeparator)
: AbstractNamespaceItem(model, parent, operations, dbIndex, filter),
m_fullPath(fullPath),
m_lastNsSeparator(lastNsSeparator),
m_removed(false) {}

QString NamespaceItem::getDisplayName() const {
Expand All @@ -33,10 +34,11 @@ QString NamespaceItem::getDisplayName() const {
}

QByteArray NamespaceItem::getName() const {
qsizetype pos = m_fullPath.lastIndexOf(m_operations->getNamespaceSeparator());
auto rx = m_operations->getNamespaceSeparator();
qsizetype pos = QString::fromUtf8(m_fullPath).lastIndexOf(rx);

if (pos >= 0) {
return m_fullPath.mid(pos + m_operations->getNamespaceSeparator().size());
return m_fullPath.mid(pos + rx.matchedLength());
} else {
return m_fullPath;
}
Expand Down Expand Up @@ -71,18 +73,18 @@ void NamespaceItem::load() {
return renderRawKeys(rawKeys, m_filter, onKeysRendered, true, false);
}

QString nsFilter = QString("%1%2*")
.arg(QString::fromUtf8(m_fullPath))
.arg(m_operations->getNamespaceSeparator());
QString nsFilter = QString("%1%2*")
.arg(QString::fromUtf8(m_fullPath))
.arg(m_lastNsSeparator);

if (!m_filter.isEmpty()) {
if (m_filter.pattern().startsWith(nsFilter.chopped(1))) {
nsFilter = m_filter.pattern();
} else {
nsFilter = QString("%1%2%3")
.arg(QString::fromUtf8(m_fullPath))
.arg(m_operations->getNamespaceSeparator())
.arg(m_filter.pattern());
.arg(QString::fromUtf8(m_fullPath))
.arg(m_lastNsSeparator)
.arg(m_filter.pattern());
}
}

Expand Down Expand Up @@ -134,7 +136,7 @@ QHash<QString, std::function<void()>> NamespaceItem::eventHandlers() {
},
QString("%1%2")
.arg(QString::fromUtf8(getFullPath()))
.arg(m_operations->getNamespaceSeparator()));
.arg(m_lastNsSeparator));
});

events.insert("reload", [this]() { reload(); });
Expand Down
3 changes: 2 additions & 1 deletion src/modules/connections-tree/items/namespaceitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class NamespaceItem : public AbstractNamespaceItem {
NamespaceItem(const QByteArray& fullPath,
QSharedPointer<Operations> operations,
QWeakPointer<TreeItem> parent, Model& model, uint dbIndex,
QRegExp filter);
QRegExp filter, QString lastNsSeparator);

QString getDisplayName() const override;

Expand All @@ -38,6 +38,7 @@ class NamespaceItem : public AbstractNamespaceItem {

private:
QByteArray m_fullPath;
QString m_lastNsSeparator;
bool m_removed;
};
} // namespace ConnectionsTree
47 changes: 34 additions & 13 deletions src/modules/connections-tree/keysrendering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,20 @@ void KeysTreeRenderer::renderKeys(QSharedPointer<Operations> operations,

int unprocessedPartStart = 0;
if (parent->getFullPath().size() > 0 || parent->type() == "namespace") {
unprocessedPartStart =
parent->getFullPath().size() + settings.nsSeparator.length();
int nsLength = 0;

if (keys.size() > 0) {
QString firstKey = QString::fromUtf8(keys[0]);
int res = firstKey.indexOf(settings.nsSeparator, parent->getFullPath().size());

qDebug() << "NSs regex pos:" << res;

nsLength = settings.nsSeparator.matchedLength();
}

unprocessedPartStart =
parent->getFullPath().size() + nsLength;

}

auto rootItem = resolveRootItem(parent);
Expand Down Expand Up @@ -68,10 +80,12 @@ void KeysTreeRenderer::renderKeys(QSharedPointer<Operations> operations,

auto isBulkInsert = [settings, preRenderedKeysSet, unprocessedPartStart](
const QByteArray &current, const QByteArray &next) {
QString currentKey = QString::fromUtf8(current);
QString nextKey = QString::fromUtf8(current);
return (settings.appendNewItems &&
current.indexOf(settings.nsSeparator, unprocessedPartStart) == -1 &&
currentKey.indexOf(settings.nsSeparator, unprocessedPartStart) == -1 &&
!next.isEmpty() &&
next.indexOf(settings.nsSeparator, unprocessedPartStart) == -1 &&
nextKey.indexOf(settings.nsSeparator, unprocessedPartStart) == -1 &&
!preRenderedKeysSet.contains(next));
};

Expand Down Expand Up @@ -130,7 +144,7 @@ void KeysTreeRenderer::renderKeys(QSharedPointer<Operations> operations,
parent->showLoadingError("Not enough memory to render all keys");
break;
}
}
}

if (preRenderedKeysToBeRemoved.size() > 0) {
QList<QWeakPointer<KeyItem>> obsoleteKeys;
Expand Down Expand Up @@ -161,10 +175,17 @@ void KeysTreeRenderer::renderLazily(QSharedPointer<AbstractNamespaceItem> root,
QWeakPointer<TreeItem> currentParent =
parent.staticCast<TreeItem>().toWeakRef();

int indexOfNaspaceSeparator =
(settings.nsSeparator.isEmpty())
? -1
: notProcessedKeyPart.indexOf(settings.nsSeparator);
int indexOfNaspaceSeparator = -1;
auto nsSeparator = settings.nsSeparator;
int nsSeparatorLength = nsSeparator.pattern().size();

if (!nsSeparator.isEmpty() && nsSeparator.patternSyntax() == QRegExp::RegExp) {
QString keyPart = QString::fromUtf8(notProcessedKeyPart);
indexOfNaspaceSeparator = keyPart.indexOf(nsSeparator);

qDebug() << "NSs regex pos:" << indexOfNaspaceSeparator << nsSeparator.cap();
nsSeparatorLength = nsSeparator.matchedLength();
}

if (indexOfNaspaceSeparator == -1) {
if (parent->getAllChilds().size() >= settings.renderLimit) {
Expand Down Expand Up @@ -199,7 +220,8 @@ void KeysTreeRenderer::renderLazily(QSharedPointer<AbstractNamespaceItem> root,
QByteArray namespaceFullPath = fullKey.mid(0, nsPos);

// Single namespaced key
if (nextKey.isEmpty() || nextKey.indexOf(namespaceFullPath) == -1) {
if (nsSeparator.patternSyntax() != QRegExp::RegExp
&& (nextKey.isEmpty() || nextKey.indexOf(namespaceFullPath) == -1)) {
QSharedPointer<KeyItem> newKey(new KeyItem(fullKey, currentParent,
parent->model(),
settings.shortKeysRendering));
Expand All @@ -209,7 +231,7 @@ void KeysTreeRenderer::renderLazily(QSharedPointer<AbstractNamespaceItem> root,

namespaceItem = QSharedPointer<NamespaceItem>(
new NamespaceItem(namespaceFullPath, m_operations, currentParent,
parent->model(), settings.dbIndex, settings.filter));
parent->model(), settings.dbIndex, settings.filter, nsSeparator.cap()));

if (expandedNamespaces.contains(namespaceFullPath)) {
namespaceItem->setExpanded(true);
Expand All @@ -219,8 +241,7 @@ void KeysTreeRenderer::renderLazily(QSharedPointer<AbstractNamespaceItem> root,
}

renderLazily(root, namespaceItem,
notProcessedKeyPart.mid(indexOfNaspaceSeparator +
settings.nsSeparator.length()),
notProcessedKeyPart.mid(indexOfNaspaceSeparator + nsSeparatorLength),
fullKey, m_operations, settings, expandedNamespaces,
level + 1, nextKey);
}
8 changes: 4 additions & 4 deletions src/modules/connections-tree/keysrendering.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ namespace ConnectionsTree {
public:
struct RenderingSettigns {
QRegExp filter;
QString nsSeparator;
uint dbIndex;
uint renderLimit;
QRegExp nsSeparator;
uint dbIndex;
uint renderLimit;
bool appendNewItems;
bool checkPreRenderedItems;
bool shortKeysRendering;
Expand All @@ -31,7 +31,7 @@ namespace ConnectionsTree {
RedisClient::Connection::RawKeysList keys,
QSharedPointer<AbstractNamespaceItem> parent,
RenderingSettigns settings,
const QSet<QByteArray> &expandedNamespaces);
const QSet<QByteArray> &expandedNamespaces);

private:
static void renderLazily(QSharedPointer<AbstractNamespaceItem> root,
Expand Down
2 changes: 1 addition & 1 deletion src/modules/connections-tree/operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class Operations {
* @brief getNamespaceSeparator
* @return
*/
virtual QString getNamespaceSeparator() = 0;
virtual QRegExp getNamespaceSeparator() = 0;

virtual QString defaultFilter() = 0;

Expand Down
26 changes: 18 additions & 8 deletions src/qml/ConnectionSettignsDialog.qml
Original file line number Diff line number Diff line change
Expand Up @@ -761,14 +761,24 @@ Dialog {

BetterLabel { text: qsTranslate("RDM","Namespace Separator:") }

BetterTextField
{
id: namespaceSeparator
Layout.fillWidth: true
objectName: "rdm_advanced_settings_namespace_separator_field"
placeholderText: qsTranslate("RDM","Separator used for namespace extraction from keys")
text: root.settings ? root.settings.namespaceSeparator : ""
onTextChanged: if (root.settings) { root.settings.namespaceSeparator = text }
RowLayout {
BetterTextField
{
id: namespaceSeparator
Layout.fillWidth: true
objectName: "rdm_advanced_settings_namespace_separator_field"
placeholderText: qsTranslate("RDM","Separator used for namespace extraction from keys")
text: root.settings ? root.settings.namespaceSeparator : ""
onTextChanged: if (root.settings) { root.settings.namespaceSeparator = text }
}

BetterCheckbox {
id: nsRegex
Layout.fillWidth: true
checked: root.settings ? root.settings.namespaceSeparatorIsRegex : false
onCheckedChanged: if (root.settings) { root.settings.namespaceSeparatorIsRegex = checked }
text: qsTranslate("RDM","Regex")
}
}

SettingsGroupTitle {
Expand Down