package org.reldb.rel.v0.storage.relvars.external.relvar;
import java.io.IOException;
import java.util.Vector;
import org.reldb.rel.client.connection.string.ClientNetwork;
import org.reldb.rel.exceptions.ExceptionSemantic;
import org.reldb.rel.shared.Defaults;
import org.reldb.rel.v0.generator.Generator;
import org.reldb.rel.v0.interpreter.Evaluation;
import org.reldb.rel.v0.interpreter.Interpreter;
import org.reldb.rel.v0.storage.RelDatabase;
import org.reldb.rel.v0.storage.relvars.RelvarCustomMetadata;
import org.reldb.rel.v0.storage.relvars.RelvarExternal;
import org.reldb.rel.v0.storage.relvars.RelvarGlobal;
import org.reldb.rel.v0.storage.relvars.RelvarHeading;
import org.reldb.rel.v0.storage.relvars.external.CSVLineParse;
import org.reldb.rel.v0.storage.tables.TableExternal.DuplicateHandling;
import org.reldb.rel.v0.types.Attribute;
import org.reldb.rel.v0.types.Heading;
import org.reldb.rel.v0.types.TypeRelation;
public class RelvarRELVARMetadata extends RelvarCustomMetadata {
public static final long serialVersionUID = 0;
private String connectionString;
private String host;
private String user;
private String password;
private String relvar;
private int port = Defaults.getDefaultPort();
public static RelvarHeading getHeading(RelDatabase database, String spec, DuplicateHandling duplicates) {
String[] values = CSVLineParse.parseTrimmed(spec);
if (values.length != 4 && values.length != 5)
throw new ExceptionSemantic("RS0482: Invalid arguments. Expected: HOST, USER, PASSWORD, RELVAR, [PORT] but got " + spec);
String host = values[0];
// String user = values[1];
// String password = values[2];
String relvar = values[3];
int port = Defaults.getDefaultPort();
if (values.length == 5) {
String portValue = values[4];
try {
port = Integer.parseInt(portValue);
} catch (NumberFormatException nfe) {
throw new ExceptionSemantic("RS0488: Invalid port specification: " + portValue);
}
}
// Send query to remote Rel DBMS
String response = "";
try {
ClientNetwork connection = new ClientNetwork(host, port);
connection.sendEvaluate(relvar + " WHERE false");
String line;
while ((line = connection.receive()) != null)
response += line;
} catch (IOException ioe) {
throw new ExceptionSemantic("RS0494: Error obtaining remote Rel relvar: " + ioe);
}
// Interpret response using local Rel DBMS
try {
Interpreter interpreter = new Interpreter(database, System.out);
Evaluation result = interpreter.evaluate(response);
if (!(result.getType() instanceof TypeRelation))
throw new ExceptionSemantic("RS0493: Error obtaining remote Rel relvar.");
TypeRelation typeRelation = (TypeRelation)result.getType();
Heading heading = new Heading();
Vector<Attribute> attributes = typeRelation.getHeading().getAttributes();
for (Attribute attribute: attributes)
heading.add(attribute);
RelvarHeading relvarHeading = new RelvarHeading(heading);
return relvarHeading;
} catch (Throwable t) {
throw new ExceptionSemantic("RS0492: Error obtaining remote Rel relvar: " + t);
}
}
@Override
public String getSourceDefinition() {
return "EXTERNAL RELVAR \"" + host + "," + user + "," + password + "," + relvar + "," + port + "\"";
}
public RelvarRELVARMetadata(RelDatabase database, String owner, String spec, DuplicateHandling duplicates) {
super(database, getHeading(database, spec, duplicates), owner);
String[] values = CSVLineParse.parseTrimmed(spec);
host = values[0];
user = values[1];
password = values[2];
relvar = values[3];
if (values.length == 5) {
String portValue = values[4];
try {
port = Integer.parseInt(portValue);
} catch (NumberFormatException nfe) {
throw new ExceptionSemantic("RS0495: Invalid port specification: " + portValue);
}
}
connectionString = spec;
}
@Override
public RelvarGlobal getRelvar(String name, RelDatabase database) {
return new RelvarExternal(name, database, new Generator(database, System.out), this, DuplicateHandling.DUP_REMOVE);
}
@Override
public void dropRelvar(RelDatabase database) {
}
public String getConnectionString() {
return connectionString;
}
public String getHost() {
return host;
}
public String getUser() {
return user;
}
public String getPassword() {
return password;
}
public String getRelvar() {
return relvar;
}
public int getPort() {
return port;
}
@Override
public String tableClassName() {
return "TableRELVAR";
}
@Override
public String getType() {
return "RELVAR";
}
}