Browse Source

HPCC-14559 Add WorkunitServices function to set application values

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 9 years ago
parent
commit
0fa32f0208

+ 14 - 7
common/workunit/workunit.cpp

@@ -2876,9 +2876,12 @@ public:
         StringAttr namefilterlo;
         StringAttr namefilterhi;
         StringArray unknownAttributes;
-        if (filters) {
-            const char *fv = (const char *)filterbuf;
-            for (unsigned i=0;filters[i]!=WUSFterm;i++) {
+        if (filters)
+        {
+            const char *fv = (const char *) filterbuf;
+            for (unsigned i=0;filters[i]!=WUSFterm;i++)
+            {
+                assertex(fv);
                 int fmt = filters[i];
                 int subfmt = (fmt&0xff);
                 if (subfmt==WUSFwuid)
@@ -2889,17 +2892,21 @@ public:
                     namefilter.set(fv);
                 else if (subfmt==WUSFappvalue)
                 {
-                    query.append("[Application/").append(fv).append("=?~\"");
+                    const char *app = fv;
                     fv = fv + strlen(fv)+1;
-                    query.append(fv).append("\"]");
+                    query.append("[Application/").append(app);
+                    if (*fv)
+                        query.append("=?~\"").append(fv).append('\"');
+                    query.append("]");
                 }
-                else if (!fv || !*fv)
+                else if (!*fv)
                 {
                     unknownAttributes.append(getEnumText(subfmt,workunitSortFields));
                     if (subfmt==WUSFtotalthortime)
                         sortorder = (WUSortField) (sortorder | WUSFnumeric);
                 }
-                else {
+                else
+                {
                     query.append('[').append(getEnumText(subfmt,workunitSortFields)).append('=');
                     if (fmt&WUSFnocase)
                         query.append('?');

+ 18 - 4
ecllibrary/std/system/Workunit.ecl

@@ -63,10 +63,11 @@ EXPORT BOOLEAN WorkunitExists(varstring wuid, boolean online=true, boolean archi
  * @param eclcontains   the text to search for in the workunit�s ECL code. This may contain wildcard ( * ? ) characters.
  * @param online        the flag specifying whether the search is performed online.
  * @param archived      the flag specifying whether the search is performed in the archives.
+ * @param appvalues     application values to search for. Use a string of the form appname/key=value or appname/*=value.
  */
 
 EXPORT dataset(WorkunitRecord) WorkunitList(
-                                         varstring lowwuid, 
+                                         varstring lowwuid='',
                                          varstring highwuid='', 
                                          varstring username='', 
                                          varstring cluster='', 
@@ -78,13 +79,14 @@ EXPORT dataset(WorkunitRecord) WorkunitList(
                                          varstring roxiecluster='',
                                          varstring eclcontains='',
                                          boolean online=true,
-                                         boolean archived=false
+                                         boolean archived=false,
+                                         varstring appvalues=''
                                         ) :=
     lib_workunitservices.WorkUnitServices.WorkunitList(
                                         lowwuid, highwuid, 
                                         username, cluster, jobname, state, priority,
                                         fileread, filewritten, roxiecluster, eclcontains,
-                                        online, archived);
+                                        online, archived, appvalues);
 
 /*
  * Returns a valid Workunit identifier for the specified date and time.  This is useful for creating ranges of wuids 
@@ -163,5 +165,17 @@ EXPORT dataset(TimingRecord) WorkunitTimings(varstring wuid) :=
 EXPORT dataset(StatisticRecord) WorkunitStatistics(varstring wuid, boolean includeActivities = false, varstring _filter = '') :=
   lib_workunitservices.WorkUnitServices.WorkunitStatistics(wuid, includeActivities, _filter);
 
+/*
+ * Sets an application value in current workunit. Returns true if the value was set successfully.
+ *
+ * @param app           the app name to set.
+ * @param key           the name of the value to set.
+ * @param value         the value to set.
+ * @param overwrite     whether an existing value should be overwritten (default=true).
+*/
 
-END;
+EXPORT boolean SetWorkunitAppValue(varstring app, varstring key, varstring value, boolean overwrite=true) :=
+  lib_workunitservices.WorkUnitServices.SetWorkunitAppValue(app, key, value, overwrite);
+
+
+END;

+ 14 - 3
plugins/workunitservices/workunitservices.cpp

@@ -120,10 +120,10 @@ static const char * EclDefinition =
                             " string description;"
                             " string unit;"
                         " end;\n"
-"export WorkunitServices := SERVICE\n"
+"export WorkunitServices := SERVICE : cpp\n"
 "   boolean WorkunitExists(const varstring wuid, boolean online=true, boolean archived=false) : context,entrypoint='wsWorkunitExists'; \n"
 "   dataset(WsWorkunitRecord) WorkunitList("
-                                        " const varstring lowwuid," 
+                                        " const varstring lowwuid='',"
                                         " const varstring highwuid=''," 
                                         " const varstring username=''," 
                                         " const varstring cluster=''," 
@@ -146,7 +146,7 @@ static const char * EclDefinition =
 "  dataset(WsFileWritten) WorkunitFilesWritten(const varstring wuid) : context,entrypoint='wsWorkunitFilesWritten'; \n"
 "  dataset(WsTiming) WorkunitTimings(const varstring wuid) : context,entrypoint='wsWorkunitTimings'; \n"
 "  streamed dataset(WsStatistic) WorkunitStatistics(const varstring wuid, boolean includeActivities = false, const varstring _filter = '') : context,entrypoint='wsWorkunitStatistics'; \n"
-    
+"  boolean setWorkunitAppValue(const varstring app, const varstring key, const varstring value, boolean overwrite=true) : context,entrypoint='wsSetWorkunitAppValue'; \n"
 "END;";
 
 #define WAIT_SECONDS 30
@@ -730,6 +730,17 @@ WORKUNITSERVICES_API IRowStream * wsWorkunitStatistics( ICodeContext *ctx, IEngi
     return new StreamedStatistics(wu, allocator, stats);
 }
 
+WORKUNITSERVICES_API bool wsSetWorkunitAppValue( ICodeContext *ctx, const char *appname, const char *key, const char *value, bool overwrite)
+{
+    if (appname && *appname && key && *key && value && *value)
+    {
+        WorkunitUpdate w(ctx->updateWorkUnit());
+        w->setApplicationValue(appname, key, value, overwrite);
+        return true;
+    }
+    return false;
+}
+
 
 WORKUNITSERVICES_API void setPluginContext(IPluginContext * _ctx) { parentCtx = _ctx; }
 

+ 8 - 2
plugins/workunitservices/workunitservices.hpp

@@ -34,8 +34,12 @@
 #include "workunit.hpp"
 #include "eclhelper.hpp"
 
-WORKUNITSERVICES_API bool getECLPluginDefinition(ECLPluginDefinitionBlock *pb);
-WORKUNITSERVICES_API void setPluginContext(IPluginContext * _ctx);
+extern "C"
+{
+  WORKUNITSERVICES_API bool getECLPluginDefinition(ECLPluginDefinitionBlock *pb);
+  WORKUNITSERVICES_API void setPluginContext(IPluginContext * _ctx);
+}
+
 WORKUNITSERVICES_API char * WORKUNITSERVICES_CALL wsGetBuildInfo(void);
 
 WORKUNITSERVICES_API bool WORKUNITSERVICES_CALL wsWorkunitExists(ICodeContext *ctx, const char *wuid, bool online, bool archived);
@@ -68,5 +72,7 @@ WORKUNITSERVICES_API void WORKUNITSERVICES_CALL wsWorkunitFilesWritten( ICodeCon
 WORKUNITSERVICES_API void WORKUNITSERVICES_CALL wsWorkunitTimings( ICodeContext *ctx, size32_t & __lenResult, void * & __result, const char *wuid );
 WORKUNITSERVICES_API IRowStream * WORKUNITSERVICES_CALL wsWorkunitStatistics( ICodeContext *ctx, IEngineRowAllocator * allocator, const char *wuid, bool includeActivities, const char * filterText);
 
+WORKUNITSERVICES_API bool WORKUNITSERVICES_CALL wsWorkunitTimings( ICodeContext *ctx, const char *wuid, const char * appname, const char *key, const char *value, bool overwrrite);
+
 #endif
 

+ 2 - 2
rtl/include/eclhelper.hpp

@@ -39,8 +39,8 @@ if the supplied pointer was not from the roxiemem heap. Usually an OwnedRoxieStr
 
 //Should be incremented whenever the virtuals in the context or a helper are changed, so
 //that a work unit can't be rerun.  Try as hard as possible to retain compatibility.
-#define ACTIVITY_INTERFACE_VERSION      159
-#define MIN_ACTIVITY_INTERFACE_VERSION  159             //minimum value that is compatible with current interface - without using selectInterface
+#define ACTIVITY_INTERFACE_VERSION      160
+#define MIN_ACTIVITY_INTERFACE_VERSION  160             //minimum value that is compatible with current interface - without using selectInterface
 
 typedef unsigned char byte;
 

+ 4 - 1
testing/regress/ecl/aaawriteresult.ecl

@@ -15,6 +15,8 @@
     limitations under the License.
 ############################################################################## */
 
+import Std.System.Workunit as Wu;
+
 namesRecord := 
             RECORD
 string10        forename;
@@ -22,5 +24,6 @@ string20        surname;
             END;
 
 ds := dataset([{'Jo','Smith'},{'Jim','Smithe'},{'Joe','Schmitt'}], namesRecord);
-    
+
+wu.setWorkunitAppValue('regress', 'writeresult', '1', true);
 output(ds,NAMED('ExportedNames'));

+ 3 - 0
testing/regress/ecl/key/aaawriteresult.xml

@@ -1,3 +1,6 @@
+<Dataset name='Result 1'>
+ <Row><Result_1>true</Result_1></Row>
+</Dataset>
 <Dataset name='ExportedNames'>
  <Row><forename>Jo        </forename><surname>Smith               </surname></Row>
  <Row><forename>Jim       </forename><surname>Smithe              </surname></Row>

+ 2 - 4
testing/regress/ecl/readresult.ecl

@@ -22,13 +22,11 @@ string20        surname;
             END;
 
 
-//Horrible code - get a list of workunits that match the name of the job that creates the result
+//Horrible code - get a list of workunits that create the result
 //which needs to be inside a nothor.
 
 import Std.System.Workunit as Wu;
-myWuid := workunit;
-startOfDay := myWuid[1..9] + '-000000';
-writers := Wu.WorkunitList(lowWuid := startOfDay,jobname := 'aaawriteresult*');
+writers := Wu.WorkunitList(appvalues := 'regress/writeresult=1');
 
 //Now sort and extract the most recent wuid that matches the condition
 lastWriter := sort(nothor(writers), -wuid);