public void IsMigrationItemEqualsToHistory() { //arrange var step = new TestStep(ExecutionResult.Success); var positiveCaseStepName = MigrationHandler.StepIdentity(step); var positiveCaseVersion = new Version("1.2.3.4"); var negativeCaseVersion = new Version("4.3.2.1"); var migrationItem = new MigrationItem(positiveCaseVersion, new TestStep(ExecutionResult.Success)); var migrationHistory = new MigrationHistory { Name = positiveCaseStepName, Version = positiveCaseVersion.ToString() }; //act var positiveCase = MigrationHandler.IsMigrationItemEqualsToHistory(migrationItem, migrationHistory); migrationHistory.Version = negativeCaseVersion.ToString(); var negativeCase1 = MigrationHandler.IsMigrationItemEqualsToHistory(migrationItem, migrationHistory); migrationHistory.Version = positiveCaseVersion.ToString(); migrationHistory.Name = String.Empty; var negativeCase2 = MigrationHandler.IsMigrationItemEqualsToHistory(migrationItem, migrationHistory); //assert Assert.True(positiveCase && !negativeCase1 && !negativeCase2); }
static void Main(string[] args) { ConfigureSerilog(); AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; var result = CommandLine.Parser.Default.ParseArguments <Options>(args) .WithParsed <Options>(opts => options = opts) .WithNotParsed <Options>((errs) => HandleParseError(errs)); if (result.Tag != ParserResultType.Parsed) { Log.Logger.Error("Command line parameters error, press a key to continue!"); Console.ReadKey(); return; } Connection connection = new Connection(options.ServiceAddress, options.GetAccessToken()); var importer = new WorkItemImporter(connection, options.OriginalIdField, options.TeamProject); //test one item MigrationItem mi = new MigrationItem(); mi.OriginalId = "AA123"; mi.WorkItemDestinationType = "Product Backlog Item"; mi.AddVersion(new MigrationItemVersion() { AuthorEmail = "*****@*****.**", Description = "Description", Title = "Title test", VersionTimestamp = new DateTime(2010, 01, 23, 22, 10, 32), }); mi.AddVersion(new MigrationItemVersion() { AuthorEmail = "*****@*****.**", Description = "Description", Title = "Title Modified", VersionTimestamp = new DateTime(2011, 01, 23, 22, 10, 32), }); mi.AddVersion(new MigrationItemVersion() { AuthorEmail = "*****@*****.**", Description = "Description", Title = "Title Modified Again", VersionTimestamp = new DateTime(2012, 01, 23, 22, 10, 32), }); var importResult = importer.ImportWorkItemAsync(mi).Result; Log.Information("import result: {importResult}", importResult); if (Environment.UserInteractive) { Console.WriteLine("Execution completed, press a key to continue"); Console.ReadKey(); } }
public async Task <Boolean> ImportWorkItemAsync(MigrationItem itemToMigrate) { var existingWorkItem = GetWorkItem(itemToMigrate.OriginalId); if (existingWorkItem != null) { Log.Information("A workitem with originalId {originalId} already exists, it will be deleted", itemToMigrate.OriginalId); connection.WorkItemStore.DestroyWorkItems(new[] { existingWorkItem.Id }); } WorkItem workItem = CreateWorkItem(itemToMigrate); if (workItem == null) { return(false); } //now that we have work item, we need to start creating all the versions for (int i = 0; i < itemToMigrate.Versions.Count(); i++) { var version = itemToMigrate.GetVersionAt(i); workItem.Fields["System.ChangedDate"].Value = version.VersionTimestamp; workItem.Fields["System.ChangedBy"].Value = version.AuthorEmail; if (i == 0) { workItem.Fields["System.CreatedBy"].Value = version.AuthorEmail; workItem.Fields["System.CreatedDate"].Value = version.VersionTimestamp; } workItem.Title = version.Title; workItem.Description = version.Description; var validation = workItem.Validate(); if (validation.Count > 0) { Log.Error("N°{errCount} validation errors for work Item {workItemId} originalId {originalId}", validation.Count, workItem.Id, itemToMigrate.OriginalId); foreach (Field error in validation) { Log.Error("Version {version}: We have validation error for work Item {workItemId} originalId {originalId} - Field: {name} ErrorStatus {errorStatus} Value {value}", i, workItem.Id, itemToMigrate.OriginalId, error.Name, error.Status, error.Value); } return(false); } workItem.Save(); if (i == 0) { Log.Information("Saved for the first time Work Item for type {workItemType} with id {workItemId} related to original id {originalId}", workItem.Type.Name, workItem.Id, itemToMigrate.OriginalId); } else { Log.Debug("Saved iteration {i} for original id {originalId}", i, itemToMigrate.OriginalId); } } return(true); }
private static void AddSongOfHealing(List <string> lines) { lines[0] = "-version 4"; var newItems = new MigrationItem[] { new MigrationItem { ID = 90 } }; var itemNames = new string[] { "Song of Healing" }; for (var i = 0; i < lines.Count; i++) { var line = lines[i]; if (line.StartsWith("-") || string.IsNullOrWhiteSpace(line)) { continue; } var updatedItemSections = line .Split(';') .Select(section => section.Split(',').Select(id => { var itemId = int.Parse(id); if (itemId >= 90) { itemId += newItems.Length; } return(itemId); }).ToList()).ToList(); lines[i] = string.Join(";", updatedItemSections.Select(section => string.Join(",", section))); } foreach (var item in newItems) { lines.Insert(item.ID * 5 + 1, $"- {itemNames[item.ID - 90]}"); lines.Insert(item.ID * 5 + 2, string.Join(",", item.DependsOnItems)); lines.Insert(item.ID * 5 + 3, string.Join(";", item.Conditionals.Select(c => string.Join(",", c)))); lines.Insert(item.ID * 5 + 4, "0"); lines.Insert(item.ID * 5 + 5, "0"); } var requireSongOfHealing = new int[] { 83, 84, 88, 89 }; // kamaro, gidbo, goron, zora masks foreach (var id in requireSongOfHealing) { lines[id * 5 + 2] = lines[id * 5 + 2].Length == 0 ? "90" : "90," + lines[id * 5 + 2]; } }
public void ApplyPermissionMigration() { var migrationVersion = new Version("1.3"); var stepIdentity = typeof(SetupDefaultMemberGroupsPermissionsStep).Name; if (!_migrationHistoryService.Exists(stepIdentity, migrationVersion)) { var step = DependencyResolver.Current.GetService <SetupDefaultMemberGroupsPermissionsStep>(); var migrationItem = new MigrationItem(migrationVersion, step); var(executionHistory, executionResult) = MigrationHandler.TryExecuteSteps(migrationItem.AsEnumerableOfOne()); if (executionResult.Type is ExecutionResultType.Success) { _migrationHistoryService.Create(MigrationHandler.ToMigrationHistory(executionHistory)); } } }
private static void AddIkanaScrubGoldRupee(List <string> lines) { lines[0] = "-version 5"; var newItems = new MigrationItem[] { new MigrationItem { ID = 256, DependsOnItems = new List <int> { 110, 89, 32 } // east access, zora mask, ocean deed } }; var itemNames = new string[] { "Ikana Scrub Gold Rupee" }; for (var i = 0; i < lines.Count; i++) { var line = lines[i]; if (line.StartsWith("-") || string.IsNullOrWhiteSpace(line)) { continue; } var updatedItemSections = line .Split(';') .Select(section => section.Split(',').Select(id => { var itemId = int.Parse(id); if (itemId >= 256) { itemId += newItems.Length; } return(itemId); }).ToList()).ToList(); lines[i] = string.Join(";", updatedItemSections.Select(section => string.Join(",", section))); } foreach (var item in newItems) { lines.Insert(item.ID * 5 + 1, $"- {itemNames[item.ID - 256]}"); lines.Insert(item.ID * 5 + 2, string.Join(",", item.DependsOnItems)); lines.Insert(item.ID * 5 + 3, string.Join(";", item.Conditionals.Select(c => string.Join(",", c)))); lines.Insert(item.ID * 5 + 4, "0"); lines.Insert(item.ID * 5 + 5, "0"); } }
private Task MigrateAsync(MigrationItem item) { _logger.LogTrace("{migrationKey} migration coming", item.MigrationKey); if (_tasks.TryGetValue(item.MigrationKey, out var task)) { _logger.LogTrace("{migrationKey} task found", item.MigrationKey); if (!NeedRestart(task)) { _logger.LogTrace("{migrationKey} no need restart. current status : {status}", item.MigrationKey, task.Status); return(task.ContinueWith(UpdateTcs)); } } _logger.LogInformation("{migrationKey} has not started, try to run it", item.MigrationKey); _tasks[item.MigrationKey] = item.Tcs.Task; var migration = item.Migration; void UpdateTcs(Task migrationTask) { if (migrationTask.IsCompletedSuccessfully) { _logger.LogTrace("{migrationKey} success", item.MigrationKey); item.Tcs.SetResult(0); } else { if (migrationTask.IsFaulted) { _logger.LogDebug("{migrationKey} failed", item.MigrationKey); item.Tcs.SetException(migrationTask.Exception.InnerException); } else { _logger.LogDebug("{migrationKey} canceled", item.MigrationKey); item.Tcs.SetCanceled(); } } } return(migration.MigrateAsync() .ContinueWith(UpdateTcs));
private string ParseMigrationItem(MigrationItem item) { bool key = item.Name == "Id"; // column switches var switches = ""; if (key) { switches += ".PrimaryKey().Identity()"; } if (item.SuggestedType == "string" && item.Length != 0) { switches += ".WithLength(" + item.Length + ")"; } if (item.Nullable) { switches += ".Nullable()"; } if (item.NotNull && !item.Nullable) { switches += ".NotNull()"; } if (!String.IsNullOrEmpty(item.WithDefault)) { if (item.SuggestedType == "string") { switches += ".WithDefault(\"" + item.WithDefault + "\")"; } else { switches += ".WithDefault(" + item.WithDefault + ")"; } } var line = String.Format(".Column<{0}>(\"{1}\"{2}{3})", item.SuggestedType, item.SuggestedName, String.IsNullOrEmpty(switches) ? "" : ", c => c", switches); return(line); }
private WorkItem CreateWorkItem(MigrationItem migrationItem) { WorkItemType type = null; try { type = teamProject.WorkItemTypes[migrationItem.WorkItemDestinationType]; } catch (WorkItemTypeDeniedOrNotExistException) { }//ignore the exception will be logged if (type == null) { Log.Error("Unable to find work item type {WorkItemDestinationType}", migrationItem.WorkItemDestinationType); return(null); } WorkItem workItem = new WorkItem(type); Log.Information("Created Work Item for type {workItemType} related to original id {originalId}", workItem.Type.Name, migrationItem.OriginalId); //now start creating basic value that we need, like the original id workItem[fieldWithOriginalId] = migrationItem.OriginalId; return(workItem); }
private static void AddMagicRequirements(List <string> lines) { lines[0] = "-version 8"; var newItems = new MigrationItem[] { new MigrationItem { ID = 278, Conditionals = new List <List <int> > { new List <int> { 11 }, new List <int> { 13 }, } }, }; var itemNames = new string[] { "Magic Meter" }; for (var i = 0; i < lines.Count; i++) { var line = lines[i]; if (line.StartsWith("-") || string.IsNullOrWhiteSpace(line)) { continue; } var updatedItemSections = line .Split(';') .Select(section => section.Split(',').Select(id => { var itemId = int.Parse(id); if (itemId >= 278) { itemId += newItems.Length; } return(itemId); }).ToList()).ToList(); lines[i] = string.Join(";", updatedItemSections.Select(section => string.Join(",", section))); } foreach (var item in newItems) { lines.Insert(item.ID * 5 + 1, $"- {itemNames[item.ID - 278]}"); lines.Insert(item.ID * 5 + 2, string.Join(",", item.DependsOnItems)); lines.Insert(item.ID * 5 + 3, string.Join(";", item.Conditionals.Select(c => string.Join(",", c)))); lines.Insert(item.ID * 5 + 4, "0"); lines.Insert(item.ID * 5 + 5, "0"); } var requireMagic = new int[] { 2, 3, 4, 9 }; // fire arrow, ice arrow, light arrow, lens of truth for (var i = 0; i < lines.Count; i++) { if (i % 5 != 2 && i % 5 != 3) { continue; } var line = lines[i]; if (line.StartsWith("-") || string.IsNullOrWhiteSpace(line)) { continue; } var updatedItemSections = line .Split(';') .Select(section => { if (section.Split(',').Select(int.Parse).Intersect(requireMagic).Any()) { section += ",278"; } return(section); }).ToList(); lines[i] = string.Join(";", updatedItemSections.Select(section => string.Join(",", section))); } }
private static void AddGreatFairies(List <string> lines) { lines[0] = "-version 7"; var newItems = new MigrationItem[] { new MigrationItem { ID = 11, Conditionals = new List <List <int> > { new List <int> { 0 }, new List <int> { 92 }, new List <int> { 93 }, } }, new MigrationItem { ID = 12, DependsOnItems = new List <int> { 104 }, }, new MigrationItem { ID = 13, DependsOnItems = new List <int> { 107 }, }, new MigrationItem { ID = 14, DependsOnItems = new List <int> { 112 }, }, }; var itemNames = new string[] { "Great Fairy Magic Meter", "Great Fairy Spin Attack", "Great Fairy Extended Magic", "Great Fairy Double Defense" }; for (var i = 0; i < lines.Count; i++) { var line = lines[i]; if (line.StartsWith("-") || string.IsNullOrWhiteSpace(line)) { continue; } var updatedItemSections = line .Split(';') .Select(section => section.Split(',').Select(id => { var itemId = int.Parse(id); if (itemId >= 11) { itemId += newItems.Length; } return(itemId); }).ToList()).ToList(); lines[i] = string.Join(";", updatedItemSections.Select(section => string.Join(",", section))); } foreach (var item in newItems) { lines.Insert(item.ID * 5 + 1, $"- {itemNames[item.ID - 11]}"); lines.Insert(item.ID * 5 + 2, string.Join(",", item.DependsOnItems)); lines.Insert(item.ID * 5 + 3, string.Join(";", item.Conditionals.Select(c => string.Join(",", c)))); lines.Insert(item.ID * 5 + 4, "0"); lines.Insert(item.ID * 5 + 5, "0"); } var updateItems = new MigrationItem[] { new MigrationItem { ID = 76, // Great Fairy's Mask // remove requirements } }; foreach (var item in updateItems) { lines[item.ID * 5 + 2] = string.Join(",", item.DependsOnItems); lines[item.ID * 5 + 3] = string.Join(";", item.Conditionals.Select(c => string.Join(",", c))); } }
private static void AddPreClocktownChestLinkTrialChestsAndStartingItems(List <string> lines) { lines[0] = "-version 6"; var newItems = new MigrationItem[] { new MigrationItem { ID = 267, DependsOnItems = new List <int> { 261, 260, 10 } }, new MigrationItem { ID = 268, DependsOnItems = new List <int> { 261, 260, 10 } }, new MigrationItem { ID = 269, DependsOnItems = new List <int> { 261 } }, new MigrationItem { ID = 270, }, new MigrationItem { ID = 271, }, new MigrationItem { ID = 272, }, new MigrationItem { ID = 273, }, }; var itemNames = new string[] { "Link Trial 30 Arrows", "Link Trial 10 Bombchu", "Pre-Clocktown 10 Deku Nuts", "Starting Sword", "Starting Shield", "Starting Heart 1", "Starting Heart 2", }; for (var i = 0; i < lines.Count; i++) { var line = lines[i]; if (line.StartsWith("-") || string.IsNullOrWhiteSpace(line)) { continue; } var updatedItemSections = line .Split(';') .Select(section => section.Split(',').Select(id => { var itemId = int.Parse(id); if (itemId >= 267) { itemId += newItems.Length; } return(itemId); }).ToList()).ToList(); lines[i] = string.Join(";", updatedItemSections.Select(section => string.Join(",", section))); } foreach (var item in newItems) { lines.Insert(item.ID * 5 + 1, $"- {itemNames[item.ID - 267]}"); lines.Insert(item.ID * 5 + 2, string.Join(",", item.DependsOnItems)); lines.Insert(item.ID * 5 + 3, string.Join(";", item.Conditionals.Select(c => string.Join(",", c)))); lines.Insert(item.ID * 5 + 4, "0"); lines.Insert(item.ID * 5 + 5, "0"); } }
private static void AddMoonItems(List <string> lines) { lines[0] = "-version 2"; var newItems = new MigrationItem[] { new MigrationItem { ID = 255, Conditionals = Enumerable.Range(68, 20).Select(i => new List <int> { i }).ToList() }, new MigrationItem { ID = 256, Conditionals = Enumerable.Range(68, 20).Combinations(2).Select(a => a.ToList()).ToList() }, new MigrationItem { ID = 257, Conditionals = Enumerable.Range(68, 20).Combinations(3).Select(a => a.ToList()).ToList() }, new MigrationItem { ID = 258, Conditionals = Enumerable.Range(68, 20).Combinations(4).Select(a => a.ToList()).ToList() }, new MigrationItem { ID = 259, DependsOnItems = new List <int> { 97, 100, 103, 108, 113 } }, new MigrationItem { ID = 260, DependsOnItems = new List <int> { 259, 0, 255 } }, new MigrationItem { ID = 261, DependsOnItems = new List <int> { 259, 88, 256 } }, new MigrationItem { ID = 262, DependsOnItems = new List <int> { 259, 89, 257 } }, new MigrationItem { ID = 263, DependsOnItems = new List <int> { 259, 258, 114, 115, 2, 10 } }, new MigrationItem { ID = 264, DependsOnItems = new List <int> { 259, 0, 88, 89, 114, 115, 2, 10 } .Concat(Enumerable.Range(68, 20)) .ToList() } }; var itemNames = new string[] { "One Mask", "Two Masks", "Three Masks", "Four Masks", "Moon Access", "Deku Trial HP", "Goron Trial HP", "Zora Trial HP", "Link Trial HP", "Fierce Deity's Mask" }; for (var i = 0; i < lines.Count; i++) { var line = lines[i]; if (line.StartsWith("-") || string.IsNullOrWhiteSpace(line)) { continue; } var updatedItemSections = line .Split(';') .Select(section => section.Split(',').Select(id => { var itemId = int.Parse(id); if (itemId >= 255) { itemId += newItems.Length; } return(itemId); }).ToList()).ToList(); lines[i] = string.Join(";", updatedItemSections.Select(section => string.Join(",", section))); } foreach (var item in newItems) { lines.Insert(item.ID * 5 + 1, $"- {itemNames[item.ID - 255]}"); lines.Insert(item.ID * 5 + 2, string.Join(",", item.DependsOnItems)); lines.Insert(item.ID * 5 + 3, string.Join(";", item.Conditionals.Select(c => string.Join(",", c)))); lines.Insert(item.ID * 5 + 4, "0"); lines.Insert(item.ID * 5 + 5, "0"); } }
/// <summary> /// Called when the Generate Migrations command is run /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> private void MigrationsCallback(object sender, EventArgs e) { IntPtr hierarchyPtr, selectionContainerPtr; uint projectItemId; IVsMultiItemSelect mis; IVsMonitorSelection monitorSelection = (IVsMonitorSelection)GetGlobalService(typeof(SVsShellMonitorSelection)); monitorSelection.GetCurrentSelection(out hierarchyPtr, out projectItemId, out mis, out selectionContainerPtr); IVsHierarchy hierarchy = Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)) as IVsHierarchy; if (hierarchy == null) { FireError("F**k knows why but it is broken, sorry"); return; } object projObj; hierarchy.GetProperty(projectItemId, (int)__VSHPROPID.VSHPROPID_ExtObject, out projObj); ProjectItem projItem = projObj as ProjectItem; if (projItem == null) { FireError("The item you have selected is not playing nicely. Apologies"); return; } var project = projItem.ContainingProject; var migrations = new List <Migration>(); var allClasses = GetProjectItems(project.ProjectItems).Where(v => v.Name.Contains(".cs")); // check for .cs extension on each, foreach (var c in allClasses) { var eles = c.FileCodeModel; if (eles == null) { continue; } foreach (var ele in eles.CodeElements) { if (ele is EnvDTE.CodeNamespace) { var ns = ele as EnvDTE.CodeNamespace; // run through classes foreach (var property in ns.Members) { var member = property as CodeType; if (member == null) { continue; } // check all classes they derive from to see if any of them are migration classes, add them if so migrations.AddRange(from object b in member.Bases select b as CodeClass into bClass where bClass != null && bClass.Name == "DataMigrationImpl" select new Migration(member)); } } } } var model = projItem.FileCodeModel; if (model == null) { FireError("This class you have selected is weird and broken. Choose another one"); return; } var elements = model.CodeElements; var classes = new List <Model>(); // run through elements (they are done in a hierachy, so first we have using statements and the namespace) to find namespace foreach (var ele in elements) { if (ele is EnvDTE.CodeNamespace) { var ns = ele as EnvDTE.CodeNamespace; // run through classes foreach (var c in ns.Members) { var member = c as CodeType; if (member == null) { continue; } classes.Add(new Model() { Class = member, Name = member.Name }); } } } if (!classes.Any()) { FireError("No classes in the selected file!"); return; } var vm = new MigrationsViewModel(migrations, classes); var window = new MigrationsWindow(vm); var success = window.ShowDialog(); if (!success.GetValueOrDefault()) { return; } CodeType selectedClass = vm.SelectedClass.Class; if (selectedClass == null) { FireError("No class to generate migrations from!"); return; } // name of class var modelName = selectedClass.Name; // get code class var cc = selectedClass as CodeClass; // get all members of the class var members = cc.Members; bool contentPartRecord = false; foreach (var d in cc.Bases) { var dClass = d as CodeClass; if (dClass != null && dClass.Name == "ContentPartRecord") { contentPartRecord = true; } } var props = new List <MigrationItem>(); //iterate through to find properties foreach (var member in members) { var prop = member as CodeProperty; if (prop == null) { continue; } if (prop.Access != vsCMAccess.vsCMAccessPublic) { continue; } var type = prop.Type; var name = prop.Name; var fullName = type.AsFullName; var nullable = fullName.Contains(".Nullable<"); var sType = type.AsString.Replace("?", ""); var sName = name; // if model, add _Id for nhibernate if (fullName.Contains(".Models.") || fullName.Contains(".Records.")) { sName += "_Id"; sType = "int"; } var mi = new MigrationItem() { Name = name, SuggestedName = sName, Type = fullName, SuggestedType = sType, Nullable = nullable, Create = true, }; props.Add(mi); } var createMigrationFile = !String.IsNullOrEmpty(vm.NewMigration); if (!createMigrationFile) { if (vm.SelectedMigration == null) { FireError("Select a migration or choose a new one!"); return; } var mig = vm.SelectedMigration.CodeType; string path = (string)mig.ProjectItem.Properties.Item("FullPath").Value; string text = File.ReadAllText(path); var noTimesCreated = Regex.Matches(text, @"SchemaBuilder.Create\(""" + modelName + @""",").Count; var noTimesDropped = Regex.Matches(text, @"SchemaBuilder.DropTable\(""" + modelName + @"""\)").Count; bool created = noTimesCreated > noTimesDropped; if (noTimesCreated == 1 && noTimesDropped == 0) { foreach (var p in props.Where(p => text.Contains(p.Name))) { p.Create = false; } } if (created) { foreach (var p in props) { var name = p.Name; var noDrops = Regex.Matches(text, @".DropColumn\(""" + name).Count; var noOccurences = Regex.Matches(text, name).Count; if ((noOccurences - noDrops) > noDrops) { p.Create = false; } } } } // if a collection ignore foreach (var p in props) { if (p.Type.Contains("System.Collection")) { p.Create = false; } } var bmvm = new BuildMigrationsViewModel(props); var bmWindow = new BuildMigrationsWindow(bmvm); var bmSuccess = bmWindow.ShowDialog(); if (!bmSuccess.GetValueOrDefault()) { return; } var sb = new StringBuilder(); var createTable = "SchemaBuilder.CreateTable(\"" + modelName + "\", t => t"; sb.AppendLine(createTable); if (contentPartRecord) { sb.AppendLine("\t.ContentPartRecord()"); } foreach (var p in bmvm.Migrations.Where(z => z.Create)) { sb.AppendLine("\t" + ParseMigrationItem(p)); } sb.AppendLine(");"); var editViewModel = new EditMigrationsViewModel() { Migrations = sb.ToString() }; var editWindow = new EditMigrationsWindow(editViewModel); var emSuccess = editWindow.ShowDialog(); if (!emSuccess.GetValueOrDefault()) { return; } var migrationsCode = new StringBuilder(); using (StringReader reader = new StringReader(editViewModel.Migrations)) { string line; while ((line = reader.ReadLine()) != null) { migrationsCode.AppendLine(line.Insert(0, "\t\t\t")); } } if (!createMigrationFile) { EditMigrations(vm.SelectedMigration.CodeType, migrationsCode.ToString()); } else { var templates = Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location), "OrchardTemplates"); var newMigration = project.ProjectItems.AddFromFileCopy(templates + "\\Migrationsxxx.cs"); Insert(newMigration.Properties.Item("FullPath").Value.ToString(), new[] { new KeyValuePair <string, string>("$module$", project.Name), new KeyValuePair <string, string>("$migrationName$", vm.NewMigration), new KeyValuePair <string, string>("$code$", migrationsCode.ToString()) }); var cs = vm.NewMigration.EndsWith(".cs") ? "" : ".cs"; newMigration.Name = vm.NewMigration + cs; } }
private string ParseMigrationItem(MigrationItem item) { bool key = item.Name == "Id"; // column switches var switches = ""; if (key) switches += ".PrimaryKey().Identity()"; if (item.SuggestedType == "string" && item.Length != 0) switches += ".WithLength(" + item.Length + ")"; if (item.Nullable) switches += ".Nullable()"; if (item.NotNull && !item.Nullable) switches += ".NotNull()"; if (!String.IsNullOrEmpty(item.WithDefault)) { if (item.SuggestedType == "string") switches += ".WithDefault(\"" + item.WithDefault + "\")"; else switches += ".WithDefault(" + item.WithDefault + ")"; } var line = String.Format(".Column<{0}>(\"{1}\"{2}{3})", item.SuggestedType, item.SuggestedName, String.IsNullOrEmpty(switches) ? "" : ", c => c", switches); return line; }
/// <summary> /// Called when the Generate Migrations command is run /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> private void MigrationsCallback(object sender, EventArgs e) { IntPtr hierarchyPtr, selectionContainerPtr; uint projectItemId; IVsMultiItemSelect mis; IVsMonitorSelection monitorSelection = (IVsMonitorSelection)GetGlobalService(typeof(SVsShellMonitorSelection)); monitorSelection.GetCurrentSelection(out hierarchyPtr, out projectItemId, out mis, out selectionContainerPtr); IVsHierarchy hierarchy = Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)) as IVsHierarchy; if (hierarchy == null) { FireError("F**k knows why but it is broken, sorry"); return; } object projObj; hierarchy.GetProperty(projectItemId, (int)__VSHPROPID.VSHPROPID_ExtObject, out projObj); ProjectItem projItem = projObj as ProjectItem; if (projItem == null) { FireError("The item you have selected is not playing nicely. Apologies"); return; } var project = projItem.ContainingProject; var migrations = new List<Migration>(); var allClasses = GetProjectItems(project.ProjectItems).Where(v => v.Name.Contains(".cs")); // check for .cs extension on each, foreach (var c in allClasses) { var eles = c.FileCodeModel; if (eles == null) continue; foreach (var ele in eles.CodeElements) { if (ele is EnvDTE.CodeNamespace) { var ns = ele as EnvDTE.CodeNamespace; // run through classes foreach (var property in ns.Members) { var member = property as CodeType; if (member == null) continue; // check all classes they derive from to see if any of them are migration classes, add them if so migrations.AddRange(from object b in member.Bases select b as CodeClass into bClass where bClass != null && bClass.Name == "DataMigrationImpl" select new Migration(member)); } } } } var model = projItem.FileCodeModel; if (model == null) { FireError("This class you have selected is weird and broken. Choose another one"); return; } var elements = model.CodeElements; var classes = new List<Model>(); // run through elements (they are done in a hierachy, so first we have using statements and the namespace) to find namespace foreach (var ele in elements) { if (ele is EnvDTE.CodeNamespace) { var ns = ele as EnvDTE.CodeNamespace; // run through classes foreach (var c in ns.Members) { var member = c as CodeType; if (member == null) continue; classes.Add(new Model() { Class = member, Name = member.Name }); } } } if (!classes.Any()) { FireError("No classes in the selected file!"); return; } var vm = new MigrationsViewModel(migrations, classes); var window = new MigrationsWindow(vm); var success = window.ShowDialog(); if (!success.GetValueOrDefault()) { return; } CodeType selectedClass = vm.SelectedClass.Class; if (selectedClass == null) { FireError("No class to generate migrations from!"); return; } // name of class var modelName = selectedClass.Name; // get code class var cc = selectedClass as CodeClass; // get all members of the class var members = cc.Members; bool contentPartRecord = false; foreach (var d in cc.Bases) { var dClass = d as CodeClass; if (dClass != null && dClass.Name == "ContentPartRecord") { contentPartRecord = true; } } var props = new List<MigrationItem>(); //iterate through to find properties foreach (var member in members) { var prop = member as CodeProperty; if (prop == null) continue; if (prop.Access != vsCMAccess.vsCMAccessPublic) continue; var type = prop.Type; var name = prop.Name; var fullName = type.AsFullName; var nullable = fullName.Contains(".Nullable<"); var sType = type.AsString.Replace("?", ""); var sName = name; // if model, add _Id for nhibernate if (fullName.Contains(".Models.") || fullName.Contains(".Records.")) { sName += "_Id"; sType = "int"; } var mi = new MigrationItem() { Name = name, SuggestedName = sName, Type = fullName, SuggestedType = sType, Nullable = nullable, Create = true, }; props.Add(mi); } var createMigrationFile = !String.IsNullOrEmpty(vm.NewMigration); if (!createMigrationFile) { if (vm.SelectedMigration == null) { FireError("Select a migration or choose a new one!"); return; } var mig = vm.SelectedMigration.CodeType; string path = (string)mig.ProjectItem.Properties.Item("FullPath").Value; string text = File.ReadAllText(path); var noTimesCreated = Regex.Matches(text, @"SchemaBuilder.Create\(""" + modelName + @""",").Count; var noTimesDropped = Regex.Matches(text, @"SchemaBuilder.DropTable\(""" + modelName + @"""\)").Count; bool created = noTimesCreated > noTimesDropped; if (noTimesCreated == 1 && noTimesDropped == 0) { foreach (var p in props.Where(p => text.Contains(p.Name))) { p.Create = false; } } if (created) { foreach (var p in props) { var name = p.Name; var noDrops = Regex.Matches(text, @".DropColumn\(""" + name).Count; var noOccurences = Regex.Matches(text, name).Count; if ((noOccurences - noDrops) > noDrops) p.Create = false; } } } // if a collection ignore foreach (var p in props) if (p.Type.Contains("System.Collection")) p.Create = false; var bmvm = new BuildMigrationsViewModel(props); var bmWindow = new BuildMigrationsWindow(bmvm); var bmSuccess = bmWindow.ShowDialog(); if (!bmSuccess.GetValueOrDefault()) { return; } var sb = new StringBuilder(); var createTable = "SchemaBuilder.CreateTable(\"" + modelName + "\", t => t"; sb.AppendLine(createTable); if (contentPartRecord) sb.AppendLine("\t.ContentPartRecord()"); foreach (var p in bmvm.Migrations.Where(z => z.Create)) { sb.AppendLine("\t" + ParseMigrationItem(p)); } sb.AppendLine(");"); var editViewModel = new EditMigrationsViewModel() { Migrations = sb.ToString() }; var editWindow = new EditMigrationsWindow(editViewModel); var emSuccess = editWindow.ShowDialog(); if (!emSuccess.GetValueOrDefault()) { return; } var migrationsCode = new StringBuilder(); using (StringReader reader = new StringReader(editViewModel.Migrations)) { string line; while ((line = reader.ReadLine()) != null) { migrationsCode.AppendLine(line.Insert(0, "\t\t\t")); } } if (!createMigrationFile) EditMigrations(vm.SelectedMigration.CodeType, migrationsCode.ToString()); else { var templates = Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location), "OrchardTemplates"); var newMigration = project.ProjectItems.AddFromFileCopy(templates + "\\Migrationsxxx.cs"); Insert(newMigration.Properties.Item("FullPath").Value.ToString(), new[] { new KeyValuePair<string, string>("$module$", project.Name), new KeyValuePair<string, string>("$migrationName$", vm.NewMigration), new KeyValuePair<string, string>("$code$", migrationsCode.ToString()) }); var cs = vm.NewMigration.EndsWith(".cs") ? "" : ".cs"; newMigration.Name = vm.NewMigration + cs; } }