package communication; import communication.optimizer.OptimizerInterface; import communication.optimizer.IntObj; import java.sql.SQLException; import tools.Reporter; //import Verbindungstest.Declarations; import sj.lang.ESInterface; import sj.lang.ListExpr; import sj.lang.IntByReference; /** * * Task of this class
*It handles all the communication between secondo and any other packet.
*Since most of the classes within communication are protected it makes sense to *have such a class */ public class CommunicationInterface { private final String AlterTempTabName = "typeTesttmp"; //AlterTabTmp private OptimizerInterface OI; private ESInterface SI; private ListExpr LEresult; private IntByReference ErrCode; private IntByReference ErrPos; private StringBuffer ErrMess; private boolean connectedToDB; private String connectedDB; private IntObj OptIO; //needed for the Optimizer, it contains the errorcode private int SecPort; private int OptPort; private String HostName; private String AlterCommand2, AlterCommand3, AlterCommand4; //Additional commands for ALTER TABLE public CommunicationInterface() { ErrCode = new IntByReference(); ErrPos = new IntByReference(); ErrMess = new StringBuffer(); LEresult = new ListExpr(); OI = new OptimizerInterface(); SI = new ESInterface(); OptIO = new IntObj(); connectedToDB = false; } /** * Task of this method
* initializes connection to Secondo server and Secondo optimizer * @return true if connection has been established */ public boolean initialize(String HName, int SPort, int OPort) { boolean IstOk = false; HostName = HName; SecPort = SPort; OptPort = OPort; if (SI.initialize("", "", HostName, SecPort)) { Reporter.writeInfo("connected to Secondo server"); SI.useBinaryLists(true); IstOk = true; } else Reporter.writeError("ERROR: Connection to Secondo server could not be established"); OI.setHost(HostName); OI.setPort(OptPort); if (OI.connect()) Reporter.writeInfo("Connected to Secondo optimizer"); else { Reporter.writeError("ERROR: Connection to Secondo optimizer could not be established"); IstOk = false; } return IstOk; } /** * Task of this method
* It establishes a connection to a given database * @param DBName Name of the database * @return true if connection has been established */ public boolean connectToDB(String DBName) throws SQLException { if (!connectedToDB) { //Reporter.writeInfo("Connect to DB " + DBName); SI.secondo("open database "+ DBName +";", LEresult, ErrCode, ErrPos, ErrMess); /* System.out.println(Ergebnis.toString()); System.out.println(ErrMess.toString()); */ if (ErrMess.toString().equals("")) { connectedToDB = true; connectedDB = DBName; } else { SQLException ex = new SQLException("Connection to database could not be established", "08001"); SQLException next = new SQLException(ErrMess.toString()); ex.setNextException(next); throw ex; } } else Reporter.writeWarning("Database is already connected to " + connectedDB); return connectedToDB; } public boolean isConnected() { if (!SI.isInitialized()) { this.connectedDB = ""; this.connectedToDB = false; } return this.connectedToDB; } /** * Task of this method
* The connection to the Optimizer Server and to the Secondo Server is terminated
* It reports an error if the connection has not been established */ public void closeDB() { if (connectedToDB) { OI.disconnect(); SI.terminate(); connectedToDB = false; connectedDB = ""; } else Reporter.writeError("DB was already disconnected"); } /** * Task of this method
* getter for result of a query or an update * @return Ergebnis usually used after having executed a query or update */ public ListExpr getResult() { return this.LEresult; } /** * Task of this method
* it gives a test query to the optimizer and then transfers the optimizers
* answer to the secondo server. It just works if the database testqueries has been opened. * @return true if the result of the test was as expected */ /*public boolean Testit() { boolean IstOk = false; if ((connectedToDB) && (connectedDB.equalsIgnoreCase("testqueries"))) { String Ausgabe = OI.optimize_execute(Declarations.Testquery, Declarations.TestDB, OptIO, false); // false means the optimizer is evaluating a query SI.secondo("query "+Ausgabe, Ergebnis, ErrCode, ErrPos, ErrMess); if (Ergebnis.toString().contains("(1)\n (2)\n (3)\n (4)")) IstOk = true; } return IstOk; }*/ /** * * Task of this method
* It sends the command to the optimizer and in case of a query
* or an update sends the execution plan to the secondo server. * @param command a string which contains the command to be executed * by the secondo server * @return true if the execution worked */ public boolean executeCommand(String command) { boolean IstOk = false; boolean IsUpdate = false; boolean AlterTCommand = false; String result; /* IsUpdate is always false. If changed to true it is expected * than a sql mquerie command is given. In this case the command * would be processed by the Optimizer directly * if (command.startsWith("select")) IsUpdate = false; else IsUpdate = true; */ LEresult = new ListExpr(); // after executeCommand has been invoked for the second time // it still has the result from the first call. Therfore it is // reinitialized here if(command.startsWith("altertable")) { AlterTCommand = true; result = this.getAlterCommands(command); } else result = OI.optimize_execute(command, connectedDB, OptIO, IsUpdate); if (result.startsWith("::ERROR")) Reporter.writeError(result); else if (result.equals("done")) // DDL-Command like CREATE TABLE IstOk = true; else { if (!AlterTCommand) result="query "+result; SI.secondo(result, LEresult, ErrCode, ErrPos, ErrMess); if (ErrCode.value == 0) { if (AlterTCommand) { SI.secondo(AlterCommand2, LEresult, ErrCode, ErrPos, ErrMess); SI.secondo(AlterCommand3, LEresult, ErrCode, ErrPos, ErrMess); SI.secondo(AlterCommand4, LEresult, ErrCode, ErrPos, ErrMess); //OI.optimize_execute("updateCatalog", connectedDB, OptIO, true); } IstOk = true; //query was successful Reporter.reportInfo(LEresult.toString(), true); } else Reporter.writeError(ErrMess.toString()); } return IstOk; } public void executeSettings(boolean UseSubqueries) { String Ausgabe=""; String command=""; if (UseSubqueries) command = "setOption(subqueries)"; else command = "delOption(subqueries)"; Ausgabe = OI.optimize_execute(command, connectedDB, OptIO, true); } /*test public void executeSettings1(String command) { String Ausgabe=""; Ausgabe = OI.optimize_execute(command, connectedDB, OptIO, true); }*/ public void executeSecSettings(String statm) { LEresult = new ListExpr(); SI.secondo(statm, LEresult, ErrCode, ErrPos, ErrMess); } /** * * Task of this method
* has been implemented for DatabaseMetaDataImpl * @return connection parameter for the current database connection */ public String getUrl() { String result; if (this.connectedToDB) result = "jdbc:secondo://"+this.HostName+":"+this.SecPort+":"+this.OptPort+"/"+this.connectedDB; else result = null; return result; } private String getAlterCommands(String OrgCommand) { String tabName, colName, commandTemp, PreCommand, result; String colType = ""; int pos1, pos2; LEresult = new ListExpr(); commandTemp = OrgCommand.substring(11); pos1 = commandTemp.indexOf(";"); tabName = commandTemp.substring(0, pos1); commandTemp = commandTemp.substring(pos1+1); pos1 = commandTemp.indexOf(';'); if (OrgCommand.contains(";add;")) { String FirstLetter; pos2 = commandTemp.substring(pos1+1).indexOf(';'); FirstLetter = commandTemp.substring(pos1+1, pos1+2); // First letter of a column needs to be a capital letter colName = FirstLetter.toUpperCase() + commandTemp.substring(pos1 + 2, pos1 + 1 + pos2); colType = commandTemp.substring(pos1+pos2+2); } else { // ALTER TABLE DROP String PreResult; colName = commandTemp.substring(pos1 + 1); PreCommand = "select " + colName + " from " + tabName; PreResult = OI.optimize_execute(PreCommand, connectedDB, OptIO, false); pos1 = PreResult.indexOf('['); pos2 = PreResult.indexOf(']'); colName = PreResult.substring(pos1+1, pos2); } PreCommand = "query getcatalog() filter[ tolower(\'\' + .ObjectName) = \""+tabName+"\"] filter[.TypeExpr startsWith \"(rel\"] extract[ObjectName]"; SI.secondo(PreCommand, LEresult, ErrCode, ErrPos, ErrMess); tabName = LEresult.second().stringValue(); // get real name of table (with correct upper case spelling) // create the 4 orders for the alter table command if (OrgCommand.contains(";add;")) result = "let " + AlterTempTabName + " = " + tabName + " feed extend[" +colName+ " : [const "+colType+" value undef]] consume"; else result = "let " + AlterTempTabName + " = " + tabName + " feed remove[" +colName+ "] consume"; AlterCommand2 = "delete " + tabName; AlterCommand3 = "let " + tabName + " = " + AlterTempTabName; AlterCommand4 = "delete " + AlterTempTabName; return result; } }