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.
Attica can be downloaded in two different formats:
attica-src.zip
.attica-build.zip
.
Additionally, the zip file containing the java-doc of the attica API
can be found at this
location: attica-doc.zip
.
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 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 is quite simple, given that the user adheres to a few conventions:
attica.server.Database
and a
call to the runStatement()
method.Operator
framework and, namely, through the Sink
classes.shutdown()
method of
the attica.server.Database
class is made. (This call
we make all buffer pool contents persistent.)
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.
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 |