diff --git a/Notesnook.API/Hubs/SyncV2Hub.cs b/Notesnook.API/Hubs/SyncV2Hub.cs index 2db1eba..6e05255 100644 --- a/Notesnook.API/Hubs/SyncV2Hub.cs +++ b/Notesnook.API/Hubs/SyncV2Hub.cs @@ -80,21 +80,21 @@ namespace Notesnook.API.Hubs await base.OnConnectedAsync(); } - private Action MapTypeToUpsertAction(string type) + private Action, string, long> MapTypeToUpsertAction(string type) { return type switch { - "settingitem" => Repositories.Settings.Upsert, - "attachment" => Repositories.Attachments.Upsert, - "note" => Repositories.Notes.Upsert, - "notebook" => Repositories.Notebooks.Upsert, - "content" => Repositories.Contents.Upsert, - "shortcut" => Repositories.Shortcuts.Upsert, - "reminder" => Repositories.Reminders.Upsert, - "relation" => Repositories.Relations.Upsert, - "color" => Repositories.Colors.Upsert, - "vault" => Repositories.Vaults.Upsert, - "tag" => Repositories.Tags.Upsert, + "settingitem" => Repositories.Settings.UpsertMany, + "attachment" => Repositories.Attachments.UpsertMany, + "note" => Repositories.Notes.UpsertMany, + "notebook" => Repositories.Notebooks.UpsertMany, + "content" => Repositories.Contents.UpsertMany, + "shortcut" => Repositories.Shortcuts.UpsertMany, + "reminder" => Repositories.Reminders.UpsertMany, + "relation" => Repositories.Relations.UpsertMany, + "color" => Repositories.Colors.UpsertMany, + "vault" => Repositories.Vaults.UpsertMany, + "tag" => Repositories.Tags.UpsertMany, _ => null, }; } diff --git a/Notesnook.API/Repositories/SyncItemsRepository.cs b/Notesnook.API/Repositories/SyncItemsRepository.cs index 73b2c60..ecdce27 100644 --- a/Notesnook.API/Repositories/SyncItemsRepository.cs +++ b/Notesnook.API/Repositories/SyncItemsRepository.cs @@ -130,8 +130,45 @@ namespace Notesnook.API.Repositories ); dbContext.AddCommand((handle, ct) => Collection.ReplaceOneAsync(handle, filter, item, new ReplaceOptions { IsUpsert = true }, ct)); - // await base.UpsertAsync(item, (x) => (x.ItemId == item.ItemId) && x.UserId == userId); - base.Upsert(item, (x) => x.UserId == userId && x.ItemId == item.ItemId); + } + + public void UpsertMany(IEnumerable items, string userId, long dateSynced) + { + var userIdFilter = Builders.Filter.Eq("UserId", userId); + var writes = new List>(); + foreach (var item in items) + { + if (item.Length > 15 * 1024 * 1024) + { + throw new Exception($"Size of item \"{item.ItemId}\" is too large. Maximum allowed size is 15 MB."); + } + + if (!IsValidAlgorithm(item.Algorithm)) + { + throw new Exception($"Invalid alg identifier {item.Algorithm}"); + } + + // Handle case where the cipher is corrupted. + if (!IsBase64String(item.Cipher)) + { + Slogger.Error("Upsert", "Corrupted", item.ItemId, item.Length.ToString(), item.Cipher); + throw new Exception($"Corrupted item \"{item.ItemId}\" in collection \"{this.collectionName}\". Please report this error to support@streetwriters.co."); + } + + var filter = Builders.Filter.And( + userIdFilter, + Builders.Filter.Eq("ItemId", item.ItemId) + ); + + item.DateSynced = dateSynced; + item.UserId = userId; + + writes.Add(new ReplaceOneModel(filter, item) + { + IsUpsert = true + }); + } + dbContext.AddCommand((handle, ct) => Collection.BulkWriteAsync(handle, writes, options: new BulkWriteOptions { IsOrdered = false }, ct)); } private static bool IsBase64String(string value)