BDL/JSON conversion basics

When the data structures and member names match, Genero BDL variables can be converted from/to JSON data with the util.JSON* utility classes.

Matching BDL and JSON data structures

In order to convert a BDL variable to/from a JSON string, the program RECORD or DYNAMIC ARRAY and the JSON data string must have the same structure.

JSON object elements and BDL RECORD member are associated by name, not by position. Elements in the JSON string and in the BDL variable can be at a different ordinal position.

JSON array elements and BDL DYNAMIC ARRAY elements are associated by position.

A JSON object can also be converted to a BDL DICTIONARY, when the JSON object is a list of named elements, using the same structure as the dictionary.

Example of BDL data structure:

DEFINE rec RECORD
             pkey INT,
             name VARCHAR(50),
             arr DYNAMIC ARRAY OF STRING,
             dic DICTIONARY OF DECIMAL
         END RECORD

LET rec.pkey = 999
LET rec.name = "Tim Birton"
LET rec.arr[1] = "item1"
LET rec.arr[2] = "item2"
LET rec.dic["abc"] = 14.45
LET rec.dic["def"] = 18.11
JSON equivalent:
{
    "pkey": 999,
    "name": "Tim Birton",
    "arr": ["item1","item2"
    ],
    "dic": {
        "def": 18.11,
        "abc": 14.45
    }
}

BDL to JSON conversion

BDL variables can be converted to JSON strings for example with the util.JSON.stringify() method.

The JSON elements get the same names of the record members, as defined in the program source. For more details about BDL to JSON names handling, see BDL names and JSON element names

Program array members in the record are converted to JSON arrays delimited by square brackets ([]).

Special consideration needs to be taken regarding empty dynamic arrays records where all elements are null. The Genero JSON API provides options to control the production of JSON elements for empty records and array. For more details, see NULLs and empty structures

For details about BDL to JSON data type conversion rules, see BDL to JSON type conversion rules

JSON to BDL conversion

When conversion from JSON to BDL, elements in the JSON string that do not match an Genero BDL record member are ignored; no error is thrown if there is no corresponding Genero BDL member.

Genero BDL record members that have no matching JSON element are initialized to NULL.

The JSON value must match the data format of the destination member. If the value does not correspond to the type (for example, if the JSON value is a character string while the target record member is defined with a numeric type), the target member will be set to NULL.

JSON arrays delimited by square brackets are used to fill a program array of the destination record. The destination array should be a dynamic array. If the array is defined as static, the additional elements of the source JSON array will be discarded, while missing elements will be initialized to NULL.

The JSON source string must follow the JSON format specification. It can contain multilevel structured data. If the source string is not well formatted, the runtime system will throw error -8109.

For details about JSON to BDL data type conversion rules, see JSON to BDL type conversion rules

JSON number limitations

The JSON specification defines numbers as a sequence of digits, with optional sign, dot, and exponent notation such as 874523 or -8.346E-5. There is theoretically no limitation regarding the precision and range for a number, in pure JSON grammar. However, the specification suggests that implementations use the IEEE 754-2008 binary64 (double precision) type to handle JSON numbers. See JSON specification for more details.

When parsing JSON numbers, or when writing JSON numbers with the util.JSONObject and util.JSONArray classes, the numbers must be in the precision and range that a binary64 can provide. For example, the integer 9007199254740997 can be stored in a BIGINT variable, but with JSONObject and JSONArray classes, this number will approximate to 9007199254740996 as a binary64. However, this binary64 limitation does not apply to the util.JSON class, which can handle any value of any BDL type, including BIGINT and DECIMAL(P,S).