@Override
  public void test() throws Exception {
    if (!SysProperties.MODIFY_ON_WRITE) {
      return;
    }
    deleteDb("modifyOnWrite");
    String dbFile = getBaseDir() + "/modifyOnWrite.h2.db";
    assertFalse(FileUtils.exists(dbFile));
    Connection conn = getConnection("modifyOnWrite");
    Statement stat = conn.createStatement();
    stat.execute("create table test(id int)");
    conn.close();
    byte[] test = IOUtils.readBytesAndClose(FileUtils.newInputStream(dbFile), -1);

    conn = getConnection("modifyOnWrite");
    stat = conn.createStatement();
    ResultSet rs;
    rs = stat.executeQuery("select * from test");
    assertFalse(rs.next());
    conn.close();
    assertTrue(FileUtils.exists(dbFile));
    byte[] test2 = IOUtils.readBytesAndClose(FileUtils.newInputStream(dbFile), -1);
    assertEquals(test, test2);

    conn = getConnection("modifyOnWrite");
    stat = conn.createStatement();
    stat.execute("insert into test values(1)");
    conn.close();

    conn = getConnection("modifyOnWrite");
    stat = conn.createStatement();
    rs = stat.executeQuery("select * from test");
    assertTrue(rs.next());
    conn.close();

    test2 = IOUtils.readBytesAndClose(FileUtils.newInputStream(dbFile), -1);
    assertFalse(Utils.compareSecure(test, test2));
  }
 private boolean openWriter() {
   if (printWriter == null) {
     try {
       FileUtils.createDirectories(FileUtils.getParent(fileName));
       if (FileUtils.exists(fileName) && !FileUtils.canWrite(fileName)) {
         // read only database: don't log error if the trace file
         // can't be opened
         return false;
       }
       fileWriter = IOUtils.getBufferedWriter(FileUtils.newOutputStream(fileName, true));
       printWriter = new PrintWriter(fileWriter, true);
     } catch (Exception e) {
       logWritingError(e);
       return false;
     }
   }
   return true;
 }
 @Override
 public FileStore openFile(String name, String mode, boolean mustExist) {
   if (mustExist && !FileUtils.exists(name)) {
     throw DbException.get(ErrorCode.FILE_NOT_FOUND_1, name);
   }
   FileStore store;
   if (cipher == null) {
     store = FileStore.open(this, name, mode);
   } else {
     store = FileStore.open(this, name, mode, cipher, fileEncryptionKey, 0);
   }
   store.setCheckedWriting(false);
   try {
     store.init();
   } catch (DbException e) {
     store.closeSilently();
     throw e;
   }
   return store;
 }
 /**
  * Get the unique and normalized database name (excluding settings).
  *
  * @return the database name
  */
 public String getName() {
   if (!persistent) {
     return name;
   }
   if (nameNormalized == null) {
     if (!SysProperties.IMPLICIT_RELATIVE_PATH) {
       if (!FileUtils.isAbsolute(name)) {
         if (name.indexOf("./") < 0
             && name.indexOf(".\\") < 0
             && name.indexOf(":/") < 0
             && name.indexOf(":\\") < 0) {
           // the name could start with "./", or
           // it could start with a prefix such as "nio:./"
           // for Windows, the path "\test" is not considered
           // absolute as the drive letter is missing,
           // but we consider it absolute
           throw DbException.get(ErrorCode.URL_RELATIVE_TO_CWD, originalURL);
         }
       }
     }
     String suffix = Constants.SUFFIX_PAGE_FILE;
     String n;
     if (FileUtils.exists(name + suffix)) {
       n = FileUtils.toRealPath(name + suffix);
     } else {
       suffix = Constants.SUFFIX_MV_FILE;
       n = FileUtils.toRealPath(name + suffix);
     }
     String fileName = FileUtils.getName(n);
     if (fileName.length() < suffix.length() + 1) { // 例如: 没有设置baseDir且dbName="./"时
       throw DbException.get(ErrorCode.INVALID_DATABASE_NAME_1, name);
     }
     nameNormalized = n.substring(0, n.length() - suffix.length());
   }
   return nameNormalized;
 }
 /**
  * Restores database files.
  *
  * @param zipFileName the name of the backup file
  * @param directory the directory name
  * @param db the database name (null for all databases)
  * @throws DbException if there is an IOException
  */
 public static void execute(String zipFileName, String directory, String db) {
   InputStream in = null;
   try {
     if (!FileUtils.exists(zipFileName)) {
       throw new IOException("File not found: " + zipFileName);
     }
     String originalDbName = null;
     int originalDbLen = 0;
     if (db != null) {
       originalDbName = getOriginalDbName(zipFileName, db);
       if (originalDbName == null) {
         throw new IOException("No database named " + db + " found");
       }
       if (originalDbName.startsWith(SysProperties.FILE_SEPARATOR)) {
         originalDbName = originalDbName.substring(1);
       }
       originalDbLen = originalDbName.length();
     }
     in = FileUtils.newInputStream(zipFileName);
     ZipInputStream zipIn = new ZipInputStream(in);
     while (true) {
       ZipEntry entry = zipIn.getNextEntry();
       if (entry == null) {
         break;
       }
       String fileName = entry.getName();
       // restoring windows backups on linux and vice versa
       fileName = fileName.replace('\\', SysProperties.FILE_SEPARATOR.charAt(0));
       fileName = fileName.replace('/', SysProperties.FILE_SEPARATOR.charAt(0));
       if (fileName.startsWith(SysProperties.FILE_SEPARATOR)) {
         fileName = fileName.substring(1);
       }
       boolean copy = false;
       if (db == null) {
         copy = true;
       } else if (fileName.startsWith(originalDbName + ".")) {
         fileName = db + fileName.substring(originalDbLen);
         copy = true;
       }
       if (copy) {
         OutputStream o = null;
         try {
           o =
               FileUtils.newOutputStream(
                   directory + SysProperties.FILE_SEPARATOR + fileName, false);
           IOUtils.copy(zipIn, o);
           o.close();
         } finally {
           IOUtils.closeSilently(o);
         }
       }
       zipIn.closeEntry();
     }
     zipIn.closeEntry();
     zipIn.close();
   } catch (IOException e) {
     throw DbException.convertIOException(e, zipFileName);
   } finally {
     IOUtils.closeSilently(in);
   }
 }
Exemple #6
0
 private void testTools() throws Exception {
   if (config.memory) {
     return;
   }
   deleteDb("web");
   Connection conn = getConnection("web");
   conn.createStatement().execute("create table test(id int) as select 1");
   conn.close();
   Server server = new Server();
   server.setOut(new PrintStream(new ByteArrayOutputStream()));
   server.runTool("-web", "-webPort", "8182", "-properties", "null", "-tcp", "-tcpPort", "9101");
   try {
     String url = "http://localhost:8182";
     WebClient client;
     String result;
     client = new WebClient();
     result = client.get(url);
     client.readSessionId(result);
     result = client.get(url, "tools.jsp");
     FileUtils.delete(getBaseDir() + "/backup.zip");
     result =
         client.get(
             url,
             "tools.do?tool=Backup&args=-dir,"
                 + getBaseDir()
                 + ",-db,web,-file,"
                 + getBaseDir()
                 + "/backup.zip");
     deleteDb("web");
     assertTrue(FileUtils.exists(getBaseDir() + "/backup.zip"));
     result =
         client.get(url, "tools.do?tool=DeleteDbFiles&args=-dir," + getBaseDir() + ",-db,web");
     assertFalse(FileUtils.exists(getBaseDir() + "/web.h2.db"));
     result =
         client.get(
             url,
             "tools.do?tool=Restore&args=-dir,"
                 + getBaseDir()
                 + ",-db,web,-file,"
                 + getBaseDir()
                 + "/backup.zip");
     assertTrue(FileUtils.exists(getBaseDir() + "/web.h2.db"));
     FileUtils.delete(getBaseDir() + "/web.h2.sql");
     FileUtils.delete(getBaseDir() + "/backup.zip");
     result = client.get(url, "tools.do?tool=Recover&args=-dir," + getBaseDir() + ",-db,web");
     assertTrue(FileUtils.exists(getBaseDir() + "/web.h2.sql"));
     FileUtils.delete(getBaseDir() + "/web.h2.sql");
     result =
         client.get(
             url,
             "tools.do?tool=RunScript&args=-script,"
                 + getBaseDir()
                 + "/web.h2.sql,-url,"
                 + getURL("web", true)
                 + ",-user,"
                 + getUser()
                 + ",-password,"
                 + getPassword());
     FileUtils.delete(getBaseDir() + "/web.h2.sql");
     assertTrue(FileUtils.exists(getBaseDir() + "/web.h2.db"));
     deleteDb("web");
   } finally {
     server.shutdown();
   }
 }
  private void testStopWhileCommitting() throws Exception {
    String fileName = getBaseDir() + "/testStopWhileCommitting.h3";
    FileUtils.delete(fileName);
    Random r = new Random(0);

    for (int i = 0; i < 10; ) {
      MVStore s;
      TransactionStore ts;
      Transaction tx;
      TransactionMap<Integer, String> m;

      s = MVStore.open(fileName);
      ts = new TransactionStore(s);
      tx = ts.begin();
      s.setReuseSpace(false);
      m = tx.openMap("test");
      final String value = "x" + i;
      for (int j = 0; j < 1000; j++) {
        m.put(j, value);
      }
      final AtomicInteger state = new AtomicInteger();
      final MVStore store = s;
      final MVMap<Integer, String> other = s.openMap("other");
      Task task =
          new Task() {

            @Override
            public void call() throws Exception {
              for (int i = 0; !stop; i++) {
                state.set(i);
                other.put(i, value);
                store.commit();
              }
            }
          };
      task.execute();
      // wait for the task to start
      while (state.get() < 1) {
        Thread.yield();
      }
      // commit while writing in the task
      tx.commit();
      // wait for the task to stop
      task.get();
      store.close();
      s = MVStore.open(fileName);
      // roll back a bit, until we have some undo log entries
      assertTrue(s.hasMap("undoLog"));
      for (int back = 0; back < 100; back++) {
        int minus = r.nextInt(10);
        s.rollbackTo(Math.max(0, s.getCurrentVersion() - minus));
        MVMap<?, ?> undo = s.openMap("undoLog");
        if (undo.size() > 0) {
          break;
        }
      }
      ts = new TransactionStore(s);
      List<Transaction> list = ts.getOpenTransactions();
      if (list.size() != 0) {
        tx = list.get(0);
        if (tx.getStatus() == Transaction.STATUS_COMMITTING) {
          i++;
        }
      }
      s.close();
      FileUtils.delete(fileName);
      assertFalse(FileUtils.exists(fileName));
    }
  }