Ejemplo n.º 1
0
        public ViewResult Index()
        {
            var migrationsViewModel = new MigrationsViewModel
            {
                CurrentVersion    = _migrationInformation.CurrentVersion().Version,
                AvailableVersions = _migrationInformation.GetMigrations()
                                    .OrderBy(x => x.Item1)
                                    .Select(x => new MigrationViewModel
                {
                    Version = x.Item1,
                    Name    = x.Item2
                })
            };

            return(View(migrationsViewModel));
        }
Ejemplo n.º 2
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;
            }
        }