Tabulator comes with a set of examples. Each is designed to illustrate various features/capabilities of the Tabulator framework.
Each example builds to produce a .zip
file,
which is then unzipped somewhere to install it.
Here we assume unzipping to /tab_<example-name>
.
Music Database
The data is stored in a .json
file, 2 .csv
files
and an .xml
file.
This examples uses
JSON file,
flat-file and
XML file sources to access them.
As a result, it has no external dependencies.
Regardless of whether you have QPid, MariaDB or MarkLogic Server, or not,
you should be able to run this example.
$ /tab_music/bin/TabulatorServer
The "album" type has an attribute called "year" which is a part of an attribute group called "extras".
The 4 "Type" classes provide navigations between each other, primarily based upon whether you are looking at a "list" or "show" page.
This example shows off the role based security in the web application.
The guest
user isn't able to view the "review" type.
Only andy
can do this.
A Type named T
is accessible to a user if the user has a
role called type.T
, the role types.*
or a role
which has been added to the Type with the addRole
method.
Complex JSON
The data is stored in a single complex.json
file,
which as the name suggests, is quite complicated.
The example shows off many of the features of the JSON file source.
$ /tab_json/bin/TabulatorServer
This example assumes you have MariaDB installed, listening on its default port (3306).
$ /tab_orders/bin/TabulatorServer
The sample comes with a couple of .sql
files.
One file is to be used to set up the database and populate it with some
content, the other cleans out the content.
Read the comments at the start.
The comments describe setting up a database called order_db
and a user called order
with password password
.
This corresponds to the values in the sample code "Configuration" class.
The sample .sql
files are MariaDB specific.
However, a file orders.xml
is also included which is a database
configuration file.
DBSetup
can be used to read this file and generate create and drop scripts which work
on MySQL (and thus MariaDB), Oracle or Sybase.
The example configuration instantiates 2 "Type" classes, one for "order" and one for "item".
The "order" type is a simple binding of attributes to columns in the ORDERS table.
$ mysql --user root --password Enter password: mysql> use order_db ; mysql> select * from ORDERS ; +----+-------------+ | id | customer | +----+-------------+ | 1 | Wile Coyote | | 2 | Roadrunner | +----+-------------+ 2 rows in set (0.00 sec)
The "item" type is a little more sophisticated. Most of its attributes are simple bindings of attributes to columns in the ITEMS table.
mysql> select * from ITEMS ; +----+----------+--------------------+ | id | order_id | description | +----+----------+--------------------+ | 10 | 1 | Acme explosives | | 11 | 1 | Acme rocket sledge | | 12 | 1 | Medical insurance | | 20 | 2 | Bird seed | +----+----------+--------------------+ 4 rows in set (0.00 sec)
However, it implements an attribute group called "Customer". If this is selected, we also have an additonal attribute called "customer". This attribute does not come from the ITEMS table, it actually comes from the ORDERS table. Put another way, the "customer" shown on the "item" is actually the "customer" from the "order" the "item" is a part of. ie: its a denormalised or JOINed view. So in this case, the query done is actually for the JOIN of the ORDERS and ITEMS tables.
mysql> select i.id,i.order_id,i.description,o.customer -> from ITEMS i LEFT JOIN ORDERS o ON i.order_id = o.id ; +----+----------+--------------------+-------------+ | id | order_id | description | customer | +----+----------+--------------------+-------------+ | 10 | 1 | Acme explosives | Wile Coyote | | 11 | 1 | Acme rocket sledge | Wile Coyote | | 12 | 1 | Medical insurance | Wile Coyote | | 20 | 2 | Bird seed | Roadrunner | +----+----------+--------------------+-------------+ 4 rows in set (0.00 sec)
Because the query is using column name aliases, the example uses a mapping from attribute names (as known to Tabulator) and SQL column names (including the alias prefixes).
Note: The code is configured to use the MariaDB JDBC driver and JDBC URL,
but some of the text above was captured running on MySQL.
Fishy Database
This example shows off the XCC source.
This example assumes you have MarkLogic Server installed.
$ /tab_fishy/bin/TabulatorServer
The sample comes with an .xqy
file which includes comments on
how you should set up MarkLogic, and how you should execute the file to
populate it with sample data.
The example configuration instantiates 3 "Type" classes, one for a type of "fish", one for an "environment" in which fish may be found and one called "environmentResident" which records the numbers of a given fish type found in an environment.
One of the fish documents looks like this :-
<fish> <variety>koi</variety> <cost>120</cost> <length units="cm">30</length> <length units="inch">12</length> <description>Exotic. Often Japanese. Beautifully coloured.</description> </fish>
One of the environment documents looks like this :-
<environment> <name>pond</name> <residents> <resident> <fish>koi</fish> <number>20</number> </resident> <resident> <fish>english-koi</fish> <number>2</number> </resident> </residents> </environment>
Note that the environment document includes details of the environment (ie: the fact it is named "pond"), and a repeating block, one per resident fish type in that environment. Its quite common for a single document to represent a hierarchy like this.
The code for the "fish" type takes advantage of the fact the URIs for the
fish documents are named fish/
followed by the variety.
This speeds up searching if we know from the start what documents to fetch.
There is a convention for environment document URIs too, but the supplied
code doesn't exploit this.
The sample only cares about fish lengths in centimetres.
However, one of the fish also has a measurement in inches.
Because the units are encoded in an attribute,
it's not possible to construct a precise query to search on it.
Therefore this code can fetch more fish than is necessary,
but conveniently the SourceXCC.search()
method filters out
the false positives.
The "fish" type provides an
extended navigation
which displays the raw XML page corresponding to a variety of fish.
To do this, it uses a low-level method in the
XCC source called
searchResultItems
and streams the data directly to the browser.
The Fishy Database example shows how named type group(s) can be created
and types associated with them.
This causes a different presentation on the home page of the web interface
whereby all buttons for types in the same type group are grouped together
on the same line, thus reducing screen clutter.
In this example, it is assumed you have QPid running, with RMI port
8999 and the The example simply instantiates the JMX variants of the
QPid queue type and the
QPid message type.
In this example, it is assumed you have QPid running,
with an The problem with using normal HTTP access is that QPid (quite sensibly)
won't let you use basic authentication (you can enable this), or see
message headers or content (you can't enable this).
The example simply instantiates the REST based variants of the
QPid queue type and the
QPid message type.
QPid JMX
admin
userid with admin
password.
These values can be changed in the "Configuration" class.
$ /tab_qpidjmx/bin/TabulatorServer
QPid REST
admin
userid with admin
password.
You need to have configured a "HTTP" listener using SSL on port 8443.
You'll probably be using an internally generated self-signed certificate,
and it'll need to be exported to SelfSigned.jks
.
This file has an empty (ie: zero characters long) keystore password.
These values can be changed in the "Configuration" class.
$ /tab_qpidrest/bin/TabulatorServer