|
@@ -34,6 +34,9 @@
|
|
|
#include "fvrelate.ipp"
|
|
|
#include "dasess.hpp"
|
|
|
|
|
|
+#include "thorxmlwrite.hpp"
|
|
|
+#include "eclhelper.hpp"
|
|
|
+
|
|
|
#define DEFAULT_FETCH_SIZE 100
|
|
|
#define FILEVIEW_VERSION 1
|
|
|
#define MAX_SORT_ELEMENTS 1000
|
|
@@ -1673,6 +1676,7 @@ void CResultSetCursor::getXmlText(StringBuffer & out, int columnIndex, const cha
|
|
|
rtlFree(resultStr);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
void CResultSetCursor::getXmlAttrText(StringBuffer & out, int columnIndex, const char *tag)
|
|
|
{
|
|
|
if (!isValid())
|
|
@@ -1791,6 +1795,274 @@ void CResultSetCursor::getXmlAttrText(StringBuffer & out, int columnIndex, const
|
|
|
rtlFree(resultStr);
|
|
|
}
|
|
|
|
|
|
+void CResultSetCursor::writeXmlText(IXmlWriter &writer, int columnIndex, const char *tag)
|
|
|
+{
|
|
|
+ if (!isValid())
|
|
|
+ return;
|
|
|
+
|
|
|
+ const char * name = (tag) ? tag : meta.meta->queryXmlTag(columnIndex);
|
|
|
+ CResultSetColumnInfo & column = meta.columns.item(columnIndex);
|
|
|
+ unsigned flags = column.flag;
|
|
|
+ switch (flags)
|
|
|
+ {
|
|
|
+ case FVFFbeginif:
|
|
|
+ case FVFFendif:
|
|
|
+ return;
|
|
|
+ case FVFFbeginrecord:
|
|
|
+ {
|
|
|
+ if (name && *name)
|
|
|
+ {
|
|
|
+ writer.outputBeginNested(name, false);
|
|
|
+ const IntArray &attributes = meta.meta->queryAttrList(columnIndex);
|
|
|
+ ForEachItemIn(ac, attributes)
|
|
|
+ writeXmlAttrText(writer, attributes.item(ac));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ case FVFFendrecord:
|
|
|
+ writer.outputEndNested(name);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const byte * cur = getColumn(columnIndex);
|
|
|
+ unsigned resultLen;
|
|
|
+ char * resultStr = NULL;
|
|
|
+
|
|
|
+ ITypeInfo & type = *column.type;
|
|
|
+ unsigned size = type.getSize();
|
|
|
+ unsigned len = UNKNOWN_LENGTH;
|
|
|
+ switch (type.getTypeCode())
|
|
|
+ {
|
|
|
+ case type_boolean:
|
|
|
+ writer.outputBool(*((byte *)cur) != 0, name);
|
|
|
+ break;
|
|
|
+ case type_int:
|
|
|
+ {
|
|
|
+ __int64 value = getIntFromInt(type, cur, isMappedIndexField(columnIndex));
|
|
|
+ if (type.isSigned())
|
|
|
+ writer.outputInt((__int64) value, name);
|
|
|
+ else
|
|
|
+ writer.outputUInt((unsigned __int64) value, name);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case type_swapint:
|
|
|
+ {
|
|
|
+ __int64 value = getIntFromSwapInt(type, cur, isMappedIndexField(columnIndex));
|
|
|
+ if (type.isSigned())
|
|
|
+ writer.outputInt((__int64) value, name);
|
|
|
+ else
|
|
|
+ writer.outputUInt((unsigned __int64) value, name);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case type_packedint:
|
|
|
+ {
|
|
|
+ if (type.isSigned())
|
|
|
+ writer.outputInt(rtlGetPackedSigned(cur), name);
|
|
|
+ else
|
|
|
+ writer.outputUInt(rtlGetPackedUnsigned(cur), name);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case type_decimal:
|
|
|
+ if (type.isSigned())
|
|
|
+ writer.outputDecimal(cur, size, type.getPrecision(), name);
|
|
|
+ else
|
|
|
+ writer.outputUDecimal(cur, size, type.getPrecision(), name);
|
|
|
+ break;
|
|
|
+ case type_real:
|
|
|
+ if (size == 4)
|
|
|
+ writer.outputReal(*(float *)cur, name);
|
|
|
+ else
|
|
|
+ writer.outputReal(*(double *)cur, name);
|
|
|
+ break;
|
|
|
+ case type_qstring:
|
|
|
+ len = getLength(type, cur);
|
|
|
+ rtlQStrToStrX(resultLen, resultStr, len, (const char *)cur);
|
|
|
+ writer.outputString(resultLen, resultStr, name);
|
|
|
+ break;
|
|
|
+ case type_data:
|
|
|
+ len = getLength(type, cur);
|
|
|
+ writer.outputData(len, cur, name);
|
|
|
+ break;
|
|
|
+ case type_string:
|
|
|
+ len = getLength(type, cur);
|
|
|
+ if (meta.isEBCDIC(columnIndex))
|
|
|
+ {
|
|
|
+ rtlStrToEStrX(resultLen, resultStr, len, (const char *)cur);
|
|
|
+ writer.outputString(resultLen, resultStr, name);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ writer.outputString(len, (const char *)cur, name);
|
|
|
+ break;
|
|
|
+ case type_unicode:
|
|
|
+ len = getLength(type, cur);
|
|
|
+ writer.outputUnicode(len, (UChar const *)cur, name);
|
|
|
+ break;
|
|
|
+ case type_varstring:
|
|
|
+ if (meta.isEBCDIC(columnIndex))
|
|
|
+ {
|
|
|
+ rtlStrToEStrX(resultLen, resultStr, strlen((const char *)cur), (const char *)cur);
|
|
|
+ writer.outputString(resultLen, resultStr, name);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ writer.outputString(strlen((const char *)cur), (const char *)cur, name);
|
|
|
+ break;
|
|
|
+ case type_varunicode:
|
|
|
+ writer.outputUnicode(rtlUnicodeStrlen((UChar const *)cur), (UChar const *)cur, name);
|
|
|
+ break;
|
|
|
+ case type_utf8:
|
|
|
+ len = getLength(type, cur);
|
|
|
+ writer.outputUtf8(len, (const char *)cur, name);
|
|
|
+ break;
|
|
|
+ case type_table:
|
|
|
+ case type_groupedtable:
|
|
|
+ {
|
|
|
+ writer.outputBeginNested(name, false);
|
|
|
+ Owned<IResultSetCursor> childCursor = getChildren(columnIndex);
|
|
|
+ childCursor->beginWriteXmlRows(writer);
|
|
|
+ ForEach(*childCursor)
|
|
|
+ childCursor->writeXmlRow(writer);
|
|
|
+ childCursor->endWriteXmlRows(writer);
|
|
|
+ writer.outputEndNested(name);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case type_set:
|
|
|
+ {
|
|
|
+ writer.outputBeginNested(name, false);
|
|
|
+ if (getIsAll(columnIndex))
|
|
|
+ writer.outputSetAll();
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Owned<IResultSetCursor> childCursor = getChildren(columnIndex);
|
|
|
+ childCursor->beginWriteXmlRows(writer);
|
|
|
+ ForEach(*childCursor)
|
|
|
+ childCursor->writeXmlItem(writer);
|
|
|
+ childCursor->endWriteXmlRows(writer);
|
|
|
+ }
|
|
|
+ writer.outputEndNested(name);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ UNIMPLEMENTED;
|
|
|
+ }
|
|
|
+ rtlFree(resultStr);
|
|
|
+}
|
|
|
+
|
|
|
+void CResultSetCursor::writeXmlAttrText(IXmlWriter &writer, int columnIndex, const char *tag)
|
|
|
+{
|
|
|
+ if (!isValid())
|
|
|
+ return;
|
|
|
+
|
|
|
+ const char * name = (tag) ? tag : meta.meta->queryXmlTag(columnIndex);
|
|
|
+ CResultSetColumnInfo & column = meta.columns.item(columnIndex);
|
|
|
+ unsigned flags = column.flag;
|
|
|
+ switch (flags)
|
|
|
+ {
|
|
|
+ case FVFFbeginif:
|
|
|
+ case FVFFendif:
|
|
|
+ case FVFFbeginrecord:
|
|
|
+ case FVFFendrecord:
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const byte * cur = getColumn(columnIndex);
|
|
|
+ unsigned resultLen;
|
|
|
+ char * resultStr = NULL;
|
|
|
+
|
|
|
+ ITypeInfo & type = *column.type;
|
|
|
+ unsigned size = type.getSize();
|
|
|
+ unsigned len = UNKNOWN_LENGTH;
|
|
|
+ switch (type.getTypeCode())
|
|
|
+ {
|
|
|
+ case type_boolean:
|
|
|
+ writer.outputBool((*((byte *)cur)) != 0, name);
|
|
|
+ break;
|
|
|
+ case type_int:
|
|
|
+ {
|
|
|
+ __int64 value = getIntFromInt(type, cur, isMappedIndexField(columnIndex));
|
|
|
+ if (type.isSigned())
|
|
|
+ writer.outputInt((__int64) value, name);
|
|
|
+ else
|
|
|
+ writer.outputUInt((unsigned __int64) value, name);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case type_swapint:
|
|
|
+ {
|
|
|
+ __int64 value = getIntFromSwapInt(type, cur, isMappedIndexField(columnIndex));
|
|
|
+ if (type.isSigned())
|
|
|
+ writer.outputInt((__int64) value, name);
|
|
|
+ else
|
|
|
+ writer.outputUInt((unsigned __int64) value, name);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case type_packedint:
|
|
|
+ {
|
|
|
+ if (type.isSigned())
|
|
|
+ writer.outputInt(rtlGetPackedSigned(cur), name);
|
|
|
+ else
|
|
|
+ writer.outputUInt(rtlGetPackedUnsigned(cur), name);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case type_decimal:
|
|
|
+ if (type.isSigned())
|
|
|
+ writer.outputDecimal(cur, size, type.getPrecision(), name);
|
|
|
+ else
|
|
|
+ writer.outputUDecimal(cur, size, type.getPrecision(), name);
|
|
|
+ break;
|
|
|
+ case type_real:
|
|
|
+ if (size == 4)
|
|
|
+ writer.outputReal(*(float *)cur, name);
|
|
|
+ else
|
|
|
+ writer.outputReal(*(double *)cur, name);
|
|
|
+ break;
|
|
|
+ case type_qstring:
|
|
|
+ len = getLength(type, cur);
|
|
|
+ rtlQStrToStrX(resultLen, resultStr, len, (const char *)cur);
|
|
|
+ writer.outputString(resultLen, resultStr, name);
|
|
|
+ break;
|
|
|
+ case type_data:
|
|
|
+ len = getLength(type, cur);
|
|
|
+ writer.outputData(len, cur, name);
|
|
|
+ break;
|
|
|
+ case type_string:
|
|
|
+ len = getLength(type, cur);
|
|
|
+ if (meta.isEBCDIC(columnIndex))
|
|
|
+ {
|
|
|
+ rtlStrToEStrX(resultLen, resultStr, len, (const char *)cur);
|
|
|
+ writer.outputString(resultLen, resultStr, name);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ writer.outputString(len, (const char *)cur, name);
|
|
|
+ break;
|
|
|
+ case type_unicode:
|
|
|
+ len = getLength(type, cur);
|
|
|
+ writer.outputUnicode(len, (UChar const *)cur, name);
|
|
|
+ break;
|
|
|
+ case type_varstring:
|
|
|
+ if (meta.isEBCDIC(columnIndex))
|
|
|
+ {
|
|
|
+ rtlStrToEStrX(resultLen, resultStr, strlen((const char *)cur), (const char *)cur);
|
|
|
+ writer.outputString(resultLen, resultStr, name);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ writer.outputString(strlen((const char *)cur), (const char *)cur, name);
|
|
|
+ break;
|
|
|
+ case type_varunicode:
|
|
|
+ writer.outputUnicode(rtlUnicodeStrlen((UChar const *)cur), (UChar const *)cur, name);
|
|
|
+ break;
|
|
|
+ case type_utf8:
|
|
|
+ len = getLength(type, cur);
|
|
|
+ writer.outputUtf8(len, (const char *)cur, name);
|
|
|
+ break;
|
|
|
+ case type_table:
|
|
|
+ case type_groupedtable:
|
|
|
+ case type_set:
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ UNIMPLEMENTED;
|
|
|
+ }
|
|
|
+ rtlFree(resultStr);
|
|
|
+}
|
|
|
+
|
|
|
IStringVal & CResultSetCursor::getXml(IStringVal &ret, int columnIndex)
|
|
|
{
|
|
|
StringBuffer temp;
|
|
@@ -1807,6 +2079,11 @@ IStringVal & CResultSetCursor::getXmlItem(IStringVal & ret)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+void CResultSetCursor::writeXmlItem(IXmlWriter &writer)
|
|
|
+{
|
|
|
+ writeXmlText(writer, 0, meta.meta->queryXmlTag());
|
|
|
+}
|
|
|
+
|
|
|
//More efficient than above...
|
|
|
IStringVal & CResultSetCursor::getXmlRow(IStringVal &ret)
|
|
|
{
|
|
@@ -1865,6 +2142,74 @@ IStringVal & CResultSetCursor::getXmlRow(IStringVal &ret)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+void CResultSetCursor::beginWriteXmlRows(IXmlWriter & writer)
|
|
|
+{
|
|
|
+ const char *rowtag = meta.meta->queryXmlTag();
|
|
|
+ if (rowtag && *rowtag)
|
|
|
+ writer.outputBeginArray(rowtag);
|
|
|
+}
|
|
|
+
|
|
|
+void CResultSetCursor::endWriteXmlRows(IXmlWriter & writer)
|
|
|
+{
|
|
|
+ const char *rowtag = meta.meta->queryXmlTag();
|
|
|
+ if (rowtag && *rowtag)
|
|
|
+ writer.outputEndArray(rowtag);
|
|
|
+}
|
|
|
+
|
|
|
+void CResultSetCursor::writeXmlRow(IXmlWriter &writer)
|
|
|
+{
|
|
|
+ StringBuffer temp;
|
|
|
+ const char *rowtag = meta.meta->queryXmlTag();
|
|
|
+ if (rowtag && *rowtag)
|
|
|
+ {
|
|
|
+ writer.outputBeginNested(rowtag, false);
|
|
|
+ const IntArray &attributes = meta.meta->queryAttrList();
|
|
|
+ ForEachItemIn(ac, attributes)
|
|
|
+ writeXmlAttrText(writer, attributes.item(ac));
|
|
|
+ }
|
|
|
+ unsigned numColumns = meta.getColumnCount();
|
|
|
+ unsigned ignoreNesting = 0;
|
|
|
+ for (unsigned col = 0; col < numColumns; col++)
|
|
|
+ {
|
|
|
+ unsigned flags = meta.columns.item(col).flag;
|
|
|
+ const char *tag = meta.meta->queryXmlTag(col);
|
|
|
+ if (tag && *tag=='@')
|
|
|
+ continue;
|
|
|
+ switch (flags)
|
|
|
+ {
|
|
|
+ case FVFFbeginif:
|
|
|
+ if (ignoreNesting || !getBoolean(col))
|
|
|
+ ignoreNesting++;
|
|
|
+ break;
|
|
|
+ case FVFFendif:
|
|
|
+ if (ignoreNesting)
|
|
|
+ ignoreNesting--;
|
|
|
+ break;
|
|
|
+ case FVFFbeginrecord:
|
|
|
+ if (ignoreNesting)
|
|
|
+ ignoreNesting++;
|
|
|
+ else
|
|
|
+ writeXmlText(writer, col);
|
|
|
+ break;
|
|
|
+ case FVFFendrecord:
|
|
|
+ if (ignoreNesting)
|
|
|
+ ignoreNesting--;
|
|
|
+ else
|
|
|
+ writeXmlText(writer, col);
|
|
|
+ break;
|
|
|
+ case FVFFnone:
|
|
|
+ case FVFFvirtual:
|
|
|
+ case FVFFdataset:
|
|
|
+ case FVFFset:
|
|
|
+ if (ignoreNesting == 0)
|
|
|
+ writeXmlText(writer, col);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ assertex(ignoreNesting == 0);
|
|
|
+ writer.outputEndNested(rowtag);
|
|
|
+}
|
|
|
+
|
|
|
bool CResultSetCursor::isAfterLast() const
|
|
|
{
|
|
|
return (curRowData.length() == 0) && (getCurRow() != BEFORE_FIRST_ROW);
|
|
@@ -2101,6 +2446,22 @@ IStringVal & IndirectResultSetCursor::getXmlItem(IStringVal &ret)
|
|
|
{
|
|
|
return queryBase()->getXmlItem(ret);
|
|
|
}
|
|
|
+void IndirectResultSetCursor::beginWriteXmlRows(IXmlWriter & writer)
|
|
|
+{
|
|
|
+ return queryBase()->beginWriteXmlRows(writer);
|
|
|
+}
|
|
|
+void IndirectResultSetCursor::writeXmlRow(IXmlWriter &writer)
|
|
|
+{
|
|
|
+ return queryBase()->writeXmlRow(writer);
|
|
|
+}
|
|
|
+void IndirectResultSetCursor::endWriteXmlRows(IXmlWriter & writer)
|
|
|
+{
|
|
|
+ return queryBase()->endWriteXmlRows(writer);
|
|
|
+}
|
|
|
+void IndirectResultSetCursor::writeXmlItem(IXmlWriter &writer)
|
|
|
+{
|
|
|
+ return queryBase()->writeXmlItem(writer);
|
|
|
+}
|
|
|
void IndirectResultSetCursor::noteRelatedFileChanged()
|
|
|
{
|
|
|
queryBase()->noteRelatedFileChanged();
|
|
@@ -3292,6 +3653,59 @@ extern FILEVIEW_API unsigned getResultXml(IStringVal & ret, INewResultSet * resu
|
|
|
return getResultCursorXml(ret, cursor, name, start, count, schemaName);
|
|
|
}
|
|
|
|
|
|
+extern FILEVIEW_API unsigned getResultJSON(IStringVal & ret, INewResultSet * result, const char* name,unsigned start, unsigned count)
|
|
|
+{
|
|
|
+ Owned<IResultSetCursor> cursor = result->createCursor();
|
|
|
+ Owned<CommonJsonWriter> writer = new CommonJsonWriter(0);
|
|
|
+ writer->outputBeginRoot();
|
|
|
+ unsigned rc = writeResultCursorXml(*writer, cursor, name, start, count, NULL);
|
|
|
+ writer->outputEndRoot();
|
|
|
+ ret.set(writer->str());
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
+extern FILEVIEW_API unsigned writeResultCursorXml(IXmlWriter & writer, IResultSetCursor * cursor, const char * name, unsigned start, unsigned count, const char * schemaName)
|
|
|
+{
|
|
|
+ if (schemaName)
|
|
|
+ {
|
|
|
+ CommonXmlWriter *xmlwriter = dynamic_cast<CommonXmlWriter *>(&writer);
|
|
|
+ if (xmlwriter)
|
|
|
+ {
|
|
|
+ StringBuffer xsd;
|
|
|
+ xsd.append("<XmlSchema name=\"").append(schemaName).append("\">");
|
|
|
+ const IResultSetMetaData & meta = cursor->queryResultSet()->getMetaData();
|
|
|
+ StringBufferAdaptor adaptor(xsd);
|
|
|
+ meta.getXmlXPathSchema(adaptor, false);
|
|
|
+ xsd.append("</XmlSchema>").newline();
|
|
|
+ xmlwriter->outputInlineXml(xsd.str());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ writer.outputBeginDataset(name, true);
|
|
|
+ if (schemaName)
|
|
|
+ writer.outputCString(schemaName, "@xmlSchema");
|
|
|
+
|
|
|
+ cursor->beginWriteXmlRows(writer);
|
|
|
+ unsigned c=0;
|
|
|
+ for(bool ok=cursor->absolute(start);ok;ok=cursor->next())
|
|
|
+ {
|
|
|
+ cursor->writeXmlRow(writer);
|
|
|
+
|
|
|
+ c++;
|
|
|
+ if(count && c>=count)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ cursor->endWriteXmlRows(writer);
|
|
|
+ writer.outputEndDataset(name);
|
|
|
+ return c;
|
|
|
+}
|
|
|
+
|
|
|
+extern FILEVIEW_API unsigned writeResultXml(IXmlWriter & writer, INewResultSet * result, const char* name,unsigned start, unsigned count, const char * schemaName)
|
|
|
+{
|
|
|
+ Owned<IResultSetCursor> cursor = result->createCursor();
|
|
|
+ return writeResultCursorXml(writer, cursor, name, start, count, schemaName);
|
|
|
+}
|
|
|
+
|
|
|
extern FILEVIEW_API unsigned getResultCursorBin(MemoryBuffer & ret, IResultSetCursor * cursor, unsigned start, unsigned count)
|
|
|
{
|
|
|
const IResultSetMetaData & meta = cursor->queryResultSet()->getMetaData();
|
|
@@ -3334,13 +3748,13 @@ inline const char *getSeverityTagname(WUExceptionSeverity severity, unsigned fla
|
|
|
return "Exception";
|
|
|
}
|
|
|
|
|
|
-extern FILEVIEW_API IStringVal& getFullWorkUnitResultsXML(const char *username, const char *password, const IConstWorkUnit *cw, IStringVal &str, unsigned flags, WUExceptionSeverity minSeverity)
|
|
|
+extern FILEVIEW_API void writeFullWorkUnitResults(const char *username, const char *password, const IConstWorkUnit *cw, IXmlWriter &writer, unsigned flags, WUExceptionSeverity minSeverity, const char *rootTag)
|
|
|
{
|
|
|
SCMStringBuffer wuid;
|
|
|
cw->getWuid(wuid);
|
|
|
- StringBuffer result;
|
|
|
- if (!(flags & WorkUnitXML_NoRoot))
|
|
|
- result.append("<Result>").newline();
|
|
|
+
|
|
|
+ if (rootTag && *rootTag && !(flags & WorkUnitXML_NoRoot))
|
|
|
+ writer.outputBeginNested(rootTag, true);
|
|
|
|
|
|
Owned<IConstWUExceptionIterator> exceptions = &cw->getExceptions();
|
|
|
ForEach(*exceptions)
|
|
@@ -3348,15 +3762,13 @@ extern FILEVIEW_API IStringVal& getFullWorkUnitResultsXML(const char *username,
|
|
|
WUExceptionSeverity severity = exceptions->query().getSeverity();
|
|
|
if (severity>=minSeverity)
|
|
|
{
|
|
|
- SCMStringBuffer x, y;
|
|
|
- exceptions->query().getExceptionSource(x);
|
|
|
- exceptions->query().getExceptionMessage(y);
|
|
|
-
|
|
|
- result.appendf("<%s><Source>", getSeverityTagname(severity, flags));
|
|
|
- encodeUtf8XML(x.str(), result);
|
|
|
- result.append("</Source><Message>");
|
|
|
- encodeUtf8XML(y.str(), result);
|
|
|
- result.appendf("</Message></%s>", getSeverityTagname(severity, flags)).newline();
|
|
|
+ SCMStringBuffer src, msg;
|
|
|
+ exceptions->query().getExceptionSource(src);
|
|
|
+ exceptions->query().getExceptionMessage(msg);
|
|
|
+ writer.outputBeginNested(getSeverityTagname(severity, flags), false);
|
|
|
+ writer.outputCString(src.str(), "Source");
|
|
|
+ writer.outputCString(msg.str(), "Message");
|
|
|
+ writer.outputEndNested(getSeverityTagname(severity, flags));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -3372,22 +3784,47 @@ extern FILEVIEW_API IStringVal& getFullWorkUnitResultsXML(const char *username,
|
|
|
IConstWUResult &ds = results->query();
|
|
|
if (ds.getResultSequence()>=0)
|
|
|
{
|
|
|
- SCMStringBuffer resultXML, name;
|
|
|
+ SCMStringBuffer name;
|
|
|
ds.getResultName(name);
|
|
|
Owned<INewResultSet> nr = factory->createNewResultSet(&ds, wuid.str());
|
|
|
- getResultXml(resultXML, nr.get(), name.str(), 0, 0, (flags & WorkUnitXML_InclSchema) ? name.str() : NULL);
|
|
|
- result.append(resultXML);
|
|
|
+ writeResultXml(writer, nr.get(), name.str(), 0, 0, (flags & WorkUnitXML_InclSchema) ? name.str() : NULL);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case WUStateAborted:
|
|
|
- result.append("<Exception><Source>System</Source><Message>Query aborted by operator</Message></Exception>");
|
|
|
+ writer.outputBeginNested("Exception", false);
|
|
|
+ writer.outputCString("System", "Source");
|
|
|
+ writer.outputCString("Query aborted by operator", "Message");
|
|
|
+ writer.outputEndNested("Exception");
|
|
|
break;
|
|
|
}
|
|
|
- if (!(flags & WorkUnitXML_NoRoot))
|
|
|
- result.append("</Result>");
|
|
|
- str.set(result.str());
|
|
|
+ if (rootTag && *rootTag && !(flags & WorkUnitXML_NoRoot))
|
|
|
+ writer.outputEndNested(rootTag);
|
|
|
+}
|
|
|
+
|
|
|
+extern FILEVIEW_API IStringVal& getFullWorkUnitResultsXML(const char *username, const char *password, const IConstWorkUnit *cw, IStringVal &str, unsigned flags, WUExceptionSeverity minSeverity)
|
|
|
+{
|
|
|
+ SCMStringBuffer wuid;
|
|
|
+ cw->getWuid(wuid);
|
|
|
+
|
|
|
+ Owned<CommonXmlWriter> writer = CreateCommonXmlWriter(0);
|
|
|
+ writeFullWorkUnitResults(username, password, cw, *writer, flags, minSeverity, "Result");
|
|
|
+
|
|
|
+ str.set(writer->str());
|
|
|
+ return str;
|
|
|
+}
|
|
|
+
|
|
|
+extern FILEVIEW_API IStringVal& getFullWorkUnitResultsJSON(const char *username, const char *password, const IConstWorkUnit *cw, IStringVal &str, unsigned flags, WUExceptionSeverity minSeverity)
|
|
|
+{
|
|
|
+ SCMStringBuffer wuid;
|
|
|
+ cw->getWuid(wuid);
|
|
|
+
|
|
|
+ Owned<CommonJsonWriter> writer = new CommonJsonWriter(0, 0, 0);
|
|
|
+ writer->outputBeginRoot();
|
|
|
+ writeFullWorkUnitResults(username, password, cw, *writer, flags, minSeverity, "Results");
|
|
|
+ writer->outputEndRoot();
|
|
|
+ str.set(writer->str());
|
|
|
return str;
|
|
|
}
|