X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.db.layer0%2Fsrc%2Forg%2Fsimantics%2Fdb%2Flayer0%2Fmigration%2FMigrationStateImpl.java;h=d7f6b4e95497fe0a1ac0991cf27c38720f316681;hp=2b19da58607dd66fa9368296ccf99a11100f30c2;hb=0b8b0bcf0ad421541ee428613da3ff1697bd11ad;hpb=c26409b1caf2f1e560d37c5befd11b442399c3fe diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/migration/MigrationStateImpl.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/migration/MigrationStateImpl.java index 2b19da586..d7f6b4e95 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/migration/MigrationStateImpl.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/migration/MigrationStateImpl.java @@ -11,6 +11,7 @@ *******************************************************************************/ package org.simantics.db.layer0.migration; +import java.io.Closeable; import java.io.File; import java.io.IOException; import java.text.DateFormat; @@ -24,6 +25,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.simantics.databoard.Bindings; import org.simantics.databoard.binding.mutable.Variant; import org.simantics.databoard.container.DataContainer; +import org.simantics.databoard.container.DataContainers; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.Session; @@ -31,12 +33,14 @@ import org.simantics.db.WriteGraph; import org.simantics.db.WriteOnlyGraph; import org.simantics.db.common.request.WriteResultRequest; import org.simantics.db.common.utils.Logger; +import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.AssumptionException; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor; import org.simantics.db.layer0.internal.SimanticsInternal; import org.simantics.db.layer0.util.Layer0Utils; import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest; +import org.simantics.db.layer0.util.TGProgressMonitor; import org.simantics.db.layer0.util.TGTransferableGraphSource; import org.simantics.db.layer0.util.TransferableGraphConfiguration2; import org.simantics.db.request.Read; @@ -51,10 +55,10 @@ import org.simantics.graph.db.TransferableGraphImporter; import org.simantics.graph.db.TransferableGraphSource; import org.simantics.graph.db.TransferableGraphs; import org.simantics.graph.db.WrapperAdvisor; -import org.simantics.graph.representation.ByteFileReader; import org.simantics.graph.representation.TransferableGraph1; import org.simantics.graph.representation.TransferableGraphFileReader; import org.simantics.layer0.Layer0; +import org.simantics.utils.logging.TimeLogger; public class MigrationStateImpl implements MigrationState { @@ -106,7 +110,9 @@ public class MigrationStateImpl implements MigrationState { try { File modelFile = getProperty(MigrationStateKeys.MODEL_FILE); reader = new TransferableGraphFileReader(modelFile); + TimeLogger.log(MigrationStateImpl.class, "reading TG into memory from " + modelFile); TransferableGraph1 tg = reader.readTG(); + TimeLogger.log(MigrationStateImpl.class, "read TG into memory from " + modelFile); setProperty(MigrationStateKeys.CURRENT_TG, tg); return (T)tg; } catch (DatabaseException e) { @@ -120,20 +126,7 @@ public class MigrationStateImpl implements MigrationState { } else if (MigrationStateKeys.CURRENT_TGS.equals(key)) { File modelFile = getProperty(MigrationStateKeys.MODEL_FILE); - - try { - StreamingTransferableGraphFileReader reader = new StreamingTransferableGraphFileReader(modelFile); - TransferableGraphSource tgs = reader.readTG(); - setProperty(MigrationStateKeys.CURRENT_TGS_READER, reader); - setProperty(MigrationStateKeys.CURRENT_TGS, tgs); - return (T)tgs; - } catch (DatabaseException e) { - throw e; - } catch (IOException e) { - throw new DatabaseException("An I/O exception occurred during reading '" + modelFile.getAbsolutePath() + "'", e); - } catch (Throwable t) { - throw new DatabaseException(t); - } + return (T) initializeTransferableGraphSource(modelFile); } else if (MigrationStateKeys.CURRENT_DATA_CONTAINER.equals(key)) { @@ -166,120 +159,22 @@ public class MigrationStateImpl implements MigrationState { } } else if (MigrationStateKeys.CURRENT_RESOURCE.equals(key) || MigrationStateKeys.CURRENT_ROOT_RESOURCES.equals(key)) { - + final Session session = getProperty(MigrationStateKeys.SESSION); final IProgressMonitor monitor = probeProperty(MigrationStateKeys.PROGRESS_MONITOR); final boolean updateDependencies = MigrationUtils.getProperty(this, MigrationStateKeys.UPDATE_DEPENDENCIES, Boolean.TRUE); - - final TransferableGraph1 tg = probeProperty(MigrationStateKeys.CURRENT_TG); - if(tg != null) { - - final Resource indexRoot = session.syncRequest(new WriteResultRequest() { - @Override - public Resource perform(WriteGraph graph) throws DatabaseException { - if(!updateDependencies) - Layer0Utils.setDependenciesIndexingDisabled(graph, true); - return createTemporaryRoot(graph); - } - }); - - IImportAdvisor baseAdvisor = MigrationUtils.getProperty(this, MigrationStateKeys.IMPORT_ADVISOR, new DefaultPasteImportAdvisor(indexRoot)); - IImportAdvisor2 advisor = new WrapperAdvisor(baseAdvisor) { - @Override - public void beforeWrite(WriteOnlyGraph graph, TransferableGraphImporter process) throws DatabaseException { - super.beforeWrite(graph, process); - if(!updateDependencies) - Layer0Utils.setDependenciesIndexingDisabled(graph, true); - } - @Override - public void afterWrite(WriteOnlyGraph graph, TransferableGraphImporter process) throws DatabaseException { - super.afterWrite(graph, process); - Boolean storeResources = probeProperty(MigrationStateKeys.GET_RESOURCE_IDS); - if(storeResources != null && storeResources) { - long[] ids = process.getResourceIds(session.getService(SerialisationSupport.class)); - setProperty(MigrationStateKeys.RESOURCE_IDS, ids); - } - } - }; - // Make sure that the supplied advisor is redirected to temp - advisor.redirect(indexRoot); - - ImportResult ir = TransferableGraphs.importGraph1(session, new TGTransferableGraphSource(tg), advisor, new TGStatusMonitor() { - @Override - public void status(int percentage) { - monitor.subTask("Importing model from file (" + percentage + "%)"); - } - @Override - public boolean isCanceled() { - return monitor.isCanceled(); - } - }); - - setProperty(MigrationStateKeys.IMPORT_RESULT, ir); - setProperty(MigrationStateKeys.CURRENT_RESOURCE, indexRoot); - setProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES, new ArrayList<>(advisor.getRoots())); - setProperty(MigrationStateKeys.DATABASE_REVISION_AFTER_TG_IMPORT, session.getService(ManagementSupport.class).getHeadRevisionId()); - setProperty(MigrationStateKeys.CURRENT_TG, null); - - return getProperty(key); - } - final TransferableGraphSource tgs = getProperty(MigrationStateKeys.CURRENT_TGS); - if(tgs != null) { - - final Resource indexRoot = session.syncRequest(new WriteResultRequest() { - @Override - public Resource perform(WriteGraph graph) throws DatabaseException { - if(!updateDependencies) - Layer0Utils.setDependenciesIndexingDisabled(graph, true); - return createTemporaryRoot(graph); - } - }); - - IImportAdvisor baseAdvisor = MigrationUtils.getProperty(this, MigrationStateKeys.IMPORT_ADVISOR, new DefaultPasteImportAdvisor(indexRoot)); - IImportAdvisor2 advisor = new WrapperAdvisor(baseAdvisor) { - @Override - public Resource getTarget() { - return indexRoot; - } - @Override - public void beforeWrite(WriteOnlyGraph graph, TransferableGraphImporter process) throws DatabaseException { - super.beforeWrite(graph, process); - if(!updateDependencies) - Layer0Utils.setDependenciesIndexingDisabled(graph, true); - } - @Override - public void afterWrite(WriteOnlyGraph graph, TransferableGraphImporter process) throws DatabaseException { - super.afterWrite(graph, process); - Boolean storeResources = probeProperty(MigrationStateKeys.GET_RESOURCE_IDS); - if(storeResources != null && storeResources) { - long[] ids = process.getResourceIds(session.getService(SerialisationSupport.class)); - setProperty(MigrationStateKeys.RESOURCE_IDS, ids); - } - } - }; - // Make sure that the supplied advisor is redirected to temp - advisor.redirect(indexRoot); - - ImportResult ir = TransferableGraphs.importGraph1(session, tgs, advisor, new TGStatusMonitor() { - @Override - public void status(int percentage) { - monitor.subTask("Importing model from file (" + percentage + "%)"); - } - @Override - public boolean isCanceled() { - return monitor.isCanceled(); - } - }); - - setProperty(MigrationStateKeys.IMPORT_RESULT, ir); - setProperty(MigrationStateKeys.CURRENT_RESOURCE, indexRoot); - setProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES, new ArrayList<>(advisor.getRoots())); - setProperty(MigrationStateKeys.DATABASE_REVISION_AFTER_TG_IMPORT, session.getService(ManagementSupport.class).getHeadRevisionId()); - setProperty(MigrationStateKeys.CURRENT_TG, null); + File temporaryTg = exportCurrentTgAsTemporaryFile(session, monitor); + if (temporaryTg != null) + setProperty(MigrationStateKeys.CURRENT_TGS, initializeTransferableGraphSource(temporaryTg)); + TransferableGraphSource tgs = getProperty(MigrationStateKeys.CURRENT_TGS); + if (tgs != null) { + importTransferableGraphSource(monitor, session, updateDependencies, tgs); + // Delete temporary file if necessary + if (temporaryTg != null) + temporaryTg.delete(); return getProperty(key); - } } else if (MigrationStateKeys.UPDATE_DEPENDENCIES.equals(key)) { @@ -308,7 +203,7 @@ public class MigrationStateImpl implements MigrationState { } } - private static void uncheckedClose(ByteFileReader closeable) { + private static void uncheckedClose(Closeable closeable) { try { if (closeable != null) closeable.close(); @@ -327,10 +222,133 @@ public class MigrationStateImpl implements MigrationState { Resource indexRoot = graph.newResource(); String indexRootName = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date()); + indexRootName = NameUtils.findFreshName(graph, indexRootName, temp, L0.ConsistsOf, "%s-%d"); graph.claim(indexRoot, L0.InstanceOf, L0.IndexRoot); graph.addLiteral(indexRoot, L0.HasName, L0.String, indexRootName, Bindings.STRING); graph.claim(temp, L0.ConsistsOf, indexRoot); return indexRoot; } + private File exportCurrentTgAsTemporaryFile(Session session, IProgressMonitor monitor) throws DatabaseException { + TransferableGraph1 tg = probeProperty(MigrationStateKeys.CURRENT_TG); + if (tg == null) + return null; + + try { + // Write TG back to disk and initialize CURRENT_TGS for the migrated TG. + File modelFile = getProperty(MigrationStateKeys.MODEL_FILE); + File tempFile = File.createTempFile("temporary-tgs", ".tg", SimanticsInternal.getTemporaryDirectory()); + TimeLogger.log(MigrationStateImpl.class, "export temporary TG " + tempFile); + + DataContainer dc = DataContainers.readHeader(modelFile); + TransferableGraphs.writeTransferableGraph(session, dc.format, dc.version, dc.metadata, + new TGTransferableGraphSource(tg), + tempFile, + new TGExportMonitor(monitor, "Exporting temporary transferable graph")); + + // Allow potentially large TG structure to be GC'ed. + setProperty(MigrationStateKeys.CURRENT_TG, null); + + TimeLogger.log(MigrationStateImpl.class, "export temporary TG done " + tempFile); + return tempFile; + } catch (Exception e) { + throw new DatabaseException(e); + } + } + + private TransferableGraphSource initializeTransferableGraphSource(File dataContainer) throws DatabaseException { + try { + StreamingTransferableGraphFileReader reader = new StreamingTransferableGraphFileReader(dataContainer); + TransferableGraphSource tgs = reader.readTG(); + setProperty(MigrationStateKeys.CURRENT_TGS_READER, reader); + setProperty(MigrationStateKeys.CURRENT_TGS, tgs); + return tgs; + } catch (DatabaseException e) { + throw e; + } catch (IOException e) { + throw new DatabaseException("An I/O exception occurred during reading '" + dataContainer.getAbsolutePath() + "'", e); + } catch (Throwable t) { + throw new DatabaseException(t); + } + } + + private void importTransferableGraphSource(IProgressMonitor monitor, Session session, boolean updateDependencies, TransferableGraphSource tgs) throws DatabaseException { + TimeLogger.log(MigrationStateImpl.class, "import TGS " + tgs); + final Resource indexRoot = session.syncRequest(new WriteResultRequest() { + @Override + public Resource perform(WriteGraph graph) throws DatabaseException { + if(!updateDependencies) + Layer0Utils.setDependenciesIndexingDisabled(graph, true); + return createTemporaryRoot(graph); + } + }); + + IImportAdvisor baseAdvisor = MigrationUtils.getProperty(this, MigrationStateKeys.IMPORT_ADVISOR, new DefaultPasteImportAdvisor(indexRoot)); + IImportAdvisor2 advisor = new WrapperAdvisor(baseAdvisor) { + @Override + public Resource getTarget() { + return indexRoot; + } + @Override + public void beforeWrite(WriteOnlyGraph graph, TransferableGraphImporter process) throws DatabaseException { + super.beforeWrite(graph, process); + if(!updateDependencies) + Layer0Utils.setDependenciesIndexingDisabled(graph, true); + } + @Override + public void afterWrite(WriteOnlyGraph graph, TransferableGraphImporter process) throws DatabaseException { + super.afterWrite(graph, process); + Boolean storeResources = probeProperty(MigrationStateKeys.GET_RESOURCE_IDS); + if(storeResources != null && storeResources) { + long[] ids = process.getResourceIds(session.getService(SerialisationSupport.class)); + setProperty(MigrationStateKeys.RESOURCE_IDS, ids); + } + } + }; + + // Make sure that the supplied advisor is redirected to temp + advisor.redirect(indexRoot); + + String task = "Importing model into database"; + monitor.subTask(task); + ImportResult ir = TransferableGraphs.importGraph1(session, tgs, advisor, new TGImportMonitor(monitor, task)); + monitor.subTask(""); + + setProperty(MigrationStateKeys.IMPORT_RESULT, ir); + setProperty(MigrationStateKeys.CURRENT_RESOURCE, indexRoot); + setProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES, new ArrayList<>(advisor.getRoots())); + setProperty(MigrationStateKeys.DATABASE_REVISION_AFTER_TG_IMPORT, session.getService(ManagementSupport.class).getHeadRevisionId()); + TimeLogger.log(MigrationStateImpl.class, "imported TGS " + tgs); + } + + + static class TGImportMonitor implements TGStatusMonitor { + private final IProgressMonitor monitor; + private final String message; + public TGImportMonitor(IProgressMonitor monitor, String message) { + this.monitor = monitor; + this.message = message; + } + @Override + public void status(int percentage) { + monitor.subTask(message + " (" + percentage + "%)"); + } + @Override + public boolean isCanceled() { + return monitor.isCanceled(); + } + } + + static class TGExportMonitor extends TGProgressMonitor { + private final String message; + public TGExportMonitor(IProgressMonitor monitor, String message) { + super(monitor); + this.message = message; + } + @Override + protected void workDone(int percentage) { + monitor.subTask(message + " (" + percentage + "%)"); + } + } + }