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

📄 jdbcconnection.java

📁 Java写的含有一个jdbc驱动的小型数据库数据库引擎
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * jdbcConnection.java
 *
 * Copyright (c) 2001, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 *
 * Neither the name of the HSQL Development Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This package is based on HypersonicSQL, originally developed by Thomas Mueller.
 *
 */
package org.hsqldb;

import java.sql.*;
import java.util.*;
import java.io.*;
import java.net.*;

/**
 * <P>A connection (session) with a specific
 * database. Within the context of a Connection, SQL statements are
 * executed and results are returned.
 *
 * <P>A Connection's database is able to provide information
 * describing its tables, its supported SQL grammar, its stored
 * procedures, the capabilities of this connection, and so on. This
 * information is obtained with the <code>getMetaData</code> method.
 *
 * <P><B>Note:</B> By default the Connection automatically commits
 * changes after executing each statement. If auto commit has been
 * disabled, an explicit commit must be done or database changes will
 * not be saved.
 * <P><font color="#009900">
 * To connect to a HSQL database, the following code may be used:
 * <pre>
 * Class.forName("org.hsqldb.jdbcDriver");
 * Connection c=DriverManager.getConnection(url,user,password);
 * </pre>
 * For HSQL, the url must start with jdbc:hsqldb.
 * The url for an In-Memory database is <code>jdbc:hsqldb:.</code>
 * The url for a standalone database is jdbc:hsqldb:name
 * where name is the filename of the database, including path. For example:
 * <code>jdbc:hsqldb:test</code> will connect to a database called
 * 'test', with the files test.properties, test.data and test.script.
 * For more information about the internal file structure of HSQL,
 * please read the documentation, page 'Files'.
 * </font><P>
 * @see jdbcStatement
 * @see jdbcResultSet
 * @see jdbcDatabaseMetaData
 */
public class jdbcConnection implements Connection {
    private boolean	     bClosed;
    private boolean	     bAutoCommit;
    private String	     sDatabaseName;
    private final static int HTTP = 0, STANDALONE = 1, INTERNAL = 2, HSQL = 3;
    private int		     iType;
    private Database	 dDatabase;
    private Channel	     cChannel;
    Socket		    	 sSocket;
    DataOutputStream	 dOutput;
    DataInputStream	     dInput;
    public static final int DEFAULT_HSQL_PORT = 9001;

    private static Hashtable tDatabase = new Hashtable();
    private static Hashtable iUsageCount = new Hashtable();

    /**
     * Creates a <code>Statement</code> object for sending
     * SQL statements to the database.
     * SQL statements without parameters are normally
     * executed using Statement objects.
     *
     * @return a new Statement object
     */
    public Statement createStatement() {
	if (Trace.TRACE) {
	    Trace.trace();
	}

	if (bClosed) {
	    return null;
	}

	return new jdbcStatement(this);
    }

    /**
     * Creates a <code>PreparedStatement</code> object for sending
     * parameterized SQL statements to the database.
     *
     * A SQL statement with or without IN parameters can be stored in
     * a PreparedStatement object. This object can then be used to execute
     * this statement multiple times.
     * <P><font color="#009900">
     * In HSQL, the statement is not sent to the database until
     * the <code>PreparedStatement</code> is executed. Other drivers may send
     * the statment to the database when this function is called. This has
     * no direct effect on users; however, it does affect which method throws
     * certain SQLExceptions.
     * </font><P>
     * @param sql a SQL statement that may contain one or more '?' IN
     * parameter placeholders
     * @return a new PreparedStatement object containing the
     * pre-compiled statement
     */
    public PreparedStatement prepareStatement(String sql) {
	if (Trace.TRACE) {
	    Trace.trace(sql);
	}

	if (bClosed) {
	    return null;
	}

	return new jdbcPreparedStatement(this, sql);
    }

    /**
     * Creates a <code>CallableStatement</code> object for calling
     * database stored procedures.
     * The CallableStatement provides
     * methods for setting up its IN and OUT parameters, and
     * methods for executing the call to a stored procedure.
     *
     * <P><B>Note:</B> This method is optimized for handling stored
     * procedure call statements.
     * <P><font color="#009900">
     * HSQL does not send the call
     * statement to the database when the method <code>prepareCall</code>
     * is done; it waits until the CallableStatement is executed. This has
     * no direct effect on users; however, it does affect which method
     * throws certain SQLExceptions.
     * </font><P>
     * @param sql a SQL statement that may contain one or more '?'
     * parameter placeholders. Typically this  statement is a JDBC
     * function call escape string.
     * @return a new CallableStatement object containing the
     * pre-compiled SQL statement
     */
    public CallableStatement prepareCall(String sql) {
	if (Trace.TRACE) {
	    Trace.trace(sql);
	}

	if (bClosed) {
	    return null;
	}

	return new jdbcPreparedStatement(this, sql);
    }

    /**
     * Converts the given SQL statement into the system's native SQL grammar.
     * <P><font color="#009900">
     * HSQL does convert the JDBC sql grammar into its system's
     * native SQL grammar prior to sending it; this method returns the
     * native form of the statement that the driver would have sent.
     * </font><P>
     * @param sql a SQL statement that may contain one or more '?'
     * parameter placeholders
     * @return the native form of this statement
     */
    public String nativeSQL(String sql) {
	if (sql.indexOf('{') == -1) {
	    return sql;
	}

	char    s[] = sql.toCharArray();
	boolean changed = false;
	int     state = 0;
	int     len = s.length;

	for (int i = 0; i < len; i++) {
	    char c = s[i];

	    switch (state) {

	    case 0:    // normal
		if (c == '\'') {
		    state = 1;
		} else if (c == '"') {
		    state = 2;
		} else if (c == '{') {
		    s[i] = ' ';
		    changed = true;

		    String sub = sql.substring(i + 1).toUpperCase();

		    if (sub.startsWith("?=")) {
			i += 2;
		    } else if (sub.startsWith("CALL")) {
			i += 4;
		    } else if (sub.startsWith("ESCAPE")) {
			i += 6;
		    }

		    state = 3;
		}

		break;

	    case 1:    // inside ' '

	    case 5:    // inside { } and ' '
		if (c == '\'') {
		    state -= 1;
		}

		break;

	    case 2:    // inside " "

	    case 6:    // inside { } and " "
		if (c == '"') {
		    state -= 2;
		}

		break;

	    case 3:    // inside { } before whitespace
		if (c == ' ') {
		    state = 4;
		} else {
		    s[i] = ' ';
		    changed = true;
		}

		break;

	    case 4:    // inside { } after whitespace
		if (c == '\'') {
		    state = 5;
		} else if (c == '"') {
		    state = 6;
		} else if (c == '}') {
		    s[i] = ' ';
		    changed = true;
		    state = 0;
		}
	    }
	}

	if (changed) {
	    sql = new String(s);

	    if (Trace.TRACE) {
		Trace.trace(s + " > " + sql);
	    }
	}

	return sql;
    }

    /**
     * Sets this connection's auto-commit mode.
     * 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.
     *
     * The commit occurs when the statement completes or the next
     * execute occurs, whichever comes first. In the case of
     * statements returning a ResultSet, the statement completes when
     * the last row of the ResultSet has been retrieved or the
     * ResultSet 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.
     *
     * @param autoCommit true enables auto-commit; false disables
     * auto-commit.
     * @exception SQLException if a database access error occurs
     */
    public void setAutoCommit(boolean autoCommit) throws SQLException {
	bAutoCommit = autoCommit;

	execute("SET AUTOCOMMIT " + (bAutoCommit ? "TRUE" : "FALSE"));
    }

    /**
     * Gets the current auto-commit state.
     *
     * @return the current state of auto-commit mode
     * @see #setAutoCommit
     */
    public boolean getAutoCommit() {
	if (Trace.TRACE) {
	    Trace.trace();
	}

	return bAutoCommit;
    }

    /**
     * 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.
     *
     * @exception SQLException if a database access error occurs
     * @see #setAutoCommit
     */
    public void commit() throws SQLException {
	execute("COMMIT");
    }

    /**
     * Drops all changes made since the previous
     * commit/rollback and releases any database locks currently held
     * by this Connection. This method should be used only when auto-
     * commit has been disabled.
     *
     * @exception SQLException if a database access error occurs
     * @see #setAutoCommit
     */
    public void rollback() throws SQLException {
	execute("ROLLBACK");
    }

    /**
     * Releases a Connection's database and JDBC resources
     * immediately instead of waiting for
     * them to be automatically released.
     *
     * <P><B>Note:</B> A Connection is automatically closed when it is
     * garbage collected.
     *
     * @exception SQLException if a database access error occurs
     */
    public void close() throws SQLException {
	if (Trace.TRACE) {
	    Trace.trace();
	}

	if (bClosed) {
	    return;
	}

	if ((iType == STANDALONE) || (iType == INTERNAL)) {
	    closeStandalone();
	} else {
	    execute("DISCONNECT");
	}

	bClosed = true;
    }

    /**
     * Tests to see if a Connection is closed.
     *
     * @return true if the connection is closed; false if it's still open
     */
    public boolean isClosed() {
	if (Trace.TRACE) {
	    Trace.trace();
	}

	return bClosed;
    }

    /**
     * Gets the metadata regarding this connection's database.
     * A Connection's database is able to provide information
     * describing its tables, its supported SQL grammar, its stored
     * procedures, the capabilities of this connection, and so on. This
     * information is made available through a DatabaseMetaData
     * object.
     *
     * @return a DatabaseMetaData object for this Connection
     */
    public DatabaseMetaData getMetaData() {
	if (Trace.TRACE) {
	    Trace.trace();
	}

	return new jdbcDatabaseMetaData(this);
    }

    /**
     * Puts this connection in read-only mode as a hint to enable
     * database optimizations.
     *
     * <P><B>Note:</B> This method should not be called while in the
     * middle of a transaction.
     * <P><font color="#009900">
     * HSQL will in this case commit the transaction automatically.
     * <P>
     * In HSQL, additionally the whole database can be put in
     * read-only mode by manually adding the line 'readonly=true' to the
     * .properties file. All connections are then automatically readonly.
     * The database files will then be opened in readonly mode, and it is
     * thus possible to create a CD with this database.
     * </font><P>
     * @param readOnly true enables read-only mode; false disables
     * read-only mode.
     * @exception SQLException if a database access error occurs
     */
    public void setReadOnly(boolean readonly) throws SQLException {
	execute("SET READONLY " + (readonly ? "TRUE" : "FALSE"));
    }

    /**
     * Tests to see if the connection is in read-only mode.
     *
     * @return true if connection is read-only and false otherwise
     * @exception SQLException if a database access error occurs
     */
    public boolean isReadOnly() throws SQLException {
	String    s =
	    "SELECT * FROM SYSTEM_CONNECTIONINFO WHERE KEY='READONLY'";
	ResultSet r = execute(s);

	r.next();

	return r.getString(2).equals("TRUE");
    }

    /**
     * Sets a catalog name in order to select
     * a subspace of this Connection's database in which to work.
     * <P><font color="#009900">
     * HSQL does not support catalogs and ignores
     * this request.
     * </font><P>
     */
    public void setCatalog(String catalog) {
	if (Trace.TRACE) {
	    Trace.trace(catalog);
	}
    }

    /**
     * Returns the Connection's current catalog name.
     *
     * @return the current catalog name or null
     */
    public String getCatalog() {
	if (Trace.TRACE) {
	    Trace.trace();
	}

	return null;
    }

    /**
     * Attempts to change the transaction
     * isolation level to the one given.
     * The constants defined in the interface <code>Connection</code>
     * are the possible transaction isolation levels.
     *
     * <P><B>Note:</B> This method should not be called while
     * in the middle of a transaction.
     * <P><font color="#009900">
     * HSQL currently ignores this call.
     * </font><P>
     * @param level one of the TRANSACTION_* isolation values with the
     * exception of TRANSACTION_NONE; some databases may not support
     * other values
     * @see DatabaseMetaData#supportsTransactionIsolationLevel
     */
    public void setTransactionIsolation(int level) {
	if (Trace.TRACE) {
	    Trace.trace(level);
	}
    }

    /**
     * Gets this Connection's current transaction isolation level.
     *
     * @return the current TRANSACTION_* mode value
     */

⌨️ 快捷键说明

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