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---