Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
ru.abyss.settings.exporter.DBExporter Maven / Gradle / Ivy
/*
* Copyright Бездна (c) 2018.
*/
package ru.abyss.settings.exporter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.URL;
import java.nio.file.DirectoryStream;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;
import org.h2.Driver;
import org.postgresql.util.PGobject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.sevenzipjbinding.IOutCreateArchive7z;
import net.sf.sevenzipjbinding.IOutCreateCallback;
import net.sf.sevenzipjbinding.IOutItem7z;
import net.sf.sevenzipjbinding.ISequentialInStream;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.SevenZipException;
import net.sf.sevenzipjbinding.impl.OutItemFactory;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import net.sf.sevenzipjbinding.impl.RandomAccessFileOutStream;
import ru.abyss.settings.ProgressCallback;
/**
* @author Minu <[email protected] >
* @since 18.05.2018 11:19:57
*/
public class DBExporter {
private static Logger logger = LoggerFactory.getLogger(DBExporter.class);
private static final transient String ID = "id";
private static final transient String DEL = "del";
private static final transient String SLAVE_ID = "slave_id";
private static final transient String DATE_CREATE = "date_create";
private static final transient String DATE_UPDATE = "date_update";
private static final transient String LAST_TUSER_ID = "last_tuser_id";
private static final transient String TFACTORY_ID = "tfactory_id";
private static final transient String TWORK_NUM_ID = "twork_num_id";
private static final List EXPORT_TABLES = new ArrayList() {
private static final long serialVersionUID = 1473786915022151125L;
{
add("accessories.taccessories");
add("accessories.talways");
add("accessories.tapp_types");
add("accessories.tcalculated");
add("accessories.tcells");
add("accessories.tcells_always");
add("accessories.tcells_calculated");
add("accessories.tgroups");
add("accessories.tlocations");
add("accessories.tranges");
add("accessories.tranges_calculated");
add("accessories.ttypes");
add("catalog.taccount_numbers");
add("catalog.tcalc_types");
add("catalog.tcertificate_product_types");
add("catalog.tdocuments");
add("catalog.tpayments");
add("catalog.tproduct_types");
add("catalog.tservices");
add("scheduling.tstage_properties");
add("scheduling.tstage_schedules");
add("config.tcurrency_names");
add("contractors.taddresses");
add("contractors.tbanks");
add("contractors.tcategories");
add("contractors.tcustomers");
add("contractors.tdirections");
add("contractors.tdocuments");
add("contractors.tnotes");
add("contractors.tsupplier_prices");
add("contractors.tsuppliers");
add("factory.tscript_materials");
add("logistics.tbrigades");
add("logistics.tdirection_timetables");
add("logistics.tdirections");
add("logistics.tdistances");
add("logistics.tmeasurers");
add("logistics.tplatforms");
add("logistics.tregions");
add("logistics.troutes");
add("logistics.ttransport_marks");
add("logistics.ttransports");
add("orders.tdaytime_task");
add("orders.tmarker_types");
add("settings.taccessories");
add("settings.taccessory_connection_catalog_names");
add("settings.taccessory_connection_elements");
add("settings.taccessory_connection_groups");
add("settings.taccessory_connection_types");
add("settings.taccessory_groups");
add("settings.taccessory_subgroups");
add("settings.tcatalog_changes");
add("settings.tcatalog_elements");
add("settings.tcatalog_names");
add("settings.tchanges");
add("settings.tclearance_groups");
add("settings.tcorrection_groups");
add("settings.tcnc");
add("settings.tcnc_codes");
add("settings.tcomment_elements");
add("settings.tcomment_notes");
add("settings.tcomments");
add("settings.tconnections");
add("settings.tconnection_elements");
add("settings.tconstruct_elements");
add("settings.tconstruct_types");
add("settings.tconstructs");
add("settings.telements");
add("settings.tfindings");
add("settings.tlimits");
add("settings.tmaterials");
add("settings.tparents");
add("settings.tprice_lists");
add("settings.tprices");
add("settings.tprocessing_cnc");
add("settings.tproperties_arc_frames");
add("settings.tproperties_glazings");
add("settings.tproperties_imposts");
add("settings.tproperties_layouts");
add("settings.tproperties_leafs");
add("settings.tproperties_moreovers");
add("settings.tproperties_rect_frames");
add("settings.tproperties_round_frames");
add("settings.ttechnologies");
add("stock.talternative_articles");
add("stock.tcolor_bindings");
add("stock.tcolor_binding_names");
add("stock.tcolor_change_groups");
add("stock.tcolor_groups");
add("stock.tcolor_groups_ext");
add("stock.tcolor_names");
add("stock.tcolor_standarts");
add("stock.tcolors");
add("stock.tconnection_groups");
add("stock.tconsist_remains");
add("stock.tgroups");
add("stock.tmaterial_type_groups");
add("stock.tmaterial_types");
add("stock.tmaterials");
add("stock.tproperties");
add("stock.tscript_steps");
add("stock.tscripts");
add("stock.ttask_cnc");
add("stock.tcnc_macros");
add("stock.ttask_finished_goods");
add("stock.ttasks");
add("stock.ttechnologies");
add("stock.tunits");
}};
private static void writeVersion(Connection h2Connect, Long factoryId) throws Exception {
Properties prop = new Properties();
Enumeration systemResources = DBExporter.class.getClassLoader().getResources("release.properties");
logger.debug("search config file 'release.properties'");
while (systemResources.hasMoreElements()) {
URL url = systemResources.nextElement();
logger.debug(url.getPath());
if (url.getPath().contains("abyss-export")) {
try (InputStream is = url.openStream()) {
prop.load(is);
}
break;
}
}
if (prop.isEmpty())
throw new Exception("Не найден файл конфигурации выгрузки");
try (Statement st = h2Connect.createStatement()) {
st.addBatch("CREATE TABLE version (num BIGINT, rev BIGINT, tfactory_id BIGINT, export_date TIMESTAMP default now())");
st.addBatch("INSERT INTO version (num, rev, tfactory_id) VALUES ("
+ prop.getProperty("build.number") + ", "
+ prop.getProperty("build.revision") + ","
+ factoryId + ")");
st.executeBatch();
h2Connect.commit();
} catch (Exception e) {
h2Connect.rollback();
throw e;
}
}
private static String castType(String pgType) throws Exception {
switch (pgType.toLowerCase().replace("\"", "")) {
case "int8":
case "bigserial":
return "bigint";
case "bool":
return "boolean";
case "timestamp":
return "timestamp";
case "float8":
return "double precision";
case "varchar":
case "accessories.calc_type":
case "accessories.calc_side":
case "catalog.element_type_group":
case "catalog.delivery_type":
case "catalog.operation_type":
case "catalog.stage_type":
case "catalog.start_type":
case "catalog.day_type":
case "contractors.contractor_type":
case "contractors.legal_type":
case "factory.saw_type":
case "settings.angle_type":
case "settings.arc_type":
case "settings.arc_def_type":
case "settings.geometry_type":
case "settings.orientation":
case "settings.limit_type":
case "settings.mark_type":
case "settings.open_type":
case "settings.price_calc_type":
case "settings.price_unit_type":
case "settings.side_type":
case "stock.debit_type":
case "stock.currency_type":
case "stock.place_type":
case "stock.price_type":
case "stock.rate_type":
case "stock.report_type":
case "stock.report_calc_type":
case "stock.report_elements_type":
case "stock.side_type":
case "stock.task_type":
return "varchar";
default:
throw new Exception("Неизвестный тип: " + pgType);
}
}
private static List createH2Table(Connection pgConnect, Connection h2Connect, String schemaName, String tableName) throws Exception {
List types = new ArrayList<>();
List columns = new ArrayList<>();
StringBuilder sql = new StringBuilder("create table ").append(schemaName).append(".").append(tableName).append( " (");
DatabaseMetaData metaData = pgConnect.getMetaData();
String pkey = getPKey(pgConnect, schemaName, tableName);
try (ResultSet rs = metaData.getColumns(null, schemaName, tableName, null)) {
while (rs.next()) {
String colName = rs.getString("COLUMN_NAME");
if (!DEL.equals(colName) && !DATE_CREATE.equals(colName)
&& !DATE_UPDATE.equals(colName) && !LAST_TUSER_ID.equals(colName)
&& !TFACTORY_ID.equals(colName) && !SLAVE_ID.equals(colName)
&& !TWORK_NUM_ID.equals(colName)) {
String typeName = rs.getString("TYPE_NAME");
columns.add(colName);
types.add(typeName);
boolean isNullable = "YES".equalsIgnoreCase(rs.getString("IS_NULLABLE"));
if ("SETTINGS".equalsIgnoreCase(schemaName) && "TCNC".equalsIgnoreCase(tableName) && "interval".equalsIgnoreCase(colName))
sql.append("\"").append(colName.toUpperCase()).append("\"");
else
sql.append(colName);
sql.append(" ").append(castType(typeName)).append((isNullable ? "" : " not null")).append(", ");
}
}
if ("SETTINGS".equalsIgnoreCase(schemaName) && "TELEMENTS".equalsIgnoreCase(tableName)) {
String colName = "element_type_npp";
String typeName = "int8";
columns.add(colName);
types.add(typeName);
sql.append(colName).append(" ").append(castType(typeName)).append(", ");
}
sql.append("PRIMARY KEY(").append(pkey).append("))");
}
try (Statement st = h2Connect.createStatement()) {
logger.debug("create table " + schemaName + "." + tableName);
st.addBatch("CREATE SCHEMA IF NOT EXISTS " + schemaName);
st.addBatch(sql.toString());
if (!ID.equals(pkey))
st.addBatch("CREATE UNIQUE INDEX ON " + schemaName + "." + tableName + " (" + ID + ")");
for (int i = 0; i < types.size(); i++)
if ("SETTINGS".equalsIgnoreCase(schemaName) && "TCNC".equalsIgnoreCase(tableName) && "interval".equalsIgnoreCase(columns.get(i)))
st.addBatch("COMMENT ON COLUMN " + schemaName + "." + tableName + ".\"" + columns.get(i).toUpperCase() + "\" IS '" + types.get(i) + "'");
else
st.addBatch("COMMENT ON COLUMN " + schemaName + "." + tableName + "." + columns.get(i) + " IS '" + types.get(i) + "'");
st.executeBatch();
h2Connect.commit();
} catch (Exception e) {
h2Connect.rollback();
throw e;
}
return columns;
}
private static String castRule(String actionType, int rule) {
switch (rule) {
case DatabaseMetaData.importedKeyCascade:
return actionType + " CASCADE";
case DatabaseMetaData.importedKeySetNull:
return actionType + " SET NULL";
default:
return "";
}
}
private static void createFKey(Statement st, String fkName, String pkTableName, String fkTableName, String pkColumnName, String fkColumnName, int updRule, int delRule) throws Exception {
if (delRule == DatabaseMetaData.importedKeyCascade)
st.addBatch("delete from " + fkTableName + " fk where fk."
+ fkColumnName + " is not null and not exists(select 1 from " + pkTableName + " pk where pk." + pkColumnName + " = fk." + fkColumnName + ")");
if (delRule == DatabaseMetaData.importedKeySetNull)
st.addBatch("update " + fkTableName + " fk set " + fkColumnName + " = null where fk."
+ fkColumnName + " is not null and not exists(select 1 from " + pkTableName + " pk where pk." + pkColumnName + " = fk." + fkColumnName + ")");
String sql = "ALTER TABLE " + fkTableName + " ADD CONSTRAINT " + fkName
+ " FOREIGN KEY (" + fkColumnName + ") REFERENCES " + pkTableName + "(" + pkColumnName + ") "
+ castRule("ON DELETE", delRule) + " " + castRule("ON UPDATE", updRule);
st.addBatch(sql);
}
private static int createFKey(Connection pgConnect, Connection h2Connect, String schemaName, String tableName) throws Exception {
int ret = 0;
DatabaseMetaData metaData = pgConnect.getMetaData();
try (ResultSet rs = metaData.getImportedKeys(null, schemaName, tableName);
Statement st = h2Connect.createStatement()) {
logger.debug("create foreign keys for " + schemaName + "." + tableName);
while (rs.next()) {
String pkTableName = rs.getString("pktable_schem") + "." + rs.getString("pktable_name");
if (!EXPORT_TABLES.contains(pkTableName)) { // проверяем есть ли связанная таблица среди экспортируемых
if (!"core.tfactories".equalsIgnoreCase(pkTableName) // если нет и это не глобальные справочники, то ругаемся
&& !"catalog.telement_types".equalsIgnoreCase(pkTableName)
&& !"logistics.twork_nums".equalsIgnoreCase(pkTableName))
throw new Exception(pkTableName + " not in export set");
continue;
}
String fkTableName = rs.getString("fktable_schem") + "." + rs.getString("fktable_name");
createFKey(st, rs.getString("fk_name"), pkTableName, fkTableName, rs.getString("pkcolumn_name"),
rs.getString("fkcolumn_name"), rs.getInt("update_rule"), rs.getInt("delete_rule"));
ret++;
}
if ("settings".equalsIgnoreCase(schemaName) && "tparents".equalsIgnoreCase(tableName))
st.addBatch("delete from settings.tparents fk where fk.parent_id is null or not (exists(select 1 from settings.telements pk where pk.id = fk.parent_id) "
+ "or exists(select 1 from settings.tcatalog_names pk where pk.id = fk.parent_id))");
if ("stock".equalsIgnoreCase(schemaName) && "tproperties".equalsIgnoreCase(tableName)) {
createFKey(st, "tproperties_outgo_supplier_fk", "contractors.tsuppliers", "stock.tproperties", ID,
"outgo_tsupplier_id", DatabaseMetaData.importedKeyCascade, DatabaseMetaData.importedKeySetNull);
createFKey(st, "tproperties_outgo_recipient_fk", "contractors.tsuppliers", "stock.tproperties", ID,
"outgo_trecipient_id", DatabaseMetaData.importedKeyCascade, DatabaseMetaData.importedKeySetNull);
createFKey(st, "tproperties_outgo_recycler_fk", "contractors.tsuppliers", "stock.tproperties", ID,
"outgo_trecycler_id", DatabaseMetaData.importedKeyCascade, DatabaseMetaData.importedKeySetNull);
createFKey(st, "tproperties_blank_supplier_fk", "contractors.tsuppliers", "stock.tproperties", ID,
"blank_tsupplier_id", DatabaseMetaData.importedKeyCascade, DatabaseMetaData.importedKeySetNull);
createFKey(st, "tproperties_incoming_recipient_fk", "contractors.tsuppliers", "stock.tproperties", ID,
"incoming_trecipient_id", DatabaseMetaData.importedKeyCascade, DatabaseMetaData.importedKeySetNull);
createFKey(st, "tproperties_write_off_supplier_fk", "contractors.tsuppliers", "stock.tproperties", ID,
"write_off_tsupplier_id", DatabaseMetaData.importedKeyCascade, DatabaseMetaData.importedKeySetNull);
createFKey(st, "tproperties_write_off_recipient_fk", "contractors.tsuppliers", "stock.tproperties", ID,
"write_off_trecipient_id", DatabaseMetaData.importedKeyCascade, DatabaseMetaData.importedKeySetNull);
ret += 7;
}
if ("contractors".equalsIgnoreCase(schemaName)) {
if ("tsupplier_prices".equalsIgnoreCase(tableName)) {
createFKey(st, "tsupplier_prices_supplier_fk", "contractors.tsuppliers", "contractors.tsupplier_prices", ID,
"tsupplier_id", DatabaseMetaData.importedKeyCascade, DatabaseMetaData.importedKeyCascade);
ret++;
}
if ("taddresses".equalsIgnoreCase(tableName)) {
st.addBatch("delete from contractors.taddresses a "
+ "where not exists(select 1 from contractors.tcustomers c where c.id = a.tcounterparty_id) and "
+ "not exists(select 1 from contractors.tsuppliers s where s.id = a.tcounterparty_id)");
ret += 2;
}
if ("tdirections".equalsIgnoreCase(tableName)) {
st.addBatch("delete from contractors.tdirections d "
+ "where not exists(select 1 from contractors.tcustomers c where c.id = d.tcounterparty_id) and "
+ "not exists(select 1 from contractors.tsuppliers s where s.id = d.tcounterparty_id)");
ret += 2;
}
}
if ("accessories".equalsIgnoreCase(schemaName)) {
if ("talways".equalsIgnoreCase(tableName)) {
createFKey(st, "talways_recipient_fk", "contractors.tsuppliers", "accessories.talways", ID,
"trecipient_id", DatabaseMetaData.importedKeyCascade, DatabaseMetaData.importedKeySetNull);
ret++;
}
if ("tcalculated".equalsIgnoreCase(tableName)) {
createFKey(st, "tcalculated_recipient_fk", "contractors.tsuppliers", "accessories.tcalculated", ID,
"trecipient_id", DatabaseMetaData.importedKeyCascade, DatabaseMetaData.importedKeySetNull);
ret++;
}
if ("tcells_always".equalsIgnoreCase(tableName)) {
createFKey(st, "tcells_always_recipient_fk", "contractors.tsuppliers", "accessories.tcells_always", ID,
"trecipient_id", DatabaseMetaData.importedKeyCascade, DatabaseMetaData.importedKeySetNull);
ret++;
}
if ("tcells_calculated".equalsIgnoreCase(tableName)) {
createFKey(st, "tcells_calculated_recipient_fk", "contractors.tsuppliers", "accessories.tcells_calculated", ID,
"trecipient_id", DatabaseMetaData.importedKeyCascade, DatabaseMetaData.importedKeySetNull);
ret++;
}
if ("tgroups".equalsIgnoreCase(tableName)) {
createFKey(st, "tgroups_recipient_fk", "contractors.tsuppliers", "accessories.tgroups", ID,
"trecipient_id", DatabaseMetaData.importedKeyCascade, DatabaseMetaData.importedKeySetNull);
ret++;
}
if ("tranges_calculated".equalsIgnoreCase(tableName)) {
createFKey(st, "tranges_calculated_recipient_fk", "contractors.tsuppliers", "accessories.tranges_calculated", ID,
"trecipient_id", DatabaseMetaData.importedKeyCascade, DatabaseMetaData.importedKeySetNull);
ret++;
}
}
st.executeBatch();
pgConnect.commit();
h2Connect.commit();
} catch (Exception e) {
pgConnect.rollback();
h2Connect.rollback();
throw e;
} finally {
logger.debug(ret + " foreign keys created " + schemaName + "." + tableName);
}
return ret;
}
// metaData.getIndexInfo не работает в драйвере 9.4.1208, эта процедура заменяется его
private static String getPKey(Connection pgConnect, String schemaName, String tableName) throws Exception {
String sql = "SELECT string_agg(replace(trim(both '\"' from pg_catalog.pg_get_indexdef(ci.oid, (i.keys).n, false)), ?, ?), ', ' order by (i.keys).n)\n"
+ "FROM pg_catalog.pg_class ct\n"
+ "JOIN pg_catalog.pg_namespace n ON ct.relnamespace = n.oid\n"
+ "JOIN (SELECT i.indexrelid, i.indrelid, i.indisunique, information_schema._pg_expandarray(i.indkey) AS keys FROM pg_catalog.pg_index i) i ON (ct.oid = i.indrelid)\n"
+ "JOIN pg_catalog.pg_class ci ON ci.oid = i.indexrelid\n"
+ "WHERE n.nspname = ? AND ct.relname = ? AND i.indisunique and ci.relname ~* 'slave_uniq'\n"
+ "and trim(both '\"' from pg_catalog.pg_get_indexdef(ci.oid, (i.keys).n, false)) <> ?";
try (PreparedStatement st = pgConnect.prepareStatement(sql)) {
st.setString(1, SLAVE_ID);
st.setString(2, ID);
st.setString(3, schemaName);
st.setString(4, tableName);
st.setString(5, TFACTORY_ID);
try (ResultSet rs = st.executeQuery()) {
if (rs.next() && (rs.getString(1) != null))
return rs.getString(1);
throw new Exception("Не найден primary key у таблицы " + schemaName + "." + tableName);
}
}
}
private static void exportTable(Connection pgConnect, Connection h2Connect, String schemaName, String tableName, Long factoryId) throws Exception {
StringBuilder sql;
if ("SETTINGS".equalsIgnoreCase(schemaName) && "TELEMENTS".equalsIgnoreCase(tableName))
sql = new StringBuilder().append("select e.*, et.npp as element_type_npp from SETTINGS.TELEMENTS e left join catalog.element_types et on et.id = e.telement_type_id where e.").append(TFACTORY_ID).append("=? and not e.").append(DEL);
else
sql = new StringBuilder().append("select * from only ").append(schemaName + "." + tableName).append(" where ").append(TFACTORY_ID).append("=? and not ").append(DEL);
try (PreparedStatement stmt = pgConnect.prepareStatement(sql.toString())) {
stmt.setObject(1, factoryId);
stmt.setFetchDirection(ResultSet.FETCH_FORWARD);
stmt.setFetchSize(128);
stmt.execute();
try (ResultSet rset = stmt.getResultSet()) {
List cols = createH2Table(pgConnect, h2Connect, schemaName, tableName);
try (PreparedStatement ps = h2Connect.prepareStatement("insert into " + schemaName + "." + tableName
+ " values (" + cols.stream().map(c -> "?").collect(Collectors.joining(", ")) + ")")) {
int count = 0;
final int batchSize = 1000;
logger.debug("insert into " + schemaName + "." + tableName);
while (rset.next()) {
for (int i = 1; i <= cols.size(); i++) {
Object val = rset.getObject(cols.get(i - 1));
if (val instanceof PGobject)
val = val.toString();
ps.setObject(i, val);
}
ps.addBatch();
if (++count % batchSize == 0)
ps.executeBatch();
}
ps.executeBatch(); // добиваем оставшиеся записи
h2Connect.commit();
logger.debug("insert complete " + schemaName + "." + tableName);
} catch (Exception e) {
h2Connect.rollback();
throw e;
}
}
pgConnect.commit();
} catch (Exception e) {
pgConnect.rollback();
throw e;
}
}
public static File export(Connection connection, Properties props, Long factoryId, ProgressCallback callback) throws Exception {
Driver.load();
Path tmpDb = Files.createTempDirectory("abyss_export_");
try {
try (Connection h2 = DriverManager.getConnection("jdbc:h2:" + tmpDb + "/abyss;TRACE_LEVEL_FILE=4;MAX_COMPACT_TIME=-1",
props.getProperty("export.h2.login"), props.getProperty("export.h2.password"))) {
h2.setAutoCommit(false);
writeVersion(h2, factoryId);
long done = 1;
long total = EXPORT_TABLES.size() + 1;
if (callback != null)
callback.setProgress("Извлечение данных", done, total);
// создаём и заполняем таблицы
for (String table : EXPORT_TABLES) {
String[] t = table.split("\\.");
exportTable(connection, h2, t[0], t[1], factoryId);
if (callback != null)
callback.setProgress("Извлечение данных", ++done, total);
}
// навешиваем внешние ключи на таблицы
int cnt = 0;
done = 1;
for (String table : EXPORT_TABLES) {
String[] t = table.split("\\.");
cnt += createFKey(connection, h2, t[0], t[1]);
if (callback != null)
callback.setProgress("Создание связей", ++done, total);
}
logger.debug(cnt + " foreign keys created");
}
logger.debug("compress results");
try (IOutCreateArchive7z arch = SevenZip.openOutArchive7z()) {
arch.setLevel(9);
arch.setThreadCount(2);
List files = new ArrayList<>();
try (DirectoryStream fls = Files.newDirectoryStream(tmpDb)) {
for (Path file : fls)
files.add(file.toFile());
}
File exportArch = File.createTempFile("abyss_export_", ".tmp");
try (RandomAccessFile out = new RandomAccessFile(exportArch, "rw")) {
arch.createArchive(new RandomAccessFileOutStream(out), files.size(), new IOutCreateCallback() {
private long total = 0;
private long perc = -1;
@Override
public void setTotal(long total) throws SevenZipException {
this.total = total;
}
@Override
public void setCompleted(long complete) throws SevenZipException {
long lastPerc = Math.round(100.0 * complete / total);
if (lastPerc != perc) {
perc = lastPerc;
logger.debug("compression: " + perc + "%");
if (callback != null)
callback.setProgress("Сжатие базы данных", complete, total);
}
}
@Override
public void setOperationResult(boolean operationResultOk) throws SevenZipException {
logger.debug(operationResultOk ? "export done" : "compression error");
}
@Override
public IOutItem7z getItemInformation(int index, OutItemFactory outItemFactory)
throws SevenZipException {
IOutItem7z outItem = outItemFactory.createOutItem();
outItem.setDataSize(files.get(index).length());
outItem.setPropertyPath(files.get(index).getName());
return outItem;
}
@Override
public ISequentialInStream getStream(int index) throws SevenZipException {
try {
return new RandomAccessFileInStream(new RandomAccessFile(files.get(index), "r"));
} catch (Exception e) {
logger.error("Произошла ошибка", e);
return null;
}
}
});
} finally {
exportArch.deleteOnExit();
}
return exportArch;
}
} finally {
Driver.unload();
Files.walkFileTree(tmpDb, new SimpleFileVisitor() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
file.toFile().deleteOnExit();
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
dir.toFile().deleteOnExit();
return FileVisitResult.CONTINUE;
}
});
}
}
}