Skip to content
logoBack to home screen

Generic Model Manipulation Language (GMML)

GMML is a human readable representation of manipulations, i.e. instances of types from the Manipulation Model.

For a quick reference see GMML Full Example.

General

GMML is primarily used to feed CollaborativeSmoodAccesses such as cortex incrementally with data to make it an event-source database.

For more information on CollaborativeSmoodAccess, see Smart Memory Object-oriented Database.

Following example shows GMML in action without requiring you to read the subsequent detailed explanation.

User = foo.bar.User
Group = foo.bar.Group
Status = foo.bar.Status

user1 = User()
.name = 'John'
.birthday = date(1967Y,1M,14D)
.status = Status::active

user2 = User()
.name = 'Johanna'
.birthday = date(1970Y,5M,23D)
.status = Status::active

user3 = User()
.name = 'Paul'
.birthday = date(1972Y,12M,22D)
.status = Status::active

user1.friends = (user2, user3)
user2.friends = (user1, user3)
user3.friends = (user1, user2)

group = Group('group:the-extra-ordinaries')
.members + (user1, user2, user3)

This example shows how three new Users are being created, equipped with simple values and wired to each other via the friends property. Finally, an existing Group entity is looked up by its globalId and the three users are added to as its members.

Supported Manipulations

Implementation of GMML can be found in the com.braintribe.gm:ManipulationModel#2.0 artifact. With GMML, you can have a short notation of the certain manipulations that can happen:

The format can be parsed into instances of the ManipulationModel for maintenance operations and later execution or can be directly executed without creating those instances. The format can be generated in the following ways:

Statements

GMML grammar supports the following statements:

Variable Assignment Statements

These statements do not directly represent a manipulation but help to store values for reuse. Values can be assigned to variables with the following form:

variable = 'value'

Examples:

someVariable = 'Hello World!'
anotherVar = 1
$0 = true
_my_var1 = (1,2,3,4)
MyType = foo.bar.MyType

Property Manipulation Statements

These statements represent instances of the PropertyManipulation

Property manipulations can come in the following 2 forms:

  • variable.property operator 'value'
  • .property operator value

The variable must contain a value of the type entity, for example:

user2.name = 'john'
.friends + user1

If the variable name is left out the last targeted variable is used as property owner.

Property Operators

OperatorDescriptionValueRepresented Manipulation
=Assigns a value to the propertyany valueChangeValueManipulation
+Inserts one or more elements to a collectionA single value or a collection of valuesAddManipulation
-Removes one or more elements to a collectionA single value or a collection of valuesRemoveManipulation
--Clears a collectionNo operandClearCollectionManipulation

Delete Entity Statements

This statements represent the DeleteManipulation

Entities can be deleted with following form:

- value

The value must be of the type entity. Here a concrete example with a variable as value:

- user

Properties

Properties are defined by EntityTypes and have a name and a type.

Variables

GMML uses variables to assign all kinds of values for reuse in the manipulations as operands. Variables can hold the following values:

  • sub types of CustomType
  • instances from the type system

Variable names can use one the following characters:

  • a-z
  • A-Z
  • $
  • _
  • 0-9 except for the first character

Type System

  • scalar types
    • simple types
      • numeric types
        • integer types
          • integer - signed 32bit
          • long - signed 64bit
        • floating point types
          • float - 32bit
          • double - 64bit
          • decimal - unlimited
      • boolean
      • string - unicode
      • date
    • enum
  • custom types
    • entity
    • enum
  • complex types
    • entity
    • parameterized collection types
      • list
      • set
      • map

Values

Values are instances from the types of the type system.

Simple Values

TypeExample Literals
Booleantrue
false
string'Hello World'
integer16
long1235678987654321L
float3.14F
double2.81D
decimal4.669201609102990671853203821578B
datedate(2018Y,10M,10D,10H,54m,43S,853s,+0200Z)

String Literal Rules

String literals are opened and closed with the single quote '. The cannot span over more than one line currently and behave very much like JavaScript string literals. Escape characters can be used to insert certain non printable characters and exotic codepoints:

EscapeMeaningCodepointCharacter
\\Escape for the escape character92\
\uxxxxUnicode codepointgeneric
\bbackspace8
\thorizontal tab9
\nline feed10
\fform feed12
\rcarriage return13
\'single quote39'

Date Literal Rules

Date literals are given in the following form:

date(dateFragment, ...)

The number of given date fragments is free and missing fragments are assumed to have a base value. The fragments are added up to make up the whole date. The following dateFragment literals are supported:

Date FragmentFormatExample
Yearinteger with suffix Y1976Y
Monthinteger with suffix M1M
Dayinteger with suffix D14D
Hourinteger with suffix H13H
Minuteinteger with suffix m42m
Secondinteger with suffix S30S
Millisecondinteger with suffix s835s
Time Zone+ or - hhmm Z+0100Z

Examples

date(1992Y)
date(1992Y,10M,10D)

Enum Constants

Enum values come in the following form:

type::constant

Example with a prepared variable for the type:

Status = foo.bar.Status
user.status = Status::active

Example with variable assignment for the type:

user.status = (Status = foo.bar.Status)::active

Entity Values

Entity Instantiations

Such values represent an InstantiationManipulation. They are formed in the following way:

type()

Example with a prepared variable for the type:

User = foo.bar.User
user = User()

Example with variable assignment for the type:

user = (User = foo.bar.User)()
Entity Lookups

Such values do not represent any manipulation and only lookup existing entities to continue with incremental operations on them. Such values are formed in the following way:

type('globalId')

Example with a prepared variable for the type:

User = foo.bar.User
user = User('globalId')

Example with variable assignment for the type:

user = (User = foo.bar.User)('globalId')
Entity Acquires

Such values represent an AcquireManipulation and are formed in the following way:

type['globalId']

Example with prepared variable for the type:

User = foo.bar.User
user = User['globalId']

Example with variable assignment for the type value:

user = (User = foo.bar.User)['globalId']

Collection Values

Collections may only contain non collection values as elements which are of the following type:

  • simple values
  • entities
  • enum constants
List Values

List values are formed in the following way:

[value1, value2, ....]

Examples:

[1,2,3]
['Hello','World']
[1,true,var,]
Set Values

Set values are formed in the following way:

(value1, value2, ....)

Examples:

(1,2,3)
('Hello','World')
(1,true,var,)
Map Values

Map values are formed in the following way:

{key1: value1, key2: value2, ....}

Examples:

{1: 'Hallo',2: 'World'}
{var1: 1L, var2: date(1976Y)}
Collection Delta Values
Value FormValid for Collection Target TypeDescription
valuelist, setappends/inserts or removes a single value.
(value1, value2, ...)list, setappends/inserts or removes a single value
{pos1: value1, pos2: value2}list, mapinserts/puts values