Many backends assign unique keys and other control information to data objects. In order to keep the results for a query compatible between backends, the driver has the responsibility to remove these. However there are some occasions when you might want those, and in fact you need key information for the datahandler get() and the update() methods. The query() method will return this control information along with the value that the get() and update() method consider to be the key for a particular object, but separated from the main data. By default, these properties will not be returned. You need to tell .query() you want them as below – where true is the keepIds parameter.

var result = handle.query ( {some query}, {some parameters}, 0, true);

Example

By default, a query will return an object that looks like this:

{
    "handleCode": 0,
    "handleError": "",
    "data": [
        {
            "name": "Virgin America",
            "link": "",
            "carrier": "VX"
        },
        {
            "name": "Virgin Atlantic Airways",
            "link": "",
            "carrier": "VS"
        },
        {
            "name": "TACV Cabo Verde Airlines",
            "link": "",
            "carrier": "VR"
        }
    ],
    "handleVersion": "DataHandler-v0.5",
    "driverVersion": "DriverDrive-v0.0"
}

After checking for a non-negative handleCode, (see  How to write a driver for the possible error codes), you would access the data store in the result.data array.
If I do a query to parse.com, I get the same result. However, parse.com actually inserts a bunch of stuff in your data which the driver strips out. The real results.data looks like this:

{
    "handleCode": 0,
    "handleError": "",
    "data": [
        {
            "carrier": "ZB",
            "name": "Monarch Airways",
            "link": "",
            "createdAt": "2014-04-22T18:39:07.154Z",
            "updatedAt": "2014-04-22T18:39:07.154Z",
            "objectId": "NJrOCY0DnB"
        },
        {
            "carrier": "YV",
            "name": "Mesa Airlines",
            "link": "",
            "createdAt": "2014-04-22T18:39:07.138Z",
            "updatedAt": "2014-04-22T18:39:07.138Z",
            "objectId": "SSuoYOcLO0"
        },
        {
            "carrier": "YR",
            "name": "Scenic Airlines Inc.",
            "link": "",
            "createdAt": "2014-04-22T18:39:07.580Z",
            "updatedAt": "2014-04-22T18:39:07.580Z",
            "objectId": "uHwXTcfBZd"
        }
    ],
    "handleVersion": "DataHandler-v0.5",
    "driverVersion": "DriverParse-v0.1"
}

The unique Id for parse.com is obviously objectId, but for other databases it will be something else. In order to keep consistency between back ends, here’s the full story of what you would get back from the parse.com driver.
Note the 2 properties 
driverIds – contains the additional fields that parse addshandleKeys – the unique keys for each object for which there is data

parse.com results with keepIds

{
    "handleCode": 0,
    "handleError": "",
    "data": [
        {
            "carrier": "ZB",
            "name": "Monarch Airways",
            "link": ""
        },
        {
            "carrier": "YV",
            "name": "Mesa Airlines",
            "link": ""
        },
        {
            "carrier": "YR",
            "name": "Scenic Airlines Inc.",
            "link": ""
        }
    ],
    "handleVersion": "DataHandler-v0.5",
    "driverVersion": "DriverParse-v0.1",
    "handleKeys": [
        "NJrOCY0DnB",
        "SSuoYOcLO0",
        "uHwXTcfBZd"
    ],
    "driverIds": [
        {
            "createdAt": "2014-04-22T18:39:07.154Z",
            "updatedAt": "2014-04-22T18:39:07.154Z",
            "objectId": "NJrOCY0DnB"
        },
        {
            "createdAt": "2014-04-22T18:39:07.138Z",
            "updatedAt": "2014-04-22T18:39:07.138Z",
            "objectId": "SSuoYOcLO0"
        },
        {
            "createdAt": "2014-04-22T18:39:07.580Z",
            "updatedAt": "2014-04-22T18:39:07.580Z",
            "objectId": "uHwXTcfBZd"
        }
    ]
}

The handleKeys array can then be used along with get() and update().

scriptDB results

{
    "handleCode": 0,
    "handleError": "",
    "data": [
        {
            "name": "Monarch Airways",
            "link": "",
            "carrier": "ZB"
        },
        {
            "name": "Mesa Airlines",
            "link": "",
            "carrier": "YV"
        },
        {
            "name": "Scenic Airlines Inc.",
            "link": "",
            "carrier": "YR"
        }
    ],
    "handleVersion": "DataHandler-v0.5",
    "driverVersion": "DriverScriptDb-v0.2",
    "handleKeys": [
        "S401370202671",
        "S401370202752",
        "S401370202668"
    ],
    "driverIds": [
        {
            "id": "S401370202671"
        },
        {
            "id": "S401370202752"
        },
        {
            "id": "S401370202668"
        }
    ]
}

Function results

{
    "handleCode": 0,
    "handleError": "",
    "data": [
        {
            "carrier": "ZB",
            "name": "Monarch Airways",
            "link": ""
        },
        {
            "carrier": "YV",
            "name": "Mesa Airlines",
            "link": ""
        },
        {
            "carrier": "YR",
            "name": "Scenic Airlines Inc.",
            "link": ""
        }
    ],
    "handleVersion": "DataHandler-v0.5",
    "driverVersion": "DriverFusion-v0.1",
    "handleKeys": [
        "359",
        "357",
        "393"
    ],
    "driverIds": [
        {
            "rowid": "359"
        },
        {
            "rowid": "357"
        },
        {
            "rowid": "393"
        }
    ]
}

Orchestrate.io results

Sometimes the .count() function for orchestrate does not reflect the true count of matching records if you execute it immediately after saving some records. I suspect there is some kind of internal delay in the orchestrate.io back end. 

{
    "handleCode": 0,
    "handleError": "",
    "data": [
        {
            "carrier": "OS",
            "name": "Austrian Airlines",
            "link": ""
        },
        {
            "carrier": "UP",
            "name": "Bahamas Air",
            "link": ""
        },
        {
            "carrier": "CX",
            "name": "Cathay Pacific Airways",
            "link": ""
        }
    ],
    "handleVersion": "DataHandler-v0.5",
    "driverVersion": "DriverOrchestrate-v0.2",
    "handleKeys": [
        "sm1398191882780",
        "ck1398191882901",
        "du1398191883704"
    ],
    "driverIds": [
        {
            "path": {
                "collection": "carriers",
                "key": "sm1398191882780",
                "ref": "bff49ff055a0c7d1"
            }
        },
        {
            "path": {
                "collection": "carriers",
                "key": "ck1398191882901",
                "ref": "2370287b9b7df8ae"
            }
        },
        {
            "path": {
                "collection": "carriers",
                "key": "du1398191883704",
                "ref": "311df3af3f37ac8c"
            }
        }
    ]
}

Drive results

{
    "handleCode": 0,
    "handleError": "",
    "data": [
        {
            "name": "Lufthansa Airlines",
            "link": "",
            "carrier": "LH"
        },
        {
            "name": "Luxair",
            "link": "",
            "carrier": "LG"
        },
        {
            "name": "Cayman Airways",
            "link": "",
            "carrier": "KX"
        }
    ],
    "handleVersion": "DataHandler-v0.5",
    "driverVersion": "DriverDrive-v0.1",
    "handleKeys": [
        "mn1398191914168",
        "es1398191914169",
        "pe1398191914168"
    ],
    "driverIds": [
        {
            "key": "mn1398191914168"
        },
        {
            "key": "es1398191914169"
        },
        {
            "key": "pe1398191914168"
        }
    ]
}

A note on Sheets

All the backends except sheets use a unique key either generated by the underlying API or by the driver, that will stick with the object for its lifetime in that database. However, the key for sheets is actually the row number which is transient and should be used with caution. I did not want to store additional key data in a sheet since it would distort its usability as a normal spreadsheet. Its probably better to do a remove() and save() operation with a Sheets backend rather than an update(). Also note that the row number is the data row number, and starts at 0. The first item of data would actually be on physical row 2 of the spreadsheet, but would be considered row 0 of data.
Here is the result from a sheets query, with keepIds set to true.

{
    "handleCode": 0,
    "handleError": "",
    "data": [
        {
            "carrier": "ZB",
            "name": "Monarch Airways",
            "link": ""
        },
        {
            "carrier": "YV",
            "name": "Mesa Airlines",
            "link": ""
        },
        {
            "carrier": "YR",
            "name": "Scenic Airlines Inc.",
            "link": ""
        }
    ],
    "handleVersion": "DataHandler-v0.5",
    "driverVersion": "DriverSheet-v0.4",
    "handleKeys": [
        142,
        223,
        139
    ],
    "driverIds": [
        {
            "_rowNumber": 142
        },
        {
            "_rowNumber": 223
        },
        {
            "_rowNumber": 139
        }
    ]
}

See Database abstraction with google apps script for more on this.

 

For help and information join the forum, follow the blog or follow me on Twitter.