Browse Source

HPCC-12081 Add ToJSON function to ECL

Signed-off-by: Anthony Fishbeck <anthony.fishbeck@lexisnexis.com>
Anthony Fishbeck 11 years ago
parent
commit
71e2e6dd5f

+ 4 - 0
common/thorhelper/thorcommon.hpp

@@ -417,6 +417,10 @@ public:
     {
         convertRowToXML(lenResult, result, info, row, flags);
     }
+    virtual void getRowJSON(size32_t & lenResult, char * & result, IOutputMetaData & info, const void * row, unsigned flags)
+    {
+        convertRowToJSON(lenResult, result, info, row, flags);
+    }
     virtual const void * fromXml(IEngineRowAllocator * _rowAllocator, size32_t len, const char * utf8, IXmlToRowTransformer * xmlTransformer, bool stripWhitespace)
     {
         return ctx->fromXml(_rowAllocator, len, utf8, xmlTransformer, stripWhitespace);

+ 14 - 0
common/thorhelper/thorxmlwrite.cpp

@@ -1313,3 +1313,17 @@ extern thorhelper_decl void convertRowToXML(size32_t & lenResult, char * & resul
     rtlStrToStrX(sizeResult, result, writer.length(), writer.str());
     lenResult = rtlUtf8Length(sizeResult, result);
 }
+
+extern thorhelper_decl void convertRowToJSON(size32_t & lenResult, char * & result, IOutputMetaData & info, const void * row, unsigned flags)
+{
+    const byte * self = (const byte *)row;
+    if (flags == (unsigned)-1)
+        flags = XWFtrim|XWFopt|XWFnoindent;
+
+    CommonJsonWriter writer(flags);
+    info.toXML(self, writer);
+    //could use detach...
+    unsigned sizeResult;
+    rtlStrToStrX(sizeResult, result, writer.length(), writer.str());
+    lenResult = rtlUtf8Length(sizeResult, result);
+}

+ 1 - 0
common/thorhelper/thorxmlwrite.hpp

@@ -266,5 +266,6 @@ public:
 extern thorhelper_decl void printKeyedValues(StringBuffer &out, IIndexReadContext *segs, IOutputMetaData *rowMeta);
 
 extern thorhelper_decl void convertRowToXML(size32_t & lenResult, char * & result, IOutputMetaData & info, const void * row, unsigned flags = (unsigned)-1);
+extern thorhelper_decl void convertRowToJSON(size32_t & lenResult, char * & result, IOutputMetaData & info, const void * row, unsigned flags = (unsigned)-1);
 
 #endif // THORXMLWRITE_HPP

+ 4 - 0
ecl/eclagent/eclagent.ipp

@@ -614,6 +614,10 @@ public:
     {
         convertRowToXML(lenResult, result, info, row, flags);
     }
+    virtual void getRowJSON(size32_t & lenResult, char * & result, IOutputMetaData & info, const void * row, unsigned flags)
+    {
+        convertRowToJSON(lenResult, result, info, row, flags);
+    }
     virtual const char *queryAllowedPipePrograms()
     {
         return allowedPipeProgs.get();

+ 1 - 0
ecl/hql/hqlattr.cpp

@@ -192,6 +192,7 @@ unsigned getOperatorMetaFlags(node_operator op)
     case no_regex_find:
     case no_regex_replace:
     case no_toxml:
+    case no_tojson:
 
 //Boolean operators:
     case no_eq:

+ 1 - 0
ecl/hql/hqlexpr.cpp

@@ -1462,6 +1462,7 @@ const char *getOpString(node_operator op)
     case no_merge_pending: return "no_merge_pending";
     case no_merge_nomatch: return "no_merge_nomatch";
     case no_toxml: return "TOXML";
+    case no_tojson: return "TOJSON";
     case no_catchds: return "CATCH";
     case no_readspill: return "no_readspill";
     case no_writespill: return "no_writespill";

+ 1 - 0
ecl/hql/hqlexpr.hpp

@@ -738,6 +738,7 @@ enum _node_operator {
         no_httpcall,
         no_getenv,
         no_fromjson,
+        no_tojson,
         no_last_op,
 
 //These never get created as IHqlExpressions....

+ 6 - 0
ecl/hql/hqlgram.y

@@ -428,6 +428,7 @@ static void eclsyntaxerror(HqlGram * parser, const char * s, short yystate, int
   TIMEOUT
   TIMELIMIT
   TOKEN
+  TOJSON
   TOPN
   TOUNICODE
   TOXML
@@ -5885,6 +5886,11 @@ primexpr1
                             //MORE Could allow ,NOTRIM,OPT,???flags
                             $$.setExpr(createValue(no_toxml, makeUtf8Type(UNKNOWN_LENGTH, NULL), $3.getExpr()));
                         }
+    | TOJSON '(' dataRow ')'
+                        {
+                            //MORE Could allow ,NOTRIM,OPT,???flags
+                            $$.setExpr(createValue(no_tojson, makeUtf8Type(UNKNOWN_LENGTH, NULL), $3.getExpr()));
+                        }
     | REGEXFIND '(' expression ',' expression regexOpt ')'
                         {
                             parser->normalizeExpression($3, type_stringorunicode, false);

+ 3 - 2
ecl/hql/hqlgram2.cpp

@@ -10575,6 +10575,7 @@ static void getTokenText(StringBuffer & msg, int token)
     case TIMEOUT: msg.append("TIMEOUT"); break;
     case TIMELIMIT: msg.append("TIMELIMIT"); break;
     case TOKEN: msg.append("TOKEN"); break;
+    case TOJSON: msg.append("TOJSON"); break;
     case TOPN: msg.append("TOPN"); break;
     case TOUNICODE: msg.append("TOUNICODE"); break;
     case TOXML: msg.append("TOXML"); break;
@@ -10760,14 +10761,14 @@ void HqlGram::simplifyExpected(int *expected)
                        FAILCODE, FAILMESSAGE, FROMUNICODE, __GROUPED__, ISNULL, ISVALID, XMLDECODE, XMLENCODE, XMLTEXT, XMLUNICODE,
                        MATCHED, MATCHLENGTH, MATCHPOSITION, MATCHTEXT, MATCHUNICODE, MATCHUTF8, NOFOLD, NOHOIST, NOTHOR, OPT, REGEXFIND, REGEXREPLACE, RELATIONSHIP, SEQUENTIAL, SKIP, TOUNICODE, UNICODEORDER, UNSORTED,
                        KEYUNICODE, TOK_TRUE, TOK_FALSE, BOOL_CONST, NOT, EXISTS, WITHIN, LEFT, RIGHT, SELF, '[', HTTPCALL, SOAPCALL, ALL, TOK_ERROR, TOK_CATCH, __COMMON__, __COMPOUND__, RECOVERY, CLUSTERSIZE, CHOOSENALL, BNOT, STEPPED, ECLCRC, NAMEOF,
-                       TOXML, '@', SECTION, EVENTEXTRA, EVENTNAME, __SEQUENCE__, IFF, OMITTED, GETENV, __DEBUG__, __STAND_ALONE__, 0);
+                       TOXML, TOJSON, '@', SECTION, EVENTEXTRA, EVENTNAME, __SEQUENCE__, IFF, OMITTED, GETENV, __DEBUG__, __STAND_ALONE__, 0);
     simplify(expected, DATA_CONST, REAL_CONST, STRING_CONST, INTEGER_CONST, UNICODE_CONST, 0);
     simplify(expected, VALUE_MACRO, DEFINITIONS_MACRO, 0);
     simplify(expected, DICTIONARY_ID, DICTIONARY_FUNCTION, DICTIONARY, 0);
     simplify(expected, ACTION_ID, ORDERED, 0); // more include other actions
     simplify(expected, VALUE_ID, DATASET_ID, DICTIONARY_ID, RECORD_ID, ACTION_ID, UNKNOWN_ID, SCOPE_ID, VALUE_FUNCTION, DATAROW_FUNCTION, DATASET_FUNCTION, DICTIONARY_FUNCTION, LIST_DATASET_FUNCTION, LIST_DATASET_ID, ALIEN_ID, TYPE_ID, SET_TYPE_ID, TRANSFORM_ID, TRANSFORM_FUNCTION, RECORD_FUNCTION, FEATURE_ID, EVENT_ID, EVENT_FUNCTION, SCOPE_FUNCTION, ENUM_ID, PATTERN_TYPE_ID, DICTIONARY_TYPE_ID, DATASET_TYPE_ID, 0);
     simplify(expected, LIBRARY, LIBRARY, SCOPE_FUNCTION, STORED, PROJECT, INTERFACE, MODULE, 0);
-    simplify(expected, MATCHROW, MATCHROW, LEFT, RIGHT, IF, IFF, ROW, HTTPCALL, SOAPCALL, PROJECT, GLOBAL, NOFOLD, NOHOIST, ALLNODES, THISNODE, SKIP, DATAROW_FUNCTION, TRANSFER, RIGHT_NN, FROMXML, 0);
+    simplify(expected, MATCHROW, MATCHROW, LEFT, RIGHT, IF, IFF, ROW, HTTPCALL, SOAPCALL, PROJECT, GLOBAL, NOFOLD, NOHOIST, ALLNODES, THISNODE, SKIP, DATAROW_FUNCTION, TRANSFER, RIGHT_NN, FROMXML, FROMJSON, 0);
     simplify(expected, TRANSFORM_ID, TRANSFORM_FUNCTION, TRANSFORM, '@', 0);
     simplify(expected, RECORD, RECORDOF, RECORD_ID, RECORD_FUNCTION, SCOPE_ID, VALUE_MACRO, '{', '@', 0);
     simplify(expected, IFBLOCK, ANY, PACKED, BIG, LITTLE, 0);

+ 1 - 0
ecl/hql/hqlir.cpp

@@ -639,6 +639,7 @@ const char * getOperatorIRText(node_operator op)
     EXPAND_CASE(no,catchds);
     EXPAND_CASE(no,file_logicalname);
     EXPAND_CASE(no,toxml);
+    EXPAND_CASE(no,tojson);
     EXPAND_CASE(no,sectioninput);
     EXPAND_CASE(no,forcegraph);
     EXPAND_CASE(no,eventextra);

+ 1 - 0
ecl/hql/hqllex.l

@@ -914,6 +914,7 @@ THRESHOLD           { RETURNSYM(THRESHOLD); }
 TIMEOUT             { RETURNSYM(TIMEOUT); }
 TIMELIMIT           { RETURNSYM(TIMELIMIT); }
 TOKEN               { RETURNSYM(TOKEN); }
+TOJSON              { RETURNSYM(TOJSON); }
 TOPN                { RETURNSYM(TOPN); }
 TOUNICODE           { RETURNSYM(TOUNICODE); }
 TOXML               { RETURNSYM(TOXML); }

+ 2 - 0
ecl/hqlcpp/hqlcatom.cpp

@@ -215,6 +215,7 @@ IIdAtom * createUnicodeRangeHighId;
 IIdAtom * createRegexId;
 IIdAtom * createWRegexId;
 IIdAtom * csvStr2BoolId;
+IIdAtom * ctxGetRowJsonId;
 IIdAtom * ctxGetRowXmlId;
 IIdAtom * data2BoolId;
 IIdAtom * dataset2DatasetXId;
@@ -864,6 +865,7 @@ MODULE_INIT(INIT_PRIORITY_HQLATOM-1)
     MAKEID(createUnicodeRangeHigh);
     MAKEID(createWRegex);
     MAKEID(csvStr2Bool);
+    MAKEID(ctxGetRowJson);
     MAKEID(ctxGetRowXml);
     MAKEID(data2Bool);
     MAKEID(dataset2DatasetX);

+ 1 - 0
ecl/hqlcpp/hqlcatom.hpp

@@ -215,6 +215,7 @@ extern IIdAtom * createUnicodeRangeHighId;
 extern IIdAtom * createRegexId;
 extern IIdAtom * createWRegexId;
 extern IIdAtom * csvStr2BoolId;
+extern IIdAtom * ctxGetRowJsonId;
 extern IIdAtom * ctxGetRowXmlId;
 extern IIdAtom * data2BoolId;
 extern IIdAtom * dataset2DatasetXId;

+ 6 - 3
ecl/hqlcpp/hqlcpp.cpp

@@ -2456,7 +2456,8 @@ void HqlCppTranslator::buildExprAssign(BuildCtx & ctx, const CHqlBoundTarget & t
         doBuildAssignToFromUnicode(ctx, target, expr);
         break;
     case no_toxml:
-        doBuildAssignToXml(ctx, target, expr);
+    case no_tojson:
+        doBuildAssignToXmlorJson(ctx, target, expr);
         break;
     case no_wuid:
         doBuildAssignWuid(ctx, target, expr);
@@ -3139,6 +3140,7 @@ void HqlCppTranslator::buildExpr(BuildCtx & ctx, IHqlExpression * expr, CHqlBoun
     case no_eventextra:
     case no_loopcounter:
     case no_toxml:
+    case no_tojson:
         buildTempExpr(ctx, expr, tgt);
         return;
     case no_asstring:
@@ -7363,7 +7365,7 @@ void HqlCppTranslator::doBuildAssignFormat(IIdAtom * func, BuildCtx & ctx, const
 
 //---------------------------------------------------------------------------
 
-void HqlCppTranslator::doBuildAssignToXml(BuildCtx & ctx, const CHqlBoundTarget & target, IHqlExpression * expr)
+void HqlCppTranslator::doBuildAssignToXmlorJson(BuildCtx & ctx, const CHqlBoundTarget & target, IHqlExpression * expr)
 {
     IHqlExpression * row = expr->queryChild(0);
 
@@ -7371,7 +7373,8 @@ void HqlCppTranslator::doBuildAssignToXml(BuildCtx & ctx, const CHqlBoundTarget
     args.append(*buildMetaParameter(row));
     args.append(*LINK(row));
     args.append(*getSizetConstant(XWFtrim|XWFopt|XWFnoindent));
-    OwnedHqlExpr call = bindFunctionCall(ctxGetRowXmlId, args);
+    node_operator op = expr->getOperator();
+    OwnedHqlExpr call = bindFunctionCall((op==no_tojson) ? ctxGetRowJsonId : ctxGetRowXmlId, args);
     buildExprAssign(ctx, target, call);
 }
 

+ 2 - 2
ecl/hqlcpp/hqlcpp.ipp

@@ -1195,7 +1195,7 @@ public:
     void doBuildAssignUnicodeOrder(BuildCtx & ctx, const CHqlBoundTarget & target, IHqlExpression * expr);
     void doBuildAssignRegexFindReplace(BuildCtx & ctx, const CHqlBoundTarget & target, IHqlExpression * expr);
     void doBuildAssignSubString(BuildCtx & ctx, const CHqlBoundTarget & target, IHqlExpression * expr);
-    void doBuildAssignToXml(BuildCtx & ctx, const CHqlBoundTarget & target, IHqlExpression * expr);
+    void doBuildAssignToXmlorJson(BuildCtx & ctx, const CHqlBoundTarget & target, IHqlExpression * expr);
     void doBuildAssignTrim(BuildCtx & ctx, const CHqlBoundTarget & target, IHqlExpression * expr);
     void doBuildAssignWhich(BuildCtx & ctx, const CHqlBoundTarget & target, IHqlExpression * expr);
     void doBuildAssignWuid(BuildCtx & ctx, const CHqlBoundTarget & target, IHqlExpression * expr);
@@ -1248,7 +1248,7 @@ public:
     void doBuildRowAssignSerializeRow(BuildCtx & ctx, IReferenceSelector * target, IHqlExpression * expr);
 
     IReferenceSelector * doBuildRowDeserializeRow(BuildCtx & ctx, IHqlExpression * expr);
-    IReferenceSelector * doBuildRowFromXMLorJSON(BuildCtx & ctx, IHqlExpression * expr, node_operator op);
+    IReferenceSelector * doBuildRowFromXMLorJSON(BuildCtx & ctx, IHqlExpression * expr);
     IReferenceSelector * doBuildRowIdToBlob(BuildCtx & ctx, IHqlExpression * expr, bool isNew);
     IReferenceSelector * doBuildRowIf(BuildCtx & ctx, IHqlExpression * expr);
     IReferenceSelector * doBuildRowMatchAttr(BuildCtx & ctx, IHqlExpression * expr);

+ 3 - 2
ecl/hqlcpp/hqlcppds.cpp

@@ -314,7 +314,7 @@ void HqlCppTranslator::buildNullRow(BuildCtx & ctx, IHqlExpression * expr, CHqlB
     bound.expr.setown(createValue(no_nullptr, makeRowReferenceType(expr)));
 }
 
-IReferenceSelector * HqlCppTranslator::doBuildRowFromXMLorJSON(BuildCtx & ctx, IHqlExpression * expr, node_operator op)
+IReferenceSelector * HqlCppTranslator::doBuildRowFromXMLorJSON(BuildCtx & ctx, IHqlExpression * expr)
 {
 //  assertex(supportsLinkCountedRows);
     Owned<ITypeInfo> overrideType = setLinkCountedAttr(expr->queryType(), true);
@@ -324,6 +324,7 @@ IReferenceSelector * HqlCppTranslator::doBuildRowFromXMLorJSON(BuildCtx & ctx, I
 
     StringBuffer instanceName, factoryName, s;
     bool usesContents = false;
+    node_operator op = expr->getOperator();
     getUniqueId(instanceName.append(op==no_fromjson ? "json" : "xml"));
     buildXmlReadTransform(ds, factoryName, usesContents);
 
@@ -416,7 +417,7 @@ IReferenceSelector * HqlCppTranslator::buildNewRow(BuildCtx & ctx, IHqlExpressio
         return buildActiveRow(ctx, expr);
     case no_fromxml:
     case no_fromjson:
-        return doBuildRowFromXMLorJSON(ctx, expr, op);
+        return doBuildRowFromXMLorJSON(ctx, expr);
     case no_serialize:
         {
             IHqlExpression * deserialized = expr->queryChild(0);

+ 1 - 0
ecl/hqlcpp/hqlcppsys.ecl

@@ -700,6 +700,7 @@ const char * cppSystemText[]  = {
     "   unsigned4 countToSize(unsigned4 numRows, const data1 raw, boolean iRecordSize) : eclrtl,pure,include,entrypoint='rtlCountToSize';",
     
     "   utf8 ctxGetRowXml(boolean _meta, const row _row, unsigned4 flags) : ctxmethod,entrypoint='getRowXML';",
+    "   utf8 ctxGetRowJson(boolean _meta, const row _row, unsigned4 flags) : ctxmethod,entrypoint='getRowJSON';",
 
     "   boolean getMatched(unsigned4 idx) : method,pure,include,entrypoint='getMatched';",
     "   unsigned4 getMatchLength(unsigned4 idx) : method,pure,include,entrypoint='getMatchLength';",

+ 4 - 0
roxie/ccd/ccdactivities.cpp

@@ -603,6 +603,10 @@ public:
     {
         convertRowToXML(lenResult, result, info, row, flags);
     }
+    virtual void getRowJSON(size32_t & lenResult, char * & result, IOutputMetaData & info, const void * row, unsigned flags)
+    {
+        convertRowToJSON(lenResult, result, info, row, flags);
+    }
     const void * fromXml(IEngineRowAllocator * rowAllocator, size32_t len, const char * utf8, IXmlToRowTransformer * xmlTransformer, bool stripWhitespace)
     {
         return createRowFromXml(rowAllocator, len, utf8, xmlTransformer, stripWhitespace);

+ 4 - 0
roxie/ccd/ccdcontext.cpp

@@ -1664,6 +1664,10 @@ public:
     {
         convertRowToXML(lenResult, result, info, row, flags);
     }
+    virtual void getRowJSON(size32_t & lenResult, char * & result, IOutputMetaData & info, const void * row, unsigned flags)
+    {
+        convertRowToJSON(lenResult, result, info, row, flags);
+    }
 
     virtual IWorkUnit *updateWorkUnit() const
     {

+ 1 - 2
rtl/include/eclhelper.hpp

@@ -642,9 +642,8 @@ interface ICodeContext : public IResourceContext
     virtual char *getDaliServers() = 0;
     virtual IWorkUnit *updateWorkUnit() const = 0;
 
-    // Called from generated code for FROMJSON
-
     virtual const void * fromJson(IEngineRowAllocator * _rowAllocator, size32_t len, const char * utf8, IXmlToRowTransformer * xmlTransformer, bool stripWhitespace) = 0;
+    virtual void getRowJSON(size32_t & lenResult, char * & result, IOutputMetaData & info, const void * row, unsigned flags) = 0;
 };
 
 

File diff suppressed because it is too large
+ 12 - 0
testing/regress/ecl/key/tojson.xml


+ 64 - 0
testing/regress/ecl/tojson.ecl

@@ -0,0 +1,64 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2014 HPCC Systems.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+phoneRecord :=
+            RECORD
+string5         areaCode{xpath('@areaCode')};
+udecimal12      number{xpath('@number')};
+            END;
+
+contactrecord :=
+            RECORD
+phoneRecord     phone;
+boolean         hasemail{xpath('@hasEmail')};
+                ifblock(self.hasemail)
+string              email;
+                end;
+            END;
+
+bookRec :=
+    RECORD
+unicode     title;
+string      author;
+    END;
+
+personRecord :=
+            RECORD
+unicode20       surname;
+unicode10       forename;
+phoneRecord     homePhone;
+boolean         hasMobile;
+                ifblock(self.hasMobile)
+phoneRecord         mobilePhone;
+                end;
+contactRecord   contact;
+dataset(bookRec) books;
+set of string    colours;
+string2         endmarker := '$$';
+            END;
+
+namesTable := dataset([
+        {U'Hälliday','Gavin','09876',123987,true,'07967',123987, 'n/a','n/a',true,'gavin@edata.com',[{U'εν αρχη ην ο λογος', 'john'}, {U'To kill a mocking bird','Lee'},{U'Zen and the art of motorcycle maintainence','Pirsig'}], ALL},
+        {U'Halliday','Abigäil','09876',123987,false,'','',false,[{U'The cat in the hat','Suess'},{U'Wolly the sheep',''}], ['Red','Yellow']}
+        ], personRecord);
+
+output(namesTable);
+
+output(namesTable, {unicode json{maxlength(1024)} := U'{' + tojson(row(namesTable)) + U'}'});
+
+output(namesTable, {unicode xml{maxlength(1024)} := U'<Row>' + toxml(row(namesTable)) + U'</Row>'});
+

+ 1 - 0
thorlcr/graph/thgraph.hpp

@@ -511,6 +511,7 @@ class graph_decl CGraphBase : public CInterface, implements IEclGraphResults, im
         virtual void getResultDictionary(size32_t & tcount, byte * * & tgt,IEngineRowAllocator * _rowAllocator,  const char * name, unsigned sequence, IXmlToRowTransformer * xmlTransformer, ICsvToRowTransformer * csvTransformer, IHThorHashLookupInfo * hasher) { ctx->getResultDictionary(tcount, tgt, _rowAllocator, name, sequence, xmlTransformer, csvTransformer, hasher); }
 
         virtual void getRowXML(size32_t & lenResult, char * & result, IOutputMetaData & info, const void * row, unsigned flags) { convertRowToXML(lenResult, result, info, row, flags); }
+        virtual void getRowJSON(size32_t & lenResult, char * & result, IOutputMetaData & info, const void * row, unsigned flags) { convertRowToJSON(lenResult, result, info, row, flags); }
         virtual unsigned getGraphLoopCounter() const
         {
             return graph->queryLoopCounter();           // only called if value is valid

+ 5 - 0
thorlcr/thorcodectx/thcodectx.cpp

@@ -140,6 +140,11 @@ void CThorCodeContextBase::getRowXML(size32_t & lenResult, char * & result, IOut
     convertRowToXML(lenResult, result, info, row, flags);
 }
 
+void CThorCodeContextBase::getRowJSON(size32_t & lenResult, char * & result, IOutputMetaData & info, const void * row, unsigned flags)
+{
+    convertRowToJSON(lenResult, result, info, row, flags);
+}
+
 const void * CThorCodeContextBase::fromXml(IEngineRowAllocator * rowAllocator, size32_t len, const char * utf8, IXmlToRowTransformer * xmlTransformer, bool stripWhitespace)
 {
     return createRowFromXml(rowAllocator, len, utf8, xmlTransformer, stripWhitespace);

+ 1 - 0
thorlcr/thorcodectx/thcodectx.hpp

@@ -113,6 +113,7 @@ public:
     virtual IEclGraphResults *resolveLocalQuery(__int64 gid);
     virtual IThorChildGraph * resolveChildQuery(__int64 activityId, IHThorArg * colocal);
     virtual void getRowXML(size32_t & lenResult, char * & result, IOutputMetaData & info, const void * row, unsigned flags);
+    virtual void getRowJSON(size32_t & lenResult, char * & result, IOutputMetaData & info, const void * row, unsigned flags);
     virtual IConstWUResult *getExternalResult(const char * wuid, const char *name, unsigned sequence) { throwUnexpected(); }
     virtual IConstWUResult *getResultForGet(const char *name, unsigned sequence) { throwUnexpected(); }
     virtual const void * fromXml(IEngineRowAllocator * rowAllocator, size32_t len, const char * utf8, IXmlToRowTransformer * xmlTransformer, bool stripWhitespace);