Types
Primitives
In order to support JSL as a rigorous modeling formalism, the primitive data types in the model must be specified.
JSL allows the following “base types” for primitive specification:
-
boolean
-
binary
-
string
-
numeric
-
date
-
time
-
timestamp
The above base types cannot be used directly in domain models. However, you must define the primitive types used in your domain model.
To define a new domain model primitive, use the type
keyword.
Syntax:
type <basetype> <name> [ (<parameter name> = <parameter value>], ...) ] ;
where the <basetype> is one of the base types defined above, the <name> is the name of the domain model primitive, and there can be an additional list of parameters for each base type. The optional comma-separated parameter list consists of name-value pairs, using =
between name and value.
Parameters are constraints that restrict the use of the newly created primitive data type.
Example:
type boolean Boolean;
type numeric Integer(precision = 9, scale = 0);
type string String(min-size = 0, max-size = 128);
The Base types section provide examples of each base type and its possible constraints and operations.
Instead of defining the most common primitives in each project, there is a built-in judo::types model that you can import into models. It defines the following primitives:
You can use these primitives a follows:
|
Enumeration
An enumeration is a primitive data type whose values are called enumeration members. Enumeration members are listed as a pair of a text (the literal) and an integer (the ordinal). An enumeration member is represented with the qualified name of enumeration tagged with literal, for example Titles#MR
or example::Color#RED
.
The literals of the enumeration members within an enumeration must be unique in case-insensitive manner. Enumeration literals are usually uppercase to improve readability.
The ordinal parts of the enumeration members within an enumeration must be unique. Enumeration members can be ordered by their ordinal.
An enumeration must have at least one enumeration member.
Ordinals are for run-time database storage, and to help model restructuring and data migration. When storing an enumeration value, only the ordinal is stored in the database. This storage mechanism allows the literal values to be changed without data migration and language-independent sorting of database records. |
To define an enumeration, use the enum
keyword.
Syntax:
enum <name> { [<literal> = <ordinal> ;] ... }
where the <name> is the name of the enumeration, and the enumeration members are defined between {
and }
. Enumeration members are defined as a list of <literal> and <ordinal> pairs using =
between them.
Example:
enum OrderStatus {
OPEN = 1;
PAID = 2;
DELIVERED = 3;
}
entity Order {
field OrderStatus status;
}
In the example above, the Order entity has a status field that shows its current state.
The supported operators of enumeration are the following:
Operator | Result | Meaning | Example |
---|---|---|---|
|
Boolean |
Comparison. Enumeration members of two different enumerations are not comparable. |
|
Supported functions are listed in chapter Enumeration functions.
Base types
String
String represents a text. String literals are delimited by double quotes. For example "apple"
.
Escape sequences allow for the representation of some nongraphic characters as well as the double quote, and backslash characters in string literals.
Escape sequences are the followings:
Escape sequence | Character |
---|---|
\t |
Horizontal tab |
\n |
Linefeed |
\f |
Form feed |
\r |
Carriage return |
\" |
Double quote |
\\ |
Backslash |
In accordance with the above, multi-line string literals are allowed, inside the string literals "\n" escape sequence can be used for line breaks. The new line character is not allowed in string literals.
In some situations, it may be inconvenient that escape sequences are interpreted differently than the rest of the string literals. To overcome these situations, use raw string literals with the "r" character before the opening double quote. For example, the string literal r"apple\nbanana"
is a single line string. A typical use of raw strings is to specify regular expressions.
To define string primitive, use the type
keyword with string
.
Syntax:
type string <name> (min-size = <min>, max-size = <max>[, regex = <regular expression>]) ;
where the <name> is the name of the domain model string, and the mandatory <min> and <max> specify the minimum and the maximum size of the text that can be stored. <max> must be a value from 1 through 4000 and <min> must be a value from 0 through <max>.
The optional <regular expression> is a sequence of characters that specifies a pattern, that is for validation. The following tables summarize the regular expression constructs.
Characters | Matches |
---|---|
|
The character x |
|
The character with hexadecimal value 0xhhhh |
|
The tab character |
|
The newline character |
|
The form-feed character |
|
The carriage-return character |
|
The backslash character |
Character classes | Matches |
---|---|
|
a, b, or c |
|
Any character except a, b, or c |
|
a through z |
|
Any character except a through z |
|
a through z or A through Z |
Predefined classes | Matches |
---|---|
|
Any character |
|
Digit: [0-9] |
|
Non-digit |
|
Whitespace character: [ \t\n\r] |
|
Non-whitespace character |
|
Word character: [a-zA-Z_0-9] |
|
Non-word character |
Quantifiers | Matches |
---|---|
|
x, once or not at all |
|
x, zero or more times |
|
x, one or more times |
|
x, exactly n times |
|
x, at least n but not more than m times |
|
x, at least n times |
Logical operators | Matches |
---|---|
|
x followed by y |
|
Either x or y |
|
x as a group |
Boundaries | Matches |
---|---|
|
Start of line |
|
End of line |
Example:
type string String(min-size = 0, max-size = 128);
type string LongString(min-size = 0, max-size = 1024);
type string Email(min-size = 0, max-size = 64, regex = r"^\w+@\w+(\.\w+)+$");
This creates three domain model primitives. The first can store a maximum of 128 length text, the second may store texts up to 1024 characters.
The third string may accept only email addresses. Please note that the regular expression is specified in a raw string using the r
prefix. In the raw string the backslash (\
) characters of the regular expression are not escaped. If you use the regular (non-raw) string to specify regex, you must escape the backslash characters as follows.
Example:
type string Email(min-size = 0, max-size = 64, regex = "^\\w+@\\w+(\\.\\w+)+$");
You can find a detailed explanation of the operators and their precedence in the Operators chapter. The supported operators of string are the following:
Operator | Result | Meaning | Example |
---|---|---|---|
|
Boolean |
Case-sensitive comparison. |
|
|
Boolean |
Case-insensitive ordering. |
|
|
String |
Concatenates two strings into a single string result. |
|
Supported functions are listed in chapter String functions.
Numeric
Numeric represents a numeric value. Numeric constants are represented by digits and at most one dot (.
) symbol that cannot be the first nor the last character. For example 10
or 3.14
.
To define numeric primitive, use the type
keyword with numeric
.
Syntax:
type numeric <name> (precision = <precision>, scale = <scale>) ;
where the <name> is the name of the domain model numeric, the <precision> is the maximum total number of decimal digits that will be stored, both to the left and to the right of the decimal point. The precision must be greater than 0. <scale> is the number of decimal digits that will be stored to the right of the decimal point (fraction). This number is subtracted from precision to determine the maximum number of digits to the left of the decimal point. Scale must be a value from 0 through precision.
The number 3.14
has a precision of 3 and a scale of 2.
Example:
type numeric Integer(precision = 9, scale = 0);
type numeric Price(precision = 7, scale 2);
You can find a detailed explanation of the operators and their precedence in the Operators chapter. The supported operators of numeric are the following:
Operator | Result | Meaning | Example |
---|---|---|---|
|
Boolean |
Comparison. |
|
|
Numeric |
Arithmetic operations. |
|
|
Numeric |
Integer arithmetic operations, scale of both arguments must be 0. |
|
Supported functions are listed in chapter Numeric functions.
Boolean
Boolean represents a logical value: true
or false
.
To define boolean primitive, use the type
keyword with boolean
.
Syntax:
type boolean <name> ;
where the <name> is the name of the domain model boolean.
Example:
type boolean Boolean;
You can find a detailed explanation of the operators and their precedence in the Operators chapter. The supported operators of boolean are the following:
Operator | Result | Meaning | Example |
---|---|---|---|
|
boolean |
logical negation |
|
|
boolean |
logical AND |
|
|
boolean |
inclusive logical OR |
|
|
boolean |
exclusive logical OR |
|
|
boolean |
logical material implication |
|
|
<any> |
conditional branching |
|
Besides true and false, the result of logical expressions can also be undefined. This three-valued logic is a consequence of supporting undefined to mark absent data. If a logical expression contains an undefined value, the result is calculated according to the Kleene three-valued logic. The truth table of the three-valued logic is as follows:
p |
q |
p or q |
p and q |
p xor q |
p implies q |
---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p |
not p |
---|---|
|
|
|
|
|
|
Supported functions are listed in chapter Boolean functions.
Date
Date is a calendar date with no time nor time zone information. Date is delimited by backtick, for example `2020-02-18`
.
To define date primitive, use the type
keyword with date
.
Syntax:
type date <name> ;
where the <name> is the name of the domain model date.
Example:
type date Date;
You can find a detailed explanation of the operators and their precedence in the Operators chapter. The supported operators of date are the following:
Operator | Result | Meaning | Example |
---|---|---|---|
|
Boolean |
Comparison. |
|
Arithmetic operators are not available for the date type. If you want to perform calculations with a date value, first convert it to a timestamp. Then use the timestamp functions and convert it back to a date type. The following example adds a week to a date.
|
Supported functions are listed in chapter Date functions.
Time
Time represents the time of day, independent of any particular day and with no time zone information.
Time literals can be represented as literals using the following syntax.
Syntax:
`<hh>:<mm>[:<ss>]`
where
-
<hh> refers to a zero-padded hour between 00 and 23,
-
<mm> refers to a zero-padded minute between 00 and 59,
-
<ss> refers to a zero-padded second between 00 and 59,
-
the surrounding backticks are required.
The valid values of time are between `00:00:00`
and `23:59:59`
.
The following examples are valid time literals.
Example:
`23:59:59`
`23:59`
To define time primitive, use the type
keyword with time
.
Syntax:
type time <name> ;
where the <name> is the name of the domain model time.
Example:
type time Time;
You can find a detailed explanation of the operators and their precedence in the Operators chapter. The supported operators of date are the following:
Operator | Result | Meaning | Example |
---|---|---|---|
|
Boolean |
Comparison. |
|
Arithmetic operators are not available for the time type. If you want to perform calculations with a time value, first convert it to a timestamp. Then use the timestamp functions and convert it back to a date type. The following example adds 6 hours to a time.
|
Supported functions are listed in chapter Time functions.
Timestamp
Timestamp is a value identifying when a certain event occurred or when a certain event will occur. The accuracy of the timestamp is in milliseconds, which is used for comparison.
Timestamp is surrounded by backticks ( ` ) and formatted using ISO-8601 standard, for example
`2020-02-18T10:11:12Z`
`2019-07-18T11:11:12+02:00`
`2019-07-18T11:11:12.003+02:00`
To define timestamp primitive, use the type
keyword with timestamp
.
Syntax:
type timestamp <name> ;
where the <name> is the name of the domain model timestamp.
Example:
type timestamp Timestamp;
Some timestamp functions may expect time zone information as input. Use the following format to specify the time zone:
Syntax:
`[+|-]<hh>:<mm>`
where
-
<hh> refers to a zero-padded hour between 00 and 23,
-
<mm> refers to a zero-padded minute between 00 and 59,
-
the surrounding backticks are required.
Example:
`+02:00`
You can find a detailed explanation of the operators and their precedence in the Operators chapter. The supported operators of timestamp are the following:
Operator | Result | Meaning | Example |
---|---|---|---|
|
Boolean |
Comparison |
|
Arithmetic operators are not available for the timestamp type. If you want to perform calculations with a timestamp value, use Timestamp functions. An easy way to use arithmetic is to convert timestamp values to milliseconds. |
Supported functions are listed in chapter Timestamp functions.
Binary
The binary data type contains an unlimited number of bytes.
To define binary primitive, use the type
keyword with binary
.
Syntax:
type binary <name> (mime-types = <mime-types>, max-file-size = <max-file-size>) ;
where the <name> is the name of the domain model binary, the <mime-types> is a list of mime types indicating the accepted formats, and the <max-file-size> is the maximum size of the file.
The <max-file-size> can be expressed in bytes, kilobytes, megabytes or gigabytes using an integer and an optional unit. The unit can be based on powers of 10 (kB, MB, GB) or on powers of 2 (KiB, MiB, GiB). If there is no unit specified, the value is interpreted in bytes. The table below gives the value in bytes for each unit.
Unit | Value in bytes |
---|---|
kB |
1000 |
MB |
10002 |
GB |
10003 |
KiB |
1024 |
MiB |
10242 |
GiB |
10243 |
The <mime-types> is a comma-separated list of strings representing mime types. A mime type string must consist of a type and a subtype separated by /
in the following format:
"<type>/<subtype>"
or
"<type>/*"
Valid mime types and subtypes can only contain alphabetic characters, digits and .
, _
, -
, +
.
Examples:
type binary Document (mime-types = ["application/pdf", "application/msword"], max-file-size = 10MB);
The example above defines a Document type that accepts pdf or ms-word documents up to 10 megabytes in size.
type binary Image (mime-types = ["image/*"], max-file-size = 500kB);
The second example defines an Image type that accepts any image format up to 500 kbytes in size.
Supported functions are listed in chapter Binary functions.