Dataset Definition
A dataset is a single conceptual “model class” within your application. It is defined in a .XML
file and it provides a matching set of insert
/update
/delete
/fetch
methods.
Jarvis was originally developed to support relational databases using the DBI/DBD drivers, and some of that legacy is still visible despite the fact that it now supports non-SQL database agents including SDP and MongoDB.
This chapter describes the common and general features of datasets.
The subsequent chapter specifically describes how to use SQL-style datasets with DBI.
The boat_class.xml
file we are using for our SQL-based relational DB examples is as follows:
<dataset read="*" write="*">
<transform fetch="notnull" store="trim,null" />
<select>
SELECT id, class, active, description
FROM boat_class
ORDER BY class
</select>
<update>
UPDATE boat_class
SET class = {$class},
active = {$active},
description = {$description},
change_user = {$__username},
change_date = datetime ('now')
WHERE id = {$id};
</update>
<insert returning="yes">
INSERT INTO boat_class (class, active, description, change_user, change_date)
VALUES ({$class}, {$active}, {$description}, {$__username}, datetime ('now'));
</insert>
<delete>
DELETE FROM boat_class
WHERE id = {$id};
</delete>
</dataset>
Nothing the use of the following features:
We use <transform>
element to request that data is pre-processed before fetch and save. The transform tag is described elsewhere. However, in this case we have requested the following transform options:
- On fetch, any
NULL
value fetched from the database is represented as a zero length string in the returned structure to the user. - On store, leading and trailing white space should be removed before saving to database.
- On store, empty strings from the client should be stored as
NULL
in the database.
Per-dataset <hook>
configuration can inject Perl code for additional processing of inputs and outputs at predefined points of the operation.
There is a single fetch
(i.e. the <select
>) SQL configuration. But for store
we have three separate SQL statements, one for each of <insert>
, <update>
, and <delete>
. For SQL-style datasets these are SQL statements. For non-relational agents they have a different structure.
For DBI datasets, two additional SQL parameters are supported:
<before>
execute an SQL statement once before any store requests are performed.<after>
execute an SQL statement once after any store requests are performed.
See DBI Datasets for more information.
Dataset Attributes
The top-level attributes of all datasets definitions are as follows.
Attribute | Default | Notes |
---|---|---|
dbname |
default |
Specify which database connection should be used for fetching and storing this dataset. By default, the database named default is used for executing the set. |
read |
<empty> |
Defines which groups may execute the SQL defined in the select element. See subsequent notes. |
write |
<empty> |
Defines which groups may execute the SQL defined in the update , insert and delete elements. |
debug |
no |
Enables debug on a per-dataset basis. |
dump |
no |
Enables dump on a per-dataset basis. |
filename_parameter |
filename |
Specifies the user-supplied parameter which specifies the filename for the returned attachment when requesting contents to be returned in csv for xlsx format. |
Dataset Elements
The elements within the <dataset>
definition are as follows:
Element | Notes |
---|---|
transform |
Optional transformations for Jarvis to perform when storing or fetching data. Supported for all dataset types. |
hook |
One or more hook module definitions. Definition is identical to global hooks. Supported for all dataset types. |
child |
One or more child dataset definitions. See chapter on Nested Datasets. Supported for all dataset types. |
select |
Parameters to use when dataset is invoked with the http GET request method, or with an override transaction type select . See agent-specific description of content. |
before |
Parameters to use for a one-off action to be performed before applying update /insert /delete changes. Currently supported for DBI only. |
after |
Parameters to use for a one-off action to be performed after applying update /insert /delete changes. Currently supported for DBI only. |
update |
Parameters to use when dataset is invoked with the http PUT request method, or with an override transaction type update . |
insert |
Parameters to use when dataset is invoked with the http POST request method, or with an override transaction type insert . |
delete |
Parameters to use when dataset is invoked with the http DELETE request method, or with an override transaction type delete . |
merge |
Parameters to use when dataset is invoked with the http PATCH request method, or with an override transaction type merge . |
Note: For select
/before
/after
/update
/insert
/delete
/merge
Implementation is specific to the database agent. For DBI databases these are SQL statements. For MongoDB these are object definitions with variables. For SDP these are MDX queries.
Note: Data store operations are not supported for SDP, and that MongoDB does not support before/after statements.
Element | DBI | SDP | MongoDB |
---|---|---|---|
transform |
YES | YES | YES |
hook |
YES | YES | YES |
child |
YES | YES | YES |
select |
YES | YES | YES |
before |
YES | NO | NO |
after |
YES | NO | NO |
update |
YES | NO | YES |
insert |
YES | NO | YES |
delete |
YES | NO | YES |
merge |
YES | NO | NO |
Access Identifiers
The access identifiers controlling Dataset are the same list of options as is used for the access control of exec
and plugin
datasets.
Specifically, the access identifier may be one of the following:
Access ID | Notes |
---|---|
<empty> |
Nobody may access these statements. |
<g1>[,<g2>...] |
A comma separated group list. Membership in any one of these groups will grant access. |
* |
Any logged-in group may access this feature. |
** |
Any user, even if not logged-in, may access this feature. |
Parameter Expansion
All of the database agents support variables within their SQL, MDX, or operation objects.
Regardless of the type of agent, the values for these parameters are sourced from the same set of parameter sources, which is the following:
- Client-Supplied Parameters.
- Server-Only Safe Parameters.
- Default Parameters.
Client-Supplied Parameters
Client-Supplied Parameters are checked in the following order:
- Parent Parameters (for linked child datasets only).
- Object attributes from the JSON or XML request body.
- Named/Numbered REST parameters from the Route.
- URL parameters e.g.
?name=value
.
Server-Only Safe Parameters
When supplying user variables via CGI GET and via JSON/XML request body, the parameter names must be limited to alphanumeric, plus underscore, colon and hyphen. They may contain a single leading hyphen, but not two. The first non-hyphen character must be [a-zA-Z]
. Parameter names are always case-sensitive.
E.g. the following are invalid as user-supplied parameter in a Jarvis dataset request:
my(param)
__my_param
_1param
1
The reason for the limitation on numeric parameters is to avoid conflict with the indexed RESTful parameters which are named simply 1
, 2
, etc.
The reason for the limitation of the leading double-underscore is because all parameters beginning with double-underscore are secure parameters, supplied by Jarvis.
A number of standard built-in
parameters are generated by the login process. The built-in safe parameters available to be substituted into SQL statements are:
Attribute | Notes |
---|---|
__username |
The logged-in username. Never the empty string. |
__group_list |
The comma separated group list. May be empty string. |
__group:<g1> |
Evaluates to 1 if the user is in group <g1> . NULL otherwise. |
__group:<g2> |
Evaluates to 2 if the user is in group <g2> . NULL otherwise. |
In addition, safe parameters may come from the following other sources:
- Login modules may define additional safe parameters, e.g.
{$__user_id}
. - Hooks may define additional safe parameters.
- Default Parameters defined in the application config file may be safe parameters.
Remember. Client-supplied values will never be allowed to modify these safe parameters.
The following pattern is common in SQL for Jarvis datasets. Imagine that table t
contains records owned by the username defined in column t.owner
. Users in group admin
may read and write all records. Other uses may see (read-only) just their own records.
<dataset read="*" write="admin">
<select>
SELECT * FROM t WHERE (owner = {$__username}) OR ({$__group:admin} IS NOT NULL)
</select>
</dataset>
Default Parameters
Any parameter may be given a static default value using the default_parameters
element within the application configuration file.
Within the default_parameters
element is one or more parameter
elements.
Attribute | Notes |
---|---|
name |
Specifies the name of the parameter to made available to processing. |
value |
If not supplied by the client or the server, this value will be used. It is not possible to specify <undefined> as a fallback value. |
Default parameter values may also be specified for safe
variables (i.e. with names that begin with double underscore). These safe variables may only be modified by the server code, and can never have their values specified by the client.