Function: Advanced Binary KV

    +

    Goal: Show and Advanced Accessor Binary Write.

    • This function advancedBinaryKV demonstrates creating, marshalling and unmarshalling binary docs.

    • Requires Eventing Storage (or metadata collection) a "source" collection, and a "destination" collection.

    • Needs a Binding of type "bucket alias" (as documented in the Scriptlet).

    • Will operate on any mutation where the KEY or meta.id starts with "advancedbinarykv".

    • The function will create two documents: a binary document and a normal JSON document.

    • Each document will be updated via the Advanced Accessor couchbase.upsert() and then will be verified.

    • The verification and logging will demonstrate binary marshalling and unmarshalling.

    • The return value of couchbase.upsert() on success will indicate either "datatype":"json" or "datatype":"binary"

    • advancedBinaryKV

    • Input Data/Mutation

    • Output Data/Logged

    // To run configure the settings for this Function, advancedBinaryKV, as follows:
    //
    // Version 7.0+
    //   "Listen to Location"
    //     bulk.data.source
    //   "Eventing Storage"
    //     rr100.eventing.metadata
    //   Binding(s)
    //    1. "binding type", "alias name...", "bucket.scope.collection", "Access"
    //       "bucket alias", "dst_col",       "bulk.data.destination",   "read and write"
    //
    // Version 6.6.2
    //   "Source Bucket"
    //     source
    //   "MetaData Bucket"
    //     metadata
    //   Binding(s)
    //    1. "binding type", "alias name...", "bucket",      "Access"
    //       "bucket alias", "dst_col",       "destination", "read and write"
    
    function OnUpdate(doc, meta) {
        if (!meta.id.startsWith("advancedbinarykv")) return;
    
        var doc_is_binary = true;
        var prefix;
        var wrkdoc;
        var is_bin_ary = [true, false];
    
        // loop twice first create a binary doc and then create a normal JSON doc
        for (let doc_is_binary of is_bin_ary) {
            if (doc_is_binary) {
                // Note, we could create binary docs via 'cbc'
                //     "cbc create bindoc -V '^LZ' -U couchbase://localhost/source -u Administrator -P password"
                // However it is easier to make a binary document via pure JavaScript code
                prefix = "bindoc";
                var arr = new Uint8Array([1, 0, 2, 3]);
                var bindoc = arr.buffer;
                wrkdoc = bindoc;
            } else {
                // make a normal JSON doc
                prefix = "jsondoc";
                wrkdoc = {
                    "jsondoc": 1
                };
            }
    
            // ========================================================================
            // Test basic Bucket Op, i.e. JavaScript map exposed via a bucket binding
            dst_col[prefix + "_put"] = wrkdoc;
    
            // ========================================================================
            // Test Advanced Accessors
            // Make a key for Advanced Accessor tests ( note, "datatype" in meta is not needed / ignored )
            var key = prefix + "_upsert";
            var new_meta = { "id": key };
    
            log("1 RUN couchbase.upsert(dst_col,", new_meta, ",", wrkdoc, ")");
            var result = couchbase.upsert(dst_col, new_meta, wrkdoc);
            if (result.success) {
                log('2 success adv. upsert: result', result);
            } else {
                log('2 failure adv. upsert: id', key, 'result', result);
            }
            var tmp = couchbase.get(dst_col, {  "id": key });
            log('3 couchbase.get(dst_col', {  "id": key }, ') => ', tmp);
            couchbase.upsert(dst_col, { "id": key + "_from_adv_get",  "datatype": "bin" }, tmp.doc);
    
            var tag;
            var disp;
            if (tmp.meta.datatype && tmp.meta.datatype == "binary") {
                tag = "binary";
                disp = new Uint8Array(tmp.doc);
                log('4 ' + tag + ' equal = ' + buffersEqual(tmp.doc, wrkdoc), '(was binary so unmarshalled)', disp);
            } else {
                tag = "json";
                disp = tmp.doc;
                log('4 ' + tag + ' equal = ' + (JSON.stringify(tmp.doc) === JSON.stringify(wrkdoc)),
                    '(was json so just the doc)', disp);
            }
        }
    }
    
    function buffersEqual(buf1, buf2) {
        if (buf1.byteLength != buf2.byteLength) return false;
        var dv1 = new Uint8Array(buf1);
        var dv2 = new Uint8Array(buf2);
        for (var i = 0; i != buf1.byteLength; i++) {
            if (dv1[i] != dv2[i]) return false;
        }
        return true;
    }
    INPUT: KEY advancedbinarykv:1
    
    {
      "id": 1,
      "type": "advancedbinarykv"
    }
    2021-07-19T11:16:20.566-07:00 [INFO] "1 RUN couchbase.upsert(dst_col," {"id":"bindoc_upsert"} "," {} ")"
    
    2021-07-19T11:16:20.566-07:00 [INFO] "2 success adv. upsert: result" {"meta":{"id":"bindoc_upsert","cas":"1626718580566458368"},"success":true}
    
    2021-07-19T11:16:20.567-07:00 [INFO] "3 couchbase.get(dst_col" {"id":"bindoc_upsert"} ") => " {"doc":{},"meta":{"id":"bindoc_upsert","cas":"1626718580566458368","datatype":"binary"},"success":true}
    
    2021-07-19T11:16:20.567-07:00 [INFO] "4 binary equal = true" "(was binary so unmarshalled)" {"0":1,"1":0,"2":2,"3":3}
    
    2021-07-19T11:16:20.567-07:00 [INFO] "1 RUN couchbase.upsert(dst_col," {"id":"jsondoc_upsert"} "," {"jsondoc":1} ")"
    
    2021-07-19T11:16:20.568-07:00 [INFO] "2 success adv. upsert: result" {"meta":{"id":"jsondoc_upsert","cas":"1626718580568031232"},"success":true}
    
    2021-07-19T11:16:20.568-07:00 [INFO] "3 couchbase.get(dst_col" {"id":"jsondoc_upsert"} ") => " {"doc":{"jsondoc":1},"meta":{"id":"jsondoc_upsert","cas":"1626718580568031232","datatype":"json"},"success":true}
    
    2021-07-19T11:16:20.568-07:00 [INFO] "4 json equal = true" "(was json so just the doc)" {"jsondoc":1}