/// <summary>
        /// Handles setting up the MapHive environment - maphive meta db, idsrv db and membership reboot db
        /// </summary>
        /// <param name="args"></param>
        protected virtual async Task Handle_SetUpDb(IDictionary <string, string> args)
        {
            var cmd = GetCallerName();

            if (GetHelp(args))
            {
                Console.WriteLine($"'{cmd}' : sets up the maphive dbs - maphive_meta, maphive_idsrv, maphive_mr; uses the configured db credentials to connect to the db server.");
                Console.WriteLine($"syntax: {cmd} space separated params: ");
                Console.WriteLine("\t[full:{presence}; whether or not all the databases created/upgraded]");
                Console.WriteLine("\t[mh:{presence}; whether or not maphive_meta should be created/upgraded]");
                Console.WriteLine("\t[mr:{presence}; whether or not maphive_mr (MembershipReboot) should be created/upgraded]");
                Console.WriteLine("\t[idsrv:{presence}; whether or not maphive_idsrv (IdentityServer) should be created/upgraded]");
                Console.WriteLine("\t[xfull:{presence}; whether or not all the databases should be dropped prior to being recreated]");
                Console.WriteLine("\t[xmh:{presence}; whether or not maphive_meta should be dropped prior to being recreated]");
                Console.WriteLine("\t[xmr:{presence}; whether or not maphive_mr (MembershipReboot) should be dropped prior to being recreated]");
                Console.WriteLine("\t[xidsrv:{presence}; whether or not maphive_idsrv (IdentityServer) should be dropped prior to being recreated]");

                Console.WriteLine($"example: {cmd} m mr idsrv xm xmr xidsrv");
                Console.WriteLine($"example: {cmd} full xfull");
                Console.WriteLine();

                return;
            }

            var dbsToDrop        = new List <string>();
            var migrationConfigs = new Dictionary <DbMigrationsConfiguration, string>();

            if (ContainsParam("full", args) || ContainsParam("mh", args))
            {
                migrationConfigs[new MapHive.Server.Core.DAL.Migrations.MapHiveMetaConfiguration.Configuration()] = "maphive_meta";
            }
            if (ContainsParam("xfull", args) || ContainsParam("xmh", args))
            {
                dbsToDrop.Add("maphive_meta");
            }
            if (ContainsParam("full", args) || ContainsParam("mr", args))
            {
                migrationConfigs[new MapHive.Identity.MembershipReboot.Migrations.Configuration()] = "maphive_mr";
            }
            if (ContainsParam("xfull", args) || ContainsParam("xmr", args))
            {
                dbsToDrop.Add("maphive_mr");
            }
            if (ContainsParam("full", args) || ContainsParam("idsrv", args))
            {
                migrationConfigs[new MapHive.Identity.IdentityServer.Migrations.ClientConfiguration.Configuration()]      = "maphive_idsrv";
                migrationConfigs[new MapHive.Identity.IdentityServer.Migrations.OperationalConfiguration.Configuration()] = "maphive_idsrv";
                migrationConfigs[new MapHive.Identity.IdentityServer.Migrations.ScopeConfiguration.Configuration()]       = "maphive_idsrv";
            }
            if (ContainsParam("xfull", args) || ContainsParam("xidsrv", args))
            {
                dbsToDrop.Add("maphive_idsrv");
            }

            //got here, so need to drop the dbs first in order to recreate them later
            if (dbsToDrop.Count > 0)
            {
                if (
                    !PromptUser(
                        $"You are about to drop the following databases {string.Join(", ", dbsToDrop)}. Are you sure you want to proceed?"))
                {
                    return;
                }

                DropDb(dbsToDrop.ToArray());
            }


            if (migrationConfigs.Count > 0)
            {
                ConsoleEx.WriteLine("Updating dbs... ", ConsoleColor.DarkYellow);
                try
                {
                    foreach (var migrationCfg in migrationConfigs.Keys)
                    {
                        var dbc = new DataSourceCredentials
                        {
                            DbName         = migrationConfigs[migrationCfg],
                            ServerHost     = Dsc.ServerHost,
                            ServerPort     = Dsc.ServerPort,
                            UserName       = Dsc.UserName,
                            Pass           = Dsc.Pass,
                            DataSourceType = DataSourceType.PgSql
                        };

                        try
                        {
                            ConsoleEx.Write($"{migrationCfg.ToString()}... ", ConsoleColor.DarkYellow);

                            //TODO - make the provider name somewhat more dynamic...
                            migrationCfg.TargetDatabase = new DbConnectionInfo(dbc.GetConnectionString(), "Npgsql");

                            var migrator = new DbMigrator(migrationCfg);


                            migrator.Update();
                            ConsoleEx.Write("Done!" + Environment.NewLine, ConsoleColor.DarkGreen);
                        }
                        catch (Exception ex)
                        {
                            ConsoleEx.WriteErr($"OOOPS... Failed to create/update database: {migrationCfg}");
                            HandleException(ex, true);
                            throw;
                        }
                    }
                }
                catch (Exception ex)
                {
                    //ignore
                    return;
                }
            }


            if (dbsToDrop.Count == 0 && migrationConfigs.Count == 0)
            {
                ConsoleEx.WriteLine(
                    "Looks like i have nothing to do... Type 'setup help' for more details on how to use this command.",
                    ConsoleColor.DarkYellow);
            }
            else
            {
                EfConnectionsPoolCacheCleanup();
            }

            Console.WriteLine();
        }
Esempio n. 2
0
        /// <summary>
        /// Sets up databases
        /// </summary>
        /// <param name="dbsToDrop"></param>
        /// <param name="ctxsToMmigrate"></param>
        /// <param name="confirmDrop"></param>
        protected void SetupDatabases(List <string> dbsToDrop, Dictionary <string, List <Type> > ctxsToMmigrate, bool confirmDrop = true)
        {
            //got here, so need to drop the dbs first in order to recreate them later
            if (dbsToDrop?.Count > 0)
            {
                if (confirmDrop)
                {
                    if (
                        !PromptUser(
                            $"You are about to drop the following databases: {string.Join(", ", dbsToDrop)}. Are you sure you want to proceed?"))
                    {
                        return;
                    }
                }

                DropDb(dbsToDrop.ToArray());
            }


            if (ctxsToMmigrate?.Count > 0)
            {
                try
                {
                    foreach (var dbName in ctxsToMmigrate.Keys)
                    {
                        var dbc = new DataSourceCredentials
                        {
                            DbName             = dbName,
                            ServerHost         = Dsc.ServerHost,
                            ServerPort         = Dsc.ServerPort,
                            UserName           = Dsc.UserName,
                            Pass               = Dsc.Pass,
                            DataSourceProvider = DataSourceProvider.Npgsql
                        };

                        try
                        {
                            ConsoleEx.WriteLine($"Updating db: {dbName}... ", ConsoleColor.DarkGray);

                            //context will be scoped to credentials defined as default for the cmd
                            foreach (var type in ctxsToMmigrate[dbName])
                            {
                                if (!typeof(IProvideDbContextFactory).GetTypeInfo().IsAssignableFrom(type.Ge‌​tTypeInfo()))
                                {
                                    ConsoleEx.WriteLine($"{type.FullName} does not implement {nameof(IProvideDbContextFactory)} and therefore will be skipped", ConsoleColor.DarkMagenta);
                                    continue;
                                }

                                ConsoleEx.Write($"Running migration on: {type.FullName}... ", ConsoleColor.DarkYellow);

                                //cannot rely on specific constructors in db contexts!
                                //var dbCtx = (DbContext)Activator.CreateInstance(type, new object[] { dbc.GetConnectionString(), true, dbc.DataSourceProvider });
                                //
                                //instead need to use some hocus pocus and only serve contexts that implement IProvideDbContextFactory
                                var dbCtxFacade = (IProvideDbContextFactory)Cartomatic.Utils.Ef.DbContextFactory.CreateDbContextFacade(type);

                                var dbCtx = dbCtxFacade.ProduceDbContextInstance(dbc.GetConnectionString(), true, dbc.DataSourceProvider);

                                //this will create db if it does not exist and apply all the pending migrations
                                dbCtx.CreateOrUpdateDatabase();

                                ConsoleEx.Write("Done!" + Environment.NewLine, ConsoleColor.DarkGreen);
                            }

                            ConsoleEx.Write("Done!" + Environment.NewLine, ConsoleColor.DarkGreen);
                            Console.WriteLine();
                        }
                        catch (Exception ex)
                        {
                            ConsoleEx.WriteErr($"OOOPS... Failed to create/update database: {dbName}");
                            HandleException(ex, true);
                            throw;
                        }
                    }
                }
                catch
                {
                    //ignore
                }
            }
        }