Sashipa tutorials

 

For learning the Sashipa language:

  • Contents of this page will give you a theoretical approach.

  • Then you'll use the HOWTO as reference documentation.

 


 

The Sashipa tutorial

Precisions on conception for relational database

Introduction

Relational databases

Identities, correct fashions

DBMS Functions to avoid !

Overview of a Sashipa file

Environment

Graphical User Interface

General structure

The GUI components

Conception in Sashipa

The generated architecture

Annex

Glossary

 

Precisions on conception for relational database

Introduction

Sashipa is an XML language for describing database interfaces.

Here is a tutorial for teaching to write a first Sashipa software. It is based on the DemoContact database example. If you don't have already installed this database, please click here.

Relational databases

Just a few vocabulary: A relational database is a set of tables, and each table is composed of columns. Data is the rows. They are called records too.

A database is created, then used, with a standard language: the SQL.

Here is the SQL script for creating the DemoContact database:

    CREATE TABLE PROFESSION (
      ProfessionId integer NOT NULL PRIMARY KEY,
      ProfessionLabel varchar(100) NOT NULL UNIQUE
    );
    CREATE TABLE CONTACT (
      ContactId integer NOT NULL PRIMARY KEY,
      ContactName varchar(100) NOT NULL,
      ContactFirstName varchar(100) NOT NULL,
      Cell varchar(20),
      Email1 varchar(100),
      Email2 varchar(100),
      Comment text,
      ProfessionRef integer NOT NULL REFERENCES PROFESSION(ProfessionId),
      FunctionLabel varchar(100),
      InsertDate date,
      LastUpdateDate datetime not null,
      UNIQUE (ContactName, ContactFirstName)
    );
    CREATE TABLE CONTACTADDRESS (
      ContactAddressId integer NOT NULL PRIMARY KEY,
      ContactAddressLabel varchar(100) NOT NULL,
      IsProfessional bool NOT NULL,
      AddressStreet varchar(255),
      AddressPostcode char(5),
      AddressCity varchar(255),
      Tel1 varchar(20),
      Tel2 varchar(20),
      Fax varchar(20),
      Email varchar(100),
      ContactRef integer NOT NULL REFERENCES CONTACT(ContactId),
      UNIQUE (ContactRef, ContactAddressLabel)
    );

Identities, correct fashions

Each table has a primary key, often composed by one unique integer column (example: ProfessionId for the table PROFESSION). This column will be used only for identifying each row in the table. Data in this column has to never be updated after inserting. Otherwise, database may have integrity problems.

Primary key values are never displayed to the user. Otherwise, the user will use it for its own needs (for its paper folder, for example). And sooner or later, he would like to modify it.

The user needs to identify each row in the table. For this purpose, we use the database UNIQUE constraint. UNIQUE constraint works as a primary key, except that it doesn't allow to do links between tables. (example: ProfessionLabel for the table PROFESSION).

In summary, for each table, we have the database identity (the primary key) and the user identity (the UNIQUE constraint).

Links between tables are made with foreign keys that reference primary keys. Example: ProfessionRef in the table CONTACT, references the column ProfessionId in the table PROFESSION. It means that values we can find in CONTACT.ProfessionRef point on values in PROFESSION.ProfessionId. So we can retreive the profession for each contact.

DBMS Functions to avoid !

Be careful ! Don't declare the primary key as auto-increment. The application automatically compute auto-increment when inserting, if this field hasn't value. So you may have conflict if the DBMS tries to put its own value.

Second problem: generated applications have a buffer, for storing last loaded records. This buffer is refresh when the server-side (the servlet) reports an update that has been done by one of its client applications. So you will have problems of non up-to-date buffers if triggers or other external programs make update without the servlet.

More dangerous: the transaction management is done at the servlet level. Not at the DBMS level. So if an external program updates data without using of the servlet, you can have integrity problems.

 

Overview of a Sashipa file

You can see the source code here.

First I show you the skeleton of the Sashipa DemoContact application.

    <?xml version='1.0' encoding='ISO-8859-1' ?>
    
    <!DOCTYPE application SYSTEM 'resources/sashipa.dtd' [
      <!ENTITY br '&#xA;'>
      <!ENTITY nbsp '&#x20;'>
      <!ENTITY frenchDefinition SYSTEM 'resources/SashipaFrench.xml'>
      <!ENTITY englishDefinition SYSTEM 'resources/SashipaEnglish.xml'>
    ]>

    
    <application name='AppliContacts'>
    
    <!--........ environment ........ -->
    
    <environment>
    <!-- ... description des SGBD et de leurs bases ... -->
    </environment>
    
    <!--........ graphicalUserInterface ........ -->
    
    <graphicalUserInterface name='guiContact'>
    <!-- ... description de l'interface utilisateur ... -->
    </graphicalUserInterface>
    
    <!--........ dataAccessStage ........  -->
    
    <architecture guiType='application'>
    <!-- ... description de l'accès au serveur ... -->
    </architecture>
    
    </application>

The main parts of this XML file are:

  • The description of the DemoContact database server environment structure
  • The description of the graphical user interface
  • The description of your application architecture.

 

Environment

The first part of a Sashipa document is a server environment description of the data structure. The server name is stored in the <physicalName> element.

NB: the name 'dbmsMain' is an internal name for internal needs into the Sashipa file. It's used when elements of the document reference this dbms. It's a common comportment for each element in Sashipa: the attribute 'name' is used only for identifying it into the Sashipa file. It isn't the real (i.e. physical) name.

    <environment>
      <dbmsSet>
      <dbms name='dbmsMain'>
        <physicalName>localhost</physicalName>
        <databaseSet>
    
        <!-- ... description des bases de données  ... -->
        
        </databaseSet>
      </dbms>
      </dbmsSet>
    </environment>

Here is described the DemoContact database. I show you the description for the table 'PROFESSION', and then the CONTACT.ProfessionRef column, for an example of foreign key.

    <database name='dbContact'>
      <physicalName>DemoContact</physicalName>
      <singularName>Base des Contacts</singularName>
      <schemaTableSet>

      <!-- ............. PROFESSION ............. -->

      <schemaTable name='tableProfession'>
        <physicalName>PROFESSION</physicalName>
        <singularName>Profession</singularName>
        <pluralName>Profession(s)</pluralName>
        <schemaColumnSet>
        <schemaColumn name='pro_ProfessionId' type='integer' 
                      notNull='yes' pk='yes'>
          <physicalName>ProfessionId</physicalName>
          <singularName>Identity</singularName>
        </schemaColumn>
        <schemaColumn name='pro_ProfessionLabel' type='text' notNull='yes' 
                      maxCharacters='100'>
          <physicalName>ProfessionLabel</physicalName>
          <singularName>Profession</singularName>
          <guiConfigSchemaColumn letterCount='20' sort='asc' />
        </schemaColumn>
        </schemaColumnSet>
        <userKey>
          <userKeyColumn schemaColumn='pro_ProfessionLabel' />
        </userKey>
      </schemaTable>
      
      <!-- ............. CONTACT ............. -->

      <schemaTable name='tableContact'>
        <!-- ... -->
        <schemaColumn name='cta_ProfessionRef'
                      type='integer' notNull='yes'>
          <physicalName>ProfessionRef</physicalName>
          <singularName>Profession</singularName>
        </schemaColumn>
        <!-- ... -->
      </schemaTable>

      </schemaTableSet>

      <!-- ............. db - foreign key ............. -->

      <schemaFkSet>
        <schemaFk name='fk_cta_Profession'
                  sourceSchemaTable='tableContact' 
                  targetSchemaTable='tableProfession'>
          <schemaColumnRef schemaColumn='cta_ProfessionRef' />
        </schemaFk>
        <!-- ... -->
      </schemaFkSet>
    </database>

 

Graphical User Interface

General structure

Here is the general structure of a Sashipa GUI.

    <graphicalUserInterface name='guiContact'>
    
    <resourceName>Contact</resourceName>
    
    <mainTitle>[Contact]</mainTitle>
    <separatorTitle> - </separatorTitle>
    <size w='800' h='600' />
    
    <guiStarting>
      <loadingScreen>
      <mainScreenRef screen='SMMain' />
    </guiStarting>

    <screenSet>
    <!-- ... liste des Screens ... -->
    </screenSet>

    <formSet>
    <!-- ... liste des Forms ... -->
    </formSet>

    </graphicalUserInterface>

Important: the <resourceName> element contains the name of the main class of the application. In our case, the internal Java command for launching your future application will be "java Contact".

The <mainScreenRef> element references the first screen that will be displayed when the application will be launching.

The GUI components

The database interface appearance is strongly dependent to the database structure (schema). Sashipa distinguishes three levels for interface components: screens, forms and fields.

I recommend watching the source code for concretely see examples, because I don't give any XML source code here.

Screens

A database interface software displays a sequence of screens. The software will display only one screen at the same time.

Forms

A screen is a container of forms. For each table, we'll have the following forms:

  • A form for reading / updating / adding, that works on one record by one record in the table. This is the cardForm.
  • A list for displaying a sub-set or the entirely table content. This is the listForm.
  • A form for researching records in the table. This is the reasearchForm. Note that it uses a listForm for displaying research results.
  • For big tables referenced by foreign keys, we need a form for selecting one row in the table: this is the selectRecordForm. It's based on a researchForm.

Another sort of form is the menuForm. The menuForm isn't dependent of a table. It's used to allow opening of others screens.

Fields and FkFields

cardForms and researchForms are based on a field container. A field container can display values of one row. There are two field categories:

  • Simple fields (field) can display a value for a column of the main table of the form.
  • Foreign key fields (fkField) allow user to select a row in the referenced table.

Here is the list of available fields:

  • the textField displays the value as a text.
  • The textAreaField displays the value as a multi-lines text.
  • The checkBoxField displays a booleen value as a check-box.

Then the available fkFields list:

  • The comboBoxField for a mouse selection.
  • The writeChoiceField for a mouse selection or a keyboard selection by auto-completment.
  • The readOnlyTextField displays only the selected row, but not allows selection. You have to use it with the selectRecordForm for selecting a referenced row in a big table.

Conception with Sashipa

Here is a theorical overview on how to deduce a GUI from a database structure.

Foreign keys and GUI.

Look at the tables CONTACT and CONTACTADDRESS. The table CONTACTADDRESS has a foreign key, composed of one unique column ContactRef that references the column CONTACT.ContactId.

A classical user interface will be:

Screen 1: A menu (menuForm) with at less one button for opening the screen 2.

Screen 2: A listForm that contains all the rows of the table CONTACT. By double-clicking on a row, we open the screen 3.

Screen 3:

  • A cardForm for displaying each values of the CONTACT row
  • A listForm that contains all the addresses for the current contact. By double-clicking on a row, we open the screen 4.

Screen 4: A cardForm to display each values of the CONTACTADDRESS row. In the cardForm, we will have a fkField to display / choose the referenced contact.

More generally, a foreign key imply:

  • For the referenced table: a listForm for dependent table rows in the same screen that the cardForm.
  • For the dependent table: a fkField in the cardForm.

Filters

A filter is, for Sashipa applications, a primary key value.

When the software opens a screen, the software suggests a sorted list of filters to the screen, and the current filter. After that, the screen can modify the current filter with buttons 'next' and 'previous'.

When the screen has a new filter, it dispatches it to all sub-forms. Each form has its own comportment:

  • cardForm wait for a primary key value of its main table. The filter is the identity of the row that it works on. If the filter misses, the cardForm becomes in 'adding' mode. If the filter exists, but it isn't a primary key value of the main table, then a fatal error is thrown. Filter is dispatched to each fkFields.
  • listForm wait for a primary key value that is referenced by one of the foreign keys of its tables. Or a primary key value of its tables. If the filter doesn't match, it is ignored. (So the list isn't filtered).
  • researchForm just dispatches the filter to the result listForm, and to its fkFields too. That means that when there is a filter, the researchForm makes research in a sub-set of the table.
  • selectRecordForm gives the filter to its based-on researchForm. So, ditto.
  • menuForm transmits the filter as an opening parameter to the screen that user decides to open.

fkFields are sensitive to filters, too. In 'update' mode, their comportment is the same than a listForm. In 'insert' (adding) mode, they are sensitive only when the filter is a value of the target primary key.

Note: theses are default comportments. They can be customized with castFilter elements.

 

Architecture

All specifical informations of your environment are described here: the DBMS type, the database connection informations (login, password, ...), etc..

    <architecture guiType='application'>
      <dbAccessStage database='dbContact' architecture='clientDatabase'>
        <dbConnection type='odbc' dbmsType='MySQL'>
          <dbConnectionString>
              DRIVER=MySQL;HOST=localhost;DB=DemoContact
          </dbConnectionString>
          <user>root</user>
          <password></password>
        </dbConnection>
        <dbAccessLog>
          <filenameLogMain>Melba_Main.log</filenameLogMain>
          <filenameLogUpdate>Melba_Update.log</filenameLogUpdate>
        </dbAccessLog>
        <specificToServer>
          <serverResourceName>ContactServlet</serverResourceName>
          <serverConnectionString type='url'>
            http://localhost:8080/servlet/ContactServlet
          </serverConnectionString>
        </specificToServer>
      </dbAccessStage>
      <defaultDbAccessLog>
        <filenameLogMain>Melba_Main.log</filenameLogMain>
        <filenameLogUpdate>Melba_Update.log</filenameLogUpdate>
      </defaultDbAccessLog>
      <languageDefinitionSet mainLanguageDefinition='french'>
        &frenchDefinition; &englishDefinition;
      </languageDefinitionSet>
    </architecture>

Note the attribute guiType='application'. That means that an application will be created. For an applet, just change it to guiType='applet'.

The attribute database='dbContact' references the database that is described in the environment part.

The attribute architecture='clientDatabase' means that the generated application architecture is client-database. For building a client-servlet-database architecture, just change it to architecture='clientServerDatabase'. However generated files are put in one unique archive. So you will have to manually unarchive if you want to separate the servlet-side and the client-side.

NB: the element <specificToServer> is used for an 'client-servlet-database' architecture only. Otherwise it is ignored. We can describe here the class name of the servlet, and the url used by the client for accessing the servlet.

Log files are described here, too.

Last but not the least, you choose the language for your application.

I hope this technology will be usefull.

Thomas

 

Annex

Glossary

Relational database

A logical set of inter-dependent tables. They are stored in a Relational DBMS. We can query them with SQL queries.

GUI

Graphical User Interface.

Relational DBMS

Relational Database Management System. This is a server software for storing relational databases.

SQL

Structured Query Language. This is a standard for query relational databases.

Referetial integrity

In a relational database, foreign keys make links between tables. The referential integrity is the mechanism that guarantees that the referenced data is really existing. For example, each AdressContact references an existing Contact.

Foreign key

In a relational database, foreign key is a set of columns in a table, that references the primary key of another table (or the same).

Primary key

In a relational database, primary key is the set of columns in a table, that identify each row.

User key

The user key of a table is the set of columns that identify each row for user needs. Note that it isn't a term of the database world.