use of net.sourceforge.sqlexplorer.parsers.NamedParameter in project tdq-studio-se by Talend.
the class ExecutionResultImpl method nextDataSet.
public DataSet nextDataSet() throws SQLException {
// Close the current one
if (currentResultSet != null) {
currentResultSet.close();
currentResultSet = null;
}
// Anything more to do?
if (state == State.CLOSED) {
return null;
}
// Get the first set
if (state == State.PRIMARY_RESULTS) {
currentResultSet = stmt.getResultSet();
state = State.SECONDARY_RESULTS;
if (currentResultSet != null) {
return new DataSet(currentResultSet, null, maxRows);
}
}
// getResults())
while (state == State.SECONDARY_RESULTS) {
// MOD msjian TDQ-5927, fix the "statement is not executing" error for SQLite.
if ("org.sqlite.PrepStmt".equals(stmt.getClass().getName())) {
return null;
}
// "updateCountState()"
if (stmt.getClass().getName().contains(hiveStatementClassName)) {
updateCountState();
} else if (stmt.getMoreResults()) {
currentResultSet = stmt.getResultSet();
} else {
updateCountState();
}
// ~ xqliu 2014-03-18
}
// Got one? Then exit
if (currentResultSet != null) {
this.updateCount += stmt.getUpdateCount();
return new DataSet(currentResultSet, null, maxRows);
}
// Look for output parameters which return resultsets
if (state == State.PARAMETER_RESULTS && parameters != null) {
CallableStatement stmt = (CallableStatement) this.stmt;
if (paramIter == null) {
paramIter = parameters.iterator();
paramColumnIndex = 1;
}
while (paramIter.hasNext()) {
NamedParameter param = paramIter.next();
if (param.getDataType() == NamedParameter.DataType.CURSOR) {
currentResultSet = product.getResultSet(stmt, param, paramColumnIndex);
}
paramColumnIndex++;
if (currentResultSet != null) {
return new DataSet(Messages.getString("DataSet.Cursor") + ' ' + param.getName(), currentResultSet, null, maxRows);
}
}
}
// Generate a dataset for output parameters
state = State.CLOSED;
if (parameters == null) {
return null;
}
if (!(stmt instanceof CallableStatement)) {
return null;
}
CallableStatement stmt = (CallableStatement) this.stmt;
TreeMap<NamedParameter, ParamValues> params = new TreeMap<NamedParameter, ParamValues>();
int columnIndex = 1;
int numValues = 0;
for (NamedParameter param : parameters) {
if (param.getDataType() != NamedParameter.DataType.CURSOR && param.isOutput()) {
ParamValues pv = params.get(param);
if (pv == null) {
params.put(param, new ParamValues(param, columnIndex));
} else {
pv.add(columnIndex);
}
numValues++;
}
columnIndex++;
}
if (numValues == 0) {
return null;
}
Comparable[][] rows = new Comparable[numValues][2];
columnIndex = 1;
int rowIndex = 0;
for (ParamValues pv : params.values()) {
int valueIndex = 1;
for (Integer index : pv.columnIndexes) {
Comparable[] row = rows[rowIndex++];
row[0] = pv.param.getName();
if (pv.columnIndexes.size() > 1) {
row[0] = (pv.param.getName() + '[' + valueIndex + ']');
} else {
row[0] = pv.param.getName();
}
row[1] = stmt.getString(index);
valueIndex++;
}
}
return new DataSet(Messages.getString("DataSet.Parameters"), new String[] { Messages.getString("SQLExecution.ParameterName"), Messages.getString("SQLExecution.ParameterValue") }, rows);
}
use of net.sourceforge.sqlexplorer.parsers.NamedParameter in project tdq-studio-se by Talend.
the class AbstractDatabaseProduct method locateNamedParameters.
/**
* Scans the StringBuffer looking for named parameters (in the form ":paramname"), and
* looking up the parameter in map. It returns a list of those parameters; note that
* the list will contain duplicates if the named parameter is referenced more than once
* @param sb
* @param map
* @return
*/
protected LinkedList<NamedParameter> locateNamedParameters(StringBuffer sb, Map<String, NamedParameter> map) throws SQLException {
LinkedList<NamedParameter> results = new LinkedList<NamedParameter>();
// The quote character when we're in the middle of a string
char inQuote = 0;
// The string to look for which terminates a comment (if we're currenbtly parsing one);
// null if not currently parsing a comment
String inComment = null;
// Where the identifier started, relative to the buffer (-1 means no identifier yet)
int idStart = -1;
for (int i = 0; i < sb.length(); i++) {
char c = sb.charAt(i);
char nextC = (i < sb.length() - 1) ? sb.charAt(i + 1) : 0;
// If we're in an identifier
if (idStart != -1) {
// Still an identifier?
if (Character.isJavaIdentifierPart(c))
continue;
// Find the parameter
String name = sb.substring(idStart + 1, i);
NamedParameter param = map.get(name);
// Ignore null parameters because they may be a valid syntax on the server
if (param != null) {
results.add(param);
sb.delete(idStart + 1, i);
sb.setCharAt(idStart, '?');
}
// Next!
idStart = -1;
continue;
}
// Already inside a string? Check for the end of the string
if (inQuote != 0) {
if (c == '\'' || c == '\"') {
// Double just escapes, it does not terminate the string
if (nextC != c)
inQuote = 0;
}
continue;
}
// Already in a comment
if (inComment != null) {
// If inComment is empty then we're in a single-line comment; check for EOL
if (inComment.length() == 0) {
if (c == '\n')
inComment = null;
continue;
}
// Otherwise inComment is the string which terminates the comment
if (c == inComment.charAt(0) && nextC == inComment.charAt(1)) {
inComment = null;
continue;
}
}
// Starting a single-line comment?
if (c == '-' && nextC == '-') {
inComment = "";
continue;
}
// Starting a multi-line comment?
if (c == '/' && nextC == '*') {
inComment = "*/";
continue;
}
// Starting a string?
if (c == '\'' || c == '\"') {
inQuote = c;
continue;
}
// Finally - is it a named parameter?
if (c == ':' && Character.isJavaIdentifierPart(nextC)) {
idStart = i;
}
}
// Check for a parameter which exists at the very end of the string
if (idStart > -1) {
String name = sb.substring(idStart + 1);
NamedParameter param = map.get(name);
if (param == null)
throw new SQLException("Unknown named parameter called " + name);
results.add(param);
sb.delete(idStart + 1, sb.length());
sb.setCharAt(idStart, '?');
}
if (results.isEmpty())
return null;
return results;
}
use of net.sourceforge.sqlexplorer.parsers.NamedParameter in project tdq-studio-se by Talend.
the class AbstractDatabaseProduct method executeQuery.
public ExecutionResults executeQuery(SQLConnection connection, Query query, int maxRows) throws SQLException {
Statement stmt = null;
try {
CharSequence querySql = query.getQuerySql();
LinkedList<NamedParameter> params = null;
// Apply any named parameters
if (query.getQueryType() != Query.QueryType.DDL) {
Map<String, NamedParameter> map = query.getNamedParameters();
if (map != null && !map.isEmpty()) {
StringBuffer sb = new StringBuffer(querySql);
params = locateNamedParameters(sb, map);
querySql = sb;
}
}
/*
* Create the statement. Note that we only create a CallableStatement if
* we have parameters; this is because some databases (MySQL) require that
* prepareCall is only used for stored code. CallableStatements are only
* needed for output parameters so because we cannot reliably detect what
* the query is (DDL/DML/SELECT/CODE/etc) unless there is a specialised
* parser, we rely on whether the user has given any named parameters.
*
* Similarly, use Statement when we're just doing DDL - eg Oracle will
* not create triggers when using PreparedStatement when it contains
* references to :new or :old.
*/
boolean hasResults = false;
if (query.getQueryType() == Query.QueryType.DDL) {
stmt = connection.getConnection().createStatement();
hasResults = stmt.execute(querySql.toString());
} else if (params != null) {
CallableStatement cstmt = connection.getConnection().prepareCall(querySql.toString());
stmt = cstmt;
int columnIndex = 1;
for (NamedParameter param : params) configureStatement((CallableStatement) stmt, param, columnIndex++);
hasResults = cstmt.execute();
} else {
PreparedStatement pstmt = connection.getConnection().prepareStatement(querySql.toString());
stmt = pstmt;
// no sense for non-select anyway.
if (query.getQueryType() == Query.QueryType.SELECT)
try {
stmt.setMaxRows(maxRows);
} catch (SQLException e) {
// Nothing
}
hasResults = pstmt.execute();
}
return new ExecutionResultImpl(this, stmt, hasResults, params, maxRows);
} catch (SQLException e) {
try {
if (stmt != null)
stmt.close();
} catch (SQLException e2) {
// Nothing
}
throw e;
}
}
Aggregations