Search in sources :

Example 1 with NamedParameter

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);
}
Also used : DataSet(net.sourceforge.sqlexplorer.dataset.DataSet) CallableStatement(java.sql.CallableStatement) NamedParameter(net.sourceforge.sqlexplorer.parsers.NamedParameter) TreeMap(java.util.TreeMap)

Example 2 with NamedParameter

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;
}
Also used : SQLException(java.sql.SQLException) NamedParameter(net.sourceforge.sqlexplorer.parsers.NamedParameter) LinkedList(java.util.LinkedList)

Example 3 with NamedParameter

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;
    }
}
Also used : SQLException(java.sql.SQLException) Statement(java.sql.Statement) CallableStatement(java.sql.CallableStatement) PreparedStatement(java.sql.PreparedStatement) CallableStatement(java.sql.CallableStatement) NamedParameter(net.sourceforge.sqlexplorer.parsers.NamedParameter) PreparedStatement(java.sql.PreparedStatement)

Aggregations

NamedParameter (net.sourceforge.sqlexplorer.parsers.NamedParameter)3 CallableStatement (java.sql.CallableStatement)2 SQLException (java.sql.SQLException)2 PreparedStatement (java.sql.PreparedStatement)1 Statement (java.sql.Statement)1 LinkedList (java.util.LinkedList)1 TreeMap (java.util.TreeMap)1 DataSet (net.sourceforge.sqlexplorer.dataset.DataSet)1