public async Task <IActionResult> CreateEntityPlugin(EditEntityPluginModel model) { if (ModelState.IsValid) { if (model.PluginFile != null && model.PluginFile.Length > 0) { if (!model.PluginFile.FileName.EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase)) { return(JError("上传的文件类型错误")); } } var entity = new EntityPlugin(); model.CopyTo(entity); entity.EntityPluginId = Guid.NewGuid(); entity.CreatedBy = CurrentUser.SystemUserId; entity.CreatedOn = DateTime.Now; entity.SolutionId = SolutionId.Value; entity.ComponentState = 0; entity.StateCode = RecordState.Enabled; entity.ProcessOrder = model.ProcessOrder; entity.TypeCode = model.TypeCode; await _entityPluginCreater.Create(entity, model.PluginFile).ConfigureAwait(false); return(CreateSuccess(new { id = entity.EntityPluginId })); } return(CreateFailure(GetModelErrors())); }
/// <summary> /// Initiates a migration operation to the target migration version. /// </summary> /// <param name="plugin">The plugin whose migrations should be run.</param> /// <param name="targetMigration">The target migration.</param> public virtual void Migrate(EntityPlugin plugin, string targetMigration = null) { Logger.LogInformation(LoggingEvents.MigratingId, LoggingEvents.Migrating, plugin.Identifier, Connection.DbConnection.Database, Connection.DbConnection.DataSource); // // Verify the history table exists and if not create it. // if (!PluginHistoryRepository.Exists()) { var command = RawSqlCommandBuilder.Build(PluginHistoryRepository.GetCreateScript()); var query = new RelationalCommandParameterObject(Connection, null, null, CurrentContext.Context, CommandLogger); command.ExecuteNonQuery(query); } // // Get all the command lists to be executed. // var commandLists = GetMigrationCommandLists( plugin, PluginHistoryRepository.GetAppliedMigrations(plugin), targetMigration); // // Execute each command list in order. // foreach (var commandList in commandLists) { MigrationCommandExecutor.ExecuteNonQuery(commandList(), Connection); } }
public async Task <bool> Update(EntityPlugin entity, IFormFile file) { if (file != null) { await _entityPluginFileProvider.Save(file).ConfigureAwait(false); } return(Update(entity)); }
public bool Create(EntityPlugin entity, string fileName) { string savePath = _entityPluginFileProvider.Save(fileName); if (!string.IsNullOrWhiteSpace(savePath)) { return(Create(entity)); } return(false); }
/// <summary> /// 创建插件实例 /// </summary> /// <param name="entity"></param> /// <returns></returns> public IEntityPlugin GetInstance(EntityPlugin entity) { IEntityPlugin _instance = null; if (_entityPluginFileProvider.LoadAssembly(entity)) { _instance = (IEntityPlugin)_serviceResolver.ResolveUnregistered(Type.GetType(entity.ClassName, false, true)); } return(_instance); }
/// <summary> /// Generates down SQL scripts. /// </summary> /// <param name="plugin">The plugin.</param> /// <param name="migration">The migration.</param> /// <param name="previousMigration">The previous migration.</param> /// <returns></returns> protected virtual IReadOnlyList <MigrationCommand> GenerateDownSql(EntityPlugin plugin, Migration migration, Migration previousMigration) { var historyScript = PluginHistoryRepository.GetDeleteScript(plugin, migration.GetType().GetCustomAttribute <MigrationAttribute>().Id); var historyCommand = RawSqlCommandBuilder.Build(historyScript); return(MigrationsSqlGenerator .Generate(migration.DownOperations, previousMigration?.TargetModel) .Concat(new[] { new MigrationCommand(historyCommand, CurrentContext.Context, CommandLogger) }) .ToList()); }
public EntityPlugin FindById(Guid id) { var dic = new Dictionary <string, string>(); dic.Add("EntityPluginId", id.ToString()); EntityPlugin entity = _cacheService.Get(dic, () => { return(_entityPluginRepository.FindById(id)); }); return(entity); }
/// <summary> /// Generates up SQL scripts. /// </summary> /// <param name="plugin">The plugin.</param> /// <param name="migration">The migration.</param> /// <returns></returns> protected virtual IReadOnlyList <MigrationCommand> GenerateUpSql(EntityPlugin plugin, Migration migration) { var migrationId = migration.GetType().GetCustomAttribute <MigrationAttribute>()?.Id; var historyRow = new HistoryRow(migrationId, ProductInfo.GetVersion()); var historyScript = PluginHistoryRepository.GetInsertScript(plugin, historyRow); var historyCommand = RawSqlCommandBuilder.Build(historyScript); return(MigrationsSqlGenerator .Generate(migration.UpOperations, migration.TargetModel) .Concat(new[] { new MigrationCommand(historyCommand, CurrentContext.Context, CommandLogger) }) .ToList()); }
public bool Update(EntityPlugin entity) { var result = false; using (UnitOfWork.Build(_entityPluginRepository.DbContext)) { result = _entityPluginRepository.Update(entity); //set to cache _cacheService.SetEntity(entity); } return(result); }
/// <summary> /// Gets the SQL script to be executed in order to delete the /// specified migration's <see cref="HistoryRow" /> from the database. /// </summary> /// <param name="plugin">The plugin.</param> /// <param name="migrationId">The migration identifier.</param> /// <returns> /// A string containing the SQL statement. /// </returns> public string GetDeleteScript(EntityPlugin plugin, string migrationId) { var stringTypeMapping = Dependencies.TypeMappingSource.GetMapping(typeof(string)); var migrationIdColumn = Dependencies.SqlGenerationHelper .DelimitIdentifier(nameof(PluginHistoryRow.MigrationId)); var pluginColumn = Dependencies.SqlGenerationHelper .DelimitIdentifier(nameof(PluginHistoryRow.Plugin)); var tableName = Dependencies.SqlGenerationHelper .DelimitIdentifier(TableName); var pluginName = stringTypeMapping.GenerateSqlLiteral(plugin.Identifier); migrationId = stringTypeMapping.GenerateSqlLiteral(migrationId); return($"DELETE FROM {tableName} WHERE {pluginColumn} = {pluginName} AND {migrationIdColumn} = {migrationId}"); }
public bool Create(EntityPlugin entity) { entity.SolutionId = SolutionDefaults.DefaultSolutionId;//组件属于默认解决方案 entity.CreatedBy = _appContext.GetFeature <ICurrentUser>().SystemUserId; entity.OrganizationId = _appContext.OrganizationId; var result = true; using (UnitOfWork.Build(_entityPluginRepository.DbContext)) { result = _entityPluginRepository.Create(entity); //solution component _solutionComponentService.Create(entity.SolutionId, entity.EntityPluginId, PluginDefaults.ModuleName); //依赖于实体 _dependencyService.Create(PluginDefaults.ModuleName, entity.EntityPluginId, EntityDefaults.ModuleName, entity.EntityId); //add to cache _cacheService.SetEntity(entity); } return(result); }
/// <summary> /// Gets the applied migrations for the specified plugin. /// </summary> /// <param name="plugin">The plugin.</param> /// <returns> /// A read only list of <see cref="HistoryRow" /> objects that represent which migrations have been run. /// </returns> public IReadOnlyList <HistoryRow> GetAppliedMigrations(EntityPlugin plugin) { var rows = new List <HistoryRow>(); if (Exists()) { var command = Dependencies.RawSqlCommandBuilder .Build(GetAppliedMigrationsSql(plugin.Identifier)); using (var reader = command.ExecuteReader(GetParameterObject())) { while (reader.Read()) { rows.Add(new HistoryRow(reader.DbDataReader.GetString(0), reader.DbDataReader.GetString(1))); } } } return(rows); }
public bool LoadAssembly(EntityPlugin entity) { try { var dllPath = GetBaseDirectory() + entity.AssemblyName; if (!System.IO.File.Exists(dllPath)) { dllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, entity.AssemblyName); } if (System.IO.File.Exists(dllPath)) { //Assembly.LoadFile(dllPath); //byte[] b = System.IO.File.ReadAllBytes(dllPath); //Assembly.Load(b); AssemblyLoadContext.Default.LoadFromAssemblyPath(dllPath); return(true); } } catch { } return(false); }
/// <summary> /// Gets the SQL script to be executed in order to save the <see cref="HistoryRow" /> /// to the database. /// </summary> /// <param name="plugin">The plugin.</param> /// <param name="historyRow">The history row.</param> /// <returns> /// A string containg the SQL statement. /// </returns> public virtual string GetInsertScript(EntityPlugin plugin, HistoryRow historyRow) { var stringTypeMapping = Dependencies.TypeMappingSource.GetMapping(typeof(string)); var migrationIdColumn = Dependencies.SqlGenerationHelper .DelimitIdentifier(nameof(PluginHistoryRow.MigrationId)); var productVersionColumn = Dependencies.SqlGenerationHelper .DelimitIdentifier(nameof(PluginHistoryRow.ProductVersion)); var pluginColumn = Dependencies.SqlGenerationHelper .DelimitIdentifier(nameof(PluginHistoryRow.Plugin)); var tableName = Dependencies.SqlGenerationHelper .DelimitIdentifier(TableName); var pluginName = stringTypeMapping.GenerateSqlLiteral(plugin.Identifier); var migrationId = stringTypeMapping.GenerateSqlLiteral(historyRow.MigrationId); var productVersion = stringTypeMapping.GenerateSqlLiteral(historyRow.ProductVersion); return($"INSERT INTO {tableName} ({pluginColumn}, {migrationIdColumn}, {productVersionColumn}) VALUES ({pluginName}, {migrationId}, {productVersion})"); }
/// <summary> /// Populates the migration lists. /// </summary> /// <param name="plugin">The plugin.</param> /// <param name="appliedMigrationEntries">The applied migration entries.</param> /// <param name="targetMigration">The target migration.</param> /// <param name="migrationsToApply">The migrations to apply.</param> /// <param name="migrationsToRevert">The migrations to revert.</param> /// <param name="actualTargetMigration">The actual target migration.</param> protected virtual void PopulateMigrations( EntityPlugin plugin, IEnumerable <string> appliedMigrationEntries, string targetMigration, out IReadOnlyList <Migration> migrationsToApply, out IReadOnlyList <Migration> migrationsToRevert, out Migration actualTargetMigration) { var appliedMigrations = new Dictionary <string, TypeInfo>(); var unappliedMigrations = new Dictionary <string, TypeInfo>(); var migrations = plugin.GetMigrations().ToList(); if (migrations.Count == 0) { Logger.LogInformation(LoggingEvents.MigrationsNotFoundId, LoggingEvents.MigrationsNotFound, plugin.Name); } // // Determine the set of applied and unapplied migrations. // foreach (var migration in migrations) { var migrationId = migration.GetCustomAttribute <MigrationAttribute>().Id; if (appliedMigrationEntries.Contains(migrationId)) { appliedMigrations.Add(migrationId, migration.GetTypeInfo()); } else { unappliedMigrations.Add(migrationId, migration.GetTypeInfo()); } } // // Build the list of migrations to apply or revert. // if (string.IsNullOrEmpty(targetMigration)) { // // Migrate to latest version. // migrationsToApply = unappliedMigrations .OrderBy(m => m.Key) .Select(p => MigrationsAssembly.CreateMigration(p.Value, DatabaseProvider.Name)) .ToList(); migrationsToRevert = Array.Empty <Migration>(); actualTargetMigration = null; } else if (targetMigration == Migration.InitialDatabase) { // // Migrate to uninstalled. // migrationsToApply = Array.Empty <Migration>(); migrationsToRevert = appliedMigrations .OrderByDescending(m => m.Key) .Select(p => MigrationsAssembly.CreateMigration(p.Value, DatabaseProvider.Name)) .ToList(); actualTargetMigration = null; } else { // // Migrate to specific version. // migrationsToApply = unappliedMigrations .Where(m => string.Compare(m.Key, targetMigration, StringComparison.OrdinalIgnoreCase) <= 0) .OrderBy(m => m.Key) .Select(p => MigrationsAssembly.CreateMigration(p.Value, DatabaseProvider.Name)) .ToList(); migrationsToRevert = appliedMigrations .Where(m => string.Compare(m.Key, targetMigration, StringComparison.OrdinalIgnoreCase) > 0) .OrderByDescending(m => m.Key) .Select(p => MigrationsAssembly.CreateMigration(p.Value, DatabaseProvider.Name)) .ToList(); actualTargetMigration = appliedMigrations .Where(m => string.Compare(m.Key, targetMigration, StringComparison.OrdinalIgnoreCase) == 0) .Select(p => MigrationsAssembly.CreateMigration(p.Value, DatabaseProvider.Name)) .SingleOrDefault(); } }
public static string BuildKey(EntityPlugin entity) { return(entity.EntityId + "/" + entity.EventName + "/" + entity.EntityPluginId + "/"); }
/// <summary> /// Gets the migration command lists. /// </summary> /// <param name="plugin">The plugin.</param> /// <param name="appliedMigrationEntries">The applied migration entries.</param> /// <param name="targetMigration">The target migration.</param> /// <returns></returns> protected virtual IEnumerable <Func <IReadOnlyList <MigrationCommand> > > GetMigrationCommandLists(EntityPlugin plugin, IReadOnlyList <HistoryRow> appliedMigrationEntries, string targetMigration = null) { // // Identify all the migration classes and whether they need to be // applied or reverted. // PopulateMigrations( plugin, appliedMigrationEntries.Select(t => t.MigrationId), targetMigration, out var migrationsToApply, out var migrationsToRevert, out var actualTargetMigration); // // Loop through the migrations to be reverted and generate a // lazy loaded enumerable containing them. This needs to be a // for-next loop and not a foreach so we can track the previous // migration reference. // for (int i = 0; i < migrationsToRevert.Count; i++) { var migration = migrationsToRevert[i]; var index = i; yield return(() => { var migrationId = migration.GetType().GetCustomAttribute <MigrationAttribute>().Id; Logger.LogInformation(LoggingEvents.RevertingMigrationId, LoggingEvents.RevertingMigration, migrationId, plugin.Identifier); var previousMigration = index != migrationsToRevert.Count - 1 ? migrationsToRevert[index + 1] : actualTargetMigration; return GenerateDownSql(plugin, migration, previousMigration); }); } // // Loop through the migrations to be applied and generate a // lazy loaded enumable containing them. // foreach (var migration in migrationsToApply) { yield return(() => { var migrationId = migration.GetType().GetCustomAttribute <MigrationAttribute>().Id; Logger.LogInformation(LoggingEvents.ApplyingMigrationId, LoggingEvents.ApplyingMigration, migrationId, plugin.Identifier); return GenerateUpSql(plugin, migration); }); } if (migrationsToRevert.Count + migrationsToApply.Count == 0) { Logger.LogInformation(LoggingEvents.MigrationNotNeededId, LoggingEvents.MigrationNotNeeded); } }