Bulk Update with RestQL
The following example bulk updates key-value collection data via RestQL.
Assume these credentials:
- Tenant name: nemo@nautilus.com
- Password: xxxxxx
SDK download
Download the appropriate SDK for Python or JavaScript.
- Python
- Javascript
pyC8 requires Python 3.5+. Python 3.6 or higher is recommended
To install pyC8, run
    $ pip3 install pyC8
Alternatively, you can use conda:
    conda install -c conda-forge pyC8
Alternatively, you can use pipenv:
    pipenv install --pre pyC8
Any one of these three commands will install Python and enable you to develop applications.
With Yarn:
    yarn add jsc8
With NPM:
    npm install jsc8
If you want to use the SDK outside of the current directory, you can also install it globally using the `--global` flag:
    npm install --global jsc8
From source:
    git clone https://github.com/macrometacorp/jsc8.git
    cd jsC8
    npm install
    npm run dist
Code Sample
- Rest API
- Python
- Javascript
class APIRequest {
    _headers = {
        Accept: "application/json",
        "Content-Type": "application/json",
    };
    constructor(url) {
        this._url = url;
    }
    login(email, password) {
        const endpoint = "/_open/auth";
        const self = this;
        return new Promise(function (resolve, reject) {
            self.req(endpoint, {
                body: { email, password },
                method: "POST",
            })
                .then(({ jwt, ...data }) => {
                    self._headers.authorization = `bearer ${jwt}`;
                    resolve(data);
                })
                .catch(reject);
        });
    }
    _handleResponse(response, resolve, reject) {
        if (response.ok) {
            resolve(response.json());
        } else {
            reject(response);
        }
    }
    req(endpoint, { body, ...options } = {}) {
        const self = this;
        return new Promise(function (resolve, reject) {
            fetch(self._url + endpoint, {
                headers: self._headers,
                body: body ? JSON.stringify(body) : undefined,
                ...options,
            }).then((response) => self._handleResponse(response, resolve, reject));
        });
    }
}
const EMAIL = "nemo@nautilus.com";
const PASSWORD = "xxxxxx";
const HTTP_URL = "https://api-play.paas.macrometa.io";
const FABRIC_NAME = "_system";
const COLLECTION_NAME = "superhero";
//Variables
const inputDocs = [
    { "_key": "james.kirk@mafabriccrometa.io", "value": "James"},
    { "_key": "han.solo@macrfabricometa.io", "value": "Han"},
    { "_key": "bruce.wayne@mfabricacrometa.io", "value": "Bruce"}
];
const updateKeys = ["james.kirk@mafabriccrometa.io", "bruce.wayne@mfabricacrometa.io"];
const updateKeyValue = {
    "bruce.wayne@mfabricacrometa.io": { key: "bruce.wayne@mfabricacrometa.io",  value: "Bruce Wayne"},
    "james.kirk@mafabriccrometa.io": { key: "james.kirk@mafabriccrometa.io", value: "James T Kirk"}
};
//Queries
const insertData = `FOR doc in @InputDocs \
INSERT {"_key": doc._key, "value": doc.value} IN ${COLLECTION_NAME}`;
const getData = `FOR doc IN ${COLLECTION_NAME} RETURN doc`;
const updateData = `FOR i IN ${COLLECTION_NAME} \
FILTER i._key IN @updateKeys \
UPDATE i with { value: (i._key == @updateKeyValue[i._key].key) ? @updateKeyValue[i._key].value : i.value } IN ${COLLECTION_NAME}`;
const run = async function () {
    try {
        const connection = new APIRequest(HTTP_URL);
        /* -------------------- Log in (nemo@nautilus.com/xxxxxxx) -------------------- */
        await connection.login(EMAIL, PASSWORD);
        console.log("Login Successfully using", EMAIL);
        /* -------------------------- Create doc collection ------------------------- */
        const collection = await connection.req(`/_fabric/${FABRIC_NAME}/_api/kv/${COLLECTION_NAME}`, {
            body: { stream: false },
            method: "POST",
        });
        console.log("COLLECTION CREATED SUCCESSFULLY", collection);
        /* ------------------------ Save a RestQL query ----------------------- */
        const saveRestQlQuery = (queryName, query, parameter) =>
            connection.req(`/_fabric/${FABRIC_NAME}/_api/restql`, {
                body: {
                    query: {
                        name: queryName,
                        value: query,
                        parameter,
                    },
                },
                method: "POST",
            });
        console.log("------- Save the RestQl Queries  ------");
        await saveRestQlQuery("insertData", insertData, {});
        await saveRestQlQuery("getData", getData, {});
        await saveRestQlQuery("updateData", updateData, {});
        console.log("Queries Saved Successfully");
        /* ----------------------- Run a RestQL query ---------------------- */
        const executeRestql = (queryName, parameter) =>
            connection.req(`/_fabric/${FABRIC_NAME}/_api/restql/execute/${queryName}`, {
                body: {
                    bindVars: parameter,
                },
                method: "POST",
            });
        console.log("------- Bulk run RestQl queries  ------");
        await executeRestql("insertData", {
            InputDocs: inputDocs,
        });
        console.log("Data Inserted \n");
        console.log("Get Data...");
        const dataBeforeUpdate = await executeRestql("getData");
        console.log(dataBeforeUpdate.result);
        console.log("\n");
        await executeRestql("updateData", {
            updateKeys,
            updateKeyValue,
        });
        console.log("Data updated \n");
        const dataAfterUpdate = await executeRestql("getData");
        console.log(dataAfterUpdate.result);
        console.log("\n");
    } catch (e) {
        console.error(e);
    }
};
run();
import time
from c8 import C8Client
HTTP_URL = "play.paas.macrometa.io"
GUEST_MAIL = "nemo@nautilus.com"
GUEST_PASSWORD = "xxxxxx"
GEO_FABRIC = "_system"
COLLECTION_NAME = "superhero"
INPUT_DOCS = [
    { "_key": "james.kirk@macrometa.io", "value": "James"},
    { "_key": "han.solo@macrometa.io", "value": "Han"},
    { "_key": "bruce.wayne@macrometa.io", "value": "Bruce"}
]
UPDATE_KEYS = ["james.kirk@macrometa.io", "bruce.wayne@macrometa.io"]
UPDATE_KEY_VALUE = {
    "bruce.wayne@macrometa.io": { "key": "bruce.wayne@macrometa.io",  "value": "Bruce Wayne"},
    "james.kirk@macrometa.io": { "key": "james.kirk@macrometa.io", "value": "James T Kirk"}
}
INSERT_DATA_QUERY = (
    f"FOR doc in @InputDocs INSERT {{'_key': doc._key, 'value': doc.value}} IN {COLLECTION_NAME}"
)
GET_DATA_QUERY = f"FOR doc IN {COLLECTION_NAME} RETURN doc"
UPDATE_DATA_QUERY = (
    f"FOR i IN {COLLECTION_NAME} FILTER i._key IN @updateKeys UPDATE i with {{ value: (i._key == @updateKeyValue[i._key].key) ? @updateKeyValue[i._key].value : i.value }} IN {COLLECTION_NAME}"
)
UPDATED_INSERT_QUERY = (
    f"INSERT {{'_key': 'barry.allen@macrometa.io', 'value': 'Barry Allen'}} IN {COLLECTION_NAME}"
)
INSERT_DATA = {
    "query": {
        "name": "insertRecord",
        "value": INSERT_DATA_QUERY,
    }
}
GET_DATA = {"query": {"name": "getRecords", "value": GET_DATA_QUERY}}
UPDATE_DATA = {"query": {"name": "updateRecord", "value": UPDATE_DATA_QUERY}}
UPDATED_INSERT_DATA = {
    "query": {
        "value": UPDATED_INSERT_QUERY,
    }
}
if __name__ == "__main__":
    print("\n ------- CONNECTION SETUP  ------")
    print(f"tenant: {GUEST_MAIL}, geofabric:{GEO_FABRIC}")
    client = C8Client(
        protocol="https",
        host=HTTP_URL,
        port=443,
        email=GUEST_MAIL,
        password=GUEST_PASSWORD,
        geofabric=GEO_FABRIC
    )
    print("\n ------- CREATE GEO-REPLICATED COLLECTION  ------")
    if client.has_collection(COLLECTION_NAME):
        print("Collection exists")
    else:
        employees = client.create_collection_kv(COLLECTION_NAME)
    print(f"Created collection: {COLLECTION_NAME}")
    print("\n ------- CREATE RESTQLs  ------")
    client.create_restql(INSERT_DATA)
    client.create_restql(GET_DATA)
    client.create_restql(UPDATE_DATA)
    print("Created RESTQLs:{client.get_restqls()}")
    #Wait for all inputs and outputs to initialize
    time.sleep(2)
    print("\n ------- RUN RESTQLs ------")
    print("Insert data....")
    try:
        response = client.execute_restql(
        "insertRecord", {"bindVars": {"InputDocs": INPUT_DOCS}}
    )
    except:
        print("Failed to insert the document because it already exists")
    print("Get data....")
    response = client.execute_restql("getRecords")
    print(response)
    print("Update data....")
    try:
        response = client.execute_restql(
        "updateRecord",
        {"bindVars": {"updateKeys": UPDATE_KEYS, "updateKeyValue": UPDATE_KEY_VALUE}},
        )
    except:
        print("Failed to update the document because it already exists")
    print("Get data....")
    response = client.execute_restql("getRecords")
    print(response)
    #Updating restqls
    client.update_restql("insertRecord",UPDATED_INSERT_DATA)
    time.sleep(2)
    print("Inserting updated data....")
    try:
        response = client.execute_restql("insertRecord")
    except:
        print("Failed to insert the document because it already exists")
    #Deleting RestQls
    client.delete_restql("insertRecord")
    client.delete_restql("getRecords")
    client.delete_restql("updateRecord")
    print("\n ------- DONE  ------")
const jsc8 = require('jsc8');
// Create an authenticated instance with a JSON Web Token or API key
// const client = new jsc8({url: "https://play.paas.macrometa.io", token: "XXXX", fabricName: '_system'});
// const client = new jsc8({url: "https://play.paas.macrometa.io", apiKey: "XXXX", fabricName: '_system'});
const client = new jsc8("https://play.paas.macrometa.io");
//Variables
const collectionName = "superhero" + Math.floor(1000 + Math.random() * 9000).toString();
const inputDocs = [
    { "_key": "james.kirk@mafabriccrometa.io", "value": "James"},
    { "_key": "han.solo@macrfabricometa.io", "value": "Han"},
    { "_key": "bruce.wayne@mfabricacrometa.io", "value": "Bruce"}
];
const updateKeys = ["james.kirk@mafabriccrometa.io", "bruce.wayne@mfabricacrometa.io"];
const updateKeyValue = {
    "bruce.wayne@mfabricacrometa.io": { key: "bruce.wayne@mfabricacrometa.io",  value: "Bruce Wayne"},
    "james.kirk@mafabriccrometa.io": { key: "james.kirk@mafabriccrometa.io", value: "James T Kirk"}
};
//Queries
const insertData = `FOR doc in @InputDocs \
INSERT {"_key": doc._key, "value": doc.value} IN ${collectionName}`;
const getData = `FOR doc IN ${collectionName} RETURN doc`;
const updateData = `FOR i IN ${collectionName} \
FILTER i._key IN @updateKeys \
UPDATE i with { value: (i._key == @updateKeyValue[i._key].key) ? @updateKeyValue[i._key].value : i.value } IN ${collectionName}`;
async function restqldemo() {
    /* Authenticate client instance with username and password */
    console.log("------- AUTHENTICATE CLIENT INSTANCE WITH USERNAME AND PASSWORD  ------");
    await client.login("nemo@nautilus.com", "xxxxxx");
    /* Create Collection */
    console.log("------- CREATE GEO-REPLICATED COLLECTION  ------");
    const collection = await client.createKVCollection(collectionName);
    console.log("Collection " + collectionName + " created.\n", collection);
    /* Save RestQl Queries */
    console.log("------- SAVE THE QUERIES  ------");
    await client.createRestql("insertData", insertData, {});
    await client.createRestql("getData", getData, {});
    await client.createRestql("updateData", updateData, {});
    console.log("Saved Queries Successfully\n");
    /* Execute RestQl Queries */
    console.log("------- RUN THE QUERIES  ------");
    await client.executeRestql("insertData", {
        InputDocs: inputDocs
    });
    console.log("Data Inserted \n");
    const res = await client.executeRestql("getData");
    console.log("Output of get data query:");
    console.log(res.result);
    console.log("\n");
    await client.executeRestql("updateData", {
        updateKeys,
        updateKeyValue
    });
    console.log("Data updated \n");
    const data = await client.executeRestql("getData");
    console.log("Output of get data query after update:");
    console.log(data.result);
    console.log("\n");
}
restqldemo().then(console.log("Starting Execution"));