diff options
Diffstat (limited to 'Plugins/JsonExport')
| -rw-r--r-- | Plugins/JsonExport/JsonExport.pro | 28 | ||||
| -rw-r--r-- | Plugins/JsonExport/jsonexport.cpp | 453 | ||||
| -rw-r--r-- | Plugins/JsonExport/jsonexport.h | 78 | ||||
| -rw-r--r-- | Plugins/JsonExport/jsonexport.json | 7 | ||||
| -rw-r--r-- | Plugins/JsonExport/jsonexport.qrc | 5 | ||||
| -rw-r--r-- | Plugins/JsonExport/jsonexport.ui | 66 | ||||
| -rw-r--r-- | Plugins/JsonExport/jsonexport_global.h | 12 |
7 files changed, 649 insertions, 0 deletions
diff --git a/Plugins/JsonExport/JsonExport.pro b/Plugins/JsonExport/JsonExport.pro new file mode 100644 index 0000000..8e29fcf --- /dev/null +++ b/Plugins/JsonExport/JsonExport.pro @@ -0,0 +1,28 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2014-07-16T20:04:29 +# +#------------------------------------------------- + +include($$PWD/../../SQLiteStudio3/plugins.pri) + +QT -= gui + +TARGET = JsonExport +TEMPLATE = lib + +DEFINES += JSONEXPORT_LIBRARY + +SOURCES += jsonexport.cpp + +HEADERS += jsonexport.h\ + jsonexport_global.h + +OTHER_FILES += \ + jsonexport.json + +FORMS += \ + jsonexport.ui + +RESOURCES += \ + jsonexport.qrc diff --git a/Plugins/JsonExport/jsonexport.cpp b/Plugins/JsonExport/jsonexport.cpp new file mode 100644 index 0000000..51fd60a --- /dev/null +++ b/Plugins/JsonExport/jsonexport.cpp @@ -0,0 +1,453 @@ +#include "jsonexport.h" +#include "common/unused.h" +#include <QJsonDocument> + +JsonExport::JsonExport() +{ +} + +QString JsonExport::getFormatName() const +{ + return "JSON"; +} + +ExportManager::StandardConfigFlags JsonExport::standardOptionsToEnable() const +{ + return ExportManager::CODEC; +} + +QString JsonExport::getDefaultEncoding() const +{ + return "UTF-8"; +} + +QString JsonExport::getExportConfigFormName() const +{ + return "JsonExportConfig"; +} + +CfgMain* JsonExport::getConfig() +{ + return &cfg; +} + +void JsonExport::validateOptions() +{ +} + +QString JsonExport::defaultFileExtension() const +{ + return "json"; +} + +bool JsonExport::beforeExportQueryResults(const QString& query, QList<QueryExecutor::ResultColumnPtr>& columns, const QHash<ExportManager::ExportProviderFlag, QVariant> providedData) +{ + UNUSED(providedData); + + beginObject(); + writeValue("type", "query results"); + writeValue("query", query); + + beginArray("columns"); + QList<DataType> columnTypes = QueryExecutor::resolveColumnTypes(db, columns, true); + int i = 0; + for (QueryExecutor::ResultColumnPtr col : columns) + { + DataType& type = columnTypes[i]; + + beginObject(); + writeValue("displayName", col->displayName); + writeValue("name", col->column); + writeValue("database", col->database); + writeValue("table", col->table); + writeValue("type", type.toFullTypeString()); + endObject(); + } + endArray(); + + beginArray("rows"); + return true; +} + +bool JsonExport::exportQueryResultsRow(SqlResultsRowPtr row) +{ + beginArray(); + for (const QVariant& value : row->valueList()) + writeValue(value); + + endArray(); + return true; +} + +bool JsonExport::afterExportQueryResults() +{ + endArray(); + endObject(); + return true; +} + +bool JsonExport::exportTable(const QString& database, const QString& table, const QStringList& columnNames, const QString& ddl, SqliteCreateTablePtr createTable, const QHash<ExportManager::ExportProviderFlag, QVariant> providedData) +{ + UNUSED(providedData); + UNUSED(columnNames); + + beginObject(); + writeValue("type", "table"); + writeValue("database", database); + writeValue("name", table); + writeValue("withoutRowId", createTable->withOutRowId.isNull()); + writeValue("ddl", ddl); + + beginArray("columns"); + for (SqliteCreateTable::Column* col : createTable->columns) + { + beginObject(); + writeValue("name", col->name); + writeValue("type", col->type ? col->type->toDataType().toFullTypeString() : ""); + if (col->constraints.size() > 0) + { + beginArray("constraints"); + for (SqliteCreateTable::Column::Constraint* constr : col->constraints) + { + beginObject(); + writeValue("type", constr->typeString()); + writeValue("definition", constr->detokenize()); + endObject(); + } + endArray(); + } + endObject(); + } + endArray(); + + if (createTable->constraints.size() > 0) + { + beginArray("constraints"); + for (SqliteCreateTable::Constraint* constr : createTable->constraints) + { + beginObject(); + writeValue("type", constr->typeString()); + writeValue("definition", constr->detokenize()); + endObject(); + } + endArray(); + } + + beginArray("rows"); + return true; +} + +bool JsonExport::exportVirtualTable(const QString& database, const QString& table, const QStringList& columnNames, const QString& ddl, SqliteCreateVirtualTablePtr createTable, const QHash<ExportManager::ExportProviderFlag, QVariant> providedData) +{ + UNUSED(providedData); + + beginObject(); + writeValue("type", "table"); + writeValue("database", database); + writeValue("name", table); + writeValue("virtual", true); + writeValue("module", createTable->module); + writeValue("ddl", ddl); + + beginArray("columns"); + for (const QString& col : columnNames) + writeValue(col); + + endArray(); + + if (createTable->args.size() > 0) + { + beginArray("moduleArgs"); + for (const QString& arg : createTable->args) + writeValue(arg); + + endArray(); + } + + beginArray("rows"); + return true; +} + +bool JsonExport::exportTableRow(SqlResultsRowPtr data) +{ + return exportQueryResultsRow(data); +} + +bool JsonExport::afterExportTable() +{ + endArray(); + endObject(); + return true; +} + +bool JsonExport::beforeExportDatabase(const QString& database) +{ + beginObject(); + writeValue("type", "database"); + writeValue("name", database); + beginArray("objects"); + return true; +} + +bool JsonExport::exportIndex(const QString& database, const QString& name, const QString& ddl, SqliteCreateIndexPtr createIndex) +{ + beginObject(); + writeValue("type", "index"); + writeValue("database", database); + writeValue("name", name); + writeValue("unique", createIndex->uniqueKw); + + if (createIndex->where) + writeValue("partial", createIndex->where->detokenize()); + + writeValue("ddl", ddl); + endObject(); + return true; +} + +bool JsonExport::exportTrigger(const QString& database, const QString& name, const QString& ddl, SqliteCreateTriggerPtr createTrigger) +{ + beginObject(); + writeValue("type", "trigger"); + writeValue("database", database); + writeValue("name", name); + writeValue("ddl", ddl); + + QString timing = SqliteCreateTrigger::time(createTrigger->eventTime); + writeValue("timing", timing); + + QString event = createTrigger->event ? SqliteCreateTrigger::Event::typeToString(createTrigger->event->type) : ""; + writeValue("action", event); + + QString obj; + if (createTrigger->eventTime == SqliteCreateTrigger::Time::INSTEAD_OF) + obj = "view"; + else + obj = "table"; + + writeValue(obj, createTrigger->table); + + if (createTrigger->precondition) + writeValue("precondition", createTrigger->precondition->detokenize()); + + QStringList queryStrings; + for (SqliteQuery* q : createTrigger->queries) + queryStrings << q->detokenize(); + + writeValue("code", queryStrings.join("\n")); + endObject(); + return true; +} + +bool JsonExport::exportView(const QString& database, const QString& name, const QString& ddl, SqliteCreateViewPtr createView) +{ + beginObject(); + writeValue("type", "view"); + writeValue("database", database); + writeValue("name", name); + writeValue("ddl", ddl); + writeValue("select", createView->select->detokenize()); + endObject(); + return true; +} + +bool JsonExport::afterExportDatabase() +{ + endArray(); + endObject(); + return true; +} + +bool JsonExport::beforeExport() +{ + setupConfig(); + return true; +} + +bool JsonExport::init() +{ + Q_INIT_RESOURCE(jsonexport); + return GenericExportPlugin::init(); +} + +void JsonExport::deinit() +{ + Q_CLEANUP_RESOURCE(jsonexport); +} + +void JsonExport::setupConfig() +{ + elementCounter.clear(); + elementCounter.push(0); + indent = (cfg.JsonExport.Format.get() == "format"); + indentDepth = 0; + updateIndent(); +} + +void JsonExport::incrIndent() +{ + elementCounter.push(0); + if (!indent) + return; + + indentDepth++; + updateIndent(); +} + +void JsonExport::decrIndent() +{ + elementCounter.pop(); + if (!indent) + return; + + indentDepth--; + updateIndent(); +} + +void JsonExport::updateIndent() +{ + static const QString singleIndent = QStringLiteral(" "); + indentStr = singleIndent.repeated(indentDepth); +} + +void JsonExport::incrElementCount() +{ + elementCounter.top()++; +} + +void JsonExport::write(const QString& str) +{ + GenericExportPlugin::write(indentStr + str); +} + +QString JsonExport::escapeString(const QString& str) +{ + QString copy = str; + return "\"" + + copy.replace("\"", "\\\"") + .replace("\\", "\\\\") + .replace("/", "\\/") + .replace("\b", "\\b") + .replace("\f", "\\f") + .replace("\n", "\\n") + .replace("\r", "\\r") + .replace("\t", "\\t") + + "\""; +} + +QString JsonExport::formatValue(const QVariant& val) +{ + if (val.isNull()) + return "null"; + + switch (val.type()) + { + case QVariant::Int: + case QVariant::UInt: + case QVariant::LongLong: + case QVariant::ULongLong: + case QVariant::Double: + case QVariant::Bool: + return val.toString(); + default: + break; + } + + return escapeString(val.toString()); +} + +void JsonExport::beginObject() +{ + static const QString formatted = QStringLiteral("{\n"); + static const QString compact = QStringLiteral("{"); + + writePrefixBeforeNextElement(); + write(indent ? formatted : compact); + incrIndent(); +} + +void JsonExport::beginObject(const QString& key) +{ + static const QString formatted = QStringLiteral("%1: {\n"); + static const QString compact = QStringLiteral("%1:{"); + + QString escaped = escapeString(key); + + writePrefixBeforeNextElement(); + write(indent ? formatted.arg(escaped) : compact.arg(escaped)); + incrIndent(); +} + +void JsonExport::endObject() +{ + writePrefixBeforeEnd(); + decrIndent(); + write("}"); + incrElementCount(); +} + +void JsonExport::beginArray() +{ + static const QString formatted = QStringLiteral("[\n"); + static const QString compact = QStringLiteral("["); + + writePrefixBeforeNextElement(); + write(indent ? formatted : compact); + incrIndent(); +} + +void JsonExport::beginArray(const QString& key) +{ + static const QString formatted = QStringLiteral("%1: [\n"); + static const QString compact = QStringLiteral("%1:["); + + QString escaped = escapeString(key); + + writePrefixBeforeNextElement(); + write(indent ? formatted.arg(escaped) : compact.arg(escaped)); + incrIndent(); +} + +void JsonExport::endArray() +{ + writePrefixBeforeEnd(); + decrIndent(); + write("]"); + incrElementCount(); +} + +void JsonExport::writeValue(const QVariant& value) +{ + writePrefixBeforeNextElement(); + write(formatValue(value)); + incrElementCount(); +} + +void JsonExport::writeValue(const QString& key, const QVariant& value) +{ + static const QString formatted = QStringLiteral("%1: %2"); + static const QString compact = QStringLiteral("%1:%2"); + + QString escaped = escapeString(key); + QString val = formatValue(value); + + writePrefixBeforeNextElement(); + write(indent ? formatted.arg(escaped, val) : compact.arg(escaped, val)); + incrElementCount(); +} + +void JsonExport::writePrefixBeforeEnd() +{ + if (indent && elementCounter.top() > 0) + GenericExportPlugin::write("\n"); +} + +void JsonExport::writePrefixBeforeNextElement() +{ + if (elementCounter.top() > 0) + { + GenericExportPlugin::write(","); + if (indent) + GenericExportPlugin::write("\n"); + } +} diff --git a/Plugins/JsonExport/jsonexport.h b/Plugins/JsonExport/jsonexport.h new file mode 100644 index 0000000..150592d --- /dev/null +++ b/Plugins/JsonExport/jsonexport.h @@ -0,0 +1,78 @@ +#ifndef JSONEXPORT_H +#define JSONEXPORT_H + +#include "jsonexport_global.h" +#include "plugins/genericexportplugin.h" +#include "config_builder.h" +#include <QStack> + +CFG_CATEGORIES(JsonExportConfig, + CFG_CATEGORY(JsonExport, + CFG_ENTRY(QString, Format, "format") + ) +) + +class JSONEXPORTSHARED_EXPORT JsonExport : public GenericExportPlugin +{ + Q_OBJECT + SQLITESTUDIO_PLUGIN("jsonexport.json") + + public: + JsonExport(); + + QString getFormatName() const; + ExportManager::StandardConfigFlags standardOptionsToEnable() const; + QString getExportConfigFormName() const; + CfgMain* getConfig(); + void validateOptions(); + QString defaultFileExtension() const; + QString getDefaultEncoding() const; + bool beforeExportQueryResults(const QString& query, QList<QueryExecutor::ResultColumnPtr>& columns, + const QHash<ExportManager::ExportProviderFlag,QVariant> providedData); + bool exportQueryResultsRow(SqlResultsRowPtr row); + bool afterExportQueryResults(); + bool exportTable(const QString& database, const QString& table, const QStringList& columnNames, const QString& ddl, SqliteCreateTablePtr createTable, + const QHash<ExportManager::ExportProviderFlag,QVariant> providedData); + bool exportVirtualTable(const QString& database, const QString& table, const QStringList& columnNames, const QString& ddl, SqliteCreateVirtualTablePtr createTable, + const QHash<ExportManager::ExportProviderFlag,QVariant> providedData); + bool exportTableRow(SqlResultsRowPtr data); + bool afterExportTable(); + bool beforeExportDatabase(const QString& database); + bool exportIndex(const QString& database, const QString& name, const QString& ddl, SqliteCreateIndexPtr createIndex); + bool exportTrigger(const QString& database, const QString& name, const QString& ddl, SqliteCreateTriggerPtr createTrigger); + bool exportView(const QString& database, const QString& name, const QString& ddl, SqliteCreateViewPtr createView); + bool afterExportDatabase(); + bool beforeExport(); + bool init(); + void deinit(); + + private: + void setupConfig(); + void incrIndent(); + void decrIndent(); + void updateIndent(); + void incrElementCount(); + void write(const QString& str); + QString escapeString(const QString& str); + QString formatValue(const QVariant& val); + void beginObject(); + void beginObject(const QString& key); + void endObject(); + void beginArray(); + void beginArray(const QString& key); + void endArray(); + void writeValue(const QVariant& value); + void writeValue(const QString& key, const QVariant& value); + void writePrefixBeforeEnd(); + void writePrefixBeforeNextElement(); + + CFG_LOCAL(JsonExportConfig, cfg) + QStack<int> elementCounter; + bool indent = false; + int indentDepth = 0; + QString indentStr; + QString newLineStr; + QString codecName; +}; + +#endif // JSONEXPORT_H diff --git a/Plugins/JsonExport/jsonexport.json b/Plugins/JsonExport/jsonexport.json new file mode 100644 index 0000000..c56270c --- /dev/null +++ b/Plugins/JsonExport/jsonexport.json @@ -0,0 +1,7 @@ +{ + "type": "ExportPlugin", + "title": "JSON export", + "description": "Provides JSON format for exporting.", + "version": 10000, + "author": "SalSoft" +} diff --git a/Plugins/JsonExport/jsonexport.qrc b/Plugins/JsonExport/jsonexport.qrc new file mode 100644 index 0000000..19ea921 --- /dev/null +++ b/Plugins/JsonExport/jsonexport.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/forms"> + <file>jsonexport.ui</file> + </qresource> +</RCC> diff --git a/Plugins/JsonExport/jsonexport.ui b/Plugins/JsonExport/jsonexport.ui new file mode 100644 index 0000000..ebb0d78 --- /dev/null +++ b/Plugins/JsonExport/jsonexport.ui @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>JsonExportConfig</class> + <widget class="QWidget" name="JsonExportConfig"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>345</width> + <height>100</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="formatGroup"> + <property name="title"> + <string>Output format</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="0" colspan="2"> + <widget class="ConfigRadioButton" name="formatRadio"> + <property name="text"> + <string>Format document (new lines, indentation)</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="assignedValue" stdset="0"> + <string>format</string> + </property> + <property name="cfg" stdset="0"> + <string>JsonExport.Format</string> + </property> + </widget> + </item> + <item row="3" column="0" colspan="2"> + <widget class="ConfigRadioButton" name="compressRadio"> + <property name="text"> + <string>Compress (everything in one line)</string> + </property> + <property name="assignedValue" stdset="0"> + <string>compress</string> + </property> + <property name="cfg" stdset="0"> + <string>JsonExport.Format</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>ConfigRadioButton</class> + <extends>QRadioButton</extends> + <header>common/configradiobutton.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/Plugins/JsonExport/jsonexport_global.h b/Plugins/JsonExport/jsonexport_global.h new file mode 100644 index 0000000..ce86078 --- /dev/null +++ b/Plugins/JsonExport/jsonexport_global.h @@ -0,0 +1,12 @@ +#ifndef JSONEXPORT_GLOBAL_H +#define JSONEXPORT_GLOBAL_H + +#include <QtCore/qglobal.h> + +#if defined(JSONEXPORT_LIBRARY) +# define JSONEXPORTSHARED_EXPORT Q_DECL_EXPORT +#else +# define JSONEXPORTSHARED_EXPORT Q_DECL_IMPORT +#endif + +#endif // JSONEXPORT_GLOBAL_H |
