package marubinotto.piggydb.impl;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import marubinotto.piggydb.model.FileRepository;
import marubinotto.util.Assert;
import marubinotto.util.RdbUtils;
import marubinotto.util.ZipUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
import org.dbunit.DatabaseUnitException;
import org.dbunit.dataset.DataSetException;
public class PigDump {
private static Log logger = LogFactory.getLog(PigDump.class);
public static final String PATH_RDB_DUMP = "rdb-dump.xml";
public static final String PATH_FILES = "files/";
public static final String FILE_NAME_ENCODING = "UTF-8";
public static final String[] TABLES = new String[]{
"global_setting", "tag", "tagging", "fragment", "filter", "fragment_relation"
};
private DataSource dataSource;
private FileRepository fileRepository;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setFileRepository(FileRepository fileRepository) {
this.fileRepository = fileRepository;
}
private Connection getJdbcConnection() {
return RdbUtils.getSpringTransactionalConnection(this.dataSource);
}
public void outputDump(OutputStream output) throws Exception {
Assert.Arg.notNull(output, "output");
Assert.Property.requireNotNull(fileRepository, "fileRepository");
ZipOutputStream zipOut = new ZipOutputStream(output);
try {
zipOut.setEncoding(FILE_NAME_ENCODING);
outputRdbDump(zipOut);
this.fileRepository.outputAll(PATH_FILES, zipOut);
}
finally {
zipOut.close();
}
}
private void outputRdbDump(ZipOutputStream zipOut)
throws IOException, DataSetException, SQLException {
Assert.Property.requireNotNull(dataSource, "dataSource");
ZipEntry zipEntry = new ZipEntry(PATH_RDB_DUMP);
zipOut.putNextEntry(zipEntry);
RdbUtils.exportAsXml(getJdbcConnection(), TABLES, zipOut);
}
public boolean checkDumpFile(File dumpFile) throws IOException {
Assert.Arg.notNull(dumpFile, "dumpFile");
if (!ZipUtils.isZip(dumpFile)) {
logger.debug("Not zip: " + dumpFile);
return false;
}
if (!ZipUtils.containsEntry(dumpFile, PATH_RDB_DUMP, FILE_NAME_ENCODING)) {
logger.debug("Does not contain a rdb dump: " + dumpFile);
return false;
}
return true;
}
public void restore(File dumpFile) throws Exception {
Assert.Arg.notNull(dumpFile, "dumpFile");
Assert.Property.requireNotNull(fileRepository, "fileRepository");
restoreRdb(dumpFile);
this.fileRepository.clear();
ZipUtils.extract(
dumpFile,
PATH_FILES,
FILE_NAME_ENCODING,
this.fileRepository.getEntryReader());
}
private void restoreRdb(File dumpFile)
throws IOException, SQLException, DatabaseUnitException {
Assert.Property.requireNotNull(dataSource, "dataSource");
ZipFile zipFile = new ZipFile(dumpFile, FILE_NAME_ENCODING);
try {
ZipEntry entry = zipFile.getEntry(PATH_RDB_DUMP);
if (entry != null) {
InputStream input = zipFile.getInputStream(entry);
try {
RdbUtils.cleanImportXml(getJdbcConnection(), input);
}
finally {
input.close();
}
}
}
finally {
zipFile.close();
}
}
}