Overview

Attica is a single user experimental database system written entirely in Java. From 6/1/09 version 1.5 of the attica database system is available, comprising the following parts:

Attica is open-source and free if used for educational and/or research purposes. Commercial use is possible only after consulting with the (sole, for the moment) creator of attica, Stratis Viglas.

Introductory slides

This is a version of the introductory slides.

Download

Attica can be downloaded in two different formats:

Additionally, the zip file containing the java-doc of the attica API can be found at this location: attica-doc.zip.

Initialising attica

The first step in using attica, is incorporating the attica API (i.e., the attica.jar file) into your classpath. Your local Java installation gives you instructions on doing that.

After attica.jar is in your classpath, the next step is writing the attica properties file. This is a standard Java properties file in which you should define the variables of your local installation. The attica server reads these values at start-up and configures the system. This is a typical attica properties file:

# The attica server directory
attica.directory=/Users/sviglas/atticadb
# The attica temporary directory
attica.temp.directory=/Users/sviglas/atticadb
# The number of pages in the buffer pool
attica.buffersize=50

The first property, attica.directory, specifies the directory under which attica stores all the DB related files, namely the system catalog and the user tables. This should be a directory you have write access to.

The second property, attica.temp.directory, specifies the directory in which all temporary files created by attica should be stored. Again, this should be a directory you have write access too. Assuming attica does not crash while running the contents of this directory remain unchanged before and after attica invocations.

The third property, attica.buffersize, specifies the number of pages in attica's buffer pool. The greater the number of pages in the buffer pool, the more disk pages will be cached in memory, the fewer the number of times the server will have to go to disk to read data. (Aside: there are 4,096 bytes in an attica disk page. If the number of pages in the buffer pool is set to 50, this means that the buffer pool takes ~205KB of memory. You can do the maths to see the portion of your on-disk data you are caching.)

If any of the first two properties are missing, they default to the user's home directory. If the third propery is missing, it defaults to 50 pages in the buffer pool.

Once everything is in place, you are ready to run attica for the first time. The main attica class is org.dejave.attica.server.Database. The first time attica is run (and only the first time) attica should be run in initialisation mode. This is achieved through the following command:

java org.dejave.attica.server.Database --properties attica.properties --init

which starts up the server reading its properties from file attica.properties file, and specifies that the server should be run in initialisation mode, through the --init option.

This cannot be stressed strongly enough: attica is not idiot-proof. If attica is run in initialisation mode after data has been stored, all data will be lost as the system catalog will be reconstructed.

After attica is run for the first time, you should see something similar to the following output in your terminal:

[zeus:~] sviglas% java org.dejave.attica.server.Database --properties attica.properties --init
Starting up the database...
Bootstrapping: Loading properties from attica.properties
Attica server is running...
Data directory: /Users/sviglas/atticadb
Termporary directory: /Users/sviglas/atticadb
Buffer pool size: 50 pages
** ready **
aSQL > _

If you are seeing the above, congratulations! This is the attica SQL prompt and you are now ready to start using the attica front-end.

Attica SQL

Attica SQL is a typical SQL implementation of data definition and data manipulation. Tables are created through create table statements, values inserted through insert statements and data retrieved through select/from/where statements. Statements are delimited by semicolons (;).

Data is defined through create table statements. The typical syntax of a table creation statement is the following:

create table tablename (
      attributename atticatype
      [, attributename atticatype]*)

Valid table names and attribute names are any non-reserved alphanumeric strings. (For instance, a table or an attribute cannot be named "create".)

Valid types are the following: byte, short, character, integer, long, float, double and string. The string data type is not fixed, i.e., when serialised, records with string attributes will occupy variable lengths. There is no set maximum for string length, but try to keep it below 255 characters as the system has not been thoroughly tested in that respect. For instance, the following statement:

create table simple (key integer, value string);

creates a table named simple with two attributes: an attribute named key of type integer, and an attribute named value of type string.

Once a data definition statement has been issued, it is executed by the DB engine. The engine then informs the user of the success (or failure) of the command:

aSQL > create table simple (key integer, value string);
(0) : [Table simple successfully created]
** end-of-stream **

If another table is to be created by the same name, the server does not perimit the creation:

aSQL > create table simple (key integer, value1 double, value2 string);
(0) : [A table by the name simple already exists]
** end-of-stream **

If the user wants to see the definition of a table, this can be achieved through a describe table tablename statement:

aSQL > describe table simple;
(0) : [{simple.key: java.lang.Integer, simple.value: java.lang.String}]
** end-of-stream **

while the contents of the catalog can be seen through the catalog statement:

aSQL > catalog;
(0) : [Catalog: 2 tables. Entries:
      {record=Table: record, filename: /Users/sviglas/atticadb/record_-934908847,
            def:{record.key: java.lang.nteger, record.name: java.lang.String, record.address: java.lang.String},
      simple=Table: simple, filename: /Users/sviglas/atticadb/simple_-902286926,
            def: {simple.key: java.lang.Integer, simple.value: java.lang.String}}]
** end-of-stream **

Data is inserted through insert into statements. For instance, the following statements insert three new rows into the simple table:

aSQL > insert into simple values (1, 'foo');
(0) : [Tuple was successfully inserted into table simple]
** end-of-stream **
aSQL > insert into simple values (2, 'bar');
(0) : [Tuple was successfully inserted into table simple]
** end-of-stream **
aSQL > insert into simple values (3, 'foobar');
(0) : [Tuple was successfully inserted into table simple]
** end-of-stream **

The data can be retrieved through select/from/where statements:

aSQL > select simple.key, simple.value from simple;
(0) : [1, foo]
(1) : [2, bar]
(2) : [3, foobar]
** end-of-stream **
aSQL > select simple.key, simple.value from simple where simple.key > 2;
(0) : [3, foobar]
** end-of-stream **

Attica SQL does not support wildcards; for instance simple.* does not work in the select clause of a query. All these enhancements will be implemented later.

Finally, deletion is not (yet) implemented.

Programming the attica API

Programming the attica API is quite simple, given that the user adheres to a few conventions:

Following is a code snippet that executes a select statement over a database instance:

import org.dejave.attica.server.Database;
import org.dejave.attica.storage.Tuple;
import org.dejave.attica.engine.operators.Sink;
import org.dejave.attica.engine.operators.EndOfStreamTuple;

public class RunMe {
    public static void main (String [] args) {
        try {
            // first argument should be the name of the properties file
            String propertiesFile = args[0];
            // start up a new database instance
            Database db = new Database(propertiesFile);
            // run a select statement
            Sink sink = db.runStatement("select simple.key, simple.value from simple");

            // start iterating through the returned values
            boolean eos = false;
            while (! eos) {
                //retrieve the next tuple
                Tuple tuple = sink.getNext();
                System.out.println(tuple);
                //check whether this is the end of stream
                eos = (tuple instanceof EndOfStreamTuple);
            }
            // shut down the database
            db.shutdown();
        }
        catch (Exception e) {
            System.err.println(e.getMessage());
            e.printStackTrace(System.err);
        }
    } // main()
} // RunMe

For further information, please consult the API documentation.


Home : Teaching : Courses : Adbs 

Informatics Forum, 10 Crichton Street, Edinburgh, EH8 9AB, Scotland, UK
Tel: +44 131 651 5661, Fax: +44 131 651 1426, E-mail: school-office@inf.ed.ac.uk
Please contact our webadmin with any comments or corrections. Logging and Cookies
Unless explicitly stated otherwise, all material is copyright © The University of Edinburgh