📄 database.java
字号:
*
* @throws SQLException
*/
private Result processScript(Tokenizer c,
Channel channel) throws SQLException {
String sToken = c.getString();
if (c.wasValue()) {
sToken = (String) c.getAsValue();
Log.scriptToFile(this, sToken, true, channel);
return new Result();
} else {
c.back();
// try to script all: drop, insert; but no positions for cached tables
return getScript(true, true, false, channel);
}
}
/**
* Method declaration
*
*
* @param c
* @param channel
*
* @return
*
* @throws SQLException
*/
private Result processCreate(Tokenizer c,
Channel channel) throws SQLException {
channel.checkReadWrite();
channel.checkAdmin();
String sToken = c.getString();
if (sToken.equals("TABLE")) {
processCreateTable(c, channel, false);
} else if (sToken.equals("MEMORY")) {
c.getThis("TABLE");
processCreateTable(c, channel, false);
} else if (sToken.equals("CACHED")) {
c.getThis("TABLE");
processCreateTable(c, channel, true);
} else if (sToken.equals("TRIGGER")) {
processCreateTrigger(c, channel);
} else if (sToken.equals("USER")) {
String u = c.getStringToken();
c.getThis("PASSWORD");
String p = c.getStringToken();
boolean admin;
if (c.getString().equals("ADMIN")) {
admin = true;
} else {
admin = false;
}
aAccess.createUser(u, p, admin);
} else if (sToken.equals("ALIAS")) {
String name = c.getString();
sToken = c.getString();
Trace.check(sToken.equals("FOR"), Trace.UNEXPECTED_TOKEN, sToken);
sToken = c.getString();
// fredt@users.sourceforge.net begin changes for 1.61
// convert org.hsql.Library aliases that exist in versions < 1.60 to org.hsqldb
if (sToken.startsWith("org.hsql.Library.") )
sToken = "org.hsqldb.Library." + sToken.substring("org.hsql.Library.".length());
// fredt@users.sourceforge.net end changes for 1.61
hAlias.put(name, sToken);
} else {
boolean unique = false;
if (sToken.equals("UNIQUE")) {
unique = true;
sToken = c.getString();
}
if (!sToken.equals("INDEX")) {
throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken);
}
String name = c.getName();
c.getThis("ON");
Table t = getTable(c.getString(), channel);
addIndexOn(c, channel, name, t, unique);
}
return new Result();
}
/**
* Method declaration
*
*
* @param c
* @param t
*
* @return
*
* @throws SQLException
*/
private int[] processColumnList(Tokenizer c,
Table t) throws SQLException {
Vector v = new Vector();
c.getThis("(");
while (true) {
v.addElement(c.getString());
String sToken = c.getString();
if (sToken.equals(")")) {
break;
}
if (!sToken.equals(",")) {
throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken);
}
}
int s = v.size();
int col[] = new int[s];
for (int i = 0; i < s; i++) {
col[i] = t.getColumnNr((String) v.elementAt(i));
}
return col;
}
/**
* Method declaration
*
*
* @param channel
* @param t
* @param col
* @param name
* @param unique
*
* @throws SQLException
*/
private void createIndex(Channel channel, Table t, int col[],
String name,
boolean unique) throws SQLException {
channel.commit();
if (t.isEmpty()) {
t.createIndex(col, name, unique);
} else {
Table tn = t.moveDefinition(null);
tn.createIndex(col, name, unique);
tn.moveData(t);
dropTable(t.getName());
linkTable(tn);
}
}
/**
* Method declaration
*
*
* @param c
* @param channel
* @param name
* @param t
*
* @throws SQLException
*/
private void addForeignKeyOn(Tokenizer c, Channel channel, String name,
Table t) throws SQLException {
int col[] = processColumnList(c, t);
c.getThis("REFERENCES");
Table t2 = getTable(c.getString(), channel);
int col2[] = processColumnList(c, t2);
if (t.getIndexForColumns(col) == null) {
createIndex(channel, t, col, "SYSTEM_FOREIGN_KEY_" + name, false);
}
if (t2.getIndexForColumns(col2) == null) {
createIndex(channel, t2, col2, "SYSTEM_REFERENCE_" + name, false);
}
t.addConstraint(new Constraint(Constraint.FOREIGN_KEY, t2, t, col2,
col));
t2.addConstraint(new Constraint(Constraint.MAIN, t2, t, col2, col));
}
/**
* Method declaration
*
*
* @param c
* @param channel
* @param name
* @param t
*
* @throws SQLException
*/
private void addUniqueConstraintOn(Tokenizer c, Channel channel,
String name,
Table t) throws SQLException {
int col[] = processColumnList(c, t);
createIndex(channel, t, col, name, true);
t.addConstraint(new Constraint(Constraint.UNIQUE, t, col));
}
/**
* Method declaration
*
*
* @param c
* @param channel
* @param name
* @param t
* @param unique
*
* @throws SQLException
*/
private void addIndexOn(Tokenizer c, Channel channel, String name,
Table t, boolean unique) throws SQLException {
int col[] = processColumnList(c, t);
createIndex(channel, t, col, name, unique);
}
/**
* Method declaration
*
*
* @param c
* @param channel
*
* @throws SQLException
*/
private void processCreateTrigger(Tokenizer c,
Channel channel) throws SQLException {
Table t;
// typical sql is: CREATE TRIGGER tr1 AFTER INSERT ON tab1 CALL "pkg.cls"
boolean bForEach = false;
String sTrigName = c.getName();
String sWhen = c.getString();
String sOper = c.getString();
c.getThis("ON");
String sTableName = c.getString();
t = getTable(sTableName, channel);
// "FOR EACH ROW" or "CALL"
String tok = c.getString();
if (tok.equals("FOR")) {
// todo: get this working
tok = c.getString();
if (tok.equals("EACH")) {
tok = c.getString();
if (tok.equals("ROW")) {
bForEach = true;
tok = c.getString(); // should be 'CALL'
} else {
throw Trace.error(Trace.UNEXPECTED_END_OF_COMMAND, tok);
}
} else {
throw Trace.error(Trace.UNEXPECTED_END_OF_COMMAND, tok);
}
}
if (!tok.equals("CALL")) {
throw Trace.error(Trace.UNEXPECTED_END_OF_COMMAND, tok);
}
String sClassName =
c.getString(); // double quotes have been stripped
// System.out.println ("creating trigger " + sTrigName+" "+sWhen+" "+sOper);
TriggerDef td;
Trigger o;
try {
Class cl = Class.forName(sClassName); // dynamically load class
o = (Trigger) cl.newInstance(); // dynamically instantiate it
td = new TriggerDef(sTrigName, sWhen, sOper, bForEach, t, o,
"\"" + sClassName + "\"");
if (td.isValid()) {
t.addTrigger(td);
td.start(); // start the trigger thread
} else {
String msg = "Error in parsing trigger command ";
throw Trace.error(Trace.UNEXPECTED_TOKEN, msg);
}
} catch (Exception e) {
String msg = "Exception in loading trigger class "
+ e.getMessage();
throw Trace.error(Trace.UNKNOWN_FUNCTION, msg);
}
}
/**
* Method declaration
*
*
* @param c
* @param channel
* @param cached
*
* @throws SQLException
*/
private void processCreateTable(Tokenizer c, Channel channel,
boolean cached) throws SQLException {
Table t;
String sToken = c.getName();
if (cached && lLog != null) {
t = new Table(this, true, sToken, true);
} else {
t = new Table(this, true, sToken, false);
}
c.getThis("(");
int primarykeycolumn = -1;
int column = 0;
boolean constraint = false;
while (true) {
boolean identity = false;
sToken = c.getString();
if (sToken.equals("CONSTRAINT") || sToken.equals("PRIMARY")
|| sToken.equals("FOREIGN") || sToken.equals("UNIQUE")) {
c.back();
constraint = true;
break;
}
String sColumn = sToken;
int iType = Column.getTypeNr(c.getString());
if (iType == Column.VARCHAR && bIgnoreCase) {
iType = Column.VARCHAR_IGNORECASE;
}
sToken = c.getString();
if (iType == Column.DOUBLE && sToken.equals("PRECISION")) {
sToken = c.getString();
}
if (sToken.equals("(")) {
// overread length
do {
sToken = c.getString();
} while (!sToken.equals(")"));
sToken = c.getString();
}
boolean nullable = true;
if (sToken.equals("NULL")) {
sToken = c.getString();
} else if (sToken.equals("NOT")) {
c.getThis("NULL");
nullable = false;
sToken = c.getString();
}
if (sToken.equals("IDENTITY")) {
identity = true;
Trace.check(primarykeycolumn == -1, Trace.SECOND_PRIMARY_KEY,
sColumn);
sToken = c.getString();
primarykeycolumn = column;
}
if (sToken.equals("PRIMARY")) {
c.getThis("KEY");
Trace.check(identity || primarykeycolumn == -1,
Trace.SECOND_PRIMARY_KEY, sColumn);
primarykeycolumn = column;
sToken = c.getString();
}
t.addColumn(sColumn, iType, nullable, identity);
if (sToken.equals(")")) {
break;
}
if (!sToken.equals(",")) {
throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken);
}
column++;
}
if (primarykeycolumn != -1) {
t.createPrimaryKey(primarykeycolumn);
} else {
t.createPrimaryKey();
}
if (constraint) {
int i = 0;
while (true) {
sToken = c.getString();
String name = "SYSTEM_CONSTRAINT" + i;
i++;
if (sToken.equals("CONSTRAINT")) {
name = c.getString();
sToken = c.getString();
}
if (sToken.equals("PRIMARY")) {
c.getThis("KEY");
addUniqueConstraintOn(c, channel, name, t);
} else if (sToken.equals("UNIQUE")) {
addUniqueConstraintOn(c, channel, name, t);
} else if (sToken.equals("FOREIGN")) {
c.getThis("KEY");
addForeignKeyOn(c, channel, name, t);
}
sToken = c.getString();
if (sToken.equals(")")) {
break;
}
if (!sToken.equals(",")) {
throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken);
}
}
}
channel.commit();
linkTable(t);
}
/**
* Method declaration
*
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -