ecl-queries.cpp 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666
  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 <stdio.h>
  14. #include "jlog.hpp"
  15. #include "jfile.hpp"
  16. #include "jargv.hpp"
  17. #include "jflz.hpp"
  18. #include "ws_workunits.hpp"
  19. #include "eclcmd.hpp"
  20. #include "eclcmd_common.hpp"
  21. #include "eclcmd_core.hpp"
  22. #include "workunit.hpp"
  23. #define INIFILE "ecl.ini"
  24. #define DEFAULTINIFILE "ecl.ini"
  25. //=========================================================================================
  26. class ActiveQueryMap
  27. {
  28. public:
  29. ActiveQueryMap(IConstWUQuerySetDetail &qs) : queryMap(createPTree())
  30. {
  31. IArrayOf<IConstQuerySetAlias> &aliases = qs.getAliases();
  32. ForEachItemIn(i, aliases)
  33. addMappedAlias(aliases.item(i).getId(), aliases.item(i).getName());
  34. }
  35. void addMappedAlias(const char *queryid, const char *alias)
  36. {
  37. if (queryid && *queryid && alias && *alias)
  38. ensureMappedQuery(queryid)->addProp("Alias", alias);
  39. }
  40. IPropertyTree *ensureMappedQuery(const char *queryid)
  41. {
  42. VStringBuffer xpath("Query[@id='%s']", queryid);
  43. IPropertyTree *query = queryMap->getPropTree(xpath.str());
  44. if (!query)
  45. {
  46. query = queryMap->addPropTree("Query", createPTree());
  47. query->setProp("@id", queryid);
  48. }
  49. return query;
  50. }
  51. bool isActive(const char *queryid)
  52. {
  53. VStringBuffer xpath("Query[@id='%s']", queryid);
  54. return queryMap->hasProp(xpath.str());
  55. }
  56. IPropertyTreeIterator *getActiveNames(const char *queryid)
  57. {
  58. VStringBuffer xpath("Query[@id='%s']/Alias", queryid);
  59. return queryMap->getElements(xpath.str());
  60. }
  61. private:
  62. Linked<IPropertyTree> queryMap;
  63. };
  64. #define QUERYLIST_SHOW_UNFLAGGED 0x01
  65. #define QUERYLIST_SHOW_ACTIVE 0x02
  66. #define QUERYLIST_SHOW_SUSPENDED 0x04
  67. #define QUERYLIST_SHOW_CLUSTER_SUSPENDED 0x08
  68. #define QUERYLIST_SHOW_INACTIVE (QUERYLIST_SHOW_UNFLAGGED | QUERYLIST_SHOW_SUSPENDED | QUERYLIST_SHOW_CLUSTER_SUSPENDED)
  69. class EclCmdQueriesList : public EclCmdCommon
  70. {
  71. public:
  72. EclCmdQueriesList() : flags(0), optInactive(false), optCheckAllNodes(false)
  73. {
  74. }
  75. virtual eclCmdOptionMatchIndicator parseCommandLineOptions(ArgvIterator &iter)
  76. {
  77. if (iter.done())
  78. return EclCmdOptionNoMatch;
  79. for (; !iter.done(); iter.next())
  80. {
  81. const char *arg = iter.query();
  82. if (*arg!='-')
  83. {
  84. optTargetCluster.set(arg);
  85. continue;
  86. }
  87. if (iter.matchOption(optTargetCluster, ECLOPT_CLUSTER_DEPRECATED)||iter.matchOption(optTargetCluster, ECLOPT_CLUSTER_DEPRECATED_S))
  88. continue;
  89. if (iter.matchOption(optTargetCluster, ECLOPT_TARGET)||iter.matchOption(optTargetCluster, ECLOPT_TARGET_S))
  90. continue;
  91. if (iter.matchFlag(optInactive, ECLOPT_INACTIVE))
  92. continue;
  93. if (iter.matchFlag(optCheckAllNodes, ECLOPT_CHECK_ALL_NODES))
  94. continue;
  95. StringAttr temp;
  96. if (iter.matchOption(temp, ECLOPT_SHOW))
  97. {
  98. for (const char *ch = temp.str(); *ch; ch++)
  99. {
  100. switch (*ch)
  101. {
  102. case 'A':
  103. flags |= QUERYLIST_SHOW_ACTIVE;
  104. break;
  105. case 'S':
  106. flags |= QUERYLIST_SHOW_SUSPENDED;
  107. break;
  108. case 'X':
  109. flags |= QUERYLIST_SHOW_CLUSTER_SUSPENDED;
  110. break;
  111. case 'U':
  112. flags |= QUERYLIST_SHOW_UNFLAGGED;
  113. break;
  114. default:
  115. fprintf(stderr, "Unrecognized --show flag = %c\n", *ch);
  116. return EclCmdOptionNoMatch;
  117. }
  118. }
  119. continue;
  120. }
  121. eclCmdOptionMatchIndicator ind = EclCmdCommon::matchCommandLineOption(iter, true);
  122. if (ind != EclCmdOptionMatch)
  123. return ind;
  124. }
  125. return EclCmdOptionMatch;
  126. }
  127. virtual bool finalizeOptions(IProperties *globals)
  128. {
  129. if (optInactive)
  130. {
  131. if (flags)
  132. {
  133. fputs("--show and --inactive should not be used together.\n", stderr);
  134. return false;
  135. }
  136. flags = QUERYLIST_SHOW_INACTIVE;
  137. }
  138. if (!optCheckAllNodes)
  139. extractEclCmdOption(optCheckAllNodes, globals, ECLOPT_CHECK_ALL_NODES_ENV, ECLOPT_CHECK_ALL_NODES_INI, false);
  140. if (!EclCmdCommon::finalizeOptions(globals))
  141. return false;
  142. return true;
  143. }
  144. void outputQuery(IConstQuerySetQuery &query, ActiveQueryMap &queryMap)
  145. {
  146. const char *queryid = query.getId();
  147. bool isActive = queryMap.isActive(queryid);
  148. bool suspendedOnCluster = false;
  149. ForEachItemIn(idx, query.getClusters())
  150. {
  151. IConstClusterQueryState &state = query.getClusters().item(idx);
  152. if (strieq(state.getState(), "Suspended"))
  153. {
  154. suspendedOnCluster = true;
  155. break;
  156. }
  157. }
  158. if (flags)
  159. {
  160. if (isActive && !(flags & QUERYLIST_SHOW_ACTIVE))
  161. return;
  162. if (query.getSuspended() && !(flags & QUERYLIST_SHOW_SUSPENDED))
  163. return;
  164. if (suspendedOnCluster && !(flags & QUERYLIST_SHOW_CLUSTER_SUSPENDED))
  165. return;
  166. if (!isActive && !query.getSuspended() && !(flags & QUERYLIST_SHOW_UNFLAGGED))
  167. return;
  168. }
  169. StringBuffer line(" ");
  170. line.append(suspendedOnCluster ? 'X' : ' ');
  171. line.append(query.getSuspended() ? 'S' : ' ');
  172. line.append(isActive ? 'A' : ' ');
  173. line.append(" ").append(queryid);
  174. if (line.length() < 34)
  175. line.appendN(34 - line.length(), ' ');
  176. line.append(' ').append(query.getWuid());
  177. if (query.getComment())
  178. {
  179. if (line.length() < 51)
  180. line.appendN(51 - line.length(), ' ');
  181. line.append(' ').append(query.getComment());
  182. }
  183. fputs(line.append('\n').str(), stdout);
  184. StringBuffer metaTags;
  185. if (!query.getTimeLimit_isNull())
  186. metaTags.append("timeLimit=").append(query.getTimeLimit());
  187. if (!query.getWarnTimeLimit_isNull())
  188. {
  189. if (metaTags.length())
  190. metaTags.append(", ");
  191. metaTags.append("warnTimeLimit=").append(query.getWarnTimeLimit());
  192. }
  193. if (query.getPriority())
  194. {
  195. if (metaTags.length())
  196. metaTags.append(", ");
  197. metaTags.append("priority=").append(query.getPriority());
  198. }
  199. if (query.getMemoryLimit())
  200. {
  201. if (metaTags.length())
  202. metaTags.append(", ");
  203. metaTags.append("memLimit=").append(query.getMemoryLimit());
  204. }
  205. if (query.getSnapshot())
  206. {
  207. if (metaTags.length())
  208. metaTags.append(", ");
  209. metaTags.append("snapshot=").append(query.getSnapshot());
  210. }
  211. if (metaTags.length())
  212. {
  213. fputs(" [", stdout);
  214. fputs(metaTags.str(), stdout);
  215. fputs("]\n\n", stdout);
  216. }
  217. }
  218. void outputQueryset(IConstWUQuerySetDetail &qs)
  219. {
  220. ActiveQueryMap queryMap(qs);
  221. if (qs.getQuerySetName())
  222. fprintf(stdout, "\nTarget: %s\n", qs.getQuerySetName());
  223. fputs("\n", stdout);
  224. fputs("Flags Query Id WUID Comment\n", stdout);
  225. fputs("----- ---------------------------- ---------------- ------------\n", stdout);
  226. IArrayOf<IConstQuerySetQuery> &queries = qs.getQueries();
  227. ForEachItemIn(id, queries)
  228. outputQuery(queries.item(id), queryMap);
  229. }
  230. virtual int processCMD()
  231. {
  232. Owned<IClientWsWorkunits> client = createCmdClient(WsWorkunits, *this);
  233. Owned<IClientWUMultiQuerySetDetailsRequest> req = client->createWUMultiQuerysetDetailsRequest();
  234. setCmdRequestTimeouts(req->rpc(), 0, optWaitConnectMs, optWaitReadSec);
  235. req->setQuerySetName(optTargetCluster.get());
  236. req->setClusterName(optTargetCluster.get());
  237. req->setFilterType("All");
  238. req->setCheckAllNodes(optCheckAllNodes);
  239. Owned<IClientWUMultiQuerySetDetailsResponse> resp = client->WUMultiQuerysetDetails(req);
  240. int ret = outputMultiExceptionsEx(resp->getExceptions());
  241. if (ret == 0)
  242. {
  243. IArrayOf<IConstWUQuerySetDetail> &querysets = resp->getQuerysets();
  244. ForEachItemIn(i, querysets)
  245. outputQueryset(querysets.item(i));
  246. }
  247. return ret;
  248. }
  249. virtual void usage()
  250. {
  251. fputs("\nUsage:\n"
  252. "\n"
  253. "The 'queries list' command displays a list of the queries published to one\n"
  254. "or more target clusters. If a target is provided the querysets associated with\n"
  255. "that cluster will be shown. If no queryset or cluster is specified all targets\n"
  256. "are shown.\n"
  257. "\n"
  258. "ecl queries list [<target>][--show=<flags>]\n\n"
  259. " Options:\n"
  260. " <target> Name of target cluster to get list of queries for\n"
  261. " --show=<flags> Show only queries with matching flags\n"
  262. " --inactive Show only queries that do not have an active alias\n"
  263. " --check-all-nodes Check query status on all nodes in the process cluster\n"
  264. " Flags:\n"
  265. " A Query is active\n"
  266. " S Query is suspended in queryset\n"
  267. //not yet " X Query is suspended on selected cluster\n"
  268. " U Query with no flags set\n"
  269. " Common Options:\n",
  270. stdout);
  271. EclCmdCommon::usage();
  272. }
  273. private:
  274. StringAttr optTargetCluster;
  275. unsigned flags;
  276. bool optInactive;
  277. bool optCheckAllNodes;
  278. };
  279. class EclCmdQueryFiles : public EclCmdCommon
  280. {
  281. public:
  282. EclCmdQueryFiles()
  283. {
  284. }
  285. virtual eclCmdOptionMatchIndicator parseCommandLineOptions(ArgvIterator &iter)
  286. {
  287. if (iter.done())
  288. return EclCmdOptionNoMatch;
  289. for (; !iter.done(); iter.next())
  290. {
  291. const char *arg = iter.query();
  292. if (*arg!='-')
  293. {
  294. if (optTarget.isEmpty())
  295. optTarget.set(arg);
  296. else if (optQuery.isEmpty())
  297. optQuery.set(arg);
  298. else
  299. {
  300. fprintf(stderr, "\n%s option not recognized\n", arg);
  301. return EclCmdOptionNoMatch;
  302. }
  303. continue;
  304. }
  305. eclCmdOptionMatchIndicator ind = EclCmdCommon::matchCommandLineOption(iter, true);
  306. if (ind != EclCmdOptionMatch)
  307. return ind;
  308. }
  309. return EclCmdOptionMatch;
  310. }
  311. virtual bool finalizeOptions(IProperties *globals)
  312. {
  313. if (optTarget.isEmpty())
  314. {
  315. fputs("Target must be specified.\n", stderr);
  316. return false;
  317. }
  318. if (!EclCmdCommon::finalizeOptions(globals))
  319. return false;
  320. return true;
  321. }
  322. void outputQueryFiles(const char *id, IArrayOf<IConstFileUsedByQuery> &files, IArrayOf<IConstQuerySuperFile> &superfiles)
  323. {
  324. fputs("------------------\n", stdout);
  325. if (!isEmptyString(id))
  326. fprintf(stdout, "Query: %s\n", id);
  327. if (!files.length())
  328. fputs("No files used.\n", stdout);
  329. else
  330. fputs("Files used:\n", stdout);
  331. ForEachItemIn(i, files)
  332. {
  333. IConstFileUsedByQuery &file = files.item(i);
  334. StringBuffer line(" ");
  335. line.append(file.getFileName()).append(", ");
  336. line.append(file.getFileSize()).append(" bytes, ");
  337. line.append(file.getNumberOfParts()).append(" part(s)\n");
  338. fputs(line, stdout);
  339. }
  340. fputs("\n", stdout);
  341. if (superfiles.length())
  342. {
  343. fputs("SuperFiles used:\n", stdout);
  344. ForEachItemIn(sp, superfiles)
  345. {
  346. IConstQuerySuperFile &superfile = superfiles.item(sp);
  347. fprintf(stdout, " %s\n", superfile.getName());
  348. StringArray &subfiles = superfile.getSubFiles();
  349. ForEachItemIn(sb, subfiles)
  350. fprintf(stdout, " > %s\n", subfiles.item(sb));
  351. }
  352. fputs("\n", stdout);
  353. }
  354. }
  355. virtual int processCMD()
  356. {
  357. Owned<IClientWsWorkunits> client = createCmdClient(WsWorkunits, *this);
  358. Owned<IClientWUQueryFilesRequest> req = client->createWUQueryFilesRequest();
  359. setCmdRequestTimeouts(req->rpc(), 0, optWaitConnectMs, optWaitReadSec);
  360. req->setTarget(optTarget.get());
  361. req->setQueryId(optQuery.get());
  362. Owned<IClientWUQueryFilesResponse> resp = client->WUQueryFiles(req);
  363. int ret = outputMultiExceptionsEx(resp->getExceptions());
  364. if (ret == 0)
  365. {
  366. IArrayOf<IConstFileUsedByQuery> &files = resp->getFiles();
  367. if (optQuery.length())
  368. outputQueryFiles(optQuery.str(), resp->getFiles(), resp->getSuperFiles());
  369. else
  370. {
  371. IArrayOf<IConstQueryFilesUsed> &queries = resp->getQueries();
  372. if (!queries.length())
  373. fputs("No queries found.\n", stdout);
  374. ForEachItemIn(i, queries)
  375. {
  376. IConstQueryFilesUsed &query = queries.item(i);
  377. outputQueryFiles(query.getQueryId(), query.getFiles(), query.getSuperFiles());
  378. }
  379. }
  380. }
  381. return ret;
  382. }
  383. virtual void usage()
  384. {
  385. fputs("\nUsage:\n"
  386. "\n"
  387. "The 'queries files' command displays a list of the files currently in use by\n"
  388. "the given query.\n"
  389. "\n"
  390. "ecl queries files <target> [<query>]\n\n"
  391. " Options:\n"
  392. " <target> Name of target cluster the query is published on\n"
  393. " <query> Name of the query to get a list of files in use by\n"
  394. " Common Options:\n",
  395. stdout);
  396. EclCmdCommon::usage();
  397. }
  398. private:
  399. StringAttr optTarget;
  400. StringAttr optQuery;
  401. };
  402. class EclCmdQueriesCopy : public EclCmdCommon
  403. {
  404. public:
  405. EclCmdQueriesCopy() : optActivate(false), optNoReload(false), optMsToWait(10000), optDontCopyFiles(false), optOverwrite(false), optAllowForeign(false),
  406. optUpdateSuperfiles(false), optUpdateCloneFrom(false), optDontAppendCluster(false)
  407. {
  408. optTimeLimit = (unsigned) -1;
  409. optWarnTimeLimit = (unsigned) -1;
  410. }
  411. virtual eclCmdOptionMatchIndicator parseCommandLineOptions(ArgvIterator &iter)
  412. {
  413. if (iter.done())
  414. return EclCmdOptionNoMatch;
  415. for (; !iter.done(); iter.next())
  416. {
  417. const char *arg = iter.query();
  418. if (*arg!='-')
  419. {
  420. if (optSourceQueryPath.isEmpty())
  421. optSourceQueryPath.set(arg);
  422. else if (optTargetCluster.isEmpty())
  423. optTargetCluster.set(arg);
  424. else
  425. {
  426. fprintf(stderr, "\nunrecognized argument %s\n", arg);
  427. return EclCmdOptionNoMatch;
  428. }
  429. continue;
  430. }
  431. if (iter.matchOption(optDaliIP, ECLOPT_DALIIP))
  432. continue;
  433. if (iter.matchOption(optSourceProcess, ECLOPT_SOURCE_PROCESS))
  434. continue;
  435. if (iter.matchFlag(optActivate, ECLOPT_ACTIVATE)||iter.matchFlag(optActivate, ECLOPT_ACTIVATE_S))
  436. continue;
  437. if (iter.matchFlag(optSourceSSL, ECLOPT_SOURCE_SSL))
  438. continue;
  439. if (iter.matchFlag(optSourceNoSSL, ECLOPT_SOURCE_NO_SSL))
  440. continue;
  441. if (iter.matchFlag(optSuspendPrevious, ECLOPT_SUSPEND_PREVIOUS)||iter.matchFlag(optSuspendPrevious, ECLOPT_SUSPEND_PREVIOUS_S))
  442. continue;
  443. if (iter.matchFlag(optDeletePrevious, ECLOPT_DELETE_PREVIOUS)||iter.matchFlag(optDeletePrevious, ECLOPT_DELETE_PREVIOUS_S))
  444. continue;
  445. if (iter.matchFlag(optNoReload, ECLOPT_NORELOAD))
  446. continue;
  447. if (iter.matchOption(optTargetCluster, ECLOPT_CLUSTER_DEPRECATED)||iter.matchOption(optTargetCluster, ECLOPT_CLUSTER_DEPRECATED_S))
  448. continue;
  449. if (iter.matchOption(optTargetCluster, ECLOPT_TARGET)||iter.matchOption(optTargetCluster, ECLOPT_TARGET_S))
  450. continue;
  451. if (iter.matchFlag(optDontCopyFiles, ECLOPT_DONT_COPY_FILES))
  452. continue;
  453. if (iter.matchFlag(optAllowForeign, ECLOPT_ALLOW_FOREIGN))
  454. continue;
  455. if (iter.matchOption(optMsToWait, ECLOPT_WAIT))
  456. continue;
  457. if (iter.matchOption(optTimeLimit, ECLOPT_TIME_LIMIT))
  458. continue;
  459. if (iter.matchOption(optWarnTimeLimit, ECLOPT_WARN_TIME_LIMIT))
  460. continue;
  461. if (iter.matchOption(optMemoryLimit, ECLOPT_MEMORY_LIMIT))
  462. continue;
  463. if (iter.matchOption(optPriority, ECLOPT_PRIORITY))
  464. continue;
  465. if (iter.matchOption(optComment, ECLOPT_COMMENT))
  466. continue;
  467. if (iter.matchFlag(optOverwrite, ECLOPT_OVERWRITE)||iter.matchFlag(optOverwrite, ECLOPT_OVERWRITE_S))
  468. continue;
  469. if (iter.matchFlag(optUpdateSuperfiles, ECLOPT_UPDATE_SUPER_FILES))
  470. continue;
  471. if (iter.matchFlag(optUpdateCloneFrom, ECLOPT_UPDATE_CLONE_FROM))
  472. continue;
  473. if (iter.matchFlag(optDontAppendCluster, ECLOPT_DONT_APPEND_CLUSTER))
  474. continue;
  475. if (iter.matchFlag(optUpdateSuperfiles, ECLOPT_UPDATE_SUPER_FILES))
  476. continue;
  477. if (iter.matchFlag(optUpdateCloneFrom, ECLOPT_UPDATE_CLONE_FROM))
  478. continue;
  479. if (iter.matchFlag(optDontAppendCluster, ECLOPT_DONT_APPEND_CLUSTER))
  480. continue;
  481. if (iter.matchOption(optName, ECLOPT_NAME)||iter.matchOption(optName, ECLOPT_NAME_S))
  482. continue;
  483. eclCmdOptionMatchIndicator ind = EclCmdCommon::matchCommandLineOption(iter, true);
  484. if (ind != EclCmdOptionMatch)
  485. return ind;
  486. }
  487. return EclCmdOptionMatch;
  488. }
  489. virtual bool finalizeOptions(IProperties *globals)
  490. {
  491. if (!EclCmdCommon::finalizeOptions(globals))
  492. return false;
  493. if (optSourceQueryPath.isEmpty() && optTargetCluster.isEmpty())
  494. {
  495. fputs("source and target must both be specified.\n", stderr);
  496. return false;
  497. }
  498. if (optMemoryLimit.length() && !isValidMemoryValue(optMemoryLimit))
  499. {
  500. fprintf(stderr, "invalid --memoryLimit value of %s.\n", optMemoryLimit.get());
  501. return false;
  502. }
  503. if (optPriority.length() && !isValidPriorityValue(optPriority))
  504. {
  505. fprintf(stderr, "invalid --priority value of %s.\n", optPriority.get());
  506. return false;
  507. }
  508. if (!optActivate && (optSuspendPrevious || optDeletePrevious))
  509. {
  510. fputs("invalid --suspend-prev and --delete-prev require --activate.\n", stderr);
  511. return false;
  512. }
  513. if (optSuspendPrevious && optDeletePrevious)
  514. {
  515. fputs("invalid --suspend-prev and --delete-prev are mutually exclusive options.\n", stderr);
  516. return false;
  517. }
  518. return true;
  519. }
  520. inline bool useSSLForSource()
  521. {
  522. if (optSourceSSL)
  523. return true;
  524. if (optSourceNoSSL)
  525. return false;
  526. return optSSL; //default to whether we use SSL to call ESP
  527. }
  528. virtual int processCMD()
  529. {
  530. Owned<IClientWsWorkunits> client = createCmdClient(WsWorkunits, *this);
  531. Owned<IClientWUQuerySetCopyQueryRequest> req = client->createWUQuerysetCopyQueryRequest();
  532. setCmdRequestTimeouts(req->rpc(), 0, optWaitConnectMs, optWaitReadSec);
  533. req->setSource(optSourceQueryPath.get());
  534. req->setTarget(optTargetCluster.get());
  535. req->setCluster(optTargetCluster.get());
  536. req->setDaliServer(optDaliIP.get());
  537. req->setSourceProcess(optSourceProcess);
  538. if (optDeletePrevious)
  539. req->setActivate(CWUQueryActivationMode_ActivateDeletePrevious);
  540. else if (optSuspendPrevious)
  541. req->setActivate(CWUQueryActivationMode_ActivateSuspendPrevious);
  542. else
  543. req->setActivate(optActivate ? CWUQueryActivationMode_Activate : CWUQueryActivationMode_NoActivate);
  544. req->setOverwrite(optOverwrite);
  545. req->setUpdateSuperFiles(optUpdateSuperfiles);
  546. req->setUpdateCloneFrom(optUpdateCloneFrom);
  547. req->setAppendCluster(!optDontAppendCluster);
  548. req->setDontCopyFiles(optDontCopyFiles);
  549. req->setWait(optMsToWait);
  550. req->setNoReload(optNoReload);
  551. req->setAllowForeignFiles(optAllowForeign);
  552. req->setIncludeFileErrors(true);
  553. //default to same tcp/tls as our ESP connection, but can be changed using --source-ssl or --source-no-ssl
  554. req->setSourceSSL(useSSLForSource());
  555. if (optTimeLimit != (unsigned) -1)
  556. req->setTimeLimit(optTimeLimit);
  557. if (optWarnTimeLimit != (unsigned) -1)
  558. req->setWarnTimeLimit(optWarnTimeLimit);
  559. if (!optMemoryLimit.isEmpty())
  560. req->setMemoryLimit(optMemoryLimit);
  561. if (!optPriority.isEmpty())
  562. req->setPriority(optPriority);
  563. if (!optName.isEmpty())
  564. req->setDestName(optName);
  565. if (optComment.get()) //allow empty
  566. req->setComment(optComment);
  567. Owned<IClientWUQuerySetCopyQueryResponse> resp = client->WUQuerysetCopyQuery(req);
  568. int ret = outputMultiExceptionsEx(resp->getExceptions());
  569. if (outputQueryFileCopyErrors(resp->getFileErrors()))
  570. ret = 1;
  571. if (resp->getQueryId() && *resp->getQueryId())
  572. fprintf(stdout, "%s/%s\n\n", optTargetQuerySet.str(), resp->getQueryId());
  573. return ret;
  574. }
  575. virtual void usage()
  576. {
  577. fputs("\nUsage:\n"
  578. "\n"
  579. "The 'queries copy' command copies a query from one queryset to another.\n"
  580. "\n"
  581. "A query can be copied from one HPCC environment to another by using a path\n"
  582. "which begins with '//' followed by the IP and Port of the source EclWatch\n"
  583. "and then followed by the source queryset and query.\n"
  584. "\n"
  585. "ecl queries copy <source_query_path> <target> [--activate]\n"
  586. "\n"
  587. "ecl queries copy //IP:Port/queryset/query <target> [--activate]\n"
  588. "ecl queries copy queryset/query <target> [--activate]\n"
  589. "\n"
  590. " Options:\n"
  591. " <source_query_path> Path of query to copy\n"
  592. " in the form: //ip:port/queryset/query\n"
  593. " or: queryset/query\n"
  594. " <target> Name of target cluster to copy the query to\n"
  595. " --source-ssl Use SSL when connecting to source (default if --ssl is used)\n"
  596. " --source-no-ssl Do not use SSL when connecting to source (default if --ssl is NOT used)\n"
  597. " --no-files Do not copy DFS file information for referenced files\n"
  598. " --daliip=<ip> Remote Dali DFS to use for copying file information\n"
  599. " (only required if remote environment version < 3.8)\n"
  600. " --source-process Process cluster to copy files from\n"
  601. " -A, --activate Activate the new query\n"
  602. " -sp, --suspend-prev Suspend previously active query\n"
  603. " -dp, --delete-prev Delete previously active query\n"
  604. " --no-reload Do not request a reload of the (roxie) cluster\n"
  605. " -O, --overwrite Completely replace existing DFS file information (dangerous)\n"
  606. " --update-super-files Update local DFS super-files if remote DALI has changed\n"
  607. " --update-clone-from Update local clone from location if remote DALI has changed\n"
  608. " --dont-append-cluster Only use to avoid locking issues due to adding cluster to file\n"
  609. " --allow-foreign Do not fail if foreign files are used in query (roxie)\n"
  610. " --wait=<ms> Max time to wait in milliseconds\n"
  611. " --timeLimit=<sec> Value to set for query timeLimit configuration\n"
  612. " --warnTimeLimit=<sec> Value to set for query warnTimeLimit configuration\n"
  613. " --memoryLimit=<mem> Value to set for query memoryLimit configuration\n"
  614. " format <mem> as 500000B, 550K, 100M, 10G, 1T etc.\n"
  615. " --priority=<val> Set the priority for this query. Value can be LOW,\n"
  616. " HIGH, SLA, NONE. NONE will clear current setting.\n"
  617. " --comment=<string> Set the comment associated with this query\n"
  618. " -n, --name=<val> Destination query name for the copied query\n"
  619. " Common Options:\n",
  620. stdout);
  621. EclCmdCommon::usage();
  622. }
  623. private:
  624. StringAttr optSourceQueryPath;
  625. StringAttr optTargetQuerySet;
  626. StringAttr optTargetCluster;
  627. StringAttr optDaliIP;
  628. StringAttr optSourceProcess;
  629. StringAttr optMemoryLimit;
  630. StringAttr optPriority;
  631. StringAttr optComment;
  632. StringAttr optName;
  633. unsigned optMsToWait;
  634. unsigned optTimeLimit;
  635. unsigned optWarnTimeLimit;
  636. bool optActivate;
  637. bool optSuspendPrevious = false;
  638. bool optDeletePrevious = false;
  639. bool optNoReload;
  640. bool optOverwrite;
  641. bool optUpdateSuperfiles;
  642. bool optUpdateCloneFrom;
  643. bool optDontAppendCluster; //Undesirable but here temporarily because DALI may have locking issues
  644. bool optDontCopyFiles;
  645. bool optAllowForeign;
  646. bool optSourceSSL = false; //user explicitly turning on SSL for accessing the remote source location (ssl defaults to use SSL if we are hitting ESP via SSL)
  647. bool optSourceNoSSL = false; //user explicitly turning OFF SSL for accessing the remote source location (ssl defaults to not use SSL if we are not hitting ESP via SSL)
  648. };
  649. class EclCmdQueriesCopyQueryset : public EclCmdCommon
  650. {
  651. public:
  652. EclCmdQueriesCopyQueryset() : optCloneActiveState(false), optAllQueries(false), optDontCopyFiles(false), optOverwrite(false), optAllowForeign(false),
  653. optUpdateSuperfiles(false), optUpdateCloneFrom(false), optDontAppendCluster(false)
  654. {
  655. }
  656. virtual eclCmdOptionMatchIndicator parseCommandLineOptions(ArgvIterator &iter)
  657. {
  658. if (iter.done())
  659. return EclCmdOptionNoMatch;
  660. for (; !iter.done(); iter.next())
  661. {
  662. const char *arg = iter.query();
  663. if (*arg!='-')
  664. {
  665. if (optSourceQuerySet.isEmpty())
  666. optSourceQuerySet.set(arg);
  667. else if (optDestQuerySet.isEmpty())
  668. optDestQuerySet.set(arg);
  669. else
  670. {
  671. fprintf(stderr, "\nunrecognized argument %s\n", arg);
  672. return EclCmdOptionNoMatch;
  673. }
  674. continue;
  675. }
  676. if (iter.matchFlag(optSourceSSL, ECLOPT_SOURCE_SSL))
  677. continue;
  678. if (iter.matchFlag(optSourceNoSSL, ECLOPT_SOURCE_NO_SSL))
  679. continue;
  680. if (iter.matchOption(optDaliIP, ECLOPT_DALIIP))
  681. continue;
  682. if (iter.matchOption(optSourceProcess, ECLOPT_SOURCE_PROCESS))
  683. continue;
  684. if (iter.matchFlag(optCloneActiveState, ECLOPT_CLONE_ACTIVE_STATE))
  685. continue;
  686. if (iter.matchFlag(optDontCopyFiles, ECLOPT_DONT_COPY_FILES))
  687. continue;
  688. if (iter.matchFlag(optAllQueries, ECLOPT_ALL))
  689. continue;
  690. if (iter.matchFlag(optAllowForeign, ECLOPT_ALLOW_FOREIGN))
  691. continue;
  692. if (iter.matchFlag(optOverwrite, ECLOPT_OVERWRITE)||iter.matchFlag(optOverwrite, ECLOPT_OVERWRITE_S))
  693. continue;
  694. if (iter.matchFlag(optUpdateSuperfiles, ECLOPT_UPDATE_SUPER_FILES))
  695. continue;
  696. if (iter.matchFlag(optUpdateCloneFrom, ECLOPT_UPDATE_CLONE_FROM))
  697. continue;
  698. if (iter.matchFlag(optDontAppendCluster, ECLOPT_DONT_APPEND_CLUSTER))
  699. continue;
  700. eclCmdOptionMatchIndicator ind = EclCmdCommon::matchCommandLineOption(iter, true);
  701. if (ind != EclCmdOptionMatch)
  702. return ind;
  703. }
  704. return EclCmdOptionMatch;
  705. }
  706. virtual bool finalizeOptions(IProperties *globals)
  707. {
  708. if (!EclCmdCommon::finalizeOptions(globals))
  709. return false;
  710. if (optSourceQuerySet.isEmpty() || optDestQuerySet.isEmpty())
  711. {
  712. fputs("source and destination querysets must both be specified.\n", stderr);
  713. return false;
  714. }
  715. return true;
  716. }
  717. inline bool useSSLForSource()
  718. {
  719. if (optSourceSSL)
  720. return true;
  721. if (optSourceNoSSL)
  722. return false;
  723. return optSSL; //default to whether we use SSL to call ESP
  724. }
  725. virtual int processCMD()
  726. {
  727. Owned<IClientWsWorkunits> client = createCmdClient(WsWorkunits, *this);
  728. Owned<IClientWUCopyQuerySetRequest> req = client->createWUCopyQuerySetRequest();
  729. setCmdRequestTimeouts(req->rpc(), 0, optWaitConnectMs, optWaitReadSec);
  730. req->setActiveOnly(!optAllQueries);
  731. req->setSource(optSourceQuerySet.get());
  732. req->setTarget(optDestQuerySet.get());
  733. req->setDfsServer(optDaliIP.get());
  734. req->setSourceProcess(optSourceProcess);
  735. req->setCloneActiveState(optCloneActiveState);
  736. req->setOverwriteDfs(optOverwrite);
  737. req->setUpdateSuperFiles(optUpdateSuperfiles);
  738. req->setUpdateCloneFrom(optUpdateCloneFrom);
  739. req->setAppendCluster(!optDontAppendCluster);
  740. req->setCopyFiles(!optDontCopyFiles);
  741. req->setAllowForeignFiles(optAllowForeign);
  742. req->setIncludeFileErrors(true);
  743. //default to same tcp/tls as our ESP connection, but can be changed using --source-ssl or --source-no-ssl
  744. req->setSourceSSL(useSSLForSource());
  745. Owned<IClientWUCopyQuerySetResponse> resp = client->WUCopyQuerySet(req);
  746. int ret = outputMultiExceptionsEx(resp->getExceptions());
  747. if (outputQueryFileCopyErrors(resp->getFileErrors()))
  748. ret = 1;
  749. StringArray &copied = resp->getCopiedQueries();
  750. fputs("Queries copied:\n", stdout);
  751. if (!copied.length())
  752. fputs(" none\n\n", stdout);
  753. else
  754. {
  755. ForEachItemIn(i, copied)
  756. fprintf(stdout, " %s\n", copied.item(i));
  757. fputs("\n", stdout);
  758. }
  759. StringArray &existing = resp->getExistingQueries();
  760. fputs("Queries already on destination target:\n", stdout);
  761. if (!existing.length())
  762. fputs(" none\n\n", stdout);
  763. else
  764. {
  765. ForEachItemIn(i, existing)
  766. fprintf(stdout, " %s\n", existing.item(i));
  767. fputs("\n", stdout);
  768. }
  769. return ret;
  770. }
  771. virtual void usage()
  772. {
  773. fputs("\nUsage:\n"
  774. "\n"
  775. "The 'queries copy-set' command copies a set of queries from one target to another.\n"
  776. "\n"
  777. "By default only active queries will be copied. Use --all to copy all queries.\n"
  778. "\n"
  779. "ecl queries copy-set <source_target> <destination_target> [--clone-active-state]\n"
  780. "ecl queries copy-set roxie1 roxie2\n"
  781. "ecl queries copy-set //ip:port/roxie1 roxie2 --clone-active-state\n"
  782. "\n"
  783. " Options:\n"
  784. " <source_target> Name of local (or path to remote) target cluster to"
  785. " copy queries from\n"
  786. " <destination_target> Target cluster to copy queries to\n"
  787. " --source-ssl Use SSL when connecting to source (default if --ssl is used)\n"
  788. " --source-no-ssl Do not use SSL when connecting to source (default if --ssl is NOT used)\n"
  789. " --all Copy both active and inactive queries\n"
  790. " --no-files Do not copy DFS file information for referenced files\n"
  791. " --daliip=<ip> Remote Dali DFS to use for copying file information\n"
  792. " --source-process Process cluster to copy files from\n"
  793. " --clone-active-state Make copied queries active if active on source\n"
  794. " -O, --overwrite Completely replace existing DFS file information (dangerous)\n"
  795. " --update-super-files Update local DFS super-files if remote DALI has changed\n"
  796. " --update-clone-from Update local clone from location if remote DALI has changed\n"
  797. " --dont-append-cluster Only use to avoid locking issues due to adding cluster to file\n"
  798. " --allow-foreign Do not fail if foreign files are used in query (roxie)\n"
  799. " Common Options:\n",
  800. stdout);
  801. EclCmdCommon::usage();
  802. }
  803. private:
  804. StringAttr optSourceQuerySet;
  805. StringAttr optDestQuerySet;
  806. StringAttr optDaliIP;
  807. StringAttr optSourceProcess;
  808. bool optCloneActiveState;
  809. bool optOverwrite;
  810. bool optUpdateSuperfiles;
  811. bool optUpdateCloneFrom;
  812. bool optDontAppendCluster; //Undesirable but here temporarily because DALI may have locking issues
  813. bool optDontCopyFiles;
  814. bool optAllowForeign;
  815. bool optAllQueries;
  816. bool optSourceSSL = false; //user explicitly turning on SSL for accessing the remote source location (ssl defaults to use SSL if we are hitting ESP via SSL)
  817. bool optSourceNoSSL = false; //user explicitly turning OFF SSL for accessing the remote source location (ssl defaults to not use SSL if we are not hitting ESP via SSL)
  818. };
  819. class EclCmdQueriesConfig : public EclCmdCommon
  820. {
  821. public:
  822. EclCmdQueriesConfig() : optNoReload(false), optMsToWait(10000)
  823. {
  824. optTimeLimit = (unsigned) -1;
  825. optWarnTimeLimit = (unsigned) -1;
  826. }
  827. virtual eclCmdOptionMatchIndicator parseCommandLineOptions(ArgvIterator &iter)
  828. {
  829. if (iter.done())
  830. return EclCmdOptionNoMatch;
  831. for (; !iter.done(); iter.next())
  832. {
  833. const char *arg = iter.query();
  834. if (*arg!='-')
  835. {
  836. if (optTargetCluster.isEmpty())
  837. optTargetCluster.set(arg);
  838. else if (optQueryId.isEmpty())
  839. optQueryId.set(arg);
  840. else
  841. {
  842. fprintf(stderr, "\nunrecognized argument %s\n", arg);
  843. return EclCmdOptionNoMatch;
  844. }
  845. continue;
  846. }
  847. if (iter.matchFlag(optNoReload, ECLOPT_NORELOAD))
  848. continue;
  849. if (iter.matchOption(optMsToWait, ECLOPT_WAIT))
  850. continue;
  851. if (iter.matchOption(optTimeLimit, ECLOPT_TIME_LIMIT))
  852. continue;
  853. if (iter.matchOption(optWarnTimeLimit, ECLOPT_WARN_TIME_LIMIT))
  854. continue;
  855. if (iter.matchOption(optMemoryLimit, ECLOPT_MEMORY_LIMIT))
  856. continue;
  857. if (iter.matchOption(optPriority, ECLOPT_PRIORITY))
  858. continue;
  859. if (iter.matchOption(optComment, ECLOPT_COMMENT))
  860. continue;
  861. eclCmdOptionMatchIndicator ind = EclCmdCommon::matchCommandLineOption(iter, true);
  862. if (ind != EclCmdOptionMatch)
  863. return ind;
  864. }
  865. return EclCmdOptionMatch;
  866. }
  867. virtual bool finalizeOptions(IProperties *globals)
  868. {
  869. if (!EclCmdCommon::finalizeOptions(globals))
  870. return false;
  871. if (optTargetCluster.isEmpty() || optQueryId.isEmpty())
  872. {
  873. fputs("Target and QueryId must both be specified.\n", stderr);
  874. return false;
  875. }
  876. if (optMemoryLimit.length() && !isValidMemoryValue(optMemoryLimit))
  877. {
  878. fprintf(stderr, "invalid --memoryLimit value of %s.\n", optMemoryLimit.get());
  879. return false;
  880. }
  881. if (optPriority.length() && !isValidPriorityValue(optPriority))
  882. {
  883. fprintf(stderr, "invalid --priority value of %s.\n", optPriority.get());
  884. return false;
  885. }
  886. return true;
  887. }
  888. virtual int processCMD()
  889. {
  890. Owned<IClientWsWorkunits> client = createCmdClient(WsWorkunits, *this);
  891. Owned<IClientWUQueryConfigRequest> req = client->createWUQueryConfigRequest();
  892. setCmdRequestTimeouts(req->rpc(), optMsToWait, optWaitConnectMs, optWaitReadSec);
  893. req->setTarget(optTargetCluster.get());
  894. req->setQueryId(optQueryId.get());
  895. req->setWait(optMsToWait);
  896. req->setNoReload(optNoReload);
  897. if (optTimeLimit != (unsigned) -1)
  898. req->setTimeLimit(optTimeLimit);
  899. if (optWarnTimeLimit != (unsigned) -1)
  900. req->setWarnTimeLimit(optWarnTimeLimit);
  901. if (!optMemoryLimit.isEmpty())
  902. req->setMemoryLimit(optMemoryLimit);
  903. if (!optPriority.isEmpty())
  904. req->setPriority(optPriority);
  905. if (optComment.get()) //allow empty
  906. req->setComment(optComment);
  907. Owned<IClientWUQueryConfigResponse> resp = client->WUQueryConfig(req);
  908. int ret = outputMultiExceptionsEx(resp->getExceptions());
  909. IArrayOf<IConstWUQueryConfigResult> &results = resp->getResults();
  910. if (results.length())
  911. {
  912. fputs("configured:\n", stdout);
  913. ForEachItemIn(i, results)
  914. fprintf(stdout, " %s\n", results.item(i).getQueryId());
  915. }
  916. return ret;
  917. }
  918. virtual void usage()
  919. {
  920. fputs("\nUsage:\n"
  921. "\n"
  922. "The 'queries config' command updates query configuration values.\n"
  923. "\n"
  924. "ecl queries config <target> <queryid> [options]\n"
  925. "\n"
  926. " Options:\n"
  927. " <target> Name of target queryset containing query\n"
  928. " <queryid> Id of the query to configure\n"
  929. " --no-reload Do not request a reload of the (roxie) cluster\n"
  930. " --wait=<ms> Max time to wait in milliseconds\n"
  931. " --timeLimit=<sec> Value to set for query timeLimit configuration\n"
  932. " --warnTimeLimit=<sec> Value to set for query warnTimeLimit configuration\n"
  933. " --memoryLimit=<mem> Value to set for query memoryLimit configuration\n"
  934. " format <mem> as 500000B, 550K, 100M, 10G, 1T etc.\n"
  935. " --priority=<val> Set the priority for this query. Value can be LOW,\n"
  936. " HIGH, SLA, NONE. NONE will clear current setting.\n"
  937. " --comment=<string> Set the comment associated with this query\n"
  938. " Common Options:\n",
  939. stdout);
  940. EclCmdCommon::usage();
  941. }
  942. private:
  943. StringAttr optTargetCluster;
  944. StringAttr optQueryId;
  945. StringAttr optMemoryLimit;
  946. StringAttr optPriority;
  947. StringAttr optComment;
  948. unsigned optMsToWait;
  949. unsigned optTimeLimit;
  950. unsigned optWarnTimeLimit;
  951. bool optNoReload;
  952. };
  953. class EclCmdQueriesRecreate : public EclCmdCommon
  954. {
  955. public:
  956. EclCmdQueriesRecreate()
  957. {
  958. }
  959. virtual eclCmdOptionMatchIndicator parseCommandLineOptions(ArgvIterator &iter)
  960. {
  961. if (iter.done())
  962. return EclCmdOptionNoMatch;
  963. for (; !iter.done(); iter.next())
  964. {
  965. const char *arg = iter.query();
  966. if (*arg!='-')
  967. {
  968. if (optTarget.isEmpty())
  969. optTarget.set(arg);
  970. else if (optQueryId.isEmpty())
  971. optQueryId.set(arg);
  972. else if (optDestTarget.isEmpty())
  973. optDestTarget.set(arg);
  974. else
  975. {
  976. fprintf(stderr, "\nunrecognized argument %s\n", arg);
  977. return EclCmdOptionNoMatch;
  978. }
  979. continue;
  980. }
  981. if (iter.matchOption(optDaliIP, ECLOPT_DALIIP))
  982. continue;
  983. if (iter.matchOption(optSourceProcess, ECLOPT_SOURCE_PROCESS))
  984. continue;
  985. if (iter.matchOption(optMsToWait, ECLOPT_WAIT))
  986. continue;
  987. if (iter.matchOption(optTimeLimit, ECLOPT_TIME_LIMIT))
  988. continue;
  989. if (iter.matchOption(optWarnTimeLimit, ECLOPT_WARN_TIME_LIMIT))
  990. continue;
  991. if (iter.matchOption(optMemoryLimit, ECLOPT_MEMORY_LIMIT))
  992. continue;
  993. if (iter.matchOption(optPriority, ECLOPT_PRIORITY))
  994. continue;
  995. if (iter.matchOption(optComment, ECLOPT_COMMENT))
  996. continue;
  997. if (iter.matchFlag(optDontCopyFiles, ECLOPT_DONT_COPY_FILES))
  998. continue;
  999. if (iter.matchFlag(optAllowForeign, ECLOPT_ALLOW_FOREIGN))
  1000. continue;
  1001. if (iter.matchFlag(optNoActivate, ECLOPT_NO_ACTIVATE))
  1002. {
  1003. activateSet=true;
  1004. continue;
  1005. }
  1006. if (iter.matchFlag(optNoReload, ECLOPT_NORELOAD))
  1007. continue;
  1008. if (iter.matchFlag(optNoPublish, ECLOPT_NOPUBLISH))
  1009. continue;
  1010. bool activate; //also supports "-A-"
  1011. if (iter.matchFlag(activate, ECLOPT_ACTIVATE)||iter.matchFlag(activate, ECLOPT_ACTIVATE_S))
  1012. {
  1013. activateSet=true;
  1014. optNoActivate=!activate;
  1015. continue;
  1016. }
  1017. if (iter.matchFlag(optSuspendPrevious, ECLOPT_SUSPEND_PREVIOUS)||iter.matchFlag(optSuspendPrevious, ECLOPT_SUSPEND_PREVIOUS_S))
  1018. continue;
  1019. if (iter.matchFlag(optDeletePrevious, ECLOPT_DELETE_PREVIOUS)||iter.matchFlag(optDeletePrevious, ECLOPT_DELETE_PREVIOUS_S))
  1020. continue;
  1021. if (iter.matchFlag(optUpdateDfs, ECLOPT_UPDATE_DFS))
  1022. continue;
  1023. if (iter.matchFlag(optUpdateSuperfiles, ECLOPT_UPDATE_SUPER_FILES))
  1024. continue;
  1025. if (iter.matchFlag(optUpdateCloneFrom, ECLOPT_UPDATE_CLONE_FROM))
  1026. continue;
  1027. if (iter.matchFlag(optDontAppendCluster, ECLOPT_DONT_APPEND_CLUSTER))
  1028. continue;
  1029. if (iter.matchOption(optResultLimit, ECLOPT_RESULT_LIMIT))
  1030. continue;
  1031. if (matchVariableOption(iter, 'f', debugValues, true))
  1032. continue;
  1033. eclCmdOptionMatchIndicator ind = EclCmdCommon::matchCommandLineOption(iter, true);
  1034. if (ind != EclCmdOptionMatch)
  1035. return ind;
  1036. }
  1037. return EclCmdOptionMatch;
  1038. }
  1039. virtual bool finalizeOptions(IProperties *globals)
  1040. {
  1041. if (!EclCmdCommon::finalizeOptions(globals))
  1042. return false;
  1043. if (optTarget.isEmpty())
  1044. {
  1045. fputs("Target not specified.\n", stderr);
  1046. return false;
  1047. }
  1048. if (optQueryId.isEmpty())
  1049. {
  1050. fputs("Query not specified.\n", stderr);
  1051. return false;
  1052. }
  1053. if (!activateSet)
  1054. {
  1055. bool activate;
  1056. if (extractEclCmdOption(activate, globals, ECLOPT_ACTIVATE_ENV, ECLOPT_ACTIVATE_INI, true))
  1057. optNoActivate=!activate;
  1058. }
  1059. if (optNoActivate && (optSuspendPrevious || optDeletePrevious))
  1060. {
  1061. fputs("invalid --suspend-prev and --delete-prev require activation.\n", stderr);
  1062. return false;
  1063. }
  1064. if (!optSuspendPrevious && !optDeletePrevious)
  1065. {
  1066. extractEclCmdOption(optDeletePrevious, globals, ECLOPT_DELETE_PREVIOUS_ENV, ECLOPT_DELETE_PREVIOUS_INI, false);
  1067. if (!optDeletePrevious)
  1068. extractEclCmdOption(optSuspendPrevious, globals, ECLOPT_SUSPEND_PREVIOUS_ENV, ECLOPT_SUSPEND_PREVIOUS_INI, false);
  1069. }
  1070. if (optSuspendPrevious && optDeletePrevious)
  1071. {
  1072. fputs("invalid --suspend-prev and --delete-prev are mutually exclusive options.\n", stderr);
  1073. return false;
  1074. }
  1075. if (optMemoryLimit.length() && !isValidMemoryValue(optMemoryLimit))
  1076. {
  1077. fprintf(stderr, "invalid --memoryLimit value of %s.\n", optMemoryLimit.get());
  1078. return false;
  1079. }
  1080. if (optPriority.length() && !isValidPriorityValue(optPriority))
  1081. {
  1082. fprintf(stderr, "invalid --priority value of %s.\n", optPriority.get());
  1083. return false;
  1084. }
  1085. return true;
  1086. }
  1087. virtual int processCMD()
  1088. {
  1089. if (optVerbose)
  1090. fprintf(stdout, "\nRecreating %s/%s\n", optTarget.str(), optQueryId.str());
  1091. Owned<IClientWsWorkunits> client = createCmdClient(WsWorkunits, *this); //upload_ disables maxRequestEntityLength
  1092. Owned<IClientWURecreateQueryRequest> req = client->createWURecreateQueryRequest();
  1093. setCmdRequestTimeouts(req->rpc(), optMsToWait, optWaitConnectMs, optWaitReadSec);
  1094. if (optDeletePrevious)
  1095. req->setActivate(CWUQueryActivationMode_ActivateDeletePrevious);
  1096. else if (optSuspendPrevious)
  1097. req->setActivate(CWUQueryActivationMode_ActivateSuspendPrevious);
  1098. else
  1099. req->setActivate(optNoActivate ? CWUQueryActivationMode_NoActivate : CWUQueryActivationMode_Activate);
  1100. req->setTarget(optTarget);
  1101. req->setDestTarget(optDestTarget);
  1102. req->setQueryId(optQueryId);
  1103. req->setRemoteDali(optDaliIP);
  1104. req->setSourceProcess(optSourceProcess);
  1105. req->setWait(optMsToWait);
  1106. req->setNoReload(optNoReload);
  1107. req->setRepublish(!optNoPublish);
  1108. req->setDontCopyFiles(optDontCopyFiles);
  1109. req->setAllowForeignFiles(optAllowForeign);
  1110. req->setUpdateDfs(optUpdateDfs);
  1111. req->setUpdateSuperFiles(optUpdateSuperfiles);
  1112. req->setUpdateCloneFrom(optUpdateCloneFrom);
  1113. req->setAppendCluster(!optDontAppendCluster);
  1114. req->setIncludeFileErrors(true);
  1115. req->setDebugValues(debugValues);
  1116. if (optTimeLimit != (unsigned) -1)
  1117. req->setTimeLimit(optTimeLimit);
  1118. if (optWarnTimeLimit != (unsigned) -1)
  1119. req->setWarnTimeLimit(optWarnTimeLimit);
  1120. if (!optMemoryLimit.isEmpty())
  1121. req->setMemoryLimit(optMemoryLimit);
  1122. if (!optPriority.isEmpty())
  1123. req->setPriority(optPriority);
  1124. if (optComment.get()) //allow empty
  1125. req->setComment(optComment);
  1126. Owned<IClientWURecreateQueryResponse> resp = client->WURecreateQuery(req);
  1127. const char *wuid = resp->getWuid();
  1128. if (wuid && *wuid)
  1129. fprintf(stdout, "\nWorkunit: %s\n", wuid);
  1130. const char *id = resp->getQueryId();
  1131. if (id && *id)
  1132. {
  1133. const char *qs = resp->getQuerySet();
  1134. fprintf(stdout, "\nPublished: %s/%s\n", qs ? qs : "", resp->getQueryId());
  1135. }
  1136. if (resp->getReloadFailed())
  1137. fputs("\nAdded to Target, but request to reload queries on cluster failed\n", stderr);
  1138. int ret = outputMultiExceptionsEx(resp->getExceptions());
  1139. if (outputQueryFileCopyErrors(resp->getFileErrors()))
  1140. ret = 1;
  1141. return ret;
  1142. }
  1143. virtual void usage()
  1144. {
  1145. fputs("\nUsage:\n"
  1146. "\n"
  1147. "The 'queries recreate' command recompiles a query into a new workunit and republishes\n"
  1148. "the new workunit. This is usefull when upgrading to a new ECL compiler and you\n"
  1149. "want to recompile a query with the exact same source.\n"
  1150. "\n"
  1151. "The ECL archive must be available within the workunit of the query.\n"
  1152. "\n"
  1153. "ecl queries recreate <target> <query> [options]\n\n"
  1154. "ecl queries recreate <target> <query> <destination-target> [options]\n\n"
  1155. " <target> the target the query you wish to recreate is in\n"
  1156. " <query> the query ID of the query you wish to recreate\n"
  1157. " <destination-target> the target you want to move the new query to\n"
  1158. " (if different from the source target)\n"
  1159. " Options:\n"
  1160. " -A, --activate Activate query when published (default)\n"
  1161. " --limit=<limit> Sets the result limit for the query, defaults to 100\n"
  1162. " -sp, --suspend-prev Suspend previously active query\n"
  1163. " -dp, --delete-prev Delete previously active query\n"
  1164. " -A-, --no-activate Do not activate query when published\n"
  1165. " --no-publish Create a recompiled workunit, but do not publish it\n"
  1166. " --no-reload Do not request a reload of the (roxie) cluster\n"
  1167. " --no-files Do not copy DFS file information for referenced files\n"
  1168. " --allow-foreign Do not fail if foreign files are used in query (roxie)\n"
  1169. " --daliip=<IP> The IP of the DALI to be used to locate remote files\n"
  1170. " --update-super-files Update local DFS super-files if remote DALI has changed\n"
  1171. " --update-clone-from Update local clone from location if remote DALI has changed\n"
  1172. " --dont-append-cluster Only use to avoid locking issues due to adding cluster to file\n"
  1173. " --source-process Process cluster to copy files from\n"
  1174. " --timeLimit=<ms> Value to set for query timeLimit configuration\n"
  1175. " --warnTimeLimit=<ms> Value to set for query warnTimeLimit configuration\n"
  1176. " --memoryLimit=<mem> Value to set for query memoryLimit configuration\n"
  1177. " format <mem> as 500000B, 550K, 100M, 10G, 1T etc.\n"
  1178. " --priority=<val> set the priority for this query. Value can be LOW,\n"
  1179. " HIGH, SLA, NONE. NONE will clear current setting.\n"
  1180. " --comment=<string> Set the comment associated with this query\n"
  1181. " --wait=<ms> Max time to wait in milliseconds\n",
  1182. stdout);
  1183. EclCmdCommon::usage();
  1184. }
  1185. private:
  1186. StringAttr optTarget;
  1187. StringAttr optDestTarget;
  1188. StringAttr optQueryId;
  1189. StringAttr optDaliIP;
  1190. StringAttr optSourceProcess;
  1191. StringAttr optMemoryLimit;
  1192. StringAttr optPriority;
  1193. StringAttr optComment;
  1194. IArrayOf<IEspNamedValue> debugValues;
  1195. unsigned optMsToWait = (unsigned) -1;
  1196. unsigned optTimeLimit = (unsigned) -1;
  1197. unsigned optWarnTimeLimit = (unsigned) -1;
  1198. unsigned optResultLimit = (unsigned) -1;
  1199. bool optNoActivate = false;
  1200. bool activateSet = false;
  1201. bool optNoReload = false;
  1202. bool optNoPublish = false;
  1203. bool optDontCopyFiles = false;
  1204. bool optSuspendPrevious = false;
  1205. bool optDeletePrevious = false;
  1206. bool optAllowForeign = false;
  1207. bool optUpdateDfs = false;
  1208. bool optUpdateSuperfiles = false;
  1209. bool optUpdateCloneFrom = false;
  1210. bool optDontAppendCluster = false; //Undesirable but here temporarily because DALI may have locking issues
  1211. };
  1212. class EclCmdQueriesExport : public EclCmdCommon
  1213. {
  1214. public:
  1215. EclCmdQueriesExport()
  1216. {
  1217. }
  1218. virtual eclCmdOptionMatchIndicator parseCommandLineOptions(ArgvIterator &iter)
  1219. {
  1220. if (iter.done())
  1221. return EclCmdOptionNoMatch;
  1222. for (; !iter.done(); iter.next())
  1223. {
  1224. const char *arg = iter.query();
  1225. if (*arg!='-')
  1226. {
  1227. if (optTarget.isEmpty())
  1228. optTarget.set(arg);
  1229. else
  1230. {
  1231. fprintf(stderr, "\nunrecognized argument %s\n", arg);
  1232. return EclCmdOptionNoMatch;
  1233. }
  1234. continue;
  1235. }
  1236. if (iter.matchOption(optFilename, ECLOPT_OUTPUT) || iter.matchOption(optFilename, ECLOPT_OUTPUT_S))
  1237. continue;
  1238. if (iter.matchFlag(optActiveOnly, ECLOPT_ACTIVE_ONLY))
  1239. continue;
  1240. if (iter.matchFlag(optProtect, ECLOPT_PROTECT))
  1241. continue;
  1242. eclCmdOptionMatchIndicator ind = EclCmdCommon::matchCommandLineOption(iter, true);
  1243. if (ind != EclCmdOptionMatch)
  1244. return ind;
  1245. }
  1246. return EclCmdOptionMatch;
  1247. }
  1248. virtual bool finalizeOptions(IProperties *globals)
  1249. {
  1250. if (optTarget.isEmpty())
  1251. {
  1252. fputs("Target must be specified.\n", stderr);
  1253. return false;
  1254. }
  1255. if (optFilename.isEmpty())
  1256. {
  1257. StringBuffer name("./queryset_backup_");
  1258. name.append(optTarget);
  1259. if (optActiveOnly)
  1260. name.append("_activeonly_");
  1261. CDateTime dt;
  1262. dt.setNow();
  1263. dt.getString(name, true);
  1264. name.replace(':', '_').append(".xml");
  1265. optFilename.set(name);
  1266. }
  1267. if (!EclCmdCommon::finalizeOptions(globals))
  1268. return false;
  1269. return true;
  1270. }
  1271. void saveAsFile(const char *s, const char *filepath)
  1272. {
  1273. if (!s || !*s)
  1274. return;
  1275. Owned<IFile> file = createIFile(filepath);
  1276. Owned<IFileIO> io = file->open(IFOcreate);
  1277. fprintf(stdout, "\nWriting to file %s\n", file->queryFilename());
  1278. if (io.get())
  1279. io->write(0, strlen(s), s);
  1280. else
  1281. fprintf(stderr, "\nFailed to create file %s\n", file->queryFilename());
  1282. }
  1283. virtual int processCMD()
  1284. {
  1285. Owned<IClientWsWorkunits> client = createCmdClient(WsWorkunits, *this);
  1286. Owned<IClientWUQuerysetExportRequest> req = client->createWUQuerysetExportRequest();
  1287. setCmdRequestTimeouts(req->rpc(), 0, optWaitConnectMs, optWaitReadSec);
  1288. req->setTarget(optTarget);
  1289. req->setActiveOnly(optActiveOnly);
  1290. req->setCompress(true);
  1291. req->setProtect(optProtect);
  1292. Owned<IClientWUQuerysetExportResponse> resp = client->WUQuerysetExport(req);
  1293. int ret = outputMultiExceptionsEx(resp->getExceptions());
  1294. if (ret == 0)
  1295. {
  1296. if (!resp->getData().length())
  1297. {
  1298. fprintf(stderr, "\nEmpty Queryset returned\n");
  1299. return 1;
  1300. }
  1301. MemoryBuffer decompressed;
  1302. fastLZDecompressToBuffer(decompressed, const_cast<MemoryBuffer &>(resp->getData())); //unfortunate need for const_cast
  1303. if (!decompressed.length())
  1304. {
  1305. fprintf(stderr, "\nError decompressing response\n");
  1306. return 1;
  1307. }
  1308. if (optFilename.length())
  1309. saveAsFile(decompressed.toByteArray(), optFilename);
  1310. else
  1311. {
  1312. decompressed.append('\0');
  1313. fputs(decompressed.toByteArray(), stdout); //for piping
  1314. fputs("\n", stdout);
  1315. }
  1316. }
  1317. return ret;
  1318. }
  1319. virtual void usage()
  1320. {
  1321. fputs("\nUsage:\n"
  1322. "\n"
  1323. "The 'queries export' command saves backup information about a given queryset.\n"
  1324. "\n"
  1325. "ecl queries export <target> [options]\n\n"
  1326. " Options:\n"
  1327. " <target> Name of target cluster to export from\n"
  1328. " -O,--output=<file> Filename to save exported backup information to (optional)\n"
  1329. " --active-only Only include active queries in the exported queryset\n"
  1330. " --protect Protect the workunits for the included queries\n"
  1331. " Common Options:\n",
  1332. stdout);
  1333. EclCmdCommon::usage();
  1334. }
  1335. private:
  1336. StringAttr optTarget;
  1337. StringAttr optFilename;
  1338. bool optActiveOnly = false;
  1339. bool optProtect = false;
  1340. };
  1341. class EclCmdQueriesImport : public EclCmdCommon
  1342. {
  1343. public:
  1344. EclCmdQueriesImport()
  1345. {
  1346. }
  1347. virtual eclCmdOptionMatchIndicator parseCommandLineOptions(ArgvIterator &iter)
  1348. {
  1349. if (iter.done())
  1350. return EclCmdOptionNoMatch;
  1351. for (; !iter.done(); iter.next())
  1352. {
  1353. const char *arg = iter.query();
  1354. if (*arg!='-')
  1355. {
  1356. if (optDestQuerySet.isEmpty())
  1357. optDestQuerySet.set(arg);
  1358. else if (optFilename.isEmpty())
  1359. optFilename.set(arg);
  1360. else
  1361. {
  1362. fprintf(stderr, "\nunrecognized argument %s\n", arg);
  1363. return EclCmdOptionNoMatch;
  1364. }
  1365. continue;
  1366. }
  1367. if (iter.matchOption(optQueries, ECLOPT_QUERIES))
  1368. continue;
  1369. if (iter.matchOption(optDaliIP, ECLOPT_DALIIP))
  1370. continue;
  1371. if (iter.matchOption(optSourceProcess, ECLOPT_SOURCE_PROCESS))
  1372. continue;
  1373. if (iter.matchFlag(optCloneActiveState, ECLOPT_CLONE_ACTIVE_STATE))
  1374. continue;
  1375. if (iter.matchFlag(optDontCopyFiles, ECLOPT_DONT_COPY_FILES))
  1376. continue;
  1377. if (iter.matchFlag(optAllQueries, ECLOPT_ALL))
  1378. continue;
  1379. if (iter.matchFlag(optReplace, ECLOPT_REPLACE))
  1380. continue;
  1381. if (iter.matchFlag(optAllowForeign, ECLOPT_ALLOW_FOREIGN))
  1382. continue;
  1383. if (iter.matchFlag(optOverwrite, ECLOPT_OVERWRITE)||iter.matchFlag(optOverwrite, ECLOPT_OVERWRITE_S))
  1384. continue;
  1385. if (iter.matchFlag(optUpdateSuperfiles, ECLOPT_UPDATE_SUPER_FILES))
  1386. continue;
  1387. if (iter.matchFlag(optUpdateCloneFrom, ECLOPT_UPDATE_CLONE_FROM))
  1388. continue;
  1389. if (iter.matchFlag(optDontAppendCluster, ECLOPT_DONT_APPEND_CLUSTER))
  1390. continue;
  1391. eclCmdOptionMatchIndicator ind = EclCmdCommon::matchCommandLineOption(iter, true);
  1392. if (ind != EclCmdOptionMatch)
  1393. return ind;
  1394. }
  1395. return EclCmdOptionMatch;
  1396. }
  1397. virtual bool finalizeOptions(IProperties *globals)
  1398. {
  1399. if (!EclCmdCommon::finalizeOptions(globals))
  1400. return false;
  1401. if (optFilename.isEmpty() || optDestQuerySet.isEmpty())
  1402. {
  1403. fputs("Target and file name must both be specified.\n", stderr);
  1404. return false;
  1405. }
  1406. content.loadFile(optFilename, false);
  1407. return true;
  1408. }
  1409. virtual int processCMD()
  1410. {
  1411. Owned<IClientWsWorkunits> client = createCmdClient(WsWorkunits, *this);
  1412. Owned<IClientWUQuerysetImportRequest> req = client->createWUQuerysetImportRequest();
  1413. setCmdRequestTimeouts(req->rpc(), 0, optWaitConnectMs, optWaitReadSec);
  1414. MemoryBuffer compressed;
  1415. fastLZCompressToBuffer(compressed, content.length()+1, content.str());
  1416. req->setCompressed(true);
  1417. req->setData(compressed);
  1418. req->setReplace(optReplace);
  1419. req->setActiveOnly(!optAllQueries);
  1420. req->setQueryMask(optQueries);
  1421. req->setTarget(optDestQuerySet);
  1422. req->setDfsServer(optDaliIP);
  1423. req->setSourceProcess(optSourceProcess);
  1424. req->setActivation(optCloneActiveState ? CQuerysetImportActivation_ImportedActive : CQuerysetImportActivation_None);
  1425. req->setOverwriteDfs(optOverwrite);
  1426. req->setUpdateSuperFiles(optUpdateSuperfiles);
  1427. req->setUpdateCloneFrom(optUpdateCloneFrom);
  1428. req->setAppendCluster(!optDontAppendCluster);
  1429. req->setCopyFiles(!optDontCopyFiles);
  1430. req->setAllowForeignFiles(optAllowForeign);
  1431. req->setIncludeFileErrors(true);
  1432. Owned<IClientWUQuerysetImportResponse> resp = client->WUQuerysetImport(req);
  1433. int ret = outputMultiExceptionsEx(resp->getExceptions());
  1434. if (outputQueryFileCopyErrors(resp->getFileErrors()))
  1435. ret = 1;
  1436. StringArray &imported = resp->getImportedQueries();
  1437. fputs("Queries Imported:\n", stdout);
  1438. if (!imported.length())
  1439. fputs(" none\n\n", stdout);
  1440. else
  1441. {
  1442. ForEachItemIn(i, imported)
  1443. fprintf(stdout, " %s\n", imported.item(i));
  1444. fputs("\n", stdout);
  1445. }
  1446. StringArray &existing = resp->getExistingQueries();
  1447. fputs("Queries already on destination target:\n", stdout);
  1448. if (!existing.length())
  1449. fputs(" none\n\n", stdout);
  1450. else
  1451. {
  1452. ForEachItemIn(i, existing)
  1453. fprintf(stdout, " %s\n", existing.item(i));
  1454. fputs("\n", stdout);
  1455. }
  1456. StringArray &missing = resp->getMissingWuids();
  1457. fputs("Missing workunits:\n", stdout);
  1458. if (!missing.length())
  1459. fputs(" none\n\n", stdout);
  1460. else
  1461. {
  1462. ForEachItemIn(i, missing)
  1463. fprintf(stdout, " %s\n", missing.item(i));
  1464. fputs("\n", stdout);
  1465. }
  1466. return ret;
  1467. }
  1468. virtual void usage()
  1469. {
  1470. fputs("\nUsage:\n"
  1471. "\n"
  1472. "The 'queries import' command imports the contents of a queryset exported to disk.\n"
  1473. "\n"
  1474. "By default only active queries will be imported. Use --all to import all queries.\n"
  1475. "\n"
  1476. "ecl queries import <target> <file> [--clone-active-state][--replace]\n"
  1477. "ecl queries import roxie1 queryset.xml\n"
  1478. "\n"
  1479. " Options:\n"
  1480. " <target> Target cluster to import queries to\n"
  1481. " --all Copy both active and inactive queries\n"
  1482. " --replace Replace entire existing queryset\n"
  1483. " --queries Filter query ids to select for import\n"
  1484. " --no-files Do not copy DFS file information for referenced files\n"
  1485. " --daliip=<ip> Remote Dali DFS to use for copying file information\n"
  1486. " --source-process Process cluster to copy files from\n"
  1487. " --clone-active-state Make copied queries active if active on source\n"
  1488. " -O, --overwrite Completely replace existing DFS file information (dangerous)\n"
  1489. " --update-super-files Update local DFS super-files if remote DALI has changed\n"
  1490. " --update-clone-from Update local clone from location if remote DALI has changed\n"
  1491. " --dont-append-cluster Only use to avoid locking issues due to adding cluster to file\n"
  1492. " --allow-foreign Do not fail if foreign files are used in query (roxie)\n"
  1493. " Common Options:\n",
  1494. stdout);
  1495. EclCmdCommon::usage();
  1496. }
  1497. private:
  1498. StringBuffer content;
  1499. StringAttr optFilename;
  1500. StringAttr optQueries;
  1501. StringAttr optDestQuerySet;
  1502. StringAttr optDaliIP;
  1503. StringAttr optSourceProcess;
  1504. bool optReplace = false;
  1505. bool optCloneActiveState = false;
  1506. bool optOverwrite = false;
  1507. bool optUpdateSuperfiles = false;
  1508. bool optUpdateCloneFrom = false;
  1509. bool optDontAppendCluster = false; //Undesirable but here temporarily because DALI may have locking issues
  1510. bool optDontCopyFiles = false;
  1511. bool optAllowForeign = false;
  1512. bool optAllQueries = false;
  1513. };
  1514. IEclCommand *createEclQueriesCommand(const char *cmdname)
  1515. {
  1516. if (!cmdname || !*cmdname)
  1517. return NULL;
  1518. if (strieq(cmdname, "list"))
  1519. return new EclCmdQueriesList();
  1520. if (strieq(cmdname, "files"))
  1521. return new EclCmdQueryFiles();
  1522. if (strieq(cmdname, "config"))
  1523. return new EclCmdQueriesConfig();
  1524. if (strieq(cmdname, "copy"))
  1525. return new EclCmdQueriesCopy();
  1526. if (strieq(cmdname, "copy-set"))
  1527. return new EclCmdQueriesCopyQueryset();
  1528. if (strieq(cmdname, "recreate"))
  1529. return new EclCmdQueriesRecreate();
  1530. if (strieq(cmdname, "export"))
  1531. return new EclCmdQueriesExport();
  1532. if (strieq(cmdname, "import"))
  1533. return new EclCmdQueriesImport();
  1534. return NULL;
  1535. }
  1536. //=========================================================================================
  1537. class EclQueriesCMDShell : public EclCMDShell
  1538. {
  1539. public:
  1540. EclQueriesCMDShell(int argc, const char *argv[], EclCommandFactory _factory, const char *_version)
  1541. : EclCMDShell(argc, argv, _factory, _version)
  1542. {
  1543. }
  1544. virtual void usage()
  1545. {
  1546. fprintf(stdout,"\nUsage:\n\n"
  1547. "ecl queries <command> [command options]\n\n"
  1548. " Queries Commands:\n"
  1549. " list list queries on target cluster(s)\n"
  1550. " files list the files currently used by a query\n"
  1551. " config update query settings\n"
  1552. " copy copy a query from one target cluster to another\n"
  1553. " copy-set copy queries from one target cluster to another\n"
  1554. " recreate recompiles query into a new workunit\n"
  1555. " export export queryset information for backup\n"
  1556. " import import queryset information from backup file\n"
  1557. );
  1558. }
  1559. };
  1560. static int doMain(int argc, const char *argv[])
  1561. {
  1562. EclQueriesCMDShell processor(argc, argv, createEclQueriesCommand, hpccBuildInfo.buildTag);
  1563. return processor.run();
  1564. }
  1565. int main(int argc, const char *argv[])
  1566. {
  1567. InitModuleObjects();
  1568. queryStderrLogMsgHandler()->setMessageFields(0);
  1569. unsigned exitCode = doMain(argc, argv);
  1570. releaseAtoms();
  1571. exit(exitCode);
  1572. }