package org.reldb.dbrowser.ui;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;
import org.reldb.rel.client.Connection.ExecuteResult;
import org.reldb.rel.client.Tuple;
import org.reldb.rel.client.Tuples;
import org.reldb.rel.client.Value;
import org.reldb.rel.utilities.StringUtils;
public class RevDatabase {
public static final int EXPECTED_REV_VERSION = 0;
public static final int QUERY_WAIT_MILLISECONDS = 5000;
private DbConnection connection;
public RevDatabase(DbConnection connection) {
this.connection = connection;
}
public Value evaluate(String query) {
return connection.evaluate(query);
}
public int hasRevExtensions() {
return connection.hasRevExtensions();
}
public long getUniqueNumber() {
return connection.evaluate("GET_UNIQUE_NUMBER()").toLong();
}
public ExecuteResult exec(String query) {
return connection.execute(query);
}
private boolean execute(String query) {
ExecuteResult result = connection.execute(query);
if (result.failed()) {
System.out.println("Rev: Error: " + result.getErrorMessage());
System.out.println("Rev: Query: " + query);
return false;
}
return true;
}
private Tuples getTuples(String query) {
return connection.getTuples(query);
}
public boolean installRevExtensions() {
String query =
"var sys.rev.Version real relation {" +
" ver INTEGER" +
"} INIT(relation {tuple {ver " + EXPECTED_REV_VERSION + "}}) key {ver};" +
"var sys.rev.Settings real relation {" +
" Name CHAR, " +
" value CHAR " +
"} key {Name};" +
"var sys.rev.Relvar real relation {" +
" Name CHAR, " +
" relvarName CHAR, " +
" xpos INTEGER, " +
" ypos INTEGER, " +
" model CHAR" +
"} key {Name};" +
"var sys.rev.Query real relation {" +
" Name CHAR, " +
" xpos INTEGER, " +
" ypos INTEGER, " +
" kind CHAR, " +
" connections RELATION {" +
" parameter INTEGER, " +
" Name CHAR" +
" }," +
" model CHAR" +
"} key {Name};" +
"var sys.rev.Script real relation {" +
" Name CHAR, " +
" text CHAR " +
"} key {Name};" +
"var sys.rev.ScriptHistory real relation {" +
" Name CHAR, " +
" text CHAR, " +
" timestamp CHAR " +
"} key {Name, timestamp};" +
"var sys.rev.Operator real relation {" +
" Name CHAR, " +
" Definition CHAR" +
"} key {Name};" +
"var sys.rev.Op_Update real relation {" +
" Name CHAR, " +
" Definition RELATION {" +
" ID INTEGER," +
" attribute CHAR," +
" expression CHAR" +
" }" +
"} key {Name};" +
"var sys.rev.Op_Extend real relation {" +
" Name CHAR, " +
" Definition RELATION {" +
" ID INTEGER," +
" attribute CHAR," +
" expression CHAR" +
" }" +
"} key {Name};" +
"var sys.rev.Op_Summarize real relation {" +
" Name CHAR, " +
" isby BOOLEAN, " +
" byList CHAR, " +
" Definition RELATION {" +
" ID INTEGER, " +
" asAttribute CHAR, " +
" aggregateOp CHAR, " +
" expression1 CHAR, " +
" expression2 CHAR " +
" }" +
"} key {Name};";
return execute(query);
}
public boolean removeRevExtensions() {
String query =
"drop var sys.rev.Operator;" +
"drop var sys.rev.Op_Update;" +
"drop var sys.rev.Op_Extend;" +
"drop var sys.rev.Op_Summarize;" +
"drop var sys.rev.Script;" +
"drop var sys.rev.ScriptHistory;" +
"drop var sys.rev.Query;" +
"drop var sys.rev.Relvar;" +
"drop var sys.rev.Settings;" +
"drop var sys.rev.Version;";
return execute(query);
}
public Tuples getRelvars() {
String query = "sys.Catalog {Name, Owner}";
return getTuples(query);
}
public Tuples getRelvars(String model) {
String query = "sys.rev.Relvar WHERE model = '" + model + "'";
return getTuples(query);
}
public Tuples getQueries(String model) {
String query = "sys.rev.Query WHERE model = '" + model + "'";
return getTuples(query);
}
// Update relvar position
public void updateRelvarPosition(String name, String relvarName, int x, int y, String model) {
String query =
"DELETE sys.rev.Relvar where Name='" + name + "', " +
"INSERT sys.rev.Relvar relation {tuple {Name '" + name + "', relvarName '" + relvarName + "', xpos " + x + ", ypos " + y + ", model '" + model + "'}};";
execute(query);
}
// Update query operator position
public void updateQueryPosition(String name, int x, int y, String kind, String connections, String model) {
String query =
"DELETE sys.rev.Query where Name='" + name + "', " +
"INSERT sys.rev.Query relation {tuple {" +
"Name '" + name + "', " +
"xpos " + x + ", " +
"ypos " + y + ", " +
"kind '" + kind + "', " +
"connections " + connections + ", " +
"model '" + model + "'" +
"}};";
execute(query);
}
// Preserved States
// Most operators
public Tuples getPreservedStateOperator(String name) {
String query = "sys.rev.Operator WHERE Name = '" + name + "'";
return getTuples(query);
}
public void updatePreservedStateOperator(String name, String definition) {
String query = "DELETE sys.rev.Operator WHERE Name = '" + name + "', " +
"INSERT sys.rev.Operator RELATION {" +
"TUPLE {Name '" + name + "', Definition '" + definition + "'}" +
"};";
execute(query);
}
// Update
public Tuples getPreservedStateUpdate(String name) {
String query = "(sys.rev.Op_Update WHERE Name = '" + name + "') UNGROUP Definition ORDER(ASC ID)";
return getTuples(query);
}
public void updatePreservedStateUpdate(String name, String definition) {
String query = "DELETE sys.rev.Op_Update WHERE Name = '" + name + "', " +
"INSERT sys.rev.Op_Update RELATION {" +
" TUPLE {Name '" + name + "', Definition " + definition + "}" +
"};";
execute(query);
}
// Extend
public Tuples getPreservedStateExtend(String name) {
String query = "(sys.rev.Op_Extend WHERE Name = '" + name + "') UNGROUP Definition ORDER(ASC ID)";
return getTuples(query);
}
public void updatePreservedStateExtend(String name, String definition) {
String query = "DELETE sys.rev.Op_Extend WHERE Name = '" + name + "', " +
"INSERT sys.rev.Op_Extend RELATION {" +
" TUPLE {Name '" + name + "', Definition " + definition + "}" +
"};";
execute(query);
}
// Summarize
public Tuples getPreservedStateSummarize(String name) {
String query = "(sys.rev.Op_Summarize WHERE Name = '" + name + "') UNGROUP Definition ORDER(ASC ID)";
return getTuples(query);
}
public void updatePreservedStateSummarize(String name, String definition) {
String query = "DELETE sys.rev.Op_Summarize WHERE Name = '" + name + "', " +
"INSERT sys.rev.Op_Summarize RELATION {" +
" TUPLE {Name '" + name + "', isby false, byList '', Definition " + definition + "}" +
"};";
execute(query);
}
public void updatePreservedStateSummarize(String name, String byList, String definition) {
String query = "DELETE sys.rev.Op_Summarize WHERE Name = '" + name + "', " +
"INSERT sys.rev.Op_Summarize RELATION {" +
" TUPLE {Name '" + name + "', isby true, byList '" + byList + "', Definition " + definition + "}" +
"};";
execute(query);
}
public void removeQuery(String name) {
String query = "DELETE sys.rev.Query WHERE Name = '" + name + "';";
execute(query);
}
public void removeRelvar(String name) {
String query = "DELETE sys.rev.Relvar WHERE Name = '" + name + "';";
execute(query);
}
public void removeOperator(String name) {
String query = "DELETE sys.rev.Operator WHERE Name = '" + name + "';";
execute(query);
}
public void removeOperator_Update(String name) {
String query = "DELETE sys.rev.Op_Update WHERE Name = '" + name + "';";
execute(query);
}
public void removeOperator_Extend(String name) {
String query = "DELETE sys.rev.Op_Extend WHERE Name = '" + name + "';";
execute(query);
}
public void removeOperator_Summarize(String name) {
String query = "DELETE sys.rev.Op_Summarize WHERE Name = '" + name + "';";
execute(query);
}
public boolean modelExists(String name) {
String query = "COUNT(((sys.rev.Query {model}) UNION (sys.rev.Relvar {model})) WHERE model = '" + name + "') > 0";
return evaluate(query).toBoolean();
}
public void modelRename(String oldName, String newName) {
if (oldName.equals(newName))
return;
String query = "DELETE sys.rev.Query WHERE model = '" + newName + "', " +
"DELETE sys.rev.Relvar WHERE model = '" + newName + "', " +
"UPDATE sys.rev.Query WHERE model = '" + oldName + "': {model := '" + newName + "'}, " +
"UPDATE sys.rev.Relvar WHERE model = '" + oldName + "': {model := '" + newName + "'};";
execute(query);
}
public void modelCopyTo(String oldName, String newName) {
if (oldName.equals(newName))
return;
String query = "DELETE sys.rev.Query WHERE model = '" + newName + "', " +
"DELETE sys.rev.Relvar WHERE model = '" + newName + "', " +
"INSERT sys.rev.Operator UPDATE sys.rev.Operator JOIN (((sys.rev.Query WHERE model = '" + oldName + "') {Name}) UNION ((sys.rev.Relvar WHERE model = '" + oldName + "') {Name})): {Name := Name || 'copy'}, " +
"INSERT sys.rev.Op_Update UPDATE sys.rev.Op_Update JOIN (((sys.rev.Query WHERE model = '" + oldName + "') {Name}) UNION ((sys.rev.Relvar WHERE model = '" + oldName + "') {Name})): {Name := Name || 'copy'}, " +
"INSERT sys.rev.Op_Extend UPDATE sys.rev.Op_Extend JOIN (((sys.rev.Query WHERE model = '" + oldName + "') {Name}) UNION ((sys.rev.Relvar WHERE model = '" + oldName + "') {Name})): {Name := Name || 'copy'}, " +
"INSERT sys.rev.Op_Summarize UPDATE sys.rev.Op_Summarize JOIN (((sys.rev.Query WHERE model = '" + oldName + "') {Name}) UNION ((sys.rev.Relvar WHERE model = '" + oldName + "') {Name})): {Name := Name || 'copy'}, " +
"INSERT sys.rev.Query UPDATE sys.rev.Query WHERE model = '" + oldName + "': {model := '" + newName + "', Name := Name || 'copy', connections := UPDATE connections: {Name := Name || 'copy'}}, " +
"INSERT sys.rev.Relvar UPDATE sys.rev.Relvar WHERE model = '" + oldName + "': {model := '" + newName + "', Name := Name || 'copy'};";
execute(query);
}
public boolean modelDelete(String name) {
String query =
"DELETE sys.rev.Operator WHERE TUPLE {Name Name} IN ((sys.rev.Query WHERE model = '" + name + "') {Name}) UNION ((sys.rev.Relvar WHERE model = '" + name + "') {Name}), " +
"DELETE sys.rev.Op_Update WHERE TUPLE {Name Name} IN ((sys.rev.Query WHERE model = '" + name + "') {Name}) UNION ((sys.rev.Relvar WHERE model = '" + name + "') {Name}), " +
"DELETE sys.rev.Op_Extend WHERE TUPLE {Name Name} IN ((sys.rev.Query WHERE model = '" + name + "') {Name}) UNION ((sys.rev.Relvar WHERE model = '" + name + "') {Name}), " +
"DELETE sys.rev.Op_Summarize WHERE TUPLE {Name Name} IN ((sys.rev.Query WHERE model = '" + name + "') {Name}) UNION ((sys.rev.Relvar WHERE model = '" + name + "') {Name}), " +
"DELETE sys.rev.Query WHERE model = '" + name + "', " +
"DELETE sys.rev.Relvar WHERE model = '" + name + "';";
return execute(query);
}
public Vector<String> getModels() {
String query = "(sys.rev.Query {model}) UNION (sys.rev.Relvar {model})";
Tuples tuples = (Tuples)evaluate(query);
Vector<String> models = new Vector<String>();
for (Tuple tuple: tuples)
models.add(tuple.get("model").toString());
return models;
}
public boolean relvarExists(String name) {
String query = "COUNT(sys.Catalog WHERE Name = '" + name + "') > 0";
Value result = (Value)evaluate(query);
return result.toBoolean();
}
public boolean scriptExists(String name) {
String query = "COUNT(sys.rev.Script WHERE Name = '" + name + "') > 0";
Value result = (Value)evaluate(query);
return result.toBoolean();
}
public boolean createScript(String name) {
String query = "INSERT sys.rev.Script RELATION {TUPLE {Name '" + name + "', text ''}};";
return execute(query);
}
public static class Script {
private String content;
private Vector<String> history;
public Script(String content, Vector<String> history) {
this.content = content;
this.history = history;
}
public Vector<String> getHistory() {
return history;
}
public String getContent() {
return content;
}
}
public Script getScript(String name) {
String query = "sys.rev.Script WHERE Name='" + name + "'";
String content = "";
Tuples tuples = (Tuples)evaluate(query);
for (Tuple tuple: tuples)
content = StringUtils.unquote(tuple.get("text").toString());
query = "sys.rev.ScriptHistory WHERE Name='" + name + "' ORDER (ASC timestamp)";
tuples = (Tuples)evaluate(query);
Vector<String> history = new Vector<String>();
for (Tuple tuple: tuples)
history.add(StringUtils.unquote(tuple.get("text").toString()));
return new Script(content, history);
}
public void setScript(String name, String content) {
String text = StringUtils.quote(content);
String query =
"IF COUNT(sys.rev.Script WHERE Name='" + name + "') = 0 THEN " +
" INSERT sys.rev.Script REL {TUP {Name '" + name + "', text '" + text + "'}}; " +
"ELSE " +
" UPDATE sys.rev.Script WHERE Name='" + name + "': {text := '" + text + "'}; " +
"END IF;";
execute(query);
}
public void addScriptHistory(String name, String historyItem) {
String timestamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss.SSS").format(new Date());
String query =
"INSERT sys.rev.ScriptHistory " + "REL {TUP {" +
" Name '" + name + "', " +
" text '" + StringUtils.quote(historyItem) + "', " +
" timestamp '" + timestamp + "'" +
"}};";
execute(query);
}
public boolean scriptDelete(String name) {
String query = "DELETE sys.rev.Script WHERE Name='" + name + "';";
return execute(query);
}
public boolean renameScript(String nameFrom, String nameTo) {
String query =
"UPDATE sys.rev.Script WHERE Name='" + nameFrom + "': {Name := '" + nameTo + "'}, " +
"UPDATE sys.rev.ScriptHistory WHERE Name='" + nameFrom + "': {Name := '" + nameTo + "'};";
return execute(query);
}
public void setSetting(String name, String value) {
String query =
"IF COUNT(sys.rev.Settings WHERE Name='" + name + "') = 0 THEN " +
" INSERT sys.rev.Settings REL {TUP {Name '" + name + "', value '" + StringUtils.quote(value) + "'}}; " +
"ELSE " +
" UPDATE sys.rev.Settings WHERE Name='" + name + "': {value := '" + StringUtils.quote(value) + "'}; " +
"END IF;";
execute(query);
}
public String getSetting(String name) {
String query = "sys.rev.Settings WHERE Name='" + name + "'";
Tuples tuples = (Tuples)evaluate(query);
for (Tuple tuple: tuples)
return StringUtils.unquote(tuple.get("value").toString());
return "";
}
public static class Overview {
private String content;
private boolean revPrompt;
public Overview(String content, boolean revPrompt) {
this.content = content;
this.revPrompt = revPrompt;
}
public String getContent() {
return content;
}
public boolean getRevPrompt() {
return revPrompt;
}
}
public Overview getOverview() {
String query = "pub.Overview";
Tuples tuples = (Tuples)evaluate(query);
try {
for (Tuple tuple: tuples) {
String content = StringUtils.unquote(tuple.get("content").toString());
boolean revPrompt = tuple.get("revPrompt").toBoolean();
return new Overview(content, revPrompt);
}
} catch (Exception e) {}
return new Overview("", true);
}
public boolean createOverview() {
String query =
"VAR pub.Overview REAL RELATION {content CHAR, revPrompt BOOLEAN} KEY {}; " +
"INSERT pub.Overview RELATION {TUP {content '" +
StringUtils.quote(
"Edit the pub.Overview variable to change this text.\n" +
"The 'contents' attribute value will appear here.\n" +
"Set the 'revPrompt' attribute to FALSE to only display this overview."
) + "', revPrompt TRUE}};";
return execute(query);
}
public String[] getKeywords() {
return connection.getKeywords();
}
public String[] getRelvarTypes() {
String query = "UNION {sys.ExternalRelvarTypes {Identifier, Description}, REL {TUP {Identifier 'REAL', Description 'REAL relation-valued variable.'}}} ORDER (ASC Identifier)";
Tuples tuples = (Tuples)evaluate(query);
Vector<String> types = new Vector<String>();
try {
for (Tuple tuple: tuples) {
String identifier = StringUtils.unquote(tuple.get("Identifier").toString());
String description = StringUtils.unquote(tuple.get("Description").toString());
types.add(identifier + ": " + description);
}
} catch (Exception e) {}
return types.toArray(new String[0]);
}
public Tuple getExternalRelvarTypeInfo(String variableType) {
String query = "sys.ExternalRelvarTypes WHERE Identifier='" + variableType + "'";
Tuples tuples = (Tuples)evaluate(query);
for (Tuple tuple: tuples)
return tuple;
return null;
}
}