From 8132a465bac55dc321f5d1de60ceeb7f3c753e39 Mon Sep 17 00:00:00 2001 From: oneRain Date: Thu, 20 Feb 2020 12:44:33 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E5=AE=9E=E7=8E=B0=20operation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Storage/Storage/Internal/Codec/LCEncoder.cs | 4 +- .../Internal/Operation/ILCOperation.cs | 14 ++++++ .../Internal/Operation/LCAddOperation.cs | 46 ++++++++++++++++++- .../Operation/LCAddRelationOperation.cs | 40 +++++++++++++++- .../Operation/LCAddUniqueOperation.cs | 43 ++++++++++++++++- .../Operation/LCDecrementOperation.cs | 25 +++++++++- .../Internal/Operation/LCDeleteOperation.cs | 25 +++++++++- .../Storage/Internal/Operation/LCOperation.cs | 7 --- .../Internal/Operation/LCRemoveOperation.cs | 43 ++++++++++++++++- .../Operation/LCRemoveRelationOperation.cs | 39 +++++++++++++++- .../Internal/Operation/LCSetOperation.cs | 32 +++++++++++-- Storage/Storage/LCObject.cs | 2 +- Storage/Storage/LCRole.cs | 1 + 13 files changed, 294 insertions(+), 27 deletions(-) create mode 100644 Storage/Storage/Internal/Operation/ILCOperation.cs delete mode 100644 Storage/Storage/Internal/Operation/LCOperation.cs diff --git a/Storage/Storage/Internal/Codec/LCEncoder.cs b/Storage/Storage/Internal/Codec/LCEncoder.cs index 1107138..245d9c4 100644 --- a/Storage/Storage/Internal/Codec/LCEncoder.cs +++ b/Storage/Storage/Internal/Codec/LCEncoder.cs @@ -17,7 +17,7 @@ namespace LeanCloud.Storage.Internal.Codec { return EncodeDictionary(dict); } else if (obj is LCObject lcObj) { return EncodeLCObject(lcObj); - } else if (obj is LCOperation op) { + } else if (obj is ILCOperation op) { return EncodeOperation(op); } else if (obj is ILCQueryCondition cond) { return EncodeQueryCondition(cond); @@ -74,7 +74,7 @@ namespace LeanCloud.Storage.Internal.Codec { }; } - static object EncodeOperation(LCOperation operation) { + static object EncodeOperation(ILCOperation operation) { return null; } diff --git a/Storage/Storage/Internal/Operation/ILCOperation.cs b/Storage/Storage/Internal/Operation/ILCOperation.cs new file mode 100644 index 0000000..865410a --- /dev/null +++ b/Storage/Storage/Internal/Operation/ILCOperation.cs @@ -0,0 +1,14 @@ +using System.Collections; +using System.Collections.Generic; + +namespace LeanCloud.Storage.Internal.Operation { + internal interface ILCOperation { + ILCOperation MergeWithPrevious(ILCOperation previousOp); + + Dictionary Encode(); + + object Apply(object oldValue, string key); + + IEnumerable GetNewObjectList(); + } +} diff --git a/Storage/Storage/Internal/Operation/LCAddOperation.cs b/Storage/Storage/Internal/Operation/LCAddOperation.cs index 0237844..8144f9d 100644 --- a/Storage/Storage/Internal/Operation/LCAddOperation.cs +++ b/Storage/Storage/Internal/Operation/LCAddOperation.cs @@ -1,7 +1,49 @@ using System; +using System.Collections; +using System.Collections.Generic; +using LeanCloud.Storage.Internal.Codec; + namespace LeanCloud.Storage.Internal.Operation { - public class LCAddOperation { - public LCAddOperation() { + internal class LCAddOperation : ILCOperation { + internal List valueList; + + internal LCAddOperation(IEnumerable values) { + valueList = new List(values); + } + + ILCOperation ILCOperation.MergeWithPrevious(ILCOperation previousOp) { + if (previousOp is LCSetOperation || previousOp is LCDeleteOperation) { + return previousOp; + } + if (previousOp is LCAddOperation addOp) { + valueList.AddRange(addOp.valueList); + return this; + } + if (previousOp is LCAddUniqueOperation addUniqueOp) { + valueList.AddRange(addUniqueOp.values); + return this; + } + throw new ArgumentException("Operation is invalid after previous operation."); + } + + Dictionary ILCOperation.Encode() { + return new Dictionary { + { "op", "Add" }, + { "objects", LCEncoder.Encode(valueList) } + }; + } + + object ILCOperation.Apply(object oldValue, string key) { + List list = new List(); + if (oldValue != null) { + list.AddRange(oldValue as IEnumerable); + } + list.AddRange(valueList); + return list; + } + + IEnumerable ILCOperation.GetNewObjectList() { + return valueList; } } } diff --git a/Storage/Storage/Internal/Operation/LCAddRelationOperation.cs b/Storage/Storage/Internal/Operation/LCAddRelationOperation.cs index 550e042..d7061f8 100644 --- a/Storage/Storage/Internal/Operation/LCAddRelationOperation.cs +++ b/Storage/Storage/Internal/Operation/LCAddRelationOperation.cs @@ -1,7 +1,43 @@ using System; +using System.Linq; +using System.Collections; +using System.Collections.Generic; +using LeanCloud.Storage.Internal.Codec; + namespace LeanCloud.Storage.Internal.Operation { - public class LCAddRelationOperation { - public LCAddRelationOperation() { + internal class LCAddRelationOperation : ILCOperation { + List valueList; + + internal LCAddRelationOperation(IEnumerable objects) { + valueList = new List(objects); + } + + public ILCOperation MergeWithPrevious(ILCOperation previousOp) { + if (previousOp is LCSetOperation || previousOp is LCDeleteOperation) { + return previousOp; + } + if (previousOp is LCAddRelationOperation addRelationOp) { + valueList.AddRange(addRelationOp.valueList); + return this; + } + throw new ArgumentException("Operation is invalid after previous operation."); + } + + public Dictionary Encode() { + return new Dictionary { + { "__op", "AddRelation" }, + { "objects", LCEncoder.Encode(valueList) } + }; + } + + public object Apply(object oldValue, string key) { + LCRelation relation = new LCRelation(); + relation.targetClass = valueList[0].ClassName; + return relation; + } + + public IEnumerable GetNewObjectList() { + return valueList; } } } diff --git a/Storage/Storage/Internal/Operation/LCAddUniqueOperation.cs b/Storage/Storage/Internal/Operation/LCAddUniqueOperation.cs index 7787d48..73259c4 100644 --- a/Storage/Storage/Internal/Operation/LCAddUniqueOperation.cs +++ b/Storage/Storage/Internal/Operation/LCAddUniqueOperation.cs @@ -1,7 +1,46 @@ using System; +using System.Linq; +using System.Collections; +using System.Collections.Generic; +using LeanCloud.Storage.Internal.Codec; + namespace LeanCloud.Storage.Internal.Operation { - public class LCAddUniqueOperation { - public LCAddUniqueOperation() { + internal class LCAddUniqueOperation : ILCOperation { + internal HashSet values; + + internal LCAddUniqueOperation(IEnumerable values) { + this.values = new HashSet(values); + } + + public ILCOperation MergeWithPrevious(ILCOperation previousOp) { + if (previousOp is LCSetOperation || previousOp is LCDeleteOperation) { + return previousOp; + } + if (previousOp is LCAddUniqueOperation addUniqueOp) { + values.UnionWith(addUniqueOp.values); + return this; + } + throw new ArgumentException("Operation is invalid after previous operation."); + } + + public Dictionary Encode() { + return new Dictionary { + { "__op", "AddUnique" }, + { "objects", LCEncoder.Encode(values.ToList()) } + }; + } + + public object Apply(object oldValue, string key) { + HashSet set = new HashSet(); + if (oldValue != null) { + set.UnionWith(oldValue as IEnumerable); + } + set.UnionWith(values); + return set; + } + + public IEnumerable GetNewObjectList() { + return values; } } } diff --git a/Storage/Storage/Internal/Operation/LCDecrementOperation.cs b/Storage/Storage/Internal/Operation/LCDecrementOperation.cs index 0e6c994..281474a 100644 --- a/Storage/Storage/Internal/Operation/LCDecrementOperation.cs +++ b/Storage/Storage/Internal/Operation/LCDecrementOperation.cs @@ -1,7 +1,28 @@ using System; +using System.Collections; +using System.Collections.Generic; + namespace LeanCloud.Storage.Internal.Operation { - public class LCDecrementOperation { - public LCDecrementOperation() { + internal class LCDecrementOperation : ILCOperation { + + + internal LCDecrementOperation() { } + + public ILCOperation MergeWithPrevious(ILCOperation previousOp) { + throw new NotImplementedException(); + } + + public Dictionary Encode() { + throw new NotImplementedException(); + } + + public object Apply(object oldValue, string key) { + throw new NotImplementedException(); + } + + public IEnumerable GetNewObjectList() { + throw new NotImplementedException(); + } } } diff --git a/Storage/Storage/Internal/Operation/LCDeleteOperation.cs b/Storage/Storage/Internal/Operation/LCDeleteOperation.cs index 330eae5..11f1a27 100644 --- a/Storage/Storage/Internal/Operation/LCDeleteOperation.cs +++ b/Storage/Storage/Internal/Operation/LCDeleteOperation.cs @@ -1,7 +1,28 @@ using System; +using System.Collections; +using System.Collections.Generic; + namespace LeanCloud.Storage.Internal.Operation { - public class LCDeleteOperation { - public LCDeleteOperation() { + internal class LCDeleteOperation : ILCOperation { + internal LCDeleteOperation() { + } + + public ILCOperation MergeWithPrevious(ILCOperation previousOp) { + return this; + } + + public Dictionary Encode() { + return new Dictionary { + { "__op", "Delete" } + }; + } + + public object Apply(object oldValue, string key) { + return null; + } + + public IEnumerable GetNewObjectList() { + return null; } } } diff --git a/Storage/Storage/Internal/Operation/LCOperation.cs b/Storage/Storage/Internal/Operation/LCOperation.cs deleted file mode 100644 index 3a63af8..0000000 --- a/Storage/Storage/Internal/Operation/LCOperation.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; -namespace LeanCloud.Storage.Internal.Operation { - public class LCOperation { - public LCOperation() { - } - } -} diff --git a/Storage/Storage/Internal/Operation/LCRemoveOperation.cs b/Storage/Storage/Internal/Operation/LCRemoveOperation.cs index f9779bc..a418f41 100644 --- a/Storage/Storage/Internal/Operation/LCRemoveOperation.cs +++ b/Storage/Storage/Internal/Operation/LCRemoveOperation.cs @@ -1,7 +1,46 @@ using System; +using System.Linq; +using System.Collections; +using System.Collections.Generic; +using LeanCloud.Storage.Internal.Codec; + namespace LeanCloud.Storage.Internal.Operation { - public class LCRemoveOperation { - public LCRemoveOperation() { + internal class LCRemoveOperation : ILCOperation { + List valueList; + + internal LCRemoveOperation(IEnumerable values) { + valueList = new List { + values.Cast() + }; + } + + public ILCOperation MergeWithPrevious(ILCOperation previousOp) { + if (previousOp is LCSetOperation || previousOp is LCDeleteOperation) { + return previousOp; + } + if (previousOp is LCRemoveOperation removeOp) { + valueList.AddRange(removeOp.valueList); + } + throw new ArgumentException("Operation is invalid after previous operation."); + } + + public Dictionary Encode() { + return new Dictionary { + { "__op", "Remove" }, + { "objects", LCEncoder.Encode(valueList) } + }; + } + + public object Apply(object oldValue, string key) { + List list = new List(); + if (oldValue != null) { + list.AddRange(oldValue as IEnumerable); + } + return list; + } + + public IEnumerable GetNewObjectList() { + return null; } } } diff --git a/Storage/Storage/Internal/Operation/LCRemoveRelationOperation.cs b/Storage/Storage/Internal/Operation/LCRemoveRelationOperation.cs index d5637de..6ca7f38 100644 --- a/Storage/Storage/Internal/Operation/LCRemoveRelationOperation.cs +++ b/Storage/Storage/Internal/Operation/LCRemoveRelationOperation.cs @@ -1,7 +1,42 @@ using System; +using System.Collections; +using System.Collections.Generic; +using LeanCloud.Storage.Internal.Codec; + namespace LeanCloud.Storage.Internal.Operation { - public class LCRemoveRelationOperation { - public LCRemoveRelationOperation() { + internal class LCRemoveRelationOperation : ILCOperation { + List valueList; + + internal LCRemoveRelationOperation(LCObject obj) { + valueList = new List { obj }; + } + + public ILCOperation MergeWithPrevious(ILCOperation previousOp) { + if (previousOp is LCSetOperation || previousOp is LCDeleteOperation) { + return previousOp; + } + if (previousOp is LCRemoveRelationOperation removeRelationOp) { + valueList.AddRange(removeRelationOp.valueList); + return this; + } + throw new ArgumentException("Operation is invalid after previous operation."); + } + + public Dictionary Encode() { + return new Dictionary { + { "__op", "RemoveRelation" }, + { "objects", LCEncoder.Encode(valueList) } + }; + } + + public object Apply(object oldValue, string key) { + LCRelation relation = new LCRelation(); + relation.targetClass = valueList[0].ClassName; + return relation; + } + + public IEnumerable GetNewObjectList() { + return null; } } } diff --git a/Storage/Storage/Internal/Operation/LCSetOperation.cs b/Storage/Storage/Internal/Operation/LCSetOperation.cs index ddb8db5..2f81f35 100644 --- a/Storage/Storage/Internal/Operation/LCSetOperation.cs +++ b/Storage/Storage/Internal/Operation/LCSetOperation.cs @@ -1,7 +1,33 @@ using System; -namespace LeanCloud.Storage.Internal { - public class LCSetOperation { - public LCSetOperation() { +using System.Collections; +using System.Collections.Generic; +using LeanCloud.Storage.Internal.Codec; + +namespace LeanCloud.Storage.Internal.Operation { + internal class LCSetOperation : ILCOperation { + object value; + + internal LCSetOperation(object value) { + this.value = value; } + + public ILCOperation MergeWithPrevious(ILCOperation previousOp) { + return this; + } + + public Dictionary Encode() { + return LCEncoder.Encode(value) as Dictionary; + } + + public object Apply(object oldValue, string key) { + return value; + } + + public IEnumerable GetNewObjectList() { + if (value is IEnumerable enumerable) { + return enumerable; + } + return new List { value }; + } } } diff --git a/Storage/Storage/LCObject.cs b/Storage/Storage/LCObject.cs index 4e5e6b6..d0cea06 100644 --- a/Storage/Storage/LCObject.cs +++ b/Storage/Storage/LCObject.cs @@ -20,7 +20,7 @@ namespace LeanCloud.Storage { /// /// 操作字典 /// - Dictionary operationDict; + Dictionary operationDict; public string ClassName { get { diff --git a/Storage/Storage/LCRole.cs b/Storage/Storage/LCRole.cs index 9eeac7e..6da6d3b 100644 --- a/Storage/Storage/LCRole.cs +++ b/Storage/Storage/LCRole.cs @@ -1,4 +1,5 @@ using System; + namespace LeanCloud.Storage { public class LCRole : LCObject { public LCRole() {