-
Notifications
You must be signed in to change notification settings - Fork 1
TomaImplementation
This page gives information about the status of the TOMA query language implementation for Ontopia.
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
cd sandbox/toma
mvn compile package
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
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>
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.
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)
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.
The current specification can be found here: TOMA Specification
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 ']'