diff --git a/Storage/Storage/Internal/Http/LCHttpClient.cs b/Storage/Storage/Internal/Http/LCHttpClient.cs index 04e2562..f1f9734 100644 --- a/Storage/Storage/Internal/Http/LCHttpClient.cs +++ b/Storage/Storage/Internal/Http/LCHttpClient.cs @@ -148,6 +148,11 @@ namespace LeanCloud.Storage.Internal.Http { string sign = $"{hash},{timestamp}"; headers.Add("X-LC-Sign", sign); } + if (LCApplication.AdditionalHeaders.Count > 0) { + foreach (KeyValuePair kv in LCApplication.AdditionalHeaders) { + headers.Add(kv.Key, kv.Value); + } + } // 当前用户 Session Token LCUser currentUser = await LCUser.GetCurrent(); if (!headers.Contains("X-LC-Session") && currentUser != null) { diff --git a/Storage/Storage/Internal/Operation/LCIgnoreHookOperation.cs b/Storage/Storage/Internal/Operation/LCIgnoreHookOperation.cs new file mode 100644 index 0000000..992e905 --- /dev/null +++ b/Storage/Storage/Internal/Operation/LCIgnoreHookOperation.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace LeanCloud.Storage.Internal.Operation { + internal class LCIgnoreHookOperation : ILCOperation { + internal HashSet ignoreHooks; + + internal LCIgnoreHookOperation(IEnumerable hooks) { + ignoreHooks = new HashSet(hooks); + } + + public object Apply(object oldValue, string key) { + HashSet set = new HashSet(); + if (oldValue != null) { + set.UnionWith(oldValue as IEnumerable); + } + set.UnionWith(ignoreHooks); + return set.ToList(); + } + + public object Encode() { + return ignoreHooks; + } + + public IEnumerable GetNewObjectList() { + return ignoreHooks; + } + + public ILCOperation MergeWithPrevious(ILCOperation previousOp) { + if (previousOp is LCIgnoreHookOperation ignoreHookOp) { + ignoreHooks.UnionWith(ignoreHookOp.ignoreHooks); + return this; + } + throw new ArgumentException("Operation is invalid after previous operation."); + } + } +} diff --git a/Storage/Storage/LCApplication.cs b/Storage/Storage/LCApplication.cs index 593c346..1b121fa 100644 --- a/Storage/Storage/LCApplication.cs +++ b/Storage/Storage/LCApplication.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using LeanCloud.Common; using LeanCloud.Storage; using LeanCloud.Storage.Internal.Http; @@ -42,6 +43,10 @@ namespace LeanCloud { get; set; } + internal static Dictionary AdditionalHeaders { + get; + } = new Dictionary(); + public static void Initialize(string appId, string appKey, string server = null, @@ -68,5 +73,9 @@ namespace LeanCloud { HttpClient = new LCHttpClient(appId, appKey, server, SDKVersion, APIVersion); } + + public static void AddHeader(string key, string value) { + AdditionalHeaders.Add(key, value); + } } } diff --git a/Storage/Storage/LCHookObject.cs b/Storage/Storage/LCHookObject.cs new file mode 100644 index 0000000..5b9cc09 --- /dev/null +++ b/Storage/Storage/LCHookObject.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using LeanCloud.Storage.Internal.Operation; + +namespace LeanCloud.Storage { + public static class LCClassHook { + public const string BeforeSave = "beforeSave"; + public const string AfterSave = "afterSave"; + public const string BeforeUpdate = "beforeUpdate"; + public const string AfterUpdate = "afterUpdate"; + public const string BeforeDelete = "beforeDelete"; + public const string AfterDelete = "afterDelete"; + } + + public partial class LCObject { + internal const string IgnoreHooksKey = "__ignore_hooks"; + + internal HashSet ignoreHooks; + + internal HashSet IgnoreHooks { + get { + if (ignoreHooks == null) { + ignoreHooks = new HashSet(); + } + return ignoreHooks; + } + } + + public void DisableBeforeHook() { + Ignore( + LCClassHook.BeforeSave, + LCClassHook.BeforeUpdate, + LCClassHook.BeforeDelete); + } + + public void DisableAfterHook() { + Ignore( + LCClassHook.AfterSave, + LCClassHook.AfterUpdate, + LCClassHook.AfterDelete); + } + + public void IgnoreHook(string hookName) { + if (hookName != LCClassHook.BeforeSave && hookName != LCClassHook.AfterSave && + hookName != LCClassHook.BeforeUpdate && hookName != LCClassHook.AfterUpdate && + hookName != LCClassHook.BeforeDelete && hookName != LCClassHook.AfterDelete) { + throw new ArgumentException($"Invalid {hookName}"); + } + + Ignore(hookName); + } + + private void Ignore(params string[] hooks) { + LCIgnoreHookOperation op = new LCIgnoreHookOperation(hooks); + ApplyOperation(IgnoreHooksKey, op); + } + } +} diff --git a/Storage/Storage/LCObject.cs b/Storage/Storage/LCObject.cs index 7a43d8e..8f828e0 100644 --- a/Storage/Storage/LCObject.cs +++ b/Storage/Storage/LCObject.cs @@ -12,7 +12,7 @@ namespace LeanCloud.Storage { /// /// LeanCloud Object /// - public class LCObject { + public partial class LCObject { /// /// Last synced data. ///