Ver Fonte

Added way to create DFSaveStorage directly from serialized form data.

Kenric Nugteren há 2 dias atrás
pai
commit
1dfb6a7cd3

+ 7 - 7
InABox.Core/DigitalForms/DigitalFormDocumentFactory.cs

@@ -10,8 +10,8 @@ namespace InABox.Core
 
     public interface IDigitalFormDocumentHandler
     {
-        Task<byte[]> LoadDocumentAsync(Guid id);
-        byte[] LoadDocument(Guid id);
+        Task<byte[]?> LoadDocumentAsync(Guid id);
+        byte[]? LoadDocument(Guid id);
         Guid SaveDocument(byte[] data);
         void Run();
         void Stop();
@@ -28,7 +28,7 @@ namespace InABox.Core
         
         private static Action<bool>? _status;
 
-        public byte[] LoadDocument(Guid id)
+        public byte[]? LoadDocument(Guid id)
         {
             var fullpath = Path.Combine(CachePath, FileName(id));
             if (File.Exists(fullpath))
@@ -42,7 +42,7 @@ namespace InABox.Core
             return result;
         }
         
-        public async Task<byte[]> LoadDocumentAsync(Guid id)
+        public async Task<byte[]?> LoadDocumentAsync(Guid id)
         {
             var fullpath = Path.Combine(CachePath, FileName(id));
             if (File.Exists(fullpath))
@@ -54,7 +54,7 @@ namespace InABox.Core
                     Columns.None<Document>().Add(x => x.Data),
                     null,
                     CoreRange.All);
-                return data.Rows.FirstOrDefault().Get<Document, byte[]>(x => x.Data);
+                return data.Rows.FirstOrDefault()?.Get<Document, byte[]>(x => x.Data);
             }
         }
 
@@ -144,8 +144,8 @@ namespace InABox.Core
 
         public static void LoadDocument(Guid id, Action<byte[]> callback) =>
             LoadDocumentAsync(id).ContinueWith(task => callback(task.Result), TaskScheduler.FromCurrentSynchronizationContext());
-        public static Task<byte[]> LoadDocumentAsync(Guid id) => Handler.LoadDocumentAsync(id);
-        public static byte[]? LoadDocument(Guid id) => Handler.LoadDocument(id);
+        public static Task<byte[]> LoadDocumentAsync(Guid id) => Handler.LoadDocumentAsync(id).ContinueWith(task => task.Result ?? Array.Empty<byte>());
+        public static byte[] LoadDocument(Guid id) => Handler.LoadDocument(id) ?? Array.Empty<byte>();
         public static Guid SaveDocument(byte[] data) => Handler.SaveDocument(data);
         
     }

+ 34 - 5
InABox.Core/DigitalForms/Forms/DigitalForm.cs

@@ -146,6 +146,26 @@ namespace InABox.Core
             var blobs = Serialization.Deserialize<Dictionary<string, object?>>(blobData);
             return new DFLoadStorage(values, blobs);
         }
+        
+        /// <summary>
+        /// Takes a serialized FormData string and BlobData string and deserializes into a <see cref="DFSaveStorage"/> object.
+        /// </summary>
+        /// <remarks>
+        ///     Returns <see langword="null"/> if <paramref name="formData"/> is not a valid JSON object.
+        /// </remarks>
+        /// <param name="formData"></param>
+        /// <param name="blobData"></param>
+        /// <returns></returns>
+        public static DFSaveStorage? DeserializeFormSaveData(string formData, string? blobData)
+        {
+            var values = Serialization.Deserialize<Dictionary<string, object?>>(formData);
+            if (values is null)
+                return null;
+            if (blobData.IsNullOrWhiteSpace())
+                return new DFSaveStorage(values, null);
+            var blobs = Serialization.Deserialize<Dictionary<string, object?>>(blobData);
+            return new DFSaveStorage(values, blobs);
+        }
 
         /// <summary>
         /// Like <see cref="DeserializeFormData(string, string?)"/>, but takes the FormData and BlobData from <paramref name="form"/>,
@@ -160,19 +180,28 @@ namespace InABox.Core
             => DeserializeFormData(form.FormData, form.BlobData);
 
         /// <summary>
-        /// Takes a form instance, set of variables and some saved values, and serializes the FormData and BlobData into the respective
+        /// Like <see cref="DeserializeFormSaveData(string, string?)"/>, but takes the FormData and BlobData from <paramref name="form"/>,
+        /// rather than having to specify them manually.
+        /// </summary>
+        /// <remarks>
+        ///     Returns <see langword="null"/> if <c>form.FormData</c> is not a valid JSON object.
+        /// </remarks>
+        /// <param name="form"></param>
+        /// <returns></returns>
+        public static DFSaveStorage? DeserializeFormSaveData(IDigitalFormInstance form)
+            => DeserializeFormSaveData(form.FormData, form.BlobData);
+
+        /// <summary>
+        /// Takes a form instance and some saved values, and serializes the FormData and BlobData into the respective
         /// fields of <paramref name="form"/>.
         /// </summary>
         /// <remarks>
         /// Doesn't return anything, but saves the serialized results directly into form.FormData and form.BlobData.
         /// It choose which fields should be saved into BlobData based on whether the form field has the <see cref="IDFBlobField"/> interface.
-        /// <br/>
-        /// <paramref name="values"/> should be the same as what you pass into <see cref="Serialization.Serialize(object?, bool)"/>.
         /// </remarks>
         /// <param name="form">The form instance.</param>
-        /// <param name="variables">The variables associated with the digital form.</param>
         /// <param name="storage">The values to save.</param>
-        public static void SerializeFormData(IDigitalFormInstance form, ICollection<DigitalFormVariable> variables, DFSaveStorage storage)
+        public static void SerializeFormData(IDigitalFormInstance form, DFSaveStorage storage)
         {
             form.FormData = Serialization.Serialize(storage.FormData);
             form.BlobData = Serialization.Serialize(storage.BlobData);

+ 3 - 4
InABox.Core/DigitalForms/Layouts/Fields/DFStorage.cs

@@ -14,10 +14,10 @@ namespace InABox.Core
 
         public Dictionary<string, object?> BlobData { get; private set; }
 
-        public DFSaveStorage()
+        public DFSaveStorage(Dictionary<string, object?>? formData = null, Dictionary<string, object?>? blobData = null)
         {
-            FormData = new Dictionary<string, object?>();
-            BlobData = new Dictionary<string, object?>();
+            FormData = formData ?? new Dictionary<string, object?>();
+            BlobData = blobData ?? new Dictionary<string, object?>();
         }
         
         public int Count() => FormData.Count();
@@ -195,7 +195,6 @@ namespace InABox.Core
         {
             return FormData;
         }
-        
     }
 
     public class DFLoadStorageEntry