Types, objects, databases#
Data definitions describe data types (or classes). They are placed in files contained in directory hierarchies, and the directory name is part of the type name (similar to Java packages). For example the file company/Employee.mdd describes the type company.Employee. Type names can contain letters, digits, underscores and dashes and cannot contain slashes and dots. Usually, the directories are used to separate organisations and projects.
Current Java implementation finds the data definition files as follows:
- the designated file extension is .mdd (Makumba Data Definition)
- relative to CLASSPATH (e.g. classes/company/Employee.mdd)
- in a directory called "dataDefinitions/" in the CLASSPATH (e.g. classes/dataDefinitions/company/Employee.mdd)
Data objects (records) are stored in databases.
Data can be copied and/or replicated between different databases, even between different DB engine types.
Replication is not yet implemented, but the design is prepared for it. Copying works.
Fields#
Every data definition file contains field definitions, separated by newline.
A field definition looks like:
fieldname= [attributes] fieldtype [parameters] [; description]
Default values are supported internally, but not by the MDD parser
As an implementation guideline, field names tend to stay approximately the same in:
- HTTP requests
- Record instances (java.util.Dictionary in the current Java API)
- Database columns
- etc
The field description is used by the code generator at interface levels to present that field. It is typically shown at the left of, or somewhere near to, the input control (text box, radio button, chooser, etc) that allows for data input in that field. If a field description is not present, its field name stands for its description by default.
Comment lines can be inserted in the data definition files as follows:
# your comment...
Default fields#
Every datatype has some additional fields by default, as follows:
- Primary Key field. When using the Makumba database layer, it consists of two parts []DBSV with 8 bits | UID with 24 bits]:
- Database identifier (DBSV). It is unique (within the webapp) per database. All objects created thru that webapp and in that database get the same value. It is set by property dbsv in the database config file.
- Object identifier (UID): unique id for the object in the given database.
This combination ensures that no two objects of one type have the same primary key field. See how to configure this. The name of the primary key field is the same with the last part of the type name. If another field by that name is defined by the makumba user, this field will be renamed in the database.
- Object creation time Can be accessed as TS_create.
- Last modification time. Updates whenever the object is changed. The initicial value is TS_create. Can be accessed as TS_modify.
Primitive field types#
Overview#
Field definition type | Description | Default edit user interface | Relational database type (orientative) | Java type (orientative) |
---|---|---|---|---|
int | a simple integer | text field | integer | java.lang.Integer |
int{} | Integer enumeration, allowing for a set of predefined values | dropdown choice or radio button | ||
real | a real number | text field | double | java.lang.Double |
date | a date | date | date and time | java.util.Date |
char | a limited text (maximum length is 255) | text field | limited char | java.lang.String |
text | an unlimited text | text area | unlimited characters | org.makumba.Text |
binary | a binary content, e.g. an image | binary area | unlimited byte | org.makumba.Text |
int#
A 32-bit integer. For example
shoeSize= int; Shoe size
If the int can have a limited number of values, it can be described as follows
gender = int{ "Male" = 10, "Female" = 20 }
This will help the presentation layer to present a suitable input control:
"deprecated" can be used in this way to denote a deprecated option: userType = int{"type1"=10, "type2"=10,"old"=0 deprecated}
In the present implementation, this type is called "intEnum" internally. Negative numbers are supported (e.g. int { "aa"=5, "bb"=2, "cc"=-10}).
real#
A real number with double precision with (2-2-52)ยท21023 as max value and 2-1074 as min value. For example:
turnover = real; turnover of the company
char#
A char field contains a number of characters. Maximal width must be specified and is limited to 255. (Optionally a minimal number of characters (lesser than max) can be indicated). Both must be positive integers. For example:
fieldName= char[maxWidth]; name= unique char[80];
unique is a field attribute, explained below.
Pay close attention to the character set (charset) for encoding the characters. In Java the charset is Unicode, but the JSP/HTML pages have their own encoding settings, as well as the database, etc.
boolean#
A boolean, that can take as values true or false. For example:
currentlyEmployed= boolean; whether this employee is currently employed
text#
An unlimited-length string of characters. This type is designed to accommodate large text content. It is implemented with LONGTEXT or its counterparts, depending on the underlying DB engine. The text data-type is ready for accepting data in UTF-8 encoding.
description=text ; Description of the project
binary#
An unlimited-length field designed for binary content. In contrast to the text data type, binary will always be of 8 bit length. It is implemented with LONGTEXT or its counterparts, depending on the underlying DB engine. This type is meant for storing only raw binary data, for storing files along with meta-data like a file name, content type, etc., you should rather use the file data type.
signature= binary ; a binary digital signature
date#
A date and/or time.
birthdate = date; Date of birth arrivalTime = date; Arrival time
Structural (relational) types and collections#
Overview#
Field definition type | Description | Default edit user interface | Relational database type (orientative) | Java type (orientative) |
---|---|---|---|---|
ptr | a pointer to another type record | dropdown select of record titles. | preferably a long (foreign index) | org.makumba.Pointer |
set | a set of records of another type (which could be re-used in another type) TODO: set chooser link | multiple choice of record titles. | table with ptrRel to the parent table and ptr to the foreign table | java.util.Vector of org.makumba.Pointer |
fieldName=set fieldName-> ... |
an internal set that relates to one specific record | table with ptrRel to the parent table, and the rest of the fields | ||
set int{} | a set of predefined values | multiple choice from values | table with ptrRel to the parent table, and an int field | java.util.Vector of java.lang.Integer |
file | a file including its meta-data (content type, size, ...) | file upload | preferably a long (foreign index) |
ptr#
Pointers define a reference to an object of a certain type. For example
manager = ptr company.Employee; The manager of the department
set#
Sets define a number of references to multiple objects of a certain type. For example:
suppliers= set company.Company; Suppliers of this company
This type accomodates sets, bags and lists. The set and list constraints (sets have to contain only one element of a certain value and lists have to be ordered) have to be cared for by the programmer. Lists are easy to represent, just having an integer field, for the order.
The type which the set is made of can be defined on the spot:
projects = set projects->project = ptr company.Project projects->timePercentage = int ;percentage assigned
The main difference between sets of external types and internal sets is that when the host object (e.g. Employee.mdd that has the above field "address") is deleted from the database (DB), also all elements of the set (addresses) are deleted automatically, so there is no orphans (addresses) in the DB. Elements (addresses) of an internal set of some host object (Person X) also can't be used in a set of some other host object (Company Y).
Internal sets are known internally as setComplex
The set can contain enumerated int values :
place= set int {"home"=1, "away"=0} ; Home or away
This is currently known internally as setintEnum
file#
A file data-type is a kind-of record containing several fields needed when wanting to store files. These fields are:
- content (binary): the actual binary data of the file.
- name (char): the file name.
- originalName (char): the original file name.
- contentType (char): the MIME content-type of the file.
- contentLength (int): the content length in byte.
- imageWidth (int): (only for images) the image width.
- imageHeight (int): (only for images) the image height.
logo = file ; Picture attachment
This type should be used in favour of the binary data type when you don't want to store only the raw binary data, but also meta-data as in the fields above.
Macro types#
A name can be defined for a more complex type and it can be reused in the file. This can be done with a !type directive
!type.rank = int{"Neutral"=0, "Very good"=5, "Very bad"=-5} happyInLife = rank
Field attributes#
- fixed fields can only set during the record's insertion in the database. The subsequent updates will not update the field
- not null fields will produce a exception if an attempt is made to insert/update without them being initialized
- not empty fields will produce a exception if an attempt is made to insert/update an empty string value
- unique fields have a unique value in the respective object, for the respective type
These attributes are used by makumba in order to perform implicit validation at form submission time, i.e., the fields of submitted forms will automatically be checked for coherence against the defined field attributes.
It is possible to customise the error message that will be displayed in case an implicit field validation fails:
login.unique = "This login is already taken, please choose another one" surname.notEmpty = "Please fill in your surname" age.notNull = "Please fill in your age" age.NaN = "Please enter a valid number" age.notInt = "Please enter a valid integer" amount.notReal = "Please enter a valid real"
The NaN (Not A Number), notInt (not an integer) and notReal (not a real) error message is part of implicit, type-dependent validation and is performed by makumba automatically, without the need of adding a field attribute.
Object title#
The object title is used for set and ptr choosers
One of the fields is always the object title, and is normally presented differently from other fields in user interface. For example, when you have a field that is a set and you use a mak:input on that field, Makumba will automatically create a list with all the items in the set and it will use the object title to know what field to display. The default is the field called "name" if that exists, otherwise it is the first non-pointer field in the record description. If another field needs to be title, it can be specified like
!title=gender
for the on-the spot types in the current implementation, the following notation works: address->!title= street
Include mechanism#
A record description can include text from one or more files. This is declared as
!include=name_of_included_type
The included file has the idd extension and is found in a similar way like the data definitions.
The included file is inserted instead of the !include line. There can be more include lines in a record description file. If a field is defined that exists also in the included metadata, the defined field takes precedence.
fieldname =
If it means that it does not actually exist. This can be used to cancel an included field.
Include might be replaced by more advanced concepts such as inheritance and type inclusion (rather than reference in foreign table)