Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/rxm.git
# Overview

Relational eXpression Map (**rxm**) is a terse database- and output-agnostic
query language for generating structured documents.

# Requirements

The software requirements include:

* [Java 8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) - Development environment
* [Gradle](http://gradle.org/) - Automated build process

# Quick Start

Download, compile, build, and parse the example using:

    git clone https://bitbucket.org/djarvis/rxm.git
    gradle -Dbeautify=true clean build javadoc run -Pargs=test/people.rxm

# Usage

This section describes how to invoke the Java API to generate documents.

## Basic

Generate an XML document using **rxm**. For example:

```
import com.whitemagicsoftware.rxm.RXM;

public class QueryTest {
  public static void main( String args[] ) throws Exception {
    RXM rxm = new RXM(
      "root   > people," +
      "person > person," +
      ".*,"
    );

    System.out.println( rxm.toString( getConnection() ) );
  }
}
```

## Modules

A module is a set of **rxm** expressions that can be reused. For example:

```
import com.whitemagicsoftware.rxm.RXM;

public class QueryTest {
  public static void main( String args[] ) throws Exception {
    RXM rxm = new RXM(
      "module person," +
      "person > person," +
      ".*,"
    );

    rxm.add( "root > people, import person," );

    System.out.println( rxm.toString( getConnection(), "json" ) );
  }
}
```


# Syntax

This section describes the **rxm** syntax, which involves:

* a **Map**;
* a **Where** clause;
* namespace definitions; and
* module definitions.

## Map

An example map resembles:

```
root               > people,           # "root" keyword starts the document
person             > person,           # maps table context to a node
.age               > @age,             # @ maps a column to an attribute node
.first_name        > name/first,       # maps a column to a node
.last_name         > .../last,         # ... reuses the previous node's path
account.person_id +> person.person_id, # +> performs an INNER JOIN
account            > account,          # context is now "account" node
.id                > @id,              # account id attribute
^,                                     # pop stack to previous table context
address            > address,          # switch context to "address" node
.*,                                    # glob remaining columns
;                                      # Denotes optional WHERE clause
```

The example mapping produces:

```
<people>
  <person age="42">
    <name>
      <first>Charles</first>
      <last>Goldfarb</last>
    </name>
    <account id="123"/>
    <address>
      <id>456</id>
      <street>123 Query Lane</street>
      <city>San Francisco</city>
    </address>
  </person>
</people>
```

Any structured document format can be produced, including JSON.

### Pops

Stack pops (`^`) switch context to a previous element. Multiple consecutive
pop lines are permitted; extraneous pops are silently ignored: context never
traverses beyond the root node.

### Globs

A column demarcation followed by a Kleene star (`.*`) maps remaining columns
automatically. Each node name corresponds directly to the entity column name.

## Where

Example **rxm** expressions for SQL WHERE clauses include:

```
account.id  = :id      # : starts a named parameter
account.id <> :id      # inequality parameter comparison
account.id  = {:id, 1} # becomes IN set
account.id <> {:id, 1} # becomes NOT IN set
account.id  = null     # becomes IS NULL
account.id <> null     # becomes IS NOT NULL
account.id  = 'text'   # string equality comparison
account.id  = -42      # numeric equality comparison
account.id  < 42       # numeric less than comparison
account.id  > 42       # numeric greater than comparison
account.id <= 42       # numeric less than or equal to comparison
account.id >= 42       # numeric greater than or equal to comparison
```

Additionally, the `&&` and `||` tokens perform logical **and** and **or**
operations, respectively.

## Namespace

Namespace syntax resembles:

    root       > people(html, http://www.w3.org/TR/html4/),
    person     > html:person,
    person.id  > people:id( people, http://www.people.com ),

## Module

Modules are defined using the *module* keyword. For example:

```
module person,
person             > person,
.first_name        > first,
.last_name         > name/last,
.age               > @age,
```

Modules are referenced using the *import* keyword.  For example:

```
root               > people,
import person,
address            > address,
.*,
```

Modules may not contain a root element.

# Rationale

The reasons for **rxm** include:

* Eliminate repetitious code.
* Decouple SQL statements from document output format.
* Few databases are fully compliant with SQL/XML:2006.
* Provide a database-agnostic mechanism to generate structured documents.
* XQuery has limited open-source implementations for major RDBMS software.

# Addendum

Review the [JDBC documentation](http://docs.oracle.com/javase/tutorial/jdbc/basics/connecting.html) to understand how database connections are established.