To invoke the interpreter, type:
durodt no db>
Duro D/T displays a prompt with the database currently in use. Since no database is selected in the example shown above, the prompt is "no db".
To exit the interpreter, type an end-of-file character (Control-D on Unix, Control-Z on Windows) or type "exit();". (Do not forget the parentheses and the semicolon)
For more information about invoking Duro D/T see Duro utilities.
In Duro D/T, variables are typed, as required by TTM, RM prescriptions 11, 12, and 13. They must be declared before they can be used.
Example:
no db> var i integer; no db>
This creates a variable named I. Note that Duro D/T is case insensitive, so there is no diffence between "var i integer;" and "VAR I INTEGER;". This tutorial shows example code in lowercase, since this is more convenient to type.
When declaring a variable, an initial value can be specified.
Example:
no db> var j integer init 2; no db>
If an initial value is given, the type can be omitted. So the above can also be written as follows:
no db> var j init 2; no db>
If an initial value is not specified, the variable is automatically initialized to a default value, which is zero for numeric types, the empty string for STRING and FALSE for BOOLEAN.
A variable can also be declared to have the same type as some other variable. Example:
no db> var k same_type_as(i); no db>
Once a variable has been declared, a value can be assigned to it. For example:
no db> i := 5; 1 element affected. no db>
Duro D/T supports multiple assignment, i.e. more than one assignment in one statement. A multiple assignment behaves as if the individual assignments were executed in parallel.
For example, to exchange the values of two variables, one can write:
no db> i := j, j := i; 2 elements affected. no db>
Duro supports the following built-in scalar types:
CHAR can be used as an alias for STRING.
Examples:
no db> var b boolean init true; no db> var i integer init 1; no db> var f float init 1.0; no db> var s string init 'Foo';
For non-scalar types, see the chapters on tuples, tables, and arrays, respectively.
Duro supports the usual arithmetical operators. Example:
no db> println(2 + 3 * 4); 14 no db>
For details on the built-in operator PRINTLN, see the chapter on I/O.
Duro D/T supports line comments and multi-line comments.
-- This is a line comment. /* This is a multi-line comment. */
Lines starting with #! are ignored to allow for Unix interpreter files.
Example:
println('Please enter a number:');
var s string;
readln(s);
var n init integer(s);
if (n < 0) then
println('Negative');
else
println('Positive');
end if
In Duro D/T, BEGIN .. END is not required since there can be several statements after THEN. But the following form, which more strictly adheres to TTM, is supported too:
println('Please enter a number:');
var s string;
readln(s);
var n init integer(s);
if (n < 0) then
begin;
println('Negative');
end
else
begin;
println('Positive');
end
end if
Example:
var i integer;
for i := 1 to 10;
println(i);
end for;
DO may be used instead of FOR.
Example:
println('Please enter a positive number:');
var s string;
readln(s);
var n init integer(s);
while n < 0;
println('This number is not positive. Please enter again:');
readln(s);
n := integer(s);
end while;
This statement is not supported yet.
Tuple variables can be declared as follows:
no db>var t tuple {i integer, s string};
no db>
Like scalar variables, tuple variables can be explicitly initialized when they are declared:
no db>var t tuple {i integer, s string} init tuple {i 1, s 'One'};
no db>
Or shorter:
no db>var t init tuple {i 1, s 'One'};
no db>
Note that as required by TTM proscription 1 there is no attribute
ordering in Duro D/T, so the statement above is perfectly equivalent
fo the following:
no db>var t init tuple {s 'One', i 1};
no db>
Tuples variables can be assigned and updated:
no db>t := tuple {i 2, s 'Two'};
1 element affected.
no db> update t {i := 3};
1 element affected.
no db> update t {i := 4, s := 'Four'};
2 elements affected.
Accessing tuple attributes:
no db>println(t.s); Four no db>
Alternative form:
no db>println(s from t); Four no db>
Database environments are the places where databases and tables are physically stored. Therefore a database environment must exist before a database can be created. In Duro D/T, a database environment can be created using the built-in update operator CREATE_ENV().
Example:
no db>create_env('dbenv');
no db>
The built-in update operator CONNECT can be used to connect to an existing database environment. CONNECT takes two arguments of type STRING. The second argument specifies the database environment. The first argument is currently ignored. In future versions it will specify a network host. For compatibility with future versions, it is recommended to pass an empty string as the first argument.
Example:
no db>connect('', 'dbenv');
no db>
After a database environment was created or connected to, a database can be created using the built-in update operator CREATE_DB().
no db>create_db('D');
no db>
The variable CURRENT_DB contains the database currently in use. A database can be selected by assigning the variable:
no db>current_db := 'D'; 1 element affected. D>
After CURRENT_DB has been set, the prompt shows the name of the database selected and a transaction can be started using BEGIN TRANSACTION. Instead of BEGIN TRANSACTION, BEGIN TX can be used.
Example:
D>begin tx; Transaction started. D>
Creating a real persistent table:
D>var r real relation{no integer, name string} key {no};
Table R created.
D>
Creating a private (real transient) table:
D> var p private relation{no integer, name string} key {no};
Local table P created.
D>
Creating a virtual table:
D> var v virtual r {no};
Table V created.
D>
Example: Printing all tuples of table R in an unspecified order:
D> var a array tuple same_heading_as(r); D> load a from r order(); D> var i integer; D> for i:= 0 to length(a)-1; D> println(a[i]); D> end for;
In its current version, Duro D/T features very limited I/O support.
It provides the following update operators for I/O:
PRINTLN takes one argument and prints it on standard output, followed by a newline. It is defined for all built-in scalar types and also for tuple and relation arguments.
Example:
no db> println(true);
TRUE
no db> println(2 * 4);
8
no db> println(tuple {a 1, b 'bee'});
TUPLE { A 1, B "bee" }
no db> println(relation {tuple {i 1, c 'foo'}, tuple {i 2, c 'bar'}});
RELATION { TUPLE { I 1, C "foo" }, TUPLE { I 2, C "bar" }}
no db>
Note that in Duro D/T, the keyword CALL in update operator invocations is optional. The following is also valid:
no db> call println(2 * 4); 8 no db>
PRINT works like PRINTLN, except that its output is not followed by a newline.
Example:
no db> print('2 + 2 = '); println(2 + 2);
2 + 2 = 4
no db>
READLN is defined as follows:
OPERATOR READLN(LINE STRING) UPDATES LINE;
READLN reads one line from standard input and stores it in LINE, without the trailing newline.
Defining a read-only operator:
D> operator incr(i integer) returns integer; D> return i + 1; D> end operator; Operator INCR created. D>
Defining an update operator:
D> operator inc(i integer) updates {i};
D> i := i + 1;
D> end operator;
Operator INC created.
D>
Dropping an operator:
D>drop operator incr; Operator INCR dropped. D>
Example for defining a type:
begin tx;
type len possrep {n float} constraint the_n(len) >= 0.0;
commit;
Before the type can be used, it must first be implemented. This is currently not possible with Duro D/T. The Durotcl command duro::type can be used for this.
$Id$