提交 3954b942 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 27cf2c8d
......@@ -21,13 +21,17 @@ import org.h2.util.Resources;
import org.h2.util.StringCache;
import org.h2.util.StringUtils;
/**
* This class can read a file that is similar to BNF (Backus–Naur form).
* It is made specially to support SQL grammar.
*/
public class Bnf {
static final boolean COMBINE_KEYWORDS = false;
private static final String SEPARATORS = " [](){}|.,\r\n<>:-+*/=<\">!'";
private static final long MAX_PARSE_TIME = 100;
private final Random random = new Random();
private final HashMap ruleMap = new HashMap();
private String syntax;
......@@ -38,10 +42,10 @@ public class Bnf {
private Rule lastRepeat;
private ArrayList statements;
private String currentTopic;
/**
* Create an instance using the grammar specified in the CSV file.
*
*
* @param csv if not specified, the help.csv is used
* @return a new instance
*/
......@@ -54,16 +58,16 @@ public class Bnf {
bnf.parse(csv);
return bnf;
}
Bnf() {
random.setSeed(1);
}
void addFixedRule(String name, int fixedType) {
Rule rule = new RuleFixed(fixedType);
addRule(name, 0, "Fixed", rule);
}
RuleHead addRule(String topic, int id, String section, Rule rule) {
RuleHead head = new RuleHead(id, section, topic, rule);
if (ruleMap.get(StringUtils.toLowerEnglish(topic)) != null) {
......@@ -72,16 +76,12 @@ public class Bnf {
ruleMap.put(StringUtils.toLowerEnglish(topic), head);
return head;
}
public Random getRandom() {
return random;
}
public HashMap getRuleMap() {
return ruleMap;
}
public void parse(Reader csv) throws Exception {
private void parse(Reader csv) throws Exception {
csv = new BufferedReader(csv);
Rule functions = null;
statements = new ArrayList();
......@@ -132,7 +132,7 @@ public class Bnf {
addFixedRule("@af@", RuleFixed.AF);
addFixedRule("@digit@", RuleFixed.DIGIT);
}
public String getSyntax(String rule, String syntax) {
StringTokenizer tokenizer = new StringTokenizer(syntax, SEPARATORS, true);
StringBuffer buff = new StringBuffer();
......@@ -169,12 +169,12 @@ public class Bnf {
}
return buff.toString();
}
private Rule parseRule() {
read();
return parseOr();
}
private Rule parseOr() {
Rule r = parseList();
if (firstChar == '|') {
......@@ -193,7 +193,7 @@ public class Bnf {
lastRepeat = r;
return r;
}
private Rule parseToken() {
Rule r;
if ((firstChar >= 'A' && firstChar <= 'Z') || (firstChar >= 'a' && firstChar <= 'z')) {
......@@ -238,7 +238,7 @@ public class Bnf {
firstChar = 0;
}
}
private String[] tokenize() {
ArrayList list = new ArrayList();
syntax = StringUtils.replaceAll(syntax, "yyyy-MM-dd", "@ymd@");
......@@ -286,7 +286,6 @@ public class Bnf {
}
public void linkStatements() {
HashMap ruleMap = getRuleMap();
for (Iterator it = ruleMap.values().iterator(); it.hasNext();) {
RuleHead r = (RuleHead) it.next();
r.getRule().setLinks(ruleMap);
......@@ -299,24 +298,7 @@ public class Bnf {
if (head == null) {
head = new RuleHead(0, "db", topic, rule);
ruleMap.put(topic, head);
statements.add(head);
} else {
head.rule = rule;
}
}
public void updateTopic(String topic, String[] array) {
topic = StringUtils.toLowerEnglish(topic);
ArrayList list = new ArrayList();
for (int i = 0; i < array.length; i++) {
list.add(new RuleElement(array[i], true, topic));
}
RuleList rule = new RuleList(list, true);
RuleHead head = (RuleHead) ruleMap.get(topic);
if (head == null) {
head = new RuleHead(0, "db", topic, rule);
ruleMap.put(topic, head);
statements.add(head);
statements.add(head);
} else {
head.rule = rule;
}
......
......@@ -6,17 +6,58 @@ package org.h2.bnf;
import java.util.HashMap;
/**
* Represents a BNF rule.
*/
public interface Rule {
/**
* Get the name of the rule.
*
* @return the name
*/
String name();
/**
* Get a random entry.
*
* @param config
* @param level
* @return the entry
*/
String random(Bnf config, int level);
/**
* Get the last entry.
*
* @return the last entry
*/
Rule last();
/**
* Update cross references.
*
* @param ruleMap the reference map
*/
void setLinks(HashMap ruleMap);
/**
* Add the next possible token for a query.
* Used for autocomplete support.
*
* @param query the query
* @param sentence the sentence context
*/
void addNextTokenList(String query, Sentence sentence);
/**
*
* Remove a token from a sentence.
* Used for autocomplete support.
*
* @param query the query
* @param sentence the sentence context
* @return null if not a match or a partial match, query.substring... if a full match
*/
String matchRemove(String query, Sentence sentence);
}
......@@ -8,6 +8,9 @@ import java.util.HashMap;
import org.h2.util.StringUtils;
/**
* A single terminal rule in a BNF object.
*/
public class RuleElement implements Rule {
private boolean keyword;
......@@ -15,15 +18,8 @@ public class RuleElement implements Rule {
private Rule link;
private int type;
private String topic;
public RuleElement(String name, boolean keyword, String topic) {
this.name = name;
this.topic = topic;
this.keyword = keyword;
this.type = Sentence.CONTEXT;
}
public RuleElement(String name, String topic) {
RuleElement(String name, String topic) {
this.name = name;
this.topic = topic;
if (name.length() == 1 || name.equals(StringUtils.toUpperEnglish(name))) {
......@@ -32,11 +28,11 @@ public class RuleElement implements Rule {
topic = StringUtils.toLowerEnglish(topic);
this.type = topic.startsWith("function") ? Sentence.FUNCTION : Sentence.KEYWORD;
}
public RuleElement merge(RuleElement rule) {
RuleElement merge(RuleElement rule) {
return new RuleElement(name + " " + rule.name, topic);
}
public String random(Bnf config, int level) {
if (keyword) {
return name.length() > 1 ? " " + name + " " : name;
......@@ -66,7 +62,7 @@ public class RuleElement implements Rule {
String test = StringUtils.toLowerEnglish(name.substring(i));
RuleHead r = (RuleHead) ruleMap.get(test);
if (r != null) {
link = r.rule;
link = r.getRule();
return;
}
}
......@@ -101,7 +97,7 @@ public class RuleElement implements Rule {
}
return query;
}
}
}
public void addNextTokenList(String query, Sentence sentence) {
if (sentence.stop()) {
......@@ -120,7 +116,7 @@ public class RuleElement implements Rule {
link.addNextTokenList(query, sentence);
}
public boolean isKeyword() {
boolean isKeyword() {
return keyword;
}
......
......@@ -9,21 +9,24 @@ import java.util.Random;
import org.h2.util.StringUtils;
/**
* Represents a hard coded terminal rule in a BNF object.
*/
public class RuleFixed implements Rule {
public static final int YMD = 0, HMS = 1, NANOS = 2;
public static final int ANY_EXCEPT_SINGLE_QUOTE = 3;
public static final int ANY_EXCEPT_DOUBLE_QUOTE = 4;
public static final int ANY_UNTIL_EOL = 5;
public static final int ANY_UNTIL_END = 6;
public static final int ANY_WORD = 7;
public static final int HEX_START = 10, CONCAT = 11, AZ_UNDERLINE = 12, AF = 13, DIGIT = 14;
static final int YMD = 0, HMS = 1, NANOS = 2;
static final int ANY_EXCEPT_SINGLE_QUOTE = 3;
static final int ANY_EXCEPT_DOUBLE_QUOTE = 4;
static final int ANY_UNTIL_EOL = 5;
static final int ANY_UNTIL_END = 6;
static final int ANY_WORD = 7;
static final int HEX_START = 10, CONCAT = 11, AZ_UNDERLINE = 12, AF = 13, DIGIT = 14;
private final int type;
public RuleFixed(int type) {
RuleFixed(int type) {
this.type = type;
}
public String random(Bnf config, int level) {
Random r = config.getRandom();
switch(type) {
......@@ -45,7 +48,7 @@ public class RuleFixed implements Rule {
}
return buff.toString();
}
case HEX_START:
case HEX_START:
return "0x";
case CONCAT:
return "||";
......@@ -70,7 +73,7 @@ public class RuleFixed implements Rule {
public void setLinks(HashMap ruleMap) {
}
public String matchRemove(String query, Sentence sentence) {
if (sentence.stop()) {
return null;
......@@ -83,12 +86,12 @@ public class RuleFixed implements Rule {
case YMD:
while (s.length() > 0 && "0123456789- ".indexOf(s.charAt(0)) >= 0) {
s = s.substring(1);
}
}
break;
case HMS:
while (s.length() > 0 && "0123456789:. ".indexOf(s.charAt(0)) >= 0) {
s = s.substring(1);
}
}
break;
case NANOS:
while (s.length() > 0 && Character.isDigit(s.charAt(0))) {
......@@ -172,9 +175,9 @@ public class RuleFixed implements Rule {
if (s == query) {
return null;
}
return s;
return s;
}
public void addNextTokenList(String query, Sentence sentence) {
if (sentence.stop()) {
return;
......@@ -241,6 +244,6 @@ public class RuleFixed implements Rule {
default:
throw new Error("type="+type);
}
}
}
}
......@@ -4,12 +4,14 @@
*/
package org.h2.bnf;
/**
* Represents the head of a BNF rule.
*/
public class RuleHead {
int id;
String section;
String topic;
Rule rule;
private String topic;
RuleHead(int id, String section, String topic, Rule rule) {
this.id = id;
......@@ -17,7 +19,7 @@ public class RuleHead {
this.topic = topic;
this.rule = rule;
}
public String getTopic() {
return topic;
}
......
......@@ -7,17 +7,15 @@ package org.h2.bnf;
import java.util.ArrayList;
import java.util.HashMap;
/**
* Represents a sequence of BNF rules, or a list of alternative rules.
*/
public class RuleList implements Rule {
private boolean or;
private ArrayList list;
private boolean mapSet;
RuleList(ArrayList list, boolean or) {
this.or = or;
this.list = list;
}
RuleList(Rule first, Rule next, boolean or) {
list = new ArrayList();
if (first instanceof RuleList && ((RuleList) first).or == or) {
......@@ -50,7 +48,7 @@ public class RuleList implements Rule {
}
this.or = or;
}
public String random(Bnf config, int level) {
if (or) {
if (level > 10) {
......@@ -70,7 +68,7 @@ public class RuleList implements Rule {
return buff.toString();
}
}
private Rule get(int idx) {
return ((Rule) list.get(idx));
}
......@@ -91,7 +89,7 @@ public class RuleList implements Rule {
mapSet = true;
}
}
public String matchRemove(String query, Sentence sentence) {
if (query.length() == 0) {
return null;
......@@ -118,7 +116,7 @@ public class RuleList implements Rule {
public void addNextTokenList(String query, Sentence sentence) {
if (sentence.stop()) {
//
//
}
if (or) {
for (int i = 0; i < list.size(); i++) {
......@@ -135,5 +133,5 @@ public class RuleList implements Rule {
}
}
}
}
......@@ -6,10 +6,13 @@ package org.h2.bnf;
import java.util.HashMap;
/**
* Represents an optional BNF rule.
*/
public class RuleOptional implements Rule {
private Rule rule;
private boolean mapSet;
RuleOptional(Rule rule, boolean repeat) {
this.rule = rule;
}
......@@ -56,6 +59,6 @@ public class RuleOptional implements Rule {
return;
}
rule.addNextTokenList(query, sentence);
}
}
}
......@@ -6,10 +6,13 @@ package org.h2.bnf;
import java.util.HashMap;
/**
* Represents a loop in a BNF object.
*/
public class RuleRepeat implements Rule {
Rule rule;
private Rule rule;
RuleRepeat(Rule rule) {
this.rule = rule;
}
......@@ -23,13 +26,13 @@ public class RuleRepeat implements Rule {
}
public void setLinks(HashMap ruleMap) {
// rule.setLinks(ruleMap);
// rule.setLinks(ruleMap);
}
public String random(Bnf config, int level) {
return rule.random(config, level);
}
public String matchRemove(String query, Sentence sentence) {
if (sentence.stop()) {
return null;
......
......@@ -9,24 +9,29 @@ import java.util.HashSet;
import org.h2.server.web.DbTableOrView;
/**
* A query context object. It contains the list of table and alias objects.
* Used for autocomplete.
*/
public class Sentence {
public static final int CONTEXT = 0, KEYWORD = 1;
public static final int FUNCTION = 2;
public static final int CONTEXT = 0;
static final int KEYWORD = 1;
static final int FUNCTION = 2;
public String text;
HashMap next;
long max;
DbTableOrView lastTable;
private DbTableOrView lastTable;
private HashSet tables;
private HashMap aliases;
public boolean stop() {
boolean stop() {
return System.currentTimeMillis() > max;
}
public void add(String n, String string, int type) {
next.put(type+"#"+n, string);
}
public void addAlias(String alias, DbTableOrView table) {
if (aliases == null) {
aliases = new HashMap();
......@@ -41,11 +46,11 @@ public class Sentence {
}
tables.add(table);
}
public HashSet getTables() {
return tables;
}
public HashMap getAliases() {
return aliases;
}
......
......@@ -12,12 +12,13 @@ import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.message.TraceObject;
import org.h2.result.LocalResult;
import org.h2.result.ResultInterface;
import org.h2.util.ObjectArray;
/**
* @author Thomas
* Represents a SQL statement. This object is only used on the server side.
*/
public abstract class Command implements CommandInterface {
private final String sql;
......@@ -54,7 +55,7 @@ public abstract class Command implements CommandInterface {
public final ResultInterface getMetaData() throws SQLException {
return queryMeta();
}
public ResultInterface executeQuery(int maxrows, boolean scrollable) throws SQLException {
return executeQueryLocal(maxrows);
}
......@@ -138,8 +139,8 @@ public abstract class Command implements CommandInterface {
public void cancel() {
this.cancel = true;
}
public String toString() {
return sql;
return TraceObject.toString(sql, getParameters());
}
}
......@@ -12,24 +12,28 @@ import org.h2.result.LocalResult;
import org.h2.util.ObjectArray;
import org.h2.value.Value;
/**
* Represents a single SQL statements.
* It wraps a prepared statement.
*/
public class CommandContainer extends Command {
private Prepared prepared;
CommandContainer(Parser parser, String sql, Prepared prepared) {
super(parser, sql);
prepared.setCommand(this);
this.prepared = prepared;
}
public ObjectArray getParameters() {
return prepared.getParameters();
}
public boolean isTransactional() {
return prepared.isTransactional();
}
public boolean isQuery() {
return prepared.isQuery();
}
......@@ -49,24 +53,24 @@ public class CommandContainer extends Command {
Value v = ((Expression) oldValues.get(i)).getValue(session);
Parameter p = (Parameter) newParams.get(i);
p.setValue(v);
}
}
prepared.prepare();
prepared.setModificationId(mod);
}
}
public int update() throws SQLException {
recompileIfRequired();
// TODO query time: should keep lock time separate from running time
// TODO query time: should keep lock time separate from running time
start();
prepared.checkParameters();
prepared.trace();
return prepared.update();
}
public LocalResult query(int maxrows) throws SQLException {
recompileIfRequired();
// TODO query time: should keep lock time separate from running time
// TODO query time: should keep lock time separate from running time
start();
prepared.checkParameters();
prepared.trace();
......@@ -80,5 +84,5 @@ public class CommandContainer extends Command {
public LocalResult queryMeta() throws SQLException {
return prepared.queryMeta();
}
}
......@@ -9,6 +9,9 @@ import java.sql.SQLException;
import org.h2.result.ResultInterface;
import org.h2.util.ObjectArray;
/**
* Represents a SQL statement.
*/
public interface CommandInterface {
boolean isQuery();
ObjectArray getParameters();
......
......@@ -9,23 +9,26 @@ import java.sql.SQLException;
import org.h2.result.LocalResult;
import org.h2.util.ObjectArray;
/**
* Represents a list of SQL statements.
*/
public class CommandList extends Command {
private final Command command;
private final String remaining;
// TODO lock if possible!
public CommandList(Parser parser, String sql, Command c, String remaining) {
super(parser, sql);
this.command = c;
this.remaining = remaining;
}
public ObjectArray getParameters() {
return command.getParameters();
}
private void executeRemaining() throws SQLException {
Command command = session.prepareLocal(remaining);
if (command.isQuery()) {
......@@ -34,23 +37,23 @@ public class CommandList extends Command {
command.update();
}
}
public int update() throws SQLException {
int updateCount = command.executeUpdate();
executeRemaining();
return updateCount;
}
public LocalResult query(int maxrows) throws SQLException {
LocalResult result = command.query(maxrows);
executeRemaining();
return result;
}
}
public boolean isQuery() {
return command.isQuery();
}
public boolean isTransactional() {
return true;
}
......@@ -58,7 +61,7 @@ public class CommandList extends Command {
public boolean isReadOnly() {
return false;
}
public LocalResult queryMeta() throws SQLException {
return command.queryMeta();
}
......
......@@ -12,11 +12,16 @@ import org.h2.engine.SessionRemote;
import org.h2.expression.ParameterInterface;
import org.h2.expression.ParameterRemote;
import org.h2.message.Trace;
import org.h2.message.TraceObject;
import org.h2.result.ResultInterface;
import org.h2.result.ResultRemote;
import org.h2.util.ObjectArray;
import org.h2.value.Transfer;
/**
* Represents the client-side part of a SQL statement.
* This class is not used in embedded mode.
*/
public class CommandRemote implements CommandInterface {
private final ObjectArray transferList;
......@@ -28,7 +33,7 @@ public class CommandRemote implements CommandInterface {
private boolean isQuery;
private boolean readonly;
private int paramCount;
public CommandRemote(SessionRemote session, ObjectArray transferList, String sql) throws SQLException {
this.transferList = transferList;
trace = session.getTrace();
......@@ -60,7 +65,7 @@ public class CommandRemote implements CommandInterface {
}
}
}
public boolean isQuery() {
return isQuery;
}
......@@ -68,7 +73,7 @@ public class CommandRemote implements CommandInterface {
public ObjectArray getParameters() {
return parameters;
}
public ResultInterface getMetaData() throws SQLException {
synchronized (session) {
session.checkClosed();
......@@ -173,7 +178,7 @@ public class CommandRemote implements CommandInterface {
return updateCount;
}
}
private void checkParameters() throws SQLException {
int len = parameters.size();
for (int i = 0; i < len; i++) {
......@@ -215,4 +220,8 @@ public class CommandRemote implements CommandInterface {
// TODO server: support cancel
}
public String toString() {
return TraceObject.toString(sql, getParameters());
}
}
......@@ -16,8 +16,11 @@ import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.util.ObjectArray;
/**
* A prepared statement.
*/
public abstract class Prepared {
protected Session session;
protected String sql;
protected int headPos = -1;
......@@ -32,7 +35,7 @@ public abstract class Prepared {
this.session = session;
modificationId = session.getDatabase().getModificationMetaId();
}
public boolean needRecompile() throws SQLException {
Database db = session.getDatabase();
if (db == null) {
......@@ -42,9 +45,9 @@ public abstract class Prepared {
// because needRecompile return true even for the first execution
return SysProperties.RECOMPILE_ALWAYS || prepareAlways || modificationId < db.getModificationMetaId();
}
public abstract boolean isTransactional();
public boolean isReadOnly() {
return false;
}
......@@ -52,11 +55,11 @@ public abstract class Prepared {
long getModificationId() {
return modificationId;
}
void setModificationId(long id) {
this.modificationId = id;
}
public void setParameterList(ObjectArray parameters) {
this.parameters = parameters;
}
......@@ -70,19 +73,19 @@ public abstract class Prepared {
Parameter param = (Parameter) parameters.get(i);
param.checkSet();
}
}
}
public void setCommand(Command command) {
this.command = command;
}
public boolean isQuery() {
return false;
}
public void prepare() throws SQLException {
// nothing to do
}
}
public int update() throws SQLException {
throw Message.getSQLException(ErrorCode.METHOD_NOT_ALLOWED_FOR_QUERY);
......@@ -90,14 +93,14 @@ public abstract class Prepared {
public LocalResult query(int maxrows) throws SQLException {
throw Message.getSQLException(ErrorCode.METHOD_ONLY_ALLOWED_FOR_QUERY);
}
}
public abstract LocalResult queryMeta() throws SQLException;
public void setSQL(String sql) {
this.sql = sql;
}
public String getSQL() {
return sql;
}
......@@ -115,7 +118,7 @@ public abstract class Prepared {
public String getPlanSQL() {
return null;
}
public void checkCancelled() throws SQLException {
// TODO strange code: probably checkCancelled should always be called on the session. fix & test after release 1.0
if (command != null) {
......@@ -124,7 +127,7 @@ public abstract class Prepared {
session.checkCancelled();
}
}
public void setObjectId(int i) {
this.objectId = i;
}
......@@ -136,7 +139,7 @@ public abstract class Prepared {
public void setSession(Session currentSession) {
this.session = currentSession;
}
void trace() throws SQLException {
if (session.getTrace().info()) {
StringBuffer buff = new StringBuffer();
......@@ -163,7 +166,7 @@ public abstract class Prepared {
public void setPrepareAlways(boolean prepareAlways) {
this.prepareAlways = prepareAlways;
}
protected void setCurrentRowNumber(int rowNumber) {
this.currentRowNumber = rowNumber;
}
......@@ -171,7 +174,7 @@ public abstract class Prepared {
public int getCurrentRowNumber() {
return currentRowNumber;
}
public String toString() {
return sql;
}
......
......@@ -13,6 +13,10 @@ import org.h2.index.Index;
import org.h2.message.Message;
import org.h2.schema.Schema;
/**
* This class represents the statement
* ALTER INDEX RENAME
*/
public class AlterIndexRename extends DefineCommand {
private Index oldIndex;
......
......@@ -12,6 +12,10 @@ import org.h2.engine.Session;
import org.h2.message.Message;
import org.h2.schema.Sequence;
/**
* This class represents the statement
* ALTER SEQUENCE
*/
public class AlterSequence extends DefineCommand {
private Sequence sequence;
......
......@@ -28,9 +28,9 @@ import org.h2.table.TableFilter;
import org.h2.util.ObjectArray;
/**
* @author Thomas
* This class represents the statement
* ALTER TABLE ADD CONSTRAINT
*/
public class AlterTableAddConstraint extends SchemaCommand {
public static final int CHECK = 0, UNIQUE = 1, REFERENTIAL = 2, PRIMARY_KEY = 3;
......
......@@ -26,6 +26,17 @@ import org.h2.table.Table;
import org.h2.table.TableData;
import org.h2.util.ObjectArray;
/**
* This class represents the statements
* ALTER TABLE ADD,
* ALTER TABLE ALTER COLUMN,
* ALTER TABLE ALTER COLUMN RESTART,
* ALTER TABLE ALTER COLUMN SELECTIVITY,
* ALTER TABLE ALTER COLUMN SET DEFAULT,
* ALTER TABLE ALTER COLUMN SET NOT NULL,
* ALTER TABLE ALTER COLUMN SET NULL,
* ALTER TABLE DROP COLUMN
*/
public class AlterTableAlterColumn extends SchemaCommand {
public static final int NOT_NULL = 0, NULL = 1, DEFAULT = 2, RESTART = 3, CHANGE_TYPE = 4;
......@@ -246,7 +257,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
}
// TODO loop instead of use insert (saves memory)
/*
*
*
* Index scan = table.getBestPlanItem(null).getIndex(); Cursor cursor =
* scan.find(null, null); while (cursor.next()) { Row row =
* cursor.get(); Row newRow = newTable.getTemplateRow(); for (int i=0,
......
......@@ -12,7 +12,8 @@ import org.h2.engine.Session;
import org.h2.schema.Schema;
/**
* @author Thomas
* This class represents the statement
* ALTER TABLE DROP CONSTRAINT
*/
public class AlterTableDropConstraint extends SchemaCommand {
......
......@@ -15,7 +15,8 @@ import org.h2.schema.Schema;
import org.h2.table.Table;
/**
* @author Thomas
* This class represents the statement
* ALTER TABLE RENAME
*/
public class AlterTableRename extends SchemaCommand {
......
......@@ -13,6 +13,10 @@ import org.h2.table.Column;
import org.h2.table.Table;
import org.h2.util.ObjectArray;
/**
* This class represents the statement
* ALTER TABLE ALTER COLUMN RENAME
*/
public class AlterTableRenameColumn extends DefineCommand {
private Table table;
......
......@@ -15,9 +15,11 @@ import org.h2.security.SHA256;
import org.h2.util.ByteUtils;
/**
* @author Thomas
* This class represents the statements
* ALTER USER ADMIN,
* ALTER USER RENAME,
* ALTER USER SET PASSWORD
*/
public class AlterUser extends DefineCommand {
public static final int SET_PASSWORD = 0, RENAME = 1, ADMIN = 2;
......
......@@ -10,6 +10,10 @@ import org.h2.engine.Right;
import org.h2.engine.Session;
import org.h2.table.TableView;
/**
* This class represents the statement
* ALTER VIEW
*/
public class AlterView extends DefineCommand {
private TableView view;
......
......@@ -17,6 +17,10 @@ import org.h2.table.Table;
import org.h2.table.TableData;
import org.h2.util.ObjectArray;
/**
* This class represents the statement
* ANALYZE
*/
public class Analyze extends DefineCommand {
private int sampleRows = Constants.SELECTIVITY_ANALYZE_SAMPLE_ROWS;
......
......@@ -12,6 +12,10 @@ import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.message.Message;
/**
* This class represents the statement
* CREATE AGGREGATE
*/
public class CreateAggregate extends DefineCommand {
private String name;
......
......@@ -15,6 +15,10 @@ import org.h2.schema.Constant;
import org.h2.schema.Schema;
import org.h2.value.Value;
/**
* This class represents the statement
* CREATE CONSTANT
*/
public class CreateConstant extends SchemaCommand {
private String constantName;
......
......@@ -12,6 +12,10 @@ import org.h2.engine.FunctionAlias;
import org.h2.engine.Session;
import org.h2.message.Message;
/**
* This class represents the statement
* CREATE ALIAS
*/
public class CreateFunctionAlias extends DefineCommand {
private String aliasName;
......
......@@ -17,7 +17,8 @@ import org.h2.table.IndexColumn;
import org.h2.table.Table;
/**
* @author Thomas
* This class represents the statement
* CREATE INDEX
*/
public class CreateIndex extends SchemaCommand {
......
......@@ -13,11 +13,10 @@ import org.h2.message.Message;
import org.h2.schema.Schema;
import org.h2.table.TableLink;
/**
* @author Thomas
* This class represents the statement
* CREATE LINKED TABLE
*/
public class CreateLinkedTable extends SchemaCommand {
private String tableName;
......@@ -76,7 +75,7 @@ public class CreateLinkedTable extends SchemaCommand {
db.addSchemaObject(session, table);
return 0;
}
public void setEmitUpdates(boolean emitUpdates) {
this.emitUpdates = emitUpdates;
}
......
......@@ -12,6 +12,10 @@ import org.h2.engine.Role;
import org.h2.engine.Session;
import org.h2.message.Message;
/**
* This class represents the statement
* CREATE ROLE
*/
public class CreateRole extends DefineCommand {
private String roleName;
......
......@@ -13,6 +13,10 @@ import org.h2.engine.User;
import org.h2.message.Message;
import org.h2.schema.Schema;
/**
* This class represents the statement
* CREATE SCHEMA
*/
public class CreateSchema extends DefineCommand {
private String schemaName;
......
......@@ -13,6 +13,10 @@ import org.h2.message.Message;
import org.h2.schema.Schema;
import org.h2.schema.Sequence;
/**
* This class represents the statement
* CREATE SEQUENCE
*/
public class CreateSequence extends SchemaCommand {
private String sequenceName;
......@@ -63,7 +67,7 @@ public class CreateSequence extends SchemaCommand {
public void setBelongsToTable(boolean belongsToTable) {
this.belongsToTable = belongsToTable;
}
public void setCacheSize(long cacheSize) {
this.cacheSize = cacheSize;
}
......
......@@ -25,7 +25,8 @@ import org.h2.util.ObjectArray;
import org.h2.value.DataType;
/**
* @author Thomas
* This class represents the statement
* CREATE TABLE
*/
public class CreateTable extends SchemaCommand {
......
......@@ -15,11 +15,10 @@ import org.h2.schema.TriggerObject;
import org.h2.table.Table;
/**
* @author Thomas
* This class represents the statement
* CREATE TRIGGER
*/
public class CreateTrigger extends SchemaCommand {
// TODO implement drop trigger
private String triggerName;
private boolean ifNotExists;
......
......@@ -14,6 +14,10 @@ import org.h2.message.Message;
import org.h2.security.SHA256;
import org.h2.util.ByteUtils;
/**
* This class represents the statement
* CREATE USER
*/
public class CreateUser extends DefineCommand {
private String userName;
......
......@@ -13,6 +13,10 @@ import org.h2.engine.UserDataType;
import org.h2.message.Message;
import org.h2.table.Column;
/**
* This class represents the statement
* CREATE DOMAIN
*/
public class CreateUserDataType extends DefineCommand {
private String typeName;
......
......@@ -14,6 +14,10 @@ import org.h2.message.Message;
import org.h2.schema.Schema;
import org.h2.table.TableView;
/**
* This class represents the statement
* CREATE VIEW
*/
public class CreateView extends SchemaCommand {
private Query select;
......
......@@ -8,14 +8,18 @@ import java.sql.SQLException;
import org.h2.engine.Session;
/**
* This class represents the statement
* DEALLOCATE
*/
public class DeallocateProcedure extends DefineCommand {
private String procedureName;
public DeallocateProcedure(Session session) {
super(session);
}
public int update() throws SQLException {
session.removeProcedure(procedureName);
return 0;
......
......@@ -8,22 +8,25 @@ import org.h2.command.Prepared;
import org.h2.engine.Session;
import org.h2.result.LocalResult;
/**
* This class represents a non-transaction statement, for example a CREATE or DROP.
*/
public abstract class DefineCommand extends Prepared {
public DefineCommand(Session session) {
super(session);
}
public boolean isTransactional() {
return false;
}
}
public boolean isReadOnly() {
return false;
}
public LocalResult queryMeta() {
return null;
}
}
......@@ -12,6 +12,10 @@ import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.message.Message;
/**
* This class represents the statement
* DROP AGGREGATE
*/
public class DropAggregate extends DefineCommand {
private String name;
......
......@@ -13,11 +13,15 @@ import org.h2.message.Message;
import org.h2.schema.Constant;
import org.h2.schema.Schema;
/**
* This class represents the statement
* DROP CONSTANT
*/
public class DropConstant extends SchemaCommand {
private String constantName;
private boolean ifExists;
public DropConstant(Session session, Schema schema) {
super(session, schema);
}
......
......@@ -15,15 +15,19 @@ import org.h2.schema.SchemaObject;
import org.h2.table.Table;
import org.h2.util.ObjectArray;
/**
* This class represents the statement
* DROP ALL OBJECTS
*/
public class DropDatabase extends DefineCommand {
private boolean dropAllObjects;
private boolean deleteFiles;
public DropDatabase(Session session) {
super(session);
}
public int update() throws SQLException {
if (dropAllObjects) {
dropAllObjects();
......@@ -33,7 +37,7 @@ public class DropDatabase extends DefineCommand {
}
return 0;
}
private void dropAllObjects() throws SQLException {
session.getUser().checkAdmin();
session.commit(true);
......@@ -108,9 +112,9 @@ public class DropDatabase extends DefineCommand {
public void setDropAllObjects(boolean b) {
this.dropAllObjects = b;
}
public void setDeleteFiles(boolean b) {
this.deleteFiles = b;
}
}
}
......@@ -12,6 +12,10 @@ import org.h2.engine.FunctionAlias;
import org.h2.engine.Session;
import org.h2.message.Message;
/**
* This class represents the statement
* DROP ALIAS
*/
public class DropFunctionAlias extends DefineCommand {
private String aliasName;
......
......@@ -17,7 +17,8 @@ import org.h2.table.Table;
import org.h2.util.ObjectArray;
/**
* @author Thomas
* This class represents the statement
* DROP INDEX
*/
public class DropIndex extends SchemaCommand {
......
......@@ -13,6 +13,10 @@ import org.h2.engine.Role;
import org.h2.engine.Session;
import org.h2.message.Message;
/**
* This class represents the statement
* DROP ROLE
*/
public class DropRole extends DefineCommand {
private String roleName;
......
......@@ -12,6 +12,10 @@ import org.h2.engine.Session;
import org.h2.message.Message;
import org.h2.schema.Schema;
/**
* This class represents the statement
* DROP SCHEMA
*/
public class DropSchema extends DefineCommand {
private String schemaName;
......
......@@ -13,6 +13,10 @@ import org.h2.message.Message;
import org.h2.schema.Schema;
import org.h2.schema.Sequence;
/**
* This class represents the statement
* DROP SEQUENCE
*/
public class DropSequence extends SchemaCommand {
private String sequenceName;
......
......@@ -15,7 +15,8 @@ import org.h2.schema.Schema;
import org.h2.table.Table;
/**
* @author Thomas
* This class represents the statement
* DROP TABLE
*/
public class DropTable extends SchemaCommand {
......
......@@ -15,6 +15,10 @@ import org.h2.schema.Schema;
import org.h2.schema.TriggerObject;
import org.h2.table.Table;
/**
* This class represents the statement
* DROP TRIGGER
*/
public class DropTrigger extends SchemaCommand {
private String triggerName;
......
......@@ -12,6 +12,10 @@ import org.h2.engine.Session;
import org.h2.engine.User;
import org.h2.message.Message;
/**
* This class represents the statement
* DROP USER
*/
public class DropUser extends DefineCommand {
private boolean ifExists;
......
......@@ -12,6 +12,10 @@ import org.h2.engine.Session;
import org.h2.engine.UserDataType;
import org.h2.message.Message;
/**
* This class represents the statement
* DROP DOMAIN
*/
public class DropUserDataType extends DefineCommand {
private String typeName;
......
......@@ -13,6 +13,10 @@ import org.h2.message.Message;
import org.h2.schema.Schema;
import org.h2.table.Table;
/**
* This class represents the statement
* DROP VIEW
*/
public class DropView extends SchemaCommand {
private String viewName;
......
......@@ -17,6 +17,13 @@ import org.h2.message.Message;
import org.h2.table.Table;
import org.h2.util.ObjectArray;
/**
* This class represents the statements
* GRANT RIGHT,
* GRANT ROLE,
* REVOKE RIGHT,
* REVOKE ROLE
*/
public class GrantRevoke extends DefineCommand {
public static final int GRANT = 0, REVOKE = 1;
......
......@@ -10,19 +10,23 @@ import org.h2.command.Prepared;
import org.h2.engine.Procedure;
import org.h2.engine.Session;
/**
* This class represents the statement
* PREPARE
*/
public class PrepareProcedure extends DefineCommand {
private String procedureName;
private Prepared prepared;
public PrepareProcedure(Session session) {
super(session);
}
public void checkParameters() {
// no not check parameters
}
public int update() throws SQLException {
Procedure proc = new Procedure(procedureName, prepared);
prepared.setParameterList(parameters);
......@@ -35,7 +39,7 @@ public class PrepareProcedure extends DefineCommand {
public void setProcedureName(String name) {
this.procedureName = name;
}
public void setPrepared(Prepared prep) {
this.prepared = prep;
}
......
......@@ -9,10 +9,13 @@ import java.sql.SQLException;
import org.h2.engine.Session;
import org.h2.schema.Schema;
/**
* This class represents a non-transaction statement that involves a schema.
*/
public abstract class SchemaCommand extends DefineCommand {
private final Schema schema;
public SchemaCommand(Session session, Schema schema) {
super(session);
this.schema = schema;
......@@ -21,5 +24,5 @@ public abstract class SchemaCommand extends DefineCommand {
protected Schema getSchema() throws SQLException {
return schema;
}
}
......@@ -14,6 +14,10 @@ import org.h2.expression.Expression;
import org.h2.message.Message;
import org.h2.table.Table;
/**
* This class represents the statement
* COMMENT
*/
public class SetComment extends DefineCommand {
private String schemaName;
......
......@@ -12,6 +12,10 @@ import org.h2.engine.Session;
import org.h2.message.Message;
import org.h2.table.Table;
/**
* This class represents the statement
* TRUNCATE TABLE
*/
public class TruncateTable extends DefineCommand {
private Table table;
......
......@@ -14,14 +14,15 @@ import org.h2.schema.Schema;
import org.h2.table.Table;
/**
* Represents a ALTER TABLE statement.
* This class represents the statement
* ALTER TABLE SET
*/
public class AlterTableSet extends SchemaCommand {
private String tableName;
private final int type;
private boolean checkExisting;
public static final int REFERENTIAL_INTEGRITY_TRUE = 4;
public static final int REFERENTIAL_INTEGRITY_FALSE = 5;
......@@ -29,21 +30,21 @@ public class AlterTableSet extends SchemaCommand {
super(session, schema);
this.type = type;
}
public void setCheckExisting(boolean b) {
this.checkExisting = b;
}
public boolean isTransactional() {
return true;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public int update() throws SQLException {
Table table = getSchema().getTableOrView(session, tableName);
Table table = getSchema().getTableOrView(session, tableName);
session.getUser().checkRight(table, Right.ALL);
table.lock(session, true, true);
switch(type) {
......
......@@ -28,6 +28,10 @@ import org.h2.util.FileUtils;
import org.h2.util.IOUtils;
import org.h2.util.ObjectArray;
/**
* This class represents the statement
* BACKUP
*/
public class BackupCommand extends Prepared {
private String fileName;
......@@ -129,7 +133,7 @@ public class BackupCommand extends Prepared {
public boolean isTransactional() {
return true;
}
public static String correctFileName(String f) {
f = f.replace('\\', '/');
if (f.startsWith("/")) {
......
......@@ -20,7 +20,8 @@ import org.h2.value.ValueArray;
import org.h2.value.ValueResultSet;
/**
* Represents a CALL statement.
* This class represents the statement
* CALL
*/
public class Call extends Prepared {
private Expression value;
......
......@@ -20,7 +20,8 @@ import org.h2.table.TableFilter;
import org.h2.util.StringUtils;
/**
* Represents a DELETE statement.
* This class represents the statement
* DELETE
*/
public class Delete extends Prepared {
......
......@@ -15,25 +15,26 @@ import org.h2.result.LocalResult;
import org.h2.util.ObjectArray;
/**
* Represents an EXECUTE statement.
* This class represents the statement
* EXECUTE
*/
public class ExecuteProcedure extends Prepared {
private ObjectArray expressions = new ObjectArray();
private Procedure procedure;
public ExecuteProcedure(Session session) {
super(session);
}
public void setProcedure(Procedure procedure) {
this.procedure = procedure;
}
public void setExpression(int index, Expression expr) throws SQLException {
expressions.add(index, expr);
}
private void setParameters() throws SQLException {
Prepared prepared = procedure.getPrepared();
ObjectArray params = prepared.getParameters();
......@@ -43,21 +44,21 @@ public class ExecuteProcedure extends Prepared {
p.setValue(expr.getValue(session));
}
}
public boolean isQuery() {
Prepared prepared = procedure.getPrepared();
Prepared prepared = procedure.getPrepared();
return prepared.isQuery();
}
public int update() throws SQLException {
setParameters();
Prepared prepared = procedure.getPrepared();
Prepared prepared = procedure.getPrepared();
return prepared.update();
}
public final LocalResult query(int limit) throws SQLException {
setParameters();
Prepared prepared = procedure.getPrepared();
Prepared prepared = procedure.getPrepared();
return prepared.query(limit);
}
......@@ -66,7 +67,7 @@ public class ExecuteProcedure extends Prepared {
}
public LocalResult queryMeta() throws SQLException {
Prepared prepared = procedure.getPrepared();
Prepared prepared = procedure.getPrepared();
return prepared.queryMeta();
}
......
......@@ -16,7 +16,8 @@ import org.h2.value.Value;
import org.h2.value.ValueString;
/**
* Represents an EXPLAIN statement.
* This class represents the statement
* EXPLAIN
*/
public class ExplainPlan extends Prepared {
......
......@@ -22,7 +22,8 @@ import org.h2.util.ObjectArray;
import org.h2.value.Value;
/**
* Represents an INSERT statement.
* This class represents the statement
* INSERT
*/
public class Insert extends Prepared {
......@@ -195,5 +196,5 @@ public class Insert extends Prepared {
public LocalResult queryMeta() {
return null;
}
}
......@@ -24,7 +24,8 @@ import org.h2.util.ObjectArray;
import org.h2.value.Value;
/**
* Represents a MERGE statement.
* This class represents the statement
* MERGE
*/
public class Merge extends Prepared {
......@@ -261,5 +262,5 @@ public class Merge extends Prepared {
public LocalResult queryMeta() {
return null;
}
}
......@@ -18,16 +18,17 @@ import org.h2.util.ScriptReader;
import org.h2.util.StringUtils;
/**
* Represents a RUNSCRIPT statement.
* This class represents the statement
* RUNSCRIPT
*/
public class RunScriptCommand extends ScriptBase {
private String charset = StringUtils.getDefaultCharset();
public RunScriptCommand(Session session) {
super(session);
}
public int update() throws SQLException {
session.getUser().checkAdmin();
int count = 0;
......@@ -51,7 +52,7 @@ public class RunScriptCommand extends ScriptBase {
}
return count;
}
private void execute(String sql) throws SQLException {
try {
Prepared command = session.prepare(sql);
......@@ -67,11 +68,11 @@ public class RunScriptCommand extends ScriptBase {
throw Message.addSQL(e, sql);
}
}
public void setCharset(String charset) {
this.charset = charset;
}
public LocalResult queryMeta() {
return null;
}
......
......@@ -17,6 +17,7 @@ import java.sql.Statement;
import java.util.Comparator;
import org.h2.command.Parser;
import org.h2.constant.SysProperties;
import org.h2.constraint.Constraint;
import org.h2.engine.Comment;
import org.h2.engine.Constants;
......@@ -54,7 +55,8 @@ import org.h2.value.ValueLob;
import org.h2.value.ValueString;
/**
* Represents a SCRIPT statement.
* This class represents the statement
* SCRIPT
*/
public class ScriptCommand extends ScriptBase {
......@@ -407,7 +409,7 @@ public class ScriptCommand extends ScriptBase {
private void reset() throws SQLException {
result = null;
buffer = null;
lineSeparator = StringUtils.utf8Encode(System.getProperty("line.separator"));
lineSeparator = StringUtils.utf8Encode(SysProperties.LINE_SEPARATOR);
}
private void add(String s, boolean insert) throws SQLException, IOException {
......
......@@ -28,7 +28,8 @@ import org.h2.value.CompareMode;
import org.h2.value.ValueInt;
/**
* Represents a SET statement.
* This class represents the statement
* SET
*/
public class Set extends Prepared {
......
......@@ -23,7 +23,8 @@ import org.h2.util.StringUtils;
import org.h2.value.Value;
/**
* Represents a union UPDATE statement.
* This class represents the statement
* UPDATE
*/
public class Update extends Prepared {
......@@ -94,10 +95,10 @@ public class Update extends Prepared {
count++;
}
}
// TODO self referencing referential integrity constraints don't work if update is multi-row and 'inversed' the condition!
// TODO self referencing referential integrity constraints don't work if update is multi-row and 'inversed' the condition!
// probably need multi-row triggers with 'deleted' and 'inserted' at the same time. anyway good for sql compatibility
// TODO update in-place (but if the position changes, we need to update all indexes) before row triggers
// the cached row is already updated - we need the old values
table.updateRows(this, session, rows);
if (table.fireRow()) {
......@@ -115,7 +116,7 @@ public class Update extends Prepared {
rows.close();
}
}
public String getPlanSQL() {
StringBuffer buff = new StringBuffer();
buff.append("UPDATE ");
......
......@@ -13,6 +13,9 @@ import java.util.zip.Inflater;
import org.h2.constant.ErrorCode;
import org.h2.message.Message;
/**
* This is a wrapper class for the Deflater class.
*/
public class CompressDeflate implements Compressor {
private int level = Deflater.BEST_SPEED;
......
......@@ -31,6 +31,10 @@
package org.h2.compress;
/**
* This class implements the LZF lossless data compression algorithm.
* LZF is optimized for speed.
*/
public class CompressLZF implements Compressor {
public void setOptions(String options) {
......
......@@ -4,6 +4,11 @@
*/
package org.h2.compress;
/**
* This class implements a data compression algorithm that does in fact not compress.
* This is useful if the data can not be compressed because it is encrypted,
* already compressed, or random.
*/
public class CompressNo implements Compressor {
public int getAlgorithm() {
......@@ -12,7 +17,7 @@ public class CompressNo implements Compressor {
public void setOptions(String options) {
}
public int compress(byte[] in, int inLen, byte[] out, int outPos) {
System.arraycopy(in, 0, out, outPos, inLen);
return outPos + inLen;
......
......@@ -6,6 +6,9 @@ package org.h2.compress;
import java.sql.SQLException;
/**
* Each data compression algorithm must implement this interface.
*/
public interface Compressor {
int NO = 0, LZF = 1, DEFLATE = 2;
......
......@@ -7,26 +7,30 @@ package org.h2.compress;
import java.io.IOException;
import java.io.InputStream;
/**
* An input stream to read from an LZF stream.
* The data is automatically expanded.
*/
public class LZFInputStream extends InputStream {
private final InputStream in;
private CompressLZF decompress = new CompressLZF();
private int pos;
private int bufferLength;
private byte[] inBuffer;
private byte[] buffer;
public LZFInputStream(InputStream in) throws IOException {
this.in = in;
if (readInt() != LZFOutputStream.MAGIC) {
throw new IOException("Not an LZFInputStream");
}
}
private byte[] ensureSize(byte[] buff, int len) {
return buff == null || buff.length < len ? new byte[len] : buff;
}
private void fillBuffer() throws IOException {
if (buffer != null && pos < bufferLength) {
return;
......@@ -50,7 +54,7 @@ public class LZFInputStream extends InputStream {
}
pos = 0;
}
private void readFully(byte[] buff, int len) throws IOException {
int off = 0;
while (len > 0) {
......@@ -59,7 +63,7 @@ public class LZFInputStream extends InputStream {
off += l;
}
}
private int readInt() throws IOException {
int x = in.read();
if (x < 0) {
......@@ -99,7 +103,7 @@ public class LZFInputStream extends InputStream {
}
return read == 0 ? -1 : read;
}
public int readBlock(byte[] b, int off, int len) throws IOException {
fillBuffer();
if (pos >= bufferLength) {
......@@ -111,7 +115,7 @@ public class LZFInputStream extends InputStream {
pos += max;
return max;
}
public void close() throws IOException {
in.close();
}
......
......@@ -9,16 +9,20 @@ import java.io.OutputStream;
import org.h2.engine.Constants;
/**
* An output stream to write an LZF stream.
* The data is automatically compressed.
*/
public class LZFOutputStream extends OutputStream {
static final int MAGIC = ('H' << 24) | ('2' << 16) | ('I' << 8) | 'S';
private final OutputStream out;
private final CompressLZF compress = new CompressLZF();
private final byte[] buffer;
private int pos;
private byte[] outBuffer;
public LZFOutputStream(OutputStream out) throws IOException {
this.out = out;
int len = Constants.IO_BUFFER_SIZE_COMPRESS;
......@@ -26,7 +30,7 @@ public class LZFOutputStream extends OutputStream {
ensureOutput(len);
writeInt(MAGIC);
}
private void ensureOutput(int len) {
// TODO calculate the maximum overhead (worst case) for the output
// buffer
......@@ -42,7 +46,7 @@ public class LZFOutputStream extends OutputStream {
}
buffer[pos++] = (byte) b;
}
private void compressAndWrite(byte[] buff, int len) throws IOException {
if (len > 0) {
ensureOutput(len);
......@@ -57,14 +61,14 @@ public class LZFOutputStream extends OutputStream {
}
}
}
private void writeInt(int x) throws IOException {
out.write((byte) (x >> 24));
out.write((byte) (x >> 16));
out.write((byte) (x >> 8));
out.write((byte) x);
}
public void write(byte[] buff, int off, int len) throws IOException {
while (len > 0) {
int copy = Math.min(buffer.length - pos, len);
......@@ -77,12 +81,12 @@ public class LZFOutputStream extends OutputStream {
len -= copy;
}
}
public void flush() throws IOException {
compressAndWrite(buffer, pos);
pos = 0;
}
public void close() throws IOException {
flush();
out.close();
......
......@@ -5,10 +5,10 @@
package org.h2.constant;
/**
* This class defines the error codes used for sql exceptions
* This class defines the error codes used for SQL exceptions.
*/
public class ErrorCode {
// 02: no data
public static final int NO_DATA_AVAILABLE = 2000;
......@@ -29,10 +29,10 @@ public class ErrorCode {
// 23: integrity constraint violation
public static final int CHECK_CONSTRAINT_VIOLATED_1 = 23000;
public static final int DUPLICATE_KEY_1 = 23001;
public static final int DUPLICATE_KEY_1 = 23001;
public static final int REFERENTIAL_INTEGRITY_VIOLATED_PARENT_MISSING_1 = 23002;
public static final int REFERENTIAL_INTEGRITY_VIOLATED_CHILD_EXISTS_1 = 23003;
// 3B: savepoint exception
// 42: syntax error or access rule violation
......@@ -60,18 +60,18 @@ public class ErrorCode {
public static final int FUNCTION_MUST_RETURN_RESULT_SET_1 = 90000;
public static final int METHOD_NOT_ALLOWED_FOR_QUERY = 90001;
public static final int METHOD_ONLY_ALLOWED_FOR_QUERY = 90002;
/**
* Thrown when trying to convert a String to a binary value. Two hex digits
* per byte are required. Example:
*
*
* <pre>
* CALL X'00023';
* Hexadecimal string with odd number of characters: 00023
* </pre>
*
*
* Correct:
*
*
* <pre>
* CALL X'000023';
* </pre>
......@@ -89,26 +89,26 @@ public class ErrorCode {
public static final int DATABASE_NOT_FOUND_1 = 90013;
public static final int PARSE_ERROR_1 = 90014;
public static final int SUM_OR_AVG_ON_WRONG_DATATYPE_1 = 90015;
/**
* The column must be included in the group by clause. Example:
*
*
* <pre>
* CREATE TABLE TEST(ID INT, NAME VARCHAR);
* INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World');
* SELECT ID, MAX(NAME) FROM TEST;
* Column ID must be in group by list.
* </pre>
*
*
* Correct:
*
*
* <pre>
* SELECT ID, MAX(NAME) FROM TEST GROUP BY ID;
* </pre>
*/
public static final int MUST_GROUP_BY_COLUMN_1 = 90016;
public static final int SECOND_PRIMARY_KEY = 90017;
/**
* The connection was opened, but never closed. In the finalizer of the
* connection, this forgotten close was detected and the connection was
......@@ -116,7 +116,7 @@ public class ErrorCode {
* as it is not guaranteed and behavior is virtual machine dependent. The
* application should close the connection. This exception only appears in
* the .trace.db file. Example:
*
*
* <pre>
* Connection conn = DriverManager.getConnection(&quot;jdbc:h2:&tilde;/test&quot;);
* conn = null;
......@@ -126,7 +126,7 @@ public class ErrorCode {
* <pre>
* conn.close();
* </pre>
*
*
*/
public static final int TRACE_CONNECTION_NOT_CLOSED = 90018;
public static final int CANNOT_DROP_CURRENT_USER = 90019;
......@@ -178,7 +178,7 @@ public class ErrorCode {
public static final int SAVEPOINT_IS_NAMED = 90065;
public static final int DUPLICATE_PROPERTY_1 = 90066;
public static final int CONNECTION_BROKEN = 90067;
/**
* The given expression that is used in the ORDER BY clause must be in the result list, otherwise the result would be ambiguous.
* <pre>
......@@ -209,9 +209,9 @@ public class ErrorCode {
public static final int SEQUENCE_BELONGS_TO_A_TABLE_1 = 90082;
public static final int COLUMN_MAY_BE_REFERENCED_1 = 90083;
public static final int CANNOT_DROP_LAST_COLUMN = 90084;
/**
* The index was generated by the system because of a unique constraint,
* The index was generated by the system because of a unique constraint,
* and it is not allowed to drop it manually.
* <pre>
* CREATE TABLE TEST(ID INT, CONSTRAINT UID UNIQUE(ID));
......@@ -227,7 +227,7 @@ public class ErrorCode {
public static final int CLASS_NOT_FOUND_1 = 90086;
public static final int METHOD_NOT_FOUND_1 = 90087;
public static final int UNKNOWN_MODE_1 = 90088;
/**
* The collection of the database must be set when the database is empty.
* <pre>
......@@ -266,9 +266,9 @@ public class ErrorCode {
public static final int VIEW_IS_INVALID_2 = 90109;
public static final int OVERFLOW_FOR_TYPE_1 = 90110;
public static final int ERROR_ACCESSING_LINKED_TABLE_2 = 90111;
/**
* When locking was disabled, a row was deleted twice.
* When locking was disabled, a row was deleted twice.
* This is an intern exception that should never be thrown to the application,
* because such deleted should be detected and the resulting exception ignored inside the database engine.
* <pre>
......@@ -291,7 +291,7 @@ public class ErrorCode {
/**
* This exception is thrown when PreparedStatement.setBigDecimal is called
* with object that extends the class BigDecimal, and the system property
* with object that extends the class BigDecimal, and the system property
* h2.allowBigDecimalExtensions is not set. Using extensions of BigDecimal is
* dangerous because the database relies on the behavior of BigDecimal.
* <pre>
......@@ -358,5 +358,5 @@ public class ErrorCode {
return "" + errorCode;
}
}
}
......@@ -21,6 +21,11 @@ import org.h2.message.TraceSystem;
*/
public class SysProperties {
public static final String LINE_SEPARATOR = getStringSetting("line.separator", "\n");
public static final String FILE_SEPARATOR = getStringSetting("file.separator", "/");
public static final String USER_HOME = getStringSetting("user.home", "");
public static final String FILE_ENCODING = getStringSetting("file.encoding", "Cp1252");
public static final int MIN_WRITE_DELAY = getIntSetting("h2.minWriteDelay", 5);
public static final boolean CHECK = getBooleanSetting("h2.check", true);
public static final boolean CHECK2 = getBooleanSetting("h2.check2", false);
......@@ -68,7 +73,7 @@ public class SysProperties {
public static final int DEFAULT_MAX_OPERATION_MEMORY = getIntSetting("h2.defaultMaxOperationMemory", 100000);
private static boolean getBooleanSetting(String name, boolean defaultValue) {
String s = System.getProperty(name);
String s = getProperty(name);
if (s != null) {
try {
return Boolean.valueOf(s).booleanValue();
......@@ -78,13 +83,22 @@ public class SysProperties {
return defaultValue;
}
private static String getStringSetting(String name, String defaultValue) {
String s = System.getProperty(name);
private static String getProperty(String name) {
try {
return System.getProperty(name);
} catch (SecurityException e) {
// applets may not do that - ignore
return null;
}
}
public static String getStringSetting(String name, String defaultValue) {
String s = getProperty(name);
return s == null ? defaultValue : s;
}
private static int getIntSetting(String name, int defaultValue) {
String s = System.getProperty(name);
String s = getProperty(name);
if (s != null) {
try {
return Integer.decode(s).intValue();
......
......@@ -17,19 +17,19 @@ import org.h2.table.Column;
import org.h2.table.Table;
/**
* @author Thomas
* The base calss for constraint checking.
*/
public abstract class Constraint extends SchemaObjectBase {
public static final String CHECK = "CHECK", REFERENTIAL = "REFERENTIAL", UNIQUE = "UNIQUE";
protected Table table;
public Constraint(Schema schema, int id, String name, Table table) {
super(schema, id, name, Trace.CONSTRAINT);
this.table = table;
this.setTemporary(table.getTemporary());
}
public void checkRename() throws SQLException {
// ok
}
......@@ -37,24 +37,24 @@ public abstract class Constraint extends SchemaObjectBase {
public int getType() {
return DbObject.CONSTRAINT;
}
public abstract String getConstraintType();
public abstract void checkRow(Session session, Table t, Row oldRow, Row newRow) throws SQLException;
public abstract boolean usesIndex(Index index);
public abstract boolean usesIndex(Index index);
public abstract boolean containsColumn(Column col);
public abstract String getCreateSQLWithoutIndexes();
public abstract boolean isBefore();
public abstract String getShortDescription();
public abstract void checkExistingData(Session session) throws SQLException;
public Table getTable() {
return table;
}
public Table getRefTable() {
return table;
}
public String getDropSQL() {
return null;
}
......
......@@ -20,30 +20,29 @@ import org.h2.table.TableFilter;
import org.h2.util.StringUtils;
/**
* @author Thomas
* A check contraint.
*/
public class ConstraintCheck extends Constraint {
private TableFilter filter;
private Expression expr;
public ConstraintCheck(Schema schema, int id, String name, Table table) {
super(schema, id, name, table);
}
public String getConstraintType() {
return Constraint.CHECK;
}
public void setTableFilter(TableFilter filter) {
this.filter = filter;
}
public void setExpression(Expression expr) {
this.expr = expr;
}
public String getCreateSQLForCopy(Table table, String quotedName) {
StringBuffer buff = new StringBuffer();
buff.append("ALTER TABLE ");
......@@ -58,8 +57,8 @@ public class ConstraintCheck extends Constraint {
buff.append(StringUtils.enclose(expr.getSQL()));
buff.append(" NOCHECK");
return buff.toString();
}
}
public String getShortDescription() {
StringBuffer buff = new StringBuffer();
buff.append(getName());
......@@ -67,23 +66,23 @@ public class ConstraintCheck extends Constraint {
buff.append(expr.getSQL());
return buff.toString();
}
public String getCreateSQLWithoutIndexes() {
return getCreateSQL();
}
}
public String getCreateSQL() {
return getCreateSQLForCopy(table, getSQL());
}
public void removeChildrenAndResources(Session session) {
table.removeConstraint(this);
table.removeConstraint(this);
filter = null;
expr = null;
table = null;
invalidate();
}
public void checkRow(Session session, Table t, Row oldRow, Row newRow) throws SQLException {
if (newRow == null) {
return;
......
......@@ -27,9 +27,8 @@ import org.h2.value.Value;
import org.h2.value.ValueNull;
/**
* @author Thomas
* A referential contraint.
*/
public class ConstraintReferential extends Constraint {
public static final int RESTRICT = 0, CASCADE = 1, SET_DEFAULT = 2, SET_NULL = 3;
......@@ -591,5 +590,5 @@ public class ConstraintReferential extends Constraint {
getShortDescription());
}
}
}
......@@ -15,9 +15,8 @@ import org.h2.table.Table;
import org.h2.util.StringUtils;
/**
* @author Thomas
* A unique contraint. This object always backed by a unique index.
*/
public class ConstraintUnique extends Constraint {
private Index index;
......
......@@ -11,6 +11,9 @@ import org.h2.message.Trace;
import org.h2.table.Table;
import org.h2.util.StringUtils;
/**
* Represents a database object comment.
*/
public class Comment extends DbObjectBase {
private final int objectType;
......@@ -56,7 +59,7 @@ public class Comment extends DbObjectBase {
return "type" + type;
}
}
public String getDropSQL() {
return null;
}
......
......@@ -20,6 +20,9 @@ import org.h2.util.MathUtils;
import org.h2.util.ObjectArray;
import org.h2.util.StringUtils;
/**
* Encapsulates the connection settings, including user name and password.
*/
public class ConnectionInfo {
private static final HashSet KNOWN_SETTINGS = new HashSet();
private final Properties prop = new Properties();
......@@ -110,7 +113,7 @@ public class ConnectionInfo {
public void setBaseDir(String dir) {
if (persistent) {
name = dir + System.getProperty("file.separator") + name;
name = dir + SysProperties.FILE_SEPARATOR + name;
}
}
......@@ -166,7 +169,7 @@ public class ConnectionInfo {
}
}
}
DatabaseEventListener removeDatabaseEventListenerObject() throws SQLException {
Object p = prop.remove("DATABASE_EVENT_LISTENER_OBJECT");
if (p == null) {
......
......@@ -61,8 +61,7 @@ import org.h2.value.ValueInt;
/**
* There is one database object per open database.
*
* @author Thomas
* @since 2004-04-15 22:49
*/
/*
......@@ -197,6 +196,8 @@ public class Database implements DataHandler {
// shutdown in progress - just don't register the handler
// (maybe an application wants to write something into a
// database at shutdown time)
} catch (SecurityException e) {
// applets may not do that - ignore
}
}
} catch (Throwable e) {
......@@ -542,7 +543,7 @@ public class Database implements DataHandler {
emergencyReserve.autoDelete();
emergencyReserve.setLength(SysProperties.EMERGENCY_SPACE_INITIAL);
}
traceSystem.getTrace(Trace.DATABASE).info("opened " + databaseName);
traceSystem.getTrace(Trace.DATABASE).info("opened " + databaseName);
}
private void recompileInvalidViews(Session session) {
......@@ -748,7 +749,7 @@ public class Database implements DataHandler {
public FunctionAlias findFunctionAlias(String name) {
return (FunctionAlias) functionAliases.get(name);
}
public UserAggregate findAggregate(String name) {
return (UserAggregate) aggregates.get(name);
}
......@@ -764,7 +765,7 @@ public class Database implements DataHandler {
}
return user;
}
public User getUser(String name) throws SQLException {
return getUser(name, Message.getSQLException(ErrorCode.USER_NOT_FOUND_1, name));
}
......@@ -870,6 +871,8 @@ public class Database implements DataHandler {
Runtime.getRuntime().removeShutdownHook(closeOnExit);
} catch (IllegalStateException e) {
// ignore
} catch (SecurityException e) {
// applets may not do that - ignore
}
closeOnExit = null;
}
......@@ -997,7 +1000,7 @@ public class Database implements DataHandler {
public ObjectArray getAllFunctionAliases() {
return new ObjectArray(functionAliases.values());
}
public ObjectArray getAllAggregates() {
return new ObjectArray(aggregates.values());
}
......@@ -1297,7 +1300,7 @@ public class Database implements DataHandler {
return ClassUtils.loadClass(className);
} catch (ClassNotFoundException e) {
throw Message.getSQLException(ErrorCode.CLASS_NOT_FOUND_1, new String[] { className }, e);
}
}
}
public void setEventListener(String className) throws SQLException {
......@@ -1598,7 +1601,7 @@ public class Database implements DataHandler {
public void setMode(Mode mode) {
this.mode = mode;
}
public Mode getMode() {
return mode;
}
......@@ -1610,7 +1613,7 @@ public class Database implements DataHandler {
public void setMultiThreaded(boolean multiThreaded) {
this.multiThreaded = multiThreaded;
}
public void setMaxOperationMemory(int maxOperationMemory) {
this.maxOperationMemory = maxOperationMemory;
}
......
......@@ -8,6 +8,9 @@ import java.sql.SQLException;
import org.h2.table.Table;
import org.h2.util.ObjectArray;
/**
* A database object such as a table, an index, or a user.
*/
public interface DbObject {
int INDEX = 1;
int SEQUENCE = 3;
......
......@@ -13,11 +13,10 @@ import org.h2.table.Table;
import org.h2.util.ObjectArray;
/**
* @author Thomas
* The base class for all database objects.
*/
public abstract class DbObjectBase implements DbObject {
private int id;
protected Database database;
protected Trace trace;
......@@ -71,7 +70,7 @@ public abstract class DbObjectBase implements DbObject {
public abstract String getCreateSQL();
public abstract String getDropSQL();
public abstract int getType();
public abstract void removeChildrenAndResources(Session session) throws SQLException;
......
......@@ -16,7 +16,9 @@ import org.h2.message.Trace;
import org.h2.util.StringUtils;
/**
* @author Thomas
* The engine contains a map of all open databases.
* It is also responsible for opening and creating new databases.
* This is a singleton class.
*/
public class Engine {
// TODO use a 'engine'/'master' database to allow shut down the server, view & kill sessions and so on
......@@ -68,7 +70,7 @@ public class Engine {
if (user == null) {
try {
database.checkFilePasswordHash(cipher, ci.getFilePasswordHash());
//create the exception here so it is not possible from the stack trace
//create the exception here so it is not possible from the stack trace
// to see if the user name was wrong or the password
SQLException wrongUserOrPassword = Message.getSQLException(ErrorCode.WRONG_USER_OR_PASSWORD);
user = database.getUser(ci.getUserName(), wrongUserOrPassword);
......
......@@ -19,6 +19,9 @@ import org.h2.value.DataType;
import org.h2.value.Value;
import org.h2.value.ValueNull;
/**
* Represents a user defined function, or alias.
*/
public class FunctionAlias extends DbObjectBase {
private boolean hasConnectionParam;
......
......@@ -16,13 +16,17 @@ import org.h2.util.ObjectArray;
import org.h2.value.ValueInt;
import org.h2.value.ValueString;
/**
* A record in the system table of the database.
* It contains the SQL statement to create the database object.
*/
public class MetaRecord {
private int id;
private int objectType;
private int headPos;
private String sql;
public MetaRecord(SearchRow r) throws SQLException {
id = r.getValue(0).getInt();
headPos = r.getValue(1).getInt();
......
......@@ -8,10 +8,14 @@ import java.util.HashMap;
import org.h2.util.StringUtils;
/**
* The compatibility modes. There is a fixed set of modes (for example PostgreSQL, MySQL).
* Each mode has different settings.
*/
public class Mode {
public static final String REGULAR = "REGULAR";
public boolean nullConcatIsNull;
public boolean convertInsertNullToZero;
public boolean convertOnlyToSmallerScale;
......@@ -22,11 +26,11 @@ public class Mode {
public boolean squareBracketQuotedNames;
private static final HashMap MODES = new HashMap();
private String name;
static {
Mode mode = new Mode(REGULAR);
Mode mode = new Mode(REGULAR);
add(mode);
mode = new Mode("PostgreSQL");
......@@ -34,39 +38,39 @@ public class Mode {
mode.roundWhenConvertToLong = true;
mode.systemColumns = true;
add(mode);
mode = new Mode("MySQL");
mode.convertInsertNullToZero = true;
mode.roundWhenConvertToLong = true;
mode.lowerCaseIdentifiers = true;
mode.indexDefinitionInCreateTable = true;
add(mode);
mode = new Mode("HSQLDB");
mode.nullConcatIsNull = true;
mode.convertOnlyToSmallerScale = true;
add(mode);
mode = new Mode("MSSQLServer");
mode.squareBracketQuotedNames = true;
add(mode);
}
private static void add(Mode mode) {
MODES.put(StringUtils.toUpperEnglish(mode.name), mode);
}
private Mode(String name) {
this.name = name;
}
public static Mode getInstance(String name) {
return (Mode) MODES.get(StringUtils.toUpperEnglish(name));
}
public String getName() {
return name;
}
}
......@@ -6,22 +6,25 @@ package org.h2.engine;
import org.h2.command.Prepared;
/**
* Represents a procedure. Procedures are implemented for PostgreSQL compatibility.
*/
public class Procedure {
private final String name;
private final Prepared prepared;
public Procedure(String name, Prepared prepared) {
this.name = name;
this.prepared = prepared;
}
public String getName() {
return name;
}
public Prepared getPrepared() {
return prepared;
}
}
......@@ -10,10 +10,13 @@ import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.table.Table;
/**
* An access right. Rights are regular database objects, but have generated names.
*/
public class Right extends DbObjectBase {
public static final int SELECT = 1, DELETE = 2, INSERT = 4, UPDATE = 8, ALL = 15;
private Role grantedRole;
private int grantedRight;
private Table grantedTable;
......@@ -24,14 +27,14 @@ public class Right extends DbObjectBase {
this.grantee = grantee;
this.grantedRole = grantedRole;
}
public Right(Database db, int id, RightOwner grantee, int grantedRight, Table grantedRightOnTable) {
super(db, id, ""+id, Trace.USER);
this.grantee = grantee;
this.grantedRight = grantedRight;
this.grantedTable = grantedRightOnTable;
}
private boolean appendRight(StringBuffer buff, int right, int mask, String name, boolean comma) {
if ((right & mask) != 0) {
if (comma) {
......@@ -120,5 +123,5 @@ public class Right extends DbObjectBase {
public int getRightMask() {
return grantedRight;
}
}
......@@ -12,13 +12,16 @@ import org.h2.constant.ErrorCode;
import org.h2.message.Message;
import org.h2.table.Table;
/**
* A right owner (sometimes called principal).
*/
public abstract class RightOwner extends DbObjectBase {
// key: role; value: right
private HashMap grantedRoles;
// key: table; value: right
private HashMap grantedRights;
protected RightOwner(Database database, int id, String name, String traceModule) {
super(database, id, name, traceModule);
}
......@@ -38,7 +41,7 @@ public abstract class RightOwner extends DbObjectBase {
}
return false;
}
protected boolean isRightGrantedRecursive(Table table, int rightMask) {
Right right;
if (grantedRights != null) {
......@@ -111,6 +114,6 @@ public abstract class RightOwner extends DbObjectBase {
return null;
}
return (Right) grantedRoles.get(role);
}
}
}
......@@ -11,8 +11,11 @@ import org.h2.message.Trace;
import org.h2.table.Table;
import org.h2.util.ObjectArray;
/**
* Represents a role. Roles can be granted to users, and to other roles.
*/
public class Role extends RightOwner {
private final boolean system;
public Role(Database database, int id, String roleName, boolean system) {
......
......@@ -36,10 +36,11 @@ import org.h2.value.Value;
import org.h2.value.ValueLong;
/**
* @author Thomas
* A session represents a database connection. When using the server mode,
* this object resides on the server side and communicates with a RemoteSession on the client side.
*/
public class Session implements SessionInterface {
private User user;
private int id;
private Database database;
......@@ -337,7 +338,7 @@ public class Session implements SessionInterface {
}
}
}
private void unlockAll() throws SQLException {
if (SysProperties.CHECK) {
if (undoLog.size() > 0) {
......@@ -597,9 +598,9 @@ public class Session implements SessionInterface {
autoCommitAtTransactionEnd = true;
autoCommit = false;
}
public boolean getRollbackMode() {
return rollbackMode;
}
}
......@@ -10,6 +10,9 @@ import org.h2.command.CommandInterface;
import org.h2.message.Trace;
import org.h2.store.DataHandler;
/**
* A local or remote session. A session represents a database connection.
*/
public interface SessionInterface {
CommandInterface prepareCommand(String sql) throws SQLException;
void close() throws SQLException;
......
......@@ -27,6 +27,10 @@ import org.h2.util.StringUtils;
import org.h2.value.Transfer;
import org.h2.value.Value;
/**
* The client side part of a session when using the server mode.
* This object communicates with a Session on the server side.
*/
public class SessionRemote implements SessionInterface, DataHandler {
public static final int SESSION_PREPARE = 0;
......
......@@ -10,8 +10,11 @@ import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.table.Table;
/**
* A persistent database setting.
*/
public class Setting extends DbObjectBase {
private int intValue;
private String stringValue;
......@@ -25,24 +28,24 @@ public class Setting extends DbObjectBase {
public int getIntValue() {
return intValue;
}
}
public void setStringValue(String value) {
stringValue = value;
}
public String getStringValue() {
return stringValue;
}
}
public String getCreateSQLForCopy(Table table, String quotedName) {
throw Message.getInternalError();
}
public String getDropSQL() {
return null;
}
public String getCreateSQL() {
StringBuffer buff = new StringBuffer();
buff.append("SET ");
......
......@@ -20,6 +20,9 @@ import org.h2.util.ObjectArray;
import org.h2.util.RandomUtils;
import org.h2.util.StringUtils;
/**
* Represents a user object.
*/
public class User extends RightOwner {
private final boolean systemUser;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论