Quick Model Editor

The Quick Model Editor is an editor to quickly specify definitions for relationships, entities and fields using a simple text DSL. You specify simple facts in text on a single line which are then processed and used to create a new element or execute a command. The Quick Model editor is opened by selecting Project -> Quick Model Editor from the main menu or by clicking the QuickModel button button on the toolbar.

The Quick Model editor is especially designed for quickly logging information during interviews with domain experts. The editor has its own visual model viewer, which contains all entities mentioned during the session which also helps you get an overview of what the statements you enter do to the model: you can see your model evolve in front of you.

QuickModel Editor

The QuickModel Editor with a statement to create a new field in 'Customer'

All elements created are directly created in the project and therefore you can undo your additions / changes by using the normal undo/redo procedure (Ctrl-Shift-Z and Ctrl-Shift-Y).

The Quick Model editor consists of three parts:

  1. The large editor canvas which is a ModelViewer and which shows the entities mentioned in statements entered
  2. The command area with the display of the active scope and the Command input, which is the text editor area to specify statements. Statements are specified using a simple text based DSL, which is described below.
  3. The log area, which displays errors found in the statements entered or remarks about which elements were created, updated or removed.

Text based DSL

The idea of Quick Model is that the line entered is a description of a fact or a command to manipulate some element in the model. It's a simple editor which can aid users to define model elements which can then be refined with the other editors.

Syntaxis, rules

The quick model editor uses the following rules for its Text based DSL:

  • A line can either be the description of an element in the current scope, or a command
  • Commands starts with '#'
  • If a referenced element doesn't exist, it's created
  • When Enter is pressed, the line is parsed and executed. If an error occurs, the error is reported and the line is not executed further
  • Statements work by default on the Active scope, unless a name is fully specified.

Syntaxis, names

A name (e.g. a name of an entity) can have one of the following structures:

Name structure Description
S1 Element with name S1 within current scope's group, or sub element with name S1 within current scope's groupname:elementname
S1:S2 Element with name S2 in group S1
:S2.S3 Sub element with name S3 in element S2 in empty group
:S2 Element with name S2 in empty group
S1:S2.S3 Sub element with name S3 in element S2 in group S1
S1: Group S1

Syntaxis, commands

The following commands are recognized (all commands start with a # character).

#d name
Delete element. This command deletes element with the name name. Which element is referred to by name depends on the active scope
#mg name group
Move element to group. The element with name name is moved to the group specified. Name can only be a value type or entity and group has to be a valid group name
#ms subtype supertype inheritancetype
Make subtype a sub-type of super-type supertype. Both subtype and supertype can only be entities. Inheritancetype can be either tpe or tpeh and is optional.
#e name
Create entity. An alternative way to create an entity definition, with name name
#v name
Create value type. As all element creation without commands suggests entities, the way to create a value type is through this command: creates a new valuetype with name name.
#r name name2
Rename element. Renames element with name name to the name name2. Element can be field, entity or valuetype. If the current group name differs from the new group name specified in name2, the group is changed for the element, as well as its name. If the name refers to a field, only the field is renamed, despite the fact that entity / group name might be different.
#u name
Update scope. Updates the active scope with the name name. This could mean: set the active scope to the name specified if the name is an absolute name, or dig deeper into the active scope by adding name to the active scope.
Update scope by going up. Updates the active scope by removing the deepest scope level from the active scope. If the active scope was already at group level, the new scope will become the empty group, the start scope.

There are also some commands which are only for the model view area of the Quick Model editor:

Reset graph layout. This layouts the entire graph again, so vertices and edges
Clear model view. This clears the model view and gives the user a clean slate.
Center model view. This centers the view of the model view.

Creating Entities fields and relationships

To create an entity with e.g. the name Customer, you simply type Customer in the command area and press Enter. If the current scope is an entity, the name has to be a full name (with group), i.e. :Customer for creating the entity in the general group, otherwise the name is considered an element in the current scope, i.e. a field, and a field is created instead. The

following directives are usable to create the various elements:

This creates a new element with name Name in the current scope, and it depends on the current scope what element is created. If the current scope is a group, a new entity is created within that group. If the scope is an entity or value type, a new field is created with no type information.
Name type typespec * null

This creates a new field in the entity or value type which is the current scope or a field in the element specified with the full name if the name is a full name, or if the field already exists, it updates the field. Type, Typespec, * and null are optional arguments and can be specified in any order. Example: CompanyName string(50) null. Their meaning is described below

  • Type
    This is a type shortcut name or a value type name. It's the type of the field
  • Typespec
    This is the type specification for the type, which is either (integer) to specify length or (integer, integer) to specify precision and scale.
  • *
    This is a marker to specify that the field is part of the identifying fields.
  • Null
    This is a marker to specify that the field is optional / nullable.
Name1 RelationshipType Name2 mo
This creates a new normal relationship, with the relationship type between Name1 and Name2. Name1 and Name2 are either navigator specifications in-scope or full navigator specifications (with entity names) or just entity names if no navigators are required. Relationshiptype can be one of the following: m1, 11 or 1n, which creates resp. a many to one, one to one or a one to many relationship. The suffix mo is optional and specifies whether the relationship is model-only or not. When mo isn't specified, the relationship is seen as a relationship which isn't model-only and thus requires a backing Foreign Key constraint.

It's key to use the right scope to be really productive, so use the #u command often to switch from scope to scope. This way it's easier to type names, as you then don't have to specify the group name part or the entity name part. It's also important to remember that you can undo any change you made, by simply pressing Ctrl-Shift-Z, so it's not harmful to experiment with statements.

It's in general quicker to specify the relations first. By doing that you already mention the entities and these are then created as well. For example the statement Customer.Orders 1n Order.Customer creates two entities and 1 relationship, and it also defines the navigators for both entities for this relationship.

After entities have been created, you can then set the scope to one entity and specify the fields. As relationships are already setup by then, the FK fields are created automatically from the PK fields once the PK fields have been specified.

Intellisense Helpers

In the editor pane, there is some simple intellisense available. To display a list of values to help with the syntax, we have defined three key strokes.

This brings up at the caret the list of names in the current scope. This can mean all entities in the current group, or all fields in the entity.
This brings up at the caret the list of available type shortcuts. As tooltip help, the target type of the type shortcut with default length/precision/scale is displayed (if available)
This brings up at the caret the list of relation types.

Each of them can be completed by typing TAB or Enter. The intellisense pop-ups pre-select a value if the already typed fragment matches one or more elements in the pop-up.

Multi-line paste support

You can copy/paste multiple commands at once into the editor pane and execute them with one enter key press. Each line is then executed as one command. This can be handy if the list of entities to create is already available in text form.