#include "xmlexport.h" #include "services/exportmanager.h" #include "common/unused.h" #include const QString XmlExport::docBegin = QStringLiteral("\n"); XmlExport::XmlExport() { } QString XmlExport::getFormatName() const { return QStringLiteral("XML"); } ExportManager::StandardConfigFlags XmlExport::standardOptionsToEnable() const { return ExportManager::CODEC; } QString XmlExport::getExportConfigFormName() const { return QStringLiteral("XmlExportConfig"); } CfgMain* XmlExport::getConfig() { return &cfg; } void XmlExport::validateOptions() { bool useNs = cfg.XmlExport.UseNamespace.get(); EXPORT_MANAGER->updateVisibilityAndEnabled(cfg.XmlExport.Namespace, true, useNs); bool nsValid = !useNs || !cfg.XmlExport.Namespace.get().isEmpty(); EXPORT_MANAGER->handleValidationFromPlugin(nsValid, cfg.XmlExport.Namespace, tr("Enter the namespace to use (for example: http://my.namespace.org)")); } QString XmlExport::defaultFileExtension() const { return QStringLiteral("xml"); } bool XmlExport::beforeExportQueryResults(const QString& query, QList& columns, const QHash providedData) { UNUSED(providedData); setupConfig(); write(docBegin.arg(codecName)); writeln(QString("").arg(nsStr)); incrIndent(); writeln(""); incrIndent(); writeln(escape(query)); decrIndent(); writeln(""); QList columnTypes = QueryExecutor::resolveColumnTypes(db, columns, true); writeln(""); incrIndent(); int i = 0; DataType type; for (QueryExecutor::ResultColumnPtr col : columns) { type = columnTypes[i]; writeln(""); incrIndent(); writeln(""+ escape(col->displayName) + ""); writeln(""+ escape(col->column) + ""); writeln(""+ escape(col->table) + "
"); writeln(""+ escape(col->database) + ""); writeln(""+ escape(type.toFullTypeString()) + ""); decrIndent(); writeln("
"); i++; } decrIndent(); writeln("
"); writeln(""); incrIndent(); return true; } bool XmlExport::exportQueryResultsRow(SqlResultsRowPtr row) { static const QString rowTpl = QStringLiteral("%2"); static const QString nullTpl = QStringLiteral(""); writeln(""); incrIndent(); int i = 0; for (const QVariant& value : row->valueList()) { if (value.isNull()) writeln(nullTpl.arg(i)); else writeln(rowTpl.arg(i).arg(escape(value.toString()))); i++; } decrIndent(); writeln(""); return true; } bool XmlExport::afterExportQueryResults() { decrIndent(); write(""); decrIndent(); write(""); return true; } bool XmlExport::exportTable(const QString& database, const QString& table, const QStringList& columnNames, const QString& ddl, SqliteCreateTablePtr createTable, const QHash providedData) { UNUSED(columnNames); UNUSED(providedData); if (isTableExport()) { setupConfig(); write(docBegin.arg(codecName)); } writeln(QString("").arg(isTableExport() ? nsStr : "")); incrIndent(); writeln("" + escape(database) + ""); writeln("" + escape(table) + ""); if (!createTable->withOutRowId.isNull()) writeln(QString("true")); writeln("" + escape(ddl) + ""); writeln(""); incrIndent(); for (SqliteCreateTable::Column* col : createTable->columns) { writeln(""); incrIndent(); writeln(""+ col->name + ""); writeln(QString("%1").arg((col->type ? col->type->toDataType().toFullTypeString() : ""))); if (col->constraints.size() > 0) { writeln(""); incrIndent(); for (SqliteCreateTable::Column::Constraint* constr : col->constraints) { writeln(""); incrIndent(); writeln("" + constr->typeString() + ""); writeln("" + constr->detokenize() + ""); decrIndent(); writeln(""); } decrIndent(); writeln(""); } decrIndent(); writeln(""); } decrIndent(); writeln(""); if (createTable->constraints.size() > 0) { writeln(""); incrIndent(); for (SqliteCreateTable::Constraint* constr : createTable->constraints) { writeln(""); incrIndent(); writeln("" + constr->typeString() + ""); writeln("" + constr->detokenize() + ""); decrIndent(); writeln(""); } decrIndent(); writeln(""); } writeln(""); incrIndent(); return true; } bool XmlExport::exportVirtualTable(const QString& database, const QString& table, const QStringList& columnNames, const QString& ddl, SqliteCreateVirtualTablePtr createTable, const QHash providedData) { UNUSED(providedData); if (isTableExport()) { setupConfig(); write(docBegin.arg(codecName)); } writeln(QString("").arg(isTableExport() ? nsStr : "")); incrIndent(); writeln("" + escape(database) + ""); writeln("" + escape(table) + ""); writeln("true"); writeln("" + escape(createTable->module) + ""); writeln("" + escape(ddl) + ""); writeln(""); incrIndent(); for (const QString& col : columnNames) { writeln(""); incrIndent(); writeln(""+ col + ""); decrIndent(); writeln(""); } decrIndent(); writeln(""); if (createTable->args.size() > 0) { writeln(""); incrIndent(); for (const QString& arg : createTable->args) writeln("" + arg + ""); decrIndent(); writeln(""); } writeln(""); incrIndent(); return true; } bool XmlExport::exportTableRow(SqlResultsRowPtr data) { return exportQueryResultsRow(data); } bool XmlExport::afterExportTable() { decrIndent(); writeln(""); decrIndent(); writeln(""); return true; } bool XmlExport::beforeExportDatabase(const QString& database) { setupConfig(); write(docBegin.arg(codecName)); writeln(QString("").arg(nsStr)); incrIndent(); writeln("" + escape(database) + ""); return true; } bool XmlExport::exportIndex(const QString& database, const QString& name, const QString& ddl, SqliteCreateIndexPtr createIndex) { writeln(""); incrIndent(); writeln("" + escape(database) + ""); writeln("" + escape(name) + ""); if (createIndex->uniqueKw) writeln("true"); if (createIndex->where) writeln("" + createIndex->where->detokenize() + ""); writeln("" + escape(ddl) + ""); decrIndent(); writeln(""); return true; } bool XmlExport::exportTrigger(const QString& database, const QString& name, const QString& ddl, SqliteCreateTriggerPtr createTrigger) { UNUSED(createTrigger); writeln(""); incrIndent(); writeln("" + escape(database) + ""); writeln("" + escape(name) + ""); writeln("" + escape(ddl) + ""); QString timing = SqliteCreateTrigger::time(createTrigger->eventTime); writeln("" + escape(timing) + ""); QString event = createTrigger->event ? SqliteCreateTrigger::Event::typeToString(createTrigger->event->type) : ""; writeln("" + escape(event) + ""); QString tag; if (createTrigger->eventTime == SqliteCreateTrigger::Time::INSTEAD_OF) tag = ""; else tag = ""; writeln(tag + escape(createTrigger->table) + tag); if (createTrigger->precondition) writeln("" + escape(createTrigger->precondition->detokenize()) + ""); QStringList queryStrings; for (SqliteQuery* q : createTrigger->queries) queryStrings << q->detokenize(); writeln("" + escape(queryStrings.join("\n")) + ""); decrIndent(); writeln(""); return true; } bool XmlExport::exportView(const QString& database, const QString& name, const QString& ddl, SqliteCreateViewPtr createView) { UNUSED(createView); writeln(""); incrIndent(); writeln("" + escape(database) + ""); writeln("" + escape(name) + ""); writeln("" + escape(ddl) + ""); writeln(""); decrIndent(); writeln(""); return true; } bool XmlExport::afterExportDatabase() { decrIndent(); writeln(""); return true; } void XmlExport::setupConfig() { codecName = codec->name(); indentDepth = 0; newLineStr = ""; indentStr = ""; indent = (cfg.XmlExport.Format.get() == "format"); if (indent) newLineStr = "\n"; nsStr = QString(); if (cfg.XmlExport.UseNamespace.get()) nsStr = " xmlns=\"" + cfg.XmlExport.Namespace.get() + "\""; if (cfg.XmlExport.Escaping.get() == "ampersand") { useAmpersand = true; useCdata = false; } else if (cfg.XmlExport.Escaping.get() == "cdata") { useAmpersand = false; useCdata = true; } else { useAmpersand = true; useCdata = true; } } void XmlExport::incrIndent() { if (indent) { indentDepth++; updateIndent(); } } void XmlExport::decrIndent() { if (indent) { indentDepth--; updateIndent(); } } void XmlExport::updateIndent() { indentStr = QString(" ").repeated(indentDepth); } void XmlExport::writeln(const QString& str) { QString newStr; if (str.contains("\n")) { QStringList lines = str.split("\n"); QMutableStringListIterator it(lines); while (it.hasNext()) it.next().prepend(indentStr); newStr = lines.join("\n") + newLineStr; } else { newStr = indentStr + str + newLineStr; } GenericExportPlugin::write(newStr); } QString XmlExport::escape(const QString& str) { if (useAmpersand && useCdata) { if (str.length() >= minLenghtForCdata) return escapeCdata(str); else return escapeAmpersand(str); } else if (useAmpersand) { return escapeAmpersand(str); } else { return escapeCdata(str); } } QString XmlExport::escapeCdata(const QString& str) { if (str.contains('"') || str.contains('&') || str.contains('<') || str.contains('>')) return ""; return str; } QString XmlExport::escapeAmpersand(const QString& str) { return str.toHtmlEscaped(); } QString XmlExport::toString(bool value) { return value ? "true" : "false"; } bool XmlExport::init() { Q_INIT_RESOURCE(xmlexport); return GenericExportPlugin::init(); } void XmlExport::deinit() { Q_CLEANUP_RESOURCE(xmlexport); }