Template-Axiom-Query (TAQ)

Axioms and Entities

TAQ features relational database support so an applications can reliably persist data over time. A resource provider, dedicated to this purpose, can connect to a relational database and perform statements and queries using SQL. In order to perform it's role as a resource provider, it maps the rows of database tables to axioms. Although there is a high level of automation, some Java development is required in order to cross the divide between SQL and TAQ. The default database product is H2. Sqlite is also supported.

Database Resource Provider

The Database resource provider is identified by having a "database" property set in the resource declaration The database value is a path containing a name and location, an example being database=db/cities" for a database name of "cities" in a location of "db" relative to the application workspace. An absolute location can also be used for the case the database already exists. Note that the actual file name for a newly created database may include an extension added by the database driver,

Here is the declaration for a resource to access a "cities" database with user = "sa" and password = "secret?"

resource cities(database="db/cities") {}
(
cities.set(user="sa", password="secret?")
)

Database resource method set() configures connection properties. It appears in the resource declaration to take effect before the database connection is established.

This is not a typical database resource declaration because there are no resource roles configured as indicated by the empty braces. This omission of roles is to show that such a configuration is still useful for a function provider that needs to connect to a database.

No Resource Roles

A database resource without roles does create the database, if it does not already exist. The connection details are then available to any function provider which wants to access that database. An example of such a declaration is in a program called "show-cities.taq" which has a "print" function to display the database contents. When the program is run before the database has been created, this error is displayed

Table "CITY" not found (this database is empty); SQL statement:
SELECT `id`, `name`, `altitude` FROM `City` [42104-214]

This indicates that the database resource provider created an empty database to which the print function successfully connected and failed while running the SQL query shown on the second line of the message. Run cities.taq to populate the cities database and show-cities.taq displays 10 cities with ids ranging from 1 to 10.

Entity Class

The cities.taq resource declaration has this data consumer role

template city -> "entities_axioms.City"

This role introduces the first example of Java development required for a database resource to access a database table, in this case, an entity class named "City". An entity class is a Java bean with annotations from the Java Persistence API] (JPA) applied to create a plan of a database table. There are 3 annotations that are relevant

AnnotationScopeDescription
@EntityclassAttribute "name" = table name
@ColumnfieldAttribute "name" = column name
@IdfieldPrimary key - always named "id"

@Id designates the primary key. A convention applies in order to keep things simple. The primary key must be a field of integer type named "id". Pleas refer to the entity classes in the examples project to see these annotations in action.

Entity Fields

Each entity class field representing an axiom term has a @Column annotation which maps both to an axiom term and a table column. To configure an axiom term name consistent with TAQ conventions A 'name' attribute is normally applied to the column annotation. In the case the database already exists and cannot be modified, the term name can also be configured independently of the entity class by using a name mapping feature of the database resource framework.

Entity Examples

The first two examples demonstrate the minimum Java development case where only a single entity class is required by a TAQ program. The next two examples deal with cases where the database resource provider has to be extended in order to cross the SQL/TAQ divide. These examples indicate the framework on offer is adaptable beyond working with a single database table.

'City' Entity Class

The "City" entity class previously referenced in cities.taq defines the following fields

NameJava Type@Column Attribute
nameStringname="name"
altitudelongname="altitude"

In this case Java field names and TAQ term names are identical. The Java types String and long map to TAQ string and integer respectively.

high-cities-sorted3.taq reads a list of cities from the "cities" database and writes the solution to a "sorted-cites" database.There is a separate resource declaration for each database

resource data_source : "cities"
(database="db/cities")
{
"entities_axioms.City" ->
axiom city(altitude, name)
}

resource data_consumer : "sort_cities"
(database="db/sorted-cities")
{
list global.insert_sort.high_cities ->
"entities_axioms.City"
}

Notice that the "cities" data-source role has the 'name' and 'altitude' terms in reverse order to the corresponding entity fields. This has been done deliberately to point out that the order of the data-source terms is is determined by the role and not the entity fields.

As the same entity is applied to both resources they both create databases with the same layout. Run show-high-cites.taq to see the contents of the "sorted-cities" database:

Exported cities:

1 denver,5280
2 flagstaff,6970
3 addis ababa,8000
4 leadville,10200

List Data-consumer

A list data-consumer role in the "sort_cities" resource declaration is used in place of customary template to delay list contents being persisted until completion of the sort query.