示例#1
0
        public static void BaselineDatabase(string host, string database, string username, string password, string scriptRoot)
        {
            using (var connection = DatabaseConnector.Connect(host, database, username, password, false))
            {
                var scripts = DatabaseStatus.GetPendingScripts(connection, scriptRoot);

                Log.Information("Found {Count} script files without change log records", scripts.Length);

                if (scripts.Length != 0)
                {
                    var commandText = new StringBuilder();
                    commandText.AppendLine("START TRANSACTION ISOLATION LEVEL REPEATABLE READ;");
                    commandText.AppendLine(AppliedChangeScriptLog.ChangesTableCreateScript);

                    foreach (var script in scripts)
                    {
                        Log.Information("Recording {FullPath} as {ScriptFile}", script.FullPath, script.RelativeName);
                        commandText.AppendLine(AppliedChangeScriptLog.CreateApplyLogScriptFor(script));
                    }

                    commandText.AppendLine("COMMIT TRANSACTION;");

                    Log.Information("Writing change log");
                    using (var command = new NpgsqlCommand(commandText.ToString(), connection))
                    {
                        command.ExecuteNonQuery();
                    }
                }

                Log.Information("Done");
            }
        }
示例#2
0
        private void CheckInstallation()
        {
            bool isEditing = webContext.ToAppRelative(webContext.Url.LocalUrl)
                             .StartsWith(webContext.ToAppRelative(editUrlManager.GetManagementInterfaceUrl()), StringComparison.InvariantCultureIgnoreCase);

            if (isEditing)
            {
                return;
            }

            DatabaseStatus status      = installer.GetStatus();
            Url            redirectUrl = Url.ResolveTokens(welcomeUrl);

            if (status.NeedsUpgrade)
            {
                redirectUrl = redirectUrl.AppendQuery("action", "upgrade");
            }
            else if (!status.IsInstalled)
            {
                redirectUrl = redirectUrl.AppendQuery("action", "install");
            }
            else if (status.NeedsRebase)
            {
                redirectUrl = redirectUrl.AppendQuery("action", "rebase");
            }
            else
            {
                return;
            }
            Trace.WriteLine("Redirecting to '" + redirectUrl + "' to handle status: " + status.ToStatusString());
            webContext.Response.Redirect(redirectUrl);
        }
示例#3
0
        public override MigrationResult Migrate(DatabaseStatus preSchemaUpdateStatus)
        {
            var alreadyUpdated = new HashSet <string>();

            int updatedItems = 0;

            using (var transaction = repository.BeginTransaction())
            {
                var detailsWithImages = repository.Find(
                    Parameter.Equal("ValueTypeKey", "String"),
                    Parameter.Like("StringValue", "%<img%")
                    );

                foreach (var detail in detailsWithImages)
                {
                    if (alreadyUpdated.Contains(detail.EnclosingItem.Name))
                    {
                        continue;
                    }

                    alreadyUpdated.Add(detail.EnclosingItem.Name);
                    linkTracker.UpdateLinks(detail.EnclosingItem);
                    itemRepository.SaveOrUpdate(detail.EnclosingItem);
                    updatedItems++;
                }

                repository.Flush();
                transaction.Commit();
            }

            return(new MigrationResult(this)
            {
                UpdatedItems = updatedItems
            });
        }
示例#4
0
        public static TwitterStatus Map([CanBeNull] DatabaseStatus status, [CanBeNull] StatusEnts statusEntities,
                                        [CanBeNull] IEnumerable <long> favorers, [CanBeNull] IEnumerable <long> retweeters,
                                        [CanBeNull] TwitterStatus originalStatus, bool isQuoted, [CanBeNull] TwitterUser user)
        {
            if (status == null)
            {
                throw new ArgumentNullException(nameof(status));
            }
            if (statusEntities == null)
            {
                throw new ArgumentNullException(nameof(statusEntities));
            }
            if (originalStatus == null)
            {
                throw new ArgumentNullException(nameof(originalStatus));
            }
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            if (status.RetweetOriginalId != originalStatus.Id)
            {
                throw new ArgumentException("Retweet id is mismatched.");
            }
            if (status.StatusType != StatusType.Tweet)
            {
                throw new ArgumentException("This overload targeting normal tweet.");
            }
            if (status.UserId != user.Id)
            {
                throw new ArgumentException("ID mismatched between staus and user.");
            }
            var ent = statusEntities.Memoize();

            if (ent.Any(e => e.ParentId != status.Id))
            {
                throw new ArgumentException("ID mismatched between status and entities.");
            }
            Tuple <int, int> displayTextRange = null;

            if (status.DisplayTextRangeBegin != null && status.DisplayTextRangeEnd != null)
            {
                displayTextRange = Tuple.Create(status.DisplayTextRangeBegin.Value, status.DisplayTextRangeEnd.Value);
            }
            Tuple <double, double> coords = null;

            if (status.Latitude != null && status.Longitude != null)
            {
                coords = Tuple.Create(status.Latitude.Value, status.Longitude.Value);
            }
            var favs    = favorers?.ToArray() ?? new long[0];
            var rts     = retweeters?.ToArray() ?? new long[0];
            var retweet = isQuoted ? null : originalStatus;
            var quote   = isQuoted ? originalStatus : null;

            return(new TwitterStatus(status.Id, user, status.Text, displayTextRange, status.CreatedAt,
                                     ent.Select(Map).ToArray(), status.Source, status.InReplyToStatusId, status.InReplyToOrRecipientUserId,
                                     favs, rts, status.InReplyToOrRecipientScreenName, coords, retweet, quote));
        }
示例#5
0
        public static void UpdateRecordedValues(DatabaseStatus status)
        {
            try
            {
                if (status.RootItem == null)
                    return;

                status.AppPath = status.RootItem[InstallationAppPath] as string;
                status.NeedsRebase = !string.IsNullOrEmpty(status.AppPath) && !string.Equals(status.AppPath, N2.Web.Url.ToAbsolute("~/"));

                Version v;
                if (status.RootItem[installationAssemblyVersion] != null && Version.TryParse(status.RootItem[installationAssemblyVersion].ToString(), out v))
                    status.RecordedAssemblyVersion = v;
                if (status.RootItem[installationFileVersion] != null && Version.TryParse(status.RootItem[installationFileVersion].ToString(), out v))
                    status.RecordedFileVersion = v;

                status.RecordedFeatures = status.RootItem.GetInstalledFeatures();

                status.RecordedImageSizes = status.RootItem.GetInstalledImageSizes().ToArray();
            }
            catch (Exception ex)
            {
                status.ItemsError = ex.Message;
            }
        }
示例#6
0
 public DbStatusCronTask(
     ILogger <DbStatusCronTask> logger,
     DatabaseStatus dbStatus)
 {
     _logger   = logger;
     _dbStatus = dbStatus;
 }
示例#7
0
        // Установка статуса базы
        DatabaseStatus SetStatus(DatabaseStatus status, string log = "")
        {
            var path = DirectoryPath + "status.cfg";
            var old  = Status;

            Status      = status;
            StatusLogId = log;

            if (File.Exists(path))
            {
                File.Delete(path);
            }

            if (status == DatabaseStatus.Ready || status == DatabaseStatus.Started)
            {
                return(old);
            }

            var fs = File.OpenWrite(path);
            var bw = new BinaryWriterFast(fs);

            bw.Write((int)status);
            bw.Write(log);

            fs.Close();

            return(old);
        }
示例#8
0
        public override MigrationResult Migrate(DatabaseStatus preSchemaUpdateStatus)
        {
            var alreadyUpdated = new HashSet <int>();

            int updatedItems = 0;

            using (var transaction = repository.BeginTransaction())
            {
                foreach (var detail in repository.Find("Name", Tracker.LinkDetailName))
                {
                    if (alreadyUpdated.Contains(detail.EnclosingItem.ID))
                    {
                        continue;
                    }

                    alreadyUpdated.Add(detail.EnclosingItem.ID);
                    linkTracker.UpdateLinks(detail.EnclosingItem);
                    itemRepository.SaveOrUpdate(detail.EnclosingItem);
                    updatedItems++;
                }
                repository.Flush();
                transaction.Commit();
            }

            return(new MigrationResult(this)
            {
                UpdatedItems = updatedItems
            });
        }
示例#9
0
        private static async Task <TwitterStatus> LoadDirectMessageAsync([NotNull] DatabaseStatus dbstatus)
        {
            if (dbstatus == null)
            {
                throw new ArgumentNullException("dbstatus");
            }
            if (dbstatus.InReplyToOrRecipientUserId == null)
            {
                throw new ArgumentException("dbstatus.InReplyToUserOrRecipientId is must not be null.");
            }
            var id        = dbstatus.Id;
            var user      = UserProxy.GetUserAsync(dbstatus.UserId);
            var recipient = UserProxy.GetUserAsync(dbstatus.InReplyToOrRecipientUserId.Value);
            var se        = Database.StatusEntityCrud.GetEntitiesAsync(id);

            try
            {
                return(Mapper.Map(dbstatus,
                                  await DatabaseUtil.RetryIfLocked(async() => await se),
                                  await user, await recipient));
            }
            catch (ArgumentNullException anex)
            {
                throw new DatabaseConsistencyException(
                          "データベースから必要なデータを読み出せませんでした。(モード: DM, ステータスID " + dbstatus.Id + ", ユーザID " + dbstatus.UserId + ")",
                          anex);
            }
        }
 public override bool IsApplicable(DatabaseStatus status)
 {
     return(status.DatabaseVersion < DatabaseStatus.RequiredDatabaseVersion ||
            !status.HasSchema ||
            repository.Find("State", ContentState.None).Any() ||
            repository.Find("State", ContentState.New).Any());
 }
示例#11
0
        public override MigrationResult Migrate(DatabaseStatus preSchemaUpdateStatus)
        {
            int updatedItems = 0;

            using (var tx = repository.BeginTransaction())
            {
                var itemsWithUntrackedLinks = repository.Find(Parameter.Like(null, "%/upload/%").Detail() & Parameter.IsNull("TrackedLinks").Detail());
                foreach (var item in itemsWithUntrackedLinks)
                {
                    tracker.UpdateLinks(item);
                    repository.SaveOrUpdate(item);
                    updatedItems++;
                }
                tx.Commit();
            }

            var path = config.UploadFolders.AllElements.Where(uf => !string.IsNullOrEmpty(uf.UrlPrefix)).Select(uf => uf.Path).FirstOrDefault();

            path = Url.ToAbsolute(path);

            return(new MigrationResult(this)
            {
                UpdatedItems = updatedItems,
                RedirectTo = "{ManagementUrl}/Content/LinkTracker/UpdateReferences.aspx"
                             + "?selectedUrl=" + path
                             + "&previousUrl=" + path
                             + "&location=upgrade"
            });
        }
示例#12
0
        public override MigrationResult Migrate(DatabaseStatus preSchemaUpdateStatus)
        {
            int updatedItems = 0;

            using (var transaction = repository.BeginTransaction())
            {
                foreach (var item in repository.Find("State", ContentState.New))
                {
                    if (item.IsExpired())
                    {
                        item.State = ContentState.Unpublished;
                    }
                    else if (item.IsPublished())
                    {
                        item.State = ContentState.Waiting;
                    }
                    else
                    {
                        item.State = ContentState.Published;
                    }

                    repository.SaveOrUpdate(item);
                    updatedItems++;
                }

                transaction.Commit();
            }

            return(new MigrationResult(this)
            {
                UpdatedItems = updatedItems
            });
        }
示例#13
0
 private void NotifyObservers(DatabaseStatus status)
 {
     foreach (var observer in observers)
     {
         observer.Notify(status);
     }
 }
示例#14
0
        private void SetDatabaseStatus(Database[] dbs, DatabaseStatus status)
        {
            for (int i = 1; i <= dbs.Length; i++)
            {
                Database db = dbs[i - 1];
                base.UpdateProgressAndDeclare(1, i, db.Name);
                switch (status)
                {
                case DatabaseStatus.Offline:
                    if (Force || ShouldProcess(db.Name, "Take Offline"))
                    {
                        db.SetOffline();
                    }

                    break;

                case DatabaseStatus.Online:
                    if (Force || ShouldProcess(db.Name, "Bring Online"))
                    {
                        db.SetOnline();
                    }
                    break;

                case DatabaseStatus.Detached:
                    if (Force || ShouldProcess(db.Name, "Detach Database"))
                    {
                        db.Parent.DetachDatabase(db.Name, true);
                    }
                    break;
                }
            }
        }
示例#15
0
        private void btnLogin_Click(object sender, EventArgs e)
        {
            if (tbUsername.Text == "")
            {
                MessageBox.Show("请输入用户名!");
                return;
            }
            if (tbPassword.Text == "")
            {
                MessageBox.Show("请输入密码!");
                return;
            }
            Database       db     = new Database();
            DatabaseStatus status = db.Login(tbUsername.Text, tbPassword.Text);

            if (status == DatabaseStatus.WrongPassword)
            {
                MessageBox.Show("密码错误!");
            }
            if (status == DatabaseStatus.Success)
            {
                ContactList formContact = new Contacts.ContactList(db);
                formContact.Show();
                this.Hide();
            }
            if (status == DatabaseStatus.UserNotExists)
            {
                MessageBox.Show("用户不存在");
            }
        }
示例#16
0
        private void btnOK_Click(object sender, EventArgs e)
        {
            if (tbUsername.Text == "")
            {
                MessageBox.Show("请输入用户名!");
                return;
            }
            if (tbPassword.Text == "")
            {
                MessageBox.Show("请输入密码!");
                return;
            }

            Database       db     = new Database();
            DatabaseStatus status = db.Register(tbUsername.Text, tbPassword.Text);

            if (status == DatabaseStatus.UserExists)
            {
                MessageBox.Show("用户已存在!");
            }
            if (status == DatabaseStatus.Success)
            {
                MessageBox.Show("用户注册成功!");
            }
        }
示例#17
0
        public static Tuple <DatabaseStatus, StatusEnts> Map([NotNull] TwitterStatus status)
        {
            if (status == null)
            {
                throw new ArgumentNullException("status");
            }
            var orig = status.RetweetedOriginal ?? status;
            var dbs  = new DatabaseStatus
            {
                CreatedAt         = status.CreatedAt,
                Id                = status.Id,
                BaseId            = status.RetweetedOriginalId ?? status.Id,
                RetweetId         = status.RetweetedOriginal != null ? status.Id : (long?)null,
                RetweetOriginalId = status.RetweetedOriginalId,
                InReplyToOrRecipientScreenName = status.Recipient != null ? status.Recipient.ScreenName : status.InReplyToScreenName,
                InReplyToStatusId          = orig.InReplyToStatusId,
                InReplyToOrRecipientUserId = status.Recipient != null ? status.Recipient.Id : orig.InReplyToUserId,
                Latitude              = status.Latitude,
                Longitude             = status.Longitude,
                Source                = status.Source,
                StatusType            = status.StatusType,
                Text                  = status.Text,
                UserId                = status.User.Id,
                BaseUserId            = orig.User.Id,
                RetweeterId           = status.RetweetedOriginal != null ? status.User.Id : (long?)null,
                RetweetOriginalUserId = status.RetweetedOriginal != null ? status.RetweetedOriginal.User.Id : (long?)null
            };
            var ent = status.Entities.Select(e => Map <DatabaseStatusEntity>(status.Id, e));

            return(Tuple.Create(dbs, ent));
        }
示例#18
0
        public override MigrationResult Migrate(DatabaseStatus preSchemaUpdateStatus)
        {
            var enumProperties = definitions.GetDefinitions()
                                 .SelectMany(d => d.Properties.Values.Where(p => p.PropertyType.IsEnum)
                                             .Select(p => new { Definition = d, Property = p }));

            using (var transaction = repository.BeginTransaction())
            {
                int updatedItems = 0;
                foreach (var enumProperty in enumProperties)
                {
                    var items = repository.Find(Parameter.TypeEqual(enumProperty.Definition.Discriminator) & Parameter.IsNotNull(enumProperty.Property.Name).Detail());
                    foreach (var item in items)
                    {
                        item[enumProperty.Property.Name] = item[enumProperty.Property.Name];
                        repository.SaveOrUpdate(item);
                    }
                }
                transaction.Commit();
                return(new MigrationResult(this)
                {
                    UpdatedItems = updatedItems
                });
            }
        }
 internal void setDatabaseConnectionStatus(DatabaseStatus status)
 {
     switch(status)
     {
         case DatabaseStatus.Connected:
             databaseConnectionIcon.BackgroundImage = Properties.Resources.db_connected_32;
             databaseConnectionLabel.Text = "Database Connected";
             break;
         case DatabaseStatus.Disconnected:
             databaseConnectionIcon.BackgroundImage = Properties.Resources.db_close_32;
             databaseConnectionLabel.Text = "Database Disconnected";
             break;
         case DatabaseStatus.Downloading:
             databaseConnectionIcon.BackgroundImage = Properties.Resources.db_download_32;
             databaseConnectionLabel.Text = "Connecting to Database";
             break;
         case DatabaseStatus.Writing:
             databaseConnectionIcon.BackgroundImage = Properties.Resources.db_write_32;
             databaseConnectionLabel.Text = "Writing Database";
             break;
         default:
             databaseConnectionIcon.BackgroundImage = Properties.Resources.db_close_32;
             databaseConnectionLabel.Text = "Database Disconnected";
             break;
     }
 }
示例#20
0
        public static void ApplyChangeScripts(string host, string database, string username, string password,
                                              bool createIfMissing, string scriptRoot, IReadOnlyDictionary <string, string> variables)
        {
            using (var connection = DatabaseConnector.Connect(host, database, username, password, createIfMissing))
            {
                var scripts = DatabaseStatus.GetPendingScripts(connection, scriptRoot);

                Log.Information("Found {Count} new script files to apply", scripts.Length);

                if (scripts.Length != 0)
                {
                    Log.Information("Ensuring the change log table exists");
                    using (var command = new NpgsqlCommand(AppliedChangeScriptLog.ChangesTableCreateScript, connection))
                        command.ExecuteNonQuery();
                }

                foreach (var script in scripts)
                {
                    Log.Information("Applying {FullPath} as {ScriptFile}", script.FullPath, script.RelativeName);
                    ApplyChangeScript(connection, script, variables);
                }

                Log.Information("Done");
            }
        }
示例#21
0
        private static async Task <TwitterStatus> LoadDirectMessageAsync([NotNull] DatabaseStatus dbstatus)
        {
            if (dbstatus == null)
            {
                throw new ArgumentNullException("dbstatus");
            }
            if (dbstatus.InReplyToOrRecipientUserId == null)
            {
                throw new ArgumentException("dbstatus.InReplyToUserOrRecipientId is must not be null.");
            }
            var id        = dbstatus.Id;
            var user      = UserProxy.GetUserAsync(dbstatus.UserId).ConfigureAwait(false);
            var recipient = UserProxy.GetUserAsync(dbstatus.InReplyToOrRecipientUserId.Value).ConfigureAwait(false);
            var se        = DatabaseUtil.RetryIfLocked(() => Database.StatusEntityCrud.GetEntitiesAsync(id)).ConfigureAwait(false);

            try
            {
                return(Mapper.Map(dbstatus, await se, await user, await recipient));
            }
            catch (ArgumentNullException anex)
            {
                throw new DatabaseConsistencyException(
                          "Lacking required data in database.(mode: DM, status ID " + dbstatus.Id + ", user ID " + dbstatus.UserId + ")",
                          anex);
            }
        }
示例#22
0
        public static TwitterStatus Map([NotNull] DatabaseStatus status, [NotNull] StatusEnts statusEntities,
                                        [CanBeNull] IEnumerable <long> favorers, [CanBeNull] IEnumerable <long> retweeters,
                                        [NotNull] TwitterStatus originalStatus, [NotNull] TwitterUser user)
        {
            if (status == null)
            {
                throw new ArgumentNullException("status");
            }
            if (statusEntities == null)
            {
                throw new ArgumentNullException("statusEntities");
            }
            if (originalStatus == null)
            {
                throw new ArgumentNullException("originalStatus");
            }
            if (user == null)
            {
                throw new ArgumentNullException("user");
            }

            if (status.RetweetOriginalId != originalStatus.Id)
            {
                throw new ArgumentException("Retweet id is mismatched.");
            }
            if (status.StatusType != StatusType.Tweet)
            {
                throw new ArgumentException("This overload targeting normal tweet.");
            }
            if (status.UserId != user.Id)
            {
                throw new ArgumentException("ID mismatched between staus and user.");
            }
            var ent = statusEntities.Memoize();

            if (ent.Any(e => e.ParentId != status.Id))
            {
                throw new ArgumentException("ID mismatched between status and entities.");
            }
            return(new TwitterStatus
            {
                CreatedAt = status.CreatedAt,
                Entities = ent.Select(Map).ToArray(),
                FavoritedUsers = favorers.Guard().ToArray(),
                Id = status.Id,
                InReplyToScreenName = status.InReplyToOrRecipientScreenName,
                InReplyToStatusId = status.InReplyToStatusId,
                InReplyToUserId = status.InReplyToOrRecipientUserId,
                Latitude = status.Latitude,
                Longitude = status.Longitude,
                RetweetedOriginal = originalStatus,
                RetweetedOriginalId = originalStatus.Id,
                RetweetedUsers = retweeters.Guard().ToArray(),
                Source = status.Source,
                StatusType = StatusType.Tweet,
                Text = status.Text,
                User = user,
            });
        }
示例#23
0
 protected void btnInstallAndMigrate_Click(object sender, EventArgs e)
 {
     ExecuteWithErrorHandling(() =>
     {
         ShowResults(Migrator.UpgradeAndMigrate());
     });
     status = null;
 }
示例#24
0
 protected void UpdateConnection(DatabaseStatus status)
 {
     //base.UpdateConnection(status);
     if (GetConnectionException() == null)
     {
         status.IsConnected = true;
     }
 }
示例#25
0
 public DatabaseStatus TestDatabaseConnection()
 {
     {
         var response = new DatabaseStatus();
         response.StatusMessage = $"Successfully opened connection to database: {_DbConnectionProvider.Invoke().Database}. Connection state: {_DbConnectionProvider.Invoke().State}";
         _logger.Info(response.StatusMessage);
         return(response);
     }
 }
示例#26
0
 public WhoisHub(
     ILogger <WhoisHub> logger,
     IStringLocalizer <WhoisHub> localizer,
     WhoisRequestQueue queue,
     IBackgroundTaskQueue <WhoisTaskQueue> taskQueue,
     WhoisCollection whois,
     DatabaseStatus serverStatus) : base(logger, localizer, queue, taskQueue)
 {
     _whois    = whois;
     _dbStatus = serverStatus;
 }
示例#27
0
 public override bool IsApplicable(DatabaseStatus status)
 {
     try
     {
         return(persister.Repository.Find(new Parameter("class", "Redirect")).Any(p => p.Parent is Models.Pages.LanguageRoot));
     }
     catch (Exception)
     {
         return(true);
     }
 }
示例#28
0
        public override MigrationResult Migrate(DatabaseStatus preSchemaUpdateStatus)
        {
            preSchemaUpdateStatus.RootItem[InstallationManager.InstallationAppPath] = webContext.ToAbsolute("~/");
            repository.Update(preSchemaUpdateStatus.RootItem);
            repository.Flush();

            return(new MigrationResult(this)
            {
                UpdatedItems = 1
            });
        }
        private DatabaseStatus GetDatabaseStatus(string databaseFilePath)
        {
            lock (statusesLock) {
                if (databaseStatuses.GetOrDefault(databaseFilePath) is null)
                {
                    databaseStatuses[databaseFilePath] = new DatabaseStatus();
                }
            }

            return(databaseStatuses[databaseFilePath]);
        }
示例#30
0
 public override bool IsApplicable(DatabaseStatus status)
 {
     try
     {
         return(status.RootItem != null && status.RootItem["RecordedAssemblyVersion"] == null);
     }
     catch (Exception)
     {
         return(false);
     }
 }
        private static void Maintainance(object o)
        {

            try
            {
                var url = o as MongodbServerUrl;

                LocalLoggingService.Info("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", "服务器",
                    string.Format("对服务器 '{0}' 开始一次维护", url.Name));

                Stopwatch sw = Stopwatch.StartNew();

                ServerInfo oldServerInfo = null;
                locker.EnterReadLock();
                if (servers.ContainsKey(url))
                    oldServerInfo = servers[url];
                locker.ExitReadLock();

                var serverInfo = new ServerInfo();
                serverInfo.Url = url;
                serverInfo.Databases = new List<DatabaseInfo>();
                var server = MongoServer.Create(url.Master);

                //元数据
                var metaDatabase = server.GetDatabase(MongodbServerConfiguration.MetaDataDbName);
                var metaCollectionNames = metaDatabase.GetCollectionNames().Where(name => !name.Contains("system.index")
                    && !name.Contains("$")).ToList();
                var descriptions = new List<MongodbDatabaseDescription>();

                foreach (var metaCollectionName in metaCollectionNames)
                {
                    try
                    {
                        var metaCollection = metaDatabase.GetCollection(metaCollectionName);
                        descriptions.Add(metaCollection.FindOneAs<MongodbDatabaseDescription>());
                    }
                    catch (Exception ex)
                    {
                        LocalLoggingService.Error("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter",
                            "获取元数据出错",ex.Message);
                    }
                }
                serverInfo.Descriptions = descriptions;

                //获取所有的数据库
                var databaseNames = server.GetDatabaseNames().Where(name =>
                {
                    var categories = descriptions.Select(description => description.DatabasePrefix).Distinct();
                    foreach (var categoryName in categories)
                    {
                        if (name.StartsWith(categoryName))
                            return true;
                    }
                    return false;
                }).ToList();

                Parallel.ForEach(databaseNames, databaseName =>
                {
                    var swdb = Stopwatch.StartNew();

                    if (!databaseName.Contains("__"))
                    {
                        LocalLoggingService.Warning("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", "数据库",
                            string.Format("数据库名 '{0}' 不包含__", databaseName));
                        return;
                    }

                    var datepart = databaseName.Substring(databaseName.LastIndexOf("__") + 2);
                    if (datepart.Length != 6)
                    {
                        LocalLoggingService.Warning("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", "数据库",
                            string.Format("数据名 '{0}' 日期部分长度不为6", databaseName));
                        return;
                    }

                    try
                    {
                        if (fristLoaded && oldServerInfo != null && oldServerInfo.Databases.Exists(db => db.DatabaseName == databaseName) && datepart != DateTime.Now.ToString("yyyyMM"))
                        {
                            var oldDb = oldServerInfo.Databases.SingleOrDefault(db => db.DatabaseName == databaseName);
                            if (oldDb != null)
                            {
                                if (!serverInfo.Databases.Contains(oldDb))
                                {
                                    serverInfo.Databases.Add(oldDb);
                                }
                                LocalLoggingService.Debug("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", "数据库",
                                    string.Format("对数据库 '{0}' 完成一次维护,直接使用现有数据.oldServerInfo", databaseName));
                                return;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        string reason = "";
                        if (oldServerInfo.Databases == null)
                            reason = "oldServerInfo.Databases == null";
                        else if (oldServerInfo.Databases.Exists(d => d == null))
                            reason = "oldServerInfo.Databases.Exists(d => d == null)";
                        else
                            reason = "other";
                        LocalLoggingService.Error("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter",
                            string.Format("获取已有数据库 {0} 出错:{1}", databaseName, reason), ex.ToString());
                    }

                    var database = server.GetDatabase(databaseName);

                    var databaseInfo = new DatabaseInfo();
                    databaseInfo.DatabaseName = databaseName;

                    try
                    {
                        var databaseStatusResult = database.GetStats();//获取数据库信息
                        if (databaseStatusResult != null)
                        {
                            var databaseStatus = new DatabaseStatus
                            {
                                AverageObjectSize = databaseStatusResult.AverageObjectSize,
                                CollectionCount = databaseStatusResult.CollectionCount,
                                DataSize = databaseStatusResult.DataSize,
                                FileSize = databaseStatusResult.FileSize,
                                IndexSize = databaseStatusResult.IndexSize,
                                IndexCount = databaseStatusResult.IndexCount,
                                ExtentCount = databaseStatusResult.ExtentCount,
                                ObjectCount = databaseStatusResult.ObjectCount,
                                StorageSize = databaseStatusResult.StorageSize,
                            };
                            databaseInfo.DatabaseStatus = databaseStatus;
                        }
                    }
                    catch (Exception ex)
                    {
                        LocalLoggingService.Error("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter",
                            string.Format("获取数据库 '{0}' 状态出错", databaseName), ex.ToString());
                    }

                    var prefixPart = databaseName.Substring(0, databaseName.LastIndexOf("__"));
                    databaseInfo.DatabasePrefix = prefixPart;
                    var date = DateTime.MinValue;
                    if (DateTime.TryParse(string.Format("{0}/{1}/{2}", datepart.Substring(0, 4), datepart.Substring(4, 2), "01"), out date))
                    {
                        databaseInfo.DatabaseDate = date;
                    }
                    else
                    {
                        LocalLoggingService.Warning("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter",
                            string.Format("数据库名 '{0}' 日期部分解析错误", databaseName));
                        return;
                    }

                    var description = descriptions.Where(d => d.DatabasePrefix == prefixPart).FirstOrDefault();
                    if (description == null)
                    {
                        LocalLoggingService.Warning("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", "数据库",
                            string.Format("没有取到数据描述 '{0}'", prefixPart));
                        return;
                    }

                    databaseInfo.Collections = new List<CollectionInfo>();

                    var expireDays = description.ExpireDays;
                    if (expireDays > 0)
                    {
                        if (databaseInfo.DatabaseDate.AddMonths(1).AddDays(-1).AddDays(expireDays) < DateTime.Now && datepart != DateTime.Now.ToString("yyyyMM"))
                        {
                            database.Drop();
                            LocalLoggingService.Info("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", "数据库",
                                string.Format("清除历史数据-删除库:{0}", databaseName));
                            return;
                        }
                    }

                    var collectionNames = database.GetCollectionNames().Where(name => !name.Contains("system.index")
                        && !name.Contains("$") && !name.Contains("__")).ToList();
                    foreach (var collectionName in collectionNames)
                    {
                        var swcoll = Stopwatch.StartNew();
                        try
                        {
                            var collection = database.GetCollection(collectionName);
                            //if (expireDays > 0)
                            //{
                            //    var statTimeColumn = description.MongodbColumnDescriptionList.FirstOrDefault(c => c.IsTimeColumn);
                            //    if (statTimeColumn != null)
                            //    {
                            //        var query = Query.LT(statTimeColumn.ColumnName, DateTime.Now.AddDays(-expireDays));
                            //        collection.Remove(query);
                            //        if (collection.Count() == 0)
                            //        {
                            //            collection.Drop();
                            //            LocalLoggingService.Info("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter 清除历史数据-无数据删除表", databaseName, collectionName);
                            //            continue;
                            //        }
                            //    }
                            //}

                            var collectionInfo = new CollectionInfo();
                            collectionInfo.CollectionName = collectionName;
                            collectionInfo.ListFilterColumns = new List<ListFilterColumnInfo>();
                            collectionInfo.CascadeFilterColumns = new List<CascadeFilterColumnInfo>();
                            collectionInfo.TextboxFilterColumns = new List<TextboxFilterColumnInfo>();

                            var collectionStatus = new CollectionStatus
                            {
                                IndexStatusList = new List<IndexStatus>(),
                            };
                            CollectionStatsResult collectionStatusResult = null;

                            try
                            {
                                if (collection.Count() > 0)
                                {
                                    collectionStatusResult = collection.GetStats();
                                    collectionStatus.AverageObjectSize = collectionStatusResult.AverageObjectSize;
                                    collectionStatus.DataSize = collectionStatusResult.DataSize;
                                    collectionStatus.StorageSize = collectionStatusResult.StorageSize;
                                    collectionStatus.LastExtentSize = collectionStatusResult.LastExtentSize;
                                    collectionStatus.Namespace = collectionStatusResult.Namespace;
                                    collectionStatus.ExtentCount = collectionStatusResult.ExtentCount;
                                    collectionStatus.Flags = collectionStatusResult.Flags;
                                    collectionStatus.IndexCount = collectionStatusResult.IndexCount;
                                    collectionStatus.ObjectCount = collectionStatusResult.ObjectCount;
                                    collectionStatus.PaddingFactor = collectionStatusResult.PaddingFactor;
                                    collectionStatus.TotalIndexSize = collectionStatusResult.TotalIndexSize;
                                }
                            }
                            catch (Exception ex)
                            {
                                LocalLoggingService.Error("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter 获取表状态出错",
                                    string.Format("库名:{0} 表名:{1}", databaseName, collectionName), ex.ToString());
                            }

                            var indexes = collection.GetIndexes();
                            collectionStatus.IndexStatusList = indexes.Select(i => new IndexStatus
                            {
                                Name = i.Name,
                                Namespace = i.Namespace,
                                Unique = i.IsUnique,
                            }).ToList();

                            collectionStatus.IndexStatusList.ForEach(i =>
                            {
                                if (collectionStatusResult != null && collectionStatusResult.IndexSizes.ContainsKey(i.Name))
                                    i.Size = collectionStatusResult.IndexSizes[i.Name];
                            });
                            collectionInfo.CollectionStatus = collectionStatus;

                            var indexColumnDescriptions = description.MongodbColumnDescriptionList.Where(c => c.MongodbIndexOption != MongodbIndexOption.None).ToList();
                            foreach (var indexColumnDescription in indexColumnDescriptions)
                            {
                                try
                                {
                                    switch (indexColumnDescription.MongodbIndexOption)
                                    {
                                        case MongodbIndexOption.Ascending:
                                            {
                                                collection.EnsureIndex(IndexKeys.Ascending(indexColumnDescription.ColumnName), IndexOptions.SetBackground(true));
                                                break;
                                            }
                                        case MongodbIndexOption.Descending:
                                            {
                                                collection.EnsureIndex(IndexKeys.Descending(indexColumnDescription.ColumnName), IndexOptions.SetBackground(true));
                                                break;
                                            }
                                        case MongodbIndexOption.AscendingAndUnique:
                                            {
                                                collection.EnsureIndex(IndexKeys.Ascending(indexColumnDescription.ColumnName), IndexOptions.SetBackground(true).SetUnique(true).SetDropDups(true));
                                                break;
                                            }
                                        case MongodbIndexOption.DescendingAndUnique:
                                            {
                                                collection.EnsureIndex(IndexKeys.Descending(indexColumnDescription.ColumnName), IndexOptions.SetBackground(true).SetUnique(true).SetDropDups(true));
                                                break;
                                            }
                                    }

                                }
                                catch (Exception ex)
                                {
                                    LocalLoggingService.Error("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", "创建索引出错", ex.Message);
                                }
                            }

                            collectionInfo.CollectionStatus.LastEnsureIndexTime = DateTime.Now;

                            //加载数据库中的元数据
                            var metaCollection = database.GetCollection("Metadata__" + collectionInfo.CollectionName);
                            var meta = metaCollection.FindOneAs<CollectionMetadata>();

                            if (meta == null)
                            {
                                meta = new CollectionMetadata
                                {
                                    CollectionName = collectionInfo.CollectionName,
                                    ListFilterColumns = new List<ListFilterColumnInfo>(),
                                    CascadeFilterColumns = new List<CascadeFilterColumnInfo>(),
                                    TextboxFilterColumns = new List<TextboxFilterColumnInfo>(),
                                };
                            }
                            var textboxColumnDescriptions = description.MongodbColumnDescriptionList.Where(c => c.MongodbFilterOption == MongodbFilterOption.TextBoxFilter).ToList();

                            foreach (var textboxColumnDescription in textboxColumnDescriptions)
                            {
                                if (!collectionInfo.CollectionStatus.IndexStatusList.Exists(index => index.Name.Contains(textboxColumnDescription.ColumnName)))
                                    continue;
                                var textboxColumnInfo = new TextboxFilterColumnInfo();
                                textboxColumnInfo.ColumnName = textboxColumnDescription.ColumnName;
                                collectionInfo.TextboxFilterColumns.Add(textboxColumnInfo);
                                if (meta.TextboxFilterColumns.Count(c => c.ColumnName == textboxColumnInfo.ColumnName) == 0)
                                    meta.TextboxFilterColumns.Add(textboxColumnInfo);
                            }

                            var filterColumnDescriptions = description.MongodbColumnDescriptionList.Where
                                (c => c.MongodbFilterOption == MongodbFilterOption.DropDownListFilter
                                || c.MongodbFilterOption == MongodbFilterOption.CheckBoxListFilter).ToList();

                            foreach (var filterColumnDescription in filterColumnDescriptions)
                            {
                                try
                                {
                                    if (!collectionInfo.CollectionStatus.IndexStatusList.Exists(index => index.Name.Contains(filterColumnDescription.ColumnName)))
                                        continue;

                                    var filterColumnInfo = new ListFilterColumnInfo();
                                    filterColumnInfo.ColumnName = filterColumnDescription.ColumnName;
                                    filterColumnInfo.DistinctValues = new List<ItemPair>();

                                    if (oldServerInfo != null && oldServerInfo.Databases != null)
                                    {
                                        var oldDatabase = oldServerInfo.Databases.FirstOrDefault(d => d != null && d.DatabaseName == databaseInfo.DatabaseName);
                                        if (oldDatabase != null && oldDatabase.Collections != null)
                                        {
                                            var oldCollection = oldDatabase.Collections.FirstOrDefault(d => d != null && d.CollectionName == collectionInfo.CollectionName);
                                            if (oldCollection != null && oldCollection.ListFilterColumns != null)
                                            {
                                                var oldColumn = oldCollection.ListFilterColumns.FirstOrDefault(d => d != null && d.ColumnName == filterColumnInfo.ColumnName);
                                                if (oldColumn != null)
                                                {
                                                    filterColumnInfo.DistinctValues = oldColumn.DistinctValues;
                                                }
                                            }
                                        }
                                    }

                                    var column = meta.ListFilterColumns.SingleOrDefault(c => c.ColumnName == filterColumnDescription.ColumnName);
                                    if (column != null)
                                    {
                                        foreach (var value in filterColumnInfo.DistinctValues)
                                        {
                                            if (column.DistinctValues.Count(v => string.Equals(v.Value.ToString(), value.Value.ToString(), StringComparison.InvariantCultureIgnoreCase)) == 0)
                                            {
                                                LocalLoggingService.Debug("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", "列",
                                                string.Format("添加新过滤索引项 {0} 到元数据 {1}.{2}.{3}", value.Value.ToString(), databaseName, collectionName, column.ColumnName));
                                                column.DistinctValues.Add(value);
                                            }
                                        }
                                        filterColumnInfo.DistinctValues = column.DistinctValues;
                                    }
                                    else
                                    {
                                        meta.ListFilterColumns.Add(filterColumnInfo);
                                    }
                                    collectionInfo.ListFilterColumns.Add(filterColumnInfo);
                                }
                                catch (Exception ex)
                                {
                                    LocalLoggingService.Error("{0} {1} {2} {3} {4}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", "列",
                                        "创建过滤数据出错", ex.Message);
                                }
                            }

                            var cascadeFilterColumnDescriptions = description.MongodbColumnDescriptionList.Where(c => c.MongodbCascadeFilterOption != MongodbCascadeFilterOption.None).ToList();
                            foreach (var cascadeFilterColumnDescription in cascadeFilterColumnDescriptions)
                            {
                                try
                                {
                                    if (!collectionInfo.CollectionStatus.IndexStatusList.Exists(index => index.Name.Contains(cascadeFilterColumnDescription.ColumnName)))
                                        continue;

                                    var filterColumnInfo = new CascadeFilterColumnInfo();
                                    filterColumnInfo.ColumnName = cascadeFilterColumnDescription.ColumnName;
                                    filterColumnInfo.DistinctValues = new List<string>();
                                    if (oldServerInfo != null && oldServerInfo.Databases != null)
                                    {
                                        var oldDatabase = oldServerInfo.Databases.FirstOrDefault(d => d != null && d.DatabaseName == databaseInfo.DatabaseName);
                                        if (oldDatabase != null && oldDatabase.Collections != null)
                                        {
                                            var oldCollection = oldDatabase.Collections.FirstOrDefault(d => d != null && d.CollectionName == collectionInfo.CollectionName);
                                            if (oldCollection != null && oldCollection.CascadeFilterColumns != null)
                                            {
                                                var oldColumn = oldCollection.CascadeFilterColumns.FirstOrDefault(d => d != null && d.ColumnName == filterColumnInfo.ColumnName);
                                                if (oldColumn != null)
                                                {
                                                    filterColumnInfo.DistinctValues = oldColumn.DistinctValues;
                                                }
                                            }
                                        }
                                    }

                                    var column = meta.CascadeFilterColumns.SingleOrDefault(c => c.ColumnName == cascadeFilterColumnDescription.ColumnName);
                                    if (column != null)
                                    {
                                        foreach (var value in filterColumnInfo.DistinctValues)
                                        {
                                            if (column.DistinctValues.Count(v => string.Equals(v, value, StringComparison.InvariantCultureIgnoreCase)) == 0)
                                            {
                                                LocalLoggingService.Debug("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", "列",
                                                string.Format("添加新级联过滤索引项 {0} 到元数据 {1}.{2}.{3}", value, databaseName, collectionName, column.ColumnName));
                                                column.DistinctValues.Add(value);
                                            }
                                        }
                                        filterColumnInfo.DistinctValues = column.DistinctValues;
                                    }
                                    else
                                    {
                                        meta.CascadeFilterColumns.Add(filterColumnInfo);
                                    }
                                    collectionInfo.CascadeFilterColumns.Add(filterColumnInfo);
                                }
                                catch (Exception ex)
                                {
                                    LocalLoggingService.Error("{0} {1} {2} {3} {4}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", "列",
                                        "创建级联过滤数据出错", ex.Message);
                                }
                            }

                            try
                            {
                                metaCollection.Save(meta);
                            }
                            catch (Exception ex)
                            {
                                LocalLoggingService.Error("{0} {1} {2} {3} {4}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", "表",
                                   "保存表元数据出错", ex.Message);
                            }
                            databaseInfo.Collections.Add(collectionInfo);
                        }
                        catch (Exception ex)
                        {
                            LocalLoggingService.Error("{0} {1} {2} {3} {4}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", "表",
                                "维护其它出错", ex.Message);
                        }
                    }

                    if (databaseInfo.Collections.Count == 0)
                    {
                        //database.Drop();
                        //AppInfoCenterService.LoggingService.Debug(MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", "数据库",
                        //    string.Format("清除历史数据-删除库:{0}", databaseName));
                    }
                    else
                    {
                        if (!serverInfo.Databases.Contains(databaseInfo))
                        {
                            serverInfo.Databases.Add(databaseInfo);
                        }
                    }

                    LocalLoggingService.Debug("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", "数据库",
                        string.Format("对数据库 '{0}' 完成一次维护,耗时 {1} 毫秒", databaseName, swdb.ElapsedMilliseconds));
                });

                LocalLoggingService.Info("{0} {1} {2} {3}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", "服务器",
                    string.Format("对服务器 '{0}' 完成一次维护,耗时 {1} 毫秒", url.Name, sw.ElapsedMilliseconds));

                locker.EnterWriteLock();
                if (servers.ContainsKey(url))
                    servers[url] = serverInfo;
                else
                    servers.Add(url, serverInfo);
                locker.ExitWriteLock();

                fristLoaded = true;

            }
            catch (Exception ex)
            {
                LocalLoggingService.Error("{0} {1} {2}", MongodbServerConfiguration.ModuleName, "MongodbServerMaintainceCenter", ex.Message);
            }
        }