public static void PrimeCountry(string countryCode) { Country country = Country.FromCode(countryCode); if (country.GeographyId != Geography.RootIdentity) { // already initialized return; } GeographyDataLoader geoDataLoader = new GeographyDataLoader(); // This next part has been hardened against transient network failures, up to 10 retries int retries = 0; bool networkSuccess = false; MasterGeography geography = null; MasterCity[] cities = null; MasterPostalCode[] postalCodes = null; while (!networkSuccess) { try { geography = geoDataLoader.GetGeographyForCountry(countryCode); cities = geoDataLoader.GetCitiesForCountry(countryCode); postalCodes = geoDataLoader.GetPostalCodesForCountry(countryCode); networkSuccess = true; } catch (Exception) { if (retries >= 10) { throw; } retries++; Thread.Sleep(5000); // wait five seconds for network conditions to clear } } // ID Translation lists Dictionary <int, int> geographyIdTranslation = new Dictionary <int, int>(); Dictionary <int, int> cityIdTranslation = new Dictionary <int, int>(); Dictionary <int, bool> cityIdsUsedLookup = new Dictionary <int, bool>(); // Create the country's root geography int countryRootGeographyId = SwarmDb.GetDatabaseForWriting().CreateGeography(geography.Name, Geography.RootIdentity); geographyIdTranslation[geography.GeographyId] = countryRootGeographyId; SwarmDb.GetDatabaseForWriting().SetCountryGeographyId(country.Identity, countryRootGeographyId); int count = 0; int total = InitDatabaseThreadCountGeographyChildren(geography.Children); InitDatabaseThreadCreateGeographyChildren(geography.Children, countryRootGeographyId, ref geographyIdTranslation, ref count, total); // Find which cities are actually used foreach (MasterPostalCode postalCode in postalCodes) { cityIdsUsedLookup[postalCode.CityId] = true; } GuidCache.Set("DbInitProgress", "(finalizing)"); // Insert cities int newCountryId = country.Identity; int cityIdHighwater = SwarmDb.GetDatabaseForAdmin().ExecuteAdminCommandScalar("SELECT Max(CityId) FROM Cities;"); StringBuilder sqlCityBuild = new StringBuilder("INSERT INTO Cities (CityName, GeographyId, CountryId, Comment) VALUES ", 65536); bool insertComma = false; foreach (MasterCity city in cities) { if (!geographyIdTranslation.ContainsKey(city.GeographyId)) { cityIdsUsedLookup[city.CityId] = false; // force non-use of invalid city } if ((cityIdsUsedLookup.ContainsKey(city.CityId) && cityIdsUsedLookup[city.CityId]) || country.PostalCodeLength == 0) { int newGeographyId = geographyIdTranslation[city.GeographyId]; if (insertComma) { sqlCityBuild.Append(","); } sqlCityBuild.Append("('" + city.Name.Replace("'", "\\'") + "'," + newGeographyId + "," + newCountryId + ",'')"); insertComma = true; cityIdTranslation[city.CityId] = ++cityIdHighwater; // Note that we assume the assigned ID here. } } sqlCityBuild.Append(";"); SwarmDb.GetDatabaseForAdmin().ExecuteAdminCommand(sqlCityBuild.ToString()); // Inserts all cities in one bulk op, to save roundtrips // Insert postal codes, if any if (postalCodes.Length > 0) { StringBuilder sqlBuild = new StringBuilder("INSERT INTO PostalCodes (PostalCode, CityId, CountryId) VALUES ", 65536); insertComma = false; foreach (MasterPostalCode postalCode in postalCodes) { if (cityIdsUsedLookup[postalCode.CityId] == false) { // Remnants of invalid pointers continue; } int newCityId = cityIdTranslation[postalCode.CityId]; if (insertComma) { sqlBuild.Append(","); } sqlBuild.Append("('" + postalCode.PostalCode.Replace("'", "\\'") + "'," + newCityId + "," + newCountryId + ")"); insertComma = true; } sqlBuild.Append(";"); // Insert all postal codes in one bulk op, to save roundtrips SwarmDb.GetDatabaseForAdmin().ExecuteAdminCommand(sqlBuild.ToString()); } }
public static Cities FromPostalCode(string postalCode, string countryCode) { return(FromPostalCode(postalCode, Country.FromCode(countryCode).Identity)); }
public static PostalCodes ForCountry(string countryCode) { return(ForCountry(Country.FromCode(countryCode).Identity)); }