A Brief Duro D/T Tutorial

Invoking the interpreter

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.

Declaring variables

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>

Assignment

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>

Types

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.

Comments

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.

Control statements

IF

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

FOR

Example:

var i integer;
for i := 1 to 10;
    println(i);
end for;

DO may be used instead of FOR.

WHILE

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;

CASE

This statement is not supported yet.

Tuples

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>

Databases and database environments

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>

Tables

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>

Arrays

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;

I/O

In its current version, Duro D/T features very limited I/O support.

It provides the following update operators for I/O:

PRINTLN

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

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

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.

User-defined operators

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>

User-defined types

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$