The MT Language

CloudaIDE gives the possibility to hook-up so-called "triggers" to the user interface events. The triggers are written in the MT (Mroovka Trigger) language. When the particular event happens – the trigger code is executed.

The grammar is based on the PL/SQL language of Oracle, which in turn is based on Ada. It differs from PL/SQL in that it is case sensitive. The source code alphabet is UTF-8.

Lexical Elements

Identifiers

Identifier

Identifier starts with an ASCII letter, dollar sign or underscore and consists of unlimited number of letters, digits, underscores or dollar signs. Identifiers are case sensitive.

Total, groupSumm, is_allowed

Item Identifier

The item identifier starts with colon followed by two identifiers separated by a dot.

:ORDER.TOTAL, :global.person_id, :parameter.branch_id

Literals

String Literal

String literal is a sequence of UTF-8 characters and escape sequences delimited by apostrophes. The escape sequences are the same as in Java. Unlike Java strings, Strings in MT can contain new lines.

EscapeSequence:: \b | -- \u0008: backspace BS \t | -- \u0009: horizontal tab HT \n | -- \u000a: linefeed LF \f | -- \u000c: form feed FF \r | -- \u000d: carriage return CR \" | -- \u0022: double quote " \' | -- \u0027: single quote ' \\ | -- \u005c: backslash \ OctalEscape | UnicodeEscape -- \u0000 to \u00ff: from octal value OctalEscape:: \ OctalDigit | \ OctalDigit OctalDigit | \ ZeroToThree OctalDigit OctalDigit OctalDigit:: (0 | 1 | 2 | 3 | 4 | 5 | 6 | 7) ZeroToThree:: (0 | 1 | 2 | 3) UnicodeEscape:: \u HexDigit HexDigit HexDigit HexDigit HexDigit:: (0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | A | B | C | D | E | F)

Integer Literal

One or more digits.

Float Literal

One or more digits, followed by dot and zero or more digits.

Comments

MT allows two forms of comments:

Single-line Comment

Any combination of characters from double minus (--) to the end of line

full_name := first_name || ' ' || last_name; -- this is a single line comment

Multi-line Comment

Any sequence of characters enclosed within /* and */. Multi level multi-line comments are not allowed.

/* Copyright © 2015 by Wiesław Poszewiecki. All rights reserved */

Data Types

MT has five datatypes: date, text, number, boolean, oidn and etext.

Date

Date represents a date with the accuracy to miliseconds. It is declared with use of date keyword.

the_day_before date;

Text

Text represents UTF-8 text of variable length. It is declared with the following syntax: text(length) where length is the maximal length of the text in characters. Texts do not have an empty value. After assignment of an empty value to text, the text becomes null.

customer_name text(40);

Number

Decimal number. Declaration syntax number(precision, scale). There are no limits on precision and scale values. Unlike JavaScript numbers MT offers exact decimal arithmetics.

Oidn

Number based object identifier. This datatype stores encrypted object identifiers. The only operations available on oidns objects is the assignment, direct or indirect (as parameters, default values, master item values).

Declaration syntax oidn.

The system encrypts numbers, that are mainly ids of database rows, and other numeric data comming from the database. The data is encrypted using session, subsession and oidn assignment graph information in order to prevent illegal access to entities.

customer_id oidn;

Boolean

Boolean datatype holds boolean value (true or false).

account_owerdrawn boolean;

Etext

This datatype stores encrypted text. The only operations available on etexts is the assignment, direct or indirect (as parameters, default values, master item values).

Declaration syntax etext.

The system encrypts texts: the data is encrypted using session, subsession and assignment graph information in order to prevent illegal access to entities. Etexts are used to assure that the text keep unchanged. They can be used to convey texts, that if modified could be used to carry-out an attack.

sql_phrase etext;

Expressions

Expressions within MT fall into categories corresponding to the data types of the result: arithmetical (number), text (text), dates (date), boolean (boolean) and oidn (oidn). The last category is more syntactical one, because it allows only the simplest form of expression – it does not allow any operators, that combine oidns in a way other than full substitutions.

Expressions of all kinds can contain braces to express the evaluation order.

Boolean Expressions

Boolean Expressions in MT are built using the SQL WHERE clause syntax. The following operators can be used.

Operator Explanations Examples Syntax
and, or The priority of evaluation follows usual mathematical convention. The conjunction (and) has the highest priority. a > 0 and b > 0 or c < 0 is the same as (a > 0 and b > 0) or c < 0 BooleanExpression (and | or) BooleanExpression
not not a>0 not BooleanExpression
Comparisons <, =, >, <=, >=, >< Applicable for all data types. No implicit data type conversions. Only = and <> tests on oidns give meaningful results. a >= 0 and invoice_date > add_days(sysdate, 10) Expression ( < | = | > | <= | >= | <>) Expression
is null, is not null Tests whether the result of expression is null or not. first_name is null Expression is [not] null
like, not like Tests whether the text expression matches a pattern with % and _ meta-characters. first_name like 'Sm%' TextExpression [not] like TextExpression
between, not between Tests whether the first operand is between second and third operands. birth_year between 1900 and 2000 Expression [not] between Expression and Expression
in, not in Tests whether the first operand belongs to a list a in (1,3,5,7,9) Expression [not] in (Expression [,Expression]*)

Arithmetical Expressions

Arithmetical expressions allow the following operators: +, - , unary +, unary -, / and *. The priorities of operands are the same as in usual arithmetic with the * and / at the highest level.

Text Expressions

Text expressions allow only concatenation (||) operator. You can use text functions of course to.

first_name || ' ' || middle_initial || '. ' || last_name

Date and Oidn Expressions

Date and oidn expressions do not allow any operators. You can use functions, variables or items of the respective type only.

Statements

Statement list is one or more statements delimited by semicolon.

StatementList::Statement ; [StatementList]

Statement

The Statement is an executable piece of the program text.

Statement:: ( AssignmentStatement | IfStatement | WhileLoop | return | ProcedureCall | null)

Assignment Statement

AssignmentStatement::DataItem := Expression DataItem::(Item Identifier | Identifier)

Data Item can be one of variable, assignable parameter, global variables and Screen Items.

count := count + 1; velocity := distance / time; fullName := firstName || ' ' || lastName; now := sysdate; tomorrowsWeekday := to_text(add_days(sysdate, 1), 'EEE');

If Statement

The If statement aim is to perform conditional execution. It starts with calculating the boolean expression. If it is true then the first statement list is executed. If it is false then the second statement list (if present) is executed.

if BooleanExpression then StatementList [else StatementList] end if
if age >= 18 then message_info('Ok, you are grown up. You can continue with this site'); else message_info('You cannot continue with this application'); end if

While Loop

While loop on the start calculates the boolean expression if it is true then the statement list is performed and the while loop is repeated. If the boolean expression is false the while loop quits execution.

while BooleanExpression loop StatementList end loop
while i < 10 loop sum := sum + i; i := i + 1; end loop

Return

Return (return) statement quits execution of the current program.

Null

Null (null) is an empty place-holder that does nothing.

Procedure Call

Procedure call is a construct which executes client or server procedure. Server procedures come in two flavours – Database stored procedure and Java server procedure.

ProcedureCall::QualifiedName[ ( Expression [, Expression]* ) ] QualifiedName::[Identifier.]Identifier

System looks up for a procedure in the following order: built – in, client, Java server procedure, Database stored procedure.

If there is a procedure with the name, but arguments do not match with parameters number and types a compilation error is reported. No client procedure argument overloading is allowed.

If more than one server procedure with the specified name is found a compilation error is reported (MT does not allow procedure overloading). Arguments and parameters have to match in number and datatypes. It has to be stressed, that the procedure names in MT are case sensitive. So always write procedure case according to the database rules.

MT allows for direct and indirect recursion in procedure calls.

execute_query; set_order('EMPLOYEES', 'LAST_NAME, FIRST_NAME');

A note about server functions: Server functions can be called by CloudaIDE using the procedure syntax. For example a PL/SQL server function

Function add2(a1 number, a2 number) return number is begin return a1 + a2; end;

can be called in MT with the following syntax:

ADD2(:global.result, 5, 3);

The first variable (in this case :global.result) in such a call receives the function result. The remaining arguments have to fit the function signature. It is worth noting, that the function (and also procedure) call is in upper case because this is the default within Oracle database.

Program

MT allows routines of two kinds: procedures and triggers. Program consists of optional program heading (procedure definition) and program body. Triggers do not have program heading.

program::[programHeading] programBody

Program Heading

Program heading declares the procedure name and optional parameters.

programHeading::procedure identifer [ ( parameterDeclaration ) ] is

The in out phrase in the parameter declaration denotes that the parameter is passed by reference. Change made to such a parameter will change the argument. If the parameter is declared without the phrase, the parameter is passed by value. Assignment to such a parameter is illegal.

parameterDeclaration::identifier [in out] datatypeName [, parameterDeclaration]
datatypeName::(date | text | number | oidn | boolean | etext)
procedure calculateTotal is procedure getEmployeeAge(employeeID oidn, age in out number) is

Program Body

programBody::[variableDeclaration] block

Variable Declaration

A variable has to be declared before being used. MT is a strongly typed language without implicit conversions.

VariableDeclaration::Identifier DatatypeDeclaration ; [VariableDeclaration] DatatypeDeclaration::(date | text(Length) | number(precision, scale) | oidn | boolean | etext)
a number(10,2); z text(10);

Block

Block contains processing description. Block is a sequence of semicolon delimited statements plus an optional exception handling block enclosed in begin and end; . The program executes consecutive statements. Exception is a control flow construct that is mainly used to handle errors.

Block:: begin StatementList [ExceptionBlock] end;

Exception Block

The purpose of the exception block is to handle errors. Exception block begins with the exception keyword and contains one or more exception handlers.

ExceptionBlock::exception ExceptionHandler [ExceptionHandler]*

Depending on exception type MT system chooses proper exception handler.

ExceptionHandler::when ExceptionTypeIdentifier then StatementList

Currently CloudaIDE uses the following exception type identifiers:

  • CLIENT – for client exceptions
  • SERVER – server exceptions
  • SYSTEM – programming or internal exceptions
  • SQL – SQL exceptions. Error Code Conveys the SQL error Number of the respective JDBC driver
  • others – a catch-all clause if the exception was not processed by the previous handlers.

Within an exception handler the values of the following built-in functions can be used: ERROR_CODE, ERROR_TYPE, ERROR_MESSAGE. They contain the values coming from the last raised exception. Outside the handler their values are meaningless.

a number(10, 2); begin do_some_processing; a := 10 / 0; exception when SYSTEM then message_error('probably zero division error'); when others then message_error(ERROR_MESSAGE); end;

All handlers execute in the definition order. Exception block quits when an exception is handled by a first matching handler. Handler with an others label catches all kinds of exceptions if and exception was not caught by and handler.

If an exception was not caught by any handler, it is propagated to an outer routine. If it was not processed by any handler, the exception is reported to the user and logged in system error logs. If an exception happens during the exception processing, the raised exception is propagated to the outer level.