Skip to content

Commit f5c382d

Browse files
committed
add support for importing records
1 parent 6ec8a0b commit f5c382d

File tree

12 files changed

+101
-41
lines changed

12 files changed

+101
-41
lines changed

src/Flow.Launcher.Plugin.ClipboardPlus.Core.Test/DatabaseHelperTest.cs

+12-12
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ public async Task TestInsertRecord()
113113
cache: SqliteCacheMode.Private
114114
);
115115
await helper.InitializeDatabaseAsync();
116-
await helper.AddOneRecordAsync(exampleTextRecord);
117-
var c = await helper.GetAllRecordsAsync();
116+
await helper.AddOneRecordAsync(exampleTextRecord, true);
117+
var c = await helper.GetAllRecordsAsync(true);
118118
var find = false;
119119
foreach (var record in c)
120120
{
@@ -163,7 +163,7 @@ public async Task TestDeleteRecordBefore(int type, string creatTime, int keepTim
163163
}
164164
// helper.Connection.BackupDatabase(new SqliteConnection("Data Source=a.db"));
165165
await helper.DeleteRecordsByKeepTimeAsync(type, keepTime);
166-
var recordsAfterDelete = await helper.GetAllRecordsAsync((str) => _testOutputHelper.WriteLine($"{str}"));
166+
var recordsAfterDelete = await helper.GetAllRecordsAsync(true, (str) => _testOutputHelper.WriteLine($"{str}"));
167167
foreach (var record in recordsAfterDelete.Where(r => r.DataType == (DataType)type))
168168
{
169169
var expTime = record.CreateTime + TimeSpan.FromHours(keepTime);
@@ -187,11 +187,11 @@ public async Task TestPinRecord()
187187
cache: SqliteCacheMode.Private
188188
);
189189
await helper.InitializeDatabaseAsync();
190-
await helper.AddOneRecordAsync(exampleTextRecord);
191-
var c1 = (await helper.GetAllRecordsAsync()).First();
190+
await helper.AddOneRecordAsync(exampleTextRecord, true);
191+
var c1 = (await helper.GetAllRecordsAsync(true)).First();
192192
exampleTextRecord.Pinned = !exampleTextRecord.Pinned;
193193
await helper.PinOneRecordAsync(exampleTextRecord);
194-
var c2 = (await helper.GetAllRecordsAsync()).First();
194+
var c2 = (await helper.GetAllRecordsAsync(true)).First();
195195
Assert.Equal(c1.Pinned, !c2.Pinned);
196196
await helper.CloseAsync();
197197
}
@@ -207,9 +207,9 @@ public async Task TestDeleteOneRecord()
207207
cache: SqliteCacheMode.Private
208208
);
209209
await helper.InitializeDatabaseAsync();
210-
await helper.AddOneRecordAsync(exampleTextRecord);
210+
await helper.AddOneRecordAsync(exampleTextRecord, true);
211211
await helper.DeleteOneRecordAsync(exampleTextRecord);
212-
var c = await helper.GetAllRecordsAsync();
212+
var c = await helper.GetAllRecordsAsync(true);
213213
Assert.Empty(c);
214214
await helper.CloseAsync();
215215
}
@@ -231,7 +231,7 @@ public async Task TestDeleteInvalidRecord()
231231
{
232232
var valid = _random.NextDouble() > 0.5;
233233
var exampleTextRecord = GetRandomClipboardData(valid);
234-
await helper.AddOneRecordAsync(exampleTextRecord);
234+
await helper.AddOneRecordAsync(exampleTextRecord, true);
235235
if (valid)
236236
{
237237
validNum++;
@@ -244,7 +244,7 @@ public async Task TestDeleteInvalidRecord()
244244
}
245245
}
246246
await helper.DeleteInvalidRecordsAsync();
247-
var c = await helper.GetAllRecordsAsync();
247+
var c = await helper.GetAllRecordsAsync(true);
248248
_testOutputHelper.WriteLine("After Delete Invalid Data");
249249
var num = 0;
250250
foreach (var record in c)
@@ -273,7 +273,7 @@ public async Task TestDeleteUnpinnedRecord()
273273
var pinned = _random.NextDouble() > 0.5;
274274
var exampleTextRecord = GetRandomClipboardData();
275275
exampleTextRecord.Pinned = pinned;
276-
await helper.AddOneRecordAsync(exampleTextRecord);
276+
await helper.AddOneRecordAsync(exampleTextRecord, true);
277277
if (pinned)
278278
{
279279
pinnedNum++;
@@ -286,7 +286,7 @@ public async Task TestDeleteUnpinnedRecord()
286286
}
287287
}
288288
await helper.DeleteUnpinnedRecordsAsync();
289-
var c = await helper.GetAllRecordsAsync();
289+
var c = await helper.GetAllRecordsAsync(true);
290290
_testOutputHelper.WriteLine("After Delete Unpinned Data");
291291
var num = 0;
292292
foreach (var record in c)

src/Flow.Launcher.Plugin.ClipboardPlus.Core/Data/Contracts/IClipboardPlus.cs

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ public interface IClipboardPlus
88

99
public SqliteDatabase Database { get; }
1010

11+
Task InitRecordsFromDatabaseAsync();
12+
1113
public ISettings Settings { get; }
1214

1315
public ISettings LoadSettingJsonStorage();

src/Flow.Launcher.Plugin.ClipboardPlus.Core/Helpers/DatabaseHelper.cs

+26-8
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ public static class DatabaseHelper
77
public static async Task ExportDatabase(IClipboardPlus clipboardPlus, string jsonPath)
88
{
99
var database = clipboardPlus.Database;
10-
var records = await database.GetAllRecordsAsync();
10+
var records = await database.GetAllRecordsAsync(false);
1111
var jsonRecords = records.Select(JsonClipboardData.FromClipboardData);
12+
var addedCount = jsonRecords.Count();
1213
var options = new JsonSerializerOptions { WriteIndented = true };
1314
await using FileStream createStream = File.Create(jsonPath);
1415
await JsonSerializer.SerializeAsync(createStream, jsonRecords, options);
1516
var context = clipboardPlus.Context;
1617
context?.API.ShowMsg(context.GetTranslation("flowlauncher_plugin_clipboardplus_success"),
17-
context.GetTranslation("flowlauncher_plugin_clipboardplus_export_succeeded"));
18+
string.Format(context.GetTranslation("flowlauncher_plugin_clipboardplus_export_succeeded"), addedCount));
1819
}
1920

2021
public static async Task ImportDatabase(IClipboardPlus clipboardPlus, string jsonPath)
@@ -34,17 +35,34 @@ public static async Task ImportDatabase(IClipboardPlus clipboardPlus, string jso
3435
{
3536
var database = clipboardPlus.Database;
3637
var records = jsonRecords.Select(r => ClipboardData.FromJsonClipboardData(r, true));
37-
var databaseRecords = await database.GetAllRecordsAsync();
38-
if (!databaseRecords.Any())
38+
var databaseRecords = await database.GetAllRecordsAsync(false);
39+
var addedCount = 0;
40+
if (!databaseRecords.Any()) // if there are no records in the database, then add all records
3941
{
40-
// TODO: Add records
42+
await database.AddRecordsAsync(records, true);
43+
addedCount = records.Count();
4144
}
42-
else
45+
else // if there are records in the database, then add only the records that are not already in the database
4346
{
44-
// TODO: Merge records
47+
var addedClipboardData = new List<ClipboardData>();
48+
foreach (var record in records)
49+
{
50+
// if hashId & encryptKeyMd5 are equal, then the record is already in the database
51+
if (databaseRecords.Any(r => r.HashId == record.HashId && r.EncryptKeyMd5 == record.EncryptKeyMd5))
52+
{
53+
continue;
54+
}
55+
addedClipboardData.Add(record);
56+
}
57+
await database.AddRecordsAsync(addedClipboardData, true);
58+
addedCount = addedClipboardData.Count;
59+
}
60+
if (addedCount > 0)
61+
{
62+
await clipboardPlus.InitRecordsFromDatabaseAsync();
4563
}
4664
context?.API.ShowMsg(context.GetTranslation("flowlauncher_plugin_clipboardplus_success"),
47-
context.GetTranslation("flowlauncher_plugin_clipboardplus_import_succeeded"));
65+
string.Format(context.GetTranslation("flowlauncher_plugin_clipboardplus_import_succeeded"), addedCount));
4866
}
4967
else
5068
{

src/Flow.Launcher.Plugin.ClipboardPlus.Core/Helpers/SqliteDatabase.cs

+41-9
Original file line numberDiff line numberDiff line change
@@ -314,23 +314,23 @@ await HandleOpenCloseAsync(async () =>
314314
}
315315

316316
#if DEBUG
317-
public async Task AddOneRecordAsync(ClipboardData data, bool needEncryptData = true, Action<string>? action = null)
317+
public async Task AddOneRecordAsync(ClipboardData data, bool needEncryptData, Action<string>? action = null)
318318
#else
319-
public async Task AddOneRecordAsync(ClipboardData data, bool needEncryptData = true)
319+
public async Task AddOneRecordAsync(ClipboardData data, bool needEncryptData)
320320
#endif
321321
{
322322
await HandleOpenCloseAsync(async () =>
323323
{
324324
// insert asset
325325
var assets = new List<Asset>
326326
{
327-
Asset.FromClipboardData(data, true)
327+
Asset.FromClipboardData(data, needEncryptData)
328328
};
329329
await Connection.ExecuteAsync(SqlInsertAsset, assets);
330330

331331
// insert record
332332
// note: you must insert record after data
333-
var record = Record.FromClipboardData(data, true);
333+
var record = Record.FromClipboardData(data, needEncryptData);
334334
#if DEBUG
335335
if (record.DataType == (int)DataType.Files && record.EncryptData == true)
336336
{
@@ -341,6 +341,31 @@ await HandleOpenCloseAsync(async () =>
341341
});
342342
}
343343

344+
public async Task AddRecordsAsync(IEnumerable<ClipboardData> datas, bool needEncryptData)
345+
{
346+
if (datas.Count() == 0)
347+
{
348+
return;
349+
}
350+
await HandleOpenCloseAsync(async () =>
351+
{
352+
foreach (var data in datas)
353+
{
354+
// insert asset
355+
var assets = new List<Asset>
356+
{
357+
Asset.FromClipboardData(data, needEncryptData)
358+
};
359+
await Connection.ExecuteAsync(SqlInsertAsset, assets);
360+
361+
// insert record
362+
// note: you must insert record after data
363+
var record = Record.FromClipboardData(data, needEncryptData);
364+
await Connection.ExecuteAsync(SqlInsertRecord, record);
365+
}
366+
});
367+
}
368+
344369
public async Task DeleteOneRecordAsync(ClipboardData clipboardData)
345370
{
346371
await HandleOpenCloseAsync(async () =>
@@ -369,17 +394,24 @@ await HandleOpenCloseAsync(async () =>
369394
}
370395

371396
#if DEBUG
372-
public async Task<List<ClipboardData>> GetAllRecordsAsync(Action<string>? action = null)
397+
public async Task<List<ClipboardData>> GetAllRecordsAsync(bool needSort, Action<string>? action = null)
373398
#else
374-
public async Task<List<ClipboardData>> GetAllRecordsAsync()
399+
public async Task<List<ClipboardData>> GetAllRecordsAsync(bool needSort)
375400
#endif
376401
{
377402
return await HandleOpenCloseAsync(async () =>
378403
{
379-
// query all records
380-
var results = await Connection.QueryAsync<Record>(SqlSelectAllRecordOrederedByDateTimeScore);
404+
// query all records & return
405+
if (!needSort)
406+
{
407+
var results = await Connection.QueryAsync<Record>(SqlSelectAllRecord);
408+
return results.Select(ClipboardData.FromRecord).ToList();
409+
}
410+
411+
// query all records & build record list
412+
var sortedResults = await Connection.QueryAsync<Record>(SqlSelectAllRecordOrederedByDateTimeScore);
381413
var allRecord = new List<ClipboardData>();
382-
foreach (var record in results)
414+
foreach (var record in sortedResults)
383415
{
384416
try
385417
{

src/Flow.Launcher.Plugin.ClipboardPlus.Panels.Test/ClipboardPlus.cs

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Globalization;
22
using System;
33
using System.IO;
4+
using System.Threading.Tasks;
45

56
namespace Flow.Launcher.Plugin.ClipboardPlus.Panels.Test;
67

@@ -10,6 +11,11 @@ internal class ClipboardPlus : IClipboardPlus
1011

1112
public SqliteDatabase Database { get; } = new SqliteDatabase(Path.Combine(AppContext.BaseDirectory, "ClipboardPlus.db"), 1);
1213

14+
public async Task InitRecordsFromDatabaseAsync()
15+
{
16+
await Task.CompletedTask;
17+
}
18+
1319
public ISettings Settings { get; }
1420

1521
public ClipboardPlus()

src/Flow.Launcher.Plugin.ClipboardPlus.Panels.Test/MainWindow.xaml.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ private void InitializeWindow()
323323
private async void InitializeDatabase()
324324
{
325325
await ClipboardPlus.Database.InitializeDatabaseAsync();
326-
RecordList = await ClipboardPlus.Database.GetAllRecordsAsync();
326+
RecordList = await ClipboardPlus.Database.GetAllRecordsAsync(true);
327327
var str = string.Empty;
328328
foreach (var record in RecordList)
329329
{

src/Flow.Launcher.Plugin.ClipboardPlus.Panels/ViewModels/SettingsViewModel.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,10 @@ private void FormatStringInsert(object? parameter)
8383
private async void ImportJsonRecords(object? parameter)
8484
{
8585
var path = FileUtils.GetOpenJsonFile();
86-
await DatabaseHelper.ImportDatabase(ClipboardPlus, path);
86+
if (!string.IsNullOrEmpty(path))
87+
{
88+
await DatabaseHelper.ImportDatabase(ClipboardPlus, path);
89+
}
8790
}
8891

8992
public ICommand ExportJsonRecordsCommand => new RelayCommand(ExportJsonRecords);

src/Flow.Launcher.Plugin.ClipboardPlus.Panels/Views/SettingsPanel.xaml

+1-2
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,7 @@
367367
HorizontalAlignment="Left"
368368
VerticalAlignment="Center"
369369
Command="{Binding ImportJsonRecordsCommand}"
370-
Content="{DynamicResource flowlauncher_plugin_clipboardplus_import_records}"
371-
IsEnabled="False" />
370+
Content="{DynamicResource flowlauncher_plugin_clipboardplus_import_records}" />
372371
<Button
373372
Margin="5,0,0,0"
374373
HorizontalAlignment="Left"

src/Flow.Launcher.Plugin.ClipboardPlus/Languages/en.xaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@
104104
<system:String x:Key="flowlauncher_plugin_clipboardplus_import_records">Import records</system:String>
105105
<system:String x:Key="flowlauncher_plugin_clipboardplus_export_records">Export records</system:String>
106106

107-
<system:String x:Key="flowlauncher_plugin_clipboardplus_export_succeeded">Export succeeded!</system:String>
108-
<system:String x:Key="flowlauncher_plugin_clipboardplus_import_succeeded">Import succeeded!</system:String>
107+
<system:String x:Key="flowlauncher_plugin_clipboardplus_export_succeeded">Export {0} records succeeded!</system:String>
108+
<system:String x:Key="flowlauncher_plugin_clipboardplus_import_succeeded">Import {0} records succeeded!</system:String>
109109
<system:String x:Key="flowlauncher_plugin_clipboardplus_import_failed">Import failed!</system:String>
110110

111111
<!-- Enum -->

src/Flow.Launcher.Plugin.ClipboardPlus/Languages/zh-cn.xaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@
104104
<system:String x:Key="flowlauncher_plugin_clipboardplus_import_records">导入记录</system:String>
105105
<system:String x:Key="flowlauncher_plugin_clipboardplus_export_records">导出记录</system:String>
106106

107-
<system:String x:Key="flowlauncher_plugin_clipboardplus_export_succeeded">导出成功!</system:String>
108-
<system:String x:Key="flowlauncher_plugin_clipboardplus_import_succeeded">导入成功!</system:String>
107+
<system:String x:Key="flowlauncher_plugin_clipboardplus_export_succeeded">导出{0}条记录成功!</system:String>
108+
<system:String x:Key="flowlauncher_plugin_clipboardplus_import_succeeded">导入{0}条记录成功!</system:String>
109109
<system:String x:Key="flowlauncher_plugin_clipboardplus_import_failed">导出失败!</system:String>
110110

111111
<!-- Enum -->

src/Flow.Launcher.Plugin.ClipboardPlus/Languages/zh-tw.xaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@
104104
<system:String x:Key="flowlauncher_plugin_clipboardplus_import_records">導入記録</system:String>
105105
<system:String x:Key="flowlauncher_plugin_clipboardplus_export_records">導出記録</system:String>
106106

107-
<system:String x:Key="flowlauncher_plugin_clipboardplus_export_succeeded">導出成功!</system:String>
108-
<system:String x:Key="flowlauncher_plugin_clipboardplus_import_succeeded">導入成功!</system:String>
107+
<system:String x:Key="flowlauncher_plugin_clipboardplus_export_succeeded">導出{0}條記録成功!</system:String>
108+
<system:String x:Key="flowlauncher_plugin_clipboardplus_import_succeeded">導入{0}條記録成功!</system:String>
109109
<system:String x:Key="flowlauncher_plugin_clipboardplus_import_failed">導入失敗!</system:String>
110110

111111
<!-- Enum -->

src/Flow.Launcher.Plugin.ClipboardPlus/Main.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ private async void OnClipboardChange(object? sender, ClipboardMonitor.ClipboardC
722722

723723
#region List & Database
724724

725-
private async Task InitRecordsFromDatabaseAsync()
725+
public async Task InitRecordsFromDatabaseAsync()
726726
{
727727
// clear expired records
728728
try
@@ -743,7 +743,7 @@ await Database.DeleteRecordsByKeepTimeAsync(
743743
}
744744

745745
// restore records
746-
var records = await Database.GetAllRecordsAsync();
746+
var records = await Database.GetAllRecordsAsync(true);
747747
if (records.Any())
748748
{
749749
var records1 = records.Select(record => new ClipboardDataPair()

0 commit comments

Comments
 (0)