skip to main content

Extending your application

We extend the application model and resolve alignment issues between the new database version and the pre-existing one.

In the previous episodes #

We realized a simple model for managing master data and generated the first version of our Livebase application. The system for now consists of a single application view (Application) that allows to manage objects belonging to Employee, the only class present in our database.

Evolutionary Maintenance #

In this lesson we continue to work on the previous model by making small incremental changes to the Employee class: we will model missing information and improve the quality of the data and the client interface.

This is a good time to talk about evolutionary maintenance: we are about to make an intervention that will modify the model of a pre-existing application and database. In these situations, it is important to avoid introducing inconsistencies in the database or regressions in the running application; fortunately, Livebase offers several solutions to transparently manage model updates without compromising the integrity of the underlying database.

Database/model alignment #

As we’ve seen, the Designer checks in real time that the model we draw is valid and consistent. When a model is installed on a Cloudlet, Livebase also checks that the model structure ’ described in the Database Schema ’ is compatible with that of the database in the Cloudlet. In case of incompatibility, Livebase alerts us by describing the problem and automatically proposes, when possible, an action to solve it.

The alignment problems we will encounter will generally be of three types, classified according to their severity:

  • Low severity issue: Problem that can be solved automatically by Livebase without data loss;
  • Medium severity issue: problem that can be solved automatically by Livebase, but in some cases results in data loss;
  • High severity issue: severe alignment issue that cannot be resolved automatically and prevents Cloudlet from starting.

At any time you can consult compatibility errors from the database panel of a Cloudlet, which you can access by clicking on its icon () from the Dashboard. Also, this will show a different warning depending on the type of the issue, yellow for low severity, orange for medium and red for high.

Handle alignment problems #

We try to modify TutorialEngine to introduce alignment problems with the Workforce database.

1. Save the engine in the library #

Before making changes to an engine it is good practice to archive the current version, especially if ’ as in our case ’ it is installed on a Cloudlet with a non-empty database. To do this, drag the TutorialEngine icon and drop it on the Engine Library. In the dialog that opens you can enter a description of the engine and change the comment for the version, which by default will be Archived from cloudlet 'Workforce'.

It is not necessary to stop the Cloudlet to archive its engine.

2. Edit the engine #

Before modifying the engine you have to stop the Cloudlet: from the Dashboard, click on Stop in its box and check that its status has changed to Stopped.

Let’s try to make destructive changes: open TutorialEngine in the Designer and delete the attribute date_of_birth from Employee by selecting the Delete option from its Attribute menu or by pressing Del.

A dialog will appear warning that the unique constraint we defined for Employee has been removed along with the attribute, as it includes date_of_birth. Click OK: along with the attribute now the icon of the uniqueness constraint has disappeared () .

Confirm consistency enforcement

Save the engine and close the Designer to return to the Dashboard. The Workforce status has changed to Cannot start (engine/database mismatch) and an orange warning has appeared on the database icon, indicating that we have introduced at least one medium severity issue. Open the Database panel, and look at the contents of the Engine compatibility issues tab:

Image issues cloudlet workforce

There are two issues related to removing items from the model; for both Livebase describes the problem and the proposed action to automatically align the database. The first issue is medium severity, as removing the date_of_birth column from the employee table would result in deletion of the stored values for the attribute in question from the objects we have inserted into the database.
The second issue on the other hand is low severity and has no effect on the objects in the database.

3. Restore the engine #

We have deliberately made a mistake; now let’s see how to solve it without losing data by using a stable version of the engine. For the moment don’t click on Resolve all issues. Instead, close the Database panel, right click on it, select Delete and click OK to confirm the deletion of the database. Once this is done, delete the “broken” copy of TutorialEngine on Workforce; then drag the copy stored in the library and drop it on the Cloudlet. In this way, the engine is restored and the issues disappear.

Edit the data model #

Let’s continue working on the single Employee class and model more attributes to track more information about our employees. Open the Designer by clicking on TutorialEngine and make sure you are in the Database Schema .

Add new attributes #

Add attributes to Employee by clicking on New attribute from the Class menu and defining them as follows:

AttributeFunction
email_address: stringThe employee’s email address
position: stringIts role in the company
team: stringThe name of the team he belongs to
date_joined: dateThe date he was hired
hourly_cost: realIts hourly cost

The resulting class should look like in the figure. Be careful to choose the right data types: date_joined is of type date, while hourly_cost is of type real, since we also want to include decimal places. You can sort the list by simply dragging and dropping the individual attributes to the position you want.

Designer Employee new attributes

2. Restrict the attributes domain #

Currently, you can enter any value for all attributes; for example, nothing prohibits you from entering an invalid email address. However, we can define restrictions on the domain of allowable values for attributes.

After closing the Domain Editor, the Designer warns us that this domain restriction could generate alignment problems for pre-existing objects; this danger is averted, since position has just been created and is not required. Click OK to confirm the changes.

Designer warning edit domain

Notice how the position attribute has changed in the class, which is now displayed with square brackets around the type: [string]. We now impose constraints on the set of allowable values for the phone_number and email_address attributes as well:

  • We assume that the phone number is a string ’ because we allow symbols such as +@, @-@, @(@ and @) ’ in addition to numeric characters, and its maximum length is 20 characters. Open the Domain Editor for phone_number, specify 20 in the Max length field, and then click OK.
  • Designer employee email address string domain editor regexp For email_address, we want it to respect the right format and be something like utente@example.com. We certainly can’t define a set of constants, since almost infinite combinations are allowed. Instead, we can specify a pattern encoded in a regular expression. Open the Domain Editor for email_address, check Value must match any of the following patterns, and click Add. From the string pattern editor, select Regular Expression for the Pattern Type field, and in the space below copy and paste this regular expression: [^@]+@[^@]+\.[^@]+.

To verify that the domain works properly, enter test values in the Test value field, such as johndoe@thesfor.com, aaa@bbb, ccc.org. The first value is accepted, while the other two are correctly rejected as ineligible. Click OK and return to the Designer. The resulting class from these changes should look like this.

Designer employee domain restrictions

3. Define a complex object title #

When we save a model, the Designer sets the first attribute of a class as its object title by default, in case no other attribute has been specified. Right now the object title of Employee is first_name, and it is in fact what appears in the breadcrumb when we examine an object in the application; however, we want both the first and last name to appear.

Since only one attribute can be set as the object title at a time, we have a problem that cannot be solved by making use of the “simple” attributes seen so far; however, we can take advantage of this situation to introduce derivative attributes.

The value of a derived attribute doesn’t exist in the database, but is calculated at the application level from the value of the other attributes; the calculated value is displayed in the application along with the other attributes - which we’ll call native attributes from now on to distinguish them. We can then create an object title in the form of a derived attribute to concatenate the values of first_name and last_name.

The Designer provides a special function to create an object title: holding Ctrl, select first_name and last_name and ’ from the Attribute menu of either ’ select Create object title to open the Math expression editor.

In this case, the panel already shows an expression concat(first_name, " ", last_name) and reports at the bottom Expression validated as STRING. This means that the attribute will be a string containing the concatenation of the employee’s first and last name, including a space for the two values.

Designer employee expression editor title

For now, let’s not worry about the other aspects of the editor; click OK to confirm and close it.

A new attribute /title has appeared in the class: the character /, placed in front of its name, indicates that the attribute in question is derived. Moreover it has already been set as object title, so it appears in bold. Since it contains the full name of the employee, rename this attribute to /full_name. In the application, for example, the breadcrumb for employee John Doe will be John Doe and no longer John.

Designer employee derived attribute title

4. Add new derived attributes #

The object title we just defined is an example of a computed attribute, defined using a simple expression based on string concatenation. Computed attributes are one of two types of derived attributes we can define, and are also called attributes of type math. The other type are attributes of type query, which we will discuss later.

In general, the expression defining a math attribute can be quite complex: the Math expression editor allows us to define expressions, which can be computed by referring not only to the attributes we define on classes (including other derived attributes), but also to additional reserved or system attributes. There are in fact three categories of reserved attributes available for each class, identified by the prefix __:

  • Platform attributes: attributes automatically managed by Livebase; they contain metadata about the class objects, such as the unique identifier (__id) and creation date (__createdon). By default, they are not shown in the Database schema; to enable these attributes on a class you need to open the Class menu and select the attribute from the New platform attribute entry;
  • System properties: attributes that belong to the system as a whole (__System), such as current date and time (__System.datetime);
  • User properties: attributes pertaining to the current Cloudlet user, who has an open session and is working on the data (__CurrentUser); includes information about his profile (__CurrentUser.username, __CurrentUser.firstName, __CurrentUser.email) and his permissions (__CurrentUser.isAdmin, __CurrentUser.team and others).

We define derived attributes for Employee: for example, we want to distinguish newcomers from the rest of the employees by age and time spent at the company. We don’t have any information about the age of the employees, but we can deduce it from their date of birth and define a derived attribute age.

From the Class menu of Employee select New derived attributeMath to reopen the Math expression editor, whose text area appears empty this time. We need to type a formula that calculates the difference in years between the current date and the date of birth; to do this, we have two alternatives: type it manually or select the attributes from the editor menus. Let’s take a quick look at them:

  • opens the list of attributes of the class for which the expression is being defined, in this case Employee. Includes any other derived attributes and enabled Platform attributes;

  • opens the list of User properties;

  • opens the list of System properties;

  • opens a list containing mathematical and logical operators;

  • opens a list of constants;

  • opens the function picker.

The function picker collects the functions that Livebase provides for defining expressions. Selecting a function from the list shows its description, which includes the parameters required as input with the corresponding data types. By clicking on Show Examples you can see examples of usage of each function.

In our case we need to manipulate dates: select Date from the Show field and select dateDiff(d1,d2,calendarField). Click Insert to close the Function picker and have the function appear in the text area of the editor.

Designer expression editor function picker

Now we need to replace the function’s placeholder parameters with the attributes we need: replace d1 with the current date (__System.date), double-clicking d1 and choosing date from the list of System properties. Similarly, replace d2 with date_of_birth by selecting it from the list of attributes. Finally, write field.year instead of calendarField.

At the end of the insertion all errors should be gone, replaced by the message Expression has been validated as INTEGER. Click OK to close the editor and rename the new attribute /math1 to /age ’ of type integer.

Now you can define ’ in a similar way ’ the attribute /junior, of type boolean, true if the employee is less than 25 years old and if he is part of the company for less than one year; the expression to use is: age < 25 && dateDiff(__System.date, date_joined, field.month) < 12.

Let’s go back to the Designer and look at the changes made:

  • by hovering over a math attribute, a tooltip appears with the expression that defines it;
  • selecting a math attribute, all attributes of the class that are used to define it are circled in red;
  • selecting any attribute, all math attributes defined from it are circled in blue.

Designer employee math attributes tooltip

For example, when clicking on /age, date_of_birth is circled in red because it appears in the expression of /age, while /junior is circled in blue because /age appears in the expression of /junior.

5. Verify the changes #

Let’s now verify the impact of this maintenance intervention on our Cloudlet. First, Save the model, close the Designer and observe the Workforce status: there are low severity issues that relate to the presence of new columns in the database following the addition of the new attributes. From the Database panel you can see that the issues only concern native attributes and not derived ones, consistent with what we said before.

Automatically resolve alignment issues ’ remember that for low severity it’s an optional step! ’ then start the Cloudlet and log in to the application. Look at the Livetable on Application > Employees: the records we inserted earlier are still there, but new columns have been added to the table, one for each attribute.

As you can see, the columns for the derived attributes Age and Junior are also present; values have already been calculated in both of them, because we inserted a date of birth for each employee. No one is junior, not only because no one is less than 25 years old, but also because the second condition of the expression is always false, since Date joined is absent for each record.

  • Let’s add a new employee junior. Click on Create and observe how the entry form has changed: there are new fields for every attribute ’ except the derived ones ’ and Position is now a drop-down menu that limits the choice of position to a value from the set of constants we specified earlier.

  • Fill in the fields as in the figure. If you want, you can verify the correct functioning of the other two domain restrictions by trying to enter a phone number longer than 20 digits or an invalid email address: when you try to save, the form will show new Data validation warnings and will block the entry.

  • Click Save and return to the Livetable. As you can see, Ted Hawkins is 21 years old and has been employed for less than a year ’ assuming you are reading this tutorial in 2018 :). If not, try changing the values of Date of birth and Date joined to make the expression true.

Gui employee form new params

Edit the application view #

So far we have always worked on the Database Schema . Instead, let’s see what we can do to add functionality and customize the appearance of our application view. From the Dashboard, stop Workforce and return to the Designer. This time, select Application from the Schemas tab to open its Application Schema .

The interface hasn’t changed much: the Employee class is still there, but it’s colored yellow; this means we’re looking at the class at the Application Schema level. Specifically, we’re in the application view named Application.

Designer application employee

In the Overview we introduced Application Schema by stating that it allows us to partition the database. This partitioning is done by changing the manageability of portions of the database; basically, we can decide which database elements are managed (managed) in each application view by enabling or disabling classes, attributes in the relevant Application Schema.

In a view, a non-enabled attribute does not appear in the tables and forms of its class, while a non-enabled class does not appear at all (there is no menu item that allows access to its Livetable).

Icon cursor application toggle For example, we can enable or disable an attribute of Employee by clicking on them when the pointer shows the icon in the figure: the disabled ones appear in gray. By clicking on the default class role, instead, you can disable the whole class.

For now, our model contains only one class and one application view
so don’t disable anything before proceeding; we’ll come back to this topic at the end of the course.

At this level the footer and the items of the Class menu and other menus also change. As you hover over the class, clickable icons appear that allow you to access different panels, each related to an application aspect for that class; you can access these same panels from the Class menu. The aspects that can be modified are numerous, and to fully understand them we need a larger model. For now, let’s focus on the Form layout and on the Class warning.

1. Change the appearance of the form #

From the Class menu, click on Set form layout... to open Employee’s Form Layout Editor. This panel changes the appearance of both the form as it is being written and the screen for the individual class object.

Designer employee application form layout editor

The panel looks like in the figure, with the Layout of the form on the right ’ which displays a field for each attribute ’ and the Widgets and Rules tabs on the left.

First, let’s give some order to the form by grouping some fields: create a new section by clicking on New section at the bottom, double-click on the name Section1 and rename it to Contact; then drag the phone_number and email_address fields into the new section. Similarly, create another section called Job and drag position, date_joined, team and hourly_cost into it.

The fields of the form, as well as its other components such as sub-sections, separators, labels, etc., all have a specific visual representation, called widgets. To learn about the types of widgets made available by Livebase, see the Widgets section within the Modeling guide.

For now, try adding a separator between the last_name and date_of_birth fields by dragging the Separator widget and placing it in the desired location.

After making the changes, the form appears as in the picture. Click OK and to close the editor and return to the Designer. As you can see, once you define rules on an aspect, the corresponding icon ( ) appears highlighted on the class. You can undo the changes at any time by right-clicking on the icon and selecting Delete custom form layout.

Designer employee application form layout editor modified

2. Set default values for the form #

When we insert new records, we might want to make one or more attributes of the class take on default values. For example, suppose that the largest team is Thesfor and most of the email addresses are in the form name.surnamee@thesfor.com. We can set default values for the attributes team and email_address: in the first case it is a constant, while in the second case we use a value calculated from the first and last name.

  1. For team, select Edit default value from the Attribute menu, and choose Constant to open the String value editor. Type Thesfor and click OK.
  2. For email_address, repeat the process by selecting Expression to open the Expression editor. Type the expression concat(lowerCase(first_name),".",lowerCase(last_name),"@thesfor.com") and check that the options When creating a new object, Initialize with computed value and Update automatically (unless set by user) are checked. This way the field is filled in automatically when we enter the employee’s first and last name, but it can still be overridden manually. Click OK to close the editor.
    Notice how a symbol has appeared next to the two attributes to indicate the presence of default values.

3. Set Class warnings #

In the first part of the lesson we imposed constraints on the domain of attributes at the database level; these constraints apply only to native attributes, not to derived attributes or platform attributes. For example, since /age is a math attribute, we have no way to control from the database that employees under the age of twenty are not included.

At the Application Schema level, we can still leverage Class warnings to impose constraints on an arbitrary number of attributes of any type. A Class warning is a validation rule based on a boolean expression: if the condition is verified, you can decide to prevent the user’s action or show a simple warning. In the first case we talk about blocked class warning.

Let’s define some Class warnings for Employee. From the Class menu, click on Set warnings... to open the Class warnings manager. Click on Add to open the Class warning editor.

Designer employee application class warning editor

A Class warning consists of a unique name, a condition and a message that is displayed when the condition is met. The editor allows you to define the boolean condition through the Expression Editor. In addition, it is possible to choose in which situations to evaluate the condition, checking one or more events as in the figure, and finally to decide whether or not to block the user’s action.

Define the three warnings listed, adding them one by one by clicking on Add from the Class warnings manager:

  1. an employee cannot be under 20 years old: type under20 as condition name, age < 20 as expression and in the message field write Employee's age is under 20!. Check Evaluated onSaveNew and SaveExisting: in this way the condition is evaluated when the user confirms the insertion or modification of a record. Finally, check Block action when message is displayed to make the condition blocking;
  2. an employee cannot have been hired in the future: type joinedInFuture as the name, date_joined > __System.date as the expression, and write the message Invalid assumption date. Check the same actions as above and make this condition blocking as well;
  3. an employee’s salary must not be too low: suppose that the minimum salary must be appropriate with respect to seniority, expressed as the number of years spent at the company. Type lowCost as name and use the expression hourly_cost < (25 + dateDiff(__System.date, date_joined, field.year) * 10); write the message Hourly cost is too low with respect to the employee's experience., check the same actions but this time do not check Block action, so that the change is still allowed.

The Class warnings manager now looks like this:

Designer employee application class warnings manager

Click Close to return to the Designer and save the model.

Designer employee math attributes

Database Schema

Designer employee application after edit

Application Schema

The Database Schema has not been minimally affected by the changes made in the Application Schema. As proof of the separation of these two levels we can see that no alignment issues have been introduced. You can verify the effect of the changes we have made in the application by starting Workforce and observing how the form of insertion and the detail of Employee have changed; you can also verify the correct functioning of the default values and class warnings set, trying to confirm the insertion of invalid data (for example, an employee with less than 20 years or hired “in a week”).

Conclusions #

In this lesson, we modeled attributes computed from expressions (or derivatives of type math); we also increased the quality of representable data by imposing domain constraints at the database level and _Class warnings at the application view level. Finally, we introduced the concepts of Database compatibility report and alignment issue related to the update of a model in presence of a pre-existing database structure.

Click on the button to download the model we made in this lesson:

TutorialEngine_extended.xml

In the next lesson… #

We momentarily interrupt our study of modeling to begin a brief digression on data management in the generated application: Import data from an Excel sheet.