package org.syrup.sql;
import org.syrup.Context;
import org.syrup.Data;
import org.syrup.LogEntry;
import org.syrup.PTask;
import org.syrup.helpers.ContextImpl;
import org.syrup.helpers.DataImpl;
import org.syrup.helpers.EndPoint;
import org.syrup.helpers.LogEntryImpl;
import org.syrup.helpers.PTaskImpl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
/**
* Utility functions to query Syrup objects using JDBC.
*
* @author Robbert van Dalen
*/
public class QueryFunctions extends Functions
{
static final String COPYRIGHT = "Copyright 2005 Robbert van Dalen."
+ "At your option, you may copy, distribute, or make derivative works under "
+ "the terms of The Artistic License. This License may be found at "
+ "http://www.opensource.org/licenses/artistic-license.php. "
+ "THERE IS NO WARRANTY; USE THIS PRODUCT AT YOUR OWN RISK.";
/**
* Constructor for the QueryFunctions object
*
* @param sqlImpl
* The SQLImpl that is held by the Function instance.
*/
public QueryFunctions(SQLImpl sqlImpl)
{
super(sqlImpl);
}
/**
* Returns true if a PTask is done by executing SQL statements over a
* Connection.
*
* @param key
* The PTask identifier that is checked.
* @param con
* The SyrupConnection over which SQL statements are executed.
* @return True if the Ptask is done.
*/
protected boolean checkDone(String key, SyrupConnection con) throws Exception
{
boolean done = false;
PreparedStatement s = null;
ResultSet result = null;
try
{
s = con.prepareStatementFromCache(sqlImpl().sqlStatements().selectDoneStatement());
s.setString(1, key);
result = s.executeQuery();
if (result.next())
{
done = result.getBoolean("done");
}
else
{
throw new Exception("Internal error: task id not valid");
}
}
finally
{
sqlImpl().genericFunctions().close(result);
}
return done;
}
/**
* Returns true if the input Port of a PTask is done by executing SQL
* statements over a Connection.
*
* @param key
* The PTask identifier that is checked.
* @param port
* The input port number.
* @param con
* The SyrupConnection over which SQL statements are executed.
* @return True if the input of a PTask is done.
*/
protected boolean checkInDone(String key, boolean port, SyrupConnection con)
throws Exception
{
String k = readInTask(key, port, con);
if (k != null)
{
return checkDone(k, con);
}
return true;
}
protected boolean checkOutDone(String key, boolean port, SyrupConnection con)
throws Exception
{
String k = readOutTask(key, port, con);
if (k != null)
{
return checkDone(k, con);
}
return true;
}
/**
* Returns true if a PTask is of type OR by executing SQL statements over a
* Connection.
*
* @param key
* The PTask identifier that is checked.
* @param con
* The SyrupConnection over which SQL statements are executed.
* @return True if a PTask is of type OR.
*/
protected boolean checkOrType(String key, SyrupConnection con) throws Exception
{
boolean type = false;
PreparedStatement s = null;
ResultSet result = null;
try
{
s = con.prepareStatementFromCache(sqlImpl().sqlStatements().selectTypeStatement());
s.setString(1, key);
result = s.executeQuery();
if (result.next())
{
type = result.getBoolean("or_type");
}
else
{
throw new Exception("Internal error: task id not valid");
}
}
finally
{
sqlImpl().genericFunctions().close(result);
}
return type;
}
/**
* Returns true if the out Link of a PTask is full by executing SQL
* statements over a Connection.
*
* @param key
* The PTask identifier that is checked.
* @param port
* The Port number of the PTask's output Link that is checked.
* @param con
* The SyrupConnection over which SQL statements are executed.
* @return True if the Link is full.
*/
protected boolean checkOutLinkFull(String key, boolean port, SyrupConnection con)
throws Exception
{
return checkTargetLink(sqlImpl().sqlStatements().checkOutLinkFullStatement(), key, port, con);
}
/**
* Returns true if the input Link of a PTask is done by executing SQL
* statements over a Connection.
*
* @param key
* The PTask identifier that is checked.
* @param port
* The Port number of the PTask's input Link that is checked.
* @param con
* The SyrupConnection over which SQL statements are executed.
* @return True if the Link is full.
*/
protected boolean checkInLinkFull(String key, boolean port, SyrupConnection con)
throws Exception
{
return checkTargetLink(sqlImpl().sqlStatements().checkInLinkFullStatement(), key, port, con);
}
/**
* Returns true if the input Link of a PTask is done by executing SQL
* statements over a Connection.
*
* @param statement
* The SQL statement to check the ingoing/outgoing Link.
* @param key
* The PTask identifier that is checked.
* @param port
* The Port number of the PTask's input Link that is checked.
* @param con
* The SyrupConnection over which SQL statements are executed.
* @return True if the Link is full.
*/
protected boolean checkTargetLink(String statement, String key,
boolean port, SyrupConnection con) throws Exception
{
boolean isFull = false;
PreparedStatement s = null;
ResultSet r = null;
try
{
s = con.prepareStatementFromCache(statement);
s.setString(1, key);
s.setBoolean(2, port);
r = s.executeQuery();
if (r.next())
{
isFull = true;
}
else
{
// There is no Link and hence not filled.
isFull = false;
}
}
finally
{
sqlImpl().genericFunctions().close(r);
}
return isFull;
}
/**
* Returns the out EndPoint of a PTask by executing SQL statements over a
* Connection.
*
* @param key
* The PTask identifier.
* @param port
* The port of the PTask.
* @param con
* The SyrupConnection over which SQL statements are executed.
* @return The out EndPoint of a PTask.
*/
protected EndPoint readOutEndPoint(String key, boolean port, SyrupConnection con)
throws Exception
{
return readTargetEndPoint(sqlImpl().sqlStatements().selectOutLinkStatement(), key, port, con);
}
/**
* Returns the in EndPoint of a PTask by executing SQL statements over a
* Connection.
*
* @param key
* The subject PTask identifier.
* @param port
* The subject port of the PTask.
* @param con
* The SyrupConnection over which SQL statements are executed.
* @return The in EndPoint of a PTask.
*/
protected EndPoint readInEndPoint(String key, boolean port, SyrupConnection con)
throws Exception
{
return readTargetEndPoint(sqlImpl().sqlStatements().selectInLinkStatement(), key, port, con);
}
/**
* Returns the in/out EndPoint of a PTask by executing SQL statements over a
* Connection.
*
* @param st
* The SQL statement to return the in/out EndPoint.
* @param key
* The subject PTask identifier.
* @param port
* The subject port of the PTask.
* @param con
* The SyrupConnection over which SQL statements are executed.
* @return The in/out EndPoint of a PTask.
*/
protected EndPoint readTargetEndPoint(String st, String key, boolean port,
SyrupConnection con) throws Exception
{
EndPoint endp = null;
PreparedStatement s = null;
ResultSet r = null;
try
{
s = con.prepareStatementFromCache(st);
s.setString(1, key);
s.setBoolean(2, port);
r = s.executeQuery();
if (r.next())
{
endp = new EndPoint(readPTask(r.getString("task"), con), r.getBoolean("port"), readData(r, "data"));
}
}
finally
{
sqlImpl().genericFunctions().close(r);
}
return endp;
}
/**
* Returns the out PTask identifier of a PTask by executing SQL statements
* over a Connection.
*
* @param key
* The subject PTask identifier.
* @param port
* The subject port of the PTask.
* @param con
* The SyrupConnection over which SQL statements are executed.
* @return The out PTask identifier of a PTask.
*/
protected String readOutTask(String key, boolean port, SyrupConnection con)
throws Exception
{
return readTargetLinkTask(sqlImpl().sqlStatements().selectOutLinkTaskStatement(), key, port, con);
}
/**
* Returns the in PTask identifier of a PTask by executing SQL statements
* over a Connection.
*
* @param key
* The subject PTask identifier.
* @param port
* The subject port of the PTask.
* @param con
* The SyrupConnection over which SQL statements are executed.
* @return The in PTask identifier of a PTask.
*/
protected String readInTask(String key, boolean port, SyrupConnection con)
throws Exception
{
return readTargetLinkTask(sqlImpl().sqlStatements().selectInLinkTaskStatement(), key, port, con);
}
/**
* Returns the in/out PTask identifier of a PTask by executing SQL
* statements over a Connection.
*
* @param st
* The SQL statement to return the in/out PTask identifier..
* @param key
* The subject PTask identifier.
* @param port
* The subject port of the PTask.
* @param con
* The SyrupConnection over which SQL statements are executed.
* @return The in/out PTask identifier of a PTask.
*/
protected String readTargetLinkTask(String st, String key, boolean port,
SyrupConnection con) throws Exception
{
PreparedStatement s = null;
ResultSet r = null;
try
{
s = con.prepareStatementFromCache(st);
s.setString(1, key);
s.setBoolean(2, port);
r = s.executeQuery();
if (r.next())
{
String k = r.getString("task");
return k;
}
}
finally
{
sqlImpl().genericFunctions().close(r);
}
return null;
}
/**
* Returns the Context of a PTask by executing SQL statements over a
* Connection.
*
* @param p
* The subject PTask.
* @param con
* The SyrupConnection over which SQL statements are executed.
* @return The Context of a PTask.
*/
protected Context readContext(PTask p, SyrupConnection con) throws Exception
{
EndPoint in_1 = readInEndPoint(p.key(), false, con);
EndPoint in_2 = readInEndPoint(p.key(), true, con);
EndPoint out_1 = readOutEndPoint(p.key(), false, con);
EndPoint out_2 = readOutEndPoint(p.key(), true, con);
// [TODO: check if it is necessary to read it again, or can we take the
// given parameter p?]
PTask self = readPTask(p.key(), con);
return new ContextImpl(self, in_1, in_2, out_1, out_2);
}
/**
* Returns the Data contained by a ResultSet.
*
* @param result
* The ResultSet the contains the raw data.
* @param k
* The SQL attribute to fetch.
* @return The Data contained by a ResultSet.
*/
protected Data readData(ResultSet result, String k) throws Exception
{
byte[] d = result.getBytes(k);
if (d != null)
{
return new DataImpl(d);
}
return null;
}
/**
* Returns the PTask, given an identifier, by executing SQL statements over
* a Connection.
*
* @param key
* The identifier of a PTask.
* @param con
* The SyrupConnection over which SQL statements are executed.
* @return The PTask, given an identifier.
*/
protected PTask readPTask(String key, SyrupConnection con) throws Exception
{
PTask t = null;
ResultSet r = null;
if (key != null)
{
PreparedStatement s = null;
try
{
s = con.prepareStatementFromCache(sqlImpl().sqlStatements().selectTaskStatement());
s.setString(1, key);
r = s.executeQuery();
if (r.next())
{
t = readPTask(r);
}
else
{
return null;
}
}
finally
{
sqlImpl().genericFunctions().close(r);
}
}
return t;
}
/**
* Returns a PTask held by a ResultSet
*
* @param result
* The ResultSet that holds the PTask attributes.
* @return The PTask held by a ResultSet.
*/
protected PTask readPTask(ResultSet result) throws Exception
{
PTask ptask = new PTaskImpl(result.getString("parent_key"), result.getString("key_"),
result.getBoolean("or_type"), result.getString("function_class"),
result.getString("name"), result.getString("description"),
result.getString("parameter"), result.getString("environment"), result.getBoolean("done"),
result.getLong("creation_time"), result.getLong("modification_time"),
result.getLong("modifications"), result.getBoolean("executable"),
result.getString("worker"), result.getBoolean("is_parent"));
return ptask;
}
/**
* Returns a LogEntry held by a ResultSet
*
* @param result
* The ResultSet that holds the LogEntry attributes.
* @return The LogEntry held by a ResultSet.
*/
protected LogEntry readLogEntry(ResultSet result) throws Exception
{
LogEntry logentry = new LogEntryImpl(result.getLong("creation_time"), result.getString("key_"), (int) result.getInt("event"), result.getString("worker"));
return logentry;
}
}