提交 d2787fcf authored 作者: Thomas Mueller's avatar Thomas Mueller

A file system implementation can now be registered. The database file system…

A file system implementation can now be registered. The database file system moved to the test section.
上级 ca083f04
...@@ -18,7 +18,8 @@ Change Log ...@@ -18,7 +18,8 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>- <ul><li>A file system implementation can now be registered using FileSystem.register.
The database file system is no longer included in the jar file, it moved to the test section.
</li></ul> </li></ul>
<h2>Version 1.1.111 (2009-04-10)</h2> <h2>Version 1.1.111 (2009-04-10)</h2>
......
...@@ -17,7 +17,12 @@ public class FileObjectInputStream extends InputStream { ...@@ -17,7 +17,12 @@ public class FileObjectInputStream extends InputStream {
private FileObject file; private FileObject file;
private byte[] buffer = new byte[1]; private byte[] buffer = new byte[1];
FileObjectInputStream(FileObject file) { /**
* Create a new file object input stream from the file object.
*
* @param file the file object
*/
public FileObjectInputStream(FileObject file) {
this.file = file; this.file = file;
} }
......
...@@ -17,7 +17,13 @@ public class FileObjectOutputStream extends OutputStream { ...@@ -17,7 +17,13 @@ public class FileObjectOutputStream extends OutputStream {
private FileObject file; private FileObject file;
private byte[] buffer = new byte[1]; private byte[] buffer = new byte[1];
FileObjectOutputStream(FileObject file, boolean append) throws IOException { /**
* Create a new file object output stream from the file object.
*
* @param file the file object
* @param append true for append mode, false for truncate and overwrite
*/
public FileObjectOutputStream(FileObject file, boolean append) throws IOException {
this.file = file; this.file = file;
if (append) { if (append) {
file.seek(file.length()); file.seek(file.length());
......
...@@ -10,6 +10,7 @@ import java.io.IOException; ...@@ -10,6 +10,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
/** /**
* The file system is a storage abstraction. * The file system is a storage abstraction.
...@@ -26,11 +27,6 @@ public abstract class FileSystem { ...@@ -26,11 +27,6 @@ public abstract class FileSystem {
*/ */
public static final String PREFIX_MEMORY_LZF = "memLZF:"; public static final String PREFIX_MEMORY_LZF = "memLZF:";
/**
* The prefix used for a database based file system.
*/
public static final String PREFIX_DB = "jdbc:";
/** /**
* The prefix used for a read-only zip-file based file system. * The prefix used for a read-only zip-file based file system.
*/ */
...@@ -52,6 +48,8 @@ public abstract class FileSystem { ...@@ -52,6 +48,8 @@ public abstract class FileSystem {
*/ */
public static final String PREFIX_NIO_MAPPED = "nioMapped:"; public static final String PREFIX_NIO_MAPPED = "nioMapped:";
public static final ArrayList SERVICES = new ArrayList();
/** /**
* Get the file system object. * Get the file system object.
* *
...@@ -61,8 +59,6 @@ public abstract class FileSystem { ...@@ -61,8 +59,6 @@ public abstract class FileSystem {
public static FileSystem getInstance(String fileName) { public static FileSystem getInstance(String fileName) {
if (isInMemory(fileName)) { if (isInMemory(fileName)) {
return FileSystemMemory.getInstance(); return FileSystemMemory.getInstance();
} else if (fileName.startsWith(PREFIX_DB)) {
return FileSystemDatabase.getInstance(fileName);
} else if (fileName.startsWith(PREFIX_ZIP)) { } else if (fileName.startsWith(PREFIX_ZIP)) {
return FileSystemZip.getInstance(); return FileSystemZip.getInstance();
} else if (fileName.startsWith(PREFIX_SPLIT)) { } else if (fileName.startsWith(PREFIX_SPLIT)) {
...@@ -72,9 +68,43 @@ public abstract class FileSystem { ...@@ -72,9 +68,43 @@ public abstract class FileSystem {
} else if (fileName.startsWith(PREFIX_NIO_MAPPED)) { } else if (fileName.startsWith(PREFIX_NIO_MAPPED)) {
return FileSystemDiskNioMapped.getInstance(); return FileSystemDiskNioMapped.getInstance();
} }
for (int i = 0; i < SERVICES.size(); i++) {
FileSystem fs = (FileSystem) SERVICES.get(i);
if (fs.accepts(fileName)) {
return fs;
}
}
return FileSystemDisk.getInstance(); return FileSystemDisk.getInstance();
} }
/**
* Register a file system.
*
* @param service the file system
*/
public static synchronized void register(FileSystem service) {
SERVICES.add(service);
}
/**
* Unregister a file system.
*
* @param service the file system
*/
public static synchronized void unregister(FileSystem service) {
SERVICES.remove(service);
}
/**
* Check if the file system is responsible for this file name.
*
* @param fileName the file name
* @return true if it is
*/
protected boolean accepts(String fileName) {
return false;
}
private static boolean isInMemory(String fileName) { private static boolean isInMemory(String fileName) {
return fileName != null && (fileName.startsWith(PREFIX_MEMORY) || fileName.startsWith(PREFIX_MEMORY_LZF)); return fileName != null && (fileName.startsWith(PREFIX_MEMORY) || fileName.startsWith(PREFIX_MEMORY_LZF));
} }
...@@ -287,13 +317,4 @@ public abstract class FileSystem { ...@@ -287,13 +317,4 @@ public abstract class FileSystem {
*/ */
public abstract InputStream openFileInputStream(String fileName) throws IOException; public abstract InputStream openFileInputStream(String fileName) throws IOException;
/**
* Close the file system. This call normally does not have an effect, except
* if the file system is kept in a database, in which case the connection is
* closed.
*/
public void close() {
// do nothing
}
} }
...@@ -4,11 +4,12 @@ ...@@ -4,11 +4,12 @@
* (http://h2database.com/html/license.html). * (http://h2database.com/html/license.html).
* Initial Developer: H2 Group * Initial Developer: H2 Group
*/ */
package org.h2.store.fs; package org.h2.test.unit;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import org.h2.store.fs.FileObject;
import org.h2.util.ByteUtils; import org.h2.util.ByteUtils;
/** /**
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* (http://h2database.com/html/license.html). * (http://h2database.com/html/license.html).
* Initial Developer: H2 Group * Initial Developer: H2 Group
*/ */
package org.h2.store.fs; package org.h2.test.unit;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
...@@ -22,6 +22,10 @@ import java.util.Properties; ...@@ -22,6 +22,10 @@ import java.util.Properties;
import org.h2.Driver; import org.h2.Driver;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.store.fs.FileObject;
import org.h2.store.fs.FileObjectInputStream;
import org.h2.store.fs.FileObjectOutputStream;
import org.h2.store.fs.FileSystem;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils; import org.h2.util.JdbcUtils;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
...@@ -31,7 +35,6 @@ import org.h2.util.StringUtils; ...@@ -31,7 +35,6 @@ import org.h2.util.StringUtils;
*/ */
public class FileSystemDatabase extends FileSystem { public class FileSystemDatabase extends FileSystem {
private static final HashMap INSTANCES = new HashMap();
private Connection conn; private Connection conn;
private String url; private String url;
private HashMap preparedMap = new HashMap(); private HashMap preparedMap = new HashMap();
...@@ -69,17 +72,12 @@ public class FileSystemDatabase extends FileSystem { ...@@ -69,17 +72,12 @@ public class FileSystemDatabase extends FileSystem {
} }
} }
public static synchronized FileSystem getInstance(String url) { protected boolean accepts(String fileName) {
int idx = url.indexOf('/'); return fileName.startsWith(url);
if (idx > 0) {
url = url.substring(0, idx);
}
FileSystemDatabase fs = (FileSystemDatabase) INSTANCES.get(url);
if (fs != null) {
return fs;
} }
public static synchronized FileSystemDatabase register(String url) throws SQLException {
Connection conn; Connection conn;
try {
if (url.startsWith("jdbc:h2:")) { if (url.startsWith("jdbc:h2:")) {
// avoid using DriverManager if possible // avoid using DriverManager if possible
conn = Driver.load().connect(url, new Properties()); conn = Driver.load().connect(url, new Properties());
...@@ -87,20 +85,17 @@ public class FileSystemDatabase extends FileSystem { ...@@ -87,20 +85,17 @@ public class FileSystemDatabase extends FileSystem {
conn = JdbcUtils.getConnection(null, url, new Properties()); conn = JdbcUtils.getConnection(null, url, new Properties());
} }
boolean log = url.toUpperCase().indexOf("TRACE_") >= 0; boolean log = url.toUpperCase().indexOf("TRACE_") >= 0;
fs = new FileSystemDatabase(url, conn, log); FileSystemDatabase fs = new FileSystemDatabase(url, conn, log);
INSTANCES.put(url, fs); FileSystem.register(fs);
return fs; return fs;
} catch (SQLException e) {
throw Message.convertToInternal(e);
}
} }
/** /**
* Close the underlying database. * Close the underlying database and unregister the file system.
*/ */
public void close() { public void unregister() {
JdbcUtils.closeSilently(conn); JdbcUtils.closeSilently(conn);
INSTANCES.remove(url); FileSystem.unregister(this);
} }
private void commit() { private void commit() {
......
...@@ -44,10 +44,12 @@ public class TestFileSystem extends TestBase { ...@@ -44,10 +44,12 @@ public class TestFileSystem extends TestBase {
testFileSystem(FileSystem.PREFIX_SPLIT + baseDir + "/fs"); testFileSystem(FileSystem.PREFIX_SPLIT + baseDir + "/fs");
testFileSystem(baseDir + "/fs"); testFileSystem(baseDir + "/fs");
testFileSystem(FileSystem.PREFIX_MEMORY); testFileSystem(FileSystem.PREFIX_MEMORY);
FileSystemDatabase fs = FileSystemDatabase.register("jdbc:h2:mem:fs");
// testFileSystem("jdbc:h2:mem:fs;TRACE_LEVEL_FILE=3"); // testFileSystem("jdbc:h2:mem:fs;TRACE_LEVEL_FILE=3");
testFileSystem("jdbc:h2:mem:fs"); testFileSystem("jdbc:h2:mem:fs");
testFileSystem(FileSystem.PREFIX_MEMORY_LZF); testFileSystem(FileSystem.PREFIX_MEMORY_LZF);
testUserHome(); testUserHome();
fs.unregister();
} }
private void testDatabaseInMemFileSys() throws SQLException { private void testDatabaseInMemFileSys() throws SQLException {
...@@ -179,12 +181,11 @@ public class TestFileSystem extends TestBase { ...@@ -179,12 +181,11 @@ public class TestFileSystem extends TestBase {
if (!fsBase.startsWith(FileSystem.PREFIX_MEMORY) && !fsBase.startsWith(FileSystem.PREFIX_MEMORY_LZF)) { if (!fsBase.startsWith(FileSystem.PREFIX_MEMORY) && !fsBase.startsWith(FileSystem.PREFIX_MEMORY_LZF)) {
fs.createDirs(fsBase + "/testDir/test"); fs.createDirs(fsBase + "/testDir/test");
assertTrue(fs.isDirectory(fsBase + "/testDir")); assertTrue(fs.isDirectory(fsBase + "/testDir"));
if (!fsBase.startsWith(FileSystem.PREFIX_DB)) { if (!fsBase.startsWith("jdbc:")) {
fs.deleteRecursive(fsBase + "/testDir"); fs.deleteRecursive(fsBase + "/testDir");
assertTrue(!fs.exists(fsBase + "/testDir")); assertTrue(!fs.exists(fsBase + "/testDir"));
} }
} }
fs.close();
} }
private void testRandomAccess(String fsBase) throws Exception { private void testRandomAccess(String fsBase) throws Exception {
...@@ -267,7 +268,6 @@ public class TestFileSystem extends TestBase { ...@@ -267,7 +268,6 @@ public class TestFileSystem extends TestBase {
} }
f.close(); f.close();
ra.close(); ra.close();
fs.close();
} }
private void testTempFile(String fsBase) throws Exception { private void testTempFile(String fsBase) throws Exception {
...@@ -288,7 +288,6 @@ public class TestFileSystem extends TestBase { ...@@ -288,7 +288,6 @@ public class TestFileSystem extends TestBase {
assertEquals(in.read(), -1); assertEquals(in.read(), -1);
in.close(); in.close();
out.close(); out.close();
fs.close();
} }
......
...@@ -585,4 +585,4 @@ versus extracts squirrel misdirected rle looking arc addressed european ...@@ -585,4 +585,4 @@ versus extracts squirrel misdirected rle looking arc addressed european
soerensen favicon glass restarts flexive fish resulted vpda mvc kotek jan soerensen favicon glass restarts flexive fish resulted vpda mvc kotek jan
consistently springfuse grep signatures wrote symbolic parents caches readers consistently springfuse grep signatures wrote symbolic parents caches readers
animate scaladoc models disadvantages vladykin sergi trims requesting animate scaladoc models disadvantages vladykin sergi trims requesting
handing bonita placed euros embeds reliability singular handing bonita placed euros embeds reliability singular unregister
\ No newline at end of file \ No newline at end of file
...@@ -377,7 +377,6 @@ public class FtpServer extends Tool implements Service { ...@@ -377,7 +377,6 @@ public class FtpServer extends Tool implements Service {
traceError(e); traceError(e);
} }
serverSocket = null; serverSocket = null;
fs.close();
} }
public boolean isRunning(boolean traceError) { public boolean isRunning(boolean traceError) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论