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

📄 connectionjdbc2.java

📁 jtds的源码 是你学习java的好东西
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
            // with cached TDS versions at this point.
            tdsVersion = baseTds.getTdsVersion();
            if (tdsVersion < Driver.TDS70 && databaseName.length() > 0) {
                // Need to select the default database
                setCatalog(databaseName);
            }
        } catch (UnknownHostException e) {
            throw Support.linkException(
                    new SQLException(Messages.get("error.connection.badhost",
                            e.getMessage()), "08S03"), e);
        } catch (IOException e) {
            if (loginTimeout > 0 && e.getMessage().indexOf("timed out") >= 0) {
                throw Support.linkException(
                        new SQLException(Messages.get("error.connection.timeout"), "HYT01"), e);
            }
            throw Support.linkException(
                    new SQLException(Messages.get("error.connection.ioerror",
                            e.getMessage()), "08S01"), e);
        } catch (SQLException e) {
            if (loginTimeout > 0 && e.getMessage().indexOf("socket closed") >= 0) {
                throw Support.linkException(
                        new SQLException(Messages.get("error.connection.timeout"), "HYT01"), e);
            }

            throw e;
        }

        // If charset is still unknown and the collation is not set either,
        // determine the charset by querying (we're using Sybase or SQL Server
        // 6.5)
        if ((serverCharset == null || serverCharset.length() == 0)
                && collation == null) {
            loadCharset(determineServerCharset());
        }

        // Initial database settings.
        // Sets: auto commit mode  = true
        //       transaction isolation = read committed.
        if (serverType == Driver.SYBASE) {
            baseTds.submitSQL(SYBASE_INITIAL_SQL);
        } else {
            // Also discover the maximum decimal precision:  28 (default)
            // or 38 for MS SQL Server 6.5/7, or 38 for 2000 and later.
            Statement stmt = this.createStatement();
            ResultSet rs = stmt.executeQuery(SQL_SERVER_INITIAL_SQL);

            if (rs.next()) {
                maxPrecision = rs.getByte(1);
            }

            rs.close();
            stmt.close();
        }

        //
        // Restore any login warnings so that the user can retrieve them
        // by calling Connection.getWarnings()
        //
        messages.warnings = warn;
    }


    /**
     * Creates a {@link SharedSocket} object representing a connection to a named
     * pipe.  If the <code>os.name</code> system property starts with "Windows"
     * (case-insensitive) and the <code>useJCIFS</code> parameter is
     * <code>false</code>, a {@link SharedLocalNamedPipe} object is created.
     * Else a {@link SharedNamedPipe} is created which uses
     * <a href="http://jcifs.samba.org/">jCIFS</a> to provide a pure-Java
     * implementation of Windows named pipes.
     * <p>
     * This method will retry for <code>loginTimeout</code> seconds to create a
     * named pipe if an <code>IOException</code> continues to be thrown stating,
     * "All pipe instances are busy".  If <code>loginTimeout</code> is set to
     * zero (e.g., not set), a default of 20 seconds will be used.
     *
     * @param connection the connection object
     * @return an object representing the named pipe connection
     * @throws IOException on error; if an <code>IOException</code> is thrown with
     * a message stating "All pipe instances are busy", then the method timed out
     * after <code>loginTimeout</code> milliseconds attempting to create a named pipe.
     */
    private SharedSocket createNamedPipe(ConnectionJDBC2 connection) throws IOException {

        final long loginTimeout = connection.getLoginTimeout();
        final long retryTimeout = (loginTimeout > 0 ? loginTimeout : 20) * 1000;
        final long startLoginTimeout = System.currentTimeMillis();
        final Random random = new Random(startLoginTimeout);
        final boolean isWindowsOS = Support.isWindowsOS();

        SharedSocket socket = null;
        IOException lastIOException = null;
        int exceptionCount = 0;

        do {
            try {
                if (isWindowsOS && !connection.getUseJCIFS()) {
                    socket = new SharedLocalNamedPipe(connection);
                }
                else {
                    socket = new SharedNamedPipe(connection);
                }
            }
            catch (IOException ioe) {
                exceptionCount++;
                lastIOException = ioe;
                if (ioe.getMessage().toLowerCase().indexOf("all pipe instances are busy") >= 0) {
                    // Per a Microsoft knowledgebase article, wait 200 ms to 1 second each time
                    // we get an "All pipe instances are busy" error.
                    // http://support.microsoft.com/default.aspx?scid=KB;EN-US;165189
                    final int randomWait = random.nextInt(800) + 200;
                    if (Logger.isActive()) {
                        Logger.println("Retry #" + exceptionCount + " Wait " + randomWait + " ms: " +
                                       ioe.getMessage());
                    }
                    try {
                        Thread.sleep(randomWait);
                    }
                    catch (InterruptedException ie) {
                        // Do nothing; retry again
                    }
                }
                else {
                    throw ioe;
                }
            }
        } while (socket == null && (System.currentTimeMillis() - startLoginTimeout) < retryTimeout);

        if (socket == null) {
            final IOException ioException = new IOException("Connection timed out to named pipe");
            Support.linkException(ioException, lastIOException);
            throw ioException;
        }

        return socket;
    }


    /**
     * Retrive the shared socket.
     *
     * @return The <code>SharedSocket</code> object.
     */
    SharedSocket getSocket() {
        return this.socket;
    }

    /**
     * Retrieve the TDS protocol version.
     *
     * @return The TDS version as an <code>int</code>.
     */
    int getTdsVersion() {
        return this.tdsVersion;
    }

    /**
     * Retrieves the next unique stored procedure name.
     * <p>Notes:
     * <ol>
     * <li>Some versions of Sybase require an id with
     * a length of &lt;= 10.
     * <li>The format of this name works for sybase and Microsoft
     * and allows for 16M names per session.
     * <li>The leading '#jtds' indicates this is a temporary procedure and
     * the '#' is removed by the lower level TDS5 routines.
     * </ol>
     * Not synchronized because it's only called from the synchronized
     * {@link #prepareSQL} method.
     *
     * @return the next temporary SP name as a <code>String</code>
     */
    String getProcName() {
        String seq = "000000" + Integer.toHexString(spSequenceNo++).toUpperCase();

        return "#jtds" + seq.substring(seq.length() - 6, seq.length());
    }

    /**
     * Retrieves the next unique cursor name.
     *
     * @return the next cursor name as a <code>String</code>
     */
    synchronized String getCursorName() {
        String seq = "000000" + Integer.toHexString(cursorSequenceNo++).toUpperCase();

        return "_jtds" + seq.substring(seq.length() - 6, seq.length());
    }

    /**
     * Try to convert the SQL statement into a statement prepare.
     * <p>
     * Synchronized because it accesses the procedure cache and the
     * <code>baseTds</code>, but the method call also needs to made in a
     * <code>synchronized (connection)</code> block together with the execution
     * (if the prepared statement is actually executed) to ensure the
     * transaction isn't rolled back between this method call and the actual
     * execution.
     *
     * @param pstmt        the target prepared statement
     * @param sql          the SQL statement to prepare
     * @param params       the parameters
     * @param returnKeys   indicates whether the statement will return
     *                     generated keys
     * @param cursorNeeded indicates whether a cursor prepare is needed
     * @return the SQL procedure name as a <code>String</code> or null if the
     *         SQL cannot be prepared
     */
    synchronized String prepareSQL(JtdsPreparedStatement pstmt,
                                   String sql,
                                   ParamInfo[] params,
                                   boolean returnKeys,
                                   boolean cursorNeeded)
            throws SQLException {
        if (prepareSql == TdsCore.UNPREPARED
                || prepareSql == TdsCore.EXECUTE_SQL) {
            return null; // User selected not to use procs
        }

        if (serverType == Driver.SYBASE) {
            if (tdsVersion != Driver.TDS50) {
                return null; // No longer support stored procs with 4.2
            }

            if (returnKeys) {
                return null; // Sybase cannot use @@IDENTITY in proc
            }

            if (cursorNeeded) {
                //
                // We are going to use the CachedResultSet so there is
                // no point in preparing the SQL as it will be discarded
                // in favour of a version with "FOR BROWSE" appended.
                //
                return null;
            }
        }

        //
        // Check parameters set and obtain native types
        //
        for (int i = 0; i < params.length; i++) {
            if (!params[i].isSet) {
                throw new SQLException(Messages.get("error.prepare.paramnotset",
                                                    Integer.toString(i+1)),
                                       "07000");
            }

            TdsData.getNativeType(this, params[i]);

            if (serverType == Driver.SYBASE) {
                if ("text".equals(params[i].sqlType)
                    || "image".equals(params[i].sqlType)) {
                    return null; // Sybase does not support text/image params
                }
            }
        }

        String key = Support.getStatementKey(sql, params, serverType,
                getCatalog(), autoCommit, cursorNeeded);

        //
        // See if we have already built this one
        //
        ProcEntry proc = (ProcEntry) statementCache.get(key);

        if (proc != null) {
            //
            // Yes found in cache OK
            //

            // If already used by the statement, decrement use count
            if (pstmt.handles != null && pstmt.handles.contains(proc)) {
                proc.release();
            }

            pstmt.setColMetaData(proc.getColMetaData());
            if (serverType == Driver.SYBASE) {
                pstmt.setParamMetaData(proc.getParamMetaData());
            }
        } else {
            //
            // No, so create the stored procedure now
            //
            proc = new ProcEntry();

            if (serverType == Driver.SQLSERVER) {
                proc.setName(
                        baseTds.microsoftPrepare(
                                sql, params, cursorNeeded,
                                pstmt.getResultSetType(),
                                pstmt.getResultSetConcurrency()));

                if (proc.toString() == null) {
                    proc.setType(ProcEntry.PREP_FAILED);
                } else if (prepareSql == TdsCore.TEMPORARY_STORED_PROCEDURES) {
                    proc.setType(ProcEntry.PROCEDURE);
                } else {
                    proc.setType((cursorNeeded) ? ProcEntry.CURSOR : ProcEntry.PREPARE);
                    // Meta data may be returned by sp_prepare
                    proc.setColMetaData(baseTds.getColumns());
                    pstmt.setColMetaData(proc.getColMetaData());
                }
                // TODO Find some way of getting parameter meta data for MS
            } else {
                proc.setName(baseTds.sybasePrepare(sql, params));

                if (proc.toString() == null) {
                    proc.setType(ProcEntry.PREP_FAILED);
                } else {
                    proc.setType(ProcEntry.PROCEDURE);
                }
                // Sybase gives us lots of useful information about the result set
                proc.setColMetaData(baseTds.getColumns());
                proc.setParamMetaData(baseTds.getParameters());
                pstmt.setColMetaData(proc.getColMetaData());
                pstmt.setParamMetaData(proc.getParamMetaData());
            }
            // OK we have built a proc so add it to the cache.
            addCachedProcedure(key, proc);
        }
        // Add the handle to the prepared statement so that the handles
        // can be used to clean up the statement cache properly when the
        // prepared statement is closed.
        if (pstmt.handles == null) {
            pstmt.handles = new HashSet(10);
        }

        pstmt.handles.add(proc);

        // Give the user the name will be null if prepare failed
        return proc.toString();
    }

    /**
     * Add a stored procedure to the cache.
     * <p>
     * Not explicitly synchronized because it's only called by synchronized
     * methods.
     *
     * @param key The signature of the procedure to cache.
     * @param proc The stored procedure descriptor.
     */
    void addCachedProcedure(String key, ProcEntry proc) {
        statementCache.put(key, proc);

        if (!autoCommit
                && proc.getType() == ProcEntry.PROCEDURE
                && serverType == Driver.SQLSERVER) {
            procInTran.add(key);
        }
    }

    /**
     * Remove a stored procedure from the cache.
     * <p>
     * Not explicitly synchronized because it's only called by synchronized
     * methods.
     *
     * @param key The signature of the procedure to remove from the cache.
     */
    void removeCachedProcedure(String key) {
        statementCache.remove(key);

        if (!autoCommit) {
            procInTran.remove(key);
        }
    }

⌨️ 快捷键说明

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