File indexing completed on 2024-06-23 05:20:32
0001 /* 0002 * Copyright (C) 2014 Aaron Seigo <aseigo@kde.org> 0003 * 0004 * This program is free software; you can redistribute it and/or modify 0005 * it under the terms of the GNU General Public License as published by 0006 * the Free Software Foundation; either version 2 of the License, or 0007 * (at your option) any later version. 0008 * 0009 * This program is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0012 * GNU General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU General Public License 0015 * along with this program; if not, write to the 0016 * Free Software Foundation, Inc., 0017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 0018 */ 0019 0020 #include <QCoreApplication> 0021 #include <QDebug> 0022 #include <QObject> // tr() 0023 #include <QModelIndex> 0024 #include <QTime> 0025 0026 #include "common/resource.h" 0027 #include "common/storage.h" 0028 #include "common/resourceconfig.h" 0029 #include "common/log.h" 0030 #include "common/definitions.h" 0031 #include "common/store.h" 0032 #include "common/propertyparser.h" 0033 0034 #include "sinksh_utils.h" 0035 #include "state.h" 0036 #include "syntaxtree.h" 0037 0038 namespace SinkLiveQuery 0039 { 0040 0041 Syntax::List syntax(); 0042 0043 bool livequery(const QStringList &args_, State &state) 0044 { 0045 if (args_.isEmpty()) { 0046 state.printError(syntax()[0].usage()); 0047 return false; 0048 } 0049 0050 auto options = SyntaxTree::parseOptions(args_); 0051 0052 auto type = options.positionalArguments.isEmpty() ? QString{} : options.positionalArguments.first(); 0053 0054 Sink::Query query; 0055 query.setId("livequery"); 0056 query.setFlags(Sink::Query::LiveQuery); 0057 if (!SinkshUtils::applyFilter(query, options)) { 0058 state.printError(syntax()[0].usage()); 0059 return false; 0060 } 0061 if (options.options.contains("resource")) { 0062 for (const auto &f : options.options.value("resource")) { 0063 query.resourceFilter(f.toLatin1()); 0064 } 0065 } 0066 if (options.options.contains("filter")) { 0067 for (const auto &f : options.options.value("filter")) { 0068 auto filter = f.split("="); 0069 const auto property = filter.value(0).toLatin1(); 0070 query.filter(property, Sink::PropertyParser::parse(type.toLatin1(), property, filter.value(1))); 0071 } 0072 } 0073 if (options.options.contains("id")) { 0074 for (const auto &f : options.options.value("id")) { 0075 query.filter(f.toUtf8()); 0076 } 0077 } 0078 // auto compact = options.options.contains("compact"); 0079 if (!options.options.contains("showall")) { 0080 if (options.options.contains("show")) { 0081 auto list = options.options.value("show"); 0082 std::transform(list.constBegin(), list.constEnd(), std::back_inserter(query.requestedProperties), [] (const QString &s) { return s.toLatin1(); }); 0083 } else { 0084 query.requestedProperties = SinkshUtils::requestedProperties(type); 0085 } 0086 } 0087 0088 QByteArrayList toPrint; 0089 QStringList tableLine; 0090 0091 auto model = SinkshUtils::loadModel(query.type(), query); 0092 QObject::connect(model.data(), &QAbstractItemModel::dataChanged, [model, state](const QModelIndex &, const QModelIndex &, const QVector<int> &roles) { 0093 if (roles.contains(Sink::Store::ChildrenFetchedRole)) { 0094 state.printLine(QObject::tr("Counted results %1").arg(model->rowCount(QModelIndex()))); 0095 } 0096 }); 0097 QObject::connect(model.data(), &QAbstractItemModel::rowsInserted, [model, state](const QModelIndex &index, int start, int end) { 0098 for (int i = start; i <= end; i++) { 0099 auto object = model->data(model->index(i, 0, index), Sink::Store::DomainObjectBaseRole).value<Sink::ApplicationDomain::ApplicationDomainType::Ptr>(); 0100 state.printLine("Resource: " + object->resourceInstanceIdentifier(), 1); 0101 state.printLine("Identifier: " + object->identifier(), 1); 0102 state.stageTableLine(QStringList() 0103 << QObject::tr("Property:") 0104 << QObject::tr("Value:")); 0105 0106 for (const auto &property : object->availableProperties()) { 0107 state.stageTableLine(QStringList() 0108 << property 0109 << object->getProperty(property).toString()); 0110 } 0111 state.flushTable(); 0112 } 0113 }); 0114 0115 if (!model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()) { 0116 return true; 0117 } 0118 0119 return false; 0120 } 0121 0122 Syntax::List syntax() 0123 { 0124 Syntax list("livequery", QObject::tr("Run a livequery."), &SinkLiveQuery::livequery, Syntax::EventDriven); 0125 0126 list.addPositionalArgument({"type", "The type to run the livequery on" }); 0127 list.addParameter("resource", {"resource", "Filter the livequery to the given resource" }); 0128 list.addFlag("compact", "Use a compact view (reduces the size of IDs)"); 0129 list.addParameter("filter", {"property=$value", "Filter the results" }); 0130 list.addParameter("id", {"id", "List only the content with the given ID" }); 0131 list.addFlag("showall", "Show all properties"); 0132 list.addParameter("show", {"property", "Only show the given property" }); 0133 0134 list.completer = &SinkshUtils::resourceOrTypeCompleter; 0135 return Syntax::List() << list; 0136 } 0137 0138 REGISTER_SYNTAX(SinkLiveQuery) 0139 0140 }