예제 #1
0
        internal DatabaseChanges(Database oldDatabase, DestinationDatabase newDatabase, IList<TableChanges> tableChanges)
        {
            this.OldDatabase = oldDatabase;
            this.NewDatabase = newDatabase;
            this.ChangeType = ChangeType.UnChanged;

            if (!oldDatabase.Removed || !newDatabase.Removed)
            {
                if (oldDatabase.Removed)
                {
                    this.ChangeType = ChangeType.Added;
                    return;
                }

                if (newDatabase.Removed)
                {
                    this.ChangeType = ChangeType.Removed;
                    return;
                }

                if (tableChanges != null && tableChanges.Count > 0)
                {
                    this.ChangeType = ChangeType.Modified;

                    this._allRecords = tableChanges;
                }
            }
        }
예제 #2
0
        internal DatabaseChanges(Database oldDatabase, DestinationDatabase newDatabase, IList <TableChanges> tableChanges)
        {
            this.OldDatabase = oldDatabase;
            this.NewDatabase = newDatabase;
            this.ChangeType  = ChangeType.UnChanged;

            if (!oldDatabase.Removed || !newDatabase.Removed)
            {
                if (oldDatabase.Removed)
                {
                    this.ChangeType = ChangeType.Added;
                    return;
                }

                if (newDatabase.Removed)
                {
                    this.ChangeType = ChangeType.Removed;
                    return;
                }

                if (tableChanges != null && tableChanges.Count > 0)
                {
                    this.ChangeType = ChangeType.Modified;

                    this._allRecords = tableChanges;
                }
            }
        }
예제 #3
0
        /// <summary>
        /// 计算出两个数据库元数据的所有表差别
        /// </summary>
        /// <param name="oldDatabase">旧数据库</param>
        /// <param name="newDatabase">新数据库</param>
        /// <returns></returns>
        public static DatabaseChanges Distinguish(Database oldDatabase, DestinationDatabase newDatabase)
        {
            if (!oldDatabase.Removed)
            {
                oldDatabase.OrderByRelations();
            }
            if (!newDatabase.Removed)
            {
                newDatabase.OrderByRelations();
            }

            List <TableChanges> result = new List <TableChanges>();

            if (!oldDatabase.Removed && !newDatabase.Removed)
            {
                //先找出所有被删除的表
                foreach (var oldTable in oldDatabase.Tables.Reverse())
                {
                    if (newDatabase.FindTable(oldTable.Name) == null && !newDatabase.IsIgnored(oldTable.Name))
                    {
                        result.Add(new TableChanges(oldTable, null, ChangeType.Removed));
                    }
                }

                foreach (var newTable in newDatabase.Tables)
                {
                    if (!newDatabase.IsIgnored(newTable.Name))
                    {
                        var oldTable = oldDatabase.FindTable(newTable.Name);
                        //如果没有找到旧表,说明这个表是新加的。
                        if (oldTable == null)
                        {
                            result.Add(new TableChanges(null, newTable, ChangeType.Added));
                        }
                        else
                        {
                            //即不是新表,也不是旧表,计算两个表的区别
                            TableChanges record = Distinguish(oldTable, newTable);

                            //如果有区别,则记录下来
                            if (record != null)
                            {
                                result.Add(record);
                            }
                        }
                    }
                }
            }

            return(new DatabaseChanges(oldDatabase, newDatabase, result));
        }
예제 #4
0
        /// <summary>
        /// 计算出两个数据库元数据的所有表差别
        /// </summary>
        /// <param name="oldDatabase">旧数据库</param>
        /// <param name="newDatabase">新数据库</param>
        /// <returns></returns>
        public static DatabaseChanges Distinguish(Database oldDatabase, DestinationDatabase newDatabase)
        {
            if (!oldDatabase.Removed) { oldDatabase.OrderByRelations(); }
            if (!newDatabase.Removed) { newDatabase.OrderByRelations(); }

            List<TableChanges> result = new List<TableChanges>();

            if (!oldDatabase.Removed && !newDatabase.Removed)
            {
                //先找出所有被删除的表
                foreach (var oldTable in oldDatabase.Tables.Reverse())
                {
                    if (newDatabase.FindTable(oldTable.Name) == null && !newDatabase.IsIgnored(oldTable.Name))
                    {
                        result.Add(new TableChanges(oldTable, null, ChangeType.Removed));
                    }
                }

                foreach (var newTable in newDatabase.Tables)
                {
                    if (!newDatabase.IsIgnored(newTable.Name))
                    {
                        var oldTable = oldDatabase.FindTable(newTable.Name);
                        //如果没有找到旧表,说明这个表是新加的。
                        if (oldTable == null)
                        {
                            result.Add(new TableChanges(null, newTable, ChangeType.Added));
                        }
                        else
                        {
                            //即不是新表,也不是旧表,计算两个表的区别
                            TableChanges record = Distinguish(oldTable, newTable);

                            //如果有区别,则记录下来
                            if (record != null) { result.Add(record); }
                        }
                    }
                }
            }

            return new DatabaseChanges(oldDatabase, newDatabase, result);
        }
예제 #5
0
        public DestinationDatabase Read()
        {
            var tableEntityTypes = this.GetMappingEntityTypes();

            var result = new DestinationDatabase(this._dbSetting.Database);
            foreach (var item in this.IgnoreTables) { result.IgnoreTables.Add(item); }

            if (tableEntityTypes.Count == 0)
            {
                result.Removed = true;
            }
            else
            {
                var reader = new TypesMetaReader
                {
                    Database = result,
                    Entities = tableEntityTypes
                };
                reader.Read();
            }

            return result;
        }
예제 #6
0
        /// <summary>
        /// 自动移植到目标结构
        /// 注意,自动迁移时,同样执行相应时间段的手工迁移。
        /// </summary>
        /// <param name="destination">目标结构</param>
        public void MigrateTo(DestinationDatabase destination)
        {
            /*********************** 代码块解释 *********************************
             *
             * 主要更新逻辑如下:
             * 1 根据当前版本号,同步最新的历史记录。
             *      客户端被动升级:当给客户版本做更新时,一般使用开发人员的历史记录替换客户版本的历史记录,此时发生此逻辑:
             *      发现历史记录中有比当前数据库版本还要新的记录时,说明已经使用了最新版本的历史记录库,这时需要根据这些历史记录来升级数据库。
             * 2 如果是第一次创建库,则:先执行自动升级、然后再执行手工结构升级。
             * 2 如果是升级库,则:先执行手工结构升级、然后再执行自动升级。
             * 3 执行手工数据升级。
             *
            **********************************************************************/

            if (this.SupportHistory) { Must(this.MigrateToHistory(DateTime.MaxValue)); }

            var manualPendings = this.GetManualPendings();
            var schemaPending = manualPendings.Where(m => m.Type == ManualMigrationType.Schema).ToList();
            var dataPending = manualPendings.Where(m => m.Type == ManualMigrationType.Data).ToList();

            var dbMeta = this.DatabaseMetaReader.Read();
            var changeSet = ModelDiffer.Distinguish(dbMeta, destination);

            //判断是否正处于升级阶段。(或者是处于创建阶段。)
            //不能直接用 dbMeta.Tables.Count > 0 来判断,这是因为里面可能有 IgnoreTables 中指定表。
            var updating = changeSet.ChangeType == ChangeType.Removed ||
                changeSet.ChangeType == ChangeType.Modified && changeSet.TablesChanged.Count(t => t.ChangeType == ChangeType.Added) < destination.Tables.Count;
            if (updating)
            {
                Must(this.MigrateUpBatch(schemaPending));

                Must(this.AutoMigrate(changeSet));
            }
            else
            {
                if (manualPendings.Count > 0)
                {
                    //此时,自动升级的时间都应该小于所有手工升级
                    Must(this.AutoMigrate(changeSet, manualPendings[0].TimeId));
                }
                else
                {
                    Must(this.AutoMigrate(changeSet));
                }

                Must(this.MigrateUpBatch(schemaPending));
            }

            if (dataPending.Count > 0)
            {
                /*********************** 代码块解释 *********************************
                 *
                 * 由于之前把 结构升级 和 数据升级 分离开了,
                 * 所以有可能出现 数据升级 中的最后时间其实没有之前的 结构升级 或者 自动升级 的时间大,
                 * 这样就会导致 数据升级 后,版本号变得更小了。
                 * 所以这里需要判断如果这种情况发生,则忽略数据升级中的版本号。
                 *
                **********************************************************************/

                var dbVersion = this.GetDbVersion();
                var maxDataPending = dataPending.Max(m => m.TimeId);

                Must(this.MigrateUpBatch(dataPending));

                if (dbVersion > maxDataPending)
                {
                    this.DbVersionProvider.SetDbVersion(dbVersion);
                }
            }
        }