📄 database.java
字号:
/*
* 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 + -