ort(5) to output
ort(5) to output

openradtool (ort) is an open source RAD tool generating front-end code (JavaScript, TypeScript) and back-end code (SQL, C) for your application, leaving you to develop your middle-tier business and presentation logic.

The system consists of a set of source generators, each accepting a single ort(5) configuration file that describes your data and how it is accessed, modified, created, deleted. The generated sources have a strong focus on security, documentation, and auditability.

ort tools manage or generate the following application components.

See the GitHub repository for installation and issue tracking. openradtool is a BSD.lv project, née kwebapp.

ort tools are designed to be operated by make(1): sources go in, results come out. During development, Makefiles continuously keep C sources, TypeScript, translations, and so on up to date from a single ort(5) file. These files are in turn compiled or bundled into your application.

ort(5) productions

1. validate configuration

% ort db.txt
ort(1) functionality

Consider an example ort(5) configuration db.txt. It defines three data objects—a user, company, and session—with relations between the three. Each session refers to a user by the userid field. Then each user refers to a company by its cid.

The ort(1) utility parses and validates the configuration. To do something with this configuration, we need to have code. Most applications start by creating an API from the data configuration as described in the next section.

Note: this validation is superfluous, as all other tools validate during parse.

2. generate back-end code

% ort-c-header -jv db.txt > db.h
% ort-c-source -jv -h db.h db.txt > db.c
ort-c-header(1) and ort-c-source(1) functionality

Generate source and header files to be linked to sources (usually, but not necessarily) driving a kcgi(3) CGI script. Each function and structure in the header file is documented thoroughly. The source files are also documented, though more sparsely.

The C source file is generated for the target operating system, so it's not guaranteed to be portable between operating systems.

You can break apart C headers and sources into the database routines, JSON export, validation, and so on. For smaller applications, it's generally easiest to have them in one.

3. compile back-end code

% cc -static -o test main.c db.c -lksql -lsqlite3 -lpthread -lkcgijson -lkcgi -lz

The -static is for simplicity when running CGI scripts in a file-system jail This is the default operation on chroot(2)'s web servers such as OpenBSD's httpd(8). It usually isn't necessary for non-CGI applications.

The required libraries are -lksql for the database routines, -lkcgijson for the JSON output, and -lkcgi for the input validation. The other libraries are dependencies on the former (-lsqlite3 and -lpthread) and latter (-lz). The third-party libraries may be in -L/usr/local/lib, with headers in -I/usr/local/include.

Some operating systems additionally need -lcrypt (for password hashing) and -lm (for -lkcgijson).

4. generate and initialise database

% ort-sql db.txt > db.sql
% sqlite3 db.db < db.sql
ort-sql(1) functionality

Some object fields, such as the user structure inside of the section, are not part of the SQL schema, but required for creating the SQL queries during runtime. For the most part, however, all ort(5) fields map into database columns.

The SQL schema file is thoroughly documented. Use sqliteconvert or similar tool to browse the SQL documentation for any non-trivial application.

5. update database

% ort-sqldiff db.old.txt db.txt > db.update.sql
% sqlite3 db.db < db.update.sql
ort-sqldiff(1) functionality

Database upgrades are a pain: ort-sqldiff(1) programmatically tracks differences in the database schema. This allows for continuous testing of database compatibility. It also generates the correct SQL commands for properly upgrading an existing database without fear of ordering or missing field attributes.

(Update scripts should, however, always be perused for correctness.)

6. generate javascript front-end

% ort-javascript db.txt > db.js
% ort-javascript -t db.txt > db.ts
ort-javascript(1) functionality

The last part of the toolchain is to handle the JSON-export output in the browser itself. The ort-javascript(1) tool will also generate JavaScript or TypeScript files to assist in filling in data for your front-end web application code.

Both are the same, and provide an easy interface for replacing elements (noted by class names) in HTML DOM trees with data. All of this is documented using jsdoc notation. For example, consider the following:

    1 <div id="foobar">
    2  User 
    3  <span class="user-email-text"></span>:
    4  company 
    5  <span class="user-company-obj">
    6   <span class="company-name-text"></span>.
    7  </span>
    8 </div>

A JavaScript file may invoke new ort.user(res).fill(document.getElementById('foobar')), where res is the JSON object parsed from an AJAX call to the CGI script. This will recursively replace text (classes ending with -text), fill in input values, and allow for extensive customisation.

7. translate javascript labels

% ort-xliff db.txt > db.fr.xml
% ort-xliff -j db.txt db.fr.xml > db.trans.txt
ort-xliff(1) functionality

The ort-javascript(1) tool is capable of filling in labels of exported enumeration and bitfield values. For example, if an exported field is of the enum foo type, and the enumeration's items have jslabel tags, integral enumeration values can be programmatically converted to the labels by invoking the ort.foo.format() method as a custom callback.

These strings may be translated by using the ort-xliff(1) utility, which extracts translatable strings into the industry-standard XLIFF 1.2 format. The translation files may then be merged back into the configuration file, with the output piped into ort-javascript(1), for a full translation sequence.

8. audit role-based access

% ort-audit audit-example.txt user

Arguably the most powerful feature of ort. Audit role-based access control access with ort-audit(1), ort-audit-json(1), and ort-audit-gv(1): see the full availability of data and operations available to the role. Role compliance in ort is guaranteed by having separate jailed database and application processes.

In the example role-backed audit-example.txt with roles user and admin, for example, these tools can fully audit for the user role as seen in the exemplar audit.html created with ort-audit-json(1). This visualisation breaks down access by structures (the foundational objects of ort(5)) and then grouped by operation.