⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jdbcconnection.java

📁 hsql是很有名的嵌入式数据库
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
     * <!-- end generic documentation -->
     * <!-- start release-specific documentation -->
     * <div class="ReleaseSpecificDocumentation">
     * <h3>HSQLDB-Specific Information:</h3> <p>
     *
     * Up to and including 1.7.2, HSQLDB converts the JDBC SQL
     * grammar into the system's native SQL grammar prior to sending
     * it, if escape processing is set true; this method returns the
     * native form of the statement that the driver would send in place
     * of client-specified JDBC SQL grammar. <p>
     *
     * Before 1.7.2, escape processing was incomplete and
     * also broken in terms of support for nested escapes. <p>
     *
     * Starting with 1.7.2, escape processing is complete and handles nesting
     * to arbitrary depth, but enforces a very strict interpretation of the
     * syntax and does not detect or process SQL comments. <p>
     *
     * In essence, the HSQLDB engine directly handles the prescribed syntax
     * and date / time formats specified internal to the JDBC escapes.
     * It also directly offers the XOpen / ODBC extended scalar
     * functions specified available internal to the {fn ...} JDBC escape.
     * As such, the driver simply removes the curly braces and JDBC escape
     * codes in the simplest and fastest fashion possible, by replacing them
     * with whitespace.
     *
     * But to avoid a great deal of complexity, certain forms of input
     * whitespace are currently not recognised.  For instance,
     * the driver handles "{?= call ...}" but not "{ ?= call ...} or
     * "{? = call ...}" <p>
     *
     * Also, comments embedded in SQL are currently not detected or
     * processed and thus may have unexpected effects on the output
     * of this method, for instance causing otherwise valid SQL to become
     * invalid. It is especially important to be aware of this because escape
     * processing is set true by default for Statement objects and is always
     * set true when producing a PreparedStatement from prepareStatement()
     * or CallableStatement from prepareCall().  Currently, it is simply
     * recommended to avoid submitting SQL having comments containing JDBC
     * escape sequence patterns and/or single or double quotation marks,
     * as this will avoid any potential problems.
     *
     * It is intended to implement a less strict handling of whitespace and
     * proper processing of SQL comments at some point in the near future,
     * perhaps before the final 1.7.2 release.
     *
     * In any event, 1.7.2 now correctly processes the following JDBC escape
     * forms to arbitrary nesting depth, but only if the exact whitespace
     * layout described below is used: <p>
     *
     * <ol>
     * <li>{call ...}
     * <li>{?= call ...}
     * <li>{fn ...}
     * <li>{oj ...}
     * <li>{d ...}
     * <li>{t ...}
     * <li>{ts ...}
     * </ol> <p>
     *
     * </div> <!-- end release-specific documentation -->
     *
     * @param sql a SQL statement that may contain one or more '?'
     *     parameter placeholders
     * @return the native form of this statement
     * @throws SQLException if a database access error occurs <p>
     */
    public synchronized String nativeSQL(final String sql)
    throws SQLException {

        // boucherb@users 20030405
        // FIXME: does not work properly for nested escapes
        //       e.g.  {call ...(...,{ts '...'},....)} does not work
        // boucherb@users 20030817
        // TESTME: First kick at the FIXME cat done.  Now lots of testing
        // and refinment
        checkClosed();

        // CHECKME:  Thow or return null if input is null?
        if (sql == null || sql.length() == 0 || sql.indexOf('{') == -1) {
            return sql;
        }

        // boolean   changed = false;
        int          state = 0;
        int          len   = sql.length();
        int          nest  = 0;
        StringBuffer sb    = new StringBuffer(sql.length());    //avoid 16 extra
        String       msg;

        //--
        final int outside_all                         = 0;
        final int outside_escape_inside_single_quotes = 1;
        final int outside_escape_inside_double_quotes = 2;

        //--
        final int inside_escape                      = 3;
        final int inside_escape_inside_single_quotes = 4;
        final int inside_escape_inside_double_quotes = 5;

        // TODO:
        // final int inside_single_line_comment          = 6;
        // final int inside_multi_line_comment           = 7;
        // Better than old way for large inputs and for avoiding GC overhead;
        // toString() reuses internal char[], reducing memory requirment
        // and garbage items 3:2
        sb.append(sql);

        for (int i = 0; i < len; i++) {
            char c = sb.charAt(i);

            switch (state) {

                case outside_all :                            // Not inside an escape or quotes
                    if (c == '\'') {
                        state = outside_escape_inside_single_quotes;
                    } else if (c == '"') {
                        state = outside_escape_inside_double_quotes;
                    } else if (c == '{') {
                        sb.setCharAt(i++, ' ');

                        i = StringUtil.skipSpaces(sql, i);

                        if (sql.regionMatches(true, i, "fn ", 0, 3)
                                || sql.regionMatches(true, i, "oj ", 0, 3)
                                || sql.regionMatches(true, i, "ts ", 0, 3)) {
                            sb.setCharAt(i++, ' ');
                            sb.setCharAt(i++, ' ');
                        } else if (sql.regionMatches(true, i, "d ", 0, 2)
                                   || sql.regionMatches(true, i, "t ", 0,
                                                        2)) {
                            sb.setCharAt(i++, ' ');
                        } else if (sql.regionMatches(true, i, "call ", 0,
                                                     5)) {
                            i += 4;
                        } else if (sql.regionMatches(true, i, "?= call ", 0,
                                                     8)) {
                            sb.setCharAt(i++, ' ');
                            sb.setCharAt(i++, ' ');

                            i += 5;
                        } else if (sql.regionMatches(true, i, "escape ", 0,
                                                     7)) {
                            i += 6;
                        } else {
                            i--;

                            throw new SQLException(Trace
                                .getMessage(Trace
                                    .jdbcConnection_nativeSQL, true, new Object[]{ sql
                                        .substring(i) }), "S0010", Trace
                                            .INVALID_JDBC_ARGUMENT);
                        }

                        // changed = true;
                        nest++;

                        state = inside_escape;
                    }
                    break;

                case outside_escape_inside_single_quotes :    // inside ' ' only
                case inside_escape_inside_single_quotes :     // inside { } and ' '
                    if (c == '\'') {
                        state -= 1;
                    }
                    break;

                case outside_escape_inside_double_quotes :    // inside " " only
                case inside_escape_inside_double_quotes :     // inside { } and " "
                    if (c == '"') {
                        state -= 2;
                    }
                    break;

                case inside_escape :                          // inside { }
                    if (c == '\'') {
                        state = inside_escape_inside_single_quotes;
                    } else if (c == '"') {
                        state = inside_escape_inside_double_quotes;
                    } else if (c == '}') {
                        sb.setCharAt(i, ' ');

                        // changed = true;
                        nest--;

                        state = (nest == 0) ? outside_all
                                            : inside_escape;
                    } else if (c == '{') {
                        sb.setCharAt(i++, ' ');

                        if (sql.regionMatches(true, i, "fn ", 0, 3)
                                || sql.regionMatches(true, i, "oj ", 0, 3)
                                || sql.regionMatches(true, i, "ts ", 0, 3)) {
                            sb.setCharAt(i++, ' ');
                            sb.setCharAt(i++, ' ');
                        } else if (sql.regionMatches(true, i, "d ", 0, 2)
                                   || sql.regionMatches(true, i, "t ", 0,
                                                        2)) {
                            sb.setCharAt(i++, ' ');
                        } else if (sql.regionMatches(true, i, "call ", 0,
                                                     5)) {
                            i += 4;
                        } else if (sql.regionMatches(true, i, "?= call ", 0,
                                                     8)) {
                            sb.setCharAt(i++, ' ');
                            sb.setCharAt(i++, ' ');

                            i += 5;
                        } else if (sql.regionMatches(true, i, "escape ", 0,
                                                     7)) {
                            i += 6;
                        } else {
                            i--;

                            throw new SQLException(Trace
                                .getMessage(Trace
                                    .jdbcConnection_nativeSQL, true, new Object[]{ sql
                                        .substring(i) }), "S0010", Trace
                                            .INVALID_JDBC_ARGUMENT);
                        }

                        // changed = true;
                        nest++;

                        state = inside_escape;
                    }
            }
        }

        return sb.toString();
    }

    /**
     * <!-- start generic documentation -->
     * Sets this connection's auto-commit mode to the given state.
     * If a connection is in auto-commit mode, then all its SQL
     * statements will be executed and committed as individual transactions.
     * Otherwise, its SQL statements are grouped into transactions that
     * are terminated by a call to either the method <code>commit</code> or
     * the method <code>rollback</code>. By default, new connections are
     * in auto-commit mode. <p>
     *
     * The commit occurs when the statement completes or the next
     * execute occurs, whichever comes first. In the case of
     * statements returning a <code>ResultSet</code> object, the
     * statement completes when the last row of the <code>ResultSet</code>
     * object has been retrieved or the <code>ResultSet</code> object
     * has been closed. In advanced cases, a single statement may
     * return multiple results as well as output parameter values. In
     * these cases, the commit occurs when all results and output
     * parameter values have been retrieved. <p>
     *
     * <B>NOTE:</B> If this method is called during a transaction,
     * the transaction is committed. <p>
     *
     * <!-- end generic documentation -->
     * <!-- start release-specific documentation -->
     * <div class="ReleaseSpecificDocumentation">
     * <h3>HSQLDB-Specific Information:</h3> <p>
     *
     * Up to and including HSQLDB 1.7.2, <p>
     *
     * <ol>
     *   <li> All rows of a result set are retrieved internally <em>
     *   before</em> the first row can actually be fetched.<br>
     *   Therefore, a statement can be considered complete as soon as
     *   any XXXStatement.executeXXX method returns. </li>
     *
     *   <li> Multiple result sets and output parameters are not yet
     *   supported. </li>
     * </ol>
     * <p>
     *
     * (boucherb@users) </div> <!-- end release-specific
     * documentation -->
     *
     * @param autoCommit <code>true</code> to enable auto-commit
     *     mode; <code>false</code> to disable it
     * @exception SQLException if a database access error occurs
     * @see #getAutoCommit
     */
    public synchronized void setAutoCommit(boolean autoCommit)
    throws SQLException {

        checkClosed();

        try {
            sessionProxy.setAutoCommit(autoCommit);
        } catch (HsqlException e) {
            throw Util.sqlException(e);
        }
    }

    /**
     *  Gets the current auto-commit state.
     *
     * @return  the current state of auto-commit mode
     * @exception  SQLException Description of the Exception
     * @see  #setAutoCommit
     */
    public synchronized boolean getAutoCommit() throws SQLException {

        checkClosed();

        try {
            return sessionProxy.isAutoCommit();
        } catch (HsqlException e) {
            throw Util.sqlException(e);
        }
    }

    /**
     * <!-- start generic documentation -->
     * Makes all changes made since the
     * previous commit/rollback permanent and releases any database
     * locks currently held by the Connection. This method should be
     * used only when auto-commit mode has been disabled. <p>
     *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -