diff options
Diffstat (limited to 'sinksh')
-rw-r--r-- | sinksh/CMakeLists.txt | 1 | ||||
-rw-r--r-- | sinksh/syntax_modules/sink_inspect.cpp | 112 | ||||
-rw-r--r-- | sinksh/syntax_modules/sink_list.cpp | 7 |
3 files changed, 119 insertions, 1 deletions
diff --git a/sinksh/CMakeLists.txt b/sinksh/CMakeLists.txt index f0e2f6c..9a4c948 100644 --- a/sinksh/CMakeLists.txt +++ b/sinksh/CMakeLists.txt | |||
@@ -16,6 +16,7 @@ set(sink_cli_SRCS | |||
16 | syntax_modules/sink_sync.cpp | 16 | syntax_modules/sink_sync.cpp |
17 | syntax_modules/sink_show.cpp | 17 | syntax_modules/sink_show.cpp |
18 | syntax_modules/sink_trace.cpp | 18 | syntax_modules/sink_trace.cpp |
19 | syntax_modules/sink_inspect.cpp | ||
19 | sinksh_utils.cpp | 20 | sinksh_utils.cpp |
20 | repl/repl.cpp | 21 | repl/repl.cpp |
21 | repl/replStates.cpp | 22 | repl/replStates.cpp |
diff --git a/sinksh/syntax_modules/sink_inspect.cpp b/sinksh/syntax_modules/sink_inspect.cpp new file mode 100644 index 0000000..175bb9d --- /dev/null +++ b/sinksh/syntax_modules/sink_inspect.cpp | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Christian Mollekopf <mollekopf@kolabsys.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the | ||
16 | * Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | */ | ||
19 | |||
20 | #include <QDebug> | ||
21 | #include <QObject> // tr() | ||
22 | #include <QTimer> | ||
23 | #include <QDir> | ||
24 | |||
25 | #include "common/resource.h" | ||
26 | #include "common/storage.h" | ||
27 | #include "common/domain/event.h" | ||
28 | #include "common/domain/folder.h" | ||
29 | #include "common/resourceconfig.h" | ||
30 | #include "common/log.h" | ||
31 | #include "common/storage.h" | ||
32 | #include "common/definitions.h" | ||
33 | #include "common/entitybuffer.h" | ||
34 | #include "common/metadata_generated.h" | ||
35 | |||
36 | #include "sinksh_utils.h" | ||
37 | #include "state.h" | ||
38 | #include "syntaxtree.h" | ||
39 | |||
40 | namespace SinkInspect | ||
41 | { | ||
42 | |||
43 | bool inspect(const QStringList &args, State &state) | ||
44 | { | ||
45 | if (args.isEmpty()) { | ||
46 | state.printError(QObject::tr("Options: $type [--resource $resource] [--db $db] [--filter $id]")); | ||
47 | } | ||
48 | auto options = SyntaxTree::parseOptions(args); | ||
49 | auto resource = options.options.value("resource").value(0); | ||
50 | |||
51 | Sink::Storage::DataStore storage(Sink::storageLocation(), resource, Sink::Storage::DataStore::ReadOnly); | ||
52 | auto transaction = storage.createTransaction(Sink::Storage::DataStore::ReadOnly); | ||
53 | |||
54 | auto dbs = options.options.value("db"); | ||
55 | auto idFilter = options.options.value("filter"); | ||
56 | |||
57 | auto databases = transaction.getDatabaseNames(); | ||
58 | if (dbs.isEmpty()) { | ||
59 | state.printLine(QString("Available databases: ") + databases.join(", ")); | ||
60 | return false; | ||
61 | } | ||
62 | auto dbName = dbs.value(0).toUtf8(); | ||
63 | auto isMainDb = dbName.contains(".main"); | ||
64 | if (!databases.contains(dbName)) { | ||
65 | state.printError(QString("Database not available: ") + dbName); | ||
66 | } | ||
67 | |||
68 | state.printLine(QString("Opening: ") + dbName); | ||
69 | auto db = transaction.openDatabase(dbName, | ||
70 | [&] (const Sink::Storage::DataStore::Error &e) { | ||
71 | Q_ASSERT(false); | ||
72 | state.printError(e.message); | ||
73 | }, false); | ||
74 | QByteArray filter; | ||
75 | if (!idFilter.isEmpty()) { | ||
76 | filter = idFilter.first().toUtf8(); | ||
77 | } | ||
78 | bool findSubstringKeys = !filter.isEmpty(); | ||
79 | auto count = db.scan(filter, [&] (const QByteArray &key, const QByteArray &data) { | ||
80 | if (isMainDb) { | ||
81 | Sink::EntityBuffer buffer(const_cast<const char *>(data.data()), data.size()); | ||
82 | if (!buffer.isValid()) { | ||
83 | state.printError("Read invalid buffer from disk: " + key); | ||
84 | } else { | ||
85 | const auto metadata = flatbuffers::GetRoot<Sink::Metadata>(buffer.metadataBuffer()); | ||
86 | state.printLine("Key: " + key + " Operation: " + QString::number(metadata->operation())); | ||
87 | } | ||
88 | } else { | ||
89 | state.printLine("Key: " + key); | ||
90 | } | ||
91 | return true; | ||
92 | }, | ||
93 | [&](const Sink::Storage::DataStore::Error &e) { | ||
94 | state.printError(e.message); | ||
95 | }, | ||
96 | findSubstringKeys); | ||
97 | |||
98 | state.printLine("Found " + QString::number(count) + " entries"); | ||
99 | return false; | ||
100 | } | ||
101 | |||
102 | Syntax::List syntax() | ||
103 | { | ||
104 | Syntax state("inspect", QObject::tr("Inspect database for the resource requested"), &SinkInspect::inspect, Syntax::NotInteractive); | ||
105 | state.completer = &SinkshUtils::resourceCompleter; | ||
106 | |||
107 | return Syntax::List() << state; | ||
108 | } | ||
109 | |||
110 | REGISTER_SYNTAX(SinkInspect) | ||
111 | |||
112 | } | ||
diff --git a/sinksh/syntax_modules/sink_list.cpp b/sinksh/syntax_modules/sink_list.cpp index feb582e..f6cae6b 100644 --- a/sinksh/syntax_modules/sink_list.cpp +++ b/sinksh/syntax_modules/sink_list.cpp | |||
@@ -64,7 +64,7 @@ QByteArray baIfAvailable(const QStringList &list) | |||
64 | bool list(const QStringList &args_, State &state) | 64 | bool list(const QStringList &args_, State &state) |
65 | { | 65 | { |
66 | if (args_.isEmpty()) { | 66 | if (args_.isEmpty()) { |
67 | state.printError(QObject::tr("Options: $type [--resource $resource] [--compact] [--filter $property=$value] [--showall|--show $property]")); | 67 | state.printError(QObject::tr("Options: $type [--resource $resource] [--compact] [--filter $property=$value] [--id $id] [--showall|--show $property]")); |
68 | return false; | 68 | return false; |
69 | } | 69 | } |
70 | 70 | ||
@@ -84,6 +84,11 @@ bool list(const QStringList &args_, State &state) | |||
84 | query.filter(filter.at(0).toLatin1(), QVariant::fromValue(Sink::ApplicationDomain::Reference{filter.at(1).toLatin1()})); | 84 | query.filter(filter.at(0).toLatin1(), QVariant::fromValue(Sink::ApplicationDomain::Reference{filter.at(1).toLatin1()})); |
85 | } | 85 | } |
86 | } | 86 | } |
87 | if (options.options.contains("id")) { | ||
88 | for (const auto &f : options.options.value("id")) { | ||
89 | query.filter(f.toUtf8()); | ||
90 | } | ||
91 | } | ||
87 | auto compact = options.options.contains("compact"); | 92 | auto compact = options.options.contains("compact"); |
88 | if (!options.options.contains("showall")) { | 93 | if (!options.options.contains("showall")) { |
89 | if (options.options.contains("show")) { | 94 | if (options.options.contains("show")) { |