Axional Studio
works.
1 General flow
Developing an application from scratch using Axional Studio
is a linear process as shown in the following figure:
2 Prerequisites
Before starting, some requirements have to be satisfied properly.
-
Axional Studio
properly installed. Read and follow Axional Studio Installation instructions. - An application Dictionary. Read and follow Administration instructions.
- A Database Target. Read and follow Administration instructions.
3 Defining and cataloging database model
IMPORTANT
This section is aimed exclusively at those customers that do not have a database model (tables and data do not yet exist) .
At this stage, the developer will define the logical DB model that will be stored in the database dictionary. The main tasks to be performed are:
- Define Table Schemas using the option Data modelling . At this point, Views and Synonyms are defined as well.
- Define Constraints using the same form. Constraints are part of a database schema definition. A constraint is usually associated with a table and is created with a CREATE CONSTRAINT or CREATE ASSERTION SQL statement.
- Develop (Program) the DB functions required for the application. There are 2 types of functions:
- Stored Functions and Procedures (compiled code). They are functions or subroutines available to applications that access the database. At this point, the code is defined but not yet compiled until the creation of the physical model.
- Triggers. A Trigger is a procedural code that is automatically executed in response to certain events on a particular table or view. Again, at this point, the code is defined but not yet compiled until the creation of the physical model.
XSQL Language
Although the definition could be done in the native
language of each DB engine, it is strongly recommended to use the XSQL language included in Axional Studio
which is written in
DB neutral code. At run time, Axional Studio
will convert it to the appropriate syntax of the target DB engine.
3.1 Creating physical database model
Three main tasks have to be performed to bring the logical model into effective action:
Creation of the DB
If Databases doesn’t already exist, at this point they should be created using the management
tools of the DB engine. Only the simply creation of the DB is required. The physical model will be
created in the next step.
Cataloging the databases
Each physical database has to be registered in the configuration catalog (wic_conf).
See setup databases.
Set-up the physical model
Using the specifications in catalog dictionary, the physical model is deployed in the associated DB. The setup is done through a two steps process:
- Compile model: create tables, views and synonyms.
- Compile code: compile the stored procedures, functions and triggers.
3.2 Creating and deploying a table
Now let's create a table that is going to be called customer. In our case it will be created in the Formación Metadata dictionary (see also video at the end of this section).
This table will be composed of several columns, each of them with different characteristics.
- Access database dictionary.
- On the menu, select Dictionary/Physical/Tables.
- Press Execute/Run button without specifying any filter on query screen.
- Reset form data by means of Clear button. The table schema form is ready to create a new table.
- Insert table name, in this case, 'customer'.
- Now insert XSQL code in statement screen.
This is the XSQL code corresponding to customer table:
<table name='customer'> <column name='customerid' type='serial' required='y' /> <column name='firstname' type='char' size='40' required='y' /> <column name='lastname' type='char' size='20' required='y' /> <column name='company' type='char' size='80' /> <column name='address' type='char' size='70' /> <column name='city' type='char' size='40' /> <column name='state' type='char' size='40' /> <column name='country' type='char' size='40' /> <column name='postalCode' type='char' size='10' /> <column name='phone' type='char' size='24' /> <column name='fax' type='char' size='24' /> <column name='email' type='char' size='60' required='y'/> <column name='status' type='char' size='1' default='A' required='y' /> <!-- PRIMARY --> <primary name='p_customer' columns='customerid' /> </table>
Now the 'customer' table exists in the dictionary, but not in the database. For this reason, it will be necessary to compile the table.
- Enter the option Deployment / Compile model (ddl)
- Fill in the fields that appear on the query screen:
- Press Execute/Run button.
- The system will ask you to confirm that you really want to execute the process. Answer OK.
The 'customer' table now exists in the specified database.
3.2.1 Feeding the table with data
The customer table exists in the database, but it does not contain any data.
We still do not have any form to fill in the columns of the table, so we will insert the data through the tool Axional DBStudio
.
As shown in the video at the end of this section, follow the steps below.
- Display the database tools menu.
- Access the
Axional DBStudio
tool. - Select dictionary, in this case, demo form.
- Enter customer data in the SQL screen using standard SQL language.
INSERT INTO customer (firstname, lastname, company, city, phone, email, status) VALUES ('Jofre', 'Orus', 'Camsa', 'Tarragona', '666777888', 'jorus@demo.es', 'A'); INSERT INTO customer (firstname, lastname, company, city, phone, email, status) VALUES ('Toni', 'García', 'Seatech', 'Madrid', '685354234', 'tgarcia@demo.es', 'A'); INSERT INTO customer (firstname, lastname, company, city, phone, email, status) VALUES ('Felip', 'Díaz', 'Celfondo', 'Salamanca', '600000555', 'fdiaz@demo.es', 'A'); INSERT INTO customer (firstname, lastname, company, city, phone, email, status) VALUES ('Joan', 'Garriga', 'SFT Group', 'Madrid', '678965432', 'jgarriga@demo.es', 'A'); INSERT INTO customer (firstname, lastname, company, city, phone, email, status) VALUES ('Eva', 'Pi', 'Cafam', 'Burgos', '658463552', 'epi@demo.es', 'B'); INSERT INTO customer (firstname, lastname, company, city, phone, email, status) VALUES ('Luis', 'Campanar', 'Tronexsa', 'Sevilla', '666777555', 'lcampanar@demo.es', 'B'); INSERT INTO customer (firstname, lastname, company, city, phone, email, status) VALUES ('Sandra', 'Navarro', 'Sumitemp', 'Madrid', '654122554', 'snavarro@demo.es', 'B'); INSERT INTO customer (firstname, lastname, company, city, phone, email, status) VALUES ('Carmen', 'Torras', 'Alpina SA', 'León', '654848484', 'ctorras@demo.es', 'B');
Customer data has been entered in customer table.
4 Defining a view
Views are the framework for any database. Understanding how each of these view works will help you create a database framework that will be useful and help user to manipulate, modify and retrieve the information he needs.
4.1 Creating a simple report
The goal of Axional JRep Objects
is to facilitate the viewing and manipulation of database information. A simple report is the most basic object for data visualization in a database.
IMPORTANT
This object has been created for example purposes and includes available options for all kind of objects. For further information in specific objects, such as reports or forms, refer to the corresponding sections.
To create a new object, the following steps must be dealt (see also video bellow):
- Access your dictionary (in this example Formación Metadata) and then Objects / Definition / Objects
- Press Execute/Run button without specifying any filter on query screen.
- Reset form data by means of Clear button. JRepObject definition form is ready to create a new object.
By way of example, we will create a simple object (by default the created object will be a report):
- At least, you must fill in the compulsory fields (some of these fields are already autocompleted).
- Object*: object_sample
- Tag name: Object Sample
- Title*: OBJECT SAMPLE
- Area*: GEN
- Render Type*: Report
- Exec. Type*: READ ONLY
- It is essential to write the select statement, which is the data source that the object will display. In this case, we are going to select only four columns of the table to be shown:
<select> <columns>customerid, firstname, lastname, phone</columns> <from table='customer' /> </select>
- Press the Insert button: the new object has been created.
- From now on, any modification made must be recorded using the Save button. The application will then force to document the reason the change was made in the Comments field.
- Press the Clear dictionary cache button.
WARNING
It is essential to clear the cache memory to make use of object. Otherwise, object will not be found.The object must be executed through the application, in this case the Demo Formación application:
Since this object still does not appear in the application menu, for test purposes it can be executed directly using the expression /object_name in the search field.
- Access application.
- Write a forward slash character followed by object name in search field and press enter. In this case /object_sample.
The object is executed directly, without calling up the selection screen and displaying the object view on the screen.
For more detailed information on Object Definition, consult following section.
4.2 Defining object navigation
Two features are necessary for developers to provide navigation capabilities to end-users: Main entries and Menus.
Use the menu option to group and classify objects by functionality, always with the purpose of facilitating and expediting the user's experience. That's why menus can be simple or can have a tree structure with main options, related branches and end options.
NOTE
To develop this example, we have started with a pre-existing Main entry provided by the manager as Main entries are related to administrative tasks. In this case, the Main entry is called FORM-TRAD and it will be shown in the menu as Sample.
The URL to connect menus to this panel is: FORM-TRAD-SAMPLES.
IMPORTANT
It is important to keep in mind the Main entries that do not contain menus will not be shown to users.
4.2.1 Creating a simple menu
In order to access our report (object_sample), it is necessary to create a menu. Take into account the basic menu structure in Axional Studio
:
For this reason we will create a menu where to connect our object (see also video at the end of this section):
- Access your dictionary (in this example Formación Metadata) and then Menus / Menus.
- Press Execute/Run button without specifying any filter on query screen.
- Reset form data by means of Clear button.
- Fill in Root folder field. In this case use the url FORM-TRAD-SAMPLE to connect to the preexisting Main Entry FORM-TRAD.
- Fill in Subfolder field. In this case it is the same the previous one, FROM-TRAD-SAMPLE, as there is no subfolder between menu and object.
- Fill in Order field. In this case 1.
- Select Type: Item.
- Select Service: Object.
- Fill in Label field: My First Report.
- Connect the object to the menu by filling in the object code on the URL field. In our case: object_sample.
- Press the Insert button: the new menu has been created.
- Remember to press the Clear dictionary cache button in order to check that menu has been created.
As you can see, now our object is connected to the My first report menu, from the Main Entry Samples.
4.2.2 Creating a submenu
To improve menu navigability, submenus are commonly used. One submenu will agrupate one or several menus; and we can have as many submenus as desired, following this schema:
To create a submenu perform the following steps:
- Access Dictionary/Menus/Menus.
- Press Execute/Run button without specifying any filter on query screen.
- Reset form data by means of Clear button.
- Fill in Root folder field. In this case FORM-TRAD-SAMPLE to connect to FORM-TRAD Main entry.
- Fill in Subfolder field. In this case FROM-TRAD-SAMPLE.
- Complete the Order field. In this case 0 (it will be positioned before the object menu to which we have assigned the number 1).
- Fill in Submenu field. In this case FORM-TRAD-SAMPLE-REPORTS.
- Select Type: Tree.
- Fill in Label field: My Reports.
Now we have created a submenu, but there is no menu on it. We are going to modify the existing menu in order to connect it to this submenu called My Reports.
- Press the search icon.
- Use the query form to look for both menus, just by looking for the FORM-TRAD-SAMPLES on Root folder field. The result will show both menu and submenu.
- The number order is really important when having various menus to control the order inside the submenu folder. Use the Renumber button to set two number distance between both elements, thinking about future actions.
- Select the menu (My First Report) that contains the object.
- Replace subfolder by the FORM-TRAD-SAMPLE-REPORT. This will connect this menu to the submenu My Reports.
- Remember to press the Clear dictionary cache button in order to check that menu and submenu have been correctly created.
Now we can access the object through the submenu My Reports in the menu My first Report.
See video:
For further information, see section Menus where is described the development process of panels and menus.
4.3 Adding query options
Primarily, queries are used to find specific data by filtering specific criteria. By adding query options to the object, users will quickly and easily create queries by themselves to find or summarize data and to obtain the necessary information.
As an example, we will add query options in the object_sample object of the previous section, since initially it did not have any. This procedure has been included in the training video below.
4.3.1 Input Fields
Use of one or more columns
- Access object_sample through the dictionary.
- Select INPUT tab: input form is displayed.
- In order to use the lastname column from the customer table as a filter, insert both data in corresponding fields.
As a result, the object displays the query screen, which contains a unique option: lastname.
The input form allows you to add as many query columns as you wish, through the simple procedure of continuing to add new column fields.
- Insert new table and column names in corresponding fields. In this case add the column firstname.
As a result, the object displays the query screen, which contains two options: lastname and firstname.
Take into account that columns from the table not selected in SQL statement can also be added as inputs, provided they are also contained in the table.
For more detailed information, consult Input fields QBE in the next section.
4.3.2 Variables
The variables are another mechanism for data filtering. They should be created when the inputs fields cannot be used due to the query complexity.
Based upon our example above, we want to include the option to confine search to those clients that have an invoice (one or several invoices).
PROCEDURE:
- Access Variables tab.
- Define and insert the Variable in the corresponding field:
- Variable: name in capital letters.
- Description: text that query form will show user
Restrict to clients with invoices (Y/N)?
- You could insert a default answer, in this case, N. Insert the variable and clean cache .
- Access object tab.
-
In the SQL statement field, include a WHERE clause to extract only those records that EXISTS in both tables through the common column
columnid if it fulfills $VARIABLE condition:
Copy
<select><columns> customerid, firstname, lastname, phone </columns><from table='customer' /><where> $HASINVOICES = 'N' OR (EXISTS (SELECT invoiceid FROM invoice WHERE customerid = customer.customerid)) </where></select>
- If the user answer is "N", then there is no restriction and query result will display all clients (if there are any other filters).
- If the user answers something different than "N", the query restricts the data to those clients that exits in the invoice table because their customer id coincides.
IMPORTANT
Variable fields are mandatory* to be filled in.
4.3.3 Metaquery
Metaqueries are those queries that are more likely to be requested by user. For this reason, they are always available through a quick access in the upper left part of the application object, with the additional advantage that they can be accessed in run time.
In the next example we are going to delete the variable we had previously defined and replace it with a new metaquery that provides the same functionality. It's possible to watch the demonstration video bellow.
To delete the previous variable:- Access OBJECT form through the dictionary.
- Remove the entire WHERE clause.
- Press save icon and clean cache (remember to document changes).
- Access VARIABLE form through the variable tab.
- Right click on the variable and delete. Confirm deletion.
- Clean cache.
- Access METAQUERY form using metaquery tab.
- Fill the code with a unique identifier, preferably using capital letters. In this case HASINV.
- Fill the Title field, which corresponds to the label code that application will show user to select metaquery. Example: LBL_HASINVOICES
- Fill the SQL condition. In this case:
EXISTS (SELECT invoiceid FROM invoice WHERE customerid = customer.customerid) - Click insert icon and clean cache.
Test metaquery:
- Execute object through the application.
- Click on Quick filter icon on the left-hand side, next to the object name.
- The application shows one query option: select and click on RUN icon to execute. As a result, the application will show only the customers that have invoices.
- Access METAQUERY form using metaquery tab.
- Click on clean icon to start creating a new metaquery option.
- Fill the code with a unique identifier, preferably using capital letters. In this case HASNOTINV.
- Fill the Title field, which corresponds to the label code that application will show user to select metaquery. Example: LBL_HASNOTINVOICES
- Choose the order you prefer, being 0 the first and 1,2,3 ... the following successively.
- Fill the SQL condition. In this case:
NOT EXISTS (SELECT invoiceid FROM invoice WHERE customerid = customer.customerid) - Click insert icon and clean cache.
Test metaquery:
- Execute object through the application.
- Click on Quick filter icon on the left-hand side, next to the object name.
- The application shows the query now two options: select Customers without invoices and click on RUN icon to execute. As a result, the application will show only the customers that have no invoices.
IMPORTANT
Metaquery are always available in run time through the quick access, in the upper left part of the application object.
4.4 Creating a form
In a database context, a form is an object that contains fields to insert, modify or delete data on a database, in an user friendly way. Each field holds a label so that any user who views the form gets an idea of its contents.
To create a form object, follow these steps or see the video at the end of this section.
4.4.1 Singlerow form
The singlerow render mode of a form displays a single record from the statement at once. It is necessary to select forward/backward buttons to display next/previous results.
- Access your dictionary (in this example Formación Metadata) and then Objects/Definition/Objects
- Press Execute/Run button without specifying any filter on query screen.
- Reset form data by means of Clear button. JRepObject definition form is ready to create a new object.
By way of example, we will create a singlerow form:
- At least, you must fill in the compulsory fields (some of these fields are already autocompleted):
- Object*: form_sample
- Tag name: Form Sample
- Title*: FORM SAMPLE
- Group*: AUTO
- Render Type*: Singlerow
- Exec. Type*: READ/WRITE
- It is essential to write the select statement, which is the data source that the object will display. In this case, we will select all columns from table customer.
<select> <columns> <rowid table='customer' />, * </columns> <from table='customer' /> </select>
IMPORTANT
It is compulsory to select rowid of main table in order to make object transactional.
This new object does not have an output field yet. The output columns will be created automatically when the object of the form is executed for the first time, although we can insert them manually.
The object must be executed through the application, in this case the Demo Formación application:
Since this object still does not appear in the application menu, for test purposes it can be executed directly using the expression /object_name in the search field.
- Access application.
- Write a forward slash character followed by object name in search field and press enter. In this case /form_sample.
The object is executed directly, without calling up the selection screen and displaying the object view on the screen.
For further information see Form section.
4.4.2 Defining the form layout
A visually attractive form speeds the use of the database, and with the correct form layout working becomes a more pleasant and more efficient experience. It also helps prevent incorrect data from being entered.
For our example we are going to re-order fields in two boxes following two criteria: customer data and address data.
Follow the steps below to define the form layout:
- Access your dictionary and then Objects/Definition/Objects.
- In the query screen, look for the form_sample object.
- Now that the object is on the screen, access the tab FORM.
- Click on insert icon. Now the object is ready to start designing the layout.
The design area now shows tool boxes on the left and on the right side. If necessary, clean cache and reload data. We will design the layout at the bottom of the form, in the design area.
- Click on the box grid icon: this tools allows inserting on the layout as many columns and rows of boxes as desired.
- Select two boxes in one row: now the layout area shows two boxes.
- Select EJB-DATA-FLOW on BOX TYPES. For further information on boxes types, access Form Boxes section.
- Drag and Drop it on both boxes.
Now we are going to put each field into one box or the other depending on the indicated criteria: customer data into the left box and address data into the right one.
- Select one field from the OUTPUT COLUMN box.
- Drag and Drop it on the correct box.
- Repeat this process with those fields that can be editable for the user.
At this moment that the fields are on the corresponding boxes, it will be useful to name each box, although they have been automatically named by the system.
- Select one of the boxes.
- On the right side of the design area, modify the LABEL field located on the box named BOX.
- Press edit button.
- Repeat these steps with the second box.
- Access the application and execute this form, form_sample. See that the fields are now classified in two boxes.
5 Developing Business Logic
Business logic is the programming that manages communication between an end user interface and a database. It describes the operations and procedures associated to data in a business database.
At this stage, we are ready to develop a business logic example of the application.
Only two steps are required:
- Register an action to associate a program
- Register a button to associate the action
5.1 Registering an Action
As a way of example, we will create a button that can change the customer's status, which will change from A to B, in order to cancel it as a customer.
- Access your dictionary and then Objects/Definition/Objects.
- In the query screen, look for the form_sample object.
- Now that the object is on the screen, access the tab FORM.
- New tabs will appear on screen: access the tab ACTION.
- Create a label that will be associated with the button. In this case BUT_CANCEL_CUSTOMER.
In order to keep all BUTTON labels classified, it is advisable to keep the BUT prefix.
- For this example, we will use native SQL language to update the customer's status on screen to B. As it is explain at Business logic module, it can be used different languages to execute inline code or invoke catalogued functions.
UPDATE customer SET status = 'B' WHERE customerid = ${customerid}
5.1.1 Registering a button
Now we will create a button and we will associate it to the previous action.
- Access the tab BUTTON.
- Select the ACTION through the Action ID* field.
- Press the Insert button: the BUTTON has been created.
- Clean cache .
Now execute the object through the application, in this case form_sample in Demo Formación.
As a result, the form displays a button that will change the customer's status from A to B when pressed.
Please, watch this video to see the animation of the process.