Exemple #1
0
        private void usageCompleted(DatabaseWriteUsage usage)
        {
            int usages = Interlocked.Decrement(ref currentWriteUsages);

            try
            {
                currentWriteDidWrite |= usage.PerformedWrite;

                if (usages > 0)
                {
                    return;
                }

                if (currentWriteDidWrite)
                {
                    // explicitly dispose to ensure any outstanding flushes happen as soon as possible (and underlying resources are purged).
                    usage.Context.Dispose();

                    currentWriteDidWrite = false;

                    // once all writes are complete, we want to refresh thread-specific contexts to make sure they don't have stale local caches.
                    recycleThreadContexts();
                }
            }
            finally
            {
                Monitor.Exit(writeLock);
            }
        }
Exemple #2
0
        private void migrateSettings(DatabaseWriteUsage db)
        {
            // migrate ruleset settings. can be removed 20220315.
            var existingSettings = db.Context.DatabasedSetting;

            // previous entries in EF are removed post migration.
            if (!existingSettings.Any())
            {
                return;
            }

            using (var realm = realmContextFactory.CreateContext())
                using (var transaction = realm.BeginWrite())
                {
                    // only migrate data if the realm database is empty.
                    if (!realm.All <RealmRulesetSetting>().Any())
                    {
                        foreach (var dkb in existingSettings)
                        {
                            if (dkb.RulesetID == null)
                            {
                                continue;
                            }

                            string?shortName = getRulesetShortNameFromLegacyID(dkb.RulesetID.Value);

                            if (string.IsNullOrEmpty(shortName))
                            {
                                continue;
                            }

                            realm.Add(new RealmRulesetSetting
                            {
                                Key         = dkb.Key,
                                Value       = dkb.StringValue,
                                RulesetName = shortName,
                                Variant     = dkb.Variant ?? 0,
                            });
                        }
                    }

                    db.Context.RemoveRange(existingSettings);

                    transaction.Commit();
                }
        }
        private void usageCompleted(DatabaseWriteUsage usage)
        {
            int usages = Interlocked.Decrement(ref currentWriteUsages);

            try
            {
                currentWriteDidWrite |= usage.PerformedWrite;
                currentWriteDidError |= usage.Errors.Any();

                if (usages == 0)
                {
                    if (currentWriteDidError)
                    {
                        rollbacks.Value++;
                        currentWriteTransaction?.Rollback();
                    }
                    else
                    {
                        commits.Value++;
                        currentWriteTransaction?.Commit();
                    }

                    if (currentWriteDidWrite || currentWriteDidError)
                    {
                        // explicitly dispose to ensure any outstanding flushes happen as soon as possible (and underlying resources are purged).
                        usage.Context.Dispose();

                        // once all writes are complete, we want to refresh thread-specific contexts to make sure they don't have stale local caches.
                        recycleThreadContexts();
                    }

                    currentWriteTransaction = null;
                    currentWriteDidWrite    = false;
                    currentWriteDidError    = false;
                }
            }
            finally
            {
                Monitor.Exit(writeLock);
            }
        }
Exemple #4
0
        private void migrateSkins(DatabaseWriteUsage db)
        {
            // can be removed 20220530.
            var existingSkins = db.Context.SkinInfo
                                .Include(s => s.Files)
                                .ThenInclude(f => f.FileInfo)
                                .ToList();

            // previous entries in EF are removed post migration.
            if (!existingSkins.Any())
            {
                return;
            }

            var userSkinChoice = config.GetBindable <string>(OsuSetting.Skin);

            int.TryParse(userSkinChoice.Value, out int userSkinInt);

            switch (userSkinInt)
            {
            case EFSkinInfo.DEFAULT_SKIN:
                userSkinChoice.Value = SkinInfo.DEFAULT_SKIN.ToString();
                break;

            case EFSkinInfo.CLASSIC_SKIN:
                userSkinChoice.Value = SkinInfo.CLASSIC_SKIN.ToString();
                break;
            }

            using (var realm = realmContextFactory.CreateContext())
                using (var transaction = realm.BeginWrite())
                {
                    // only migrate data if the realm database is empty.
                    // note that this cannot be written as: `realm.All<SkinInfo>().All(s => s.Protected)`, because realm does not support `.All()`.
                    if (!realm.All <SkinInfo>().Any(s => !s.Protected))
                    {
                        foreach (var skin in existingSkins)
                        {
                            var realmSkin = new SkinInfo
                            {
                                Name              = skin.Name,
                                Creator           = skin.Creator,
                                Hash              = skin.Hash,
                                Protected         = false,
                                InstantiationInfo = skin.InstantiationInfo,
                            };

                            foreach (var file in skin.Files)
                            {
                                var realmFile = realm.Find <RealmFile>(file.FileInfo.Hash);

                                if (realmFile == null)
                                {
                                    realm.Add(realmFile = new RealmFile {
                                        Hash = file.FileInfo.Hash
                                    });
                                }

                                realmSkin.Files.Add(new RealmNamedFileUsage(realmFile, file.Filename));
                            }

                            realm.Add(realmSkin);

                            if (skin.ID == userSkinInt)
                            {
                                userSkinChoice.Value = realmSkin.ID.ToString();
                            }
                        }
                    }

                    db.Context.RemoveRange(existingSkins);
                    // Intentionally don't clean up the files, so they don't get purged by EF.

                    transaction.Commit();
                }
        }