Skip to main content

"getRecordsStartingAtKey"

Abstract

getRecordsStartingAtKey positions the current record in the index at the key that most closely matches the comparison criteria.

The "getRecordsStartingAtKey" action positions the current record in the index at the key that most closely matches the comparison criteria. It is the fastest way to walk records in index order starting at a specific key and is typically used to retrieve one or more records that match a key value. It can also be used to retrieve a span of records before and after a key value.

"getRecordsStartingAtKey" includes records by finding the first key that matches the supplied key and comparison operator.

Important

The index is required and is used to position a cursor to the first record that will be retrieved. Records are retrieved in index order.

Things to know

  • Results can be further filtered by a table filter expression, which filters records using any field in the table.

    Note

    A table filter is applied after a record is retrieved from the index. The index filter primarily controls which records are returned and the table filter subsequently filters the records.

  • Records are returned starting from the matching record position and optionally skipping forward or backward over records to move to a new position.

  • The number of records returned can be specified or unlimited.

  • This action can also return a cursor, which allows you to use the "getRecordsFromCursor" action to retrieve a large number of records efficiently.

  • Results are returned in ascending or descending index order and are formatted as JSON or an array of fields. You can specify which fields and JSON properties are included in the results.

  • The  "forceRecordCount" property is not available for this action because the action's purpose is to position the cursor at the first matching record. For the same reason, the "totalRecordCount" property in the response message is -1.

  • The "getRecordsStartingAtKey" action directly returns filtered records in index sorted order or returns a cursor that walks the filtered recordset.

  • It uses an index and an index filter to filter records quickly and efficiently.

  • The index filter uses one comparison operator to compare index field values to field values specified in the query.

  • It optionally uses a table filter to filter records using values that are not in the index.

  • It sets "errorCode" to 4046 if the database has no matching records to return.

  • An index key may contain multiple fields.

    • The index filter works by comparing each indexed field to a field value defined in the query.

    • The "indexFilter" property specifies the comparison value for each indexed field using the properties ("fieldName" and "value") and it defines the comparison operator using the "operator" property.

  • The "getRecordsStartingAtKey" action does not support the "!=" operator because that operator does not provide a starting point for getting records.

    • The "errorMessage" indicates that "getRecordsByCursor" cannot use a "!=" operator.

    • Instead, use a "tableFilter" with a "!=" comparison.

When returning records:
  • "getRecordsStartingAtKey" directly returns one or more filtered records in index-sorted order.

    It sets "errorCode" to 4046 if the database has no matching records to return.

  • A client uses this action to return records directly when it has a maximum number of records it wants to retrieve in one request.

  • The "getRecordsStartingAtKey" action returns a maximum number of records defined by the "maxRecords" property, after skipping the number of records defined by the "skipRecords" property.

  • The "getRecordsStartingAtKey" action supports pagination using "skipRecords" but this is inefficient and slower than returning and using a cursor.

  • When the "operator" is ">" , or ">=", "getRecordsStartingAtKey" finds and returns each record that has a key in the index that is greater than or greater than or equal to the key specified in "indexFilter".

    • If at least one matching record is returned, it sets "errorCode" to 0.

    • If no matching records are found, it sets "errorCode" to TBD and the "errorMessage" indicates that no more matching records exist.

  • When the "operator" is "<" , or "<=", "getRecordsStartingAtKey" finds and returns each record that has a key in the index that is less than or less than or equal to the key specified in "indexFilter".

    • If at least one matching record is returned, it sets "errorCode" to 0.

    • If no matching records are found, it sets "errorCode" to TBD and the "errorMessage" indicates that no more matching records exist.

  • When the "operator" is "=", "getRecordsStartingAtKey" finds and returns each record that has a key in the index that is equal to the key specified in "indexFilter".

    • A non-unique index may return more than one record.

    • A unique index will return zero or one record.

    • When one or more records are returned, it sets "errorCode" to 0.

    • If no matching records are found, it sets "errorCode" to TBD and the "errorMessage" indicates that no more matching records exist.

When returning a cursor
  • When returning a cursor, the "getRecordsStartingAtKey" action sets the starting position of the cursor and sets "errorCode" to an error if the key cannot find a match.

  • A client uses this action to return a cursor when it has a large number of records it wants to retrieve over multiple requests.

  • When the "operator" is ">" , or ">=", "getRecordsStartingAtKey" sets the starting position of the cursor to the closest matching record.

    • If at least one record exists after the key, it sets "errorCode" to 0. The matching record can be retrieved using "getRecordsByCursor" with "fetchRecords" set to 1.

    • If no records exists after the key, it sets "errorCode" to TBD. The "errorMessage" indicates that no records exists after the key and the cursor is set to the end of the record set.

  • When the "operator" is "<" , or "<=", "getRecordsStartingAtKey" sets the starting position of the cursor to the closest matching record.

    • If at least one record exists prior to the key, it sets "errorCode" to 0. The matching record can be retrieved using "getRecordsByCursor" with "fetchRecords" set to -1.

    • If no records exists before the key, it sets "errorCode" to TBD. The "errorMessage" indicates that no records exists before the key and the cursor is set to the beginning of the record set.

  • When the "operator" is "=", "getRecordsStartingAtKey" sets the cursor to the matching record.

    • f a match is found, it sets the cursor to the matching record and sets "errorCode" to 0. The record can be retrieved using "getRecordsByCursor" with "fetchRecords" set to 1.

    • If no matching record is found, it sets "errorCode" to TBD. The cursor is also set to the first record that has a key value greater than the requested key. The "errorMessage" indicates that no match was found and the cursor is set to the first record that has a key value greater than the requested key.

Performance considerations:
  • Results are returned quickly when retrieving fewer records.

  • Results return less quickly when:

    • The "skipRecords" property skips over many records.

    • The "tableFilter" property further filters the results.

To find the first match on a partial key:
  1. Set the "operator" property to ">=".

  2. Set the "value" property to a partial key value.

Request examples

Minimal request example

{
  "api": "db",
  "authToken": "replaceWithAuthtokenFromCreateSession",
  "action": "getRecordsStartingAtKey",
  "params": {
    "tableName": "athlete",
    "indexFilter": {
      "indexName": "admin_athlete_id_pk",
      "operator": "=",
      "indexFields": [
        {
          "fieldName": "id",
          "value": "2"
        }
      ]
    }
  }
}
{
  "api": "db",
  "requestId": "2",
  "authToken": "replaceWithAuthtokenFromCreateSession",
  "action": "getRecordsStartingAtKey",
  "params": {
    "tableName": "athlete",
    "indexFilter": {
      "indexName": "admin_athlete_id_pk",
      "operator": "=",
      "indexFields": [
        {
          "fieldName": "id",
          "value": "2"
        }
      ]
    },
    "returnCursor": true
  }
}
{
  "api": "db",
  "apiVersion": "1.0",
  "requestId": "3",
  "authToken": "replaceWithAuthtokenFromCreateSession",
  "action": "getRecordsStartingAtKey",
  "params": {
    "databaseName": "ctreeSQL",
    "ownerName": "admin",
    "tableName": "athlete",
    "tableFilter": "playerNumber >= 10",
    "indexFilter": {
      "indexName": "earnings",
      "operator": ">=",
      "indexFields": [
        {
          "fieldName": "earnings",
          "value": 2000000
        }
      ]
    },
    "returnCursor": false,
    "reverseOrder": false,
    "skipRecords": 0,
    "maxRecords": -1
  },
  "responseOptions": {
    "binaryFormat": "hex",
    "dataFormat": "objects",
    "numberFormat": "string",
    "includeFields": [],
    "excludeFields": [
      "ranking",
      "earnings",
      "playerNumber",
      "favoriteSaying",
      "livedPast2000"
    ]
  },
  "debug": "none"
}

Response examples

{
  "authToken": "authToken",
  "result": {
    "dataFormat": "objects",
    "binaryFormat": "hex",
    "fields": [
      {
        "name": "id",
        "type": "bigint",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": false,
        "primaryKey": 1,
        "autoValue": "incrementOnInsert"
      },
      {
        "name": "changeId",
        "type": "bigint",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "changeId"
      },
      {
        "name": "name",
        "type": "varchar",
        "length": 30,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "ranking",
        "type": "smallint",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": false,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "birthDate",
        "type": "date",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "playerNumber",
        "type": "number",
        "length": 32,
        "scale": 6,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "livedPast2000",
        "type": "bit",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "earnings",
        "type": "money",
        "length": 32,
        "scale": 4,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "favoriteSaying",
        "type": "varchar",
        "length": 500,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      }
    ],
    "data": [
      {
        "birthDate": "1895-02-06",
        "changeId": 1291366,
        "earnings": 800000,
        "favoriteSaying": "Every strike brings me closer to the next home run.",
        "id": 2,
        "livedPast2000": false,
        "name": "Babe Ruth",
        "playerNumber": 3,
        "ranking": 2
      },
      {
        "birthDate": "1942-01-17",
        "changeId": 1291366,
        "earnings": 60000000,
        "favoriteSaying": "Float like a butterfly, sting like a bee.",
        "id": 3,
        "livedPast2000": true,
        "name": "Muhammad Ali",
        "playerNumber": 1,
        "ranking": 3
      },
      {
        "birthDate": "1940-10-23",
        "changeId": 1291366,
        "earnings": 115000000,
        "favoriteSaying": "Everything is practice.",
        "id": 4,
        "livedPast2000": true,
        "name": "Pele",
        "playerNumber": 10,
        "ranking": 4
      },
      {
        "birthDate": "1961-01-26",
        "changeId": 1291366,
        "earnings": 1720000,
        "favoriteSaying": "You miss 100 percent of the shots you never take.",
        "id": 5,
        "livedPast2000": true,
        "name": "Wayne Gretzky",
        "playerNumber": 99,
        "ranking": 5
      },
      {
        "birthDate": "1969-01-03",
        "changeId": 1291366,
        "earnings": 990000000,
        "favoriteSaying": "Once something is a passion, the motivation is there.",
        "id": 6,
        "livedPast2000": true,
        "name": "Michael Schumacher",
        "playerNumber": 1,
        "ranking": 6
      }
    ],
    "primaryKeyFields": [
      "id"
    ],
    "changeIdField": "changeId",
    "moreRecords": false,
    "requestedRecordCount": 20,
    "returnedRecordCount": 5,
    "totalRecordCount": 5
  },
  "errorCode": 0,
  "errorMessage": ""
}
{
  "authToken": "authToken",
  "result": {
    "cursorId": "cursorId",
    "totalRecordCount": 6
  },
  "requestId": "2",
  "errorCode": 0,
  "errorMessage": ""
}
{
  "authToken": "authToken",
  "result": {
    "dataFormat": "objects",
    "binaryFormat": "hex",
    "fields": [
      {
        "name": "id",
        "type": "bigint",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": false,
        "primaryKey": 1,
        "autoValue": "incrementOnInsert"
      },
      {
        "name": "changeId",
        "type": "bigint",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "changeId"
      },
      {
        "name": "name",
        "type": "varchar",
        "length": 30,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "birthDate",
        "type": "date",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      }
    ],
    "data": [
      {
        "birthDate": "1940-10-23",
        "changeId": "1291366",
        "id": "4",
        "name": "Pele"
      },
      {
        "birthDate": "1963-02-17",
        "changeId": "1291366",
        "id": "1",
        "name": "Michael Jordan"
      }
    ],
    "primaryKeyFields": [
      "id"
    ],
    "changeIdField": "changeId",
    "moreRecords": false,
    "requestedRecordCount": 2,
    "returnedRecordCount": 2,
    "totalRecordCount": 2
  },
  "requestId": "3",
  "errorCode": 0,
  "errorMessage": ""
}

"params"

The "params" property is an object that contains an action's parameters. Each action defines its own required and optional properties.

Property summary

Table 1. "params" property summaries

Property

Description

Default

Type

Limits (inclusive)

"databaseName"

contains the name of a database

Defaults to the "defaultDatabaseName" value that is set during "createSession"

string

Minimum length: 1
Maximum length: 64

"indexFilter"

selects an index and defines the lower and upper bounds of records to be returned from the index

Required - No default value

object

"ownerName"

contains the unique name of a schema in a database

""

string

Minimum length: 1
Maximum length: 64

"tableFilter"

filters the records in a table

""

string

Minimum length: 0
Maximum length: no practical limit

"tableName"

contains the name of a table

Required - No default value

string

Minimum length: 1
Maximum length: 64


The "databaseName" property is an optional string that specifies the database that contains the tables. It defaults to the database name supplied at login.

Note

In the API Explorer, "defaultDatabaseName" is set to "ctreeSQL" in the "createSession" action that happens at login.

Things to know:
  • A zero-length "databaseName" is invalid.

  • Its limits are from 0 to 64 bytes.

  • If the "databaseName" property is omitted or set to null, the server will use the default database name specified at login.

  • If no default database is specified during "createSession", "defaultDatabaseName" will be set to the "defaultDatabaseName" value that is specified in the services.json file.

The "indexFilter" property selects an index and defines the lower and upper bounds of records to be returned from the index. The "indexFieldFilters" is a required array containing at least one object. Each object is a field comparison operation. A comparison operation compares its value to the index key of a record. A record is included in the results when all the field comparison operations return true.

Example

"indexFilter":
    {
      "indexName": "name_livedpast2000",
      "operator": "=",
      "indexFields":
      [
        {
          "fieldName": "name",
          "value": "Pele"
        }
      ]
    }

Property Summary

Table 2. "indexFilter" property summaries

Property

Description

Default

Type

Limits (inclusive)

"indexFields"

used by an index to find a record

Required - No default value

array of objects

"indexName"

contains the name of an index

Required - No default value

string

Minimum length: 1
Maximum length: 64

"operator"

used by the server to filter records in a query to compare a field value to a constant value or expression so that when evaluated as true the record is included in the result

Required - No default value

string

"="
">"
">="
"<"
"<="


The "ownerName" property is an optional string from 1 to 64 bytes that specifies the account that owns an object.

Things to know:
  • The "ownerName" property is optional and has a dynamic default value.

  • If the "ownerName" property is omitted or set to null, the server uses the value of the "defaultOwnerName" property supplied during the "createSession" action.

  • If the "defaultOwnerName" property is not defined, the server uses the "admin" as the owner name.

  • The owner of an object has administrative rights over that object.

  • The "ownerName" property is a namespace for an object. You can think of it as a container of objects.

    The "ownerName" allows users to use any name for the objects they create — for example, a QA engineer may copy tables into their owner space to run a set of tests.

    It is common for a user to create their own copies of objects from other accounts for testing, troubleshooting, and fixing data. The copied objects can retain the same name because the "ownerName" distinguishes between them.

  • The fully qualified name of an object is the "databaseName", "ownerName", and the object's name, such as "tableName" meaning a FairCom server may contain many tables with the name "mytable" as long as each one is in a different database or in a different owner space.

    For example, an organization often creates different databases for different phases of the development lifecycle, such as dev, test, stage, ua, and prod. Each of these databases contains the same set of objects with the same names. Applications leave the "databaseName" out of their JSON actions and use the "defaultDatabaseName" property to specify the target database.

  • Queries and scripts are often written without specifying "databaseName" and/or "ownerName", allowing queries and scripts to work properly when run in different databases or in different schemas.

The "tableFilter" property is an optional string with no practical size limit. No table filter is applied when it is an empty string, a null value, or is omitted. It is a server-side filter of the records in a table. It includes records in the result only when they match the filter requirements. It works like a SQL WHERE clause except for using C syntax and C functions.

Things to know:
  • See Use Table Filters for more information and examples.

  • It uses FairCom's expression language, which is based on C syntax and supports arbitrarily nested expressions, operators, and functions, such as

    "tableFilter": "((name IS NOT NULL &amp;&amp; name != \"Michael Jordan\" &amp;&amp; strnicmp( name, \"m\", 1 ) == 0 &amp;&amp; (ranking - 5) * 2 &lt;= 6 &amp;&amp; livedPast2000 ) || ( earnings &lt; 1000000 &amp;&amp; ! livedPast2000 )) &amp;&amp; (ranking % 2 == 1)"

  • A zero-length table filter, such as "tableFilter": "" does not filter any records.

  • A "tableFilter" can be combined with other query techniques. For example, the "getRecordsInKeyRange" action can be used to retrieve a limited range of records that are further filtered by a "tableFilter".

  • To include a double quote character in a "tableFilter" expression, precede it with the backslash (escape) character, \".

The "tableName" property is an optional string that contains the name of an integration table or MQTT topic that holds the topic's messages. It defaults to an empty string.

Things to know:
  • You can use a topic name for an MQTT table because FairCom automatically generates a table name for each topic.

  • A "tableName" cannot begin with a number.

  • It refers to the name of the integration table that stores a topic’s messages and is used to rename that table or assign a new topic to an existing integration table.

  • MQTT automatically creates an integration table for each new topic it receives. Thus, when a message is sent to a topic, FairCom Edge automatically creates a table to hold it.

  • As you refine your integration processes, you may want to rename an integration table to better label the data it holds. You can use the "tableName" property of the "configureTopic" action to rename an integration table.

  • The "alterIntegrationTable" action can also be used to rename an integration table, but it is less convenient because you must know the original name of the integration table.

"result"

Property summary

Table 4. "result" property summaries

Property

Description

Type

Limits (inclusive)

"binaryFormat"

designates how binary values are returned

string enum

"base64"
"hex"

"cursorId"

contains a unique identifier returned by the server

string

Minimum length: 0
Maximum length: 255

"data"

contains an array or object that the server returns, such as records returned by a query

Note

It is an empty array when there are no results available.

array

Its contents are determined by the action

"dataFormat"

defines the format of the data in the "data" property

string

"autoDetect"
"arrays"
"objects"

"fields"

shows an array of objects set by the server where each object is the definition of a field in a table defining the details of each field returned by a query

array

"primaryKey"

represents the order of the primary keys in the index

Note

When "primaryKey" is 0 it means a field is not part of a primary key.

integer

0 - 255

"requestedRecordCount"

shows how many records were requested in the "getRecordsFromCursor" action to determine if fewer records were returned than were requested

integer

0 - 2147483647

"returnedRecordCount"

shows how many records were returned from the "getRecordsFromCursor" action to determine if fewer records were returned than were requested

integer

0 - 2147483647

"totalRecordCount"

contains an integer, the server sets its value to the number of records returned by a query

integer

-1 - 99,999,999,999,999,999,999,999,999,999,999



The "binaryFormat" property designates how binary values are formatted in the JSON request and JSON response message. The default value is "base64".

Note

Typically, response options apply only to the server’s response, but the "binaryFormat" property applies to both the request and the response.

Things to know:
  • The "binaryFormat" property may occur inside "params""responseOptions", "defaultResponseOptions" , and "result".

  • When "binaryFormat" occurs in "params" it specifies how the sender represents binary values.

    For example, when  "binaryFormat" is set to "hex", the FairCom server expects the binary values of fields and keys to be represented in strings with hexadecimal format.

  • When "binaryFormat" occurs in "responseOptions" or "defaultResponseOptions" it specifies how the FairCom server should represent binary values in responses.

    For example, when "binaryFormat" is set to "hex", the FairCom server represents binary values in strings with hexadecimal format.

  • When "binaryFormat" occurs in "result" it signifies how binary values are represented.

    For example, when "binaryFormat" is set to "base64", the FairCom server represents binary values in the response in base64 format.

  • The following are the possible values for each format.

    • "base64"

      When the server reads and writes from a binary field, it represents the binary value as a base64 string.

      • This is the default

      • "base64" strings contain the following characters:

        • 0-9

        • A-Z

        • a-z

        • +

        • /

        • =

    • "hex"

      When the server reads and writes from a binary field, it represents the binary value as a hexadecimal string.

      • Hexadecimal is easier for people to read and convert to binary.

      • Hexadecimal creates a larger payload than "base64", which makes it less efficient for data transmission.

      • Hexadecimal strings contain the following characters:

        • 0-9

        • A-F

    • "byteArray"

      When the server reads and writes from a binary field, it represents the binary value as an array of bytes.

      • An array of bytes is easiest for a program to manipulate.

      • An array of bytes creates a larger payload than "base64" and "hex", which makes it less efficient for data transmission.

      • An array of bytes returns a JSON array containing one integer number between 0 and 255 for each byte in the binary value:

        • "aBinaryField": [ 255, 0, 255 ]

Examples

Create a "binary_test" table

This example creates a table containing one binary field named "bin" with a fixed length of 5 bytes.

{
  "api": "db",
  "action": "createTable",
  "params": {
    "tableName": "binary_test",
    "fields": [
      {
        "name": "bin",
        "type": "binary",
        "length": 5
      }
    ]
  },
  "authToken": "replaceWithValidAuthtoken"
}
Insert a record into the "binary_test" table using an array of bytes format

This example inserts a record with the ASCII characters "123" in the "bin" field. The value of "bin" is represented as an array of bytes.

{
  "api": "db",
  "action": "insertRecords",
  "params": {
    "tableName": "binary_test",
    "dataFormat": "objects",
    "binaryFormat": "byteArray",
    "sourceData": [
      {
        "bin": [49,50,51]
      }
    ]
  },
  "authToken": "replaceWithValidAuthtoken"
}
Insert a record into the "binary_test" table using hexadecimal format

This example inserts a record with the ASCII characters "123" in the "bin" field. The value of "bin" is represented as a string in hexadecimal format.

{
  "api": "db",
  "action": "insertRecords",
  "params": {
    "tableName": "binary_test",
    "dataFormat": "objects",
    "binaryFormat": "hex",
    "sourceData": [
      {
        "bin": "313233"
      }
    ]
  },
  "authToken": "replaceWithValidAuthtoken"
}
Insert a record into the "binary_test" table using base64 format

This example inserts a record with the ASCII characters "123" in the "bin" field. The value of "bin" is represented as a string in base64 format.

{
  "api": "db",
  "action": "insertRecords",
  "params": {
    "tableName": "binary_test",
    "dataFormat": "objects",
    "binaryFormat": "base64",
    "sourceData": [
      {
        "bin": "MTIz"
      }
    ]
  },
  "authToken": "replaceWithValidAuthtoken"
}
Retrieve a record with "binaryFormat" as an array of bytes

This example requests the first record in the "binary_test" table with the value of "bin" represented as an array of bytes.

{
  "api": "db",
  "action": "getRecordsByTable",
  "params": {
    "tableName": "binary_test",
    "maxRecords": 1
  },
  "responseOptions": {
    "binaryFormat": "byteArray",
    "dataFormat": "objects",
    "numberFormat": "number"
  },
  "authToken": "replaceWithValidAuthtoken"
}
Response

Note

Our examples insert only 3 bytes into "bin" . Because the "bin" field has a fixed-length if 5 bytes, the server pads unused bytes with 0x00 and stores the result. When a record is retrieved, the server returns all 5 bytes.

{
  "authToken": "authtokenFromServer",
  "result": {
    "dataFormat": "objects",
    "binaryFormat": "byteArray",
    "fields": [
      { "name": "id",       "type": "bigint", "length": null, "scale": null, "autoTimestamp": "none", "defaultValue": null, "nullable": false, "primaryKey": 1 },
      { "name": "changeId", "type": "bigint", "length": null, "scale": null, "autoTimestamp": "none", "defaultValue": null, "nullable": true,  "primaryKey": 0 },
      { "name": "bin",      "type": "binary", "length": 5,    "scale": null, "autoTimestamp": "none", "defaultValue": null, "nullable": true,  "primaryKey": 0 }
    ],
    "data": [
      {
        "bin": [49,50,51,0,0],
        "changeId": 50217,
        "id": 1
      }
    ],
    "moreRecords": true,
    "requestedRecordCount": 1,
    "returnedRecordCount": 1,
    "totalRecordCount": 3
  },
  "errorCode": 0,
  "errorMessage": ""
}

Retrieve a record with "binaryFormat" as hexadecimal

This example requests the first record in the "binary_test" table with the value of "bin" represented as a hexadecimal string.

{
  "api": "db",
  "action": "getRecordsByTable",
  "params": {
    "tableName": "binary_test",
    "maxRecords": 1
  },
  "responseOptions": {
    "binaryFormat": "hex",
    "dataFormat": "objects",
    "numberFormat": "number"
  },
  "authToken": "replaceWithValidAuthtoken"
}
Response
{
  "authToken": "authtokenFromServer",
  "result": {
    "dataFormat": "objects",
    "binaryFormat": "byteArray",
    "fields": [
      { "name": "id",       "type": "bigint", "length": null, "scale": null, "autoTimestamp": "none", "defaultValue": null, "nullable": false, "primaryKey": 1 },
      { "name": "changeId", "type": "bigint", "length": null, "scale": null, "autoTimestamp": "none", "defaultValue": null, "nullable": true,  "primaryKey": 0 },
      { "name": "bin",      "type": "binary", "length": 5,    "scale": null, "autoTimestamp": "none", "defaultValue": null, "nullable": true,  "primaryKey": 0 }
    ],
    "data": [
      {
        "bin": "3132330000",
        "changeId": 50217,
        "id": 1
      }
    ],
    "moreRecords": true,
    "requestedRecordCount": 1,
    "returnedRecordCount": 1,
    "totalRecordCount": 3
  },
  "errorCode": 0,
  "errorMessage": ""
}


Retrieve a record with "binaryFormat" as base64

This example requests the first record in the "binary_test" table with the value of "bin" represented as a base64 string.

{
  "api": "db",
  "action": "getRecordsByTable",
  "params": {
    "tableName": "binary_test",
    "maxRecords": 1
  },
  "responseOptions": {
    "binaryFormat": "base64",
    "dataFormat": "objects",
    "numberFormat": "number"
  },
  "authToken": "replaceWithValidAuthtoken"
}
Response
{
  "authToken": "authtokenFromServer",
  "result": {
    "dataFormat": "objects",
    "binaryFormat": "byteArray",
    "fields": [
      { "name": "id",       "type": "bigint", "length": null, "scale": null, "autoTimestamp": "none", "defaultValue": null, "nullable": false, "primaryKey": 1 },
      { "name": "changeId", "type": "bigint", "length": null, "scale": null, "autoTimestamp": "none", "defaultValue": null, "nullable": true,  "primaryKey": 0 },
      { "name": "bin",      "type": "binary", "length": 5,    "scale": null, "autoTimestamp": "none", "defaultValue": null, "nullable": true,  "primaryKey": 0 }
    ],
    "data": [
      {
        "bin": "MTIzAAA=",
        "changeId": 50217,
        "id": 1
      }
    ],
    "moreRecords": true,
    "requestedRecordCount": 1,
    "returnedRecordCount": 1,
    "totalRecordCount": 3
  },
  "errorCode": 0,
  "errorMessage": ""
}


The "cursorId" property is a required string from 0 to 255 bytes. It is a unique identifier returned by the server.

Things to know:
  • The "getRecordsFromCursor" action uses it to quickly and efficiently retrieve paginated records.

  • Setting a zero-length "cursorId" in the request is invalid.

  • It is not returned when "returnCursor" is false.

Important

Do not assume the "cursorId" is a number embedded in a string.

The "dataFormat" property is an optional, case-insensitive string enum that defines the format of the response in the "data" property. The default format is an array of arrays. The alternative is an array of objects. The default for "dataFormat" can be changed during a "createSession" action by assigning a different value to the "dataFormat" property in "defaultResponseOptions".

There are three different (but similar) versions of the "dataFormat" property:

Two of those versions occur in a request and another occurs in a response. They all indicate how data is formatted.

  • "dataFormat" in the request inside "responseOptions" determines how the "data" property in the response is formatted.

    Possible values include:

    • "arrays"

      This is the default and causes the server to return results as an array of arrays, which is the most efficient.

    • "objects"

      This returns results as an array of objects. This is less efficient but is simpler to generate, read, and troubleshoot.

  • "dataFormat" in the request in the "params" object notifies the server how the "sourceData" property is formatted in the request. This version is rarely used because of the default "autoDetect" behavior.

    Possible values include:

    • "arrays"

      This causes the server to return results as an array of arrays, which is the most efficient.

    • "objects"

      This returns results as an array of objects. This is less efficient but is simpler to generate, read, and troubleshoot.

    • "autoDetect"

      This is the default and causes the server to automatically detect the format of the data in the "sourceData" property.

  • "dataFormat" in the response shows the client how the server formatted the "data" property.

    Possible values include:

    • "arrays"

      This is the default and causes the server to return results as an array of arrays, which is the most efficient.

    • "objects"

      This returns results as an array of objects. This is less efficient but is simpler to generate, read, and troubleshoot.

The "fields" property is a required array of field-type objects. There is one object for each top-level field in the array. Each object identifies the actual data type of the field as stored in the database.

A field-type object is used when creating a table. It contains one object for each field definition returned in the data.

Full request example

"fields": 
[
    {
      "name": "name",
      "type": "varchar",
      "length": 50,
      "scale": null,
      "defaultValue": null,
      "nullable": false,
      "primaryKey":1
   }
]

Full response example

"fields":
[
  {
      "name": "id",
      "type": "bigint",
      "length": null,
      "scale": null,
      "autoValue": "none",
      "defaultValue": null,
      "nullable": false,
      "primaryKey": 1
  }
]

Property summary

Table 5. "fields" property summaries

Property

Description

Default

Type

Limits (inclusive)

"autoValue"

controls when and how the server automatically sets the field value

""

string

"none"
"incrementOnInsert"
"timestampOnInsert"
"timestampOnUpdate"
"timestampOnUpdateAndInsert"
"changeid"

"defaultValue"

specifies the default value of a field

string

Minimum length: 0
Maximum length: 65500

"length"

defines the length of a field's value in a record

integer

1 - 65500

"name"

defines a new name of the field

string

Minimum length: 0
Maximum length: 64

"nullable"

allows a field to contain a NULL value when true

Boolean

true
false

"primaryKey"

adds a field to the specified ordinal position of the table's primary key when > 0

integer

0 - 32

"scale"

defines the number of places to the right of the decimal point

integer

0 - 32

"type"

defines the type of field

string

"bit"
"tinyint"
"smallint"
"integer"
"bigint"
"real"
"double"
"number"
"money"
"date"
"time"
"timestamp"
"char"
"varchar"
"lvarchar"
"binary"
"varbinary"
"lvarbinary"
"json"


This property controls when and how the server automatically sets the field value.

Specify only one of these values per field.

  • "none" indicates the server does not automatically set the field's value.

  • "incrementOnInsert" indicates the server automatically increments a field’s value each time the server inserts a new record. It applies to fields that are of the type of decimal or one of the integer types, such as "bigint". Only one field per table can have this attribute. The server returns an error when assigning this attribute to multiple fields. The JSON DB API automatically creates the "id" field as an "incrementOnInsert" field. If you apply this attribute to another field, it becomes the only automatically incremented field in the table. If you want that field to be the primary key, assign  "primaryKey": 1 to it.

  • "timestampOnInsert" indicates the server automatically sets a field’s value to the current date and time of an insert. It applies only to fields with a type of "timestamp".

  • "timestampOnUpdate" indicates the server automatically sets a field’s value to the current date and time of an update. It applies only to timestamp fields.

  • "timestampOnUpdateAndInsert" indicates the server automatically sets a field’s value to the current date and time of an insert and an update. It applies only to fields with a type of "timestamp".

  • "changeId" indicates the server uses the field for optimistic locking. The server automatically sets the field's value to the internal transaction number used during the last update of the record. This value changes each time the server updates the record. A table may only have one change tracking field. The field type must be "bigint".

    The JSON DB API automatically creates a "changeid" field with change-tracking functionality.

    Change tracking is optional in the CTDB and ISAM APIs. The application must create a 64-bit integer field and assign change-tracking functionality to it.

The "requestedRecordCount" property is a signed, 32-bit integer set by the server in response to the "getRecordsFromCursor" method.

Things to know:
  • It makes it easy to know how many records were requested in the last call to "getRecordsFromCursor".

  • An application can use "requestedRecordCount" in conjunction with "returnedRecordCount" to determine if fewer records were returned than requested, which occurs when the cursor reaches the end of the recordset.

The "returnedRecordCount" is a 32-bit integer set by the server in response to the "getRecordsFromCursor" method.

Things to know:
  • It makes it easy to know how many records were returned from the last call to "getRecordsFromCursor".

  • An application can use "returnedRecordCount" in conjunction with "requestedRecordCount" to determine if fewer records were returned than requested, which occurs when the cursor reaches the end of the recordset.

The "totalRecordCount" property contains the total available number of records that can be returned from a query.

Things to know:
  • The "totalRecordCount" is set to -1, when the server does not know the total record count.

  • A very fast way to get the total number of records in a table is to call the "getRecordsByTable" method without applying a "tableFilter". This immediately returns the count without reading and counting records.

  • For most methods, the server does not calculate "totalRecordCount" because calculating it requires walking all records in the query, which may take a significant amount of time.

  • When the result is returned as a cursor, "totalRecordCount" is the total number of records that the cursor can traverse.

    Note

    This does not apply to cursor responses.

  • When the result returns records directly, "totalRecordCount" is the total number of records that can be retrieved – not necessarily the number of records returned.