private async Task PerformUpgradeAsync(Domain domain, UpgradeStage stage, CancellationToken token) { context.Stage = stage; await OnBeforeStageAsync(token).ConfigureAwait(false); var session = await domain.OpenSessionAsync(SessionType.System, token).ConfigureAwait(false); await using (session.ConfigureAwait(false)) { using (session.Activate()) { var transaction = session.OpenTransaction(); await using (transaction.ConfigureAwait(false)) { var upgrader = new SchemaUpgrader(context, session); var extractor = new SchemaExtractor(context, session); await SynchronizeSchemaAsync(domain, upgrader, extractor, GetUpgradeMode(stage), token).ConfigureAwait(false); var storageNode = BuildStorageNode(domain, await extractor.GetSqlSchemaAsync(token).ConfigureAwait(false)); session.SetStorageNode(storageNode); await OnStageAsync(session, token).ConfigureAwait(false); transaction.Complete(); } } } }
/// <exception cref="ArgumentOutOfRangeException"><c>context.Stage</c> is out of range.</exception> private void PerformUpgrade(Domain domain, UpgradeStage stage) { context.Stage = stage; OnBeforeStage(); using (var session = domain.OpenSession(SessionType.System)) using (session.Activate()) using (var transaction = session.OpenTransaction()) { var upgrader = new SchemaUpgrader(context, session); var extractor = new SchemaExtractor(context, session); SynchronizeSchema(domain, upgrader, extractor, GetUpgradeMode(stage)); var storageNode = BuildStorageNode(domain, extractor); session.SetStorageNode(storageNode); OnStage(session); transaction.Complete(); } }
private StorageNode BuildStorageNode(Domain domain, SchemaExtractor extractor) { var schemaExtractionResult = GetRealExtractionResult(extractor.GetSqlSchema()); context.ExtractedSqlModelCache = schemaExtractionResult; var modelMapping = ModelMappingBuilder.Build( domain.Handlers, schemaExtractionResult, context.Services.MappingResolver, context.NodeConfiguration, context.UpgradeMode.IsLegacy()); var result = new StorageNode(context.NodeConfiguration, modelMapping, new TypeIdRegistry()); // Register default storage node immediately, // non-default nodes are registered in NodeManager after everything completes successfully. if (result.Id == WellKnown.DefaultNodeId) { domain.Handlers.StorageNodeRegistry.Add(result); } context.StorageNode = result; return(result); }
private void SynchronizeSchema( Domain domain, SchemaUpgrader upgrader, SchemaExtractor extractor, SchemaUpgradeMode schemaUpgradeMode) { using (UpgradeLog.InfoRegion(Strings.LogSynchronizingSchemaInXMode, schemaUpgradeMode)) { StorageModel targetSchema = null; if (schemaUpgradeMode == SchemaUpgradeMode.Skip) { if (context.ParentDomain == null) { //If we build main domain we should log target model. //Log of Storage Node target model is not necessary //because storage target model exactly the same. targetSchema = GetTargetModel(domain); context.TargetStorageModel = targetSchema; if (UpgradeLog.IsLogged(LogLevel.Info)) { UpgradeLog.Info(Strings.LogTargetSchema); targetSchema.Dump(); } } var builder = ExtractedModelBuilderFactory.GetBuilder(context); context.ExtractedSqlModelCache = builder.Run(); OnSchemaReady(); return; // Skipping comparison completely } var extractedSchema = extractor.GetSchema(); // Hints var triplet = BuildTargetModelAndHints(extractedSchema); var hintProcessingResult = triplet.Third; targetSchema = triplet.First; context.TargetStorageModel = targetSchema; var hints = triplet.Second; if (UpgradeLog.IsLogged(LogLevel.Info)) { UpgradeLog.Info(Strings.LogExtractedSchema); extractedSchema.Dump(); UpgradeLog.Info(Strings.LogTargetSchema); targetSchema.Dump(); } OnSchemaReady(); var breifExceptionFormat = domain.Configuration.SchemaSyncExceptionFormat == SchemaSyncExceptionFormat.Brief; var result = SchemaComparer.Compare(extractedSchema, targetSchema, hints, context.Hints, schemaUpgradeMode, domain.Model, breifExceptionFormat, context.Stage); var shouldDumpSchema = !schemaUpgradeMode.In( SchemaUpgradeMode.Skip, SchemaUpgradeMode.ValidateCompatible, SchemaUpgradeMode.Recreate); if (shouldDumpSchema && UpgradeLog.IsLogged(LogLevel.Info)) { UpgradeLog.Info(result.ToString()); } if (UpgradeLog.IsLogged(LogLevel.Info)) { UpgradeLog.Info(Strings.LogComparisonResultX, result); } context.SchemaDifference = (NodeDifference)result.Difference; context.SchemaUpgradeActions = result.UpgradeActions; switch (schemaUpgradeMode) { case SchemaUpgradeMode.ValidateExact: if (result.SchemaComparisonStatus != SchemaComparisonStatus.Equal || result.HasColumnTypeChanges) { throw new SchemaSynchronizationException(result); } if (!hintProcessingResult.AreAllTypesMapped() && hintProcessingResult.SuspiciousTypes.Any()) { throw new SchemaSynchronizationException(Strings.ExExtractedAndTargetSchemasAreEqualButThereAreChangesInTypeIdentifiersSet); } break; case SchemaUpgradeMode.ValidateCompatible: if (result.SchemaComparisonStatus != SchemaComparisonStatus.Equal && result.SchemaComparisonStatus != SchemaComparisonStatus.TargetIsSubset) { throw new SchemaSynchronizationException(result); } break; case SchemaUpgradeMode.PerformSafely: if (result.HasUnsafeActions) { throw new SchemaSynchronizationException(result); } goto case SchemaUpgradeMode.Perform; case SchemaUpgradeMode.Recreate: case SchemaUpgradeMode.Perform: upgrader.UpgradeSchema(extractor.GetSqlSchema(), extractedSchema, targetSchema, result.UpgradeActions); if (result.UpgradeActions.Any()) { extractor.ClearCache(); } break; case SchemaUpgradeMode.ValidateLegacy: if (result.IsCompatibleInLegacyMode != true) { throw new SchemaSynchronizationException(result); } break; default: throw new ArgumentOutOfRangeException("schemaUpgradeMode"); } } }