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

📄 database.java

📁 Java写的含有一个jdbc驱动的小型数据库数据库引擎
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 * Database.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.io.*;
import java.net.*;
import java.util.*;

/**
 * Database class declaration
 * <P>Database is the root class for HSQL Database Engine database.
 * This class should not be used directly by the application,
 * instead the jdbc* classes should be used.
 *
 * @version 1.0.0.1
 */
class Database {
    private String		sName;
    private Access		aAccess;
    private Vector		tTable;
    private DatabaseInformation dInfo;
    private Log			lLog;
    private boolean		bReadOnly;
    private boolean		bShutdown;
    private Hashtable		hAlias;
    private boolean		bIgnoreCase;
    private boolean		bReferentialIntegrity;
    private Vector		cChannel;

    /**
     * Constructor declaration
     *
     *
     * @param name
     */
    Database(String name) throws SQLException {
	if (Trace.TRACE) {
	    Trace.trace();
	}

	sName = name;
	tTable = new Vector();
	aAccess = new Access();
	cChannel = new Vector();
	hAlias = new Hashtable();
	bReferentialIntegrity = true;

	Library.register(hAlias);

	dInfo = new DatabaseInformation(this, tTable, aAccess);

	boolean newdatabase = false;
	Channel sys = new Channel(this, new User(null, null, true, null),
				  true, false, 0);

	registerChannel(sys);

	if (name.equals(".")) {
	    newdatabase = true;
	} else {
	    lLog = new Log(this, sys, name);
	    newdatabase = lLog.open();
	}

	if (newdatabase) {
	    execute("CREATE USER SA PASSWORD \"\" ADMIN", sys);
	}

	aAccess.grant("PUBLIC", "CLASS \"java.lang.Math\"", Access.ALL);
	aAccess.grant("PUBLIC", "CLASS \"org.hsqldb.Library\"", Access.ALL);
    }

    /**
     * Method declaration
     *
     *
     * @return
     */
    String getName() {
	return sName;
    }

    /**
     * Method declaration
     *
     *
     * @return
     */
    boolean isShutdown() {
	return bShutdown;
    }

    /**
     * Method declaration
     *
     *
     * @param username
     * @param password
     *
     * @return
     *
     * @throws SQLException
     */
    synchronized Channel connect(String username,
				 String password) throws SQLException {
	User user = aAccess.getUser(username.toUpperCase(),
				    password.toUpperCase());
	int  size = cChannel.size(), id = size;

	for (int i = 0; i < size; i++) {
	    if (cChannel.elementAt(i) == null) {
		id = i;

		break;
	    }
	}

	Channel c = new Channel(this, user, true, bReadOnly, id);

	if (lLog != null) {
	    lLog.write(c,
		       "CONNECT USER " + username + " PASSWORD \"" + password
		       + "\"");
	}

	registerChannel(c);

	return c;
    }

    /**
     * Method declaration
     *
     *
     * @param channel
     */
    void registerChannel(Channel channel) {
	int size = cChannel.size();
	int id = channel.getId();

	if (id >= size) {
	    cChannel.setSize(id + 1);
	}

	cChannel.setElementAt(channel, id);
    }

    /**
     * Method declaration
     *
     *
     * @param user
     * @param password
     * @param statement
     *
     * @return
     */
    byte[] execute(String user, String password, String statement) {
	Result r = null;

	try {
	    Channel channel = connect(user, password);

	    r = execute(statement, channel);

	    execute("DISCONNECT", channel);
	} catch (Exception e) {
	    r = new Result(e.getMessage());
	}

	try {
	    return r.getBytes();
	} catch (Exception e) {
	    return new byte[0];
	}
    }

    /**
     * Method declaration
     *
     *
     * @param statement
     * @param channel
     *
     * @return
     */
    synchronized Result execute(String statement, Channel channel) {
	if (Trace.TRACE) {
	    Trace.trace(statement);
	}

	Tokenizer c = new Tokenizer(statement);
	Parser    p = new Parser(this, c, channel);
	Result    rResult = new Result();

	try {
	    if (lLog != null && lLog.cCache != null) {
		lLog.cCache.cleanUp();
	    }

	    if (Trace.ASSERT) {
		Trace.assert(!channel.isNestedTransaction());
	    }

	    Trace.check(channel != null, Trace.ACCESS_IS_DENIED);
	    Trace.check(!bShutdown, Trace.DATABASE_IS_SHUTDOWN);

	    while (true) {
		int     begin = c.getPosition();
		boolean script = false;
		String  sToken = c.getString();

		if (sToken.equals("")) {
		    break;
		} else if (sToken.equals("SELECT")) {
		    rResult = p.processSelect();
		} else if (sToken.equals("INSERT")) {
		    rResult = p.processInsert();
		} else if (sToken.equals("UPDATE")) {
		    rResult = p.processUpdate();
		} else if (sToken.equals("DELETE")) {
		    rResult = p.processDelete();
		} else if (sToken.equals("CREATE")) {
		    rResult = processCreate(c, channel);
		    script = true;
		} else if (sToken.equals("DROP")) {
		    rResult = processDrop(c, channel);
		    script = true;
		} else if (sToken.equals("GRANT")) {
		    rResult = processGrantOrRevoke(c, channel, true);
		    script = true;
		} else if (sToken.equals("REVOKE")) {
		    rResult = processGrantOrRevoke(c, channel, false);
		    script = true;
		} else if (sToken.equals("CONNECT")) {
		    rResult = processConnect(c, channel);
		} else if (sToken.equals("DISCONNECT")) {
		    rResult = processDisconnect(c, channel);
		} else if (sToken.equals("SET")) {
		    rResult = processSet(c, channel);
		    script = true;
		} else if (sToken.equals("SCRIPT")) {
		    rResult = processScript(c, channel);
		} else if (sToken.equals("COMMIT")) {
		    rResult = processCommit(c, channel);
		    script = true;
		} else if (sToken.equals("ROLLBACK")) {
		    rResult = processRollback(c, channel);
		    script = true;
		} else if (sToken.equals("SHUTDOWN")) {
		    rResult = processShutdown(c, channel);
		} else if (sToken.equals("CHECKPOINT")) {
		    rResult = processCheckpoint(channel);
		} else if (sToken.equals("CALL")) {
		    rResult = p.processCall();
		} else if (sToken.equals(";")) {

		    // ignore
		} else {
		    throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken);
		}

		if (script && lLog != null) {
		    int end = c.getPosition();

		    lLog.write(channel, c.getPart(begin, end));
		}
	    }
	} catch (SQLException e) {

	    // e.printStackTrace();
	    rResult = new Result(Trace.getMessage(e) + " in statement ["
				 + statement + "]");
	} catch (Exception e) {
	    e.printStackTrace();

	    String s = Trace.getMessage(Trace.GENERAL_ERROR) + " " + e;

	    rResult = new Result(s + " in statement [" + statement + "]");
	}

	return rResult;
    }

    /**
     * Method declaration
     *
     */
    void setReadOnly() {
	bReadOnly = true;
    }

    /**
     * Method declaration
     *
     *
     * @return
     */
    Vector getTables() {
	return tTable;
    }

    /**
     * Method declaration
     *
     *
     * @param ref
     */
    void setReferentialIntegrity(boolean ref) {
	bReferentialIntegrity = ref;
    }

    /**
     * Method declaration
     *
     *
     * @return
     */
    boolean isReferentialIntegrity() {
	return bReferentialIntegrity;
    }

    /**
     * Method declaration
     *
     *
     * @return
     */
    Hashtable getAlias() {
	return hAlias;
    }

    /**
     * Method declaration
     *
     *
     * @param s
     *
     * @return
     */
    String getAlias(String s) {
	Object o = hAlias.get(s);

	if (o == null) {
	    return s;
	}

	return (String) o;
    }

    /**
     * Method declaration
     *
     *
     * @return
     */
    Log getLog() {
	return lLog;
    }

    /**
     * Method declaration
     *
     *
     * @param name
     * @param channel
     *
     * @return
     *
     * @throws SQLException
     */
    Table getTable(String name, Channel channel) throws SQLException {
	Table t = null;

	for (int i = 0; i < tTable.size(); i++) {
	    t = (Table) tTable.elementAt(i);

	    if (t.getName().equals(name)) {
		return t;
	    }
	}

	t = dInfo.getSystemTable(name, channel);

	if (t == null) {
	    throw Trace.error(Trace.TABLE_NOT_FOUND, name);
	}

	return t;
    }

    /**
     * Method declaration
     *
     *
     * @param drop
     * @param insert
     * @param cached
     * @param channel
     *
     * @return
     *
     * @throws SQLException
     */
    Result getScript(boolean drop, boolean insert, boolean cached,
		     Channel channel) throws SQLException {
	return dInfo.getScript(drop, insert, cached, channel);
    }

    /**
     * Method declaration
     *
     *
     * @param t
     *
     * @throws SQLException
     */
    void linkTable(Table t) throws SQLException {
	String name = t.getName();

	for (int i = 0; i < tTable.size(); i++) {
	    Table o = (Table) tTable.elementAt(i);

	    if (o.getName().equals(name)) {
		throw Trace.error(Trace.TABLE_ALREADY_EXISTS, name);
	    }
	}

	tTable.addElement(t);
    }

    /**
     * Method declaration
     *
     *
     * @return
     */
    boolean isIgnoreCase() {
	return bIgnoreCase;
    }

    /**
     * Method declaration
     *
     *
     * @param c
     * @param channel
     *
     * @return

⌨️ 快捷键说明

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