001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (license2)
004: * Initial Developer: H2 Group
005: */
006: package org.h2.test.db;
007:
008: import java.io.File;
009: import java.io.RandomAccessFile;
010: import java.sql.Connection;
011: import java.sql.SQLException;
012: import java.sql.Statement;
013: import java.util.ArrayList;
014:
015: import org.h2.engine.Constants;
016: import org.h2.store.FileLister;
017: import org.h2.test.TestBase;
018:
019: /**
020: * Test for the read-only database feature.
021: */
022: public class TestReadOnly extends TestBase {
023:
024: public void test() throws Exception {
025: if (config.memory) {
026: return;
027: }
028: testReadOnlyFiles(true);
029: if (!config.deleteIndex) {
030: testReadOnlyFiles(false);
031: }
032: }
033:
034: private void testReadOnlyFiles(boolean setReadOnly)
035: throws Exception {
036:
037: File f = File.createTempFile("test", "temp");
038: check(f.canWrite());
039: f.setReadOnly();
040: check(!f.canWrite());
041: f.delete();
042:
043: f = File.createTempFile("test", "temp");
044: RandomAccessFile r = new RandomAccessFile(f, "rw");
045: r.write(1);
046: f.setReadOnly();
047: r.close();
048: check(!f.canWrite());
049: f.delete();
050:
051: deleteDb("readonly");
052: Connection conn = getConnection("readonly");
053: Statement stat = conn.createStatement();
054: stat
055: .execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
056: stat.execute("INSERT INTO TEST VALUES(1, 'Hello')");
057: stat.execute("INSERT INTO TEST VALUES(2, 'World')");
058: check(!conn.isReadOnly());
059: conn.close();
060:
061: if (setReadOnly) {
062: setReadOnly();
063: conn = getConnection("readonly");
064: } else {
065: conn = getConnection("readonly;ACCESS_MODE_DATA=r");
066: }
067: check(conn.isReadOnly());
068: stat = conn.createStatement();
069: stat.execute("SELECT * FROM TEST");
070: try {
071: stat.execute("DELETE FROM TEST");
072: error("read only delete");
073: } catch (SQLException e) {
074: checkNotGeneralException(e);
075: }
076: conn.close();
077:
078: if (setReadOnly) {
079: conn = getConnection("readonly;DB_CLOSE_DELAY=1");
080: } else {
081: conn = getConnection("readonly;DB_CLOSE_DELAY=1;ACCESS_MODE_DATA=r");
082: }
083: stat = conn.createStatement();
084: stat.execute("SELECT * FROM TEST");
085: try {
086: stat.execute("DELETE FROM TEST");
087: error("read only delete");
088: } catch (SQLException e) {
089: checkNotGeneralException(e);
090: }
091: stat.execute("SET DB_CLOSE_DELAY=0");
092: conn.close();
093: }
094:
095: private void setReadOnly() throws SQLException {
096: String lastLogFile = null;
097: ArrayList list = FileLister.getDatabaseFiles(TestBase.baseDir,
098: "readonly", true);
099: for (int i = 0; i < list.size(); i++) {
100: String fileName = (String) list.get(i);
101: File file = new File(fileName);
102: file.setReadOnly();
103: if (fileName.endsWith(Constants.SUFFIX_LOG_FILE)) {
104: if (lastLogFile == null
105: || lastLogFile.compareTo(fileName) < 0) {
106: lastLogFile = fileName;
107: }
108: }
109: }
110: // delete all log files except the last one
111: for (int i = 0; i < list.size(); i++) {
112: String fileName = (String) list.get(i);
113: if (fileName.endsWith(Constants.SUFFIX_LOG_FILE)) {
114: if (!lastLogFile.equals(fileName)) {
115: File file = new File(fileName);
116: file.delete();
117: }
118: }
119: }
120: }
121:
122: }
|