|
1 |
| -using System.Collections.Concurrent; |
| 1 | +using System; |
| 2 | +using System.Collections.Concurrent; |
2 | 3 | using System.Collections.Generic;
|
3 | 4 | using System.Linq;
|
| 5 | +using System.Text.Json; |
4 | 6 | using System.Text.Json.Serialization;
|
5 | 7 | using Flow.Launcher.Infrastructure.Storage;
|
6 | 8 | using Flow.Launcher.Plugin;
|
7 | 9 |
|
8 | 10 | namespace Flow.Launcher.Storage
|
9 | 11 | {
|
10 |
| - public class FlowLauncherJsonStorageTopMostRecord : ISavable |
| 12 | + public class FlowLauncherJsonStorageTopMostRecord |
11 | 13 | {
|
12 | 14 | private readonly FlowLauncherJsonStorage<MultipleTopMostRecord> _topMostRecordStorage;
|
13 | 15 | private readonly MultipleTopMostRecord _topMostRecord;
|
14 | 16 |
|
15 | 17 | public FlowLauncherJsonStorageTopMostRecord()
|
16 | 18 | {
|
| 19 | + // Get old data & new data |
17 | 20 | var topMostRecordStorage = new FlowLauncherJsonStorage<TopMostRecord>();
|
18 |
| - var exist = topMostRecordStorage.Exists(); |
19 |
| - if (exist) |
20 |
| - { |
21 |
| - // Get old data |
22 |
| - var topMostRecord = topMostRecordStorage.Load(); |
| 21 | + _topMostRecordStorage = new FlowLauncherJsonStorage<MultipleTopMostRecord>(); |
| 22 | + |
| 23 | + // Check if data exist |
| 24 | + var oldDataExist = topMostRecordStorage.Exists(); |
| 25 | + var newDataExist = _topMostRecordStorage.Exists(); |
23 | 26 |
|
24 |
| - // Convert to new data |
25 |
| - _topMostRecordStorage = new FlowLauncherJsonStorage<MultipleTopMostRecord>(); |
| 27 | + // If new data exist, it means we have already migrated the old data |
| 28 | + // So we can safely delete the old data and load the new data |
| 29 | + if (newDataExist) |
| 30 | + { |
| 31 | + try |
| 32 | + { |
| 33 | + topMostRecordStorage.Delete(); |
| 34 | + } |
| 35 | + catch |
| 36 | + { |
| 37 | + // Ignored |
| 38 | + } |
26 | 39 | _topMostRecord = _topMostRecordStorage.Load();
|
27 |
| - _topMostRecord.Add(topMostRecord); |
28 | 40 | }
|
| 41 | + // If new data does not exist and old data exist, we need to migrate the old data to the new data |
| 42 | + else if (oldDataExist) |
| 43 | + { |
| 44 | + // Migrate old data to new data |
| 45 | + _topMostRecord = _topMostRecordStorage.Load(); |
| 46 | + _topMostRecord.Add(topMostRecordStorage.Load()); |
| 47 | + |
| 48 | + // Delete old data and save the new data |
| 49 | + try |
| 50 | + { |
| 51 | + topMostRecordStorage.Delete(); |
| 52 | + } |
| 53 | + catch |
| 54 | + { |
| 55 | + // Ignored |
| 56 | + } |
| 57 | + Save(); |
| 58 | + } |
| 59 | + // If both data do not exist, we just need to create a new data |
29 | 60 | else
|
30 | 61 | {
|
31 |
| - // Get new data |
32 |
| - _topMostRecordStorage = new FlowLauncherJsonStorage<MultipleTopMostRecord>(); |
33 | 62 | _topMostRecord = _topMostRecordStorage.Load();
|
34 | 63 | }
|
35 | 64 | }
|
@@ -109,6 +138,7 @@ internal void AddOrUpdate(Result result)
|
109 | 138 | public class MultipleTopMostRecord
|
110 | 139 | {
|
111 | 140 | [JsonInclude]
|
| 141 | + [JsonConverter(typeof(ConcurrentDictionaryConcurrentBagConverter))] |
112 | 142 | public ConcurrentDictionary<string, ConcurrentBag<Record>> records { get; private set; } = new();
|
113 | 143 |
|
114 | 144 | internal void Add(TopMostRecord topMostRecord)
|
@@ -207,6 +237,30 @@ internal void AddOrUpdate(Result result)
|
207 | 237 | }
|
208 | 238 | }
|
209 | 239 |
|
| 240 | + public class ConcurrentDictionaryConcurrentBagConverter : JsonConverter<ConcurrentDictionary<string, ConcurrentBag<Record>>> |
| 241 | + { |
| 242 | + public override ConcurrentDictionary<string, ConcurrentBag<Record>> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
| 243 | + { |
| 244 | + var dictionary = JsonSerializer.Deserialize<Dictionary<string, List<Record>>>(ref reader, options); |
| 245 | + var concurrentDictionary = new ConcurrentDictionary<string, ConcurrentBag<Record>>(); |
| 246 | + foreach (var kvp in dictionary) |
| 247 | + { |
| 248 | + concurrentDictionary.TryAdd(kvp.Key, new ConcurrentBag<Record>(kvp.Value)); |
| 249 | + } |
| 250 | + return concurrentDictionary; |
| 251 | + } |
| 252 | + |
| 253 | + public override void Write(Utf8JsonWriter writer, ConcurrentDictionary<string, ConcurrentBag<Record>> value, JsonSerializerOptions options) |
| 254 | + { |
| 255 | + var dict = new Dictionary<string, List<Record>>(); |
| 256 | + foreach (var kvp in value) |
| 257 | + { |
| 258 | + dict.Add(kvp.Key, kvp.Value.ToList()); |
| 259 | + } |
| 260 | + JsonSerializer.Serialize(writer, dict, options); |
| 261 | + } |
| 262 | + } |
| 263 | + |
210 | 264 | public class Record
|
211 | 265 | {
|
212 | 266 | public string Title { get; init; }
|
|
0 commit comments