提交 437073c1 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 da6e461b
/*
* 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.util;
public class ClassUtils {
public static Class loadClass(String className) throws ClassNotFoundException {
// TODO support special syntax to load classes using another classloader
return Class.forName(className);
}
}
...@@ -151,6 +151,7 @@ public class DateTimeUtils { ...@@ -151,6 +151,7 @@ public class DateTimeUtils {
if(s.endsWith("Z")) { if(s.endsWith("Z")) {
s = s.substring(0, s.length()-1); s = s.substring(0, s.length()-1);
tz = TimeZone.getTimeZone("UTC");
} else { } else {
int timezoneStart = s.indexOf('+', s2 + 1); int timezoneStart = s.indexOf('+', s2 + 1);
if(timezoneStart < 0) { if(timezoneStart < 0) {
......
...@@ -314,7 +314,7 @@ public class FileUtils { ...@@ -314,7 +314,7 @@ public class FileUtils {
return fileName.startsWith(MEMORY_PREFIX) || fileName.startsWith(MEMORY_PREFIX_2); return fileName.startsWith(MEMORY_PREFIX) || fileName.startsWith(MEMORY_PREFIX_2);
} }
public static String createTempFile(String name, String suffix, boolean deleteOnExit) throws IOException, SQLException { public static String createTempFile(String name, String suffix, boolean deleteOnExit, boolean inTempDir) throws IOException, SQLException {
name += "."; name += ".";
if(isInMemory(name)) { if(isInMemory(name)) {
for(int i=0;; i++) { for(int i=0;; i++) {
...@@ -327,12 +327,18 @@ public class FileUtils { ...@@ -327,12 +327,18 @@ public class FileUtils {
} }
} }
String prefix = new File(name).getName(); String prefix = new File(name).getName();
File dir = new File(name).getAbsoluteFile().getParentFile(); File dir;
dir.mkdirs(); if(inTempDir) {
dir = null;
} else {
dir = new File(name).getAbsoluteFile().getParentFile();
dir.mkdirs();
}
File f = File.createTempFile(prefix, suffix, dir); File f = File.createTempFile(prefix, suffix, dir);
if(deleteOnExit) { if(deleteOnExit) {
f.deleteOnExit(); f.deleteOnExit();
} }
// return f.getPath();
return f.getCanonicalPath(); return f.getCanonicalPath();
} }
...@@ -344,6 +350,7 @@ public class FileUtils { ...@@ -344,6 +350,7 @@ public class FileUtils {
} }
public static String[] listFiles(String path) throws SQLException { public static String[] listFiles(String path) throws SQLException {
//System.out.println("listFiles: " + path);
if(isInMemory(path)) { if(isInMemory(path)) {
String[] list = new String[memoryFiles.size()]; String[] list = new String[memoryFiles.size()];
MemoryFile[] l = new MemoryFile[memoryFiles.size()]; MemoryFile[] l = new MemoryFile[memoryFiles.size()];
...@@ -353,19 +360,34 @@ public class FileUtils { ...@@ -353,19 +360,34 @@ public class FileUtils {
} }
return list; return list;
} }
File f = new File(path);
try { try {
File[] files = new File(path).listFiles(); String[] list = f.list();
if(files == null) { if(list == null) {
return new String[0]; return new String[0];
} }
String[] list = new String[files.length]; String base = f.getCanonicalPath() + File.separator;
for(int i=0; i<files.length; i++) { for(int i=0; i<list.length; i++) {
list[i] = files[i].getCanonicalPath(); list[i] = base + list[i];
} }
return list; return list;
} catch (IOException e) { } catch (IOException e) {
throw Message.convert(e); throw Message.convert(e);
} }
// try {
// File[] files = new File(path).listFiles();
// if(files == null) {
// return new String[0];
// }
// String[] list = new String[files.length];
// for(int i=0; i<files.length; i++) {
// list[i] = files[i].getCanonicalPath();
// }
// return list;
// } catch (IOException e) {
// throw Message.convert(e);
// }
} }
public static boolean isDirectory(String fileName) { public static boolean isDirectory(String fileName) {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package org.h2.util; package org.h2.util;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
...@@ -13,6 +14,8 @@ import java.sql.Statement; ...@@ -13,6 +14,8 @@ import java.sql.Statement;
import javax.sql.XAConnection; import javax.sql.XAConnection;
//#endif //#endif
import org.h2.message.Message;
public class JdbcUtils { public class JdbcUtils {
public static void closeSilently(Statement stat) { public static void closeSilently(Statement stat) {
...@@ -65,4 +68,15 @@ public class JdbcUtils { ...@@ -65,4 +68,15 @@ public class JdbcUtils {
} }
//#endif //#endif
public static Connection getConnection(String driver, String url, String user, String password) throws SQLException {
if(!StringUtils.isNullOrEmpty(driver)) {
try {
ClassUtils.loadClass(driver);
} catch (ClassNotFoundException e) {
throw Message.getSQLException(Message.CLASS_NOT_FOUND_1, new String[]{driver}, e);
}
}
return DriverManager.getConnection(url, user, password);
}
} }
...@@ -601,4 +601,8 @@ public class StringUtils { ...@@ -601,4 +601,8 @@ public class StringUtils {
return buff.append('\"').toString(); return buff.append('\"').toString();
} }
public static boolean isNullOrEmpty(String s) {
return s == null || s.length() == 0;
}
} }
...@@ -175,11 +175,13 @@ public class DataType { ...@@ -175,11 +175,13 @@ public class DataType {
createString(true), createString(true),
new String[]{"CLOB", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT", "NTEXT", "NCLOB"} new String[]{"CLOB", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT", "NTEXT", "NCLOB"}
); );
DataType dataType = new DataType();
dataType.prefix = "(";
dataType.suffix = "')";
add(Value.ARRAY, Types.ARRAY, "Array", add(Value.ARRAY, Types.ARRAY, "Array",
createString(false), dataType,
new String[]{"ARRAY"} new String[]{"ARRAY"}
); );
// TODO data types: try to support other types as well (longvarchar for odbc/access,...) - maybe map them to regular types? // TODO data types: try to support other types as well (longvarchar for odbc/access,...) - maybe map them to regular types?
} }
......
...@@ -262,7 +262,13 @@ public class Transfer { ...@@ -262,7 +262,13 @@ public class Transfer {
} }
writeLong(length); writeLong(length);
Reader reader = v.getReader(); Reader reader = v.getReader();
Writer writer = new OutputStreamWriter(out, Constants.UTF8); // below, writer.flush needs to be called to ensure the buffer is written
// but, this will also flush the output stream, and this slows things down
// so construct an output stream that will ignore this chained flush call
java.io.OutputStream out2 = new java.io.FilterOutputStream(out) {
public void flush() {}
};
Writer writer = new OutputStreamWriter(out2, Constants.UTF8);
long written = IOUtils.copyAndCloseInput(reader, writer); long written = IOUtils.copyAndCloseInput(reader, writer);
if(Constants.CHECK && written != length) { if(Constants.CHECK && written != length) {
throw Message.getInternalError("length:" + length + " written:" + written); throw Message.getInternalError("length:" + length + " written:" + written);
......
...@@ -194,9 +194,9 @@ public class ValueLob extends Value { ...@@ -194,9 +194,9 @@ public class ValueLob extends Value {
return name; return name;
} }
private static int getNewObjectId(String path) throws SQLException { private int getNewObjectId(DataHandler handler) throws SQLException {
int objectId; String path = handler.getDatabasePath();
objectId = 0; int objectId = 0;
while(true) { while(true) {
String dir = getFileNamePrefix(path, objectId); String dir = getFileNamePrefix(path, objectId);
String[] list = FileUtils.listFiles(dir); String[] list = FileUtils.listFiles(dir);
...@@ -204,7 +204,7 @@ public class ValueLob extends Value { ...@@ -204,7 +204,7 @@ public class ValueLob extends Value {
boolean[] used = new boolean[Constants.LOB_FILES_PER_DIRECTORY]; boolean[] used = new boolean[Constants.LOB_FILES_PER_DIRECTORY];
for(int i=0; i<list.length; i++) { for(int i=0; i<list.length; i++) {
String name = list[i]; String name = list[i];
if(name.endsWith(".db")) { if(name.endsWith(Constants.SUFFIX_DB_FILE)) {
name = name.substring(name.lastIndexOf(File.separatorChar) + 1); name = name.substring(name.lastIndexOf(File.separatorChar) + 1);
String n = name.substring(0, name.indexOf('.')); String n = name.substring(0, name.indexOf('.'));
int id; int id;
...@@ -282,7 +282,7 @@ public class ValueLob extends Value { ...@@ -282,7 +282,7 @@ public class ValueLob extends Value {
this.compression = compressionAlgorithm != null; this.compression = compressionAlgorithm != null;
synchronized(handler) { synchronized(handler) {
if(Constants.LOB_FILES_IN_DIRECTORIES) { if(Constants.LOB_FILES_IN_DIRECTORIES) {
objectId = getNewObjectId(handler.getDatabasePath()); objectId = getNewObjectId(handler);
fileName = getFileNamePrefix(handler.getDatabasePath(), objectId) + ".temp.db"; fileName = getFileNamePrefix(handler.getDatabasePath(), objectId) + ".temp.db";
} else { } else {
objectId = handler.allocateObjectId(false, true); objectId = handler.allocateObjectId(false, true);
...@@ -377,7 +377,7 @@ public class ValueLob extends Value { ...@@ -377,7 +377,7 @@ public class ValueLob extends Value {
if(linked) { if(linked) {
ValueLob copy = ValueLob.copy(this); ValueLob copy = ValueLob.copy(this);
if(Constants.LOB_FILES_IN_DIRECTORIES) { if(Constants.LOB_FILES_IN_DIRECTORIES) {
copy.objectId = getNewObjectId(handler.getDatabasePath()); copy.objectId = getNewObjectId(handler);
} else { } else {
copy.objectId = handler.allocateObjectId(false, true); copy.objectId = handler.allocateObjectId(false, true);
} }
......
...@@ -8,7 +8,7 @@ import java.sql.Connection; ...@@ -8,7 +8,7 @@ import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.Statement; import java.sql.Statement;
import org.h2.tools.Backup; import org.h2.tools.Script;
import org.h2.tools.DeleteDbFiles; import org.h2.tools.DeleteDbFiles;
import org.h2.tools.RunScript; import org.h2.tools.RunScript;
...@@ -30,9 +30,9 @@ public class Compact { ...@@ -30,9 +30,9 @@ public class Compact {
public static void compact(String dir, String dbName, String user, String password) throws Exception { public static void compact(String dir, String dbName, String user, String password) throws Exception {
String url = "jdbc:h2:" + dir + "/" + dbName; String url = "jdbc:h2:" + dir + "/" + dbName;
String script = "data/test.sql"; String file = "data/test.sql";
Backup.execute(url, user, password, script); Script.execute(url, user, password, file);
DeleteDbFiles.execute(dir, dbName, true); DeleteDbFiles.execute(dir, dbName, true);
RunScript.execute(url, user, password, script, null, false); RunScript.execute(url, user, password, file, null, false);
} }
} }
...@@ -16,6 +16,7 @@ import java.sql.SQLException; ...@@ -16,6 +16,7 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.sql.Types; import java.sql.Types;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Properties; import java.util.Properties;
import org.h2.jdbc.JdbcConnection; import org.h2.jdbc.JdbcConnection;
...@@ -561,4 +562,24 @@ public abstract class TestBase { ...@@ -561,4 +562,24 @@ public abstract class TestBase {
} }
} }
protected void compareDatabases(Statement stat1, Statement stat2) throws Exception {
ResultSet rs1 = stat1.executeQuery("SCRIPT NOPASSWORDS");
ResultSet rs2 = stat2.executeQuery("SCRIPT NOPASSWORDS");
ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList();
while(rs1.next()) {
check(rs2.next());
list1.add(rs1.getString(1));
list2.add(rs2.getString(1));
}
for(int i=0; i<list1.size(); i++) {
String s = (String)list1.get(i);
if(!list2.remove(s)) {
error("not found: " + s);
}
}
check(list2.size(), 0);
checkFalse(rs2.next());
}
} }
--- special grammar and test cases --------------------------------------------------------------------------------------------- --- special grammar and test cases ---------------------------------------------------------------------------------------------
select (1, 2);
> 1, 2
> ------
> (1, 2)
> rows: 1
select * from table(id int=(1, 2), name varchar=('Hello', 'World')) x order by id;
> ID NAME
> -- -----
> 1 Hello
> 2 World
> rows (ordered): 2
create table array_test(x array);
> ok
insert into array_test values((1, 2, 3)), ((2, 3, 4));
> update count: 2
select * from array_test where x = (1, 2, 3);
> X
> ---------
> (1, 2, 3)
> rows: 1
drop table array_test;
> ok
select * from (select 1), (select 2);
> 1 2
> - -
> 1 2
> rows: 1
CREATE TABLE TEST(A VARCHAR, B VARCHAR, C VARCHAR AS LOWER(A));
> ok
ALTER TABLE TEST DROP COLUMN B;
> ok
DROP TABLE TEST;
> ok
create table t1(c1 int, c2 int); create table t1(c1 int, c2 int);
> ok > ok
...@@ -92,14 +135,14 @@ CREATE TABLE test (family_name VARCHAR_IGNORECASE(63) NOT NULL); ...@@ -92,14 +135,14 @@ CREATE TABLE test (family_name VARCHAR_IGNORECASE(63) NOT NULL);
INSERT INTO test VALUES('Smith'), ('de Smith'), ('el Smith'), ('von Smith'); INSERT INTO test VALUES('Smith'), ('de Smith'), ('el Smith'), ('von Smith');
> update count: 4 > update count: 4
SELECT * FROM test WHERE family_name IN ('de Smith', 'Smith'); SELECT * FROM test WHERE family_name IN ('de Smith', 'Smith');
> FAMILY_NAME > FAMILY_NAME
> ----------- > -----------
> Smith > Smith
> de Smith > de Smith
> rows: 2 > rows: 2
SELECT * FROM test WHERE family_name BETWEEN 'D' AND 'T'; SELECT * FROM test WHERE family_name BETWEEN 'D' AND 'T';
> FAMILY_NAME > FAMILY_NAME
> ----------- > -----------
> Smith > Smith
...@@ -110,7 +153,7 @@ SELECT * FROM test WHERE family_name BETWEEN 'D' AND 'T'; ...@@ -110,7 +153,7 @@ SELECT * FROM test WHERE family_name BETWEEN 'D' AND 'T';
CREATE INDEX family_name ON test(family_name); CREATE INDEX family_name ON test(family_name);
> ok > ok
SELECT * FROM test WHERE family_name IN ('de Smith', 'Smith'); SELECT * FROM test WHERE family_name IN ('de Smith', 'Smith');
> FAMILY_NAME > FAMILY_NAME
> ----------- > -----------
> Smith > Smith
...@@ -7430,9 +7473,9 @@ select ifnull(null, '1') x1, ifnull(null, null) xn, ifnull('a', 'b') xa from tes ...@@ -7430,9 +7473,9 @@ select ifnull(null, '1') x1, ifnull(null, null) xn, ifnull('a', 'b') xa from tes
> rows: 1 > rows: 1
select casewhen(null, '1', '2') xn, casewhen(1>0, 'n', 'y') xy, casewhen(0<1, 'a', 'b') xa from test; select casewhen(null, '1', '2') xn, casewhen(1>0, 'n', 'y') xy, casewhen(0<1, 'a', 'b') xa from test;
> XN XY XA > XN XY XA
> ---- -- -- > -- -- --
> null n a > 2 n a
> rows: 1 > rows: 1
select x, case when x=0 then 'zero' else 'not zero' end y from system_range(0, 2); select x, case when x=0 then 'zero' else 'not zero' end y from system_range(0, 2);
......
create table test(id int primary key check id>1);
drop table test;
create table table1(f1 int not null primary key);
create table table2(f2 int not null references table1(f1) on delete cascade);
drop table table2;
drop table table1;
create table table1(f1 int not null primary key);
create table table2(f2 int not null primary key references table1(f1));
drop table table1;
drop table table2;
select case when 1=null then 1 else 2 end;
> 2;
select case (1) when 1 then 1 else 2 end; select case (1) when 1 then 1 else 2 end;
> 1; > 1;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论