Interaction between commands, formatters, and other actors

Definitions

An HTSQL URI consists of three parts: the request, the command, and the formatter. In the URI /op:person/select().html, /op:person is a request, /select() is a command, and .html is a formatter.

A command part, a formatter part or both of them could be omittted; the following URIs are valid (and will produce the same output provided that .html is the default formatter):

  • /op:person/select().html
  • /op:person/select()
  • /op:person.html
  • /op:person

Use Cases

Default command

If no explicit command is specified, a default command is used. Depending on the request, the default command acts differently:

  • / is transformed to /root().
  • /op:person is transformed to /op:person/select().

The default command may be used explicitly, called by the name htsql:default().

Commands with no formatters

Some commands accept no formatters, they fail if a formatter is specified. They either produce no content (204 No Content) or generate content on their own, without formatter assistance. Examples:

  • /root()
  • /import()

Default formatters

Some commands require a formatter to process the request and generate content. If no explicit formatter is specified, a default formatter is used. For different commands, default formatters could also be different:

  • /op:person/select() is transformed to /op:person/select().html.
  • /meta() is transformed to /meta().js.

The name of the default formatter is htsql:default().

Command supports multiple interfaces

A command may perform different actions depending on the specified formatter. For instance:

  • /op:person/select().html executes a statement SELECT * FROM op.person and provides the result set to the formatter .html.
  • /op:person/select().sql generates the string "SELECT * FROM op.person" and provides it to the formatter .sql.

Formatter supports multiple interfaces

A formatter may produce different types of output depending on the specified command. For instance:

  • /op:person/select().json displays the row of the table op.person in the JSON format.
  • /meta().json displays the database metadata, which is non-tabular data, in the JSON format.

Commands and Connections

Generally, a command manages connections to the database. A command:

  • Creates a connection object.
  • Executes SQL statements.
  • Performs COMMIT if the operation succeeded and ROLLBACK otherwise.
  • Finally, release the connection.

However one may want to perform a command in a subrequest, obtain the result generator and use it in some way. In this case, it is often desirable that the command does not manage the connection object by itself. Of four operations on connection objects, it should perform only one:

  • Creates a connection object.
  • Executes SQL statements.
  • Performs COMMIT if the operation succeeded and ROLLBACK otherwise.
  • Finally, release the connection.

It leaves the task of managing the connection to the entity that issues the subrequest and allows performing several commands withing a single connection.

Commands, Formatters and Connections

Typically, an HTSQL request results in a triple of:

  • Status code.
  • List of headers.
  • Output data.

Within an existing HTSQL request, one may want to generate and perform one or more HTSQL subrequests and obtain the resulting triples of status, headers and data. Then it could be combined to produce the result of the main request.

Moreover it is often needed to perform several subrequests using the same connection object managed by the main command.

Other issues

Formatter vs Extension

Perhaps formatter could be better named as extension? Since the new API allows commands to format their results themselves, the name "formatter" becomes somewhat misleading. On the other hand, "extension" is an overloaded term.