Demo
Programs on Reading and Writing MDELite6 Databases
Start with these imports, not all of which are needed for each program
given below. The imports are the union required to run all
demo programs.
import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import PrologDB.*;
Program
1: Printing the Contents of a Database Schema
This
program takes an ooschema declaration and flattens it into a schema
declaration. The distinction between ooschema files and
schema fiiles, as explained in class, is that attributes of supertables
are propagated to each of its subtables, recursively. Next,
the code prints out the contents of the database schema, getting one
table at a time, and printing the schema of the table.
Printing subtable declarations of the database conclude the
program.
---printSchema---
Program
2 : Constructing Schemas Programmatically
This
program creates a starTrek ooschema programmatically and prints it out
using standard utilities.
---schemaBuild---
Program
3: Programmatically Reading a Database
This
program reads a database given its file, prints the database using
available utilities and also the hard way by extracting out its
individual tables and printing its tuples.
---DBread---
Program
4: Programmatically Creating a Database
The
following program creates the startrek database, which has 3 tuples,
one tuple per table. An ooschema for the database is created
and then converted into a true schema (via the flatten operation).
At this point, a database instance of the schema can be
created, one table and one tuple at a time.
---DBBuild---
Program
5: Programmatically Reading a Table
This
program reads a dog-owner database, which has a table of dogs.
Using Java Streams, the stream of all aussie tuples ('aussie'
means Australian Shepherd). This stream is then
printed. A similar stream is reconstituted (remember: once
you use a stream, it's finished) and then filtered further, and printed.
---TableRetrieve---
Program
6: Programmatically Reading Tuples of a Table and its Subtables
This
program reads the tuples of a table and all of its subtables, using the
toTupleList() method. If you want to retrieve tuples of only
that table (and not its subtables), you use the getLocalTuples()
method. A couple queries are illustrated.
---InheritanceRetrieve---
Program 7: Talking Cross Products of Schemas
Table
joins take cross products of schemas. Occasionally you might need
to do this yourself. The following program illustrates how cross
products of schemas are taken and printed.
---crossSchema---
Program 8: Table Joins
This
program reads a dog-owner database, finds the dog, when, and owner
tables, joins the dog table with the when table over dog.did = when.did
join predicate (i.e., the did columns of both tuples must have the same
value) to produce a new table dogXwhen. Note: the attributes of
the joined relation are renamed. What used to be attribute T in
the dog table is now renamed dog.T. Same for all other
attributes, so that one can always distinguish attributes with similar
names. Continuing, this table is printed, and then it is joined with
the owner table over predicate when.oid = owner.oid, and then the table
is printed out.
---TableJoins---
Program 8: Self Joins
Self-joins
(joining a table with itself) has always been an obstacle in database
development. Here is a program that joins the dog table with
itself over dog identifiers (did). The key to self-joins is that
a copy of a table for each self-join must be made. If a dog table
is to be joined with itself, the dog table is really joined with a
copy. If a dog table is to be joined with itself, followed by
itself, the dog table and two distinct copies of the dog table must be
joined. Now, this particular example, of joining a dog table with
itself isn't particularly useful,
but when you have a table that
encodes (parent, child) relationships, joining such tables allows you
to relate parents to grandchildren, and so on.
---SelfJoins---
Program 9: Checking Uniqueness Constraints on a Table
Checking
that the name field of a table has unique values for all tuples is a
typical constraint. Java Streams are stateless, so one has to
create an operation that updates a stateful object which also will do
the work of error checking. MDELite6 uses the following scheme.
An ErrorReport object maintains a list of errors that have been
accumulated across any number of constraints. When stateful
computations are needed, like remembering the name values of previous
tuples seen -- to check whether a name value has been seen before, one
needs another object that does the checking and then reports errors, as
it encounters them to an ErrorReport object. This program
illustrates this process. A database is read, and a particular
table (dog) is found. An error reporter is created, along with a
"unique" object that looks at, in this case, the "name" field of each
tuple and performs a test to see if this name has been seen before.
If it has, an error is reported to the ErrorReport object, and
the message includes another attribute of the tuple, namely the
atttribute of its identifier ("did") so that the offending tuple can be
tracked down later. When an ErrorReport object is printed (via
printReport()), if there are errors, a RuntimeException is thrown,
terminating the program.
---Unique---
Program 10: Filtering Tuples from Tables
This
program illustrates several ways in which you can filter tuples from
tables. The first way uses standard for loops with an
if-statement. The second way creates a stream of tuples that are
filtered and printed. The third way creates a TupleList of a
relation, filters the tuplelist and prints the list. You'll
notice that the stream and tuplelist versions are very similar.
They should be: the only difference between the two is that
stream implementations process one tuple at a time. TupleList
implementations process one TupleList at a time.
---filter---
Program 11: Conform Tests
This
program illustrates an example from class. A Contract is owned by
precisely one Person or one Company, but never both. The value of
a Contract held by a Company must exceed 500 (dollars); the value of a
Contract held by a Person must not be greater than 100 (dollars).
Note the use of a ErrorReport object that collects all
conformance failures.
---conform---
Program 12: Reading and Writing Individual Tables
MDELite6
allows you to read and write inidividual tables, either in the standard
Prolog format or as a CSV (comma separated value) file. The name
of the file (whether it ends or not in ".csv") determines whether the
file is to be read/written as a CSV file..
---csvfile---