|
@@ -1855,7 +1855,7 @@ public:
|
|
|
virtual IStringVal & str(IStringVal &s) { s.clear(); return s; }
|
|
|
};
|
|
|
|
|
|
-mapEnums sortFields[] =
|
|
|
+mapEnums workunitSortFields[] =
|
|
|
{
|
|
|
{ WUSFuser, "@submitID" },
|
|
|
{ WUSFcluster, "@clusterName" },
|
|
@@ -1879,6 +1879,24 @@ mapEnums sortFields[] =
|
|
|
{ WUSFterm, NULL }
|
|
|
};
|
|
|
|
|
|
+mapEnums querySortFields[] =
|
|
|
+{
|
|
|
+ { WUQSFId, "@id" },
|
|
|
+ { WUQSFwuid, "@wuid" },
|
|
|
+ { WUQSFname, "@name" },
|
|
|
+ { WUQSFdll, "@dll" },
|
|
|
+ { WUQSFmemoryLimit, "@memoryLimit" },
|
|
|
+ { WUQSFmemoryLimitHi, "@memoryLimit" },
|
|
|
+ { WUQSFtimeLimit, "@timeLimit" },
|
|
|
+ { WUQSFtimeLimitHi, "@timeLimit" },
|
|
|
+ { WUQSFwarnTimeLimit, "@warnTimeLimit" },
|
|
|
+ { WUQSFwarnTimeLimitHi, "@warnTimeLimit" },
|
|
|
+ { WUQSFpriority, "@priority" },
|
|
|
+ { WUQSFpriorityHi, "@priority" },
|
|
|
+ { WUQSFQuerySet, "../@id" },
|
|
|
+ { WUQSFterm, NULL }
|
|
|
+};
|
|
|
+
|
|
|
class asyncRemoveDllWorkItem: public CInterface, implements IWorkQueueItem // class only used in asyncRemoveDll
|
|
|
{
|
|
|
StringAttr name;
|
|
@@ -1919,6 +1937,47 @@ public:
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+//==========================================================================================
|
|
|
+
|
|
|
+class CConstQuerySetQueryIterator : public CInterface, implements IConstQuerySetQueryIterator
|
|
|
+{
|
|
|
+ IArrayOf<IPropertyTree> trees;
|
|
|
+ unsigned index;
|
|
|
+public:
|
|
|
+ IMPLEMENT_IINTERFACE;
|
|
|
+ CConstQuerySetQueryIterator(IArrayOf<IPropertyTree> &_trees)
|
|
|
+ {
|
|
|
+ ForEachItemIn(t, _trees)
|
|
|
+ trees.append(*LINK(&_trees.item(t)));
|
|
|
+ index = 0;
|
|
|
+ }
|
|
|
+ ~CConstQuerySetQueryIterator()
|
|
|
+ {
|
|
|
+ trees.kill();
|
|
|
+ }
|
|
|
+ bool first()
|
|
|
+ {
|
|
|
+ index = 0;
|
|
|
+ return (trees.ordinality()!=0);
|
|
|
+ }
|
|
|
+
|
|
|
+ bool next()
|
|
|
+ {
|
|
|
+ index++;
|
|
|
+ return (index<trees.ordinality());
|
|
|
+ }
|
|
|
+
|
|
|
+ bool isValid()
|
|
|
+ {
|
|
|
+ return (index<trees.ordinality());
|
|
|
+ }
|
|
|
+
|
|
|
+ IPropertyTree &query()
|
|
|
+ {
|
|
|
+ return trees.item(index);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
#define WUID_VERSION 2 // recorded in each wuid created, useful for bkwd compat. checks
|
|
|
|
|
|
class CWorkUnitFactory : public CInterface, implements IWorkUnitFactory, implements IDaliClientShutdown
|
|
@@ -2211,6 +2270,32 @@ public:
|
|
|
ISecUser *secuser,
|
|
|
unsigned *total)
|
|
|
{
|
|
|
+ class CWorkUnitsPager : public CSimpleInterface, implements IElementsPager
|
|
|
+ {
|
|
|
+ StringAttr xPath;
|
|
|
+ StringAttr sortOrder;
|
|
|
+ StringAttr nameFilterLo;
|
|
|
+ StringAttr nameFilterHi;
|
|
|
+
|
|
|
+ public:
|
|
|
+ IMPLEMENT_IINTERFACE_USING(CSimpleInterface);
|
|
|
+
|
|
|
+ CWorkUnitsPager(const char* _xPath, const char *_sortOrder, const char* _nameFilterLo, const char* _nameFilterHi)
|
|
|
+ : xPath(_xPath), sortOrder(_sortOrder), nameFilterLo(_nameFilterLo), nameFilterHi(_nameFilterHi)
|
|
|
+ {
|
|
|
+ }
|
|
|
+ virtual IRemoteConnection* getElements(IArrayOf<IPropertyTree> &elements)
|
|
|
+ {
|
|
|
+ Owned<IRemoteConnection> conn = querySDS().connect("WorkUnits", myProcessSession(), 0, SDS_LOCK_TIMEOUT);
|
|
|
+ if (!conn)
|
|
|
+ return NULL;
|
|
|
+ Owned<IPropertyTreeIterator> iter = conn->getElements(xPath);
|
|
|
+ if (!iter)
|
|
|
+ return NULL;
|
|
|
+ sortElements(iter, sortOrder.get(), nameFilterLo.get(), nameFilterHi.get(), elements);
|
|
|
+ return conn.getClear();
|
|
|
+ }
|
|
|
+ };
|
|
|
class CScopeChecker : public CSimpleInterface, implements ISortedElementsTreeFilter
|
|
|
{
|
|
|
UniqueScopes done;
|
|
@@ -2261,7 +2346,7 @@ public:
|
|
|
else if (subfmt==WUSFwuidhigh)
|
|
|
namefilterhi.set(fv);
|
|
|
else {
|
|
|
- query.append('[').append(getEnumText(subfmt,sortFields)).append('=');
|
|
|
+ query.append('[').append(getEnumText(subfmt,workunitSortFields)).append('=');
|
|
|
if (fmt&WUSFnocase)
|
|
|
query.append('?');
|
|
|
if (fmt&WUSFwild)
|
|
@@ -2282,12 +2367,12 @@ public:
|
|
|
so.append('?');
|
|
|
if (fmt&WUSFnumeric)
|
|
|
so.append('#');
|
|
|
- so.append(getEnumText(fmt&0xff,sortFields));
|
|
|
+ so.append(getEnumText(fmt&0xff,workunitSortFields));
|
|
|
}
|
|
|
}
|
|
|
IArrayOf<IPropertyTree> results;
|
|
|
- Owned<IRemoteConnection> conn=getElementsPaged("WorkUnits", query.str(), so.length()?so.str():NULL,startoffset,maxnum,
|
|
|
- secmgr?sc:NULL,queryowner,cachehint,namefilterlo.get(),namefilterhi.get(),results,total);
|
|
|
+ Owned<IElementsPager> elementsPager = new CWorkUnitsPager(query.str(), so.length()?so.str():NULL, namefilterlo.get(), namefilterhi.get());
|
|
|
+ Owned<IRemoteConnection> conn=getElementsPaged(elementsPager,startoffset,maxnum,secmgr?sc:NULL,queryowner,cachehint,results,total);
|
|
|
return new CConstWUArrayIterator(conn, results, secmgr, secuser);
|
|
|
}
|
|
|
|
|
@@ -2304,6 +2389,129 @@ public:
|
|
|
return getWorkUnitsSorted(sortorder,filters,filterbuf,startoffset,maxnum,queryowner,cachehint, NULL, NULL, total);
|
|
|
}
|
|
|
|
|
|
+ IConstQuerySetQueryIterator* getQuerySetQueriesSorted( WUQuerySortField *sortorder, // list of fields to sort by (terminated by WUSFterm)
|
|
|
+ WUQuerySortField *filters, // NULL or list of fields to folteron (terminated by WUSFterm)
|
|
|
+ const void *filterbuf, // (appended) string values for filters
|
|
|
+ unsigned startoffset,
|
|
|
+ unsigned maxnum,
|
|
|
+ __int64 *cachehint,
|
|
|
+ unsigned *total)
|
|
|
+ {
|
|
|
+ class CQuerySetQueriesPager : public CSimpleInterface, implements IElementsPager
|
|
|
+ {
|
|
|
+ StringAttr querySet;
|
|
|
+ StringAttr xPath;
|
|
|
+ StringAttr sortOrder;
|
|
|
+
|
|
|
+ void getQuerySetQueries(const char* querySetId, IPropertyTree* querySetTree, const char *xPath, IPropertyTree* queryTreeRoot)
|
|
|
+ {
|
|
|
+ Owned<IPropertyTreeIterator> iter = querySetTree->getElements(xPath);
|
|
|
+ ForEach(*iter)
|
|
|
+ {
|
|
|
+ IPropertyTree &query = iter->query();
|
|
|
+ IPropertyTree *queryWithSetId = queryTreeRoot->addPropTree("Query", LINK(&query));
|
|
|
+ queryWithSetId->addProp("@querySetId", querySetId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ IPropertyTree* getAllQuerySetQueries(IRemoteConnection* conn, const char *querySet, const char *xPath)
|
|
|
+ {
|
|
|
+ Owned<IPropertyTree> queryTreeRoot = createPTree("Queries");
|
|
|
+ IPropertyTree* root = conn->queryRoot();
|
|
|
+ if (querySet && *querySet)
|
|
|
+ {
|
|
|
+ VStringBuffer path("QuerySet[@id='%s']/Query%s", querySet, xPath);
|
|
|
+ getQuerySetQueries(querySet, root, path.str(), queryTreeRoot);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Owned<IPropertyTreeIterator> iter = root->getElements("QuerySet");
|
|
|
+ ForEach(*iter)
|
|
|
+ {
|
|
|
+ IPropertyTree &querySet = iter->query();
|
|
|
+ const char* id = querySet.queryProp("@id");
|
|
|
+ if (id && *id)
|
|
|
+ {
|
|
|
+ VStringBuffer path("Query%s", xPath);
|
|
|
+ getQuerySetQueries(id, &querySet, path.str(), queryTreeRoot);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return queryTreeRoot.getClear();
|
|
|
+ }
|
|
|
+
|
|
|
+ public:
|
|
|
+ IMPLEMENT_IINTERFACE_USING(CSimpleInterface);
|
|
|
+
|
|
|
+ CQuerySetQueriesPager(const char* _querySet, const char* _xPath, const char *_sortOrder)
|
|
|
+ : querySet(_querySet), xPath(_xPath), sortOrder(_sortOrder)
|
|
|
+ {
|
|
|
+ }
|
|
|
+ virtual IRemoteConnection* getElements(IArrayOf<IPropertyTree> &elements)
|
|
|
+ {
|
|
|
+ Owned<IRemoteConnection> conn = querySDS().connect("QuerySets", myProcessSession(), 0, SDS_LOCK_TIMEOUT);
|
|
|
+ if (!conn)
|
|
|
+ return NULL;
|
|
|
+ Owned<IPropertyTree> elementTree = getAllQuerySetQueries(conn, querySet.get(), xPath.get());
|
|
|
+ if (!elementTree)
|
|
|
+ return NULL;
|
|
|
+ Owned<IPropertyTreeIterator> iter = elementTree->getElements("*");
|
|
|
+ if (!iter)
|
|
|
+ return NULL;
|
|
|
+ sortElements(iter, sortOrder.get(), NULL, NULL, elements);
|
|
|
+ return conn.getClear();
|
|
|
+ }
|
|
|
+ };
|
|
|
+ StringAttr querySet;
|
|
|
+ StringBuffer xPath;
|
|
|
+ StringBuffer so;
|
|
|
+ if (filters)
|
|
|
+ {
|
|
|
+ const char *fv = (const char *)filterbuf;
|
|
|
+ for (unsigned i=0;filters[i]!=WUQSFterm;i++) {
|
|
|
+ int fmt = filters[i];
|
|
|
+ int subfmt = (fmt&0xff);
|
|
|
+ if (subfmt==WUQSFQuerySet)
|
|
|
+ querySet.set(fv);
|
|
|
+ else if ((subfmt==WUQSFmemoryLimit) || (subfmt==WUQSFtimeLimit) || (subfmt==WUQSFwarnTimeLimit) || (subfmt==WUQSFpriority))
|
|
|
+ xPath.append('[').append(getEnumText(subfmt,querySortFields)).append(">=").append(fv).append("]");
|
|
|
+ else if ((subfmt==WUQSFmemoryLimitHi) || (subfmt==WUQSFtimeLimitHi) || (subfmt==WUQSFwarnTimeLimitHi) || (subfmt==WUQSFpriorityHi))
|
|
|
+ xPath.append('[').append(getEnumText(subfmt,querySortFields)).append("<=").append(fv).append("]");
|
|
|
+ else {
|
|
|
+ xPath.append('[').append(getEnumText(subfmt,querySortFields)).append('=');
|
|
|
+ if (fmt&WUQSFnocase)
|
|
|
+ xPath.append('?');
|
|
|
+ if (fmt&WUQSFnumeric)
|
|
|
+ xPath.append('#');
|
|
|
+ if (fmt&WUQSFwild)
|
|
|
+ xPath.append('~');
|
|
|
+ xPath.append('"').append(fv).append("\"]");
|
|
|
+ }
|
|
|
+ fv = fv + strlen(fv)+1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (xPath.length() < 1)
|
|
|
+ xPath.set("*");
|
|
|
+ if (sortorder) {
|
|
|
+ for (unsigned i=0;sortorder[i]!=WUQSFterm;i++) {
|
|
|
+ if (so.length())
|
|
|
+ so.append(',');
|
|
|
+ int fmt = sortorder[i];
|
|
|
+ if (fmt&WUQSFreverse)
|
|
|
+ so.append('-');
|
|
|
+ if (fmt&WUQSFnocase)
|
|
|
+ so.append('?');
|
|
|
+ if (fmt&WUQSFnumeric)
|
|
|
+ so.append('#');
|
|
|
+ so.append(getEnumText(fmt&0xff,querySortFields));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ IArrayOf<IPropertyTree> results;
|
|
|
+ Owned<IElementsPager> elementsPager = new CQuerySetQueriesPager(querySet.get(), xPath.str(), so.length()?so.str():NULL);
|
|
|
+ Owned<IRemoteConnection> conn=getElementsPaged(elementsPager,startoffset,maxnum,NULL,"",cachehint,results,total);
|
|
|
+ return new CConstQuerySetQueryIterator(results);
|
|
|
+ }
|
|
|
+
|
|
|
virtual unsigned numWorkUnits()
|
|
|
{
|
|
|
Owned<IRemoteConnection> conn = sdsManager->connect("/WorkUnits", session, 0, SDS_LOCK_TIMEOUT);
|
|
@@ -2570,6 +2778,17 @@ public:
|
|
|
return factory->getWorkUnitsSorted(sortorder,filters,filterbuf,startoffset,maxnum,queryowner,cachehint, secMgr.get(), secUser.get(), total);
|
|
|
}
|
|
|
|
|
|
+ virtual IConstQuerySetQueryIterator* getQuerySetQueriesSorted( WUQuerySortField *sortorder,
|
|
|
+ WUQuerySortField *filters,
|
|
|
+ const void *filterbuf,
|
|
|
+ unsigned startoffset,
|
|
|
+ unsigned maxnum,
|
|
|
+ __int64 *cachehint,
|
|
|
+ unsigned *total)
|
|
|
+ {
|
|
|
+ return factory->getQuerySetQueriesSorted(sortorder,filters,filterbuf,startoffset,maxnum,cachehint,total);
|
|
|
+ }
|
|
|
+
|
|
|
virtual unsigned numWorkUnits()
|
|
|
{
|
|
|
return factory->numWorkUnits();
|