Skip to content

Commit

Permalink
added to migrate new h2 jar data
Browse files Browse the repository at this point in the history
  • Loading branch information
kompiro committed Dec 26, 2010
1 parent c509dfb commit 66d8e8e
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 11 deletions.
Expand Up @@ -2,11 +2,14 @@

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.io.File;
import java.sql.Driver;
import java.sql.SQLException;
import java.util.UUID;
Expand All @@ -16,9 +19,7 @@
import org.eclipse.core.runtime.NullProgressMonitor;
import org.junit.*;
import org.junit.rules.TemporaryFolder;
import org.kompiro.jamcircle.storage.exception.DBMigrationNeededException;
import org.kompiro.jamcircle.storage.service.StorageService;
import org.kompiro.jamcircle.storage.service.StorageSetting;
import org.kompiro.jamcircle.storage.service.*;

/**
* @TestContext StorageServiceImpl
Expand Down Expand Up @@ -64,8 +65,12 @@ public void pickup() throws Exception {
verify(entity, times(1)).setTrashed(false);
}

@Test(expected = DBMigrationNeededException.class)
public void migrate_needed() throws Exception {
DatabaseMigrator migrator = mock(DatabaseMigrator.class);
service.setDatabaseMigrator(migrator);
StorageSettings settings = mock(StorageSettings.class);
service.setSettings(settings);

service = new StorageServiceImpl() {
@Override
protected DatabaseProvider createDatabaseProvider(String uri, String username, String password) {
Expand All @@ -91,6 +96,8 @@ public Class<? extends Driver> getDriverClass() throws ClassNotFoundException {
StorageSetting setting = new StorageSetting(0, folder.getRoot().getAbsolutePath(),
StorageService.ConnectionMode.MEM.toString(), "sa", "");
service.loadStorage(setting, new NullProgressMonitor());
verify(migrator).execute((File) anyObject(), (File) anyObject(), eq(true), eq("sa"), eq(""), eq(true));
verify(settings).storeSttings();
}

@Test
Expand Down
@@ -0,0 +1,127 @@
package org.kompiro.jamcircle.storage.service.internal;

import java.io.*;

import org.h2.tools.RunScript;

public class DatabaseMigrator {

private static final String TEMP_SCRIPT = "backup.sql";
private PrintStream sysOut = System.out;
private boolean quiet;

public DatabaseMigrator() {
}

/**
* Migrate a database.
*
* @param oldH2Jar
* the old JAR file
* @param file
* the database file (must end with .data.db) or directory
* @param recursive
* if the file parameter is in fact a directory (in which
* case the directory is scanned recursively)
* @param user
* the user name of the database
* @param password
* the password
* @param runQuiet
* to run in quiet mode
* @throws Exception
* if conversion fails
*/
public void execute(File oldH2Jar, File file, boolean recursive, String user, String password, boolean runQuiet)
throws Exception {
String pathToJavaExe = getJavaExecutablePath();
this.quiet = runQuiet;
if (file.isDirectory() && recursive) {
for (File f : file.listFiles()) {
execute(oldH2Jar, f, recursive, user, password, runQuiet);
}
return;
}
if (!file.getName().endsWith(".data.db")) {
return;
}
println("Migrating " + file.getName());
String url = "jdbc:h2:" + file.getAbsolutePath();
url = url.substring(0, url.length() - ".data.db".length());
exec(new String[] {
pathToJavaExe,
"-Xmx128m",
"-cp", oldH2Jar.getAbsolutePath(),
"org.h2.tools.Script",
"-script", TEMP_SCRIPT,
"-url", url,
"-user", user,
"-password", password });
file.renameTo(new File(file.getAbsoluteFile() + ".backup"));
RunScript.execute(url, user, password, TEMP_SCRIPT, "UTF-8", true);
new File(TEMP_SCRIPT).delete();
}

private String getJavaExecutablePath() {
String pathToJava;
if (File.separator.equals("\\")) {
pathToJava = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java.exe";
} else {
pathToJava = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
}
if (!new File(pathToJava).exists()) {
// Fallback to old behaviour
pathToJava = "java";
}
return pathToJava;
}

private void println(String s) {
if (!quiet) {
sysOut.println(s);
}
}

private void print(String s) {
if (!quiet) {
sysOut.print(s);
}
}

private int exec(String[] command) {
try {
for (String c : command) {
print(c + " ");
}
println("");
Process p = Runtime.getRuntime().exec(command);
copyInThread(p.getInputStream(), quiet ? null : sysOut);
copyInThread(p.getErrorStream(), quiet ? null : sysOut);
p.waitFor();
return p.exitValue();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private void copyInThread(final InputStream in, final OutputStream out) {
new Thread() {
public void run() {
try {
while (true) {
int x = in.read();
if (x < 0) {
return;
}
if (out != null) {
out.write(x);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}.start();
}

}
Expand Up @@ -4,10 +4,10 @@

public class StorageAccessRule implements ISchedulingRule {
public boolean isConflicting(ISchedulingRule rule) {
return rule.getClass().equals(StorageAccessRule.class);
return rule == this;
}

public boolean contains(ISchedulingRule rule) {
return rule.getClass().equals(StorageAccessRule.class);
return rule == this;
}
}
Expand Up @@ -2,8 +2,7 @@

import static java.lang.String.format;

import java.io.File;
import java.io.FileReader;
import java.io.*;
import java.lang.reflect.Array;
import java.sql.*;
import java.util.*;
Expand All @@ -14,10 +13,10 @@
import org.eclipse.core.runtime.jobs.Job;
import org.h2.tools.Csv;
import org.kompiro.jamcircle.storage.*;
import org.kompiro.jamcircle.storage.exception.DBMigrationNeededException;
import org.kompiro.jamcircle.storage.exception.StorageConnectException;
import org.kompiro.jamcircle.storage.model.GraphicalEntity;
import org.kompiro.jamcircle.storage.service.*;
import org.osgi.framework.Bundle;

/**
* This service provides storage service.
Expand Down Expand Up @@ -81,6 +80,7 @@ public int compare(StorageChageListener o1, StorageChageListener o2) {
private EntityManager manager;
private FileStorageService fileService;
private StorageCallbackHandlerLoader loader = new StorageCallbackHandlerLoader();
private DatabaseMigrator migrator = new DatabaseMigrator();

public void activate() {
loadStorageSetting();
Expand Down Expand Up @@ -164,16 +164,48 @@ protected void createEntityManager(String uri, String username, String password)
provider.getConnection();
} catch (SQLException e) {
if (org.h2.constant.ErrorCode.FILE_VERSION_ERROR_1 == e.getErrorCode()) {
throw new DBMigrationNeededException(e);
databaseMigration(username, password);
} else {
throw new StorageConnectException(e);
}
throw new StorageConnectException(e);
}
if (StorageStatusHandler.isDebug()) {
StorageStatusHandler.info(format("path:%s", uri), true); //$NON-NLS-1$
}
manager = new EntityManager(provider);
}

private void databaseMigration(String username, String password) throws StorageConnectException {
File oldH2Jar = getOldH2Jar();
try {
migrator.execute(oldH2Jar, new File(fileService.getStoreRoot()), true, username, password, false);
} catch (Exception ex) {
throw new StorageConnectException(ex);
}
}

private File getOldH2Jar() throws StorageConnectException {
File bundleFile = getBundleFile();
if (bundleFile == null)
return null;
File oldH2Jar = new File(bundleFile, "lib/h2.jar"); //$NON-NLS-1$
return oldH2Jar;
}

private File getBundleFile() throws StorageConnectException {
StorageActivator activator = StorageActivator.getDefault();
if (activator == null)
return null;
Bundle bundle = activator.getBundle();
File bundleFile;
try {
bundleFile = FileLocator.getBundleFile(bundle);
} catch (IOException ex) {
throw new StorageConnectException(ex);
}
return bundleFile;
}

protected DatabaseProvider createDatabaseProvider(String uri, String username, String password) {
return new H2DatabaseProvider(uri, username, password);
}
Expand Down Expand Up @@ -439,4 +471,8 @@ public void setFileService(FileStorageService fileService) {
this.fileService = fileService;
}

public void setDatabaseMigrator(DatabaseMigrator migrator) {
this.migrator = migrator;
}

}

0 comments on commit 66d8e8e

Please sign in to comment.