rtldynfield.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2016 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifndef rtldynfield_hpp
  14. #define rtldynfield_hpp
  15. #include "rtlfield.hpp"
  16. #include "rtlnewkey.hpp"
  17. //These classes support the dynamic creation of type and field information
  18. //-------------------------------------------------------------------------------------------------------------------
  19. /*
  20. * Used to represent the info that is needed to dynamically create an RtlTypeInfo object
  21. */
  22. struct ECLRTL_API FieldTypeInfoStruct
  23. {
  24. public:
  25. unsigned fieldType = 0;
  26. unsigned length = 0;
  27. const char *locale = nullptr;
  28. const char *className = nullptr;
  29. const RtlTypeInfo *childType = nullptr;
  30. const RtlFieldInfo * * fieldsArray = nullptr;
  31. const IFieldFilter * filter = nullptr;
  32. const RtlTypeInfo *createRtlTypeInfo() const;
  33. };
  34. interface ITypeInfo;
  35. /**
  36. * IRtlFieldTypeDeserializer is used to manage the creation of RtlTypeInfo structures dynamically.
  37. * All created structures are owned by the deserializer and will be destroyed when the deserializer is destroyed.
  38. */
  39. interface IRtlFieldTypeDeserializer : public IInterface
  40. {
  41. /*
  42. * Create RtlTypeInfo structures from a serialized json representation
  43. *
  44. * @param json The json representation
  45. * @return Deserialized RtlTypeInfo structure
  46. */
  47. virtual const RtlTypeInfo *deserialize(const char *json) = 0;
  48. /*
  49. * Create RtlTypeInfo structures from a serialized json representation
  50. *
  51. * @param jsonTree The json representation
  52. * @return Deserialized RtlTypeInfo structure
  53. */
  54. virtual const RtlTypeInfo *deserialize(IPropertyTree &jsonTree) = 0;
  55. /*
  56. * Create RtlTypeInfo structures from a serialized binary representation
  57. *
  58. * @param buf The binary representation
  59. * @return Deserialized RtlTypeInfo structure
  60. */
  61. virtual const RtlTypeInfo *deserialize(MemoryBuffer &buf) = 0;
  62. /*
  63. * Create a single RtlTypeInfo structure from a FieldTypeInfoStruct
  64. *
  65. * @param info The information used to create the type
  66. * @param key A unique pointer used to dedup typeinfo structures
  67. * @return RtlTypeInfo structure
  68. */
  69. virtual const RtlTypeInfo *addType(FieldTypeInfoStruct &info, const IInterface *typeOrIfblock) = 0;
  70. /*
  71. * Check if a type has already been created for a given key
  72. *
  73. * @param key A unique pointer used to dedup typeinfo structures
  74. * @return RtlTypeInfo structure, or nullptr if not yet created
  75. */
  76. virtual const RtlTypeInfo *lookupType(const IInterface *key) const = 0;
  77. /*
  78. * Create RtlFieldInfo structure as part of a RtlTypeInfo tree
  79. *
  80. * @param fieldName Field name
  81. * @param xpath XPath
  82. * @param type Field type
  83. * @param flags Field flags
  84. * @param init Field initializer, or nullptr
  85. * @return RtlFieldInfo structure. All strings will be owned by the deserializer object
  86. */
  87. virtual const RtlFieldInfo *addFieldInfo(const char *fieldName, const char *xpath, const RtlTypeInfo *type, unsigned flags, const char *init) = 0;
  88. };
  89. enum class RecordTranslationMode : byte
  90. {
  91. None = 0, // Never translate - throw an error if the ecl does not match published
  92. // All = 1, // Translate all fields. Not supported or used
  93. Payload = 2, // Translate all fields in datasets, and only payload fields in indexes
  94. AlwaysDisk = 3, // Always translate - even if wouldn't normally (e.g. csv/xml source read as binary), or crcs happen to match
  95. AlwaysECL = 4, // Ignore the published format - can make sense to force no translation e.g. when field names have changed
  96. Unspecified = 5
  97. }; // AlwaysDisk and AlwaysECL are for testing purposes only, and can only be set per file (not globally)
  98. extern ECLRTL_API RecordTranslationMode getTranslationMode(const char *modeStr, bool isLocal);
  99. extern ECLRTL_API const char *getTranslationModeText(RecordTranslationMode val);
  100. interface IDynamicRowIterator;
  101. interface IDynamicFieldValueFetcher : extends IInterface
  102. {
  103. virtual const byte *queryValue(unsigned fieldNum, size_t &sz) const = 0;
  104. virtual IDynamicRowIterator *getNestedIterator(unsigned fieldNum) const = 0;
  105. virtual size_t getSize(unsigned fieldNum) const = 0;
  106. virtual size32_t getRecordSize() const = 0;
  107. };
  108. interface IDynamicRowIterator : extends IIteratorOf<IDynamicFieldValueFetcher>
  109. {
  110. };
  111. interface IDynamicTransform : public IInterface
  112. {
  113. virtual void describe() const = 0;
  114. virtual size32_t translate(ARowBuilder &builder, IVirtualFieldCallback & callback, const byte *sourceRec) const = 0;
  115. virtual size32_t translate(ARowBuilder &builder, IVirtualFieldCallback & callback, const RtlRow &sourceRow) const = 0; // allows offsets to be reused if already calculated
  116. virtual size32_t translate(ARowBuilder &builder, IVirtualFieldCallback & callback, const IDynamicFieldValueFetcher & fetcher) const = 0; // called when reading from non binary e.g. xml/csv
  117. virtual bool canTranslate() const = 0;
  118. virtual bool needsTranslate() const = 0;
  119. virtual bool keyedTranslated() const = 0;
  120. virtual bool needsNonVirtualTranslate() const = 0;
  121. };
  122. interface IKeyTranslator : public IInterface
  123. {
  124. /*
  125. * Describe the operations of a translator to the log
  126. */
  127. virtual void describe() const = 0;
  128. /*
  129. * Translate the field numbers of a RowFilter array in-situ. An exception will be thrown if an
  130. * untranslatable field is encountered.
  131. *
  132. * @param filters The RowFilter array to be updated
  133. * @return Indicates whether any field numbers changed
  134. */
  135. virtual bool translate(RowFilter &filters) const = 0;
  136. /*
  137. * Translate the field numbers of a RowFilter array, creating a new RowFilter array. An exception will be thrown if an
  138. * untranslatable field is encountered.
  139. *
  140. * @param filters The input RowFilter array to be translated
  141. * @param result Updated to add translated versions of all the FieldFilters in the input
  142. * @return Indicates whether any field numbers changed
  143. */
  144. virtual bool translate(RowFilter &result, IConstArrayOf<IFieldFilter> &filters) const = 0;
  145. /*
  146. * Return whether any fields are translated by this translator
  147. */
  148. virtual bool needsTranslate() const = 0;
  149. };
  150. interface IDynamicTransformViaCallback : public IInterface
  151. {
  152. virtual void describe() const = 0;
  153. virtual size32_t translate(ARowBuilder &builder, IVirtualFieldCallback & callback, const void *sourceRec) const = 0;
  154. virtual bool canTranslate() const = 0;
  155. virtual bool needsTranslate() const = 0;
  156. virtual bool keyedTranslated() const = 0;
  157. virtual bool needsNonVirtualTranslate() const = 0;
  158. };
  159. extern ECLRTL_API const IDynamicTransform *createRecordTranslator(const RtlRecord &_destRecInfo, const RtlRecord &_srcRecInfo);
  160. extern ECLRTL_API const IDynamicTransform *createCloneVirtualRecordTranslator(const RtlRecord &_destRecInfo, IOutputMetaData & _source);
  161. extern ECLRTL_API const IDynamicTransform *createRecordTranslatorViaCallback(const RtlRecord &_destRecInfo, const RtlRecord &_srcRecInfo, type_vals rawType);
  162. extern ECLRTL_API void throwTranslationError(const RtlRecord &_destRecInfo, const RtlRecord &_srcRecInfo, const char * filename);
  163. extern ECLRTL_API const IKeyTranslator *createKeyTranslator(const RtlRecord &_destRecInfo, const RtlRecord &_srcRecInfo);
  164. extern ECLRTL_API IRtlFieldTypeDeserializer *createRtlFieldTypeDeserializer();
  165. extern ECLRTL_API StringBuffer &dumpTypeInfo(StringBuffer &ret, const RtlTypeInfo *t);
  166. extern ECLRTL_API bool dumpTypeInfo(MemoryBuffer &ret, const RtlTypeInfo *t);
  167. /**
  168. * Serialize metadata of supplied record to JSON, and return it to ECL caller as a string. Used for testing serializer.
  169. *
  170. */
  171. extern ECLRTL_API void dumpRecordType(size32_t & __lenResult, char * & __result, IOutputMetaData & metaVal);
  172. /**
  173. * Serialize metadata of supplied record to DATA.
  174. *
  175. */
  176. extern ECLRTL_API void serializeRecordType(size32_t & __lenResult, void * & __result, IOutputMetaData & metaVal);
  177. /**
  178. * Extract a field from a record via dynamic column number
  179. *
  180. */
  181. extern ECLRTL_API void getFieldVal(size32_t & __lenResult, char * & __result, int column, IOutputMetaData & metaVal, const byte *row);
  182. /**
  183. * Extract a column number from a record via dynamic fieldname
  184. *
  185. */
  186. extern ECLRTL_API int getFieldNum(const char *fieldName, IOutputMetaData & metaVal);
  187. extern ECLRTL_API IRowStream * transformRecord(IEngineRowAllocator * resultAllocator,IOutputMetaData & metaInput,IRowStream * input);
  188. //---------------------------------------------------------------------------------------------------------------------
  189. //Default implementations of the virtual field callbacks
  190. class ECLRTL_API NullVirtualFieldCallback : public CInterfaceOf<IVirtualFieldCallback>
  191. {
  192. public:
  193. virtual const char * queryLogicalFilename(const void * row) override;
  194. virtual unsigned __int64 getFilePosition(const void * row) override;
  195. virtual unsigned __int64 getLocalFilePosition(const void * row) override;
  196. virtual const byte * lookupBlob(unsigned __int64 id) override;
  197. };
  198. class ECLRTL_API UnexpectedVirtualFieldCallback : public CInterfaceOf<IVirtualFieldCallback>
  199. {
  200. public:
  201. virtual const char * queryLogicalFilename(const void * row) override;
  202. virtual unsigned __int64 getFilePosition(const void * row) override;
  203. virtual unsigned __int64 getLocalFilePosition(const void * row) override;
  204. virtual const byte * lookupBlob(unsigned __int64 id) override;
  205. };
  206. typedef UnexpectedVirtualFieldCallback IndexVirtualFieldCallback;
  207. //Backward compatibility implementation for fetch - only fileposition implemented. Revisit later when all working.
  208. class ECLRTL_API FetchVirtualFieldCallback : public UnexpectedVirtualFieldCallback
  209. {
  210. public:
  211. FetchVirtualFieldCallback(unsigned __int64 _filepos) : filepos(_filepos) {}
  212. virtual unsigned __int64 getFilePosition(const void * row) override;
  213. private:
  214. unsigned __int64 filepos;
  215. };
  216. class ECLRTL_API LocalVirtualFieldCallback : public CInterfaceOf<IVirtualFieldCallback>
  217. {
  218. public:
  219. LocalVirtualFieldCallback(const char * _filename, unsigned __int64 _filepos, unsigned __int64 _localfilepos)
  220. : filename(_filename), filepos(_filepos), localfilepos(_localfilepos) {}
  221. virtual const char * queryLogicalFilename(const void * row) override;
  222. virtual unsigned __int64 getFilePosition(const void * row) override;
  223. virtual unsigned __int64 getLocalFilePosition(const void * row) override;
  224. virtual const byte * lookupBlob(unsigned __int64 id) override;
  225. private:
  226. const char * filename;
  227. unsigned __int64 filepos;
  228. unsigned __int64 localfilepos;
  229. };
  230. #endif