瀏覽代碼

Merge pull request #3930 from richardkchapman/kill-old-examples

HPCC-8738 Delete the original embedding examples

Reviewed-by: Gavin Halliday <ghalliday@hpccsystems.com>
Gavin Halliday 12 年之前
父節點
當前提交
5653d288e6

+ 0 - 147
initfiles/examples/javascript/jsmoz.ecl

@@ -1,147 +0,0 @@
-/* Example of calling JavaScript (Mozilla SpiderMonkey) from ECL code via embedded C++
-*
-* This example evalues a JavaScript expression within an ECL transform
-*
-*/
-
-#option('compileOptions', '-I/usr/include/js/')
-#option('linkOptions', '-lmozjs185')
-
-// Embedded C++ that makes a call to a JavaScript function
-
-string jseval(varstring script, varstring a, varstring b) := BEGINC++
-
-// This section of the code should probably move to a plugin, or somesuch
-
-/* Include the JSAPI header file to get access to SpiderMonkey. */
-#include "jsapi.h"
-#include <pthread.h>
-
-/* The class of the global object. */
-static JSClass global_class = {
-    "global", JSCLASS_GLOBAL_FLAGS,
-    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
-    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
-    JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-class MozJsContext
-{
-    JSRuntime *rt;
-    JSContext *cx;
-    JSObject  *global;
-
-public:
-    MozJsContext()
-    {
-        // Initialize to NULL so that initFailed can be used
-        rt = NULL;
-        cx = NULL;
-        global = NULL;
-
-        // We use a separate runtime each time - this may be a bad idea
-        rt = JS_NewRuntime(8 * 1024 * 1024);
-        if (!rt)
-            initFailed("Could not create JavaScript runtime");
-
-        // We need a context per thread - we COULD share between JS calls on a thread (using TLS, for example)
-        cx = JS_NewContext(rt, 8192);
-        if (cx == NULL)
-            initFailed("Could not create JavaScript context");
-        JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
-        JS_SetVersion(cx, JSVERSION_LATEST);
-        JS_SetErrorReporter(cx, reportError);
-        /*
-         * Create the global object in a new compartment.
-         * You always need a global object per context.
-         */
-        global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
-        if (global == NULL)
-            initFailed("Could not create JavaScript global object");
-        /*
-         * Populate the global object with the standard JavaScript
-         * function and object classes, such as Object, Array, Date.
-         */
-        if (!JS_InitStandardClasses(cx, global))
-            initFailed("Could not populate JavaScript global object");
-        JS_BeginRequest(cx);  // Probably not really necessary with a separate runtime per instance, but will be as soon as we change that.
-    }
-    ~MozJsContext()
-    {
-        if (global)
-            JS_EndRequest(cx);
-        if (cx)
-            JS_DestroyContext(cx);
-        if (rt)
-            JS_DestroyRuntime(rt);
-    }
-    inline operator JSContext *() const { return cx; }
-    inline JSObject *queryGlobal() const { return global; }
-private:
-    void cleanup()
-    {
-        if (cx)
-            JS_DestroyContext(cx);
-        if (rt)
-            JS_DestroyRuntime(rt);
-    }
-    void initFailed(const char *why)
-    {
-        cleanup();
-        rtlFail(0, why);
-    }
-    static void reportError(JSContext *cx, const char *message, JSErrorReport *report)
-    {
-        // MORE - need to think about what is appropriate here!
-        fprintf(stderr, "%s:%u:%s\n",
-                 report->filename ? report->filename : "<no filename=\"filename\">",
-                 (unsigned int) report->lineno,
-                 message);
-    }
-};
-
-//#body
-
-// extern  void user1(size32_t & __lenResult,char * & __result, const char * script, const char *a, const char *b) {
-{
-    MozJsContext c;
-    JSString * aa = JS_NewStringCopyZ(c, a);
-    JSString * bb = JS_NewStringCopyZ(c, b);
-    jsval rval;
-    JS_DefineProperty(c, c.queryGlobal(), "a", STRING_TO_JSVAL(aa), NULL, NULL, JSPROP_READONLY);
-    JS_DefineProperty(c, c.queryGlobal(), "b", STRING_TO_JSVAL(bb), NULL, NULL, JSPROP_READONLY);
-    JSBool ok = JS_EvaluateScript(c, c.queryGlobal(), script, strlen(script), __FILE__, __LINE__, &rval);
-    if (rval == NULL | rval == JS_FALSE)
-        rtlFail(0, "Error in JavaScript evaluation");
-    JSString *str = JS_ValueToString(c, rval);
-    const char * chars = JS_EncodeString(c, str);
-    __lenResult = strlen(chars);
-    __result = (char *) rtlMalloc(__lenResult);
-    memcpy(__result, chars, __lenResult);
-}
-ENDC++;
-
-//--------------------------------------------------------
-
-// ECL code - an input dataset with 2 records, each containing 2 strings
-// Note that it uses the threaded concat operation, to test that multi-threaded access to the JS engine works
-
-inrec := RECORD
-           string f1;
-           string f2;
-         END;
-infile1 := DATASET([{'a', 'b'}, {'c', 'd'}], inrec);
-infile2 := DATASET([{'e', 'f'}, {'g', 'h'}], inrec);
-
-// Output record has just one string, filled in from the result of the JavaScript function
-outrec := RECORD
-            string c;
-          END;
-
-outrec t(inrec L) := TRANSFORM
-  SELF.c := jseval('a + b', L.f1, L.f2)  // Evaluates JavaScript expression to concatenate strings
-END;
-
-outfile := project(infile1, t(LEFT))+project(infile2, t(LEFT));  // threaded concat operation
-
-outfile;

+ 0 - 81
initfiles/examples/javascript/jsv8.ecl

@@ -1,81 +0,0 @@
-/* Example of calling JavaScript (V8 engine) from ECL code via embedded C++
-*
-* This example evalues a JS expression within an ECL transform
-*
-*/
-
-#option('linkOptions', '-lv8')
-
-// Embedded C++ that makes a evaluates the script passed to it
-
-string jseval(varstring script, varstring a, varstring b) := BEGINC++
-
-// This section of the code should probably move to a plugin, or somesuch
-
-/* Include the JSAPI header file to get access to SpiderMonkey. */
-#include "v8.h"
-
-#body
-
-using namespace v8;
-
-// extern  void user1(size32_t & __lenResult,char * & __result, const char * script, const char *a, const char *b) {
-{
-    Isolate* isolate = Isolate::New();
-    {
-        v8::Isolate::Scope iscope(isolate);
-        // Create a stack-allocated handle scope.
-        HandleScope handle_scope;
-        Persistent<Context> context = Context::New();
-        Context::Scope context_scope(context);
-
-        // Bind the parameters into the context
-        context->Global()->Set(String::New("a"), String::New(a));
-        context->Global()->Set(String::New("b"), String::New(b));
-
-        // Create a string containing the JavaScript source code.
-        Handle<String> source = String::New(script);
-
-        // Compile the source code.
-        Handle<Script> script = Script::Compile(source);
-
-        // Run the script to get the result.
-        Handle<Value> result = script->Run();
-
-        // Dispose the persistent context.
-        context.Dispose();
-
-        // Convert the result to an ASCII string and return it.
-        String::AsciiValue ascii(result);
-        const char *chars= *ascii;
-        __lenResult = strlen(chars);
-        __result = (char *)rtlMalloc(__lenResult);
-        memcpy(__result, chars, __lenResult);
-    }
-    isolate->Dispose();
-}
-ENDC++;
-
-//--------------------------------------------------------
-
-// ECL code - an input dataset with 2 records, each containing 2 strings
-
-inrec := RECORD
-           string f1;
-           string f2;
-         END;
-infile1 := DATASET([{'a', 'b'}, {'c', 'd'}], inrec);
-infile2 := DATASET([{'e', 'f'}, {'g', 'h'}], inrec);
-
-// Output record has just one string, filled in from the result of the JavaScript function
-outrec := RECORD
-            string c;
-          END;
-
-outrec t(inrec L) := TRANSFORM
-  SELF.c := jseval('a + b', L.f1, L.f2)  // Evaluates JavaScript expression to concatenate strings
-END;
-
-outfile := project(infile1, t(LEFT))+project(infile2, t(LEFT));  // threaded concat operation
-
-outfile;

二進制
initfiles/examples/jni/JavaCat.class


+ 0 - 9
initfiles/examples/jni/JavaCat.java

@@ -1,9 +0,0 @@
-public class JavaCat
-{
-    public static String cat(String a, String b)
-    {
-        // System.out.println("In java");
-        // System.out.println(a+b);
-        return a + b;
-    }
-}

+ 0 - 166
initfiles/examples/jni/java_from_ecl.ecl

@@ -1,166 +0,0 @@
-/* Example of calling java from ECL code via embedded C++
-*
-* This example uses the following code in JavaCat.java:
-*
-* public class JavaCat
-* {
-*   public static String cat(String a, String b)
-*   {
-*     System.out.println("In java");
-*     System.out.println(a+b);
-*     return a + b;
-*   }
-* }
-*
-* Compile it using
-*
-*   javac javacat
-*
-* You can also generate the signature for the function to be called using
-*
-*   javap -s -p javacat
-*
-* Note that a JVM - once loaded - cannot be successfully unloaded. Therefore this code will work
-* for repeated workunits on hthor, but on Thor and Roxie you will only be able to run once before
-* needing to restart the Thor/Roxie cluster. Moving the code into a plugin will help resolve that.
-*
-*/
-
-// Set the compiler/linker options needed to ensure that the jvm is linked
-
-#option ('compileOptions', '-I/usr/lib/jvm/java-6-openjdk/include/');
-#option ('linkOptions', '-L/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/ -L/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/ -Wl,-rpath,/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/ -Wl,-rpath,/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/');
-
-// Embedded C++ that makes a JNI call
-
-string cat(varstring a, varstring b) := BEGINC++
-
-// This section of the code should probably move to a plugin, or somesuch
-
-#include <jni.h>
-#include <assert.h>
-#option library jawt
-#option library jvm
-
-static JavaVM *javaVM;       /* denotes a Java VM */
-static pthread_once_t jni_init_flag = PTHREAD_ONCE_INIT;  /* Ensures initialized just once */
-
-static void initJNI()
-{
-    assert (!javaVM);
-    JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */
-    JavaVMOption* options = new JavaVMOption[2];
-    char classPath[2048];
-    strcpy(classPath,"-Djava.class.path=.:/opt/HPCCSystems/examples/jni");
-    const char *oldPath = getenv("CLASSPATH");
-    if (oldPath && *oldPath)
-    {
-        strcat(classPath, ":");
-        strcat(classPath, oldPath);
-    }
-    options[0].optionString = classPath;
-    options[1].optionString = (char *) "-verbose:jni";
-    vm_args.version = JNI_VERSION_1_6;
-    vm_args.nOptions = 1;  // set to 2 if you want the verbose...
-    vm_args.options = options;
-    vm_args.ignoreUnrecognized = false;
-    /* load and initialize a Java VM, return a JNI interface pointer in env */
-    JNIEnv *env;       /* receives pointer to native method interface */
-    jint res =JNI_CreateJavaVM(&javaVM, (void**)&env, &vm_args);
-    delete options;
-    if (res < 0)
-    {
-        rtlFail(res, "Couldn't create JVM");
-    }
-}
-
-static JNIEnv *getJNIEnvironment()
-{
-    pthread_once(&jni_init_flag, initJNI);
-    // Make sure we attach the current thread to the JVM env...
-    // MORE - not sure how efficient it is to call AttachCurrentThread every time
-    //      - We could probably avoid doing so if we add a hook into jthread
-    //      - we are also never calling DetachCurrentThread
-    JNIEnv *JNIenv;       /* receives pointer to native method interface */
-    jint res = javaVM->AttachCurrentThread((void **) &JNIenv, NULL);
-    if (!res < 0)
-       printf("Thread attach failed");
-    return JNIenv;
-}
-
-// MORE - as coded, the JavaVM is never released.
-// This is not too big a deal for a standalone ECL test program for POC,
-// and isn't that much of a problem in a hthor program, as the process terminates
-// at the end of of the workunit execution, but might be an issue if using from thor or roxie.
-//
-// Also should consider whether the java VM should be shared between queries.
-//
-// There is a known bug in DestroyJavaVM, which means you can't actually create more than one Java VM per process.
-// This bug has been around forever, and is not going to get fixed. So the options here are limited...
-
-//--------------------------------------------------------
-
-// This section of code should ideally be generated by the ECL compiler in response to a method being marked as ,jni
-// You would need similar code for each java method you want to call
-
-static jclass JavaCat;
-static jmethodID JavaCat_cat;
-static pthread_once_t jni_resolve_flag = PTHREAD_ONCE_INIT;  /* Ensures called just once */
-
-static void resolveJNIMethods()
-{
-    /* Do all the function resolution just the once... */
-    /* MORE - this bit should be generated too */
-    JNIEnv *env = getJNIEnvironment();
-    JavaCat = env->FindClass("JavaCat");
-    JavaCat_cat = env->GetStaticMethodID(JavaCat, "cat", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
-}
-
-//--------------------------------------------------------
-
-// This section of code should ideally be generated by the ECL compiler inline when calling a ,jni method
-
-#body
-
-// extern  void user1(size32_t & __lenResult,char * & __result,const char * a,const char * b) {
-    pthread_once(&jni_resolve_flag, resolveJNIMethods);
-
-    JNIEnv *env = getJNIEnvironment();
-    if (!env || !JavaCat || !JavaCat_cat)
-        rtlFail(0, "Failed to resolve JNI functions");
-    jstring jstrA = env->NewStringUTF(a);
-    jstring jstrB = env->NewStringUTF(b);
-    jstring result = (jstring) env->CallStaticObjectMethod(JavaCat, JavaCat_cat, jstrA, jstrB);
-    // MORE - should consider marshalling java exceptions into c++ ones here...
-
-    __lenResult = env->GetStringUTFLength(result);
-    const char * chars =  env->GetStringUTFChars(result, NULL);
-    __result = (char *)rtlMalloc(__lenResult);
-    memcpy(__result, chars, __lenResult);
-    env->ReleaseStringUTFChars(result, chars);
-// }
-ENDC++;
-
-//--------------------------------------------------------
-
-// ECL code - an input dataset with 2 records, each containing 2 strings
-
-inrec := RECORD
-           string f1;
-           string f2;
-         END;
-infile1 := DATASET([{'a', 'b'}, {'c', 'd'}], inrec);
-infile2 := DATASET([{'e', 'f'}, {'g', 'h'}], inrec);
-
-// Output record has just one string, filled in from the result of the java function
-outrec := RECORD
-            string c;
-          END;
-
-outrec t(inrec L) := TRANSFORM
-  SELF.c := cat(L.f1, L.f2)  // Calls Java function
-END;
-
-outfile := project(infile1, t(LEFT))+project(infile2, t(LEFT));  // threaded concat operation
-
-outfile;

+ 0 - 7
initfiles/examples/python/python_cat.py

@@ -1,7 +0,0 @@
-#!/usr/bin/python
-
-def cat(a, b):
-  return a + b
-
-if __name__=="__main__":
-   print cat("Hello", " world")

+ 0 - 152
initfiles/examples/python/python_embed.ecl

@@ -1,152 +0,0 @@
-/* Example of calling Python from ECL code via embedded C++
-*
-* This example evalues a python expression within an ECL transform
-* Because the python will be compiled every time the expression is evaluated, it
-* is likely to be less efficient than calling external python code as in the example
-* python_from_ecl
-*
-*/
-
-#option('compileOptions', '-I/usr/include/python2.7/')
-#option('linkOptions', '-lpython2.7')
-
-// Embedded C++ that makes a call to a Python function
-
-
-string pythonCat(varstring a, varstring b) := BEGINC++
-
-// This section of the code should probably move to a plugin, or somesuch
-
-#include <Python.h>
-#include <assert.h>
-#include <pthread.h>
-
-static PyObject *pFunc_cat;
-
-class PythonInitializer
-{
-    PyObject *pModule;
-    PyThreadState *tstate;
-    bool pythonInitialized;
-public:
-    PythonInitializer()
-    {
-        pModule = NULL;
-        tstate = NULL;
-        pythonInitialized = false;
-
-        // Initialize the Python Interpreter
-        Py_Initialize();
-        PyEval_InitThreads();
-        pythonInitialized = true;
-        tstate = PyEval_SaveThread();
-    }
-    ~PythonInitializer()
-    {
-        PyEval_RestoreThread(tstate);
-        // Clean up
-        if (pModule)
-            Py_DECREF(pModule);
-        // Finish the Python Interpreter
-        if (pythonInitialized)
-            Py_Finalize();
-    }
-
-};
-
-PythonInitializer __initializer;
-
-// Use class OwnedPyObject for any objects that are not 'borrowed references'
-// so that the appropriate Py_DECREF call is made when the OwnedPyObject goes
-// out of scope, even if the function returns prematurely (such as via an exception).
-// In particular, checkPythonError is a lot easier to call safely if this is used.
-
-class OwnedPyObject
-{
-    PyObject *ptr;
-public:
-    inline OwnedPyObject(PyObject *_ptr) : ptr(_ptr) {}
-    inline ~OwnedPyObject()                { if (ptr) Py_DECREF(ptr); }
-    inline PyObject * get() const          { return ptr; }
-    inline PyObject * operator -> () const { return ptr; }
-    inline operator PyObject *() const     { return ptr; }
-};
-
-// call checkPythonError to throw an exception if Python error state is set
-
-static void checkPythonError()
-{
-    PyObject* err = PyErr_Occurred();
-    if (err)
-    {
-        OwnedPyObject errStr = PyObject_Str(err);
-        PyErr_Clear();
-        rtlFail(0, PyString_AsString(errStr));
-    }
-}
-
-// The Python Global Interpreter Lock (GIL) won't know about C++-created threads, so we need to
-// call PyGILState_Ensure() and PyGILState_Release at the start and end of every function.
-// Wrapping them in a class like this ensures that the release always happens even if
-// the function exists prematurely
-
-class GILstateWrapper
-{
-    PyGILState_STATE gstate;
-public:
-    GILstateWrapper()
-    {
-        gstate = PyGILState_Ensure();
-    }
-    ~GILstateWrapper()
-    {
-        PyGILState_Release(gstate);
-    }
-};
-
-//--------------------------------------------------------
-
-#body
-
-// extern  void user1(size32_t & __lenResult,char * & __result, const char *a, const char *b) {
-{
-    GILstateWrapper gstate;
-    static OwnedPyObject pythonCode = Py_CompileString("a+b", "user1", Py_eval_input);
-
-    OwnedPyObject locals = PyDict_New ();
-    OwnedPyObject globals = PyDict_New ();
-    PyDict_SetItemString(locals, "a", PyString_FromString(a));
-    PyDict_SetItemString(locals, "b", PyString_FromString(b));
-    OwnedPyObject pResult = PyEval_EvalCode((PyCodeObject *) pythonCode.get(), locals, globals);
-    checkPythonError();
-     __lenResult = PyString_Size(pResult);
-    const char * chars =  PyString_AsString(pResult);
-    checkPythonError();
-    __result = (char *)rtlMalloc(__lenResult);
-    memcpy(__result, chars, __lenResult);
-}
-ENDC++;
-
-//--------------------------------------------------------
-
-// ECL code - an input dataset with 2 records, each containing 2 strings
-
-inrec := RECORD
-           string f1;
-           string f2;
-         END;
-infile1 := DATASET([{'a', 'b'}, {'c', 'd'}], inrec);
-infile2 := DATASET([{'e', 'f'}, {'g', 'h'}], inrec);
-
-// Output record has just one string, filled in from the result of the python function
-outrec := RECORD
-            string c;
-          END;
-
-outrec t(inrec L) := TRANSFORM
-  SELF.c := pythonCat(L.f1, L.f2)  // Evaluates python expression to concatenate strings
-END;
-
-outfile := project(infile1, t(LEFT))+project(infile2, t(LEFT));  // threaded concat operation
-
-outfile;

+ 0 - 151
initfiles/examples/python/python_embed2.ecl

@@ -1,151 +0,0 @@
-/* Example of calling Python from ECL code via embedded C++
-*
-* This example evalues a python expression within an ECL transform
-* Because the python will be compiled every time the expression is evaluated, it
-* is likely to be less efficient than calling external python code as in the example
-* python_from_ecl
-*
-*/
-
-#option('compileOptions', '-I/usr/include/python2.7/')
-#option('linkOptions', '-lpython2.7')
-
-// Embedded C++ that makes a call to a Python function
-
-
-string python(varstring expr, varstring a, varstring b) := BEGINC++
-
-// This section of the code should probably move to a plugin, or somesuch
-
-#include <Python.h>
-#include <assert.h>
-#include <pthread.h>
-
-static PyObject *pFunc_cat;
-
-class PythonInitializer
-{
-    PyObject *pModule;
-    PyThreadState *tstate;
-    bool pythonInitialized;
-public:
-    PythonInitializer()
-    {
-        pModule = NULL;
-        tstate = NULL;
-        pythonInitialized = false;
-
-        // Initialize the Python Interpreter
-        Py_Initialize();
-        PyEval_InitThreads();
-        pythonInitialized = true;
-        tstate = PyEval_SaveThread();
-    }
-    ~PythonInitializer()
-    {
-        PyEval_RestoreThread(tstate);
-        // Clean up
-        if (pModule)
-            Py_DECREF(pModule);
-        // Finish the Python Interpreter
-        if (pythonInitialized)
-            Py_Finalize();
-    }
-
-};
-
-PythonInitializer __initializer;
-
-// Use class OwnedPyObject for any objects that are not 'borrowed references'
-// so that the appropriate Py_DECREF call is made when the OwnedPyObject goes
-// out of scope, even if the function returns prematurely (such as via an exception).
-// In particular, checkPythonError is a lot easier to call safely if this is used.
-
-class OwnedPyObject
-{
-    PyObject *ptr;
-public:
-    inline OwnedPyObject(PyObject *_ptr) : ptr(_ptr) {}
-    inline ~OwnedPyObject()                { if (ptr) Py_DECREF(ptr); }
-    inline PyObject * get() const          { return ptr; }
-    inline PyObject * operator -> () const { return ptr; }
-    inline operator PyObject *() const     { return ptr; }
-};
-
-// call checkPythonError to throw an exception if Python error state is set
-
-static void checkPythonError()
-{
-    PyObject* err = PyErr_Occurred();
-    if (err)
-    {
-        OwnedPyObject errStr = PyObject_Str(err);
-        PyErr_Clear();
-        rtlFail(0, PyString_AsString(errStr));
-    }
-}
-
-// The Python Global Interpreter Lock (GIL) won't know about C++-created threads, so we need to
-// call PyGILState_Ensure() and PyGILState_Release at the start and end of every function.
-// Wrapping them in a class like this ensures that the release always happens even if
-// the function exists prematurely
-
-class GILstateWrapper
-{
-    PyGILState_STATE gstate;
-public:
-    GILstateWrapper()
-    {
-        gstate = PyGILState_Ensure();
-    }
-    ~GILstateWrapper()
-    {
-        PyGILState_Release(gstate);
-    }
-};
-
-//--------------------------------------------------------
-
-#body
-
-// extern  void user1(size32_t & __lenResult,char * & __result, const char * python, const char *a, const char *b) {
-{
-    GILstateWrapper gstate;
-    checkPythonError();
-    OwnedPyObject locals = PyDict_New ();
-    OwnedPyObject globals = PyDict_New ();
-    PyDict_SetItemString(locals, "a", PyString_FromString(a));
-    PyDict_SetItemString(locals, "b", PyString_FromString(b));
-    OwnedPyObject pResult = PyRun_String(expr, Py_eval_input, locals, globals);
-    checkPythonError();
-     __lenResult = PyString_Size(pResult);
-    const char * chars =  PyString_AsString(pResult);
-    checkPythonError();
-    __result = (char *)rtlMalloc(__lenResult);
-    memcpy(__result, chars, __lenResult);
-}
-ENDC++;
-
-//--------------------------------------------------------
-
-// ECL code - an input dataset with 2 records, each containing 2 strings
-
-inrec := RECORD
-           string f1;
-           string f2;
-         END;
-infile1 := DATASET([{'a', 'b'}, {'c', 'd'}], inrec);
-infile2 := DATASET([{'e', 'f'}, {'g', 'h'}], inrec);
-
-// Output record has just one string, filled in from the result of the python function
-outrec := RECORD
-            string c;
-          END;
-
-outrec t(inrec L) := TRANSFORM
-  SELF.c := python('a + b', L.f1, L.f2)  // Evaluates python expression to concatenate strings
-END;
-
-outfile := project(infile1, t(LEFT))+project(infile2, t(LEFT));  // threaded concat operation
-
-outfile;

+ 0 - 177
initfiles/examples/python/python_from_ecl.ecl

@@ -1,177 +0,0 @@
-/* Example of calling Python from ECL code via embedded C++
-*
-* This example uses the following code in python_cat.py:
-*
-* def cat(a, b):
-*   return a + b
-*
-* Note that you may need to change the line that sets the Python sys.path, if you extend this
-* code to use other python examples, or it you are running on a system other than a standard HPCC
-* install on Linux
-*
-*/
-
-#option('compileOptions', '-I/usr/include/python2.7/')
-#option('linkOptions', '-lpython2.7')
-
-// Embedded C++ that makes a call to a Python function
-
-
-string cat(varstring a, varstring b) := BEGINC++
-
-// This section of the code should probably move to a plugin, or somesuch
-
-#include <Python.h>
-#include <assert.h>
-#include <pthread.h>
-
-static PyObject *pFunc_cat;
-
-class PythonInitializer
-{
-    PyObject *pModule;
-    PyThreadState *tstate;
-    bool pythonInitialized;
-public:
-    PythonInitializer()
-    {
-        pModule = NULL;
-        tstate = NULL;
-        pythonInitialized = false;
-
-        // Initialize the Python Interpreter
-        Py_Initialize();
-        PyEval_InitThreads();
-        pythonInitialized = true;
-        resolvePythonFunctions();
-        tstate = PyEval_SaveThread();
-    }
-    ~PythonInitializer()
-    {
-        PyEval_RestoreThread(tstate);
-        // Clean up
-        if (pModule)
-            Py_DECREF(pModule);
-        // Finish the Python Interpreter
-        if (pythonInitialized)
-            Py_Finalize();
-    }
-
-    void resolvePythonFunctions()
-    {
-        PySys_SetPath("/opt/HPCCSystems/examples/python/");    // Set this to where you want to pick up python_cat.py from
-        pModule = PyImport_ImportModule("python_cat");
-        if (pModule == NULL)
-        {
-            PyErr_Print();
-        }
-        else
-        {
-            // pDict is a borrowed reference
-            PyObject *pDict = PyModule_GetDict(pModule);
-            // pFunc_cat is also a borrowed reference
-            pFunc_cat = PyDict_GetItemString(pDict, "cat");
-            if (!pFunc_cat || !PyCallable_Check(pFunc_cat))
-            {
-                PyErr_Print();
-                pFunc_cat = NULL;
-            }
-        }
-    }
-
-};
-
-PythonInitializer __initializer;
-
-// Use class OwnedPyObject for any objects that are not 'borrowed references'
-// so that the appropriate Py_DECREF call is made when the OwnedPyObject goes
-// out of scope, even if the function returns prematurely (such as via an exception).
-// In particular, checkPythonError is a lot easier to call safely if this is used.
-
-class OwnedPyObject
-{
-    PyObject *ptr;
-public:
-    inline OwnedPyObject(PyObject *_ptr) : ptr(_ptr) {}
-    inline ~OwnedPyObject()                { if (ptr) Py_DECREF(ptr); }
-    inline PyObject * get() const          { return ptr; }
-    inline PyObject * operator -> () const { return ptr; }
-    inline operator PyObject *() const     { return ptr; }
-};
-
-// call checkPythonError to throw an exception if Python error state is set
-
-static void checkPythonError()
-{
-    PyObject* err = PyErr_Occurred();
-    if (err)
-    {
-        OwnedPyObject errStr = PyObject_Str(err);
-        PyErr_Clear();
-        rtlFail(0, PyString_AsString(errStr));
-    }
-}
-
-// The Python Global Interpreter Lock (GIL) won't know about C++-created threads, so we need to
-// call PyGILState_Ensure() and PyGILState_Release at the start and end of every function.
-// Wrapping them in a class like this ensures that the release always happens even if
-// the function exists prematurely
-
-class GILstateWrapper
-{
-    PyGILState_STATE gstate;
-public:
-    GILstateWrapper()
-    {
-        gstate = PyGILState_Ensure();
-    }
-    ~GILstateWrapper()
-    {
-        PyGILState_Release(gstate);
-    }
-};
-
-//--------------------------------------------------------
-
-#body
-
-// extern  void user1(size32_t & __lenResult,char * & __result,const char * a,const char * b) {
-{
-    if (!pFunc_cat)
-       rtlFail(0, "Could not resolve python functions");
-    GILstateWrapper gstate;
-    OwnedPyObject pArgs = Py_BuildValue("s,s", a, b);
-    checkPythonError();
-    OwnedPyObject pResult = PyObject_CallObject(pFunc_cat, pArgs);
-    checkPythonError();
-     __lenResult = PyString_Size(pResult);
-    const char * chars =  PyString_AsString(pResult);
-    checkPythonError();
-    __result = (char *)rtlMalloc(__lenResult);
-    memcpy(__result, chars, __lenResult);
-}
-ENDC++;
-
-//--------------------------------------------------------
-
-// ECL code - an input dataset with 2 records, each containing 2 strings
-
-inrec := RECORD
-           string f1;
-           string f2;
-         END;
-infile1 := DATASET([{'a', 'b'}, {'c', 'd'}], inrec);
-infile2 := DATASET([{'e', 'f'}, {'g', 'h'}], inrec);
-
-// Output record has just one string, filled in from the result of the python function
-outrec := RECORD
-            string c;
-          END;
-
-outrec t(inrec L) := TRANSFORM
-  SELF.c := cat(L.f1, L.f2)  // Calls Python function
-END;
-
-outfile := project(infile1, t(LEFT))+project(infile2, t(LEFT));  // threaded concat operation
-
-outfile;

+ 0 - 149
initfiles/examples/python/python_from_ecl2.ecl

@@ -1,149 +0,0 @@
-/* Example of calling Python from ECL code via embedded C++
-*
-* This example evalues a python expression within an ECL transform
-* Because the python will be compiled every time the expression is evaluated, it
-* is likely to be less efficient than calling external python code as in the example
-* python_from_ecl
-*
-*/
-
-#option('compileOptions', '-I/usr/include/python2.7/')
-#option('linkOptions', '-lpython2.7')
-
-// Embedded C++ that makes a call to a Python function
-
-
-string python(varstring expr) := BEGINC++
-
-// This section of the code should probably move to a plugin, or somesuch
-
-#include <Python.h>
-#include <assert.h>
-#include <pthread.h>
-
-static PyObject *pFunc_cat;
-
-class PythonInitializer
-{
-    PyObject *pModule;
-    PyThreadState *tstate;
-    bool pythonInitialized;
-public:
-    PythonInitializer()
-    {
-        pModule = NULL;
-        tstate = NULL;
-        pythonInitialized = false;
-
-        // Initialize the Python Interpreter
-        Py_Initialize();
-        PyEval_InitThreads();
-        pythonInitialized = true;
-        tstate = PyEval_SaveThread();
-    }
-    ~PythonInitializer()
-    {
-        PyEval_RestoreThread(tstate);
-        // Clean up
-        if (pModule)
-            Py_DECREF(pModule);
-        // Finish the Python Interpreter
-        if (pythonInitialized)
-            Py_Finalize();
-    }
-
-};
-
-PythonInitializer __initializer;
-
-// Use class OwnedPyObject for any objects that are not 'borrowed references'
-// so that the appropriate Py_DECREF call is made when the OwnedPyObject goes
-// out of scope, even if the function returns prematurely (such as via an exception).
-// In particular, checkPythonError is a lot easier to call safely if this is used.
-
-class OwnedPyObject
-{
-    PyObject *ptr;
-public:
-    inline OwnedPyObject(PyObject *_ptr) : ptr(_ptr) {}
-    inline ~OwnedPyObject()                { if (ptr) Py_DECREF(ptr); }
-    inline PyObject * get() const          { return ptr; }
-    inline PyObject * operator -> () const { return ptr; }
-    inline operator PyObject *() const     { return ptr; }
-};
-
-// call checkPythonError to throw an exception if Python error state is set
-
-static void checkPythonError()
-{
-    PyObject* err = PyErr_Occurred();
-    if (err)
-    {
-        OwnedPyObject errStr = PyObject_Str(err);
-        PyErr_Clear();
-        rtlFail(0, PyString_AsString(errStr));
-    }
-}
-
-// The Python Global Interpreter Lock (GIL) won't know about C++-created threads, so we need to
-// call PyGILState_Ensure() and PyGILState_Release at the start and end of every function.
-// Wrapping them in a class like this ensures that the release always happens even if
-// the function exists prematurely
-
-class GILstateWrapper
-{
-    PyGILState_STATE gstate;
-public:
-    GILstateWrapper()
-    {
-        gstate = PyGILState_Ensure();
-    }
-    ~GILstateWrapper()
-    {
-        PyGILState_Release(gstate);
-    }
-};
-
-//--------------------------------------------------------
-
-#body
-
-// extern  void user1(size32_t & __lenResult,char * & __result, const char * expr) {
-{
-    GILstateWrapper gstate;
-    checkPythonError();
-    OwnedPyObject locals = PyDict_New ();
-    OwnedPyObject globals = PyDict_New ();
-    OwnedPyObject pResult = PyRun_String(expr, Py_eval_input, locals, globals);
-    checkPythonError();
-     __lenResult = PyString_Size(pResult);
-    const char * chars =  PyString_AsString(pResult);
-    checkPythonError();
-    __result = (char *)rtlMalloc(__lenResult);
-    memcpy(__result, chars, __lenResult);
-}
-ENDC++;
-
-//--------------------------------------------------------
-
-// ECL code - an input dataset with 2 records, each containing 2 strings
-
-inrec := RECORD
-           string f1;
-           string f2;
-         END;
-infile1 := DATASET([{'a', 'b'}, {'c', 'd'}], inrec);
-infile2 := DATASET([{'e', 'f'}, {'g', 'h'}], inrec);
-
-// Output record has just one string, filled in from the result of the python function
-outrec := RECORD
-            string c;
-          END;
-
-outrec t(inrec L) := TRANSFORM
-  SELF.c := python('"' + L.f1 + '" + "' + L.f2 + '"')  // Evaluates python expression to concatenate strings
-END;
-
-outfile := project(infile1, t(LEFT))+project(infile2, t(LEFT));  // threaded concat operation
-
-outfile;