import Sav.Processor.*;
import java.io.*;

/** Indexing and selecting records of the table */
public class DBSession {

public static void main(String args[]) throws Exception {
    String DBName = "Soft";
    String tableName = "Reference";
    int columnNumber = 5, rowNumber = 4;
    Table table = new Table(DBName, tableName, rowNumber, columnNumber);
/** Indexing */
    InputStream fis = new FileInputStream(tableName + ".txt");
    InputStreamReader isr = new InputStreamReader(fis);
    BufferedReader fTable = new BufferedReader(isr, 81920);
    table.createIndex(fTable);
/** Selecting */
    String queryRow[] = new String[columnNumber];
    int i = rowNumber - 1;
    queryRow[0] = table.bufTable[i][0];
    queryRow[2] = table.bufTable[i][2];
    queryRow[3] = table.bufTable[i][3];
    table.select(queryRow);
}//main()

}//DBSession

/* @(#) Table.java 2.3, 99/09
 * Copyright (c) 1997-99 Sav. All Rights Reserved.
 */
import Sav.Processor.*;
import java.io.*;
import java.util.*;

class Table {
String DBName;
String tableName;
int rowNumber;
int columnNumber;
String schema[];
String bufTable[][];
Association aTable;
Association aDomain[];
int index = 0;

Table(String DBName, String tableName, int rowNumber, int columnNumber) throws Exception {
    this.DBName = DBName;
    this.tableName = tableName;
    this.rowNumber = rowNumber;
    this.columnNumber = columnNumber;
    schema = new String[columnNumber];
    bufTable = new String[rowNumber][];
    aTable = new Association(DBName);
    aTable.con(tableName).con(PN.RELATION).fix();
    aDomain = new Association[columnNumber];
    for (int j = 0; j < columnNumber; ++j) {
        aDomain[j] = (Association) aTable.clone();
    }
}//Table()

void createIndex(BufferedReader fTable) throws Exception {
    StringTokenizer tokens;
    System.out.println("READING " + " ...");
    String line = fTable.readLine();
    System.out.print("#");
    System.out.println("\t" + line);
    tokens = new StringTokenizer(line, "\t;");
    for (int j = 0; j < columnNumber; ++j) {
        if (tokens.hasMoreTokens()) {
            schema[j] = tokens.nextToken().trim();
            aDomain[j].con(schema[j]).con(PN.NAME).fix();
        }
        else schema[j] = "";
    }
    for (line = fTable.readLine(); line != null; line = fTable.readLine()) {
        if (index > PN.MAX_NUMBER)
            new IndexOutOfBoundsException("index > " + PN.MAX_NUMBER);
        System.out.println(index + "\t" + line);
        bufTable[index] = new String[columnNumber];
        tokens = new StringTokenizer(line, "\t;");
        for (int j = 0; j < columnNumber; ++j) {
            if (tokens.hasMoreTokens()) {
                bufTable[index][j] = tokens.nextToken().trim();
            }
            else bufTable[index][j] = "";
        }
        if (++index == rowNumber) break;
    }//for
    createBufIndex();
}//createIndex()

void createBufIndex() throws Exception {
    System.out.println("INDEXING " + " ...");
    System.out.println();
    for (int j = 0; j < columnNumber; ++j) {
        for (int i = 0; i < index; ++i) {
            if (bufTable[i][j].length() == 0) continue;
            aDomain[j].con(bufTable[i][j]).con(PN.RELATION);
            aDomain[j].set("#" + i);
            aDomain[j].regain();
        }
    }
    System.out.println("STORING ...");
    System.out.println();
    aTable.store();
    Runtime.getRuntime().gc();
}//createBufIndex()

void select(String queryRow[]) throws Exception {
    Association aResultSet = new Association();
    Concept cIndex = null;
    boolean initiate = true;
    int i, j;
    System.out.println("SELECT * ");
    System.out.println("FROM " + DBName + '.' + tableName);
    System.out.print("WHERE ");
    for (j = 0; j < columnNumber; ++j) {
        if (queryRow[j] == null) continue;
        if (initiate) {
            initiate = false;
        }
        else {
            System.out.print("  AND ");
        }
        System.out.println(schema[j] + " = " + queryRow[j]);
    }
    initiate = true;
    for (j = 0; j < columnNumber; ++j) {
        if (queryRow[j] == null) continue;
        aDomain[j].con(queryRow[j]).con(PN.RELATION);
        if (initiate) {
            initiate = false;
            aResultSet.set(aDomain[j]);
        }
        else {
            aResultSet = aDomain[j].get(aResultSet);
        }
        aDomain[j].regain();
        aDomain[j].store();
    }

    System.out.println("\nRESULT SET");
    for (cIndex = aResultSet.getFirst(); cIndex != null; cIndex = aResultSet.getNext()) {
        i = Integer.parseInt(cIndex.toString().substring(1));
        System.out.print(i);
        for (j = 0; j < columnNumber; ++j) {
            System.out.print("\t " + bufTable[i][j]);
        }
        System.out.println();
    }
}//select()

}//Table class