creapage.net

HOWTO - Sashipa development

 SelectQueryBuilder.

You can find here general information about the selectQueryBuilder element.

Skeleton

A selectQueryBuilder element creates SQL select queries when the application is runing. The same element can define a complete query builder, or can be used for completing another selectQueryBuilder already created by a component. So it isn't always complete. For example, the Select statement is never specified in a listForm query because the listForm defines it.

Here is the skeleton of the selectQueryBuilder element:

  <selectQueryBuilder distinctRequired='no' type='list'>
    <castFilterSet>
      ...
    </castFilterSet>
    <selectStatementBuilder>
      ...
    </selectStatementBuilder>
    <fromStatementBuilder>
      ...
    </fromStatementBuilder>
    <whereStatementBuilder>
      ...
    </whereStatementBuilder>
  </selectQueryBuilder>

There are two attributes.

castFilters

A query is filtered (or not) with the filter of the current screen. A filter is a primary key value. A castFilter builds a criterion with the current filter, and adds it in the SQL Where statement. Built criterion are like 'pk_columns = filter', or 'fk_columns = filter' or a composition of sub-castFilters.

A list of castFilters is defined for the query. When the query receives a filter, it tries to match the first castFilter with the filter. If the first castFilter doesn't match, then query tries with the second, etc..

Here is an example:

  <castFilterSet filterSensitive='yes' autoCastFilter='yes'
                 stuckWhenNoFilter='no'>
    <fkCastFilter>
      <instanceFk schemaFk='fk_tblTravel_tblPerson' />
    </fkCastFilter>
    <pkCastFilter>
      <instanceTable schemaTable='tblTravel' />
    </pkCastFilter>
  </castFilterSet>

castFilterSet attributes are optional. In this example, they have all their default value.

Select statement

A Select statement contains column instances, group of column instances or SQL expressions. Here is a select statement that contains one element of each type. All work with a from statement contains 'tblPerson' as mainInstanceTable value.

  <selectStatementBuilder autoPrimaryKey='yes'>
    <instanceColumnList>
      <instanceColumn schemaColumn='tblPerson_Name' />
      <referencedUserKeyColumns join='inner'>
        <instanceFk schemaFk='fk_tblPerson_tblCountry' />
      </referencedUserKeyColumns>
      <agregatInstanceColumn type='count' schemaFk='fk_tblTravel_tblPerson'
                             letterCount='6' sort='desc'>
        <title>Travels</title>
      </agregatInstanceColumn>
      <instanceFk schemaFk='fk_tblPerson_tblSex' />
      <manualColumn>                 <!-- MySQL syntax -->
        <schemaColumnRef schemaColumn='tblPerson_NumeroInYear' />
        <contentOfExpression>ifnull(max(Numero_In_Year), 0)+1</contentOfExpression>
      </manualColumn>
    </instanceColumnList>
  </selectStatementBuilder>

In 'list' queries, primary key columns are automatically added in the Select statement. This can be disabled by setting the autoPrimaryKey attribute to 'no'.

An instanceColumn is a column of an instanceTable. So the element instanceColumn contains the instance table container, and the instance table must be into the from statement too. When the instanceTable element is omitted then the default instance of the schemaTable is used.

A referencedUserKeyColumns element adds column instances of a table userKey AND add a join in the From statement.

A agregatInstanceColumn element creates a computed column. Available types are:

A instanceFk element adds instance columns contained in a foreign key.

A SQL expression can be manually written in element manualColumn. When the element is used in the query for a default value in field of cardForm, the schemaColumnRef element must be the same as the field one. Be carefull: using this element can make your Sashipa code specific for only one dbms...

From statement

A From statement contains an element mainInstanceTable and a list of fkJoin for adding other tables:

  <fromStatementBuilder>
    <mainInstanceTable schemaTable='tblPerson' />

    <fkJoin join='inner'>
      <instanceFk schemaFk='fk_tblPerson_tblSex' />
    </fkJoin>

    <fkJoin join='left'>
      <instanceFk schemaFk='fk_tblPerson_tblCountry_Live'>
        <startInstanceTable schemaTable='tblPerson' />
      </instanceFk>
      <referencedInstanceTable schemaTable='tblCountry' nickName='countryLive' />
      <XxxCriteriaXxx> ... </XxxCriteriaXxx>
    </fkJoin>

    <fkJoin join='inner'>
      <instanceFk schemaFk='fk_tblPerson_tblCountry_Originate'>
        <startInstanceTable schemaTable='tblPerson' />
      </instanceFk>
      <referencedInstanceTable schemaTable='tblCountry' nickName='countryOrig' />
    </fkJoin>
  </fromStatementBuilder>

Each instance of table (elements mainInstanceTable, startInstanceTable, referencedInstanceTable) has a required attribute schemaTable, and an optional nicname.

Joins (elements fkJoin) have an attribute for the type (inner, left, right, full, nojoin). 'left' is more often used when the foreign key can be null, and 'inner' is used when the foreign key has always a value.

In an element fkJoin, instances of tables are optional because they can be deducted from the foreign key. So we define tables that need to be renamed in the SQL query. So in the example we could remove the startInstanceTable.

The criterion is optional too. It is added to the join criterion with a SQL 'AND'. Criteria are described below in the Where section.

Where statement

A Where statement contains a set of constantCriteria, manualCriteria, and/or criteriaBuilders. The separator is always a SQL 'AND'. For adding criteria with SQL OR, just put them in a criteriaBuilder with mode='or'.

Where statement: constantCriteria

You can manually specify a SQL criterion based on a column, for example:

  <whereStatementBuilder>
    <constantCriteria>
      <instanceColumn schemaColumn='tblContactaddress_ContactAddressLabel' />
      <endOfCriteria>is not null</endOfCriteria>
    </constantCriteria>
  </whereStatementBuilder>

The generated criterion will be the concatenation of the column instance and the content of element endOfCriteria.

The endOfCriteria content is open. But be carefull if you need to change your dbms later...

Where statement: manualCriteria

You can manually define a SQL criterion, for example:

  <whereStatementBuilder>
    <manualCriteria>
      <contentOfCriteria>ContactAddressLabel is not null</contentOfCriteria>
      <instanceColumnList>
        <instanceColumn schemaColumn='tblContactaddress_ContactAddressLabel' />
      </instanceColumnList>
    </manualCriteria>
  </whereStatementBuilder>

Remarks :

Where statement: criteriaBuilders

A criteriaBuilder is a criterion that contains a set of sub-criteria.

  <whereStatementBuilder>
    <criteriaBuilder mode='and' emptyAction='stuck'
                     defaultSubEmptyAction='ignore'>

      ... set of sub-criteria ...

    </criteriaBuilder>
  </whereStatementBuilder>

There are three attributes:

Where statement: researchCriteria

A researchCriteria is a dynamic criterion that will be built from a value of a field. Due to a limitation of Melba, a researchCriteria has to be contained by a criteriaBuilder. In the example are two researchCriteria: the first one takes value in a fkField, the second one takes value in a simple field:

  <whereStatementBuilder>
    <criteriaBuilder mode='and' emptyAction='stuck'
                     defaultSubEmptyAction='ignore'>

      <researchCriteria emptyAction='stuck'>
        <castSchemaValue>
          <fkCastFilter>
            <instanceFk schemaFk='fk_tblPerson_tblSex' />
          </fkCastFilter>
        </castSchemaValue>
        <fieldRef field='fieldFkSex' />
      </researchCriteria>

      <researchCriteria>
        <castSchemaValue>
          <instanceColumn schemaColumn='tblPerson_Name' />
        </castSchemaValue>
        <fieldRef field='fieldPersonName' />
      </researchCriteria>
      
    </criteriaBuilder>
  </whereStatementBuilder>

A researchCriteria element contains a castSchemaValue and a reference to a field defined in the same screen. This field has to be defined (in a cardForm or a researchForm for example) and named before to be referenced.

A castSchemaValue can work on primary keys or foreign keys (with a castFilter), or on a simple column (with a instanceColumn).

In this example, the first researchCriteria requires a value (emptyAction='stuck') and the criteriaBuilder will be stuck if 'fieldFkSex' doesn't return a value. The second researchCriteria will be ignored if the field 'fieldPersonName' is empty.

© Copyright 2003 Sashipa-Melba Team. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License as much as this note clearly appears.