Variant type
The variant field type is flexible and strongly typed
A variant field is flexible because it can store any type of value. It is strongly typed because it stores the type and value of the data it contains. Each record containing a variant field may store a different type of value. For example, one record might store a JSON document, another record might store a GIF image, and another might store a raw binary value.
A variant field supports the following types: "null", "json", "binary", "string", "number", and "boolean". FairCom plans to add more types, and you will be able to create your own data types.
FairCom also provides a variant object, which is a JSON representation of a variant. This object extends JSON to include strongly typed values, enabling the embedding of binary data within JSON along with its specified data type and encoding. FairCom servers support variant objects, and applications can easily be programmed to convert between variant objects and native binary values.
The following table describes the variant types built into FairCom servers.
Variant Object | Variant Object | Internal Variant ID Number | FairCom Constant Name in C and C++ | Description | |||
|---|---|---|---|---|---|---|---|
Not applicable | 0 |
| Zero represents an invalid type. | ||||
|
| Not applicable | Not applicable | A variant field can have a If a variant field is nullable and its value is If the variant field is not nullable, assigning a The JSON DB API generally returns a JSON null for a null field value. However, if the | |||
|
|
|
| A binary variant is a variable-length binary value up to 2 GB in length. The server stores bytes in the exact order as received and does not validate the value. The JSON DB API always returns a binary variant using the format defined by the | |||
|
|
|
| A string variant is a variable-length, UTF-8 string up to 2 GB in length. The server validates the value as a UTF-8 string. The JSON DB API always returns a string variant as a JSON string, which requires specific characters to be escaped according to JSON rules. For example, you must escape | |||
|
|
| TBD | A number variant contains any number of digits to the left and right of the decimal point. The sign and decimal point are optional. The server validates a numeric variant as a JSON number and stores it as UTF-8 characters. The JSON DB API returns the value based on the value of the | |||
|
|
| A Boolean variant is always encoded as a JSON true or false. The JSON DB API always returns the value as | ||||
|
|
|
| A JSON value may be an object, array, string, number, The JSON DB API always returns the value as JSON. |
A variant object is a JSON object that describes all aspects of the data stored in a variant field, including its value, its type, and how the value is encoded. It is a standard way of representing any type of data. It is built into all FairCom products. People can easily read it, and computer languages can use it to transmit strongly typed binary data between applications.
In FairCom APIs, you can use the variant object to insert or update data in a variant field. The APIs detect the presence of a variant object when a JSON object contains the "schema" property set to "jsonaction.org/schemas/variantObject". The following variant object represents a GIF image. It stores the image in the "value" property as a string containing Base64 encoded characters.
{
"schema": "jsonaction.org/schemas/variantObject",
"value": "R0lGODlhAQABAIAAAAAAAP///yH5BAUAAAEALAAAAAABAAEAAAICRAEAOw==",
"valueEncoding": ["base64"],
"type": "binary",
}
When a client sends a variant object to the server, the server converts the value in the "value" property to the type specified in the "type" property and stores the converted value.
When a client receives a variant object from the server, the "type" property identifies the underlying type of the variant.
If the value is encoded in an unexpected form, the optional "valueEncoding" property identifies the value's encoding.
Property | Description | Default | Type | Limits (inclusive) | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
contains the value of the variant field | Required - No default value | JSON value | ||||||||
(optional) specifies how the |
| array |
| |||||||
specifies the data type of the | Required - No default value | enum |
|
The "type" property is a required property that contains the data type of the value. See Variant Types.
The "value" property is a required property that contains the value to be stored in the variant field. It is always a JSON value, which may be a JSON string, number, boolean, object, or array.
The example below shows a JSON string containing a number being stored in the variant as a big integer.
{
"schema": "jsonaction.org/schemas/variantObject",
"value": "1234567890123456789",
"type": "number"
}The optional "valueEncoding" property specifies how the "value" property is encoded.
The "valueEncoding" property specifies how the sender encodes the "value" property so the receiver can decode it.
In the following example, the "valueEncoding" property is an empty array because there are no additional decoding steps beyond converting from the JSON number type specified in the "value" property to the big integer number specified in the "type" property. Using an empty array is the same as setting "valueEncoding" to null or omitting it.
{
"schema": "jsonaction.org/schemas/variantObject",
"value": 123,
"valueEncoding": [],
"type": "number"
}In the following example, the "valueEncoding" property is "number" because the "value" property is a JSON string containing an embedded number. The receiver of the variant object must decode the JSON string into the big integer number specified in the "type" property.
{
"schema": "jsonaction.org/schemas/variantObject",
"value": "123",
"valueEncoding": ["number"],
"type": "number"
}JSON Action APIs
FairCom's JSON action APIs read and write to variant fields. By default, they read and write JSON values to variant fields. They also support using variant objects when you want to read and write binary values to variant fields.
The "variantFormat" property specifies how values in variant fields are formatted. It defaults to "json", which assigns and returns JSON values to and from variant fields.
The "binaryFormat" property specifies how binary values in variant fields are encoded. It defaults to "hex", which embeds a hexadecimal encoding of the binary value in a JSON string.
CTDB and ISAM
CTDB and ISAM APIs read and write to a variant field using a C structure representing the variant object, including its length, value, type, and storage encoding.
SQL
SQL reads and writes to a variant field using its binary value. In the future, you can set and return its value using the Variant Object.
The following sections contain examples of variant objects. They show you how to use a variant object to represent all major data types.
When the variant object's "type" property is "json", you can assign any JSON value directly to the "value" property. The server stores the value as JSON inside the variant field. You do not need to specify the "valueEncoding" property for the server to interpret the value properly.
JSON string in a Variant Object
{
"schema": "jsonaction.org/schemas/variantObject",
"value": "my string",
"type": "json"
}
JSON number in a Variant Object
{
"schema": "jsonaction.org/schemas/variantObject",
"value": -123.456,
"type": "json"
}
JSON boolean in a Variant Object
{
"schema": "jsonaction.org/schemas/variantObject",
"value": false,
"type": "json"
}
JSON null in a Variant Object
{
"schema": "jsonaction.org/schemas/variantObject",
"value": null,
"type": "json"
}
JSON object in a Variant Object
{
"schema": "jsonaction.org/schemas/variantObject",
"value": { "myKey": "myValue"},
"type": "json"
}
JSON array in a Variant Object
{
"schema": "jsonaction.org/schemas/variantObject",
"value": [1, "2", 3.0],
"type": "json"
}
When you want to store a binary value in a variant field, set the "type" property to "binary", set the "valueEncoding" property to "base64", "hex", or "byteArray", and set the "value" property to a binary value embedded in a string or array.
Binary data embedded in a string in hexadecimal format
{
"schema": "jsonaction.org/schemas/variantObject",
"value": "00FF1E58",
"valueEncoding": ["hex"],
"type": "binary"
}
Binary data embedded in a string in Base64 format
{
"schema": "jsonaction.org/schemas/variantObject",
"value": "AP8eWA==",
"valueEncoding": ["base64"],
"type": "binary"
}
Binary data as an array of bytes
{
"schema": "jsonaction.org/schemas/variantObject",
"value": [0, 255, 30, 88],
"valueEncoding": ["byteArray"],
"type": "binary"
}
When you want to store a number in a variant field, set the "type" property to "number", omit the "valueEncoding" property, and set the "value" property to a JSON number or string containing a number.
Example of a numeric Variant object
{
"schema": "jsonaction.org/schemas/variantObject",
"value": -123.456,
"type": "number"
}
Embedding a number in a string
When the "type" property is "number", you can embed a number in a string, and the FairCom server will properly convert and store it in a variant field as a number.
It is common to store numbers in a string because JSON numbers are decimal numbers with no limits on the number of digits to the left and right of the decimal point. JSON parsers and many programming languages cannot handle numbers with more than 15 digits of precision. For example, most languages and JSON parsers convert JSON numbers into IEEE floating point numbers, which are lossy numbers. They may change a number's value when converting between JSON's base ten value and the IEEE number's binary value. They will change a number's value when it has more than 15 digits of precision.
To prevent such problems, you must embed a number inside a JSON string. To do this in a Variant Object, set the "type" property to "number", omit the "valueEncoding" property, and set the "value" property to a string containing a number.
Example of a numeric Variant object in a string
{
"schema": "jsonaction.org/schemas/variantObject",
"value": "-123.456",
"type": "number"
}
To store a string in a Variant Object, set the "type" property to "string" and assign a string to the "value" property. Omit the "valueEncoding" property.
Example of a Variant Object representing a number embedded in a string
{
"schema": "jsonaction.org/schemas/variantObject",
"value": "my string",
"type": "string"
}
To store a Boolean value in a Variant Object, set the "type" property to "boolean" and assign true or false to the "value" property. Omit the "valueEncoding" property.
Example of a Variant Object representing a number embedded in a string
{
"schema": "jsonaction.org/schemas/variantObject",
"value": true,
"type": "boolean"
}
To store a null value in a variant object, set the "value" property to null. Set the "type" property to "null" or "json".
Note
In the JSON DB, SQL, CTDB, and ISAM APIs, you can set the value of a variant field directly to
null. These APIs also return thenullvalue when the variant isnull.In the JSON DB API, you can optionally set the
"variantFormat"property to"variantObject". This causes anullvalue to return the variant object shown in the example below. You can also set a variant field tonullusing the same variant object.If the variant field is not nullable, assigning a
nullvalue to the variant field returns an error.
Null Variant Object
{
"schema": "jsonaction.org/schemas/variantObject",
"value": null
"type": "null"
}
The following Variant Object also represents a null value. There is no functional difference between these examples because a null value in JSON is simply a null value.
{
"schema": "jsonaction.org/schemas/variantObject",
"value": null
"type": "json"
}