The project "Sashipa-Melba" is stopped since 2005. The project sources are available for downloading.
I'm now a Webmaster: I create Web sites from Benin.
For learning the Sashipa language:
The Sashipa tutorial
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.
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)
);
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.
Be careful ! about auto-incremented primary key, these columns are not supported by Sashipa-Melba for all DBMS. But you can fixe that easily, cf the HOWTO. You can also declare a primary key column as a simple 'integer'. A value will be automatically computed by the software when inserting.
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.
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 '
'>
<!ENTITY nbsp ' '>
<!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 of the user interface ... -->
</graphicalUserInterface>
<!--........ servers ........ -->
<serverSet guiType='application'>
<!-- ... description of the Sashipa servers and connections
to DBMS ... -->
</serverSet>
<!--........ architecture ........ -->
<architecture>
<!-- ... description of deployment and used language ... -->
</architecture>
</application>
The main parts of this XML file are:
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'>
<schemaColumnSet>
...
<schemaColumn name='cta_ProfessionRef'
type='integer' notNull='yes'>
<physicalName>ProfessionRef</physicalName>
<singularName>Profession</singularName>
</schemaColumn>
</schemaColumnSet>
...
<schemaFkSet>
<schemaFk name='fk_cta_Profession'
targetSchemaTable='tableProfession'>
<schemaColumnRef schemaColumn='cta_ProfessionRef' />
</schemaFk>
</schemaFkSet>
</schemaTable>
</schemaTableSet>
</database>
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 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.
A database interface software displays a sequence of screens. The software will display only one screen at the same time.
A screen is a container of forms. For each table, we'll have the following forms:
Another sort of form is the menuForm. The menuForm isn't dependent of a table. It's used to allow opening of others screens.
cardForms and researchForms are based on a field container. A field container can display values of one row. There are two field categories:
Here is the list of available fields:
Then the available fkFields list:
Here is a theorical overview on how to deduce a GUI from a database structure.
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:
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.
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:
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.
All informations about servlets and databases connections that will be used are described here.
<serverSet>
<server name='srvDemoContact' type='servlet'>
<dbConnection database='dbDemoContact' type='odbc' dbmsType='MySQL'>
<dbConnectionString>
DRIVER=MySQL;HOST=localhost;DB=DemoContact
</dbConnectionString>
<user>root</user>
<password></password>
</dbConnection>
<configStorage>
<configDbStorage database='dbDemoContact' sashipaConfigStorage='cfgMain' />
</configStorage>
<logStorage>
<mainLog><logFileStorage>
<uri>Melba_DemoContact_Main.log</uri>
</logFileStorage></mainLog>
<updateLog><logFileStorage>
<uri>Melba_DemoContact_Update.log</uri>
</logFileStorage></updateLog>
</logStorage>
<specificToServlet>
<servletResourceName>DemoContactServlet</servletResourceName>
<servletUrl>
http://localhost:8080/servlet/DemoContactServlet
</servletUrl>
</specificToServlet>
</server>
</serverSet>
The attribute type='servlet' means that the generated application architecture is client-servlet-database. For building a client-database architecture, just change it to type='embeddedInGui'.
The attribute database='dbDemoContact' references a database described in the environment part.
NB: the element <specificToServlet> 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.
All specifical informations about the deployment of GUI instances are described here:
<architecture guiType='application'>
<guiInstance gui='guiDemoContact' type='application'>
<guiResourceName>GuiDemoContact</guiResourceName>
<usedConfigStorage server='srvDemoContact' />
<usedServerForDatabase server='srvDemoContact' database='dbDemoContact' />
</guiInstance>
<languageDefinitionSet mainLanguageDefinition='english'>
&frenchDefinition; &englishDefinition;
</languageDefinitionSet>
</architecture>
Note the attribute type='application'. That means that an application will be created. For an applet, just change it to type='applet'.
Last but not the least, you choose the language for your application.
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. |