fvresultset.cpp 98 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 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. #include "platform.h"
  14. #include "jliball.hpp"
  15. #include "rtlbcd.hpp"
  16. #include "workunit.hpp"
  17. #include "seclib.hpp"
  18. #include "eclrtl.hpp"
  19. #include "fvresultset.ipp"
  20. #include "fileview.hpp"
  21. #include "fverror.hpp"
  22. #include "fvdatasource.hpp"
  23. #include "fvwusource.ipp"
  24. #include "fvresultset.ipp"
  25. #include "fvdisksource.ipp"
  26. #include "fvidxsource.ipp"
  27. #include "fvrelate.ipp"
  28. #include "dasess.hpp"
  29. #include "thorxmlwrite.hpp"
  30. #include "eclhelper.hpp"
  31. #define DEFAULT_FETCH_SIZE 100
  32. #define FILEVIEW_VERSION 1
  33. #define MAX_SORT_ELEMENTS 1000
  34. //#define PAGELOADED_WORKUNITS
  35. #define MAX_FILTER_ELEMENTS 20000
  36. #define MAX_SKIP_ELEMENTS 1000
  37. #define MAX_SKIP_TIME 10000 // 10 seconds, no match then give up
  38. CResultSetMetaData * nullMeta;
  39. ITypeInfo * filePositionType;
  40. MODULE_INIT(INIT_PRIORITY_STANDARD)
  41. {
  42. nullMeta = new CResultSetMetaData(NULL, false);
  43. filePositionType = makeIntType(8, false);
  44. return true;
  45. }
  46. MODULE_EXIT()
  47. {
  48. filePositionType->Release();
  49. nullMeta->Release();
  50. }
  51. //---------------------------------------------------------------------------
  52. IFvDataSource * createDataSource(IConstWUResult * wuResult, const char * wuid, const char * username, const char * password)
  53. {
  54. Owned<ADataSource> ds;
  55. SCMStringBuffer tempFilename;
  56. wuResult->getResultFilename(tempFilename);
  57. __int64 rowLimit = wuResult->getResultRowLimit();
  58. if (tempFilename.length())
  59. ds.setown(new WorkunitDiskDataSource(tempFilename.str(), wuResult, wuid, username, password));
  60. else if (rowLimit == -2)
  61. assertex(!"Delayed queries not yet supported");
  62. else if ((rowLimit == 0) && (wuResult->getResultTotalRowCount() == 0))
  63. ds.setown(new NullDataSource);
  64. #ifdef PAGELOADED_WORKUNITS
  65. else if (wuResult->getResultDataSize() < PAGED_WU_LIMIT)
  66. ds.setown(new FullWorkUnitDataSource(wuResult, wuid));
  67. else
  68. ds.setown(new PagedWorkUnitDataSource(wuResult, wuid));
  69. #else
  70. else
  71. ds.setown(new FullWorkUnitDataSource(wuResult, wuid));
  72. #endif
  73. if (ds && ds->init())
  74. return ds.getClear();
  75. return NULL;
  76. }
  77. IFvDataSource * createFileDataSource(const char * logicalName, const char * cluster, const char * username, const char * password)
  78. {
  79. Owned<IUserDescriptor> udesc;
  80. if(username != NULL && *username != '\0')
  81. {
  82. udesc.setown(createUserDescriptor());
  83. udesc->set(username, password);
  84. }
  85. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(logicalName, udesc.get());
  86. if (!df)
  87. throwError1(FVERR_CouldNotResolveX, logicalName);
  88. return createFileDataSource(df, logicalName, cluster, username, password);
  89. }
  90. IFvDataSource * createFileDataSource(IDistributedFile * df, const char * logicalName, const char * cluster, const char * username, const char * password)
  91. {
  92. bool blocked;
  93. if (df->isCompressed(&blocked) && !blocked)
  94. throwError1(FVERR_CompressedFile, logicalName);
  95. IPropertyTree & properties = df->queryAttributes();
  96. const char * format = properties.queryProp("@format");
  97. if (format && (stricmp(format,"csv")==0 || memicmp(format, "utf", 3) == 0))
  98. {
  99. Owned<ADataSource> ds = new DirectCsvDiskDataSource(df, format);
  100. if (ds && ds->init())
  101. return ds.getClear();
  102. return NULL;
  103. }
  104. const char * recordEcl = properties.queryProp("ECL");
  105. OwnedHqlExpr diskRecord;
  106. if (recordEcl)
  107. {
  108. diskRecord.setown(parseQuery(recordEcl));
  109. if (!diskRecord)
  110. throwError1(FVERR_BadRecordDesc, logicalName);
  111. }
  112. else
  113. {
  114. size32_t len = (size32_t)properties.getPropInt("@recordSize", 0);
  115. if (len)
  116. {
  117. VStringBuffer recordText("{ string%u contents };", len);
  118. diskRecord.setown(parseQuery(recordText));
  119. }
  120. if (!diskRecord)
  121. throwError1(FVERR_NoRecordDescription, logicalName);
  122. }
  123. Owned<ADataSource> ds;
  124. try
  125. {
  126. const char * kind = properties.queryProp("@kind");
  127. if (kind && (stricmp(kind, "key") == 0))
  128. {
  129. OwnedHqlExpr indexRecord = annotateIndexBlobs(diskRecord);
  130. if (isSimplifiedRecord(indexRecord, true))
  131. ds.setown(new IndexDataSource(logicalName, indexRecord, username, password));
  132. else
  133. throwError1(FVERR_ViewComplexKey, logicalName);
  134. }
  135. else if (isSimplifiedRecord(diskRecord, false))
  136. ds.setown(new DirectDiskDataSource(logicalName, diskRecord, username, password));
  137. else if (cluster)
  138. ds.setown(new TranslatedDiskDataSource(logicalName, diskRecord, cluster, username, password));
  139. else
  140. throwError1(FVERR_NeedClusterToBrowseX, logicalName);
  141. }
  142. catch (IException * e)
  143. {
  144. ds.setown(new FailureDataSource(diskRecord, e, false, 0));
  145. e->Release();
  146. }
  147. if (ds && ds->init())
  148. return ds.getClear();
  149. return NULL;
  150. }
  151. //---------------------------------------------------------------------------
  152. static __int64 getIntBias(unsigned size)
  153. {
  154. return I64C(1) << (size * 8 - 1);
  155. }
  156. static __int64 getIntFromSwapInt(ITypeInfo & type, const void * cur, bool isMappedIndexField);
  157. static __int64 getIntFromInt(ITypeInfo & type, const void * cur, bool isMappedIndexField)
  158. {
  159. #if __BYTE_ORDER == __LITTLE_ENDIAN
  160. if (isMappedIndexField) return getIntFromSwapInt(type, cur, isMappedIndexField);
  161. #endif
  162. unsigned size=type.getSize();
  163. bool isSigned = type.isSigned();
  164. if (isSigned && !isMappedIndexField)
  165. {
  166. switch (size)
  167. {
  168. case 1: return *((signed char *)cur);
  169. case 2: return *((short *)cur);
  170. case 3: return rtlReadInt3(cur);
  171. case 4: return *((int *)cur);
  172. case 5: return rtlReadInt5(cur);
  173. case 6: return rtlReadInt6(cur);
  174. case 7: return rtlReadInt7(cur);
  175. case 8: return *((__int64 *)cur);
  176. }
  177. }
  178. else
  179. {
  180. unsigned __int64 result;
  181. switch (size)
  182. {
  183. case 1: result = *((unsigned char *)cur); break;
  184. case 2: result = *((unsigned short *)cur); break;
  185. case 3: result = rtlReadUInt3(cur); break;
  186. case 4: result = *((unsigned int *)cur); break;
  187. case 5: result = rtlReadUInt5(cur); break;
  188. case 6: result = rtlReadUInt6(cur); break;
  189. case 7: result = rtlReadUInt7(cur); break;
  190. case 8: result = *((unsigned __int64 *)cur); break;
  191. default: UNIMPLEMENTED;
  192. }
  193. if (isSigned && isMappedIndexField)
  194. result -= getIntBias(size);
  195. return result;
  196. }
  197. UNIMPLEMENTED;
  198. }
  199. static __int64 getIntFromSwapInt(ITypeInfo & type, const void * cur, bool isMappedIndexField)
  200. {
  201. #if __BYTE_ORDER != __LITTLE_ENDIAN
  202. if (insideIndex) return getIntFromInt(type, cur, isMappedIndexField);
  203. #endif
  204. unsigned size = type.getSize();
  205. bool isSigned = type.isSigned();
  206. if (isSigned && !isMappedIndexField)
  207. {
  208. switch (size)
  209. {
  210. case 1: return *((signed char *)cur);
  211. case 2: return rtlRevInt2(cur);
  212. case 3: return rtlRevInt3(cur);
  213. case 4: return rtlRevInt4(cur);
  214. case 5: return rtlRevInt5(cur);
  215. case 6: return rtlRevInt6(cur);
  216. case 7: return rtlRevInt7(cur);
  217. case 8: return rtlRevInt8(cur);
  218. }
  219. }
  220. else
  221. {
  222. unsigned __int64 result;
  223. switch (size)
  224. {
  225. case 1: result = *((unsigned char *)cur); break;
  226. case 2: result = rtlRevUInt2(cur); break;
  227. case 3: result = rtlRevUInt3(cur); break;
  228. case 4: result = rtlRevUInt4(cur); break;
  229. case 5: result = rtlRevUInt5(cur); break;
  230. case 6: result = rtlRevUInt6(cur); break;
  231. case 7: result = rtlRevUInt7(cur); break;
  232. case 8: result = rtlRevUInt8(cur); break;
  233. default:
  234. throwUnexpected();
  235. }
  236. if (isSigned && isMappedIndexField)
  237. result -= getIntBias(size);
  238. return result;
  239. }
  240. UNIMPLEMENTED;
  241. }
  242. //---------------------------------------------------------------------------
  243. CResultSetMetaData::CResultSetMetaData(IFvDataSourceMetaData * _meta, bool _useXPath)
  244. {
  245. meta = _meta;
  246. fixedSize = true;
  247. alwaysUseXPath = _useXPath;
  248. unsigned max = meta ? meta->numColumns() : 0;
  249. for (unsigned idx = 0; idx < max; idx++)
  250. {
  251. ITypeInfo * type = meta->queryType(idx);
  252. CResultSetColumnInfo * column = new CResultSetColumnInfo;
  253. column->type = type;
  254. column->flag = meta->queryFieldFlags(idx);
  255. if (type->getSize() == UNKNOWN_LENGTH)
  256. fixedSize = false;
  257. switch (type->getTypeCode())
  258. {
  259. case type_void:
  260. case type_boolean:
  261. case type_int:
  262. case type_swapint:
  263. case type_decimal:
  264. case type_real:
  265. case type_data:
  266. case type_string:
  267. case type_varstring:
  268. case type_qstring:
  269. case type_unicode:
  270. case type_varunicode:
  271. case type_utf8:
  272. case type_packedint:
  273. column->childMeta.set(nullMeta);
  274. break;
  275. case type_set:
  276. case type_table:
  277. case type_groupedtable:
  278. column->childMeta.setown(new CResultSetMetaData(meta->queryChildMeta(idx), _useXPath));
  279. break;
  280. default:
  281. UNIMPLEMENTED;
  282. }
  283. columns.append(*column);
  284. }
  285. }
  286. CResultSetMetaData::CResultSetMetaData(const CResultSetMetaData & _other)
  287. {
  288. meta = _other.meta;
  289. alwaysUseXPath = _other.alwaysUseXPath;
  290. ForEachItemIn(i, _other.columns)
  291. columns.append(OLINK(_other.columns.item(i)));
  292. fixedSize = _other.fixedSize;
  293. }
  294. void CResultSetMetaData::calcFieldOffsets(const byte * data, unsigned * offsets) const
  295. {
  296. unsigned curOffset = 0;
  297. ForEachItemIn(idx, columns)
  298. {
  299. ITypeInfo & type = *columns.item(idx).type;
  300. unsigned size = type.getSize();
  301. if (size == UNKNOWN_LENGTH)
  302. {
  303. const byte * cur = data + curOffset;
  304. switch (type.getTypeCode())
  305. {
  306. case type_data:
  307. case type_string:
  308. case type_table:
  309. case type_groupedtable:
  310. size = *((unsigned *)cur) + sizeof(unsigned);
  311. break;
  312. case type_set:
  313. size = *((unsigned *)(cur + sizeof(bool))) + sizeof(unsigned) + sizeof(bool);
  314. break;
  315. case type_qstring:
  316. size = rtlQStrSize(*((unsigned *)cur)) + sizeof(unsigned);
  317. break;
  318. case type_unicode:
  319. size = *((unsigned *)cur)*sizeof(UChar) + sizeof(unsigned);
  320. break;
  321. case type_utf8:
  322. size = sizeof(unsigned) + rtlUtf8Size(*(unsigned *)cur, cur+sizeof(unsigned));
  323. break;
  324. case type_varstring:
  325. size = strlen((char *)cur)+1;
  326. break;
  327. case type_varunicode:
  328. size = (rtlUnicodeStrlen((UChar *)cur)+1)*sizeof(UChar);
  329. break;
  330. case type_packedint:
  331. size = rtlGetPackedSize(cur);
  332. break;
  333. default:
  334. UNIMPLEMENTED;
  335. }
  336. }
  337. offsets[idx] = curOffset;
  338. curOffset += size;
  339. }
  340. offsets[columns.ordinality()] = curOffset;
  341. }
  342. IResultSetMetaData * CResultSetMetaData::getChildMeta(int column) const
  343. {
  344. if (columns.isItem(column))
  345. return LINK(columns.item(column).childMeta);
  346. return NULL;
  347. }
  348. int CResultSetMetaData::getColumnCount() const
  349. {
  350. return columns.ordinality();
  351. }
  352. DisplayType CResultSetMetaData::getColumnDisplayType(int columnIndex) const
  353. {
  354. CResultSetColumnInfo & curColumn = columns.item(columnIndex);
  355. unsigned flag = curColumn.flag;
  356. switch (flag)
  357. {
  358. case FVFFbeginif:
  359. return TypeBeginIfBlock;
  360. case FVFFendif:
  361. return TypeEndIfBlock;
  362. case FVFFbeginrecord:
  363. return TypeBeginRecord;
  364. case FVFFendrecord:
  365. return TypeEndRecord;
  366. }
  367. ITypeInfo & type = *curColumn.type;
  368. switch (type.getTypeCode())
  369. {
  370. case type_boolean:
  371. return TypeBoolean;
  372. case type_int:
  373. case type_swapint:
  374. case type_packedint:
  375. if (type.isSigned())
  376. return TypeInteger;
  377. return TypeUnsignedInteger;
  378. case type_decimal:
  379. case type_real:
  380. return TypeReal;
  381. case type_qstring:
  382. case type_string:
  383. case type_varstring:
  384. return TypeString;
  385. case type_unicode:
  386. case type_varunicode:
  387. case type_utf8:
  388. return TypeUnicode;
  389. case type_data:
  390. return TypeData;
  391. case type_set:
  392. return TypeSet;
  393. case type_table:
  394. case type_groupedtable:
  395. return TypeDataset;
  396. }
  397. UNIMPLEMENTED; // Should have been translated to one of the above by this point...
  398. return TypeUnknown;
  399. }
  400. IStringVal & CResultSetMetaData::getColumnLabel(IStringVal & s, int column) const
  401. {
  402. assertex(columns.isItem(column));
  403. s.set(meta->queryName(column));
  404. return s;
  405. }
  406. IStringVal & CResultSetMetaData::getColumnEclType(IStringVal & s, int column) const
  407. {
  408. assertex(columns.isItem(column));
  409. StringBuffer str;
  410. s.set(columns.item(column).type->getECLType(str).str());
  411. return s;
  412. }
  413. IStringVal & CResultSetMetaData::getColumnXmlType(IStringVal & s, int column) const
  414. {
  415. //This really doesn't make any sense - only makes sense to get the entire schema because of the user-defined types
  416. UNIMPLEMENTED;
  417. }
  418. bool CResultSetMetaData::isSigned(int column) const
  419. {
  420. assertex(columns.isItem(column));
  421. return columns.item(column).type->isSigned();
  422. }
  423. bool CResultSetMetaData::isEBCDIC(int column) const
  424. {
  425. assertex(columns.isItem(column));
  426. ICharsetInfo * charset = columns.item(column).type->queryCharset();
  427. return (charset && charset->queryName() == ebcdicAtom);
  428. }
  429. bool CResultSetMetaData::isBigEndian(int column) const
  430. {
  431. assertex(columns.isItem(column));
  432. ITypeInfo * type = columns.item(column).type;
  433. #if __BYTE_ORDER == __LITTLE_ENDIAN
  434. return (type->getTypeCode() == type_swapint);
  435. #else
  436. return (type->getTypeCode() != type_swapint);
  437. #endif
  438. }
  439. unsigned CResultSetMetaData::getColumnRawType(int column) const
  440. {
  441. assertex(columns.isItem(column));
  442. return getClarionResultType(columns.item(column).type);
  443. }
  444. unsigned CResultSetMetaData::getColumnRawSize(int column) const
  445. {
  446. assertex(columns.isItem(column));
  447. unsigned size = columns.item(column).type->getSize();
  448. return (size == UNKNOWN_LENGTH) ? 0 : size;
  449. }
  450. unsigned CResultSetMetaData::getNumKeyedColumns() const
  451. {
  452. return meta->numKeyedColumns();
  453. }
  454. IStringVal & CResultSetMetaData::getNaturalColumnLabel(IStringVal & s, int columnIndex) const
  455. {
  456. assertex(columns.isItem(columnIndex));
  457. CResultSetColumnInfo & column = columns.item(columnIndex);
  458. s.set(column.naturalName);
  459. return s;
  460. }
  461. bool CResultSetMetaData::isVirtual(int columnIndex) const
  462. {
  463. assertex(columns.isItem(columnIndex));
  464. CResultSetColumnInfo & column = columns.item(columnIndex);
  465. return (column.flag == FVFFvirtual);
  466. }
  467. bool CResultSetMetaData::hasGetTranslation(int columnIndex) const
  468. {
  469. assertex(columns.isItem(columnIndex));
  470. CResultSetColumnInfo & column = columns.item(columnIndex);
  471. return (column.getTransforms.ordinality() != 0);
  472. }
  473. bool CResultSetMetaData::hasSetTranslation(int columnIndex) const
  474. {
  475. assertex(columns.isItem(columnIndex));
  476. CResultSetColumnInfo & column = columns.item(columnIndex);
  477. return (column.setTransforms.ordinality() != 0);
  478. }
  479. static bool findSize(int size, IntArray &sizes)
  480. {
  481. ForEachItemIn(idx, sizes)
  482. {
  483. if (sizes.item(idx)==size)
  484. return true;
  485. }
  486. return false;
  487. }
  488. unsigned CResultSetMetaData::queryColumnIndex(unsigned firstField, const char * fieldName) const
  489. {
  490. // DonKeep track of record depth, so we don't select fields from nested records..
  491. unsigned recordDepth = 0;
  492. unsigned max = columns.ordinality();
  493. for (unsigned idx =firstField; idx < max; idx++)
  494. {
  495. CResultSetColumnInfo & column = columns.item(idx);
  496. unsigned flag = column.flag;
  497. const char * name = meta->queryName(idx);
  498. if ((recordDepth == 0) && (name && stricmp(name, fieldName) == 0))
  499. return idx;
  500. switch (flag)
  501. {
  502. case FVFFbeginrecord:
  503. recordDepth++;
  504. break;
  505. case FVFFendrecord:
  506. if (recordDepth == 0)
  507. return NotFound;
  508. recordDepth--;
  509. break;
  510. }
  511. }
  512. return NotFound;
  513. }
  514. ITypeInfo * containsSingleSimpleFieldBlankXPath(IResultSetMetaData * meta)
  515. {
  516. if (meta->getColumnCount() != 1)
  517. return NULL;
  518. CResultSetMetaData * castMeta = static_cast<CResultSetMetaData *>(meta);
  519. const char * xpath = castMeta->queryXPath(0);
  520. if (xpath && (*xpath == 0))
  521. {
  522. return castMeta->queryType(0);
  523. }
  524. return NULL;
  525. }
  526. void fvSplitXPath(const char *xpath, StringBuffer &s, const char *&name, const char **childname=NULL)
  527. {
  528. if (!xpath)
  529. return;
  530. const char * slash = strchr(xpath, '/');
  531. if (!slash)
  532. {
  533. name = xpath;
  534. if (childname)
  535. *childname = NULL;
  536. }
  537. else
  538. {
  539. if (!childname || strchr(slash+1, '/')) //output ignores xpaths that are too deep
  540. return;
  541. name = s.clear().append(slash-xpath, xpath).str();
  542. *childname = slash+1;
  543. }
  544. }
  545. void CResultSetMetaData::getXmlSchema(ISchemaBuilder & builder, bool useXPath) const
  546. {
  547. StringBuffer xname;
  548. unsigned keyedCount = getNumKeyedColumns();
  549. ForEachItemIn(idx, columns)
  550. {
  551. CResultSetColumnInfo & column = columns.item(idx);
  552. unsigned flag = column.flag;
  553. const char * name = meta->queryName(idx);
  554. const char * childname = NULL;
  555. switch (flag)
  556. {
  557. case FVFFbeginif:
  558. builder.beginIfBlock();
  559. break;
  560. case FVFFendif:
  561. builder.endIfBlock();
  562. break;
  563. case FVFFbeginrecord:
  564. if (useXPath)
  565. fvSplitXPath(meta->queryXPath(idx), xname, name);
  566. builder.beginRecord(name, meta->mixedContent(idx), NULL);
  567. break;
  568. case FVFFendrecord:
  569. if (useXPath)
  570. fvSplitXPath(meta->queryXPath(idx), xname, name);
  571. builder.endRecord(name);
  572. break;
  573. case FVFFdataset:
  574. {
  575. childname = "Row";
  576. if (useXPath)
  577. fvSplitXPath(meta->queryXPath(idx), xname, name, &childname);
  578. ITypeInfo * singleFieldType = (useXPath && name && *name && childname && *childname) ? containsSingleSimpleFieldBlankXPath(column.childMeta.get()) : NULL;
  579. if (!singleFieldType || !builder.addSingleFieldDataset(name, childname, *singleFieldType))
  580. {
  581. const CResultSetMetaData *childMeta = static_cast<const CResultSetMetaData *>(column.childMeta.get());
  582. if (builder.beginDataset(name, childname, childMeta->meta->mixedContent(), NULL))
  583. {
  584. childMeta->getXmlSchema(builder, useXPath);
  585. }
  586. builder.endDataset(name, childname);
  587. }
  588. break;
  589. }
  590. case FVFFblob: //for now FileViewer will output the string "[blob]"
  591. {
  592. Owned<ITypeInfo> stringType = makeStringType(UNKNOWN_LENGTH, NULL, NULL);
  593. if (useXPath)
  594. fvSplitXPath(meta->queryXPath(idx), xname, name);
  595. builder.addField(name, *stringType, idx < keyedCount);
  596. }
  597. break;
  598. default:
  599. {
  600. ITypeInfo & type = *column.type;
  601. if (type.getTypeCode() == type_set)
  602. {
  603. childname = "Item";
  604. if (useXPath)
  605. fvSplitXPath(meta->queryXPath(idx), xname, name, &childname);
  606. builder.addSetField(name, childname, type);
  607. }
  608. else
  609. {
  610. if (useXPath)
  611. fvSplitXPath(meta->queryXPath(idx), xname, name);
  612. builder.addField(name, type, idx < keyedCount);
  613. }
  614. break;
  615. }
  616. }
  617. }
  618. }
  619. IStringVal & CResultSetMetaData::getXmlSchema(IStringVal & str, bool addHeader) const
  620. {
  621. XmlSchemaBuilder builder(addHeader);
  622. getXmlSchema(builder, alwaysUseXPath);
  623. builder.getXml(str);
  624. return str;
  625. }
  626. IStringVal & CResultSetMetaData::getXmlXPathSchema(IStringVal & str, bool addHeader) const
  627. {
  628. XmlSchemaBuilder builder(addHeader);
  629. getXmlSchema(builder, true);
  630. builder.getXml(str);
  631. return str;
  632. }
  633. //---------------------------------------------------------------------------
  634. IResultSetCursor * CResultSetBase::createCursor()
  635. {
  636. return doCreateCursor();
  637. }
  638. IResultSetCursor * CResultSetBase::createCursor(IDataVal & savedCursor)
  639. {
  640. MemoryBuffer buffer;
  641. buffer.append(savedCursor.length(), savedCursor.data());
  642. byte version;
  643. unsigned column;
  644. bool desc;
  645. buffer.read(version);
  646. buffer.read(column);
  647. if (column == (unsigned)-1)
  648. return new CResultSetCursor(getMeta(), this, buffer);
  649. buffer.read(desc);
  650. return new CResultSetSortedCursor(getMeta(), this, column, desc, buffer);
  651. }
  652. IFilteredResultSet * CResultSetBase::createFiltered()
  653. {
  654. return new CFilteredResultSetBuilder(this);
  655. }
  656. IResultSetCursor * CResultSetBase::createSortedCursor(unsigned column, bool descend)
  657. {
  658. if (getNumRows() > MAX_SORT_ELEMENTS)
  659. return NULL;
  660. return new CResultSetSortedCursor(getMeta(), this, column, descend);
  661. }
  662. CResultSetCursor * CResultSetBase::doCreateCursor()
  663. {
  664. return new CResultSetCursor(getMeta(), this);
  665. }
  666. //---------------------------------------------------------------------------
  667. CResultSet::CResultSet(IFvDataSource * _dataSource, bool _useXPath) : meta(_dataSource->queryMetaData(), _useXPath)
  668. {
  669. dataSource.set(_dataSource);
  670. if (dataSource->isIndex())
  671. calcMappedFields();
  672. }
  673. IExtendedNewResultSet * CResultSet::cloneForFilter()
  674. {
  675. Owned<IFvDataSource> clonedDataSource = dataSource->cloneForFilter();
  676. if (clonedDataSource)
  677. return new CResultSet(clonedDataSource, meta.alwaysUseXPath);
  678. return NULL;
  679. }
  680. void CResultSet::calcMappedFields()
  681. {
  682. //Work out which fields within an index record are mapped. It should be any numeric fields,
  683. //but not those within ifblocks or nested child records.... and not the fileposition
  684. unsigned max = getMetaData().getColumnCount();
  685. unsigned nesting = 0;
  686. for(unsigned i = 0; i < max; i++)
  687. {
  688. unsigned flag = meta.queryFlags(i);
  689. bool mapped = false;
  690. switch (flag)
  691. {
  692. case FVFFbeginif:
  693. case FVFFbeginrecord:
  694. nesting++;
  695. break;
  696. case FVFFendif:
  697. case FVFFendrecord:
  698. nesting--;
  699. break;
  700. default:
  701. if ((nesting == 0) && (i != max -1))
  702. {
  703. ITypeInfo * type = meta.queryType(i);
  704. switch (type->getTypeCode())
  705. {
  706. case type_int:
  707. case type_swapint:
  708. mapped = true;
  709. break;
  710. }
  711. }
  712. break;
  713. }
  714. mappedFields.append(mapped);
  715. }
  716. }
  717. int CResultSet::findColumn(const char * columnName) const
  718. {
  719. SCMStringBuffer s;
  720. for(int i = 0; i < getMetaData().getColumnCount(); i++)
  721. {
  722. s.clear();
  723. if(!stricmp(columnName, getMetaData().getColumnLabel(s, i).str()))
  724. return i;
  725. }
  726. return -1;
  727. }
  728. const IResultSetMetaData & CResultSet::getMetaData() const
  729. {
  730. return meta;
  731. }
  732. __int64 CResultSet::getNumRows() const
  733. {
  734. return dataSource->numRows();
  735. }
  736. void CResultSet::setColumnMapping(IDistributedFile * df)
  737. {
  738. StringBuffer mappingText;
  739. df->getColumnMapping(mappingText);
  740. if (mappingText.length())
  741. {
  742. FieldTransformInfoArray mappings;
  743. parseFileColumnMapping(mappings, mappingText.str(), meta);
  744. ForEachItemIn(i, mappings)
  745. {
  746. FieldTransformInfo & cur = mappings.item(i);
  747. CResultSetColumnInfo & column = meta.columns.item(cur.column);
  748. appendArray(column.getTransforms, cur.getTransforms);
  749. appendArray(column.setTransforms, cur.setTransforms);
  750. column.naturalName.setown(cur.naturalName.detach());
  751. }
  752. }
  753. }
  754. bool CResultSet::supportsRandomSeek() const
  755. {
  756. return meta.meta->supportsRandomSeek();
  757. }
  758. bool CResultSet::fetch(MemoryBuffer & out, __int64 offset)
  759. {
  760. CriticalBlock procedure(cs);
  761. return dataSource->fetchRow(out, offset);
  762. }
  763. bool CResultSet::fetchRaw(MemoryBuffer & out, __int64 offset)
  764. {
  765. CriticalBlock procedure(cs);
  766. return dataSource->fetchRawRow(out, offset);
  767. }
  768. bool CResultSet::getRow(MemoryBuffer & out, __int64 row)
  769. {
  770. CriticalBlock procedure(cs);
  771. return dataSource->getRow(out, row);
  772. }
  773. bool CResultSet::getRawRow(MemoryBuffer & out, __int64 row)
  774. {
  775. CriticalBlock procedure(cs);
  776. return dataSource->getRawRow(out, row);
  777. }
  778. bool CResultSet::isMappedIndexField(unsigned columnIndex)
  779. {
  780. return mappedFields.isItem(columnIndex) && mappedFields.item(columnIndex);
  781. }
  782. void CResultSet::serialize(MemoryBuffer & out)
  783. {
  784. out.append((byte)FILEVIEW_VERSION); // current version
  785. }
  786. //---------------------------------------------------------------------------
  787. CResultSetCursor::CResultSetCursor(const CResultSetMetaData & _meta, IExtendedNewResultSet * _resultSet) : meta(_meta)
  788. {
  789. init(_resultSet);
  790. absolute(BEFORE_FIRST_ROW);
  791. }
  792. CResultSetCursor::CResultSetCursor(const CResultSetMetaData & _meta, IExtendedNewResultSet * _resultSet, MemoryBuffer & buffer) : meta(_meta)
  793. {
  794. init(_resultSet);
  795. buffer.read(curRow);
  796. absolute(curRow);
  797. }
  798. CResultSetCursor::~CResultSetCursor()
  799. {
  800. resultSet->onClose();
  801. delete [] offsets;
  802. }
  803. void CResultSetCursor::init(IExtendedNewResultSet * _resultSet)
  804. {
  805. resultSet.set(_resultSet);
  806. offsets = new unsigned[meta.getColumnCount()+1];
  807. if (meta.isFixedSize())
  808. meta.calcFieldOffsets(NULL, offsets);
  809. resultSet->onOpen();
  810. }
  811. bool CResultSetCursor::absolute(__int64 row)
  812. {
  813. curRow = row;
  814. curRowData.clear();
  815. if ((row >= 0) && resultSet->getRow(curRowData, curRow))
  816. {
  817. if (!meta.isFixedSize())
  818. meta.calcFieldOffsets((const byte *)curRowData.toByteArray(), offsets);
  819. return true;
  820. }
  821. return false;
  822. }
  823. void CResultSetCursor::afterLast()
  824. {
  825. absolute(getNumRows()+1);
  826. curRowData.clear();
  827. }
  828. void CResultSetCursor::beforeFirst()
  829. {
  830. absolute(BEFORE_FIRST_ROW);
  831. curRowData.clear();
  832. }
  833. bool CResultSetCursor::fetch(__int64 offset)
  834. {
  835. curRow = AFTER_LAST_ROW;
  836. curRowData.clear();
  837. if (resultSet->fetch(curRowData, offset))
  838. {
  839. if (!meta.isFixedSize())
  840. meta.calcFieldOffsets((const byte *)curRowData.toByteArray(), offsets);
  841. return true;
  842. }
  843. return false;
  844. }
  845. bool CResultSetCursor::first()
  846. {
  847. return absolute(0);
  848. }
  849. static unsigned getLength(ITypeInfo & type, const byte * & cursor)
  850. {
  851. unsigned len = type.getStringLen();
  852. if (len != UNKNOWN_LENGTH)
  853. return len;
  854. len = *(unsigned *)cursor;
  855. cursor += sizeof(unsigned);
  856. return len;
  857. }
  858. bool CResultSetCursor::getBoolean(int columnIndex)
  859. {
  860. if (!isValid()) return false;
  861. const byte * cur = getColumn(columnIndex);
  862. ITypeInfo & type = *meta.columns.item(columnIndex).type;
  863. unsigned size = type.getSize();
  864. unsigned len = UNKNOWN_LENGTH; // error value
  865. switch (type.getTypeCode())
  866. {
  867. case type_void:
  868. case type_set:
  869. case type_table:
  870. case type_groupedtable:
  871. return false;
  872. case type_boolean:
  873. return *((byte *)cur) != 0;
  874. case type_int:
  875. case type_swapint:
  876. switch (size)
  877. {
  878. case 1:
  879. return *((byte *)cur) != 0;
  880. case 2:
  881. return *((short *)cur) != 0;
  882. case 4:
  883. return *((int *)cur) != 0;
  884. case 8:
  885. return *((__int64 *)cur) != 0;
  886. }
  887. break;
  888. case type_packedint:
  889. if (type.isSigned())
  890. return rtlGetPackedSigned(cur) != 0;
  891. else
  892. return rtlGetPackedUnsigned(cur) != 0;
  893. case type_decimal:
  894. if (type.isSigned())
  895. return Dec2Bool(size, cur);
  896. return UDec2Bool(size, cur);
  897. case type_real:
  898. if (size == 4)
  899. return *((float *)cur) != 0;
  900. return *((double *)cur) != 0;
  901. case type_string:
  902. len = getLength(type, cur);
  903. return rtlStrToBool(len, (const char *)cur);
  904. case type_unicode:
  905. len = getLength(type, cur);
  906. return rtlUnicodeToBool(len, (UChar const *)cur);
  907. case type_varstring:
  908. return rtlVStrToBool((const char *)cur);
  909. case type_varunicode:
  910. return rtlUnicodeToBool(rtlUnicodeStrlen((UChar const *)cur), (UChar const *)cur);
  911. case type_utf8:
  912. len = getLength(type, cur);
  913. return rtlUtf8ToBool(len, (const char *)cur);
  914. case type_qstring:
  915. len = getLength(type, cur);
  916. return rtlQStrToBool(len, (const char *)cur);
  917. case type_data:
  918. len = getLength(type, cur);
  919. return rtlDataToBool(len, cur);
  920. }
  921. UNIMPLEMENTED;
  922. return true;
  923. }
  924. IDataVal & CResultSetCursor::getBytes(IDataVal &d, int columnIndex)
  925. {
  926. if (isValid())
  927. d.setLen(getColumn(columnIndex), offsets[columnIndex+1]-offsets[columnIndex]);
  928. else
  929. d.setLen(NULL, 0);
  930. return d;
  931. }
  932. IResultSetCursor * CResultSetCursor::getChildren(int columnIndex) const
  933. {
  934. if (!isValid()) return NULL;
  935. ITypeInfo & type = *meta.columns.item(columnIndex).type;
  936. const byte * cur = getColumn(columnIndex);
  937. switch (type.getTypeCode())
  938. {
  939. case type_set:
  940. cur += sizeof(bool);
  941. break;
  942. case type_table:
  943. case type_groupedtable:
  944. break;
  945. default:
  946. return NULL;
  947. }
  948. unsigned len = *(unsigned *)cur;
  949. const byte * data = cur + sizeof(unsigned);
  950. Owned<IFvDataSource> childData = meta.meta->createChildDataSource(columnIndex, len, data);
  951. Owned<CResultSet> nestedResult = new CResultSet(childData, meta.alwaysUseXPath);
  952. return nestedResult->createCursor();
  953. }
  954. xdouble CResultSetCursor::getDouble(int columnIndex)
  955. {
  956. if (!isValid()) return 0.0;
  957. const byte * cur = getColumn(columnIndex);
  958. ITypeInfo & type = *meta.columns.item(columnIndex).type;
  959. unsigned size = type.getSize();
  960. unsigned len = UNKNOWN_LENGTH; // error value
  961. switch (type.getTypeCode())
  962. {
  963. case type_void:
  964. case type_set:
  965. case type_table:
  966. case type_groupedtable:
  967. return 0;
  968. case type_boolean:
  969. return *((byte *)cur) != 0;
  970. case type_int:
  971. if (type.isSigned())
  972. return (xdouble)getIntFromInt(type, cur, isMappedIndexField(columnIndex));
  973. return (xdouble)(__int64)getIntFromInt(type, cur, isMappedIndexField(columnIndex));
  974. case type_swapint:
  975. if (type.isSigned())
  976. return (xdouble)getIntFromSwapInt(type, cur, isMappedIndexField(columnIndex));
  977. return (xdouble)(__int64)getIntFromSwapInt(type, cur, isMappedIndexField(columnIndex));
  978. case type_packedint:
  979. if (type.isSigned())
  980. return (xdouble)rtlGetPackedSigned(cur);
  981. else
  982. return (xdouble)rtlGetPackedUnsigned(cur);
  983. case type_decimal:
  984. {
  985. DecLock();
  986. if (type.isSigned())
  987. DecPushDecimal(cur, type.getSize(), type.getPrecision());
  988. else
  989. DecPushUDecimal(cur, type.getSize(), type.getPrecision());
  990. xdouble ret = DecPopReal();
  991. DecUnlock();
  992. return ret;
  993. }
  994. case type_real:
  995. if (size == 4)
  996. return *((float *)cur);
  997. return *((double *)cur);
  998. case type_data:
  999. case type_string:
  1000. len = getLength(type, cur);
  1001. return rtlStrToReal(len, (const char *)cur);
  1002. case type_qstring:
  1003. {
  1004. len = getLength(type, cur);
  1005. unsigned newSize;
  1006. char * newStr;
  1007. rtlQStrToStrX(newSize, newStr, len, (const char *)cur);
  1008. double ret = rtlStrToReal(newSize, newStr);
  1009. rtlFree(newStr);
  1010. return ret;
  1011. }
  1012. case type_unicode:
  1013. len = getLength(type, cur);
  1014. return rtlUnicodeToReal(len, (UChar const *)cur);
  1015. case type_utf8:
  1016. len = getLength(type, cur);
  1017. return rtlUtf8ToReal(len, (const char *)cur);
  1018. case type_varstring:
  1019. return rtlVStrToReal((const char *)cur);
  1020. case type_varunicode:
  1021. return rtlUnicodeToReal(rtlUnicodeStrlen((UChar const *)cur), (UChar const *)cur);
  1022. }
  1023. UNIMPLEMENTED;
  1024. return 0.0;
  1025. }
  1026. int CResultSetCursor::getFetchSize() const
  1027. {
  1028. return DEFAULT_FETCH_SIZE;
  1029. }
  1030. __int64 CResultSetCursor::getInt(int columnIndex)
  1031. {
  1032. if (!isValid()) return 0;
  1033. const byte * cur = getColumn(columnIndex);
  1034. ITypeInfo & type = *meta.columns.item(columnIndex).type;
  1035. unsigned size = type.getSize();
  1036. unsigned len = UNKNOWN_LENGTH;
  1037. switch (type.getTypeCode())
  1038. {
  1039. case type_void:
  1040. case type_set:
  1041. case type_table:
  1042. case type_groupedtable:
  1043. return 0;
  1044. case type_boolean:
  1045. return *((byte *)cur) != 0;
  1046. case type_int:
  1047. return getIntFromInt(type, cur, isMappedIndexField(columnIndex));
  1048. case type_swapint:
  1049. return getIntFromSwapInt(type, cur, isMappedIndexField(columnIndex));
  1050. case type_packedint:
  1051. if (type.isSigned())
  1052. return rtlGetPackedSigned(cur);
  1053. else
  1054. return rtlGetPackedUnsigned(cur);
  1055. case type_decimal:
  1056. {
  1057. DecLock();
  1058. if (type.isSigned())
  1059. DecPushDecimal(cur, type.getSize(), type.getPrecision());
  1060. else
  1061. DecPushUDecimal(cur, type.getSize(), type.getPrecision());
  1062. __int64 ret = DecPopInt64();
  1063. DecUnlock();
  1064. return ret;
  1065. }
  1066. case type_real:
  1067. if (size == 4)
  1068. return (__int64) *((float *)cur);
  1069. return (__int64) *((double *)cur);
  1070. case type_data:
  1071. case type_string:
  1072. len = getLength(type, cur);
  1073. return rtlStrToInt8(len, (const char *)cur);
  1074. case type_qstring:
  1075. {
  1076. unsigned newSize;
  1077. char * newStr;
  1078. len = getLength(type, cur);
  1079. rtlQStrToStrX(newSize, newStr, len, (const char *)cur);
  1080. __int64 ret = rtlStrToInt8(newSize, newStr);
  1081. rtlFree(newStr);
  1082. return ret;
  1083. }
  1084. case type_unicode:
  1085. len = getLength(type, cur);
  1086. return rtlUnicodeToInt8(len, (UChar const *)cur);
  1087. case type_utf8:
  1088. len = getLength(type, cur);
  1089. return rtlUtf8ToInt(len, (const char *)cur);
  1090. case type_varstring:
  1091. return rtlVStrToInt8((const char *)cur);
  1092. case type_varunicode:
  1093. return rtlUnicodeToInt8(rtlUnicodeStrlen((UChar const *)cur), (UChar const *)cur);
  1094. }
  1095. UNIMPLEMENTED;
  1096. return 0;
  1097. }
  1098. bool CResultSetCursor::getIsAll(int columnIndex) const
  1099. {
  1100. if (!isValid()) return false;
  1101. ITypeInfo & type = *meta.columns.item(columnIndex).type;
  1102. if (type.getTypeCode() != type_set)
  1103. return false;
  1104. const byte * cur = getColumn(columnIndex);
  1105. return *(bool *)cur;
  1106. }
  1107. int CResultSetCursor::getType()
  1108. {
  1109. if (getNumRows() != UNKNOWN_NUM_ROWS)
  1110. return TYPE_SCROLL_INSENSITIVE;
  1111. return TYPE_FORWARD_ONLY;
  1112. }
  1113. const IResultSetMetaData & CResultSetCursor::getMetaData() const
  1114. {
  1115. return meta;
  1116. }
  1117. __int64 CResultSetCursor::getCurRow() const
  1118. {
  1119. return curRow;
  1120. }
  1121. __int64 CResultSetCursor::getNumRows() const
  1122. {
  1123. return resultSet->getNumRows();
  1124. }
  1125. IDataVal & CResultSetCursor::getRaw(IDataVal &d, int columnIndex)
  1126. {
  1127. //MORE: This should work on the raw data!
  1128. return getBytes(d, columnIndex);
  1129. }
  1130. IDataVal & CResultSetCursor::getRawRow(IDataVal &d)
  1131. {
  1132. MemoryBuffer temp;
  1133. if (resultSet->getRawRow(temp, curRow))
  1134. d.setLen(temp.toByteArray(), temp.length());
  1135. return d;
  1136. }
  1137. __int64 CResultSetCursor::translateRow(__int64 row) const
  1138. {
  1139. return row;
  1140. }
  1141. IStringVal & CResultSetCursor::getString(IStringVal & ret, int columnIndex)
  1142. {
  1143. if (!isValid())
  1144. {
  1145. ret.set("");
  1146. return ret;
  1147. }
  1148. const byte * cur = getColumn(columnIndex);
  1149. unsigned resultLen;
  1150. char * resultStr = NULL;
  1151. ITypeInfo & type = *meta.columns.item(columnIndex).type;
  1152. unsigned size = type.getSize();
  1153. unsigned len;
  1154. switch (type.getTypeCode())
  1155. {
  1156. case type_void:
  1157. case type_set:
  1158. case type_table:
  1159. case type_groupedtable:
  1160. ret.set("");
  1161. break;
  1162. case type_boolean:
  1163. if (*((byte *)cur) != 0)
  1164. ret.set("1");
  1165. else
  1166. ret.set("");
  1167. break;
  1168. case type_int:
  1169. {
  1170. __int64 value = getIntFromInt(type, cur, isMappedIndexField(columnIndex));
  1171. if (type.isSigned())
  1172. rtlInt8ToStrX(resultLen, resultStr, value);
  1173. else
  1174. rtlUInt8ToStrX(resultLen, resultStr, (unsigned __int64) value);
  1175. ret.setLen(resultStr, resultLen);
  1176. break;
  1177. }
  1178. case type_swapint:
  1179. {
  1180. __int64 value = getIntFromSwapInt(type, cur, isMappedIndexField(columnIndex));
  1181. if (type.isSigned())
  1182. rtlInt8ToStrX(resultLen, resultStr, value);
  1183. else
  1184. rtlUInt8ToStrX(resultLen, resultStr, (unsigned __int64) value);
  1185. ret.setLen(resultStr, resultLen);
  1186. break;
  1187. }
  1188. case type_packedint:
  1189. {
  1190. if (type.isSigned())
  1191. rtlInt8ToStrX(resultLen, resultStr, rtlGetPackedSigned(cur));
  1192. else
  1193. rtlUInt8ToStrX(resultLen, resultStr, rtlGetPackedUnsigned(cur));
  1194. ret.setLen(resultStr, resultLen);
  1195. break;
  1196. }
  1197. case type_decimal:
  1198. {
  1199. DecLock();
  1200. if (type.isSigned())
  1201. DecPushDecimal(cur, type.getSize(), type.getPrecision());
  1202. else
  1203. DecPushUDecimal(cur, type.getSize(), type.getPrecision());
  1204. DecPopStringX(resultLen, resultStr);
  1205. DecUnlock();
  1206. ret.setLen(resultStr, resultLen);
  1207. return ret;
  1208. }
  1209. case type_real:
  1210. if (size == 4)
  1211. rtlRealToStrX(resultLen, resultStr, *(float *)cur);
  1212. else
  1213. rtlRealToStrX(resultLen, resultStr, *(double *)cur);
  1214. ret.setLen(resultStr, resultLen);
  1215. break;
  1216. case type_qstring:
  1217. len = getLength(type, cur);
  1218. rtlQStrToStrX(resultLen, resultStr, len, (const char *)cur);
  1219. ret.setLen(resultStr, resultLen);
  1220. break;
  1221. case type_data:
  1222. case type_string:
  1223. len = getLength(type, cur);
  1224. ret.setLen((const char *)cur, len);
  1225. break;
  1226. case type_unicode:
  1227. len = getLength(type, cur);
  1228. rtlUnicodeToStrX(resultLen, resultStr, len, (UChar const *)cur);
  1229. ret.setLen(resultStr, resultLen);
  1230. break;
  1231. case type_utf8:
  1232. len = getLength(type, cur);
  1233. rtlUtf8ToStrX(resultLen, resultStr, len, (const char *)cur);
  1234. ret.setLen(resultStr, resultLen);
  1235. break;
  1236. case type_varstring:
  1237. ret.set((const char *)cur);
  1238. break;
  1239. case type_varunicode:
  1240. rtlUnicodeToStrX(resultLen, resultStr, rtlUnicodeStrlen((UChar const *)cur), (UChar const *)cur);
  1241. ret.setLen(resultStr, resultLen);
  1242. break;
  1243. default:
  1244. UNIMPLEMENTED;
  1245. }
  1246. free(resultStr);
  1247. return ret;
  1248. }
  1249. IStringVal & CResultSetCursor::getDisplayText(IStringVal &ret, int columnIndex)
  1250. {
  1251. if (!isValid())
  1252. {
  1253. ret.set("");
  1254. return ret;
  1255. }
  1256. CResultSetColumnInfo & column = meta.columns.item(columnIndex);
  1257. unsigned flags = column.flag;
  1258. switch (flags)
  1259. {
  1260. case FVFFbeginif:
  1261. case FVFFendif:
  1262. case FVFFbeginrecord:
  1263. case FVFFendrecord:
  1264. case FVFFdataset:
  1265. case FVFFset:
  1266. ret.set("");
  1267. return ret;
  1268. }
  1269. const byte * cur = getColumn(columnIndex);
  1270. unsigned resultLen;
  1271. char * resultStr = NULL;
  1272. ITypeInfo & type = *column.type;
  1273. unsigned size = type.getSize();
  1274. unsigned len = UNKNOWN_LENGTH;
  1275. switch (type.getTypeCode())
  1276. {
  1277. case type_boolean:
  1278. if (*((byte *)cur) != 0)
  1279. ret.set("true");
  1280. else
  1281. ret.set("false");
  1282. break;
  1283. case type_int:
  1284. {
  1285. __int64 value = getIntFromInt(type, cur, isMappedIndexField(columnIndex));
  1286. if (type.isSigned())
  1287. rtlInt8ToStrX(resultLen, resultStr, value);
  1288. else
  1289. rtlUInt8ToStrX(resultLen, resultStr, (unsigned __int64) value);
  1290. ret.setLen(resultStr, resultLen);
  1291. break;
  1292. }
  1293. case type_swapint:
  1294. {
  1295. __int64 value = getIntFromSwapInt(type, cur, isMappedIndexField(columnIndex));
  1296. if (type.isSigned())
  1297. rtlInt8ToStrX(resultLen, resultStr, value);
  1298. else
  1299. rtlUInt8ToStrX(resultLen, resultStr, (unsigned __int64) value);
  1300. ret.setLen(resultStr, resultLen);
  1301. break;
  1302. }
  1303. case type_packedint:
  1304. {
  1305. if (type.isSigned())
  1306. rtlInt8ToStrX(resultLen, resultStr, rtlGetPackedSigned(cur));
  1307. else
  1308. rtlUInt8ToStrX(resultLen, resultStr, rtlGetPackedUnsigned(cur));
  1309. ret.setLen(resultStr, resultLen);
  1310. break;
  1311. }
  1312. case type_decimal:
  1313. {
  1314. DecLock();
  1315. if (type.isSigned())
  1316. DecPushDecimal(cur, type.getSize(), type.getPrecision());
  1317. else
  1318. DecPushUDecimal(cur, type.getSize(), type.getPrecision());
  1319. DecPopStringX(resultLen, resultStr);
  1320. DecUnlock();
  1321. ret.setLen(resultStr, resultLen);
  1322. return ret;
  1323. }
  1324. case type_real:
  1325. if (size == 4)
  1326. rtlRealToStrX(resultLen, resultStr, *(float *)cur);
  1327. else
  1328. rtlRealToStrX(resultLen, resultStr, *(double *)cur);
  1329. ret.setLen(resultStr, resultLen);
  1330. break;
  1331. case type_qstring:
  1332. len = getLength(type, cur);
  1333. rtlQStrToStrX(resultLen, resultStr, len, (const char *)cur);
  1334. ret.setLen(resultStr, resultLen);
  1335. break;
  1336. case type_data:
  1337. {
  1338. len = getLength(type, cur);
  1339. StringBuffer temp;
  1340. while (len--)
  1341. temp.appendhex(*cur++, true);
  1342. ret.setLen(temp.str(), temp.length());
  1343. break;
  1344. }
  1345. case type_string:
  1346. {
  1347. len = getLength(type, cur);
  1348. rtlStrToUtf8X(resultLen, resultStr, len , (const char *)cur);
  1349. ret.setLen(resultStr, rtlUtf8Size(resultLen, resultStr));
  1350. break;
  1351. }
  1352. case type_unicode:
  1353. len = getLength(type, cur);
  1354. rtlUnicodeToUtf8X(resultLen, resultStr, len, (UChar const *)cur);
  1355. ret.setLen(resultStr, rtlUtf8Size(resultLen, resultStr));
  1356. break;
  1357. case type_utf8:
  1358. len = getLength(type, cur);
  1359. ret.setLen((const char *)cur, rtlUtf8Size(len, cur));
  1360. break;
  1361. case type_varstring:
  1362. ret.set((const char *)cur);
  1363. break;
  1364. case type_varunicode:
  1365. rtlUnicodeToCodepageX(resultLen, resultStr, rtlUnicodeStrlen((UChar const *)cur), (UChar const *)cur, "UTF-8");
  1366. ret.setLen(resultStr, resultLen);
  1367. break;
  1368. default:
  1369. UNIMPLEMENTED;
  1370. }
  1371. rtlFree(resultStr);
  1372. return ret;
  1373. }
  1374. void CResultSetCursor::writeXmlText(IXmlWriter &writer, int columnIndex, const char *tag)
  1375. {
  1376. if (!isValid())
  1377. return;
  1378. const char * name = (tag) ? tag : meta.meta->queryXmlTag(columnIndex);
  1379. CResultSetColumnInfo & column = meta.columns.item(columnIndex);
  1380. unsigned flags = column.flag;
  1381. switch (flags)
  1382. {
  1383. case FVFFblob:
  1384. writer.outputCString("[blob]", name);
  1385. return;
  1386. case FVFFbeginif:
  1387. case FVFFendif:
  1388. return;
  1389. case FVFFbeginrecord:
  1390. {
  1391. if (name && *name)
  1392. {
  1393. writer.outputBeginNested(name, false);
  1394. const IntArray &attributes = meta.meta->queryAttrList(columnIndex);
  1395. ForEachItemIn(ac, attributes)
  1396. writeXmlText(writer, attributes.item(ac), NULL);
  1397. }
  1398. }
  1399. return;
  1400. case FVFFendrecord:
  1401. if (name && *name)
  1402. writer.outputEndNested(name);
  1403. return;
  1404. }
  1405. const byte * cur = getColumn(columnIndex);
  1406. unsigned resultLen;
  1407. char * resultStr = NULL;
  1408. ITypeInfo & type = *column.type;
  1409. unsigned size = type.getSize();
  1410. unsigned len = UNKNOWN_LENGTH;
  1411. switch (type.getTypeCode())
  1412. {
  1413. case type_boolean:
  1414. writer.outputBool(*((byte *)cur) != 0, name);
  1415. break;
  1416. case type_int:
  1417. {
  1418. __int64 value = getIntFromInt(type, cur, isMappedIndexField(columnIndex));
  1419. if (type.isSigned())
  1420. writer.outputInt((__int64) value, type.getSize(), name);
  1421. else
  1422. writer.outputUInt((unsigned __int64) value, type.getSize(), name);
  1423. break;
  1424. }
  1425. case type_swapint:
  1426. {
  1427. __int64 value = getIntFromSwapInt(type, cur, isMappedIndexField(columnIndex));
  1428. if (type.isSigned())
  1429. writer.outputInt((__int64) value, type.getSize(), name);
  1430. else
  1431. writer.outputUInt((unsigned __int64) value, type.getSize(), name);
  1432. break;
  1433. }
  1434. case type_packedint:
  1435. {
  1436. if (type.isSigned())
  1437. writer.outputInt(rtlGetPackedSigned(cur), type.getSize(), name);
  1438. else
  1439. writer.outputUInt(rtlGetPackedUnsigned(cur), type.getSize(), name);
  1440. break;
  1441. }
  1442. case type_decimal:
  1443. if (type.isSigned())
  1444. writer.outputDecimal(cur, size, type.getPrecision(), name);
  1445. else
  1446. writer.outputUDecimal(cur, size, type.getPrecision(), name);
  1447. break;
  1448. case type_real:
  1449. if (size == 4)
  1450. writer.outputReal(*(float *)cur, name);
  1451. else
  1452. writer.outputReal(*(double *)cur, name);
  1453. break;
  1454. case type_qstring:
  1455. len = getLength(type, cur);
  1456. rtlQStrToStrX(resultLen, resultStr, len, (const char *)cur);
  1457. writer.outputString(resultLen, resultStr, name);
  1458. break;
  1459. case type_data:
  1460. len = getLength(type, cur);
  1461. writer.outputData(len, cur, name);
  1462. break;
  1463. case type_string:
  1464. len = getLength(type, cur);
  1465. if (meta.isEBCDIC(columnIndex))
  1466. {
  1467. rtlEStrToStrX(resultLen, resultStr, len, (const char *)cur);
  1468. writer.outputString(resultLen, resultStr, name);
  1469. }
  1470. else
  1471. writer.outputString(len, (const char *)cur, name);
  1472. break;
  1473. case type_unicode:
  1474. len = getLength(type, cur);
  1475. writer.outputUnicode(len, (UChar const *)cur, name);
  1476. break;
  1477. case type_varstring:
  1478. if (meta.isEBCDIC(columnIndex))
  1479. {
  1480. rtlStrToEStrX(resultLen, resultStr, strlen((const char *)cur), (const char *)cur);
  1481. writer.outputString(resultLen, resultStr, name);
  1482. }
  1483. else
  1484. writer.outputString(strlen((const char *)cur), (const char *)cur, name);
  1485. break;
  1486. case type_varunicode:
  1487. writer.outputUnicode(rtlUnicodeStrlen((UChar const *)cur), (UChar const *)cur, name);
  1488. break;
  1489. case type_utf8:
  1490. len = getLength(type, cur);
  1491. writer.outputUtf8(len, (const char *)cur, name);
  1492. break;
  1493. case type_table:
  1494. case type_groupedtable:
  1495. {
  1496. writer.outputBeginNested(name, false);
  1497. Owned<IResultSetCursor> childCursor = getChildren(columnIndex);
  1498. childCursor->beginWriteXmlRows(writer);
  1499. ForEach(*childCursor)
  1500. childCursor->writeXmlRow(writer);
  1501. childCursor->endWriteXmlRows(writer);
  1502. writer.outputEndNested(name);
  1503. }
  1504. break;
  1505. case type_set:
  1506. {
  1507. writer.outputBeginNested(name, false);
  1508. if (getIsAll(columnIndex))
  1509. writer.outputSetAll();
  1510. else
  1511. {
  1512. Owned<IResultSetCursor> childCursor = getChildren(columnIndex);
  1513. childCursor->beginWriteXmlRows(writer);
  1514. ForEach(*childCursor)
  1515. childCursor->writeXmlItem(writer);
  1516. childCursor->endWriteXmlRows(writer);
  1517. }
  1518. writer.outputEndNested(name);
  1519. }
  1520. break;
  1521. default:
  1522. UNIMPLEMENTED;
  1523. }
  1524. rtlFree(resultStr);
  1525. }
  1526. IStringVal & CResultSetCursor::getXml(IStringVal &ret, int columnIndex)
  1527. {
  1528. Owned<CommonXmlWriter> writer = CreateCommonXmlWriter(XWFexpandempty);
  1529. writeXmlText(*writer, columnIndex);
  1530. ret.set(writer->str());
  1531. return ret;
  1532. }
  1533. IStringVal & CResultSetCursor::getXmlItem(IStringVal & ret)
  1534. {
  1535. Owned<CommonXmlWriter> writer = CreateCommonXmlWriter(XWFexpandempty);
  1536. writeXmlText(*writer, 0, meta.meta->queryXmlTag());
  1537. ret.set(writer->str());
  1538. return ret;
  1539. }
  1540. void CResultSetCursor::writeXmlItem(IXmlWriter &writer)
  1541. {
  1542. writeXmlText(writer, 0, meta.meta->queryXmlTag());
  1543. }
  1544. IStringVal & CResultSetCursor::getXmlRow(IStringVal &ret)
  1545. {
  1546. Owned<CommonXmlWriter> writer = CreateCommonXmlWriter(XWFexpandempty);
  1547. writeXmlRow(*writer);
  1548. ret.set(writer->str());
  1549. return ret;
  1550. }
  1551. void CResultSetCursor::beginWriteXmlRows(IXmlWriter & writer)
  1552. {
  1553. const char *rowtag = meta.meta->queryXmlTag();
  1554. if (rowtag && *rowtag)
  1555. writer.outputBeginArray(rowtag);
  1556. }
  1557. void CResultSetCursor::endWriteXmlRows(IXmlWriter & writer)
  1558. {
  1559. const char *rowtag = meta.meta->queryXmlTag();
  1560. if (rowtag && *rowtag)
  1561. writer.outputEndArray(rowtag);
  1562. }
  1563. void CResultSetCursor::writeXmlRow(IXmlWriter &writer)
  1564. {
  1565. StringBuffer temp;
  1566. const char *rowtag = meta.meta->queryXmlTag();
  1567. if (rowtag && *rowtag)
  1568. {
  1569. writer.outputBeginNested(rowtag, false);
  1570. const IntArray &attributes = meta.meta->queryAttrList();
  1571. ForEachItemIn(ac, attributes)
  1572. writeXmlText(writer, attributes.item(ac), NULL);
  1573. }
  1574. unsigned numColumns = meta.getColumnCount();
  1575. unsigned ignoreNesting = 0;
  1576. for (unsigned col = 0; col < numColumns; col++)
  1577. {
  1578. unsigned flags = meta.columns.item(col).flag;
  1579. const char *tag = meta.meta->queryXmlTag(col);
  1580. if (tag && *tag=='@')
  1581. continue;
  1582. switch (flags)
  1583. {
  1584. case FVFFbeginif:
  1585. if (ignoreNesting || !getBoolean(col))
  1586. ignoreNesting++;
  1587. break;
  1588. case FVFFendif:
  1589. if (ignoreNesting)
  1590. ignoreNesting--;
  1591. break;
  1592. case FVFFbeginrecord:
  1593. if (ignoreNesting)
  1594. ignoreNesting++;
  1595. else
  1596. writeXmlText(writer, col);
  1597. break;
  1598. case FVFFendrecord:
  1599. if (ignoreNesting)
  1600. ignoreNesting--;
  1601. else
  1602. writeXmlText(writer, col);
  1603. break;
  1604. case FVFFnone:
  1605. case FVFFvirtual:
  1606. case FVFFdataset:
  1607. case FVFFset:
  1608. case FVFFblob:
  1609. if (ignoreNesting == 0)
  1610. writeXmlText(writer, col);
  1611. break;
  1612. }
  1613. }
  1614. assertex(ignoreNesting == 0);
  1615. writer.outputEndNested(rowtag);
  1616. }
  1617. bool CResultSetCursor::isAfterLast() const
  1618. {
  1619. return (curRowData.length() == 0) && (getCurRow() != BEFORE_FIRST_ROW);
  1620. }
  1621. bool CResultSetCursor::isBeforeFirst() const
  1622. {
  1623. return getCurRow() == BEFORE_FIRST_ROW;
  1624. }
  1625. bool CResultSetCursor::isFirst() const
  1626. {
  1627. return (getCurRow() == 0);
  1628. }
  1629. bool CResultSetCursor::isLast() const
  1630. {
  1631. if (curRowData.length() == 0)
  1632. return false;
  1633. __int64 numRows = getNumRows();
  1634. if (numRows != UNKNOWN_NUM_ROWS)
  1635. return getCurRow() == numRows+1;
  1636. MemoryBuffer temp;
  1637. return !resultSet->getRow(temp, translateRow(getCurRow()+1));
  1638. }
  1639. bool CResultSetCursor::isValid() const
  1640. {
  1641. return (curRowData.length() != 0);
  1642. }
  1643. bool CResultSetCursor::isNull(int columnIndex) const
  1644. {
  1645. //MORE: There needs to be some projected extra field to
  1646. return false;
  1647. }
  1648. bool CResultSetCursor::last()
  1649. {
  1650. return absolute(getNumRows()-1);
  1651. }
  1652. bool CResultSetCursor::next()
  1653. {
  1654. return absolute(getCurRow()+1);
  1655. }
  1656. bool CResultSetCursor::previous()
  1657. {
  1658. return absolute(getCurRow()-1);
  1659. }
  1660. bool CResultSetCursor::relative(__int64 rows)
  1661. {
  1662. if (getCurRow() + rows < 0)
  1663. {
  1664. beforeFirst();
  1665. return false;
  1666. }
  1667. else
  1668. return absolute (getCurRow() + rows);
  1669. }
  1670. void CResultSetCursor::serialize(IDataVal & d)
  1671. {
  1672. MemoryBuffer buffer;
  1673. resultSet->serialize(buffer);
  1674. serializeType(buffer);
  1675. serialize(buffer);
  1676. d.setLen(buffer.toByteArray(), buffer.length());
  1677. }
  1678. void CResultSetCursor::serializeType(MemoryBuffer & buffer)
  1679. {
  1680. buffer.append((unsigned)-1);
  1681. }
  1682. void CResultSetCursor::serialize(MemoryBuffer & buffer)
  1683. {
  1684. buffer.append(getCurRow());
  1685. }
  1686. void CResultSetCursor::setFetchSize(int rows)
  1687. {
  1688. }
  1689. bool CResultSetCursor::supportsRandomSeek() const
  1690. {
  1691. return meta.meta->supportsRandomSeek();
  1692. }
  1693. //---------------------------------------------------------------------------
  1694. bool IndirectResultSetCursor::absolute(__int64 row)
  1695. {
  1696. return queryBase()->absolute(row);
  1697. }
  1698. void IndirectResultSetCursor::afterLast()
  1699. {
  1700. queryBase()->afterLast();
  1701. }
  1702. void IndirectResultSetCursor::beforeFirst()
  1703. {
  1704. queryBase()->beforeFirst();
  1705. }
  1706. bool IndirectResultSetCursor::fetch(__int64 fileoffset)
  1707. {
  1708. return queryBase()->fetch(fileoffset);
  1709. }
  1710. bool IndirectResultSetCursor::first()
  1711. {
  1712. return queryBase()->first();
  1713. }
  1714. bool IndirectResultSetCursor::getBoolean(int columnIndex)
  1715. {
  1716. return queryBase()->getBoolean(columnIndex);
  1717. }
  1718. IDataVal & IndirectResultSetCursor::getBytes(IDataVal &d, int columnIndex)
  1719. {
  1720. return queryBase()->getBytes(d, columnIndex);
  1721. }
  1722. IResultSetCursor * IndirectResultSetCursor::getChildren(int columnIndex) const
  1723. {
  1724. return queryBase()->getChildren(columnIndex);
  1725. }
  1726. xdouble IndirectResultSetCursor::getDouble(int columnIndex)
  1727. {
  1728. return queryBase()->getDouble(columnIndex);
  1729. }
  1730. int IndirectResultSetCursor::getFetchSize() const
  1731. {
  1732. return queryBase()->getFetchSize();
  1733. }
  1734. bool IndirectResultSetCursor::getIsAll(int columnIndex) const
  1735. {
  1736. return queryBase()->getIsAll(columnIndex);
  1737. }
  1738. __int64 IndirectResultSetCursor::getInt(int columnIndex)
  1739. {
  1740. return queryBase()->getInt(columnIndex);
  1741. }
  1742. IDataVal & IndirectResultSetCursor::getRaw(IDataVal &d, int columnIndex)
  1743. {
  1744. return queryBase()->getRaw(d, columnIndex);
  1745. }
  1746. IDataVal & IndirectResultSetCursor::getRawRow(IDataVal &d)
  1747. {
  1748. return queryBase()->getRawRow(d);
  1749. }
  1750. __int64 IndirectResultSetCursor::getNumRows() const
  1751. {
  1752. return queryBase()->getNumRows();
  1753. }
  1754. IStringVal & IndirectResultSetCursor::getString(IStringVal & ret, int columnIndex)
  1755. {
  1756. return queryBase()->getString(ret, columnIndex);
  1757. }
  1758. bool IndirectResultSetCursor::isAfterLast() const
  1759. {
  1760. return queryBase()->isAfterLast();
  1761. }
  1762. bool IndirectResultSetCursor::isBeforeFirst() const
  1763. {
  1764. return queryBase()->isBeforeFirst();
  1765. }
  1766. bool IndirectResultSetCursor::isFirst() const
  1767. {
  1768. return queryBase()->isFirst();
  1769. }
  1770. bool IndirectResultSetCursor::isLast() const
  1771. {
  1772. return queryBase()->isLast();
  1773. }
  1774. bool IndirectResultSetCursor::isNull(int columnIndex) const
  1775. {
  1776. return queryBase()->isNull(columnIndex);
  1777. }
  1778. bool IndirectResultSetCursor::isValid() const
  1779. {
  1780. return queryBase()->isValid();
  1781. }
  1782. bool IndirectResultSetCursor::last()
  1783. {
  1784. return queryBase()->last();
  1785. }
  1786. bool IndirectResultSetCursor::next()
  1787. {
  1788. return queryBase()->next();
  1789. }
  1790. bool IndirectResultSetCursor::previous()
  1791. {
  1792. return queryBase()->previous();
  1793. }
  1794. INewResultSet * IndirectResultSetCursor::queryResultSet()
  1795. {
  1796. return queryBase()->queryResultSet();
  1797. }
  1798. bool IndirectResultSetCursor::relative(__int64 rows)
  1799. {
  1800. return queryBase()->relative(rows);
  1801. }
  1802. void IndirectResultSetCursor::serialize(IDataVal & d)
  1803. {
  1804. queryBase()->serialize(d);
  1805. }
  1806. IStringVal & IndirectResultSetCursor::getDisplayText(IStringVal &ret, int columnIndex)
  1807. {
  1808. return queryBase()->getDisplayText(ret, columnIndex);
  1809. }
  1810. IStringVal & IndirectResultSetCursor::getXml(IStringVal & ret, int columnIndex)
  1811. {
  1812. return queryBase()->getXml(ret, columnIndex);
  1813. }
  1814. IStringVal & IndirectResultSetCursor::getXmlRow(IStringVal &ret)
  1815. {
  1816. return queryBase()->getXmlRow(ret);
  1817. }
  1818. IStringVal & IndirectResultSetCursor::getXmlItem(IStringVal &ret)
  1819. {
  1820. return queryBase()->getXmlItem(ret);
  1821. }
  1822. void IndirectResultSetCursor::beginWriteXmlRows(IXmlWriter & writer)
  1823. {
  1824. return queryBase()->beginWriteXmlRows(writer);
  1825. }
  1826. void IndirectResultSetCursor::writeXmlRow(IXmlWriter &writer)
  1827. {
  1828. return queryBase()->writeXmlRow(writer);
  1829. }
  1830. void IndirectResultSetCursor::endWriteXmlRows(IXmlWriter & writer)
  1831. {
  1832. return queryBase()->endWriteXmlRows(writer);
  1833. }
  1834. void IndirectResultSetCursor::writeXmlItem(IXmlWriter &writer)
  1835. {
  1836. return queryBase()->writeXmlItem(writer);
  1837. }
  1838. void IndirectResultSetCursor::noteRelatedFileChanged()
  1839. {
  1840. queryBase()->noteRelatedFileChanged();
  1841. }
  1842. //---------------------------------------------------------------------------
  1843. bool NotifyingResultSetCursor::absolute(__int64 row)
  1844. {
  1845. bool ret = IndirectResultSetCursor::absolute(row);
  1846. notifyChanged();
  1847. return ret;
  1848. }
  1849. void NotifyingResultSetCursor::afterLast()
  1850. {
  1851. IndirectResultSetCursor::afterLast();
  1852. notifyChanged();
  1853. }
  1854. void NotifyingResultSetCursor::beforeFirst()
  1855. {
  1856. IndirectResultSetCursor::beforeFirst();
  1857. notifyChanged();
  1858. }
  1859. bool NotifyingResultSetCursor::fetch(__int64 fileoffset)
  1860. {
  1861. bool ret = IndirectResultSetCursor::fetch(fileoffset);
  1862. notifyChanged();
  1863. return ret;
  1864. }
  1865. bool NotifyingResultSetCursor::first()
  1866. {
  1867. bool ret = IndirectResultSetCursor::first();
  1868. notifyChanged();
  1869. return ret;
  1870. }
  1871. bool NotifyingResultSetCursor::last()
  1872. {
  1873. bool ret = IndirectResultSetCursor::last();
  1874. notifyChanged();
  1875. return ret;
  1876. }
  1877. bool NotifyingResultSetCursor::next()
  1878. {
  1879. bool ret = IndirectResultSetCursor::next();
  1880. notifyChanged();
  1881. return ret;
  1882. }
  1883. bool NotifyingResultSetCursor::previous()
  1884. {
  1885. bool ret = IndirectResultSetCursor::previous();
  1886. notifyChanged();
  1887. return ret;
  1888. }
  1889. bool NotifyingResultSetCursor::relative(__int64 rows)
  1890. {
  1891. bool ret = IndirectResultSetCursor::relative(rows);
  1892. notifyChanged();
  1893. return ret;
  1894. }
  1895. void NotifyingResultSetCursor::noteRelatedFileChanged()
  1896. {
  1897. IndirectResultSetCursor::noteRelatedFileChanged();
  1898. notifyChanged();
  1899. }
  1900. void NotifyingResultSetCursor::notifyChanged()
  1901. {
  1902. ForEachItemIn(i, dependents)
  1903. dependents.item(i).noteRelatedFileChanged();
  1904. }
  1905. //---------------------------------------------------------------------------
  1906. DelayedFilteredResultSetCursor::DelayedFilteredResultSetCursor(INewResultSet * _resultSet)
  1907. {
  1908. filtered.setown(_resultSet->createFiltered());
  1909. }
  1910. void DelayedFilteredResultSetCursor::clearCursor()
  1911. {
  1912. cursor.clear();
  1913. resultSet.clear();
  1914. }
  1915. void DelayedFilteredResultSetCursor::clearFilters()
  1916. {
  1917. clearCursor();
  1918. filtered->clearFilters();
  1919. }
  1920. void DelayedFilteredResultSetCursor::ensureFiltered()
  1921. {
  1922. }
  1923. void DelayedFilteredResultSetCursor::noteRelatedFileChanged()
  1924. {
  1925. //Don't create a cursor, just to tell the class that the cursor is no longer valid!
  1926. if (cursor)
  1927. IndirectResultSetCursor::noteRelatedFileChanged();
  1928. }
  1929. IExtendedResultSetCursor * DelayedFilteredResultSetCursor::queryBase()
  1930. {
  1931. //NB: Not thread safe - but none of the interface is
  1932. if (!cursor)
  1933. {
  1934. ensureFiltered();
  1935. //MORE: should possibly have the ability to create a null dataset at this point.
  1936. resultSet.setown(filtered->create());
  1937. cursor.setown(static_cast<IExtendedResultSetCursor *>(resultSet->createCursor()));
  1938. }
  1939. return cursor;
  1940. }
  1941. //---------------------------------------------------------------------------
  1942. //was using function templates that didn't use their types in their arguments, but
  1943. //VC++ fails to process them correctly.
  1944. template <class KEY> int qsortCompare(const void * _left, const void * _right) { return 0; }
  1945. typedef int (*qsortFunc)(const void *, const void *);
  1946. struct StringKeyElement
  1947. {
  1948. unsigned index;
  1949. StringAttr value;
  1950. };
  1951. int qsortCompare_StringKeyElement(const void * _left, const void * _right)
  1952. {
  1953. const StringKeyElement * left = (const StringKeyElement *)_left;
  1954. const StringKeyElement * right = (const StringKeyElement *)_right;
  1955. int i = strcmp(left->value, right->value);
  1956. if (i != 0)
  1957. return i;
  1958. if (left->index < right->index) return -1;
  1959. assertex(left->index > right->index);
  1960. return +1;
  1961. }
  1962. qsortFunc qsortCompare(StringKeyElement *) { return qsortCompare_StringKeyElement; }
  1963. void extractKey(StringKeyElement & element, CResultSetCursor * cursor, unsigned column)
  1964. {
  1965. StringAttrAdaptor adaptor(element.value);
  1966. cursor->getString(adaptor, column);
  1967. }
  1968. struct IntegerKeyElement
  1969. {
  1970. unsigned index;
  1971. __int64 value;
  1972. };
  1973. int qsortCompare_IntegerKeyElement(const void * _left, const void * _right)
  1974. {
  1975. const IntegerKeyElement * left = (const IntegerKeyElement *)_left;
  1976. const IntegerKeyElement * right = (const IntegerKeyElement *)_right;
  1977. if (left->value < right->value) return -1;
  1978. if (left->value > right->value) return +1;
  1979. if (left->index < right->index) return -1;
  1980. assertex(left->index > right->index);
  1981. return +1;
  1982. }
  1983. qsortFunc qsortCompare(IntegerKeyElement *) { return qsortCompare_IntegerKeyElement; }
  1984. void extractKey(IntegerKeyElement & element, CResultSetCursor * cursor, unsigned column)
  1985. {
  1986. element.value = cursor->getInt(column);
  1987. }
  1988. struct UnsignedKeyElement
  1989. {
  1990. unsigned index;
  1991. unsigned __int64 value;
  1992. };
  1993. int qsortCompare_UnsignedKeyElement(const void * _left, const void * _right)
  1994. {
  1995. const UnsignedKeyElement * left = (const UnsignedKeyElement *)_left;
  1996. const UnsignedKeyElement * right = (const UnsignedKeyElement *)_right;
  1997. if (left->value < right->value) return -1;
  1998. if (left->value > right->value) return +1;
  1999. if (left->index < right->index) return -1;
  2000. assertex(left->index > right->index);
  2001. return +1;
  2002. }
  2003. qsortFunc qsortCompare(UnsignedKeyElement *) { return qsortCompare_UnsignedKeyElement; }
  2004. void extractKey(UnsignedKeyElement & element, CResultSetCursor * cursor, unsigned column)
  2005. {
  2006. element.value = (unsigned __int64)cursor->getInt(column);
  2007. }
  2008. struct RealKeyElement
  2009. {
  2010. unsigned index;
  2011. double value;
  2012. };
  2013. int qsortCompare_RealKeyElement(const void * _left, const void * _right)
  2014. {
  2015. const RealKeyElement * left = (const RealKeyElement *)_left;
  2016. const RealKeyElement * right = (const RealKeyElement *)_right;
  2017. if (left->value < right->value) return -1;
  2018. if (left->value > right->value) return +1;
  2019. if (left->index < right->index) return -1;
  2020. assertex(left->index > right->index);
  2021. return +1;
  2022. }
  2023. qsortFunc qsortCompare(RealKeyElement *) { return qsortCompare_RealKeyElement; }
  2024. void extractKey(RealKeyElement & element, CResultSetCursor * cursor, unsigned column)
  2025. {
  2026. element.value = cursor->getDouble(column);
  2027. }
  2028. template <class KEYELEMENT>
  2029. void buildCursorIndex(unsigned & numElements, unsigned * & elements, CResultSetCursor * cursor, unsigned column, bool descend, KEYELEMENT *)
  2030. {
  2031. __int64 max64 = cursor->getNumRows();
  2032. assertex(max64 <= MAX_SORT_ELEMENTS);
  2033. unsigned max = (unsigned)max64;
  2034. KEYELEMENT * keys = new KEYELEMENT[max];
  2035. for (unsigned idx=0; idx < max; idx++)
  2036. {
  2037. cursor->absolute(idx);
  2038. keys[idx].index = idx;
  2039. extractKey(keys[idx], cursor, column);
  2040. }
  2041. qsort(keys, max, sizeof(KEYELEMENT), qsortCompare((KEYELEMENT *)0));
  2042. numElements = max;
  2043. elements = (unsigned *)malloc(max * sizeof(unsigned));
  2044. if (descend)
  2045. {
  2046. for (unsigned idx=0; idx < max; idx++)
  2047. elements[max-idx-1] = keys[idx].index;
  2048. }
  2049. else
  2050. {
  2051. for (unsigned idx=0; idx < max; idx++)
  2052. elements[idx] = keys[idx].index;
  2053. }
  2054. delete [] keys;
  2055. }
  2056. CResultSetSortedCursor::CResultSetSortedCursor(const CResultSetMetaData & _meta, IExtendedNewResultSet * _resultSet, unsigned _column, bool _desc) : CResultSetCursor(_meta, _resultSet)
  2057. {
  2058. numEntries = 0;
  2059. elements = NULL;
  2060. lastRow = 0;
  2061. column = _column;
  2062. desc = _desc;
  2063. buildIndex();
  2064. }
  2065. CResultSetSortedCursor::CResultSetSortedCursor(const CResultSetMetaData & _meta, IExtendedNewResultSet * _resultSet, unsigned _column, bool _desc, MemoryBuffer & buffer) : CResultSetCursor(_meta, _resultSet)
  2066. {
  2067. numEntries = 0;
  2068. elements = NULL;
  2069. lastRow = 0;
  2070. column = _column;
  2071. desc = _desc;
  2072. buildIndex();
  2073. buffer.read(curRow);
  2074. buffer.read(lastRow);
  2075. absolute(lastRow);
  2076. }
  2077. CResultSetSortedCursor::~CResultSetSortedCursor()
  2078. {
  2079. free(elements);
  2080. }
  2081. void CResultSetSortedCursor::buildIndex()
  2082. {
  2083. Owned<CResultSetCursor> cursor = new CResultSetCursor(meta, resultSet);
  2084. switch (meta.getColumnDisplayType(column))
  2085. {
  2086. case TypeBoolean:
  2087. case TypeInteger:
  2088. buildCursorIndex<IntegerKeyElement>(numEntries, elements, cursor, column, desc, (IntegerKeyElement*)0);
  2089. break;
  2090. case TypeUnsignedInteger:
  2091. buildCursorIndex<UnsignedKeyElement>(numEntries, elements, cursor, column, desc, (UnsignedKeyElement*)0);
  2092. break;
  2093. case TypeReal:
  2094. buildCursorIndex<RealKeyElement>(numEntries, elements, cursor, column, desc, (RealKeyElement*)0);
  2095. break;
  2096. case TypeString:
  2097. case TypeData:
  2098. case TypeUnicode: //MORE!
  2099. buildCursorIndex<StringKeyElement>(numEntries, elements, cursor, column, desc, (StringKeyElement*)0);
  2100. break;
  2101. default:
  2102. UNIMPLEMENTED; // Should have been translated to one of the above by this point...
  2103. }
  2104. }
  2105. bool CResultSetSortedCursor::absolute(__int64 row)
  2106. {
  2107. lastRow = row;
  2108. return CResultSetCursor::absolute(translateRow(row));
  2109. }
  2110. __int64 CResultSetSortedCursor::getCurRow() const
  2111. {
  2112. return lastRow;
  2113. }
  2114. __int64 CResultSetSortedCursor::translateRow(__int64 row) const
  2115. {
  2116. if ((row >= 0) && (row < numEntries))
  2117. return elements[row];
  2118. return row;
  2119. }
  2120. void CResultSetSortedCursor::serializeType(MemoryBuffer & buffer)
  2121. {
  2122. buffer.append((unsigned)column);
  2123. buffer.append(desc);
  2124. }
  2125. void CResultSetSortedCursor::serialize(MemoryBuffer & buffer)
  2126. {
  2127. CResultSetCursor::serialize(buffer);
  2128. buffer.append(lastRow);
  2129. }
  2130. //---------------------------------------------------------------------------
  2131. inline byte hex2digit(char c)
  2132. {
  2133. if (c >= 'a')
  2134. return (c - 'a' + 10);
  2135. else if (c >= 'A')
  2136. return (c - 'A' + 10);
  2137. return (c - '0');
  2138. }
  2139. inline byte getHexPair(const char * s)
  2140. {
  2141. return hex2digit(s[0]) << 4 | hex2digit(s[1]);
  2142. }
  2143. static unsigned getSubstringMatchLength(size32_t len, const void * data)
  2144. {
  2145. const char * inbuff = (const char *)data;
  2146. unsigned trimLen = rtlTrimStrLen(len, inbuff);
  2147. if (trimLen && (inbuff[trimLen-1] == '*'))
  2148. return rtlUtf8Length(trimLen-1, inbuff);
  2149. return FullStringMatch;
  2150. }
  2151. void CColumnFilter::addValue(unsigned sizeText, const char * text)
  2152. {
  2153. unsigned lenText = rtlUtf8Length(sizeText, text);
  2154. unsigned size = type->getSize();
  2155. MemoryAttrItem * next = new MemoryAttrItem;
  2156. type_t tc = type->getTypeCode();
  2157. if (isMappedIndexField)
  2158. {
  2159. if (__BYTE_ORDER == __LITTLE_ENDIAN)
  2160. {
  2161. if (tc == type_int)
  2162. tc = type_swapint;
  2163. }
  2164. else
  2165. {
  2166. if (tc == type_swapint)
  2167. tc = type_int;
  2168. }
  2169. }
  2170. //sublen is the number of characters (not the size)
  2171. subLen = getSubstringMatchLength(sizeText, text);
  2172. switch (tc)
  2173. {
  2174. case type_void:
  2175. case type_set:
  2176. case type_table:
  2177. case type_groupedtable:
  2178. break;
  2179. case type_boolean:
  2180. {
  2181. byte value = rtlCsvStrToBool(lenText, text);
  2182. next->set(sizeof(value), &value);
  2183. break;
  2184. }
  2185. break;
  2186. case type_int:
  2187. {
  2188. __int64 value = type->isSigned() ? rtlStrToInt8(lenText, text) : (__int64)rtlStrToUInt8(lenText, text);
  2189. if (isMappedIndexField && type->isSigned())
  2190. value += getIntBias(size);
  2191. if (__BYTE_ORDER == __LITTLE_ENDIAN)
  2192. next->set(size, &value);
  2193. else
  2194. next->set(size, ((const byte *)&value)+(sizeof(value)-size));
  2195. break;
  2196. }
  2197. case type_swapint:
  2198. {
  2199. __int64 value = type->isSigned() ? rtlStrToInt8(lenText, text) : (__int64)rtlStrToUInt8(lenText, text);
  2200. if (isMappedIndexField && type->isSigned())
  2201. value += getIntBias(size);
  2202. _rev8((char *)&value);
  2203. if (__BYTE_ORDER == __LITTLE_ENDIAN)
  2204. next->set(size, ((const byte *)&value)+(sizeof(value)-size));
  2205. else
  2206. next->set(size, &value);
  2207. break;
  2208. }
  2209. case type_packedint:
  2210. {
  2211. void * target = next->allocate(size);
  2212. if (type->isSigned())
  2213. rtlSetPackedSigned(target, rtlStrToInt8(lenText, text));
  2214. else
  2215. rtlSetPackedUnsigned(target, rtlStrToUInt8(lenText, text));
  2216. break;
  2217. }
  2218. case type_decimal:
  2219. {
  2220. void * target = next->allocate(size);
  2221. DecLock();
  2222. rtlDecPushUtf8(lenText, text);
  2223. if (type->isSigned())
  2224. DecPopDecimal(target, size, type->getPrecision());
  2225. else
  2226. DecPopUDecimal(target, size, type->getPrecision());
  2227. DecUnlock();
  2228. break;
  2229. }
  2230. case type_real:
  2231. {
  2232. if (size == 4)
  2233. {
  2234. float value = (float)rtlStrToReal(lenText, text);
  2235. next->set(sizeof(value), &value);
  2236. }
  2237. else
  2238. {
  2239. double value = rtlStrToReal(lenText, text);
  2240. next->set(sizeof(value), &value);
  2241. }
  2242. break;
  2243. }
  2244. case type_qstring:
  2245. {
  2246. if (lenText > subLen) lenText = subLen;
  2247. char * target = (char *)next->allocate(rtlQStrSize(lenText));
  2248. rtlStrToQStr(lenText, target, lenText, text);
  2249. break;
  2250. }
  2251. break;
  2252. case type_data:
  2253. {
  2254. if (lenText > subLen) lenText = subLen;
  2255. if (subLen != FullStringMatch)
  2256. subLen /= 2;
  2257. unsigned max = lenText/2;
  2258. char * target = (char *)next->allocate(max);
  2259. for (unsigned i=0; i<max; i++)
  2260. target[i] = getHexPair(text+i*2);
  2261. break;
  2262. }
  2263. case type_string:
  2264. {
  2265. if (lenText > subLen) lenText = subLen;
  2266. char * target = (char *)next->allocate(lenText);
  2267. rtlUtf8ToStr(lenText, target, lenText, text);
  2268. break;
  2269. }
  2270. case type_unicode:
  2271. {
  2272. if (lenText > subLen) lenText = subLen;
  2273. UChar * target = (UChar *)next->allocate(lenText*2);
  2274. rtlUtf8ToUnicode(lenText, target, lenText, text);
  2275. break;
  2276. }
  2277. break;
  2278. case type_varstring:
  2279. {
  2280. if (lenText > subLen) lenText = subLen;
  2281. next->set(lenText+1, text);
  2282. break;
  2283. }
  2284. case type_varunicode:
  2285. {
  2286. UChar * target = (UChar *)next->allocate(lenText*2+2);
  2287. rtlUtf8ToUnicode(lenText, target, lenText, text);
  2288. target[lenText] = 0;
  2289. break;
  2290. }
  2291. break;
  2292. case type_utf8:
  2293. {
  2294. if (lenText > subLen) sizeText = rtlUtf8Size(subLen, text);
  2295. next->set(sizeText, text);
  2296. //Should it be utf8 or ascii coming in?
  2297. //char * target = (char *)next->allocate(lenText*4);
  2298. //rtlStrToUtf8(lenText, target, lenText, text);
  2299. break;
  2300. }
  2301. break;
  2302. default:
  2303. UNIMPLEMENTED;
  2304. }
  2305. if (next->length())
  2306. values.append(*next);
  2307. else
  2308. next->Release();
  2309. }
  2310. void CColumnFilter::deserialize(MemoryBuffer & buffer)
  2311. {
  2312. unsigned num;
  2313. buffer.read(num);
  2314. for (unsigned i= 0; i < num; i++)
  2315. {
  2316. MemoryAttrItem * next = new MemoryAttrItem;
  2317. ::deserialize(buffer, *next);
  2318. values.append(*next);
  2319. }
  2320. }
  2321. bool CColumnFilter::optimizeFilter(IFvDataSource * dataSource)
  2322. {
  2323. if (values.ordinality() == 0)
  2324. return true;
  2325. optimized = true;
  2326. ForEachItemIn(i, values)
  2327. {
  2328. MemoryAttr & cur = values.item(i);
  2329. if (!dataSource->addFilter(whichColumn, subLen, cur.length(), cur.get()))
  2330. optimized = false;
  2331. }
  2332. return optimized;
  2333. }
  2334. bool CColumnFilter::matches(const byte * rowValue, unsigned valueSize, const byte * value)
  2335. {
  2336. unsigned size = type->getSize();
  2337. unsigned len;
  2338. switch (type->getTypeCode())
  2339. {
  2340. case type_void:
  2341. case type_set:
  2342. case type_table:
  2343. case type_groupedtable:
  2344. return true;
  2345. case type_boolean:
  2346. case type_int:
  2347. case type_swapint:
  2348. case type_packedint:
  2349. return memcmp(rowValue, value, size) == 0;
  2350. case type_decimal:
  2351. if (type->isSigned())
  2352. return DecCompareDecimal(size, rowValue, value) == 0;
  2353. return DecCompareUDecimal(size, rowValue, value) == 0;
  2354. case type_real:
  2355. if (size == 4)
  2356. return *(float *)rowValue == *(float *)value;
  2357. return *(double *)rowValue == *(double *)value;
  2358. case type_qstring:
  2359. len = getLength(*type, rowValue);
  2360. if ((subLen != FullStringMatch) && (len > subLen))
  2361. len = subLen;
  2362. return rtlCompareQStrQStr(len, rowValue, rtlQStrLength(valueSize), value) == 0;
  2363. case type_data:
  2364. len = getLength(*type, rowValue);
  2365. if ((subLen != FullStringMatch) && (len > subLen))
  2366. len = subLen;
  2367. return rtlCompareDataData(len, (const char *)rowValue, valueSize, (const char *)value) == 0;
  2368. case type_string:
  2369. len = getLength(*type, rowValue);
  2370. if ((subLen != FullStringMatch) && (len > subLen))
  2371. len = subLen;
  2372. return rtlCompareStrStr(len, (const char *)rowValue, valueSize, (const char *)value) == 0;
  2373. case type_unicode:
  2374. len = getLength(*type, rowValue);
  2375. return rtlCompareUnicodeUnicode(len, (const UChar *)rowValue, valueSize/2, (const UChar *)value, "") == 0;
  2376. case type_utf8:
  2377. len = getLength(*type, rowValue);
  2378. if ((subLen != FullStringMatch) && (len > subLen))
  2379. len = subLen;
  2380. return rtlCompareUtf8Utf8(len, (const char *)rowValue, rtlUtf8Length(valueSize, value), (const char *)value, "") == 0;
  2381. case type_varstring:
  2382. return strcmp((const char *)rowValue, (const char *)value) != 0;
  2383. case type_varunicode:
  2384. return rtlCompareVUnicodeVUnicode((const UChar *)rowValue, (const UChar *)value, "") == 0;
  2385. default:
  2386. UNIMPLEMENTED;
  2387. }
  2388. }
  2389. bool CColumnFilter::isValid(const byte * rowValue, const unsigned * offsets)
  2390. {
  2391. if (optimized || values.ordinality() == 0)
  2392. return true;
  2393. const byte * columnValue = rowValue + offsets[whichColumn];
  2394. ForEachItemIn(i, values)
  2395. {
  2396. MemoryAttr & cur = values.item(i);
  2397. if (matches(columnValue, cur.length(), (const byte *)cur.get()))
  2398. return true;
  2399. }
  2400. return false;
  2401. }
  2402. void CColumnFilter::serialize(MemoryBuffer & buffer)
  2403. {
  2404. buffer.append((unsigned)values.ordinality());
  2405. ForEachItemIn(i, values)
  2406. ::serialize(buffer, values.item(i));
  2407. }
  2408. //---------------------------------------------------------------------------
  2409. CFilteredResultSet::CFilteredResultSet(IExtendedNewResultSet * _other, ColumnFilterArray & _filters) : CIndirectResultSet(_other)
  2410. {
  2411. appendArray(filters, _filters);
  2412. initExtra();
  2413. }
  2414. #if 0
  2415. CFilteredResultSet::CFilteredResultSet(const CResultSetMetaData & _meta, CResultSet * _resultSet, MemoryBuffer & buffer) : CResultSetCursor(_meta, _resultSet, false)
  2416. {
  2417. unsigned numFilters;
  2418. buffer.read(numFilters);
  2419. for (unsigned i=0; i< numFilters; i++)
  2420. {
  2421. CColumnFilter & next = * new CColumnFilter(meta.queryType(i));
  2422. next.deserialize(buffer);
  2423. filters.append(next);
  2424. }
  2425. initExtra();
  2426. buffer.read(curRow);
  2427. buffer.read(lastRow);
  2428. absolute(lastRow);
  2429. }
  2430. #endif
  2431. CFilteredResultSet::~CFilteredResultSet()
  2432. {
  2433. delete [] offsets;
  2434. }
  2435. bool CFilteredResultSet::getRow(MemoryBuffer & out, __int64 row)
  2436. {
  2437. __int64 newRow = translateRow(row);
  2438. if (newRow < 0)
  2439. return false;
  2440. return CIndirectResultSet::getRow(out, newRow);
  2441. }
  2442. bool CFilteredResultSet::getRawRow(MemoryBuffer & out, __int64 row)
  2443. {
  2444. __int64 newRow = translateRow(row);
  2445. if (newRow < 0)
  2446. return false;
  2447. return CIndirectResultSet::getRawRow(out, newRow);
  2448. }
  2449. __int64 CFilteredResultSet::getNumRows() const
  2450. {
  2451. if (readAll)
  2452. return validPositions.ordinality();
  2453. return UNKNOWN_NUM_ROWS;
  2454. }
  2455. bool CFilteredResultSet::rowMatchesFilter(const byte * row)
  2456. {
  2457. if (!meta.isFixedSize())
  2458. meta.calcFieldOffsets(row, offsets);
  2459. ForEachItemIn(i, filters)
  2460. {
  2461. if (!filters.item(i).isValid(row, offsets))
  2462. return false;
  2463. }
  2464. return true;
  2465. }
  2466. __int64 CFilteredResultSet::translateRow(__int64 row)
  2467. {
  2468. if (row < 0)
  2469. return row;
  2470. if (row > MAX_FILTER_ELEMENTS)
  2471. return AFTER_LAST_ROW; // would it be better to throw an error?
  2472. if (!readAll && (row >= validPositions.ordinality()))
  2473. {
  2474. unsigned __int64 nextPos = 0;
  2475. if (validPositions.ordinality())
  2476. nextPos = validPositions.tos()+1;
  2477. MemoryBuffer tempBuffer;
  2478. unsigned startTime = msTick();
  2479. while (row >= validPositions.ordinality())
  2480. {
  2481. if (!CIndirectResultSet::getRow(tempBuffer.clear(), nextPos))
  2482. {
  2483. readAll = true;
  2484. break;
  2485. }
  2486. if (rowMatchesFilter((byte *)tempBuffer.toByteArray()))
  2487. {
  2488. validPositions.append(nextPos);
  2489. }
  2490. else
  2491. {
  2492. unsigned timeTaken = msTick() - startTime;
  2493. if (timeTaken > MAX_SKIP_TIME)
  2494. throwError1(FVERR_FilterTooRestrictive, timeTaken/1000);
  2495. }
  2496. nextPos++;
  2497. }
  2498. }
  2499. if ((unsigned)row < validPositions.ordinality())
  2500. return validPositions.item((unsigned)row);
  2501. return AFTER_LAST_ROW;
  2502. }
  2503. void CFilteredResultSet::serialize(MemoryBuffer & buffer)
  2504. {
  2505. CIndirectResultSet::serialize(buffer);
  2506. buffer.append((unsigned)filters.ordinality());
  2507. ForEachItemIn(i, filters)
  2508. filters.item(i).serialize(buffer);
  2509. }
  2510. void CFilteredResultSet::initExtra()
  2511. {
  2512. readAll = false;
  2513. offsets = new unsigned[meta.getColumnCount()+1];
  2514. if (meta.isFixedSize())
  2515. meta.calcFieldOffsets(NULL, offsets);
  2516. }
  2517. //---------------------------------------------------------------------------
  2518. CFetchFilteredResultSet::CFetchFilteredResultSet(IExtendedNewResultSet * _parent, const CStrColumnFilter & _filter) : CIndirectResultSet(_parent)
  2519. {
  2520. ForEachItemIn(i, _filter.values)
  2521. {
  2522. const MemoryAttrItem & value = _filter.values.item(i);
  2523. unsigned __int64 offset = rtlStrToUInt8(value.length(), static_cast<const char *>(value.get()));
  2524. validOffsets.append(offset);
  2525. }
  2526. }
  2527. bool CFetchFilteredResultSet::getRow(MemoryBuffer & out, __int64 row)
  2528. {
  2529. if (!validOffsets.isItem((unsigned)row))
  2530. return false;
  2531. return CIndirectResultSet::fetch(out, validOffsets.item((unsigned)row));
  2532. }
  2533. bool CFetchFilteredResultSet::getRawRow(MemoryBuffer & out, __int64 row)
  2534. {
  2535. if (!validOffsets.isItem((unsigned)row))
  2536. return false;
  2537. return CIndirectResultSet::fetchRaw(out, validOffsets.item((unsigned)row));
  2538. }
  2539. __int64 CFetchFilteredResultSet::getNumRows() const
  2540. {
  2541. return validOffsets.ordinality();
  2542. }
  2543. void CFetchFilteredResultSet::serialize(MemoryBuffer & buffer)
  2544. {
  2545. CIndirectResultSet::serialize(buffer);
  2546. buffer.append((unsigned)validOffsets.ordinality());
  2547. ForEachItemIn(i, validOffsets)
  2548. buffer.append(validOffsets.item(i));
  2549. }
  2550. //---------------------------------------------------------------------------
  2551. CFilteredResultSetBuilder::CFilteredResultSetBuilder(IExtendedNewResultSet * _resultSet)
  2552. {
  2553. resultSet.set(_resultSet);
  2554. }
  2555. INewResultSet * CFilteredResultSetBuilder::create()
  2556. {
  2557. Linked<IExtendedNewResultSet> baseResultSet = resultSet;
  2558. const CResultSetMetaData & meta = static_cast<const CResultSetMetaData &>(resultSet->getMetaData());
  2559. //Check for fetch filter, and if present apply that first
  2560. unsigned numColumns = meta.getColumnCount();
  2561. if (filters.isItem(numColumns-1) && meta.isVirtual(numColumns-1))
  2562. {
  2563. CStrColumnFilter & cur = filters.item(numColumns-1);
  2564. if (cur.values.ordinality())
  2565. {
  2566. baseResultSet.setown(new CFetchFilteredResultSet(resultSet, cur));
  2567. cur.values.kill();
  2568. }
  2569. }
  2570. Owned<IExtendedNewResultSet> cloned = baseResultSet->cloneForFilter();
  2571. IFvDataSource * dataSource = cloned ? cloned->queryDataSource() : NULL;
  2572. ColumnFilterArray rawFilters;
  2573. ForEachItemIn(columnIndex, filters)
  2574. {
  2575. CStrColumnFilter & cur = filters.item(columnIndex);
  2576. if (cur.values.ordinality())
  2577. {
  2578. Owned<CColumnFilter> next = new CColumnFilter(columnIndex, meta.queryType(columnIndex), resultSet->isMappedIndexField(columnIndex));
  2579. ForEachItemIn(j, cur.values)
  2580. {
  2581. MemoryAttrItem & curValue = cur.values.item(j);
  2582. next->addValue(curValue.length(), reinterpret_cast<const char *>(curValue.get()));
  2583. }
  2584. if (!cloned || !next->optimizeFilter(dataSource))
  2585. rawFilters.append(*next.getClear());
  2586. }
  2587. }
  2588. if (cloned)
  2589. {
  2590. dataSource->applyFilter();
  2591. if (rawFilters.ordinality() == 0)
  2592. return cloned.getClear();
  2593. return new CFilteredResultSet(cloned, rawFilters);
  2594. }
  2595. if (rawFilters.ordinality() == 0)
  2596. return baseResultSet.getClear();
  2597. return new CFilteredResultSet(baseResultSet, rawFilters);
  2598. }
  2599. void CFilteredResultSetBuilder::addFilter(unsigned columnIndex, const char * value)
  2600. {
  2601. addFilter(columnIndex, strlen(value), value);
  2602. }
  2603. void CFilteredResultSetBuilder::addFilter(unsigned columnIndex, unsigned len, const char * value)
  2604. {
  2605. assertex(columnIndex < (unsigned)resultSet->getMetaData().getColumnCount());
  2606. while (filters.ordinality() <= columnIndex)
  2607. filters.append(*new CStrColumnFilter());
  2608. filters.item(columnIndex).addValue(len, value);
  2609. }
  2610. void CFilteredResultSetBuilder::addNaturalFilter(unsigned columnIndex, unsigned len, const char * value)
  2611. {
  2612. const CResultSetMetaData & meta = static_cast<const CResultSetMetaData &>(resultSet->getMetaData());
  2613. assertex(columnIndex < (unsigned)meta.getColumnCount());
  2614. const CResultSetColumnInfo & column = meta.queryColumn(columnIndex);
  2615. if (column.setTransforms.ordinality())
  2616. {
  2617. MemoryAttr source(len, value);
  2618. MemoryAttr translated;
  2619. translateValue(translated, source, column.setTransforms);
  2620. addFilter(columnIndex, translated.length(), static_cast<const char *>(translated.get()));
  2621. }
  2622. else
  2623. addFilter(columnIndex, len, value);
  2624. }
  2625. void CFilteredResultSetBuilder::clearFilter(unsigned columnIndex)
  2626. {
  2627. assertex(columnIndex < (unsigned)resultSet->getMetaData().getColumnCount());
  2628. if (filters.isItem(columnIndex))
  2629. filters.item(columnIndex).clear();
  2630. }
  2631. void CFilteredResultSetBuilder::clearFilters()
  2632. {
  2633. filters.kill();
  2634. }
  2635. //---------------------------------------------------------------------------
  2636. CResultSetFactoryBase::CResultSetFactoryBase(const char * _username, const char * _password)
  2637. {
  2638. username.set(_username);
  2639. password.set(_password);
  2640. }
  2641. CResultSetFactoryBase::CResultSetFactoryBase(ISecManager &secmgr, ISecUser &secuser)
  2642. {
  2643. secMgr.set(&secmgr);
  2644. secUser.set(&secuser);
  2645. username.set(secuser.getName());
  2646. password.set(secuser.credentials().getPassword());
  2647. }
  2648. //---------------------------------------------------------------------------
  2649. CResultSetFactory::CResultSetFactory(const char * _username, const char * _password) : CResultSetFactoryBase(_username, _password)
  2650. {
  2651. }
  2652. CResultSetFactory::CResultSetFactory(ISecManager &secmgr, ISecUser &secuser) : CResultSetFactoryBase(secmgr, secuser)
  2653. {
  2654. }
  2655. IDistributedFile * CResultSetFactory::lookupLogicalName(const char * logicalName)
  2656. {
  2657. Owned<IUserDescriptor> udesc;
  2658. if(username != NULL && *username != '\0')
  2659. {
  2660. udesc.setown(createUserDescriptor());
  2661. udesc->set(username, password);
  2662. }
  2663. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(logicalName, udesc.get());
  2664. if (!df)
  2665. throwError1(FVERR_CouldNotResolveX, logicalName);
  2666. return df.getClear();
  2667. }
  2668. INewResultSet * CResultSetFactory::createNewResultSet(IConstWUResult * wuResult, const char * wuid)
  2669. {
  2670. Owned<IFvDataSource> ds = createDataSource(wuResult, wuid, username, password);
  2671. if (ds)
  2672. return createResultSet(ds, (wuResult->getResultFormat() == ResultFormatXml));
  2673. return NULL;
  2674. }
  2675. INewResultSet * CResultSetFactory::createNewFileResultSet(const char * logicalName, const char * cluster)
  2676. {
  2677. Owned<IDistributedFile> df = lookupLogicalName(logicalName);
  2678. Owned<IFvDataSource> ds = createFileDataSource(df, logicalName, cluster, username, password);
  2679. if (ds)
  2680. {
  2681. Owned<CResultSet> result = createResultSet(ds, false);
  2682. result->setColumnMapping(df);
  2683. return result.getClear();
  2684. }
  2685. return NULL;
  2686. }
  2687. INewResultSet * CResultSetFactory::createNewResultSet(const char * wuid, unsigned sequence, const char * name)
  2688. {
  2689. Owned<IConstWUResult> wuResult = (secMgr) ? secResolveResult(*secMgr, *secUser, wuid, sequence, name) : resolveResult(wuid, sequence, name);
  2690. return (wuResult) ? createNewResultSet(wuResult, wuid) : NULL;
  2691. }
  2692. INewResultSet * CResultSetFactory::createNewFileResultSet(const char * logicalFile)
  2693. {
  2694. return createNewFileResultSet(logicalFile, NULL);
  2695. }
  2696. CResultSet * CResultSetFactory::createResultSet(IFvDataSource * ds, bool _useXPath)
  2697. {
  2698. //MORE: Save in a hash table, which times out after a certain period...
  2699. return new CResultSet(ds, _useXPath);
  2700. }
  2701. IResultSetMetaData * CResultSetFactory::createResultSetMeta(IConstWUResult * wuResult)
  2702. {
  2703. return new CResultSetMetaData(createMetaData(wuResult), false);
  2704. }
  2705. IResultSetMetaData * CResultSetFactory::createResultSetMeta(const char * wuid, unsigned sequence, const char * name)
  2706. {
  2707. Owned<IConstWUResult> wuResult = (secMgr) ? secResolveResult(*secMgr, *secUser, wuid, sequence, name) : resolveResult(wuid, sequence, name);
  2708. return (wuResult) ? createResultSetMeta(wuResult) : NULL;
  2709. }
  2710. //---------------------------------------------------------------------------
  2711. CRemoteResultSetFactory::CRemoteResultSetFactory(const char * remoteServer, const char * _username, const char * _password) : CResultSetFactoryBase(_username, _password)
  2712. {
  2713. serverEP.set(remoteServer);
  2714. }
  2715. CRemoteResultSetFactory::CRemoteResultSetFactory(const char * remoteServer, ISecManager &secmgr, ISecUser &secuser) : CResultSetFactoryBase(secmgr, secuser)
  2716. {
  2717. serverEP.set(remoteServer);
  2718. }
  2719. INewResultSet * CRemoteResultSetFactory::createNewResultSet(IConstWUResult * wuResult, const char * wuid)
  2720. {
  2721. SCMStringBuffer name;
  2722. wuResult->getResultName(name);
  2723. Owned<IFvDataSource> ds = createRemoteDataSource(serverEP, username, password, wuid, wuResult->getResultSequence(), name.length() ? name.str() : NULL);
  2724. if (ds)
  2725. return new CResultSet(ds, false);
  2726. return NULL;
  2727. }
  2728. INewResultSet * CRemoteResultSetFactory::createNewFileResultSet(const char * logicalName, const char * cluster)
  2729. {
  2730. Owned<IFvDataSource> ds = createRemoteFileDataSource(serverEP, username, password, logicalName);
  2731. if (ds)
  2732. return new CResultSet(ds, false);
  2733. return NULL;
  2734. }
  2735. INewResultSet* CRemoteResultSetFactory::createNewResultSet(const char * wuid, unsigned sequence, const char * name)
  2736. {
  2737. Owned<IFvDataSource> ds = createRemoteDataSource(serverEP, username, password, wuid, sequence, name);
  2738. if (ds)
  2739. return new CResultSet(ds, false);
  2740. return NULL;
  2741. }
  2742. INewResultSet* CRemoteResultSetFactory::createNewFileResultSet(const char * logicalName)
  2743. {
  2744. Owned<IFvDataSource> ds = createRemoteFileDataSource(serverEP, username, password, logicalName);
  2745. if (ds)
  2746. return new CResultSet(ds, false);
  2747. return NULL;
  2748. }
  2749. IResultSetMetaData * CRemoteResultSetFactory::createResultSetMeta(IConstWUResult * wuResult)
  2750. {
  2751. UNIMPLEMENTED;
  2752. }
  2753. IResultSetMetaData * CRemoteResultSetFactory::createResultSetMeta(const char * wuid, unsigned sequence, const char * name)
  2754. {
  2755. UNIMPLEMENTED;
  2756. }
  2757. //---------------------------------------------------------------------------
  2758. INewResultSet* createNewResultSet(IResultSetFactory & factory, IStringVal & error, IConstWUResult * wuResult, const char * wuid)
  2759. {
  2760. try
  2761. {
  2762. return factory.createNewResultSet(wuResult, wuid);
  2763. }
  2764. catch (IException * e)
  2765. {
  2766. StringBuffer s;
  2767. error.set(e->errorMessage(s).str());
  2768. e->Release();
  2769. return NULL;
  2770. }
  2771. }
  2772. INewResultSet* createNewFileResultSet(IResultSetFactory & factory, IStringVal & error, const char * logicalFile, const char * cluster)
  2773. {
  2774. try
  2775. {
  2776. return factory.createNewFileResultSet(logicalFile, cluster);
  2777. }
  2778. catch (IException * e)
  2779. {
  2780. StringBuffer s;
  2781. error.set(e->errorMessage(s).str());
  2782. e->Release();
  2783. return NULL;
  2784. }
  2785. }
  2786. INewResultSet* createNewResultSetSeqName(IResultSetFactory & factory, IStringVal & error, const char * wuid, unsigned sequence, const char * name)
  2787. {
  2788. try
  2789. {
  2790. return factory.createNewResultSet(wuid, sequence, name);
  2791. }
  2792. catch (IException * e)
  2793. {
  2794. StringBuffer s;
  2795. error.set(e->errorMessage(s).str());
  2796. e->Release();
  2797. return NULL;
  2798. }
  2799. }
  2800. //---------------------------------------------------------------------------
  2801. //MORE: There should be an option to create a proxy-based IFileView so that
  2802. //i) formatting etc. can be done remotely
  2803. //ii) cacching and sort order calculation can be done remotely.
  2804. // Should still cache the last n rows locally (raw/non-raw).
  2805. IResultSetFactory * getResultSetFactory(const char * username, const char * password)
  2806. {
  2807. return new CResultSetFactory(username, password);
  2808. }
  2809. IResultSetFactory * getSecResultSetFactory(ISecManager *secmgr, ISecUser *secuser, const char *username, const char *password)
  2810. {
  2811. if (secmgr)
  2812. return new CResultSetFactory(*secmgr, *secuser);
  2813. return getResultSetFactory(username, password);
  2814. }
  2815. IResultSetFactory * getRemoteResultSetFactory(const char * remoteServer, const char * username, const char * password)
  2816. {
  2817. return new CRemoteResultSetFactory(remoteServer, username, password);
  2818. }
  2819. int findResultSetColumn(const INewResultSet * results, const char * columnName)
  2820. {
  2821. const IResultSetMetaData & meta = results->getMetaData();
  2822. SCMStringBuffer s;
  2823. for(int i = 0; i < meta.getColumnCount(); i++)
  2824. {
  2825. s.clear();
  2826. if(!stricmp(columnName, meta.getColumnLabel(s, i).str()))
  2827. return i;
  2828. }
  2829. return -1;
  2830. }
  2831. extern FILEVIEW_API unsigned getResultCursorXml(IStringVal & ret, IResultSetCursor * cursor, const char * name, unsigned start, unsigned count, const char * schemaName, const IProperties *xmlns)
  2832. {
  2833. Owned<CommonXmlWriter> writer = CreateCommonXmlWriter(XWFexpandempty);
  2834. unsigned rc = writeResultCursorXml(*writer, cursor, name, start, count, schemaName, xmlns);
  2835. ret.set(writer->str());
  2836. return rc;
  2837. }
  2838. extern FILEVIEW_API unsigned getResultXml(IStringVal & ret, INewResultSet * result, const char* name,unsigned start, unsigned count, const char * schemaName, const IProperties *xmlns)
  2839. {
  2840. Owned<IResultSetCursor> cursor = result->createCursor();
  2841. return getResultCursorXml(ret, cursor, name, start, count, schemaName, xmlns);
  2842. }
  2843. extern FILEVIEW_API unsigned getResultJSON(IStringVal & ret, INewResultSet * result, const char* name,unsigned start, unsigned count, const char * schemaName)
  2844. {
  2845. Owned<IResultSetCursor> cursor = result->createCursor();
  2846. Owned<CommonJsonWriter> writer = new CommonJsonWriter(0);
  2847. writer->outputBeginRoot();
  2848. unsigned rc = writeResultCursorXml(*writer, cursor, name, start, count, schemaName);
  2849. writer->outputEndRoot();
  2850. ret.set(writer->str());
  2851. return rc;
  2852. }
  2853. extern FILEVIEW_API unsigned writeResultCursorXml(IXmlWriter & writer, IResultSetCursor * cursor, const char * name, unsigned start, unsigned count, const char * schemaName, const IProperties *xmlns)
  2854. {
  2855. if (schemaName)
  2856. {
  2857. writer.outputBeginNested("XmlSchema", false);
  2858. writer.outputUtf8(strlen(schemaName), schemaName, "@name");
  2859. SCMStringBuffer xsd;
  2860. const IResultSetMetaData & meta = cursor->queryResultSet()->getMetaData();
  2861. meta.getXmlXPathSchema(xsd, false);
  2862. writer.outputInlineXml(xsd.str());
  2863. writer.outputEndNested("XmlSchema");
  2864. }
  2865. writer.outputBeginDataset(name, true);
  2866. if (schemaName)
  2867. writer.outputCString(schemaName, "@xmlSchema");
  2868. if (xmlns)
  2869. {
  2870. Owned<IPropertyIterator> it = const_cast<IProperties*>(xmlns)->getIterator();
  2871. ForEach(*it)
  2872. {
  2873. const char *name = it->getPropKey();
  2874. writer.outputXmlns(name,const_cast<IProperties*>(xmlns)->queryProp(name));
  2875. }
  2876. }
  2877. cursor->beginWriteXmlRows(writer);
  2878. unsigned c=0;
  2879. for(bool ok=cursor->absolute(start);ok;ok=cursor->next())
  2880. {
  2881. cursor->writeXmlRow(writer);
  2882. c++;
  2883. if(count && c>=count)
  2884. break;
  2885. }
  2886. cursor->endWriteXmlRows(writer);
  2887. writer.outputEndDataset(name);
  2888. return c;
  2889. }
  2890. extern FILEVIEW_API unsigned writeResultXml(IXmlWriter & writer, INewResultSet * result, const char* name,unsigned start, unsigned count, const char * schemaName, const IProperties *xmlns)
  2891. {
  2892. Owned<IResultSetCursor> cursor = result->createCursor();
  2893. return writeResultCursorXml(writer, cursor, name, start, count, schemaName, xmlns);
  2894. }
  2895. extern FILEVIEW_API unsigned getResultCursorBin(MemoryBuffer & ret, IResultSetCursor * cursor, unsigned start, unsigned count)
  2896. {
  2897. const IResultSetMetaData & meta = cursor->queryResultSet()->getMetaData();
  2898. unsigned numCols = meta.getColumnCount();
  2899. unsigned c=0;
  2900. for(bool ok=cursor->absolute(start);ok;ok=cursor->next())
  2901. {
  2902. for (unsigned col=0; col < numCols; col++)
  2903. cursor->getRaw(MemoryBuffer2IDataVal(ret), col);
  2904. c++;
  2905. if(count && c>=count)
  2906. break;
  2907. }
  2908. return c;
  2909. }
  2910. extern FILEVIEW_API unsigned getResultBin(MemoryBuffer & ret, INewResultSet * result, unsigned start, unsigned count)
  2911. {
  2912. Owned<IResultSetCursor> cursor = result->createCursor();
  2913. return getResultCursorBin(ret, cursor, start, count);
  2914. }
  2915. inline const char *getSeverityTagname(ErrorSeverity severity, unsigned flags)
  2916. {
  2917. if (flags & WorkUnitXML_SeverityTags)
  2918. {
  2919. switch (severity)
  2920. {
  2921. case SeverityInformation:
  2922. return "Info";
  2923. case SeverityWarning:
  2924. return "Warning";
  2925. case SeverityAlert:
  2926. return "Alert";
  2927. case SeverityError:
  2928. default:
  2929. break;
  2930. }
  2931. }
  2932. return "Exception";
  2933. }
  2934. extern FILEVIEW_API void writeFullWorkUnitResults(const char *username, const char *password, const IConstWorkUnit *cw, IXmlWriter &writer, unsigned flags, ErrorSeverity minSeverity, const char *rootTag)
  2935. {
  2936. SCMStringBuffer wuid;
  2937. cw->getWuid(wuid);
  2938. if (rootTag && *rootTag && !(flags & WorkUnitXML_NoRoot))
  2939. writer.outputBeginNested(rootTag, true);
  2940. Owned<IConstWUExceptionIterator> exceptions = &cw->getExceptions();
  2941. ForEach(*exceptions)
  2942. {
  2943. IConstWUException & exception = exceptions->query();
  2944. ErrorSeverity severity = exception.getSeverity();
  2945. if (severity>=minSeverity)
  2946. {
  2947. SCMStringBuffer src, msg, filename;
  2948. exception.getExceptionSource(src);
  2949. exception.getExceptionMessage(msg);
  2950. exception.getExceptionFileName(filename);
  2951. unsigned lineno = exception.getExceptionLineNo();
  2952. unsigned code = exception.getExceptionCode();
  2953. writer.outputBeginNested(getSeverityTagname(severity, flags), false);
  2954. if (code)
  2955. writer.outputUInt(code, sizeof(unsigned), "Code");
  2956. if (filename.length())
  2957. writer.outputCString(filename.str(), "Filename");
  2958. if (lineno)
  2959. writer.outputUInt(lineno, sizeof(unsigned), "Line");
  2960. writer.outputCString(src.str(), "Source");
  2961. writer.outputCString(msg.str(), "Message");
  2962. writer.outputEndNested(getSeverityTagname(severity, flags));
  2963. }
  2964. }
  2965. Owned<IResultSetFactory> factory = getResultSetFactory(username, password);
  2966. switch (cw->getState())
  2967. {
  2968. case WUStateCompleted:
  2969. case WUStateWait:
  2970. {
  2971. Owned<IConstWUResultIterator> results = &cw->getResults();
  2972. ForEach(*results)
  2973. {
  2974. IConstWUResult &ds = results->query();
  2975. if (ds.getResultSequence()>=0 && (ds.getResultStatus() != ResultStatusUndefined))
  2976. {
  2977. SCMStringBuffer name;
  2978. ds.getResultName(name);
  2979. Owned<INewResultSet> nr = factory->createNewResultSet(&ds, wuid.str());
  2980. const IProperties *xmlns = ds.queryResultXmlns();
  2981. writeResultXml(writer, nr.get(), name.str(), 0, 0, (flags & WorkUnitXML_InclSchema) ? name.str() : NULL, xmlns);
  2982. }
  2983. }
  2984. }
  2985. break;
  2986. case WUStateAborted:
  2987. writer.outputBeginNested("Exception", false);
  2988. writer.outputCString("System", "Source");
  2989. writer.outputCString("Query aborted by operator", "Message");
  2990. writer.outputEndNested("Exception");
  2991. break;
  2992. }
  2993. if (rootTag && *rootTag && !(flags & WorkUnitXML_NoRoot))
  2994. writer.outputEndNested(rootTag);
  2995. }
  2996. extern FILEVIEW_API IStringVal& getFullWorkUnitResultsXML(const char *username, const char *password, const IConstWorkUnit *cw, IStringVal &str, unsigned flags, ErrorSeverity minSeverity)
  2997. {
  2998. SCMStringBuffer wuid;
  2999. cw->getWuid(wuid);
  3000. Owned<CommonXmlWriter> writer = CreateCommonXmlWriter(XWFexpandempty);
  3001. writeFullWorkUnitResults(username, password, cw, *writer, flags, minSeverity, "Result");
  3002. const char *xml = writer->str();
  3003. unsigned len = writer->length();
  3004. if (len && xml[len-1]=='\n')
  3005. len--;
  3006. str.setLen(xml, len);
  3007. return str;
  3008. }
  3009. extern FILEVIEW_API IStringVal& getFullWorkUnitResultsJSON(const char *username, const char *password, const IConstWorkUnit *cw, IStringVal &str, unsigned flags, ErrorSeverity minSeverity)
  3010. {
  3011. SCMStringBuffer wuid;
  3012. cw->getWuid(wuid);
  3013. Owned<CommonJsonWriter> writer = new CommonJsonWriter(0);
  3014. writer->outputBeginRoot();
  3015. writeFullWorkUnitResults(username, password, cw, *writer, flags, minSeverity, "Results");
  3016. writer->outputEndRoot();
  3017. str.set(writer->str());
  3018. return str;
  3019. }