提交 10b7282c authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 5d76a0d3
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.compress;
import java.sql.SQLException;
import java.util.StringTokenizer;
import java.util.zip.*;
import org.h2.message.Message;
public class CompressDeflate implements Compresser {
private int level = Deflater.BEST_SPEED;
private int strategy = Deflater.DEFAULT_STRATEGY;
public void setOptions(String options) throws SQLException {
if(options == null) {
return;
}
try {
StringTokenizer tokenizer = new StringTokenizer(options);
while(tokenizer.hasMoreElements()) {
String option = tokenizer.nextToken();
if(option.equals("level") || option.equals("l")) {
level = Integer.parseInt(tokenizer.nextToken());
} else if(option.equals("strategy") || option.equals("s")) {
strategy = Integer.parseInt(tokenizer.nextToken());
}
}
} catch(Exception e) {
throw Message.getSQLException(Message.UNSUPPORTED_COMPRESSION_OPTIONS_1, options);
}
}
public int compress(byte[] in, int inLen, byte[] out, int outPos) {
Deflater deflater = new Deflater(level);
deflater.setStrategy(strategy);
deflater.setInput(in, 0, inLen);
deflater.finish();
int compressed = deflater.deflate(out, outPos, out.length - outPos);
return compressed;
}
public int getAlgorithm() {
return Compresser.DEFLATE;
}
public void expand(byte[] in, int inPos, int inLen, byte[] out, int outPos, int outLen) throws DataFormatException {
Inflater decompresser = new Inflater();
decompresser.setInput(in, inPos, inLen);
decompresser.finished();
decompresser.inflate(out, outPos, outLen);
decompresser.end();
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Copyright (c) 2000-2005 Marc Alexander Lehmann <schmorp@schmorp.de>
* Copyright (c) 2005 Oren J. Maurice <oymaurice@hazorea.org.il>
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
* CIAL, 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 OTH-
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License version 2 (the "GPL"), in which case the
* provisions of the GPL are applicable instead of the above. If you wish to
* allow the use of your version of this file only under the terms of the
* GPL and not to allow others to use your version of this file under the
* BSD license, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the GPL. If
* you do not delete the provisions above, a recipient may use your version
* of this file under either the BSD or the GPL.
*/
package org.h2.compress;
public class CompressLZF implements Compresser {
public void setOptions(String options) {
}
public int getAlgorithm() {
return Compresser.LZF;
}
static final int HLOG = 14;
static final int HASH_SIZE = (1 << 14);
static final int MAX_LITERAL = (1 << 5);
static final int MAX_OFF = (1 << 13);
static final int MAX_REF = ((1 << 8) + (1 << 3));
int first(byte[] in, int inPos) {
return (in[inPos] << 8) + (in[inPos + 1] & 255);
}
int next(int v, byte[] in, int inPos) {
return (v << 8) + (in[inPos + 2] & 255);
}
int hash(int h) {
// or 57321
return ((h * 184117) >> 9) & (HASH_SIZE - 1);
}
private int[] hashTab;
private static int[] empty = new int[HASH_SIZE];
public int compress(byte[] in, int inLen, byte[] out, int outPos) {
int inPos = 0;
if(hashTab == null) {
hashTab = new int[HASH_SIZE];
} else {
System.arraycopy(empty, 0, hashTab, 0, HASH_SIZE);
}
int literals = 0;
int hval = first(in, inPos);
while (true) {
if (inPos < inLen - 4) {
hval = next(hval, in, inPos);
int off = hash(hval);
int ref = hashTab[off];
hashTab[off] = inPos;
off = inPos - ref - 1;
if (off < MAX_OFF && ref > 0 && in[ref + 2] == in[inPos + 2] && in[ref + 1] == in[inPos + 1] && in[ref] == in[inPos]) {
int maxlen = inLen - inPos - 2;
maxlen = maxlen > MAX_REF ? MAX_REF : maxlen;
int len = 3;
while (len < maxlen && in[ref + len] == in[inPos + len]) {
len++;
}
len -= 2;
if (literals != 0) {
out[outPos++] = (byte) (literals - 1);
literals = -literals;
do {
out[outPos++] = in[inPos + literals++];
} while (literals != 0);
}
if (len < 7) {
out[outPos++] = (byte) ((off >> 8) + (len << 5));
} else {
out[outPos++] = (byte) ((off >> 8) + (7 << 5));
out[outPos++] = (byte) (len - 7);
}
out[outPos++] = (byte) off;
inPos += len;
hval = first(in, inPos);
hval = next(hval, in, inPos);
hashTab[hash(hval)] = inPos++;
hval = next(hval, in, inPos);
hashTab[hash(hval)] = inPos++;
continue;
}
} else if (inPos == inLen) {
break;
}
inPos++;
literals++;
if (literals == MAX_LITERAL) {
out[outPos++] = (byte) (literals - 1);
literals = -literals;
do {
out[outPos++] = in[inPos + literals++];
} while (literals != 0);
}
}
if (literals != 0) {
out[outPos++] = (byte) (literals - 1);
literals = -literals;
do {
out[outPos++] = in[inPos + literals++];
} while (literals != 0);
}
return outPos;
}
public void expand(byte[] in, int inPos, int inLen, byte[] out, int outPos, int outLen) {
do {
int ctrl = in[inPos++] & 255;
if (ctrl < (1 << 5)) {
// literal run
ctrl += inPos;
do {
out[outPos++] = in[inPos];
} while (inPos++ < ctrl);
} else {
// back reference
int len = ctrl >> 5;
int ref = -((ctrl & 0x1f) << 8) - 1;
if (len == 7) {
len += in[inPos++] & 255;
}
ref -= in[inPos++] & 255;
len += outPos + 2;
out[outPos] = out[outPos++ + ref];
out[outPos] = out[outPos++ + ref];
while (outPos < len - 8) {
out[outPos] = out[outPos++ + ref];
out[outPos] = out[outPos++ + ref];
out[outPos] = out[outPos++ + ref];
out[outPos] = out[outPos++ + ref];
out[outPos] = out[outPos++ + ref];
out[outPos] = out[outPos++ + ref];
out[outPos] = out[outPos++ + ref];
out[outPos] = out[outPos++ + ref];
}
while (outPos < len) {
out[outPos] = out[outPos++ + ref];
}
}
} while (outPos < outLen);
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.compress;
public class CompressNo implements Compresser {
public int getAlgorithm() {
return Compresser.NO;
}
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;
}
public void expand(byte[] in, int inPos, int inLen, byte[] out, int outPos, int outLen) {
System.arraycopy(in, inPos, out, outPos, outLen);
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.compress;
import java.sql.SQLException;
public interface Compresser {
int NO = 0, LZF = 1, DEFLATE = 2;
int getAlgorithm();
int compress(byte[] in, int inLen, byte[] out, int outPos);
void expand(byte[] in, int inPos, int inLen, byte[] out, int outPos, int outLen) throws Exception;
void setOptions(String options) throws SQLException;
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.compress;
import java.io.IOException;
import java.io.InputStream;
public class LZFInputStream extends InputStream {
private 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;
}
int len = readInt();
if(decompress == null) {
// EOF
this.bufferLength = 0;
} else if(len < 0) {
len = -len;
buffer = ensureSize(buffer, len);
readFully(buffer, len);
this.bufferLength = len;
} else {
inBuffer = ensureSize(inBuffer, len);
int size = readInt();
readFully(inBuffer, len);
buffer = ensureSize(buffer, size);
try {
decompress.expand(inBuffer, 0, len, buffer, 0, size);
} catch(Exception e) {
throw new IOException("Error decompressing bytes");
}
this.bufferLength = size;
}
pos = 0;
}
private void readFully(byte[] buff, int len) throws IOException {
int off = 0;
while(len > 0) {
int l = in.read(buff, off, len);
len -= l;
off += l;
}
}
private int readInt() throws IOException {
int x = in.read();
if(x<0) {
close();
decompress = null;
return 0;
}
x = (x<< 24) + (in.read() << 16) + (in.read() << 8) + in.read();
return x;
}
public int read() throws IOException {
fillBuffer();
if(pos >= bufferLength) {
return -1;
}
return buffer[pos++] & 255;
}
public int read(byte[] b) throws IOException {
return read(b, 0, b.length);
}
public int read(byte[] b, int off, int len) throws IOException {
if(len == 0) {
return 0;
}
int read = 0;
while(len > 0) {
int r = readBlock(b, off, len);
if(r < 0) {
break;
}
read += r;
off += r;
len -= r;
}
return read == 0 ? -1 : read;
}
public int readBlock(byte[] b, int off, int len) throws IOException {
fillBuffer();
if(pos >= bufferLength) {
return -1;
}
int max = Math.min(len, bufferLength - pos);
max = Math.min(max, b.length - off);
System.arraycopy(buffer, pos, b, off, max);
pos += max;
return max;
}
public void close() throws IOException {
in.close();
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.compress;
import java.io.IOException;
import java.io.OutputStream;
import org.h2.engine.Constants;
public class LZFOutputStream extends OutputStream {
static final int MAGIC = ('H' << 24) | ('2' << 16) | ('I' << 8) | 'S';
private OutputStream out;
private byte[] buffer;
private int pos;
private byte[] outBuffer;
private CompressLZF compress = new CompressLZF();
public LZFOutputStream(OutputStream out) throws IOException {
this.out = out;
int len = Constants.IO_BUFFER_SIZE_COMPRESS;
buffer = new byte[len];
ensureOutput(len);
writeInt(MAGIC);
}
private void ensureOutput(int len) {
// TODO calculate the maximum overhead (worst case) for the output buffer
int outputLen = (len < 100 ? len + 100 : len) * 2;
if(outBuffer == null || outBuffer.length < outputLen) {
outBuffer = new byte[outputLen];
}
}
public void write(int b) throws IOException {
if(pos >= buffer.length) {
flush();
}
buffer[pos++] = (byte)b;
}
private void compressAndWrite(byte[] buff, int len) throws IOException {
if(len > 0) {
ensureOutput(len);
int compressed = compress.compress(buff, len, outBuffer, 0);
if(compressed > len) {
writeInt(-len);
out.write(buff, 0, len);
} else {
writeInt(compressed);
writeInt(len);
out.write(outBuffer, 0, compressed);
}
}
}
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);
System.arraycopy(buff, off, buffer, pos, copy);
pos += copy;
if(pos >= buffer.length) {
flush();
}
off += copy;
len -= copy;
}
}
public void flush() throws IOException {
compressAndWrite(buffer, pos);
pos = 0;
}
public void close() throws IOException {
flush();
out.close();
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.constraint;
import java.sql.SQLException;
import org.h2.engine.DbObject;
import org.h2.engine.Session;
import org.h2.index.Index;
import org.h2.message.Trace;
import org.h2.result.Row;
import org.h2.schema.Schema;
import org.h2.schema.SchemaObject;
import org.h2.table.Column;
import org.h2.table.Table;
/**
* @author Thomas
*/
public abstract class Constraint extends SchemaObject {
protected Table table;
public static final String CHECK = "CHECK", REFERENTIAL = "REFERENTIAL", UNIQUE = "UNIQUE";
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
}
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 containsColumn(Column col);
public abstract String getCreateSQLWithoutIndexes();
public abstract boolean isBefore();
public abstract String getShortDescription();
public Table getTable() {
return table;
}
public Table getRefTable() {
return table;
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.constraint;
import java.sql.SQLException;
import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.index.Index;
import org.h2.message.Message;
import org.h2.result.Row;
import org.h2.schema.Schema;
import org.h2.table.Column;
import org.h2.table.Table;
import org.h2.table.TableFilter;
import org.h2.util.StringUtils;
/**
* @author Thomas
*/
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 ");
buff.append(table.getSQL());
buff.append(" ADD CONSTRAINT ");
buff.append(quotedName);
if(comment != null) {
buff.append(" COMMENT ");
buff.append(StringUtils.quoteStringSQL(comment));
}
buff.append(" CHECK");
buff.append(StringUtils.enclose(expr.getSQL()));
return buff.toString();
}
public String getShortDescription() {
StringBuffer buff = new StringBuffer();
buff.append(getName());
buff.append(": ");
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);
filter = null;
expr = null;
table = null;
invalidate();
}
public void checkRow(Session session, Table t, Row oldRow, Row newRow) throws SQLException {
if(newRow == null) {
return;
}
filter.set(newRow);
// Both TRUE and NULL are ok
if(Boolean.FALSE.equals(expr.getValue(session).getBoolean())) {
throw Message.getSQLException(Message.CHECK_CONSTRAINT_VIOLATED_1, getShortDescription());
}
}
public boolean usesIndex(Index index) {
return false;
}
public boolean containsColumn(Column col) {
// TODO check constraints / containsColumn: this is cheating, maybe the column is not referenced
String s = col.getSQL();
String sql = getCreateSQL();
return sql.indexOf(s) >= 0;
}
public Expression getExpression() {
return expr;
}
public boolean isBefore() {
return true;
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.constraint;
import java.sql.SQLException;
import org.h2.command.Parser;
import org.h2.engine.Session;
import org.h2.index.Index;
import org.h2.result.Row;
import org.h2.schema.Schema;
import org.h2.table.Column;
import org.h2.table.Table;
import org.h2.util.StringUtils;
/**
* @author Thomas
*/
public class ConstraintUnique extends Constraint {
private Index index;
private boolean indexOwner;
private Column[] columns;
public ConstraintUnique(Schema schema, int id, String name, Table table) {
super(schema, id, name, table);
}
public String getConstraintType() {
return Constraint.UNIQUE;
}
public String getCreateSQLForCopy(Table table, String quotedName) {
return getCreateSQLForCopy(table, quotedName, true);
}
public String getCreateSQLForCopy(Table table, String quotedName, boolean internalIndex) {
StringBuffer buff = new StringBuffer();
buff.append("ALTER TABLE ");
buff.append(table.getSQL());
buff.append(" ADD CONSTRAINT ");
buff.append(quotedName);
if(comment != null) {
buff.append(" COMMENT ");
buff.append(StringUtils.quoteStringSQL(comment));
}
buff.append(" UNIQUE(");
for (int i = 0; i < columns.length; i++) {
if (i > 0) {
buff.append(", ");
}
buff.append(Parser.quoteIdentifier(columns[i].getName()));
}
buff.append(")");
if(internalIndex && indexOwner && table == this.table) {
buff.append(" INDEX ");
buff.append(index.getSQL());
}
return buff.toString();
}
public String getShortDescription() {
StringBuffer buff = new StringBuffer();
buff.append(getName());
buff.append(": ");
buff.append("UNIQUE(");
for (int i = 0; i < columns.length; i++) {
if (i > 0) {
buff.append(", ");
}
buff.append(Parser.quoteIdentifier(columns[i].getName()));
}
buff.append(")");
return buff.toString();
}
public String getCreateSQLWithoutIndexes() {
return getCreateSQLForCopy(table, getSQL(), false);
}
public String getCreateSQL() {
return getCreateSQLForCopy(table, getSQL());
}
public void setColumns(Column[] columns) {
this.columns = columns;
}
public Column[] getColumns() {
return columns;
}
public void setIndex(Index index, boolean isOwner) {
this.index = index;
this.indexOwner = isOwner;
}
public void removeChildrenAndResources(Session session) throws SQLException {
table.removeConstraint(this);
if(indexOwner) {
database.removeSchemaObject(session, index);
}
index = null;
columns = null;
table = null;
invalidate();
}
public void checkRow(Session session, Table t, Row oldRow, Row newRow) {
// unique index check is enough
}
public boolean usesIndex(Index ind) {
return ind == index;
}
public boolean containsColumn(Column col) {
for(int i=0; i<columns.length; i++) {
if(columns[i] == col) {
return true;
}
}
return false;
}
public boolean isBefore() {
return true;
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.engine;
import java.sql.SQLException;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.table.Table;
import org.h2.util.StringUtils;
public class Comment extends DbObject {
private int objectType;
private String objectName;
private String commentText;
public Comment(Database database, int id, DbObject obj) {
super(database, id, getKey(obj), Trace.DATABASE);
this.objectType = obj.getType();
this.objectName = obj.getSQL();
}
public String getCreateSQLForCopy(Table table, String quotedName) {
throw Message.getInternalError();
}
private static String getTypeName(int type) {
switch(type) {
case DbObject.CONSTANT:
return "CONSTANT";
case DbObject.CONSTRAINT:
return "CONSTRAINT";
case DbObject.FUNCTION_ALIAS:
return "ALIAS";
case DbObject.INDEX:
return "INDEX";
case DbObject.ROLE:
return "ROLE";
case DbObject.SCHEMA:
return "SCHEMA";
case DbObject.SEQUENCE:
return "SEQUENCE";
case DbObject.TABLE_OR_VIEW:
return "TABLE";
case DbObject.TRIGGER:
return "TRIGGER";
case DbObject.USER:
return "USER";
case DbObject.USER_DATATYPE:
return "DOMAIN";
default:
// not supported by parser, but required when trying to find a comment
return "type" + type;
}
}
public String getCreateSQL() {
StringBuffer buff = new StringBuffer();
buff.append("COMMENT ON ");
buff.append(getTypeName(objectType));
buff.append(' ');
buff.append(objectName);
buff.append(" IS ");
if(commentText == null) {
buff.append("NULL");
} else {
buff.append(StringUtils.quoteStringSQL(commentText));
}
return buff.toString();
}
public int getType() {
return DbObject.COMMENT;
}
public void removeChildrenAndResources(Session session) throws SQLException {
}
public void checkRename() throws SQLException {
throw Message.getInternalError();
}
public static String getKey(DbObject obj) {
return getTypeName(obj.getType()) + " " + obj.getSQL();
}
public void setCommentText(String comment) {
this.commentText = comment;
}
}
差异被折叠。
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.engine;
/*
* Coding rules:
* - boolean CHECK = x > boolean CHECK = Database.CHECK
* - Database.CHECK = false (or true for debug build)
* - System.out > trace messages
*
* Release checklist
* - ant jarClient, check jar file size
* - change FAQ (next release planned, known bugs)
* - check version, change build number in Constants.java and build.xml
* - check code coverage
* - No " Message.getInternalError" (must be "throw Message.getInternalError")
* - No TODO in the docs
* - Run regression test with JDK 1.4 and 1.5
* - Change version(s) in performance.html; use latest versions of other databases
* - Run 'ant benchmark' (with JDK 1.4 currently)
* - copy the benchmark results and update the performance page and diagram
* (remove rows 2*open/close, 2*executed statement)
*
* - documentation: if there are new files, add them to MergeDocs
* - documentation: check if all javadoc files are in the index
* - ant docs
* - PDF (15 min)
* - footer
* - front page
* - tables (optimal size)
* - orphan control, page breaks
* - check no javascript
* - table of contents
* - switch off auto-build
* - ant all
* - make sure odbc files are the
* - make sure the pdf file is there
* - make sure the build files are removed
* - ant zip
* - windows installer (nsis)
* - test
* - test the windows service
* - TestSystemExit
* - test with hibernate
* - scan for viruses
*
* - Send a mail to Google Groups
* - newsletter: prepare, send (always send to BCC!!)
*
* @author Thomas
*/
public class Constants {
public static final int BUILD_ID = 32;
private static final String BUILD = "2006-12-03";
public static final int VERSION_MAJOR = 1;
public static final int VERSION_MINOR = 0;
public static final int FILE_BLOCK_SIZE = 16;
public static final String MAGIC_FILE_HEADER_TEXT = "-- H2 0.5/T -- ".substring(0, FILE_BLOCK_SIZE-1) + "\n";
public static final String MAGIC_FILE_HEADER = "-- H2 0.5/B -- ".substring(0, FILE_BLOCK_SIZE-1) + "\n";
public static final int TCP_DRIVER_VERSION = 3;
public static final int VERSION_JDBC_MAJOR = 3;
public static final int VERSION_JDBC_MINOR = 0;
public static String getVersion() {
return VERSION_MAJOR + "." + VERSION_MINOR+ " (" + BUILD + ")";
}
public static final int NULL_SORT_LOW = 1, NULL_SORT_HIGH = 2;
public static final int NULL_SORT_START = 3, NULL_SORT_END = 4;
public static final int NULL_SORT_DEFAULT = NULL_SORT_LOW;
public static final int DEFAULT_SERVER_PORT = 9092; // this is also in the docs
public static final String START_URL = "jdbc:h2:";
public static final String URL_FORMAT = START_URL + "{ {.|mem:}[name] | [file:]fileName | {tcp|ssl}:[//]server[:port][,server2[:port]]/name }[;key=value...]";
public static final String PRODUCT_NAME = "H2";
public static final String DRIVER_NAME = "H2 JDBC Driver";
public static final int IO_BUFFER_SIZE = 4 * 1024;
public static final int IO_BUFFER_SIZE_COMPRESS = 128 * 1024;
public static final int DEFAULT_CACHE_SIZE = 1 << 16;
public static final int CACHE_SIZE_INDEX_SHIFT = 3;
public static int CACHE_MIN_RECORDS = 16;
public static final int DEFAULT_CACHE_SIZE_INDEX = DEFAULT_CACHE_SIZE >> CACHE_SIZE_INDEX_SHIFT;
public static final int DEFAULT_CACHE_SIZE_LINEAR_INDEX = 1 << 8;
public static final String SUFFIX_DATA_FILE = ".data.db";
public static final String SUFFIX_LOG_FILE = ".log.db";
public static final String SUFFIX_INDEX_FILE = ".index.db";
public static final String SUFFIX_HASH_FILE = ".hash.db";
public static final String SUFFIX_LOCK_FILE = ".lock.db";
public static final String SUFFIX_TEMP_FILE = ".temp.db";
public static final String SUFFIX_TRACE_FILE = ".trace.db";
public static final String SUFFIX_LOB_FILE = ".lob.db";
public static final String SUFFIX_TRACE_START_FILE = ".start";
public static final String SUFFIX_SUMMARY_FILE = ".sum.db";
public static final String SUFFIX_LOBS_DIRECTORY = ".lobs.db";
public static final String UTF8 = "UTF8";
public static final int DEFAULT_TABLE_TYPE = 0;
public static final int DEFAULT_MAX_LENGTH_INPLACE_LOB = 128;
public static final int DEFAULT_MAX_LENGTH_CLIENTSIDE_LOB = 65536;
public static final int SALT_LEN = 8;
public static final int DEFAULT_DATA_PAGE_SIZE = 512;
public static final boolean USE_OBJECT_CACHE = true;
public static final int OBJECT_CACHE_SIZE = 1024;
public static final int OBJECT_CACHE_MAX_PER_ELEMENT_SIZE = 4096;
public static final String PRIMARY_KEY_PREFIX = "PRIMARY_KEY_";
public static final int LOCK_SLEEP = 1000;
// TODO for testing, the lock timeout is smaller than for interactive use cases
// public static final int INITIAL_LOCK_TIMEOUT = 60 * 1000;
public static final int INITIAL_LOCK_TIMEOUT = 1000;
public static final char DEFAULT_ESCAPE_CHAR = '\\';
public static final int DEFAULT_HTTP_PORT = 8082; // also in the docs
public static final boolean DEFAULT_HTTP_SSL = false;
public static final boolean DEFAULT_HTTP_ALLOW_OTHERS = false;
public static final int DEFAULT_FTP_PORT = 8021;
public static boolean MULTI_THREADED_KERNEL;
public static final int DEFAULT_MAX_MEMORY_ROWS = 10000;
public static final int DEFAULT_MAX_MEMORY_UNDO = Integer.MAX_VALUE;
public static final int DEFAULT_WRITE_DELAY = 500;
public static final String SERVER_PROPERTIES_TITLE = "H2 Server Properties";
public static final String SERVER_PROPERTIES_FILE = ".h2.server.properties";
public static final long LONG_QUERY_LIMIT_MS = 100;
public static final String PUBLIC_ROLE_NAME = "PUBLIC";
public static final String TEMP_TABLE_PREFIX = "TEMP_TABLE_";
public static final String TEMP_TABLE_TRANSACTION_PREFIX = "TEMP_TRANS_TABLE_";
public static final int BIGDECIMAL_SCALE_MAX = 100000;
public static final String SCHEMA_MAIN = "PUBLIC";
public static final String SCHEMA_INFORMATION = "INFORMATION_SCHEMA";
public static final String DBA_NAME = "DBA";
public static final String CHARACTER_SET_NAME = "Unicode";
public static final String CLUSTERING_DISABLED = "''";
public static final int EMERGENCY_SPACE_INITIAL = 1 * 1024 * 1024;
public static final int EMERGENCY_SPACE_MIN = 128 * 1024;
public static final int LOCK_MODE_OFF = 0;
public static final int LOCK_MODE_TABLE = 1;
public static final int LOCK_MODE_TABLE_GC = 2;
public static final int LOCK_MODE_READ_COMMITTED = 3;
public static final int SELECTIVITY_DISTINCT_COUNT = 10000;
public static final int SELECTIVITY_DEFAULT = 50;
public static final int SELECTIVITY_ANALYZE_SAMPLE_ROWS = 10000;
public static final int SERVER_CACHED_OBJECTS = 64;
public static final int SERVER_SMALL_RESULTSET_SIZE = 100;
public static final boolean LOG_ALL_ERRORS = false;
// the cost is calculated on rowcount + this offset, to avoid using the wrong or no index
// if the table contains no rows _currently_ (when preparing the statement)
public static final int COST_ROW_OFFSET = 1000;
public static final long FLUSH_INDEX_DELAY = 0;
public static final int THROTTLE_DELAY = 50;
public static boolean RUN_FINALIZERS = true;
// TODO performance: change this values and recompile for higher performance
public static boolean CHECK = true;
public static boolean CHECK2;
public static final String MANAGEMENT_DB_PREFIX = "management_db_";
public static final String MANAGEMENT_DB_USER = "sa";
public static int REDO_BUFFER_SIZE = 256 * 1024;
public static final boolean SERIALIZE_JAVA_OBJECTS = true;
public static boolean RECOMPILE_ALWAYS;
public static boolean OPTIMIZE_SUBQUERY_CACHE = true;
public static boolean OVERFLOW_EXCEPTIONS = true;
public static boolean LOB_FILES_IN_DIRECTORIES;
// TODO: also remove DataHandler.allocateObjectId, createTempFile when setting this to true and removing it
public static int LOB_FILES_PER_DIRECTORY = 256;
public static boolean OPTIMIZE_MIN_MAX = true;
public static boolean OPTIMIZE_IN = true;
// TODO there is a bug currently, need to refactor & debug the code to fix this (and add more tests!)
public static boolean OPTIMIZE_EVALUATABLE_SUBQUERIES;
public static final long DEFAULT_MAX_LOG_SIZE = 32 * 1024 * 1024;
public static final long LOG_SIZE_DIVIDER = 10;
public static final int ALLOW_LITERALS_NONE = 0;
public static final int ALLOW_LITERALS_NUMBERS = 1;
public static final int ALLOW_LITERALS_ALL = 2;
public static final int DEFAULT_ALLOW_LITERALS = ALLOW_LITERALS_ALL;
public static boolean AUTO_CONVERT_LOB_TO_FILES = true;
public static int MIN_WRITE_DELAY = 5;
public static final boolean ALLOW_EMTPY_BTREE_PAGES = true;
public static final String CONN_URL_INTERNAL = "jdbc:default:connection";
public static final String CONN_URL_COLUMNLIST = "jdbc:columnlist:connection";
public static final int VIEW_COST_CACHE_SIZE = 64;
public static final int VIEW_COST_CACHE_MAX_AGE = 10000; // 10 seconds
public static final int MAX_PARAMETER_INDEX = 100000;
// to slow down dictionary attacks
public static final int ENCRYPTION_KEY_HASH_ITERATIONS = 1024;
public static final String SCRIPT_SQL = "script.sql";
}
差异被折叠。
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.engine;
import java.lang.ref.WeakReference;
public class DatabaseCloser extends Thread {
private WeakReference databaseRef;
private int delayInMillis;
private boolean shutdownHook;
DatabaseCloser(Database db, int delayInMillis, boolean shutdownHook) {
this.databaseRef = new WeakReference(db);
this.delayInMillis = delayInMillis;
this.shutdownHook = shutdownHook;
}
public void reset() {
synchronized(this) {
databaseRef = null;
}
}
public void run() {
while(delayInMillis > 0) {
try {
int step = 100;
Thread.sleep(step);
delayInMillis -= step;
} catch(Exception e) {
// ignore
}
if(databaseRef == null) {
return;
}
}
synchronized(this) {
if(databaseRef != null) {
Database database = (Database) databaseRef.get();
if(database != null) {
database.close(shutdownHook);
}
}
}
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.engine;
import java.sql.SQLException;
import org.h2.command.Parser;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.table.Table;
import org.h2.util.ObjectArray;
/**
* @author Thomas
*/
public abstract class DbObject {
public static final int TABLE_OR_VIEW=0, INDEX=1, USER=2, SEQUENCE=3, TRIGGER=4;
public static final int CONSTRAINT = 5, SETTING = 6, ROLE = 7, RIGHT = 8, FUNCTION_ALIAS = 9;
public static final int SCHEMA = 10, CONSTANT = 11;
public static final int USER_DATATYPE = 12, COMMENT = 13;
protected String comment;
static int getCreateOrder(int type) {
switch(type) {
case SETTING:
return 0;
case USER:
return 1;
case SCHEMA:
return 2;
case USER_DATATYPE:
return 3;
case SEQUENCE:
return 4;
case CONSTANT:
return 5;
case FUNCTION_ALIAS:
return 6;
case TABLE_OR_VIEW:
return 7;
case INDEX:
return 8;
case CONSTRAINT:
return 9;
case TRIGGER:
return 10;
case ROLE:
return 11;
case RIGHT:
return 12;
case COMMENT:
return 13;
default:
throw Message.getInternalError("type="+type);
}
}
private int id;
protected Database database;
protected Trace trace;
private String objectName;
private long modificationId;
private boolean temporary;
protected DbObject(Database database, int id, String name, String traceModule) {
this.database = database;
this.trace = database.getTrace(traceModule);
this.id = id;
this.objectName = name;
this.modificationId = database == null ? -1 : database.getModificationMetaId();
}
public void setModified() {
this.modificationId = database == null ? -1 : database.getNextModificationMetaId();
}
public long getModificationId() {
return modificationId;
}
protected void setObjectName(String name) {
objectName = name;
}
public String getSQL() {
return Parser.quoteIdentifier(objectName);
}
public ObjectArray getChildren() {
return null;
}
public Database getDatabase() {
return database;
}
public int getId() {
return id;
}
public String getName() {
return objectName;
}
public abstract String getCreateSQLForCopy(Table table, String quotedName);
public abstract String getCreateSQL();
public abstract int getType();
public abstract void removeChildrenAndResources(Session session) throws SQLException;
public abstract void checkRename() throws SQLException;
protected void invalidate() {
setModified();
id = -1;
database = null;
trace = null;
objectName = null;
}
protected int getHeadPos() {
return 0;
}
public void rename(String newName) throws SQLException {
checkRename();
objectName = newName;
setModified();
}
public boolean getTemporary() {
return temporary;
}
public void setTemporary(boolean temporary) {
this.temporary = temporary;
}
public void setComment(String comment) {
this.comment = comment;
}
public String getComment() {
return comment;
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.engine;
import java.sql.SQLException;
import java.util.HashMap;
import org.h2.command.CommandInterface;
import org.h2.command.Parser;
import org.h2.command.dml.SetTypes;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.util.StringUtils;
/**
* @author Thomas
*/
public class Engine {
// TODO use a 'engine'/'master' database to allow shut down the server, view & kill sessions and so on
private HashMap databases = new HashMap();
private static Engine instance = new Engine();
private Engine() {
// don't allow others to instantiate
}
public static Engine getInstance() {
return instance;
}
private Session openSession(ConnectionInfo ci, boolean ifExists, String cipher) throws SQLException {
// may not remove properties here, otherwise they are lost if it is required to call it twice
String name = ci.getName();
Database database = (Database) databases.get(name);
User user = null;
boolean opened = false;
if(database == null) {
if(ifExists && !Database.exists(name)) {
throw Message.getSQLException(Message.DATABASE_NOT_FOUND_1, name);
}
database = new Database(name, ci, cipher);
opened = true;
if(database.getAllUsers().size()==0) {
// users is the last thing we add, so if no user is around, the database is not initialized correctly
user = new User(database, database.allocateObjectId(false, true), ci.getUserName(), false);
user.setAdmin(true);
user.setUserPasswordHash(ci.getUserPasswordHash());
database.setMasterUser(user);
}
databases.put(name, database);
}
synchronized(database) {
if(database.isClosing()) {
return null;
}
if(user == null) {
try {
database.checkFilePasswordHash(cipher, ci.getFilePasswordHash());
user = database.getUser(ci.getUserName());
user.checkUserPasswordHash(ci.getUserPasswordHash());
if(opened && !user.getAdmin()) {
// reset - because the user is not an admin, and has no right to listen to exceptions
database.setEventListener(null);
}
} catch(SQLException e) {
database.removeSession(null);
throw e;
}
}
checkClustering(ci, database);
Session session = database.createSession(user);
return session;
}
}
public synchronized Session getSession(ConnectionInfo ci) throws SQLException {
boolean ifExists = ci.removeProperty("IFEXISTS", false);
boolean ignoreUnknownSetting = ci.removeProperty("IGNORE_UNKNOWN_SETTINGS", false);
String cipher = ci.removeProperty("CIPHER", null);
Session session;
while(true) {
session = openSession(ci, ifExists, cipher);
if(session != null) {
break;
}
// we found a database that is currently closing
// wait a bit to avoid a busy loop
try {
Thread.sleep(1);
} catch(InterruptedException e) {
// ignore
}
}
String[] keys = ci.getKeys();
session.setAllowLiterals(true);
for(int i=0; i<keys.length; i++) {
String setting = keys[i];
String value = ci.getProperty(setting);
try {
CommandInterface command = session.prepareCommand("SET " + Parser.quoteIdentifier(setting) + " " + value);
command.executeUpdate();
} catch(SQLException e) {
if(!ignoreUnknownSetting) {
session.close();
throw e;
}
}
}
session.setAllowLiterals(false);
session.commit();
session.getDatabase().getTrace(Trace.SESSION).info("connected #" + session.getId());
return session;
}
private void checkClustering(ConnectionInfo ci, Database database) throws SQLException {
String clusterSession = ci.getProperty(SetTypes.CLUSTER, null);
if(Constants.CLUSTERING_DISABLED.equals(clusterSession)) {
// in this case, no checking is made
// (so that a connection can be made to disable/change clustering)
return;
}
String clusterDb = database.getCluster();
if(!Constants.CLUSTERING_DISABLED.equals(clusterDb)) {
if(!StringUtils.equals(clusterSession, clusterDb)) {
if(clusterDb.equals(Constants.CLUSTERING_DISABLED)) {
throw Message.getSQLException(Message.CLUSTER_ERROR_DATABASE_RUNS_ALONE);
} else {
throw Message.getSQLException(Message.CLUSTER_ERROR_DATABASE_RUNS_CLUSTERED_1, clusterDb);
}
}
}
}
public void close(String name) {
databases.remove(name);
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.engine;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.sql.Connection;
import java.sql.SQLException;
import org.h2.command.Parser;
import org.h2.expression.Expression;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.table.Table;
import org.h2.util.TypeConverter;
import org.h2.value.DataType;
import org.h2.value.Value;
import org.h2.value.ValueNull;
public class FunctionAlias extends DbObject {
private String className;
private String methodName;
private Method javaMethod;
private int paramCount;
private boolean hasConnectionParam;
private int dataType;
public FunctionAlias(Database db, int id, String name, String javaClassMethod) throws SQLException {
super(db, id, name, Trace.FUNCTION);
int paren = javaClassMethod.indexOf('(');
int lastDot = javaClassMethod.lastIndexOf('.', paren < 0 ? javaClassMethod.length() : paren);
if(lastDot < 0) {
throw Message.getSQLException(Message.SYNTAX_ERROR_1, javaClassMethod);
}
className = javaClassMethod.substring(0, lastDot);
methodName = javaClassMethod.substring(lastDot + 1);
Class javaClass;
try {
javaClass = database.loadClass(className);
} catch (ClassNotFoundException e) {
throw Message.getSQLException(Message.CLASS_NOT_FOUND_1, new String[]{className + " (" + methodName + ")"}, e);
}
Method[] methods = javaClass.getMethods();
for(int i=0; i<methods.length; i++) {
Method m = methods[i];
if(!Modifier.isStatic(m.getModifiers())) {
continue;
}
if(m.getName().equals(methodName)) {
javaMethod = m;
break;
} else if(getMethodSignature(m).equals(methodName)) {
javaMethod = m;
break;
}
}
if(javaMethod == null) {
throw Message.getSQLException(Message.METHOD_NOT_FOUND_1, methodName + " (" + className + ")");
}
Class[] paramClasses = javaMethod.getParameterTypes();
paramCount = paramClasses.length;
if(paramCount > 0) {
Class paramClass = paramClasses[0];
if(Connection.class.isAssignableFrom(paramClass)) {
hasConnectionParam = true;
paramCount--;
}
}
Class returnClass = javaMethod.getReturnType();
dataType = DataType.getTypeFromClass(returnClass);
}
private String getMethodSignature(Method m) {
StringBuffer buff = new StringBuffer();
buff.append(m.getName());
buff.append('(');
Class[] params = m.getParameterTypes();
for(int i=0; i<params.length; i++) {
if(i>0) {
buff.append(", ");
}
Class p = params[i];
if(p.isArray()) {
buff.append(p.getComponentType().getName());
buff.append("[]");
} else {
buff.append(p.getName());
}
}
buff.append(')');
return buff.toString();
}
public Class[] getColumnClasses() {
return javaMethod.getParameterTypes();
}
public int getDataType() {
return dataType;
}
public String getCreateSQLForCopy(Table table, String quotedName) {
throw Message.getInternalError();
}
public String getCreateSQL() {
StringBuffer buff = new StringBuffer();
buff.append("CREATE ALIAS ");
buff.append(getSQL());
buff.append(" FOR ");
buff.append(Parser.quoteIdentifier(className + "." + methodName));
return buff.toString();
}
public int getType() {
return DbObject.FUNCTION_ALIAS;
}
public void removeChildrenAndResources(Session session) throws SQLException {
className = methodName = null;
javaMethod = null;
invalidate();
}
public void checkRename() throws SQLException {
throw Message.getUnsupportedException();
}
public Value getValue(Session session, Expression[] args) throws SQLException {
return getValue(session, args, false);
}
public Value getValue(Session session, Expression[] args, boolean columnList) throws SQLException {
synchronized(this) {
Class[] paramClasses = javaMethod.getParameterTypes();
Object[] params = new Object[paramClasses.length];
int p = 0;
if(hasConnectionParam && params.length > 0) {
params[p++] = session.createConnection(columnList);
}
for(int a=0; a<args.length && p<params.length; a++, p++) {
Class paramClass = paramClasses[p];
int type = DataType.getTypeFromClass(paramClass);
Value v = args[a].getValue(session);
v = v.convertTo(type);
Object o = v.getObject();
if(o == null) {
if(paramClass.isPrimitive()) {
if(columnList) {
// if the column list is requested, the parameters may be null
// need to set to default value otherwise the function can't be called at all
o = TypeConverter.getDefaultForPrimitiveType(paramClass);
} else {
// NULL value for a java primitive: return NULL
return ValueNull.INSTANCE;
}
}
} else {
if(!paramClass.isAssignableFrom(o.getClass()) && !paramClass.isPrimitive()) {
o = TypeConverter.convertTo(session, session.createConnection(false), v, paramClass);
}
}
params[p] = o;
}
boolean old = session.getAutoCommit();
try {
session.setAutoCommit(false);
try {
Object returnValue;
returnValue = javaMethod.invoke(null, params);
if(returnValue == null) {
return ValueNull.INSTANCE;
}
Value ret = DataType.convertToValue(session, returnValue, dataType);
return ret.convertTo(dataType);
} catch (Exception e) {
throw Message.convert(e);
}
} finally {
session.setAutoCommit(old);
}
}
}
public int getParameterCount() {
return paramCount;
}
public String getJavaClassName() {
return this.className;
}
public String getJavaMethodName() {
return this.methodName;
}
public boolean hasConnectionParam() {
return this.hasConnectionParam;
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.engine;
import java.sql.SQLException;
import java.util.Comparator;
import org.h2.api.DatabaseEventListener;
import org.h2.command.Prepared;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.result.SearchRow;
import org.h2.util.ObjectArray;
import org.h2.value.ValueInt;
import org.h2.value.ValueString;
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();
objectType = r.getValue(2).getInt();
sql = r.getValue(3).getString();
}
public static void sort(ObjectArray records) {
records.sort(new Comparator() {
public int compare(Object o1, Object o2) {
MetaRecord m1 = (MetaRecord)o1;
MetaRecord m2 = (MetaRecord)o2;
int c1 = DbObject.getCreateOrder(m1.getObjectType());
int c2 = DbObject.getCreateOrder(m2.getObjectType());
if(c1 != c2) {
return c1 - c2;
}
return m1.getId() - m2.getId();
}
});
}
public void setRecord(SearchRow r) {
r.setValue(0, ValueInt.get(id));
r.setValue(1, ValueInt.get(headPos));
r.setValue(2, ValueInt.get(objectType));
r.setValue(3, ValueString.get(sql));
}
public MetaRecord(DbObject obj) {
id = obj.getId();
objectType = obj.getType();
headPos = obj.getHeadPos();
sql = obj.getCreateSQL();
}
void execute(Database db, Session systemSession, DatabaseEventListener listener) throws SQLException {
try {
Prepared command = systemSession.prepare(sql);
command.setObjectId(id);
command.setHeadPos(headPos);
command.update();
} catch(Throwable e) {
SQLException s = Message.convert(e);
db.getTrace(Trace.DATABASE).error(sql, s);
if(listener != null) {
listener.exceptionThrown(s);
// continue startup in this case
} else {
throw s;
}
}
}
public int getHeadPos() {
return headPos;
}
public void setHeadPos(int headPos) {
this.headPos = headPos;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getObjectType() {
return objectType;
}
public void setObjectType(int objectType) {
this.objectType = objectType;
}
public String getSQL() {
return sql;
}
public void setSql(String sql) {
this.sql = sql;
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.engine;
import java.util.HashMap;
import org.h2.util.StringUtils;
public class Mode {
// TODO isolation: this setting should not be global
public static Mode currentMode;
public static final String REGULAR_NAME = "REGULAR";
public boolean nullConcatIsNull;
public boolean convertInsertNullToZero;
public boolean convertOnlyToSmallerScale;
public boolean roundWhenConvertToLong ;
public boolean lowerCaseIdentifiers;
public boolean indexDefinitionInCreateTable;
private static final HashMap MODES = new HashMap();
private String name;
public static void setCurrentMode(Mode mode) {
currentMode = mode;
}
public static Mode getCurrentMode() {
return currentMode;
}
static {
Mode mode = new Mode(REGULAR_NAME);
setCurrentMode(mode);
add(mode);
mode = new Mode("PostgreSQL");
mode.nullConcatIsNull = true;
mode.roundWhenConvertToLong = 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);
}
private static void add(Mode mode) {
MODES.put(StringUtils.toUpperEnglish(mode.name), mode);
}
private Mode(String name) {
this.name = name;
}
public static Mode getMode(String name) {
return (Mode) MODES.get(StringUtils.toUpperEnglish(name));
}
public String getName() {
return name;
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.engine;
import java.sql.SQLException;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.table.Table;
public class Right extends DbObject {
public static final int SELECT = 1, DELETE = 2, INSERT = 4, UPDATE = 8, ALL = 15;
private Role grantedRole;
private int grantedRight;
private Table grantedTable;
private RightOwner grantee;
public Right(Database db, int id, RightOwner grantee, Role grantedRole) {
super(db, id, "RIGHT_"+id, Trace.USER);
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) {
buff.append(", ");
}
buff.append(name);
return true;
}
return comma;
}
public String getRights() {
StringBuffer buff = new StringBuffer();
if(grantedRight == ALL) {
buff.append("ALL");
} else {
boolean comma = false;
comma = appendRight(buff, grantedRight, SELECT, "SELECT", comma);
comma = appendRight(buff, grantedRight, DELETE, "DELETE", comma);
comma = appendRight(buff, grantedRight, INSERT, "INSERT", comma);
appendRight(buff, grantedRight, UPDATE, "UPDATE", comma);
}
return buff.toString();
}
public Role getGrantedRole() {
return grantedRole;
}
public Table getGrantedTable() {
return grantedTable;
}
public DbObject getGrantee() {
return grantee;
}
public String getCreateSQLForCopy(Table table, String quotedName) {
StringBuffer buff = new StringBuffer();
buff.append("GRANT ");
if(grantedRole != null) {
buff.append(grantedRole.getSQL());
} else {
buff.append(getRights());
buff.append(" ON ");
buff.append(table.getSQL());
}
buff.append(" TO ");
// TODO rights: need role 'PUBLIC'
buff.append(grantee.getSQL());
return buff.toString();
}
public String getCreateSQL() {
return getCreateSQLForCopy(grantedTable, null);
}
public int getType() {
return DbObject.RIGHT;
}
public void removeChildrenAndResources(Session session) throws SQLException {
if(grantedTable != null) {
grantee.revokeRight(grantedTable);
} else {
grantee.revokeRole(session, grantedRole);
}
grantedRole = null;
grantedTable = null;
grantee = null;
invalidate();
}
public void checkRename() throws SQLException {
throw Message.getInternalError();
}
public void setRightMask(int rightMask) {
grantedRight = rightMask;
}
public int getRightMask() {
return grantedRight;
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.engine;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import org.h2.message.Message;
import org.h2.table.Table;
public abstract class RightOwner extends DbObject {
// 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);
}
public boolean isRoleGranted(Role grantedRole) {
if(grantedRoles != null) {
Iterator it = grantedRoles.keySet().iterator();
while(it.hasNext()) {
Role role = (Role) it.next();
if(role == grantedRole) {
return true;
}
if(role.isRoleGranted(grantedRole)) {
return true;
}
}
}
return false;
}
protected boolean isRightGrantedRecursive(Table table, int rightMask) {
Right right;
if(grantedRights != null) {
right = (Right) grantedRights.get(table);
if(right != null) {
if((right.getRightMask() & rightMask) == rightMask) {
return true;
}
}
}
if(grantedRoles != null) {
Iterator it = grantedRoles.keySet().iterator();
while(it.hasNext()) {
RightOwner role = (RightOwner) it.next();
if(role.isRightGrantedRecursive(table, rightMask)) {
return true;
}
}
}
return false;
}
public void grantRight(Table table, Right right) {
if(grantedRights == null) {
grantedRights = new HashMap();
}
grantedRights.put(table, right);
}
public void revokeRight(Table table) {
if(grantedRights == null) {
return;
}
grantedRights.remove(table);
if(grantedRights.size() == 0) {
grantedRights = null;
}
}
public void grantRole(Session session, Role role, Right right) {
if(grantedRoles == null) {
grantedRoles = new HashMap();
}
grantedRoles.put(role, right);
}
public void revokeRole(Session session, Role role) throws SQLException {
if(grantedRoles == null) {
throw Message.getSQLException(Message.RIGHT_NOT_FOUND);
}
Right right = (Right) grantedRoles.get(role);
if(right == null) {
throw Message.getSQLException(Message.RIGHT_NOT_FOUND);
}
grantedRoles.remove(role);
if(grantedRoles.size() == 0) {
grantedRoles = null;
}
}
public Right getRightForTable(Table table) {
if(grantedRights == null) {
return null;
}
return (Right) grantedRights.get(table);
}
public Right getRightForRole(Role role) {
if(grantedRoles == null) {
return null;
}
return (Right) grantedRoles.get(role);
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.engine;
import java.sql.SQLException;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.table.Table;
import org.h2.util.ObjectArray;
public class Role extends RightOwner {
private boolean system;
public Role(Database database, int id, String roleName, boolean system) {
super(database, id, roleName, Trace.USER);
this.system = system;
}
public String getCreateSQLForCopy(Table table, String quotedName) {
throw Message.getInternalError();
}
public String getCreateSQL() {
if(system) {
return null;
}
return "CREATE ROLE "+getSQL();
}
public int getType() {
return DbObject.ROLE;
}
public void removeChildrenAndResources(Session session) throws SQLException {
ObjectArray users = database.getAllUsers();
for(int i=0; i<users.size(); i++) {
User user = (User) users.get(i);
Right right = user.getRightForRole(this);
if(right != null) {
database.removeDatabaseObject(session, right);
}
}
ObjectArray roles = database.getAllRoles();
for(int i=0; i<roles.size(); i++) {
Role r2 = (Role) roles.get(i);
Right right = r2.getRightForRole(this);
if(right != null) {
database.removeDatabaseObject(session, right);
}
}
ObjectArray rights = database.getAllRights();
for(int i=0; i<rights.size(); i++) {
Right right = (Right) rights.get(i);
if(right.getGrantee() == this) {
database.removeDatabaseObject(session, right);
}
}
invalidate();
}
public void checkRename() throws SQLException {
}
}
差异被折叠。
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.engine;
import java.sql.SQLException;
import org.h2.command.CommandInterface;
import org.h2.message.Trace;
import org.h2.store.DataHandler;
public interface SessionInterface {
CommandInterface prepareCommand(String sql) throws SQLException;
void close() throws SQLException;
Trace getTrace();
boolean isClosed();
SessionInterface createSession(ConnectionInfo ci) throws SQLException;
int getPowerOffCount();
void setPowerOffCount(int i) throws SQLException;
DataHandler getDataHandler();
}
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.expression;
import org.h2.value.Value;
/**
* @author Thomas
*/
public abstract class Condition extends Expression {
public int getType() {
return Value.BOOLEAN;
}
public int getScale() {
return 0;
}
public long getPrecision() {
return 0;
}
}
差异被折叠。
差异被折叠。
差异被折叠。
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.expression;
class FunctionInfo {
String name;
int type;
int dataType;
int parameterCount;
boolean nullIfParameterIsNull;
boolean isDeterministic;
}
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论