diff --git a/common/storage/key.h b/common/storage/key.h --- a/common/storage/key.h +++ b/common/storage/key.h @@ -48,6 +48,10 @@ bool isNull() const; + static bool isValidInternal(const QByteArray &); + static bool isValidDisplay(const QByteArray &); + static bool isValid(const QByteArray &); + bool operator==(const Identifier &other) const; bool operator!=(const Identifier &other) const; @@ -72,6 +76,10 @@ static Revision fromDisplayByteArray(const QByteArray &bytes); qint64 toQint64() const; + static bool isValidInternal(const QByteArray &); + static bool isValidDisplay(const QByteArray &); + static bool isValid(const QByteArray &); + bool operator==(const Revision &other) const; bool operator!=(const Revision &other) const; @@ -99,6 +107,10 @@ bool isNull() const; + static bool isValidInternal(const QByteArray &); + static bool isValidDisplay(const QByteArray &); + static bool isValid(const QByteArray &); + bool operator==(const Key &other) const; bool operator!=(const Key &other) const; @@ -110,6 +122,6 @@ } // namespace Storage } // namespace Sink -SINK_EXPORT QDebug& operator<<(QDebug &dbg, const Sink::Storage::Identifier &); -SINK_EXPORT QDebug& operator<<(QDebug &dbg, const Sink::Storage::Revision &); -SINK_EXPORT QDebug& operator<<(QDebug &dbg, const Sink::Storage::Key &); +SINK_EXPORT QDebug &operator<<(QDebug &dbg, const Sink::Storage::Identifier &); +SINK_EXPORT QDebug &operator<<(QDebug &dbg, const Sink::Storage::Revision &); +SINK_EXPORT QDebug &operator<<(QDebug &dbg, const Sink::Storage::Key &); diff --git a/common/storage/key.cpp b/common/storage/key.cpp --- a/common/storage/key.cpp +++ b/common/storage/key.cpp @@ -84,6 +84,27 @@ return uid.isNull(); } +bool Identifier::isValidInternal(const QByteArray &bytes) +{ + return !QUuid::fromRfc4122(bytes).isNull(); +} + +bool Identifier::isValidDisplay(const QByteArray &bytes) +{ + return !QUuid(bytes).isNull(); +} + +bool Identifier::isValid(const QByteArray &bytes) +{ + switch (bytes.size()) { + case Identifier::INTERNAL_REPR_SIZE: + return isValidInternal(bytes); + case Identifier::DISPLAY_REPR_SIZE: + return isValidDisplay(bytes); + } + return false; +} + bool Identifier::operator==(const Identifier &other) const { return uid == other.uid; @@ -128,6 +149,27 @@ return rev; } +bool Revision::isValidInternal(const QByteArray &bytes) +{ + if (bytes.size() != Revision::INTERNAL_REPR_SIZE) { + return false; + } + + bool ok; + bytes.toLongLong(&ok); + return ok; +} + +bool Revision::isValidDisplay(const QByteArray &bytes) +{ + isValidInternal(bytes); +} + +bool Revision::isValid(const QByteArray &bytes) +{ + isValidInternal(bytes); +} + bool Revision::operator==(const Revision &other) const { return rev == other.rev; @@ -191,6 +233,39 @@ return id.isNull(); } +bool Key::isValidInternal(const QByteArray &bytes) +{ + if (bytes.size() != Key::INTERNAL_REPR_SIZE) { + return false; + } + + auto idBytes = bytes.mid(0, Identifier::INTERNAL_REPR_SIZE); + auto revBytes = bytes.mid(Identifier::INTERNAL_REPR_SIZE); + return Identifier::isValidInternal(idBytes) && Revision::isValidInternal(revBytes); +} + +bool Key::isValidDisplay(const QByteArray &bytes) +{ + if (bytes.size() != Key::DISPLAY_REPR_SIZE) { + return false; + } + + auto idBytes = bytes.mid(0, Identifier::DISPLAY_REPR_SIZE); + auto revBytes = bytes.mid(Identifier::DISPLAY_REPR_SIZE); + return Key::isValidDisplay(idBytes) && Revision::isValidDisplay(revBytes); +} + +bool Key::isValid(const QByteArray &bytes) +{ + switch (bytes.size()) { + case Key::INTERNAL_REPR_SIZE: + return isValidInternal(bytes); + case Key::DISPLAY_REPR_SIZE: + return isValidDisplay(bytes); + } + return false; +} + bool Key::operator==(const Key &other) const { return (id == other.id) && (rev == other.rev); @@ -200,4 +275,3 @@ { return !(*this == other); } - diff --git a/sinksh/syntax_modules/sink_inspect.cpp b/sinksh/syntax_modules/sink_inspect.cpp --- a/sinksh/syntax_modules/sink_inspect.cpp +++ b/sinksh/syntax_modules/sink_inspect.cpp @@ -41,6 +41,20 @@ namespace SinkInspect { +using Sink::Storage::Key; +using Sink::Storage::Identifier; + +QString parse(const QByteArray &bytes) +{ + if (Key::isValidInternal(bytes)) { + return Key::fromInternalByteArray(bytes).toDisplayString(); + } else if (Identifier::isValidInternal(bytes)) { + return Identifier::fromInternalByteArray(bytes).toDisplayString(); + } else { + return QString::fromUtf8(bytes); + } +} + bool inspect(const QStringList &args, State &state) { if (args.isEmpty()) { @@ -90,7 +104,7 @@ QSet uids; db.scan("", [&] (const QByteArray &key, const QByteArray &data) { - uids.insert(Sink::Storage::Key::fromInternalByteArray(key).identifier().toDisplayByteArray()); + uids.insert(Key::fromInternalByteArray(key).identifier().toDisplayByteArray()); return true; }, [&](const Sink::Storage::DataStore::Error &e) { @@ -187,21 +201,24 @@ auto count = db.scan(filter, [&] (const QByteArray &key, const QByteArray &data) { keySizeTotal += key.size(); valueSizeTotal += data.size(); + + const auto parsedKey = parse(key); + if (isMainDb) { Sink::EntityBuffer buffer(const_cast(data.data()), data.size()); if (!buffer.isValid()) { - state.printError("Read invalid buffer from disk: " + key); + state.printError("Read invalid buffer from disk: " + parsedKey); } else { const auto metadata = flatbuffers::GetRoot(buffer.metadataBuffer()); - state.printLine("Key: " + key + state.printLine("Key: " + parsedKey + " Operation: " + QString::number(metadata->operation()) + " Replay: " + (metadata->replayToSource() ? "true" : "false") + ((metadata->modifiedProperties() && metadata->modifiedProperties()->size() != 0) ? (" [" + Sink::BufferUtils::fromVector(*metadata->modifiedProperties()).join(", ")) + "]": "") + " Value size: " + QString::number(data.size()) ); } } else { - state.printLine("Key: " + key + "\tValue: " + QString::fromUtf8(data)); + state.printLine("Key: " + parsedKey + "\tValue: " + parse(data)); } return true; },