예제 #1
0
		public override MigrationInfo GetMigrationInfo(string scriptName)
		{
			using (var command = (NpgsqlCommand)GetDbCommand())
			{
				command.CommandText =
					$@" select * from public.{MigrationsTableName}
						where sctipt_name = @script_name";

				command.Parameters.Add(new NpgsqlParameter("@script_name", NpgsqlTypes.NpgsqlDbType.Varchar) { NpgsqlValue = scriptName });

				using (var reader = command.ExecuteReader())
				{
					if (!reader.Read())
					{
						return null;
					}

					MigrationInfo mi = new MigrationInfo
					{
						ScriptName = reader.GetString(0),
						ScriptText = reader.GetString(1),
						Hash = reader.GetString(2),
						DateTimeStamp = reader.GetDateTime(3)
					};

					return mi;
				}
			}
		}
예제 #2
0
        public void ensure_version_repository_is_initialised_when_running_an_up_migration()
        {
            var migrationInfo = new MigrationInfo(direction: MigrationDirection.Up, scriptFolder: Some.String(), targetSchema: "testSchema",
                targetTablespace: "testTablespace", targetEnvironment: Some.ListOf(Some.String()), targetVersion: null);

            _migrator.Migrate(Some.ConnectionInfo(), migrationInfo);

            _mockVersionRepository.Verify(m => m.InitialiseVersioningTable("testSchema", "testTablespace"));
        }
 private List<MigrationInfo> GetMigrationsList(Migrator mig)
 {
     List<System.Type> migrations = mig.MigrationsTypes;
     migrations.Reverse();
     List<MigrationInfo> list = new List<MigrationInfo>();
     List<System.Type>.Enumerator en = migrations.GetEnumerator();
     while(en.MoveNext()){
         MigrationInfo info = new MigrationInfo(en.Current);
         list.Add(info);
     }
     return list;
 }
예제 #4
0
		protected override void WriteMigrationInfo(MigrationInfo migrationInfo)
		{
			using (var command = (NpgsqlCommand)GetDbCommand())
			{
				command.CommandText =
					$@"insert into public.{MigrationsTableName}
						(sctipt_name, script_text, hash)
						VALUES (@sctipt_name, @script_text, @hash)";

				command.Parameters.Add(new NpgsqlParameter("@sctipt_name", NpgsqlTypes.NpgsqlDbType.Varchar) { NpgsqlValue = migrationInfo.ScriptName });
				command.Parameters.Add(new NpgsqlParameter("@script_text", NpgsqlTypes.NpgsqlDbType.Text) { NpgsqlValue = migrationInfo.ScriptText });
				command.Parameters.Add(new NpgsqlParameter("@hash", NpgsqlTypes.NpgsqlDbType.Text) { NpgsqlValue = migrationInfo.Hash });

				command.ExecuteNonQuery();
			}
		}
        private async Task ApplyMigration(MigrationInfo migrationInfo, DbConnection connection,
                                          CancellationToken cancellationToken)
        {
            try
            {
                var command = connection.CreateCommand();
                command.CommandTimeout = 300;

                await using (command)
                {
                    command.CommandText = migrationInfo.Data;
                    await command.ExecuteNonQueryAsync(cancellationToken);

                    Logger.LogInformation("Migration \"{MigrationName}\" applied", migrationInfo.MigrationName);
                }
            }
            catch (Exception e)
            {
                Logger.LogError("Error while applying \"{MigrationName}\" - {ErrorMessage}", migrationInfo.MigrationName,
                                e.Message);
                throw;
            }
        }
        public async Task MigrateNewest()
        {
            TestSettings.SkipTestIfNecessary();

            var now = DateTime.UtcNow;

            await using var container = CreateContainer();
            var engine = container.GetRequiredService <MigrationEngine>();

            using var session = container.GetRequiredService <IDocumentStore>().OpenAsyncSession();
            session.Advanced.WaitForIndexesAfterSaveChanges();
            await session.StoreAsync(new MigrationInfo { Id = "migrationInfos/1.0.0", Name = nameof(FirstMigration), Version = "1.0.0", AppliedAt = now.AddDays(-1) });

            await session.SaveChangesAsync();

            var summary = await engine.MigrateAsync(now, new[] { GetType().Assembly });

            summary.TryGetAppliedMigrations(out var appliedMigrations).Should().BeTrue();
            var expectedMigrationInfo = new MigrationInfo {
                Id = "migrationInfos/2.0.0", Name = nameof(SecondMigration), Version = "2.0.0", AppliedAt = now
            };
            var expectedMigrationInfos = new List <MigrationInfo> {
                expectedMigrationInfo
            };

            appliedMigrations.Should().BeEquivalentTo(expectedMigrationInfos);
            var storedEntities = await session.Query <Entity>().ToListAsync();

            var expectedStoredEntities = new List <Entity> {
                new () { Id = "entities/1-A", Value = "Bar" }
            };

            storedEntities.Should().BeEquivalentTo(expectedStoredEntities);
            var storedMigrationInfo = await session.LoadAsync <MigrationInfo?>(expectedMigrationInfo.Id);

            storedMigrationInfo.Should().BeEquivalentTo(expectedMigrationInfo);
        }
예제 #7
0
            private static IMigrationInfo GetMigrationInfoFor(FluentMigrator.IMigration migration)
            {
                var migrationType      = migration.GetType();
                var migrationAttribute = migrationType.GetOneAttribute <MigrationAttribute>();
                var chunSunMigration   = migration as MigrationBase;

                if (chunSunMigration == null)
                {
                    throw new Exception("迁移提供程序必须继承自 \"" + typeof(MigrationBase).FullName + "\" 类型。");
                }
                var id = chunSunMigration.Feature.Descriptor.Id;

                var version     = migrationAttribute.Version;
                var description = id + "_" + migrationAttribute.Description + "_" + migrationAttribute.Version;

                var migrationInfo = new MigrationInfo(version, description, migrationAttribute.TransactionBehavior, () => migration);
                var allAttributes = migrationType.GetAllAttributes <MigrationTraitAttribute>();

                foreach (var traitAttribute in allAttributes)
                {
                    migrationInfo.AddTrait(traitAttribute.Name, traitAttribute.Value);
                }
                return(migrationInfo);
            }
예제 #8
0
        private static void Draw(List<MigrationInfo> migrationsInOrder, MigrationInfo current)
        {
            Console.WriteLine();

            foreach (var mi in migrationsInOrder)
            {
                ConsoleColor color = current == mi ? ConsoleColor.Green :
                    mi.FileName != null && mi.IsExecuted ? ConsoleColor.DarkGreen :
                    mi.FileName == null && mi.IsExecuted ? ConsoleColor.Red :
                    mi.FileName != null && !mi.IsExecuted ? ConsoleColor.White :
                    throw new InvalidOperationException();


                SafeConsole.WriteColor(color,  
                    mi.IsExecuted?  "- " : 
                    current == mi ? "->" : 
                                    "  ");
                
                SafeConsole.WriteColor(color, mi.Version);
                SafeConsole.WriteLineColor(mi.FileName == null ? ConsoleColor.Red: ConsoleColor.Gray, " " + mi.Comment);
            }

            Console.WriteLine();
        }
 public override void InsertVersion(MigrationInfo migrationInfo)
 {
     base.InsertVersion(migrationInfo);
     RaiseOnUpdateVersion(migrationInfo.Version);
 }
예제 #10
0
        public override void GenerateMigrationMetadataClass(
            string @namespace,
            string className,
            MigrationInfo migration,
            Type contextType,
            IndentedStringBuilder stringBuilder)
        {
            Check.NotEmpty(@namespace, "namespace");
            Check.NotEmpty(className, "className");
            Check.NotNull(migration, "migration");
            Check.NotNull(contextType, "contextType");
            Check.NotNull(stringBuilder, "stringBuilder");

            foreach (var ns in GetMetadataNamespaces(migration, contextType).OrderBy(n => n).Distinct())
            {
                stringBuilder
                .Append("using ")
                .Append(ns)
                .AppendLine(";");
            }

            stringBuilder
            .AppendLine()
            .Append("namespace ")
            .AppendLine(@namespace)
            .AppendLine("{");

            using (stringBuilder.Indent())
            {
                stringBuilder
                .Append("[ContextType(typeof(")
                .Append(contextType.GetNestedName())
                .AppendLine("))]")
                .Append("public partial class ")
                .Append(className)
                .AppendLine(" : IMigrationMetadata")
                .AppendLine("{");

                using (stringBuilder.Indent())
                {
                    GenerateMigrationProperty(
                        "string IMigrationMetadata.MigrationId",
                        () => stringBuilder
                        .Append("return ")
                        .Append(GenerateLiteral(migration.MigrationId))
                        .Append(";"),
                        stringBuilder);

                    stringBuilder.AppendLine().AppendLine();

                    GenerateMigrationProperty(
                        "string IMigrationMetadata.ProductVersion",
                        () => stringBuilder
                        .Append("return ")
                        .Append(GenerateLiteral(migration.ProductVersion))
                        .Append(";"),
                        stringBuilder);

                    stringBuilder.AppendLine().AppendLine();

                    GenerateMigrationProperty(
                        "IModel IMigrationMetadata.TargetModel",
                        () => ModelCodeGenerator.Generate(migration.TargetModel, stringBuilder),
                        stringBuilder);
                }

                stringBuilder
                .AppendLine()
                .Append("}");
            }

            stringBuilder
            .AppendLine()
            .Append("}");
        }
예제 #11
0
 public MigrationException(string message, Exception innerException, MigrationInfo migrationInfo)
     : base(message, innerException)
 {
     MigrationInfo = migrationInfo;
 }
예제 #12
0
        private static void Draw(List<MigrationInfo> migrationsInOrder, MigrationInfo current)
        {
            Console.WriteLine();

            foreach (var mi in migrationsInOrder)
            {
                ConsoleColor color = current == mi ? ConsoleColor.Green :
                    mi.FileName != null && mi.IsExecuted ? ConsoleColor.DarkGreen :
                    mi.FileName == null && mi.IsExecuted ? ConsoleColor.Red :
                    mi.FileName != null && !mi.IsExecuted ? ConsoleColor.White :
                    new InvalidOperationException().Throw<ConsoleColor>();


                SafeConsole.WriteColor(color,  
                    mi.IsExecuted?  "- " : 
                    current == mi ? "->" : 
                                    "  ");
                
                SafeConsole.WriteColor(color, mi.Version);
                SafeConsole.WriteLineColor(mi.FileName == null ? ConsoleColor.Red: ConsoleColor.Gray, " " + mi.Comment);
            }

            Console.WriteLine();
        }
        public void Down(MigrationInfo migrationToExecute)
        {
            var migrationObject = Activator.CreateInstance(Type.GetType(migrationToExecute.MigrationClassName), new object[] { ApplicationContext.DatabaseContext.SqlSyntax, Logger }) as MigrationBase;

            migrationObject.Down();
        }
        public void ConstructingShouldRetainTransactionBehaviorDefault()
        {
            MigrationInfo migrationinfo = Create(TransactionBehavior.Default);

            migrationinfo.TransactionBehavior.ShouldBe(TransactionBehavior.Default);
        }
        public void ConstructingShouldRetainValueOfVersion()
        {
            MigrationInfo migrationinfo = Create();

            migrationinfo.Version.ShouldBe(_expectedVersion);
        }
예제 #16
0
        public virtual MigrationCode GenerateMigration(MigrationInfo migrationInfo)
        {
            //var assembly = Assembly.LoadFrom((migrationInfo.ContextAssemblyPath
            //    + "\\KS.Dynamic.Migration_r3.dll").Replace(@"\\", @"\"));
            //var type = assembly.GetType("KS.Dynamic.Migration.EntityFramework.Migration");

            //// Get the constructor and create an instance of MagicClass

            ////Type magicType = Type.GetType("MagicClass");
            //ConstructorInfo magicConstructor = type.GetConstructor(Type.EmptyTypes);
            //object magicClassObject = magicConstructor.Invoke(new object[] { });

            //// Get the ItsMagic method and invoke with a parameter value of 100

            //MethodInfo magicMethod = type.GetMethod("GenerateMigration");
            //object magicValue = magicMethod.Invoke(magicClassObject, new object[] { migrationInfo });


            //return (MigrationCode) magicValue;

            var infos    = new StringBuilder();
            var warnings = new StringBuilder();
            var verbose  = new StringBuilder();

            //connection:connectionString, NameSpaceQualifiedConnectionType:for example :"System.Data.SqlClient"
            var connectionStringInfo = new DbConnectionInfo(migrationInfo.Connection,
                                                            migrationInfo.NameSpaceQualifiedConnectionType);

            var toolingFacade = new ToolingFacade(
                migrationInfo.ContextAssemblyName,   //"MyDll",   // MigrationAssemblyName. In this case dll should be located in "C:\\Temp\\MigrationTest" dir
                migrationInfo.ContextAssemblyName,   //"MyDll",  // ContextAssemblyName. Same as above
                migrationInfo.ConfigurationTypeName, //KS.ObjectiveDataAccess.ContentManagementDbContextMigrations.Configuration
                migrationInfo.ContextAssemblyPath,   //"C:\\Temp\\MigrationTest",   // Where the dlls are located
                migrationInfo.WebConfigPath,         //"C:\\Temp\\MigrationTest\\App.config", // Insert the right directory and change with Web.config if required
                migrationInfo.AppDataPath,           //"C:\\Temp\\App_Data",
                connectionStringInfo)
            {
                LogInfoDelegate    = s => { infos.AppendLine($"Infos : {s} . <br>"); },
                LogWarningDelegate = s => { warnings.AppendLine($"Warning : {s} . <br>"); },
                LogVerboseDelegate = s => { verbose.AppendLine($"Verbose : {s} . <br>"); }
            };



            ScaffoldedMigration scaffoldedMigration = toolingFacade
                                                      .Scaffold(migrationInfo.TargetName,
                                                                migrationInfo.Language == GlobalVarioable.SourceType.Csharp ?
                                                                CSharp : VisualBasic, migrationInfo.ContextAssemblyRootNameSpace, false);


            var designCode = scaffoldedMigration.DesignerCode.Insert(
                scaffoldedMigration.DesignerCode.IndexOf("private readonly ResourceManager Resources", StringComparison.Ordinal), "//");

            return(new MigrationCode()
            {
                DesignerCode = designCode.Replace("Resources.GetString(\"Target\")", "\"" + scaffoldedMigration.Resources["Target"] + "\""),
                UserCode = scaffoldedMigration.UserCode,
                Resources = scaffoldedMigration.Resources,
                MigrationId = scaffoldedMigration.MigrationId,
                Infos = infos.ToString(),
                Warnings = warnings.ToString(),
                Verbose = verbose.ToString()
            });

            //using (var db = new KS.DataAccess.Contexts.SecurityContext())
            //{
            //    var services = ((IInfrastructure<IServiceProvider>)db).Instance;
            //    var codeHelper = new CSharpHelper();
            //    var scaffolder = ActivatorUtilities.CreateInstance<MigrationsScaffolder>(
            //        services,
            //        new CSharpMigrationsGenerator(
            //            codeHelper,
            //            new CSharpMigrationOperationGenerator(codeHelper),
            //            new CSharpSnapshotGenerator(codeHelper)));

            //    var migration = scaffolder.ScaffoldMigration(
            //        "MyMigration",
            //        "MyApp.Data");

            //    File.WriteAllText(
            //        migration.MigrationId + migration.FileExtension,
            //        migration.MigrationCode);
            //    File.WriteAllText(
            //        migration.MigrationId + ".Designer" + migration.FileExtension,
            //        migration.MetadataCode);
            //    File.WriteAllText(
            //        migration.SnapshotName + migration.FileExtension,
            //        migration.SnapshotCode);
            //}
        }
        public void Generate_migration_metadata_class()
        {
            var model      = new Model();
            var entityType = model.AddEntityType("Entity");

            entityType.GetOrSetPrimaryKey(entityType.GetOrAddProperty("Id", typeof(int), shadowProperty: true));

            var migration
                = new MigrationInfo("000000000000001_Name", "1.2.3.4")
                {
                TargetModel = model
                };

            var codeGenerator = new CSharpMigrationCodeGenerator(new CSharpModelCodeGenerator());
            var stringBuilder = new IndentedStringBuilder();

            codeGenerator.GenerateMigrationMetadataClass("MyNamespace", "MyClass", migration, typeof(MyContext), stringBuilder);

            Assert.Equal(
                @"using Microsoft.Data.Entity;
using Microsoft.Data.Entity.Commands.Tests.Migrations;
using Microsoft.Data.Entity.Metadata;
using Microsoft.Data.Entity.Migrations.Infrastructure;
using System;

namespace MyNamespace
{
    [ContextType(typeof(Microsoft.Data.Entity.Commands.Tests.Migrations.CSharpMigrationCodeGeneratorTest.MyContext))]
    public partial class MyClass : IMigrationMetadata
    {
        string IMigrationMetadata.MigrationId
        {
            get
            {
                return ""000000000000001_Name"";
            }
        }
        
        string IMigrationMetadata.ProductVersion
        {
            get
            {
                return ""1.2.3.4"";
            }
        }
        
        IModel IMigrationMetadata.TargetModel
        {
            get
            {
                var builder = new BasicModelBuilder();
                
                builder.Entity(""Entity"", b =>
                    {
                        b.Property<int>(""Id"");
                        b.Key(""Id"");
                    });
                
                return builder.Model;
            }
        }
    }
}",
                stringBuilder.ToString());
        }
 public override void RemoveVersion(MigrationInfo migrationInfo)
 {
     base.RemoveVersion(migrationInfo);
     RaiseOnUpdateVersion(migrationInfo.Version);
 }
 protected abstract DbCommand GetWriteMigrationAppliedDataCommand(MigrationInfo migrationInfo,
                                                                  DbConnection connection);
        private static void Draw(List<MigrationInfo> migrationsInOrder, MigrationInfo current)
        {
            Console.WriteLine();

            foreach (var mi in migrationsInOrder)
            {
                ConsoleColor color = mi.IsExecuted ? ConsoleColor.DarkGreen :
                                     current == mi ? ConsoleColor.Green :
                                     ConsoleColor.White;


                SafeConsole.WriteColor(color,  
                    mi.IsExecuted?  "- " : 
                    current == mi ? "->" : 
                                    "  ");
                
                SafeConsole.WriteColor(color, mi.Version);
                Console.WriteLine(" " + mi.Comment);
            }

            Console.WriteLine();
        }
        private static void Execute(MigrationInfo mi, bool autoRun)
        {
            string title = mi.Version + (mi.Comment.HasText() ? " ({0})".FormatWith(mi.Comment) : null);

            string databaseName = Connector.Current.DatabaseName();

            using (Connector.CommandTimeoutScope(Timeout))
            using (Transaction tr = new Transaction())
            {
                string text = File.ReadAllText(mi.FileName);

                text = text.Replace(DatabaseNameReplacement, databaseName);

                var parts = Regex.Split(text, "GO\r?\n", RegexOptions.IgnoreCase);

                int pos = 0;

                try
                {   
                    for (pos = 0; pos < parts.Length; pos++)
			        {
                        if (autoRun)
                            Executor.ExecuteNonQuery(parts[pos]);
                        else
                            SafeConsole.WaitExecute("Executing {0} [{1}/{2}]".FormatWith(title, pos + 1, parts.Length), () => Executor.ExecuteNonQuery(parts[pos]));
			        }
                }
                catch (SqlException e)
                {
                    Console.WriteLine();
                    Console.WriteLine();

                    var list = text.Lines();

                    var lineNumer = (e.LineNumber - 1) + pos + parts.Take(pos).Sum(a => a.Lines().Length);

                    SafeConsole.WriteLineColor(ConsoleColor.Red, "ERROR:");

                    var min = Math.Max(0, lineNumer - 20);
                    var max = Math.Min(list.Length - 1, lineNumer + 20);

                    if (min > 0)
                        Console.WriteLine("...");

                    for (int i = min; i <= max; i++)
                    {
                        Console.Write(i + ": ");
                        SafeConsole.WriteLineColor(i == lineNumer ? ConsoleColor.Red : ConsoleColor.DarkRed, list[i]);
                    }

                    if (max < list.Length - 1)
                        Console.WriteLine("...");

                    Console.WriteLine();
                    SafeConsole.WriteLineColor(ConsoleColor.DarkRed, e.GetType().Name + (e is SqlException ? " (Number {0}): ".FormatWith(((SqlException)e).Number) : ": "));
                    SafeConsole.WriteLineColor(ConsoleColor.Red, e.Message);

                    Console.WriteLine();

                    throw new MigrationException();
                }

                SqlMigrationEntity m = new SqlMigrationEntity
                {
                    VersionNumber = mi.Version,
                }.Save();

                mi.IsExecuted = true;

                tr.Commit();
            }
        }
예제 #22
0
 public override void RemoveVersion(MigrationInfo migrationInfo)
 {
     base.RemoveVersion(migrationInfo);
     OnUpdateVersion?.Invoke(migrationInfo.Version);
 }
예제 #23
0
 public abstract void GenerateMigrationMetadataClass(
     [NotNull] string @namespace,
     [NotNull] string className,
     [NotNull] MigrationInfo migration,
     [NotNull] Type contextType,
     [NotNull] IndentedStringBuilder stringBuilder);
 public override void InsertVersion(MigrationInfo migrationInfo)
 {
     base.InsertVersion(migrationInfo);
     RaiseOnUpdateVersion(migrationInfo.Version);
 }
		public override void Migrate(string sourceFilePath, string destinationFilePath)
		{
			string sourceFileName = Path.GetFileName(sourceFilePath);

			var writingSystemDefinitionV0 = new WritingSystemDefinitionV0();
			new LdmlAdaptorV0().Read(sourceFilePath, writingSystemDefinitionV0);

			var rfcHelper = new Rfc5646TagCleaner(
				writingSystemDefinitionV0.ISO639,
				writingSystemDefinitionV0.Script,
				writingSystemDefinitionV0.Region,
				writingSystemDefinitionV0.Variant,
				"");

			rfcHelper.Clean();

			var writingSystemDefinitionV1 = new WritingSystemDefinitionV1
				{
					DefaultFontName = writingSystemDefinitionV0.DefaultFontName,
					Abbreviation = writingSystemDefinitionV0.Abbreviation,
					DefaultFontSize = writingSystemDefinitionV0.DefaultFontSize,
					IsUnicodeEncoded = !writingSystemDefinitionV0.IsLegacyEncoded,
					Keyboard = writingSystemDefinitionV0.Keyboard,
					LanguageName = writingSystemDefinitionV0.LanguageName,
					RightToLeftScript = writingSystemDefinitionV0.RightToLeftScript,
					SortRules = writingSystemDefinitionV0.SortRules,
					SortUsing = (WritingSystemDefinitionV1.SortRulesType)writingSystemDefinitionV0.SortUsing,
					SpellCheckingId = writingSystemDefinitionV0.SpellCheckingId,
					VersionDescription = writingSystemDefinitionV0.VersionDescription,
					DateModified = DateTime.Now
				};

			writingSystemDefinitionV1.SetAllComponents(
				rfcHelper.Language,
				rfcHelper.Script,
				rfcHelper.Region,
				ConcatenateVariantAndPrivateUse(rfcHelper.Variant, rfcHelper.PrivateUse)
			);
			_writingSystemsV1[sourceFileName] = writingSystemDefinitionV1;
			//_migratedWs.VerboseDescription //not written out by LdmlAdaptorV1 - flex?
			//_migratedWs.NativeName //not written out by LdmlAdaptorV1 - flex?);

			// Record the details for use in PostMigrate where we change the file name to match the rfc tag where we can.
			var migrationInfo = new MigrationInfo
				{
					FileName = sourceFileName,
					RfcTagBeforeMigration = writingSystemDefinitionV0.Rfc5646,
					RfcTagAfterMigration = writingSystemDefinitionV1.Bcp47Tag
				};
			_migrationInfo.Add(migrationInfo);
		}
 public override void RemoveVersion(MigrationInfo migrationInfo)
 {
     base.RemoveVersion(migrationInfo);
     RaiseOnUpdateVersion(migrationInfo.Version);
 }
        public void ConstructingShouldRetainMigration()
        {
            MigrationInfo migrationinfo = Create();

            migrationinfo.Migration.ShouldBeSameAs(_migration);
        }
예제 #28
0
        public void when_target_environment_is_not_provided_then_there_are_no_errors()
        {
            var migrationInfo = new MigrationInfo(direction: MigrationDirection.Up, scriptFolder: Some.String(), targetSchema: "testSchema",
                targetTablespace: "testTablespace", targetEnvironment: null, targetVersion: null);

            Assert.DoesNotThrow(() => _migrator.Migrate(Some.ConnectionInfo(), migrationInfo));
        }
        public void ConstructingShouldRetainTransactionBehaviorNone()
        {
            MigrationInfo migrationinfo = Create(TransactionBehavior.None);

            migrationinfo.TransactionBehavior.ShouldBe(TransactionBehavior.None);
        }
        public void TraitMethodReturnsNullForNonExistentTrait()
        {
            MigrationInfo migrationinfo = Create();

            migrationinfo.Trait("foo").ShouldBeNull();
        }
        public void HasTraitReturnsFalseWhenTraitIsNotDefined()
        {
            MigrationInfo migrationinfo = Create();

            migrationinfo.HasTrait("foo").ShouldBeFalse();
        }
예제 #32
0
 public MigrationPlanStep(Direction down, MigrationInfo migrationInfo, bool shouldUpdateVersion = true)
 {
     Direction           = down;
     MigrationInfo       = migrationInfo;
     ShouldUpdateVersion = shouldUpdateVersion;
 }
예제 #33
0
        /// <summary>
        /// Look through all the GUIDs, compare it to the MigrationInfoList, and do migration when necessary
        /// </summary>
        private static IEnumerable <ResolveInfo> MigrateGUID(IEnumerable <ResolveInfo> extInfo, string characterName)
        {
            List <ResolveInfo> extInfoNew = new List <ResolveInfo>();
            bool DidBlankGUIDMessage      = false;

            try
            {
                if (extInfo == null)
                {
                    return(extInfo);
                }

                foreach (ResolveInfo resolveInfo in extInfo)
                {
                    if (resolveInfo.GUID.IsNullOrEmpty())
                    {
                        //Don't add empty GUID to the new list, this way CompatibilityResolve will treat it as a hard mod and attempt to find a match
                        if (!DidBlankGUIDMessage) //No need to spam it for every single thing
                        {
                            Logger.Log(LogLevel.Warning | LogLevel.Message, $"[{characterName}] Blank GUID detected, attempting Compatibility Resolve");
                            DidBlankGUIDMessage = true;
                        }
                    }
                    else
                    {
                        string propertyWithoutPrefix = resolveInfo.Property;

                        //Remove outfit and accessory prefixes for searching purposes
                        if (propertyWithoutPrefix.StartsWith("outfit"))
                        {
                            propertyWithoutPrefix = propertyWithoutPrefix.Remove(0, propertyWithoutPrefix.IndexOf('.') + 1);
                        }
                        if (propertyWithoutPrefix.StartsWith("accessory"))
                        {
                            propertyWithoutPrefix = propertyWithoutPrefix.Remove(0, propertyWithoutPrefix.IndexOf('.') + 1);
                        }

                        MigrationInfo info = MigrationInfoList.Where(x => (x.Property == propertyWithoutPrefix && x.OldID == resolveInfo.Slot && x.OldGUID == resolveInfo.GUID) ||
                                                                     (x.Property == "*" && x.OldGUID == resolveInfo.GUID) ||
                                                                     (x.Property == "-" && x.OldGUID == resolveInfo.GUID)).FirstOrDefault();
                        if (info == null)
                        {
                            //This item does not need to be migrated
                            extInfoNew.Add(resolveInfo);
                        }
                        else if (info.Property == "*") //* assumes only the GUID changed while the IDs stayed the same
                        {
                            ResolveInfo GUIDCheckOld = UniversalAutoResolver.LoadedResolutionInfo.FirstOrDefault(x => x.GUID == resolveInfo.GUID);

                            if (GUIDCheckOld == null)
                            {
                                //We do not have the old mod installed, do migration. Whether we have the new mod is irrelevant.
                                //If we don't have the new mod the user will get a missing mod warning for the new mod since they should be using that instead.
                                //If we do it will load correctly.
                                Logger.Log(LogLevel.Info, $"Migrating GUID {info.OldGUID} -> {info.NewGUID}");
                                ResolveInfo resolveInfoNew = new ResolveInfo();
                                resolveInfoNew      = resolveInfo;
                                resolveInfoNew.GUID = info.NewGUID;
                                extInfoNew.Add(resolveInfoNew);
                            }
                            else
                            {
                                ResolveInfo GUIDCheckNew = UniversalAutoResolver.LoadedResolutionInfo.FirstOrDefault(x => x.GUID == info.NewGUID);

                                if (GUIDCheckNew == null)
                                {
                                    //We have the old mod but not the new, do not do migration
                                    extInfoNew.Add(resolveInfo);
                                }
                                else
                                {
                                    //We have the old mod and the new, do migration so characters save with the new stuff
                                    Logger.Log(LogLevel.Info, $"Migrating GUID {info.OldGUID} -> {info.NewGUID}");
                                    ResolveInfo resolveInfoNew = new ResolveInfo();
                                    resolveInfoNew      = resolveInfo;
                                    resolveInfoNew.GUID = info.NewGUID;
                                    extInfoNew.Add(resolveInfoNew);
                                }
                            }
                        }
                        else if (info.Property == "-") //- indicates the entry needs to be stripped of its extended data and loaded as a hard mod
                        {
                            continue;
                        }
                        else
                        {
                            ResolveInfo intResolveOld = UniversalAutoResolver.LoadedResolutionInfo.FirstOrDefault(x => x.Property == propertyWithoutPrefix && x.Slot == resolveInfo.Slot && x.GUID == resolveInfo.GUID);

                            if (intResolveOld == null)
                            {
                                //We do not have the old mod installed, do migration. Whether we have the new mod is irrelevant.
                                //If we don't have the new mod the user will get a missing mod warning for the new mod since they should be using that instead.
                                //If we do it will load correctly.
                                Logger.Log(LogLevel.Info, $"Migrating {info.OldGUID}:{info.OldID} -> {info.NewGUID}:{info.NewID}");
                                ResolveInfo resolveInfoNew = new ResolveInfo();
                                resolveInfoNew      = resolveInfo;
                                resolveInfoNew.GUID = info.NewGUID;
                                resolveInfoNew.Slot = info.NewID;
                                extInfoNew.Add(resolveInfoNew);
                            }
                            else
                            {
                                ResolveInfo intResolveNew = UniversalAutoResolver.LoadedResolutionInfo.FirstOrDefault(x => x.Property == propertyWithoutPrefix && x.Slot == info.NewID && x.GUID == info.NewGUID);

                                if (intResolveNew == null)
                                {
                                    //We have the old mod but not the new, do not do migration
                                    extInfoNew.Add(resolveInfo);
                                }
                                else
                                {
                                    //We have the old mod and the new, do migration so characters save with the new stuff
                                    Logger.Log(LogLevel.Warning, $"Migrating {info.OldGUID}:{info.OldID} -> {info.NewGUID}:{info.NewID}");
                                    ResolveInfo b = new ResolveInfo();
                                    b      = resolveInfo;
                                    b.GUID = info.NewGUID;
                                    b.Slot = info.NewID;
                                    extInfoNew.Add(b);
                                }
                            }
                        }
                    }
                }
                extInfo = extInfoNew;
            }
            catch (Exception ex)
            {
                //If something goes horribly wrong, return the original extInfo
                Logger.Log(LogLevel.Error, $"GUID migration cancelled due to error: {ex}");
                return(extInfo);
            }

            return(extInfoNew);
        }
예제 #34
0
        public virtual async Task UpsertMigrationInfoAsync(IMigrationContext context, MigrationInfo info)
        {
            var db = await EnsureDbHasBeenInitialized(context);

            long   migrationInfoId = 0;
            string insertQuery     = $@"INSERT INTO {PostgreSqlConstants.MigrationInfoTableName}(
                                        Name,
                                        MigrationCompleted,
                                        TotalMigrationTimeInMs,
                                        CompletedAtUtc) 
                                   VALUES (
                                        @Name,
                                        @MigrationCompleted,
                                        @TotalMigrationTimeInMs,
                                        @CompletedAtUtc)
                                   ON CONFLICT (name)
                                   DO UPDATE SET
                                        Name = @Name,
                                        MigrationCompleted = @MigrationCompleted,
                                        TotalMigrationTimeInMs = @TotalMigrationTimeInMs,
                                        CompletedAtUtc = @CompletedAtUtc
                                   RETURNING id";

            using (var reader = await db.ExecuteReaderAsync(insertQuery, new
            {
                Name = info.Name,
                MigrationCompleted = info.MigrationCompleted,
                TotalMigrationTimeInMs = info.TotalMigrationTimeInMs,
                CompletedAtUtc = info.CompletedAtUtc
            }))
            {
                while (reader.Read())
                {
                    migrationInfoId = reader.GetInt64(0);
                }
            }
            foreach (var stepName in info.StepsCompleted)
            {
                string completedStepInsertQuery = $@"INSERT INTO {PostgreSqlConstants.CompletedStepsTableName}(
                                        StepName,
                                        MigrationInfoId)
                                   VALUES (
                                        @StepName,
                                        @MigrationInfoId)
                                   ON CONFLICT (StepName, MigrationInfoId)
                                   DO NOTHING
                                    ";

                await db.ExecuteAsync(completedStepInsertQuery, new
                {
                    StepName        = stepName,
                    MigrationInfoId = migrationInfoId
                });
            }
        }