HPCCFile.hpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2014 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 HPCCFILE_HPP_
  14. #define HPCCFILE_HPP_
  15. #include "ws_sql.hpp"
  16. #include "SQLColumn.hpp"
  17. #include "ws_sql_esp.ipp"
  18. #include "hqlerror.hpp"
  19. #include "hqlexpr.hpp"
  20. /* undef SOCKET definitions to avoid collision in Antlrdefs.h*/
  21. #ifdef INVALID_SOCKET
  22. //#pragma message( "UNDEFINING INVALID_SOCKET - Will be redefined by ANTLRDEFS.h" )
  23. #undef INVALID_SOCKET
  24. #endif
  25. #ifdef SOCKET
  26. //#pragma message( "UNDEFINING SOCKET - Will be redefined by ANTLRDEFS.h" )
  27. #undef SOCKET
  28. #endif
  29. #include "HPCCSQLLexer.h"
  30. #include "HPCCSQLParser.h"
  31. typedef enum _HPCCFileFormat
  32. {
  33. HPCCFileFormatUnknown=-1,
  34. HPCCFileFormatFlat,
  35. HPCCFileFormatCSV,
  36. HPCCFileFormatXML,
  37. HPCCFileFormatKey,
  38. HPCCFileFormatJSON,
  39. } HPCCFileFormat;
  40. class HPCCFile : public CInterface, public IInterface
  41. {
  42. public:
  43. static HPCCFileFormat DEFAULTFORMAT;
  44. IMPLEMENT_IINTERFACE;
  45. HPCCFile();
  46. virtual ~HPCCFile();
  47. const char * getCluster() const
  48. {
  49. return cluster.str();
  50. }
  51. void setCluster(const char * cluster)
  52. {
  53. this->cluster.set(cluster);
  54. }
  55. HPCCColumnMetaData * getColumn(const char * colname);
  56. IArrayOf<HPCCColumnMetaData> * getColumns()
  57. {
  58. return &columns;
  59. }
  60. const char * getEcl() const
  61. {
  62. return ecl;
  63. }
  64. bool setEcl(const char * ecl)
  65. {
  66. if (setFileColumns(ecl))
  67. this->ecl = ecl;
  68. else
  69. return false;
  70. return true;
  71. }
  72. static const char * formatToString(HPCCFileFormat format)
  73. {
  74. switch(format)
  75. {
  76. case HPCCFileFormatFlat:
  77. return "FLAT";
  78. case HPCCFileFormatCSV:
  79. return "CSV";
  80. case HPCCFileFormatXML:
  81. return "XML";
  82. case HPCCFileFormatKey:
  83. return "KEYED";
  84. case HPCCFileFormatJSON:
  85. return "JSON";
  86. case HPCCFileFormatUnknown:
  87. default:
  88. return "UNKNOWN";
  89. }
  90. }
  91. const char * getFormat() const
  92. {
  93. return formatToString(formatEnum);
  94. }
  95. static HPCCFileFormat formatStringToEnum(const char * formatstr)
  96. {
  97. if (!formatstr || !*formatstr)
  98. return HPCCFileFormatUnknown;
  99. else
  100. {
  101. StringBuffer toUpper(formatstr);
  102. toUpper.trim().toUpperCase();
  103. if (strcmp(toUpper.str(), "FLAT")==0)
  104. return HPCCFileFormatFlat;
  105. else if (strcmp(toUpper.str(), "UTF8N")==0)
  106. return HPCCFileFormatCSV;
  107. else if (strcmp(toUpper.str(), "CSV")==0)
  108. return HPCCFileFormatCSV;
  109. else if (strcmp(toUpper.str(), "XML")==0)
  110. return HPCCFileFormatXML;
  111. else if (strcmp(toUpper.str(), "KEY")==0)
  112. return HPCCFileFormatKey;
  113. else if (strcmp(toUpper.str(), "JSON")==0)
  114. return HPCCFileFormatJSON;
  115. else
  116. return HPCCFileFormatUnknown;
  117. }
  118. }
  119. void setFormat(const char * format)
  120. {
  121. HPCCFileFormat formatenum = formatStringToEnum(format);
  122. if (formatenum == HPCCFileFormatUnknown)
  123. this->formatEnum = DEFAULTFORMAT;
  124. else
  125. this->formatEnum = formatenum;
  126. }
  127. const char * getFullname() const
  128. {
  129. return fullname.str();
  130. }
  131. void setFullname(const char * fullname)
  132. {
  133. this->fullname.set(fullname);
  134. }
  135. bool isFileKeyed() const
  136. {
  137. return iskeyfile;
  138. }
  139. void setIsKeyedFile(bool iskeyfile)
  140. {
  141. this->iskeyfile = iskeyfile;
  142. }
  143. bool isFileSuper() const
  144. {
  145. return issuperfile;
  146. }
  147. void setIsSuperfile(bool issuperfile)
  148. {
  149. this->issuperfile = issuperfile;
  150. }
  151. const char * getName() const
  152. {
  153. return name.str();
  154. }
  155. void setName(const char * name)
  156. {
  157. this->name.set(name);
  158. }
  159. static bool validateFileName(const char * fullname);
  160. void setKeyedColumn(const char * name);
  161. bool getFileRecDefwithIndexpos(HPCCColumnMetaData * fieldMetaData, StringBuffer & out, const char * structname);
  162. bool getFileRecDef(StringBuffer & out, const char * structname, const char * linedelimiter = "\n", const char * recordindent = "\t");
  163. int getNonKeyedColumnsCount();
  164. int getKeyedColumnsCount();
  165. void getKeyedFieldsAsDelimitedString(char delim, const char * prefix, StringBuffer & out);
  166. void getNonKeyedFieldsAsDelmitedString(char delim, const char * prefix, StringBuffer & out);
  167. const char * getIdxFilePosField()
  168. {
  169. return idxFilePosField.length() > 0 ? idxFilePosField.str() : getLastNonKeyedNumericField();
  170. }
  171. bool hasValidIdxFilePosField()
  172. {
  173. const char * posfield = getIdxFilePosField();
  174. return (posfield && *posfield);
  175. }
  176. static HPCCFile * createHPCCFile();
  177. bool containsField(SQLColumn * field, bool verifyEclType) const;
  178. const char * getOwner() const
  179. {
  180. return owner.str();
  181. }
  182. void setOwner(const char * owner)
  183. {
  184. this->owner.set(owner);
  185. }
  186. const char* getDescription() const
  187. {
  188. return description.str();
  189. }
  190. void setDescription(const char* description)
  191. {
  192. if (description && *description)
  193. {
  194. this->description.set(description);
  195. const char * pos = strstr(description, "XDBC:RelIndexes");
  196. if (pos)
  197. {
  198. pos = pos + 15;//advance to end of "XDBC:RelIndexes"
  199. while(pos && *pos) //find the = char
  200. {
  201. if (!isspace(*pos))
  202. {
  203. if (*pos == '=' )
  204. {
  205. pos++;
  206. while(pos && *pos) //find the beginning bracket
  207. {
  208. if (!isspace(*pos))
  209. {
  210. if (*pos == '[' )
  211. {
  212. pos++;
  213. break;
  214. }
  215. else
  216. return;//found invalid char before [
  217. }
  218. pos++;
  219. }
  220. break;
  221. }
  222. else
  223. return;//found invalid char before = char
  224. }
  225. pos++;
  226. }
  227. if ( pos && *pos) //found keyword
  228. setRelatedIndexes(pos);
  229. }
  230. }
  231. }
  232. static bool parseOutRelatedIndexes(StringBuffer & description, StringBuffer & releatedIndexes)
  233. {
  234. if (description.length() > 0)
  235. {
  236. const char * head = strstr(description.str(), "XDBC:RelIndexes");
  237. if (head && *head)
  238. {
  239. const char * tail = strchr(head, ']');
  240. if (tail && *tail)
  241. {
  242. description.remove(head-description.str(), tail-description.str()).trim();
  243. return true;
  244. }
  245. }
  246. }
  247. return false;
  248. }
  249. void getRelatedIndexes(StringArray & indexes)
  250. {
  251. ForEachItemIn(c, relIndexFiles)
  252. {
  253. indexes.append(relIndexFiles.item(c));
  254. }
  255. }
  256. const char * getRelatedIndex(int relindexpos)
  257. {
  258. if (relindexpos > -1 && relindexpos < relIndexFiles.length())
  259. return relIndexFiles.item(relindexpos);
  260. else
  261. return NULL;
  262. }
  263. int getRelatedIndexCount()
  264. {
  265. return relIndexFiles.length();
  266. }
  267. /*
  268. tutorial::yn::peoplebyzipindex;
  269. Tutorial.IDX_PeopleByName;
  270. Tutorial.IDX_PeopleByPhonetic]
  271. */
  272. void setRelatedIndexes(const char * str)
  273. {
  274. StringBuffer index;
  275. while (str && *str)
  276. {
  277. if (!isspace(*str))
  278. {
  279. if (*str == ';' || *str == ']')
  280. {
  281. relIndexFiles.append(index.str());
  282. if (*str == ']')
  283. break;
  284. else
  285. index.clear();
  286. }
  287. else
  288. index.append(*str);
  289. }
  290. str++;
  291. }
  292. }
  293. void setIdxFilePosField(const char* idxfileposfieldname)
  294. {
  295. idxFilePosField.set(idxfileposfieldname);
  296. }
  297. bool containsNestedColumns() const
  298. {
  299. return hasNestedColumns;
  300. }
  301. void setHasNestedColumns(bool hasNestedColumns)
  302. {
  303. this->hasNestedColumns = hasNestedColumns;
  304. }
  305. private:
  306. void getFieldsAsDelmitedString(char delim, const char* prefix, StringBuffer& out, bool onlykeyed);
  307. bool setFileColumns(const char* eclString);
  308. void setKeyCounts();
  309. const char* getLastNonKeyedNumericField()
  310. {
  311. for (int i = columns.length() - 1;i >= 0;i--)
  312. {
  313. if (!columns.item(i).isKeyedField())
  314. return columns.item(i).getColumnName();
  315. }
  316. return NULL;
  317. }
  318. private:
  319. HPCCFileFormat formatEnum;
  320. StringBuffer name;
  321. StringBuffer fullname;
  322. StringBuffer cluster;
  323. StringBuffer idxFilePosField;
  324. bool iskeyfile;
  325. bool issuperfile;
  326. StringBuffer ecl;
  327. IArrayOf<HPCCColumnMetaData> columns;
  328. int keyedCount;
  329. int nonKeyedCount;
  330. bool hasNestedColumns;
  331. StringBuffer description;
  332. StringBuffer owner;
  333. StringArray relIndexFiles;
  334. }
  335. ;
  336. #endif /* HPCCFILE_HPP_ */