static int Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Connection string not provided"); return(1); } var connectionString = args[0]; Console.WriteLine("Applying migrations using connectionString = [{0}]", connectionString); var context = new VaultContext( new DbContextOptionsBuilder <VaultContext>() .UseNpgsql(connectionString, x => x.MigrationsAssembly("TW.Vault.Migration")) .Options ); var migrations = context.Database.GetPendingMigrations().ToList(); Console.WriteLine("Applying {0} pending migrations:", migrations.Count); foreach (var m in migrations) { Console.WriteLine(m); } context.Database.Migrate(); return(0); }
public void Context_ContextInit_Success() { EntityContainer.RegisterEntity <TestEntity3>(); IContext iContext = VaultContext.GetContext(); Assert.NotNull(iContext); }
public void Context_GetContext_Success() { var iContext = VaultContext.GetContext(); var iContext2 = VaultContext.GetContext(); Assert.NotNull(iContext); Assert.NotNull(iContext2); Assert.AreSame(iContext, iContext2); }
public void Context_RegisterTest_Success() { IContext iContext = VaultContext.GetContext(); var dataSet = iContext.GetDataSet <TestEntity3>(); Assert.IsNotNull(dataSet); Assert.IsInstanceOf(typeof(DataSet <TestEntity3>), dataSet); }
public VaultController(VaultContext context) { _context = context; if (_context.VaultItems.Count() == 0) { _context.VaultItems.Add(new VaultItem { Description = "Item1" }); _context.SaveChanges(); } }
public static async Task <UserUploadHistory> GetOrCreateUserUploadHistory(VaultContext context, int uid) { var userUploadHistory = await context.UserUploadHistory.Where(h => h.Uid == uid).FirstOrDefaultAsync(); if (userUploadHistory == null) { userUploadHistory = new UserUploadHistory(); userUploadHistory.Uid = uid; context.Add(userUploadHistory); } return(userUploadHistory); }
public static async Task <CurrentPlayer> GetOrCreateCurrentPlayer(VaultContext context, long playerId, short worldId, int accessGroupId) { var currentPlayer = await context.CurrentPlayer.FromAccessGroup(accessGroupId).FromWorld(worldId).Where(p => p.PlayerId == playerId).FirstOrDefaultAsync(); if (currentPlayer == null) { currentPlayer = new CurrentPlayer(); currentPlayer.PlayerId = playerId; currentPlayer.WorldId = worldId; currentPlayer.AccessGroupId = accessGroupId; context.Add(currentPlayer); } return(currentPlayer); }
private static void DeleteForWorld(VaultContext context, IProgressBar progressBar, Type type, int worldId) { var entityType = context.Model.FindEntityType(type); var table = entityType.GetTableName(); var schema = entityType.GetSchema(); var primaryKeys = entityType.FindPrimaryKey().Properties.Select(p => p.Name).Where(n => n != "WorldId" && n != "AccessGroupId").ToList(); if (primaryKeys.Count != 1) { Console.WriteLine("Unexpected number of primary keys for {0}, got {1} but expected 1", type.Name, primaryKeys.Count); } var primaryKey = primaryKeys.Single(); var numTotal = 0; progressBar.Tick(0, $"Counting {type.Name} entities..."); using (var command = context.Database.GetDbConnection().CreateCommand()) { command.CommandText = $"SELECT COUNT(1) FROM {schema}.{table} WHERE world_id = {worldId}"; context.Database.OpenConnection(); using (var result = command.ExecuteReader()) { result.Read(); numTotal = result.GetInt32(0); } } if (numTotal == 0) { progressBar.Tick(progressBar.MaxTicks); return; } progressBar.Message = $"Deleting {numTotal} entries of type {type.Name} with single transaction..."; progressBar.MaxTicks = numTotal; int numDeleted = context.Database.ExecuteSqlRaw($"DELETE FROM {schema}.{table} WHERE world_id = {worldId}"); if (numDeleted != numTotal) { Console.WriteLine("Deletion failed for {0}, expected to delete {1} but deleted {2} instead", type.Name, numTotal, numDeleted); } progressBar.Tick(numTotal); }
static void Main(string[] args) { var config = Config.ParseParams(args); if (!config.IsValid) { Console.WriteLine(Config.UsageDescription); Environment.ExitCode = 1; return; } Console.WriteLine("Using config:\n" + config.ToString()); var connectionString = config.ConnectionString; var extraTLDs = config.ExtraTLDs; var extraServers = config.ExtraServers; var deleteOldWorlds = config.Clean; var fetchNewServers = config.FetchTldServers; var vaultContext = new VaultContext( new DbContextOptionsBuilder <VaultContext>() .UseNpgsql(connectionString, opt => opt.CommandTimeout((int)TimeSpan.FromMinutes(30).TotalSeconds)) .Options ); using (vaultContext) { var worlds = vaultContext.World.Where(w => !w.IsPendingDeletion).Include(w => w.WorldSettings).ToList(); var tlds = worlds.Select(HostOf).Concat(extraTLDs).Distinct().ToList(); var hostLocales = tlds.ToDictionary(h => h, h => { var matchedWorlds = worlds.Where(w => HostOf(w) == h).ToList(); var distinctLocales = matchedWorlds .Select(w => new LocaleSettings { DefaultTranslationId = w.DefaultTranslationId, TimeZoneId = w.WorldSettings.TimeZoneId }) .Distinct() .ToList(); if (distinctLocales.Count > 1) { throw new Exception($"Expected one time zone for host {h}, got {distinctLocales.Count}"); } return(distinctLocales.FirstOrDefault()); }); foreach (var template in Vault.Scaffold.Seed.WorldSettingsTemplate.Templates) { if (!hostLocales.ContainsKey(template.TldHostname) || hostLocales[template.TldHostname] == null) { hostLocales[template.TldHostname] = new LocaleSettings { TimeZoneId = template.TimeZoneId, DefaultTranslationId = template.DefaultTranslationId } } ; } var activeWorldHostnames = tlds.SelectMany(h => FetchAvailableWorlds(h)).ToList(); var allWorldHostnames = extraServers.Concat(fetchNewServers ? activeWorldHostnames : worlds.Select(w => w.Hostname) ).Distinct().ToList(); Console.WriteLine($"Creating and pulling {allWorldHostnames.Count} worlds..."); foreach (var hostname in allWorldHostnames) { FetchWorldData(vaultContext, worlds, hostLocales, hostname, config.FetchExisting); } if (deleteOldWorlds) { Console.WriteLine("Cleaning old world data..."); var oldWorlds = vaultContext.World.Include(w => w.WorldSettings).ToList().Where(w => w.IsPendingDeletion || !activeWorldHostnames.Contains(w.Hostname)).ToList(); Console.WriteLine("Found {0} old worlds to be cleaned:", oldWorlds.Count); foreach (var w in oldWorlds) { Console.WriteLine("- " + w.Hostname); } Console.WriteLine("Press Enter to continue."); Console.ReadLine(); Console.WriteLine("Marking worlds as pending deletion..."); foreach (var w in oldWorlds) { w.IsPendingDeletion = true; } vaultContext.SaveChanges(); foreach (var w in oldWorlds) { DeleteWorld(vaultContext, w); } } } vaultContext.Dispose(); Console.WriteLine("FINISHED."); Console.ReadLine(); }
private static void DeleteWorld(VaultContext vaultContext, World world) { vaultContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; List <Type> typeJobs = new List <Type> { typeof(User), typeof(UserLog), typeof(Command), typeof(CurrentBuilding), typeof(CurrentVillage), typeof(CurrentVillageSupport), typeof(CurrentArmy), typeof(CommandArmy), typeof(CurrentPlayer), typeof(EnemyTribe), typeof(IgnoredReport), typeof(Report), typeof(ReportArmy), typeof(ReportBuilding), typeof(Transaction), typeof(Village), typeof(Player), typeof(Ally), typeof(Conquer), typeof(AccessGroup) }; Console.WriteLine("Deleting non-trivial datatypes..."); Console.WriteLine("Deleting UserUploadHistory entries..."); vaultContext.UserUploadHistory.RemoveRange(vaultContext.UserUploadHistory.Where(h => h.U.WorldId == world.Id)); vaultContext.SaveChanges(); var numJobsDone = 0; String JobsProgressMessage() => $"Deleting data for {world.Hostname} (id={world.Id}) ({numJobsDone}/{typeJobs.Count} done)"; using (var dataProgressBar = new ProgressBar(typeJobs.Count, JobsProgressMessage())) { foreach (var type in typeJobs) { using (var jobProgressBar = dataProgressBar.Spawn(1, "")) { Console.Out.Flush(); Thread.Sleep(100); DeleteForWorld(vaultContext, jobProgressBar, type, world.Id); } numJobsDone++; dataProgressBar.Tick(JobsProgressMessage()); } } Console.WriteLine("Deleting world settings..."); if (world.WorldSettings != null) { vaultContext.Remove(world.WorldSettings); vaultContext.SaveChanges(); } Console.WriteLine("Deleting world..."); vaultContext.Remove(world); vaultContext.SaveChanges(); Console.WriteLine("Deleted all data for {0}.", world.Hostname); vaultContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.TrackAll; }
private static void FetchWorldData(VaultContext context, List <World> worlds, Dictionary <String, LocaleSettings> hostLocales, String hostname, bool overwrite) { var host = HostFor(hostname); var localeSettings = hostLocales.ContainsKey(host) ? hostLocales[host] : null; var fetchers = new IFetcher[] { new BuildingFetcher(), new ConfigFetcher() { Overwrite = overwrite, DefaultTimeZoneId = localeSettings?.TimeZoneId ?? "Europe/London" }, new UnitFetcher() }; var world = worlds.Where(w => w.Hostname == hostname).SingleOrDefault(); if (world == null) { short translationId; if (localeSettings != null) { translationId = localeSettings.DefaultTranslationId; } else { translationId = 1; Console.WriteLine($"Warning: No default translation could be found for {hostname}, defaulting to primary English translation."); } world = new World { Name = hostname.Split('.')[0], Hostname = hostname, DefaultTranslationId = translationId }; context.Add(world); } var pendingFetchers = fetchers.Where(f => f.NeedsUpdate(world)).ToList(); if (pendingFetchers.Count > 0) { Console.WriteLine("Pulling for world {0}...", world.Hostname); } else { Console.WriteLine("World {0} is up to date", world.Hostname); } var baseUrl = $"https://{world.Hostname}"; foreach (var fetcher in pendingFetchers) { var url = $"{baseUrl}{fetcher.Endpoint}"; Console.Write("Fetching {0} ... ", url); Console.Out.Flush(); var response = httpClient.GetAsync(url).Result; if ((int)response.StatusCode >= 300 && (int)response.StatusCode < 400) { Console.WriteLine("Warning: server {0} seems to have ended (redirection occurred)", world.Hostname); break; } if (!response.IsSuccessStatusCode) { Console.WriteLine("ERROR: Request failed with code {0}", response.StatusCode); Environment.ExitCode = 1; continue; } Console.Write("Processing... "); Console.Out.Flush(); var data = response.Content.ReadAsStringAsync().Result; fetcher.Process(context, world, data); Console.WriteLine("Done."); } var worldSettings = context.WorldSettings.Where(s => s.WorldId == world.Id).First(); String timezoneId; if (localeSettings != null) { timezoneId = hostLocales[host].TimeZoneId; } else { Console.WriteLine($"Warning: No timezone ID could be found for {hostname}, please manually enter a timezone ID for the server."); Console.WriteLine("An exhaustive list of Timezone IDs can be found at: https://nodatime.org/TimeZones"); Console.WriteLine("(The default for .net and .co.uk is 'Europe/London'.)"); do { Console.Write("Timezone ID: "); timezoneId = Console.ReadLine().Trim(); if (NodaTime.TimeZones.TzdbDateTimeZoneSource.Default.ForId(timezoneId) == null) { Console.WriteLine("Invalid ID: " + timezoneId); timezoneId = null; } } while (timezoneId == null); hostLocales.Add(host, new LocaleSettings { DefaultTranslationId = world.DefaultTranslationId, TimeZoneId = timezoneId }); } worldSettings.TimeZoneId = timezoneId; context.SaveChanges(); }
public CurrentContextDbSets(VaultContext context, int worldId, int accessGroupId) { this.worldId = worldId; this.accessGroupId = accessGroupId; this.context = context; }
public BaseController(VaultContext context, IServiceScopeFactory scopeFactory, ILoggerFactory loggerFactory) { this.context = context; this.logger = loggerFactory.CreateLogger(this.GetType().FullName); this.scopeFactory = scopeFactory; }
public ScriptController(IWebHostEnvironment environment, IServiceScopeFactory scopeFactory, VaultContext context, ILoggerFactory loggerFactory) : base(context, scopeFactory, loggerFactory) { asputil = new ASPUtil(environment, ScriptsBasePath); }
public static IDataSet <TEntity> GetSetFor <TEntity>() where TEntity : class { return(VaultContext.GetContext().GetDataSet <TEntity>()); }
public static IWebServiceCredentials GetCredentials(this VaultContext context) { return(new UserIdTicketCredentials(context.RemoteBaseUrl.ToString(), context.VaultName, context.UserId, context.Ticket)); }
public PlayerTranslationController(VaultContext context, IServiceScopeFactory scopeFactory, ILoggerFactory loggerFactory) : base(context, scopeFactory, loggerFactory) { }
public override void Process(VaultContext context, World world, string fetchedContents) { var xml = ParseXml(fetchedContents); }
public override void Process(VaultContext context, World world, string fetchedContents) { var xml = ParseXml(fetchedContents); var newSettings = Parse(xml); var oldSettings = world.WorldSettings; if (oldSettings == null) { Console.WriteLine("Got world settings for new world, storing"); world.WorldSettings = newSettings; context.Add(world.WorldSettings); context.SaveChanges(); } else if (Overwrite) { var props = typeof(WorldSettings).GetProperties(); var differingValues = new Dictionary <String, object[]>(); foreach (var prop in props) { if (!ComparableSettingPropertyTypes.Contains(prop.PropertyType) || prop.Name == "WorldId") { continue; } var newValue = prop.GetValue(newSettings); var oldValue = prop.GetValue(oldSettings); if (!newValue.Equals(oldValue)) { differingValues.Add(prop.Name, new[] { oldValue, newValue }); } } if (differingValues.Count == 0) { Console.WriteLine("Got updated world settings for existing world, but stored config matches latest. No action necessary."); return; } Console.WriteLine("Got updated world settings for existing world, and new settings do not match the old:"); foreach (var prop in differingValues.Keys) { var values = differingValues[prop]; var oldValue = values[0]; var newValue = values[1]; Console.WriteLine("- {0}: Changed from {1} (old) to {2} (new)", prop, oldValue, newValue); } bool?confirmOverwrite = null; while (!confirmOverwrite.HasValue) { Console.Write("Overwrite? [y/n]: "); var response = Console.ReadLine(); if (response.ToLower().Trim() == "y") { confirmOverwrite = true; } if (response.ToLower().Trim() == "n") { confirmOverwrite = false; } } if (confirmOverwrite.Value) { Console.WriteLine("Copying new config..."); CopyTo(newSettings, oldSettings); context.SaveChanges(); } else { Console.WriteLine("Ignoring new config, keeping old."); } } }
public ServerController(VaultContext context, IServiceScopeFactory scopeFactory, ILoggerFactory loggerFactory) : base(context, scopeFactory, loggerFactory) { }
public abstract void Process(VaultContext context, World world, String fetchedContents);