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?"
(
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
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
Annotation | Scope | Description |
@Entity | class | Attribute "name" = table name |
@Column | field | Attribute "name" = column name |
@Id | field | Primary 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.
'StarPerson' Entity Class
perfect-match2.taq writes a list of clients of a match maker agency to a "star-people" database. Included is each person's Zodiac sign. A "StarPerson" entity class has been created to provide the plan for a "StartPerson" database table. These are the @Column fields
Name | Java Type | @Column Attribute |
name | String | name="name" |
age | long | name="age" |
starsign | entities_axiom.Zodiac | name="starsign" |
rating | double | name="rating" |
timestamp | java.time.Instant | name="timestamp" |
This class features types which require a special approach to data persistence:
enumeration
Type 'Zodiac' is an enumeration of the 12 signs of the Zodiac. A Zodiac constant is persisted as a string, the value being the Zodiac name. This name is converted back to a Zodiac enumeration when the StartPerson table is queried.
double
Primitive type double (and it's Double wrapper) is persisted as a long value set to the bits which represent the double value. This preserves the precision of Java double values and special values "NaN" and "Infinity".
Instant
Type java.time.Instant is an example of a class which implements interface java.lang.Serializable. All serializable objects are persisted as byte arrays and readily recovered using deserialization. Note that there is no support for any object which is neither mapped to an TAQ type nor serializable.
Entity Agents
The database resource framework has two agents that perform database operations with entity classes. One is called a "collector", an agent for performing read operations and the other is called an "emitter" which performs write operations. These agents can be extended in order to customize their behavior, for example, working with two database tables which have an association with each other.
"AgriAreaPercent" Entity Class
agriculture-report.taq finds all countries which have increased the area under cultivation in the twenty-year interval between 1990 and 2010. Input data comes from 208 countries with 5 data points per country. Data for some years is not available and this is indicated using the double value 'NaN' (not a number).
The AgriAreaPercent entity class models the "AgriAreaPercent" database table which contains the input data for the report. It has the following @Column fields
Name | Java Type | @Column Attribute |
country | String | name="country" |
surfaceAreaKm2 | double | name="surface_area_Km2" |
y1970 | double | name="Y1970" |
y1980 | double | name="Y1980" |
y1990 | double | name="Y1990" |
y2000 | double | name="Y2000" |
y2010 | double | name="Y2010" |
Here we have the name of a country, it's surface area in square kilometers and "under cultivation" percentage values sampled over 5 decades. In all but one field, the term name differs from the field name, for example, "surface_area_Km2" is the table/axiom name for field "surfaceAreaKm2",
A second entity class named Agri20Year models the "Agri20Year" table of the report database. This defines country and surface area fields
Name | Java Type | @Column Attribute |
country | String | name="country" |
surfaceArea | double | name="surface_area |