public void Migrate(string version) { EnsureMigrationRecordsExists(); IEnumerable <IDataMigration> migrations = _dataMigrationDiscoverer.DataMigrations; IDataMigration migration = migrations.SingleOrDefault(m => m.Version == version); if (migration == null) { throw new MigrationNullException(version); } IEnumerable <IDataMigration> readyToUndoMigrations = migrations.Where(m => m.TableName == migration.TableName && m.Version.CompareTo(version) > 0) .OrderByDescending(m => m.Version); foreach (IDataMigration m in readyToUndoMigrations) { m.SchemaBuilder = new SchemaBuilder(_interpreter); m.Down(); } DoUpdateMigrationRecord(migration); }
private IEnumerable <OperationsMigration> LoadMirations(IDataMigration instance, int version) { var type = instance.GetType(); var migration = instance as DataMigration; if (migration != null) { InitDataMigration(migration); } var dbMigration = _reposority.FindMigration(type.FullName); if ((dbMigration == null && version == -1) || //卸载 (dbMigration != null && dbMigration.Version == version)) //版本已经是设置的版本 { return(null); } if (version == 0) //安装版本设为最大值 { version = int.MaxValue; } if (dbMigration == null || version > dbMigration.Version) { return(Upgrade(migration, dbMigration, version)); } if (dbMigration.Version > version) { return(Downgrade(migration, dbMigration, version)); } return(null); }
private async Task<Records.DataMigration> GetDataMigrationRecordAsync(IDataMigration tempMigration) { var dataMigrationRecord = await GetDataMigrationRecordAsync(); return dataMigrationRecord .DataMigrations .FirstOrDefault(dm => dm.DataMigrationClass == tempMigration.GetType().FullName); }
private DataMigrationRecord GetDataMigrationRecord(IDataMigration tempMigration) { return(_contentStorageManager .Query <DataMigrationDocument>(x => x != null) .SelectMany(x => x.DataMigrationRecords) .FirstOrDefault(dm => dm.DataMigrationClass == tempMigration.GetType().FullName)); }
private async Task <DataMigrationRecord?> GetDataMigrationRecordAsync(IDataMigration migration) { var dataMigrationsDocument = await GetOrCreateDataMigrationsDocumentAsync(); var records = dataMigrationsDocument.DataMigrations; return(records.FirstOrDefault(x => x.DataMigrationClass == migration.GetType().FullName)); }
/// <summary> /// Returns the CreateAsync method from a data migration class if it's found /// </summary> private static MethodInfo?GetMethod(IDataMigration dataMigration, string name) { var flags = BindingFlags.Public | BindingFlags.Instance; var methodInfo = dataMigration.GetType().GetMethod(name, flags); var returnType = methodInfo?.ReturnType; return(returnType != null && (returnType == typeof(Task <int>) || returnType == typeof(int)) ? methodInfo : null); }
/// <summary> /// Create a list of all available Update methods from a data migration class, indexed by the version number /// </summary> private static Dictionary <int, MethodInfo> CreateUpgradeLookupTable(IDataMigration dataMigration) { return(dataMigration .GetType() .GetMethods(BindingFlags.Public | BindingFlags.Instance) .Select(GetUpdateMethod) .Where(tuple => tuple != null) .ToDictionary(tuple => tuple.Item1, tuple => tuple.Item2)); }
/// <summary> /// Returns the UninstallAsync method from a data migration class if it's found /// </summary> private static MethodInfo GetUninstallAsyncMethod(IDataMigration dataMigration) { var methodInfo = dataMigration.GetType().GetMethod("UninstallAsync", BindingFlags.Public | BindingFlags.Instance); if (methodInfo != null && methodInfo.ReturnType == typeof(Task)) { return methodInfo; } return null; }
/// <summary> /// Returns the Create method from a data migration class if it's found /// </summary> private static MethodInfo GetCreateMethod(IDataMigration dataMigration) { var methodInfo = dataMigration.GetType().GetMethod("Create", BindingFlags.Public | BindingFlags.Instance); if (methodInfo != null && methodInfo.ReturnType == typeof(int)) { return methodInfo; } return null; }
public IDataMigrationDiscoverer Add(IDataMigration dataMigration) { IDataMigration migration = null; if (!_internalDataMigrationStore.TryGetValue(dataMigration.Version, out migration)) { _internalDataMigrationStore.Add(dataMigration.Version, dataMigration); } return(this); }
/// <summary> /// Returns the CreateAsync method from a data migration class if it's found /// </summary> private static MethodInfo GetCreateAsyncMethod(IDataMigration dataMigration) { var methodInfo = dataMigration.GetType().GetMethod("CreateAsync", BindingFlags.Public | BindingFlags.Instance); if (methodInfo != null && methodInfo.ReturnType == typeof(Task <int>)) { return(methodInfo); } return(null); }
/// <summary> /// Returns the Uninstall method from a data migration class if it's found /// </summary> private static MethodInfo GetUninstallMethod(IDataMigration dataMigration) { var methodInfo = dataMigration.GetType().GetMethod("Uninstall", BindingFlags.Public | BindingFlags.Instance); if (methodInfo != null && methodInfo.ReturnType == typeof(void)) { return(methodInfo); } return(null); }
private void ActivateDataInitializer() { Type dataMigrationType = this.DependencyTypes.FirstOrDefault(t => typeof(IDataMigration).IsAssignableFrom(t)); if (dataMigrationType != null) { IDataMigration dataMigration = Activator.CreateInstance(dataMigrationType) as IDataMigration; this.DataInitializer = new DataInitializer(this, dataMigration); this.DataInitializer.Initialize(); } }
public async Task <string> ExecuteAsync(string recipeFileName, IDataMigration migration) { var featureInfo = _typeFeatureProvider.GetFeatureForDependency(migration.GetType()); var recipeBasePath = Path.Combine(featureInfo.Extension.SubPath, "Migrations").Replace('\\', '/'); var recipeFilePath = Path.Combine(recipeBasePath, recipeFileName).Replace('\\', '/'); var recipeFileInfo = _hostingEnvironment.ContentRootFileProvider.GetFileInfo(recipeFilePath); var recipeDescriptor = await _recipeReader.GetRecipeDescriptor(recipeBasePath, recipeFileInfo, _hostingEnvironment.ContentRootFileProvider); recipeDescriptor.RequireNewScope = false; var executionId = Guid.NewGuid().ToString("n"); return(await _recipeExecutor.ExecuteAsync(executionId, recipeDescriptor, new object(), CancellationToken.None)); }
protected void DoUpdateMigrationRecord(IDataMigration dataMigration) { MigrationRecord record = _migrationRecordRepository.Get(m => m.TableName == dataMigration.TableName); if (record == null) { record = new MigrationRecord { TableName = dataMigration.TableName }; } record.Version = dataMigration.Version; Logger.Debug("DataMigrationManager", "Migrate {0} to version:{1}", record.TableName, record.Version); _migrationRecordRepository.CreateOrUpdate(record); }
public async Task <string> ExecuteAsync(string recipeFileName, IDataMigration migration) { var featureInfo = _typeFeatureProvider.GetFeatureForDependency(migration.GetType()); var recipeBasePath = Path.Combine(featureInfo.Extension.SubPath, "Migrations").Replace('\\', '/'); var recipeFilePath = Path.Combine(recipeBasePath, recipeFileName).Replace('\\', '/'); var recipeFileInfo = _hostingEnvironment.ContentRootFileProvider.GetFileInfo(recipeFilePath); var recipeDescriptor = await _recipeReader.GetRecipeDescriptor(recipeBasePath, recipeFileInfo, _hostingEnvironment.ContentRootFileProvider); recipeDescriptor.RequireNewScope = false; var environment = new Dictionary <string, object>(); await _environmentProviders.OrderBy(x => x.Order).InvokeAsync((provider, env) => provider.PopulateEnvironmentAsync(env), environment, _logger); var executionId = Guid.NewGuid().ToString("n"); return(await _recipeExecutor.ExecuteAsync(executionId, recipeDescriptor, environment, CancellationToken.None)); }
private static int PerformMigration(IDataMigration migration, Type migrationType, int nextVersion) { var migrationMethodVersions = migrationType.GetMethods(BindingFlags.Instance | BindingFlags.Public) .Where(IsMigrationMethod) .ToDictionary(ExtractAvailableMethodVersion, method => method); var allVersionSorted = migrationMethodVersions.Keys.OrderBy(version => version).ToList(); if (!migrationMethodVersions.Any()) { return NoMigrationsFound; } var migrationIndex = allVersionSorted.BinarySearch(nextVersion); if (migrationIndex < 0) { return NoMigrationsFound; } for (var i = migrationIndex; i < allVersionSorted.Count; i++) { var version = allVersionSorted[i]; try { var methodInfo = migrationMethodVersions[version]; if (methodInfo.GetParameters().Any()) { throw new InvalidOperationException("Migration method must be parameterless."); } methodInfo.Invoke(migration, new object[0]); } catch (Exception ex) { throw new InvokingMigrationException(version, migrationType.FullName, ex); } } return allVersionSorted.Last(); }
private void PerformMigration(IDataMigration migration, MigrationInfo migrationEntity) { var migrationType = migration.GetType(); bool newMigration = false; if (migrationEntity == null) { newMigration = true; migrationEntity = new MigrationInfo { MigrationName = migration.GetType().FullName, Version = -1 }; } try { migrationEntity.Version = PerformMigration(migration, migrationType, migrationEntity.Version + 1); if (migrationEntity.Version == NoMigrationsFound) { return; } if (newMigration) { this.storage.New(migrationEntity); } else { this.storage.Update(migrationEntity); } } catch (Exception ex) { throw; } }
private DataMigrationRecord GetDataMigrationRecord(IDataMigration tempMigration) { return _dataMigrationRepository .Table .FirstOrDefault(dm => dm.DataMigrationClass == tempMigration.GetType().FullName); }
private Tables.OrmTablesInfo GetDataMigrationRecord(IDataMigration tempMigration) { return(OrmManager.Read <Tables.OrmTablesInfo>(" DataMigrationClass='" + tempMigration.GetType().FullName + "'").FirstOrDefault()); }
private async Task <DataMigration> GetDataMigrationRecordAsync(IDataMigration tempMigration) { return((await GetDataMigrationRecord()).DataMigrations .FirstOrDefault(dm => dm.DataMigrationClass == tempMigration.GetType().FullName)); }
public DataInitializer(IModule module, IDataMigration dataMigration) { this.Module = module; this.DataMigration = dataMigration; }
private DataMigrationRecord GetDataMigrationRecord(IDataMigration tempMigration) { return(_dataMigrationRepository .Table .FirstOrDefault(dm => dm.DataMigrationClass == tempMigration.GetType().FullName)); }
public DataMigrationInterpreter(IDataMigration dataMigrationInvoker, IMigrationMetaStorage storage) { this.dataMigrationInvoker = dataMigrationInvoker; this.storage = storage; }
/// <summary> /// Returns the CreateAsync method from a data migration class if it's found /// </summary> private static MethodInfo?GetCreateAsyncMethod(IDataMigration dataMigration) => GetMethod(dataMigration, "CreateAsync");
/// <summary> /// Create a list of all available Update methods from a data migration class, indexed by the version number /// </summary> private static Dictionary<int, MethodInfo> CreateUpgradeLookupTable(IDataMigration dataMigration) { return dataMigration .GetType() .GetMethods(BindingFlags.Public | BindingFlags.Instance) .Select(GetUpdateMethod) .Where(tuple => tuple != null) .ToDictionary(tuple => tuple.Item1, tuple => tuple.Item2); }
private async Task UpdateAsync(IDataMigration dataMigration) { if (_processedMigrations.Contains(dataMigration)) { return; } var migrationName = dataMigration.GetType().FullName; _processedMigrations.Add(dataMigration); _logger.LogInformation("Running migration '{MigrationName}'", migrationName); // Apply update methods to migration class. var schemaBuilder = new SchemaBuilder(_store.Configuration, await _session.BeginTransactionAsync()); dataMigration.SchemaBuilder = schemaBuilder; // Copy the object for the Linq query. var tempMigration = dataMigration; // Get current version for this migration. var dataMigrationRecord = await GetDataMigrationRecordAsync(tempMigration); var current = 0; var dataMigrationsDocument = await GetOrCreateDataMigrationsDocumentAsync(); if (dataMigrationRecord != null) { // Version can be null if a failed create migration has occurred and the data migration record was saved. current = dataMigrationRecord.Version ?? current; } else { dataMigrationRecord = new DataMigrationRecord { DataMigrationClass = dataMigration.GetType().FullName ! }; dataMigrationsDocument.DataMigrations.Add(dataMigrationRecord); } try { // Do we need to call Create()? if (current == 0) { // try to resolve a Create method. var createMethod = GetCreateMethod(dataMigration); if (createMethod != null) { current = (int)createMethod.Invoke(dataMigration, new object[0]) !; } // try to resolve a CreateAsync method. var createAsyncMethod = GetCreateAsyncMethod(dataMigration); if (createAsyncMethod != null) { current = await(Task <int>) createAsyncMethod.Invoke(dataMigration, new object[0]) !; } } var lookupTable = CreateUpgradeLookupTable(dataMigration); while (lookupTable.TryGetValue(current, out var methodInfo)) { _logger.LogInformation( "Applying migration '{MigrationName}' from version {Version}", migrationName, current); var isAwaitable = methodInfo.ReturnType.GetMethod(nameof(Task.GetAwaiter)) != null; current = isAwaitable ? await(Task <int>) methodInfo.Invoke(dataMigration, new object[0]) ! : (int)methodInfo.Invoke(dataMigration, new object[0]) !; } // If current is 0, it means no upgrade/create method was found or succeeded. if (current == 0) { return; } dataMigrationRecord.Version = current; } catch (Exception ex) { _logger.LogError( ex, "Error while running migration version {Version} for '{MigrationName}'", current, migrationName); } finally { // Persist data migrations _session.Save(dataMigrationsDocument); } }
/// <summary> /// Returns the Uninstall method from a data migration class if it's found /// </summary> private static MethodInfo GetUninstallMethod(IDataMigration dataMigration) { var methodInfo = dataMigration.GetType().GetMethod("Uninstall", BindingFlags.Public | BindingFlags.Instance); if (methodInfo != null && methodInfo.ReturnType == typeof(void)) { return methodInfo; } return null; }
private async Task<DataMigration> GetDataMigrationRecordAsync(IDataMigration tempMigration) { return (await GetDataMigrationRecord()).DataMigrations .FirstOrDefault(dm => dm.DataMigrationClass == tempMigration.GetType().FullName); }