Skip to content
Quintin Siebers edited this page Jun 18, 2015 · 1 revision

Introduction

This page gives information about the status of the TOMA query language implementation for Ontopia.

Status

Current Version: 1.0.1

The implementation currently lives in the sandbox part of Subversion, so you must access the sandbox to find it.

The implementation is fully functional, missing parts are as follows:

  • square brackets have to be fully supported
  • query optimization has to be improved
  • improve test coverage & documentation

Compile & Run

Prerequisites

Compile

 cd sandbox/toma
 mvn compile package

Commandline

A simple command-line tool to run queries against a topic map is included. To run it, simply type in the following to get a help message:

 cd target
 java -jar toma-{$version}-full.jar

Maven Integration

Include the following snippet in your pom.xml:

<dependency>
  <groupId>net.ontopia</groupId>
  <artifactId>toma</artifactId>
  <version>1.0.1</version>
</dependency>

<repositories>
  <repository>
    <id>Ontopia-Snapshot</id>
    <url>http://ontopia.googlecode.com/svn/maven-snapshot-repository</url>
  </repository>
</repositories>

Omnigator Integration

Copy the current toma package to the common library path of the ontopia tomcat instance.

 cp target/toma-{$version}.jar {$ontopia-install-path}/apache-tomcat/common/lib

Select a topic map within omnigator and use the "Generic Query" plugin, where you can select "Toma" as query processor.

Google App Engine

Toma can also be tested out using a specific version of omnigator deployed to Google App Engine: http://toma-demo.appspot.com (Note: Does not seem to work anymore, as the application takes too long to load, and the execution is aborted)

Examples

Some examples based on the famous Italian Opera topic map:

Description Query
Get the names of all operas select $t.name where $t.type = opera;
Get all persons which have been born in Milano select $t where milano.(place)<-(born-in)->(person) = $t;
Get the first 3 Composers select $c where $c.type = composer limit 3;
Get all operas which have a name that starts with 'B' or 'V' and sort by the ID select $t, $t.name where $t.type = opera and $t.name ~ 'B' union select $t, $t.name where $t.type = opera and $t.name ~ 'V' order by 1;
Count the number of operas select count($t) where $t.type = opera;
Get all web resources about librettos select $t.oc(libretto)@web where exists $t.oc(libretto)@web;
Get all persons whose type is writer or a sub-type of it select $writer where ($t = writer or $t.super = writer) and $writer.type = $t;

Note: do not forget to escape '$' with '' when trying to run the examples in a shell.

More examples be found within the 'Generic Query' plugin of Omnigator while using the ItalianOpera.ltm topic map.

Specification

The current specification can be found here: TOMA Specification

Grammar

The grammar for the toma query language in EBNF notation (sorted by name), the starting point is 'query-expression':


aggregate-function := "count" | "sum" | "max" | "min" | "avg" | "concat"

and-clause := clause ( "and" clause )* 

assocpath-expr := variable? '(' path-expr ')' 
                  scope-expr? 
                  "->" role-expr
                  variable-binding? 
                  ( '.' path-part )* 
                  ( '.' assocpath-leftside )?

assocpath-leftside := role-expr "<-" assocpath-expr

atom-expr := topicpath-expr | assocpath-expr | function-expr | string

clause := ( "not" )? "exists" expr    | 
          '(' orclause ')'            |
          expr comparator expr        | 
          expr "is" ("not")? "null"   | 
          expr "in" 
             '(' (statement | expr ( ',' atom-expr )* )? ')'

comment := '#' ( ~'\n' )* '\n' 

comparator := "!=" | "=" | "<" | ">" | "<=" | ">=" | "~" | "~*" | "!~" | "!~*"

expr := atom-expr ("||" atom-expr)* 

function-expr := ( aggregate-function | simple-function ) 
                 '(' atom-expr ( ',' function-param )* ')'

function-param := integer | identifier | string

identifier := ('A'..'Z' | 'a'..'z') ('A'..'Z' |	'a'..'z' | '0'..'9' | '_' | '-')* 

integer := ('0'..'9')+ 

level := integer ( ".." (integer | '*') )? | '*'

limit := "limit" integer 

offset := "offset" integer

or-clause := and-clause ( "or" and-clause )*

order := "order by" order-part ( ',' order-part )* 

order-part := integer ("asc" | "desc")

path-expr := (topic-literal | variable) ( '.' path-part )*

path-part := ("id" | "sl" | "si" | "name" | "var" | "oc" | "ref" | "data" | "sc" | 
              "player" | "role" | "reifier" | "type" | "instance" | "sub" | "super")
             ( '(' ( path-expr | level ) ')' )?
             scope-expr? 
             variable-binding?

query-expression := statement ';'

role-expr := '(' ( "$$" | path-expr ) ')'

scope-expr := '@' ( variable | topic-literal | '(' path-expr ')' )

select-expr := "select" ( "all" | "distinct" )? select-list ( "where" or-clause ) 

select-list := expr ( ',' expr )*

simple-function := "lowercase" | "uppercase" | "titlecase" | "length" | 
                   "substr" | "trim" | "to_num"

statement := select-expr ( ( "union" ( "all" )? | "intersect" | "except" ) select-expr )* 
             order? limit? offset?

string := '\'' ( ( '\'' | '\n' ) | '\n' | '\'' )* '\'' 

topicpath-expr := path-expr ( '.' assocpath-leftside )?

topicliteral := 'i' string | 'n' string | 'v' string | "si" string | "sl" string | 
                identifier

variable := '$' ( 'A'..'Z' | 'a'..'z' | '_' ) ( 'A'..'Z' | 'a'..'z' | '0'..'9' | '_' )* 

variable-binding := '[' variable ']'

Clone this wiki locally