Exemplo n.º 1
0
        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()));
        }
Exemplo n.º 2
0
        /// <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);
            }
        }
Exemplo n.º 3
0
 public async Task <bool> Update(EntityPlugin entity, IFormFile file)
 {
     if (file != null)
     {
         await _entityPluginFileProvider.Save(file).ConfigureAwait(false);
     }
     return(Update(entity));
 }
Exemplo n.º 4
0
        public bool Create(EntityPlugin entity, string fileName)
        {
            string savePath = _entityPluginFileProvider.Save(fileName);

            if (!string.IsNullOrWhiteSpace(savePath))
            {
                return(Create(entity));
            }
            return(false);
        }
Exemplo n.º 5
0
        /// <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);
        }
Exemplo n.º 6
0
        /// <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());
        }
Exemplo n.º 7
0
        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);
        }
Exemplo n.º 8
0
        /// <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());
        }
Exemplo n.º 9
0
        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}");
        }
Exemplo n.º 11
0
        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);
        }
Exemplo n.º 13
0
 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})");
        }
Exemplo n.º 15
0
        /// <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();
            }
        }
Exemplo n.º 16
0
 public static string BuildKey(EntityPlugin entity)
 {
     return(entity.EntityId + "/" + entity.EventName + "/" + entity.EntityPluginId + "/");
 }
Exemplo n.º 17
0
        /// <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);
            }
        }