diff --git a/AuroraSignal.test/CursorList.test.cs b/AuroraSignal.test/CursorList.test.cs index 913b1ec..7780280 100644 --- a/AuroraSignal.test/CursorList.test.cs +++ b/AuroraSignal.test/CursorList.test.cs @@ -1,8 +1,7 @@ -using System; -using System.Collections.Generic; using Xunit; using Aurora; using Aurora.Services.Signal; +using Aurora.Cursor; namespace AuroraSignal.test @@ -14,57 +13,30 @@ namespace AuroraSignal.test [InlineData(SortDirection.Desc)] public void CursorListSortOnStringValue(SortDirection direction) { - CursorList cursor = new CursorList(); - cursor.Add(new Party(){Name = "asdf", PartyId = "1111"}); - cursor.Add(new Party(){Name = "bsdf", PartyId = "2222"}); - cursor.Add(new Party(){Name = "csdf", PartyId = "3333"}); + CursorList list = new CursorList(); + list.Add(new Party() { Name = "asdf", Id = "1111" }); + list.Add(new Party() { Name = "bsdf", Id = "2222" }); + list.Add(new Party() { Name = "csdf", Id = "3333" }); - List result = cursor.WithSort("Name", direction).Get(); + CursorResult result = new Cursor(ref list) + .WithSort(item => item.Value.Name, direction) + .GetNextPage(); - if(direction == SortDirection.Desc) + if (direction == SortDirection.Desc) { - Assert.Collection(cursor, - item => item.Name.Equals("asdf"), - item => item.Name.Equals("bsdf"), + Assert.Collection(result.Result, + item => item.Name.Equals("asdf"), + item => item.Name.Equals("bsdf"), item => item.Name.Equals("csdf")); } else { - Assert.Collection(cursor, - item => item.Name.Equals("csdf"), - item => item.Name.Equals("bsdf"), + Assert.Collection(result.Result, + item => item.Name.Equals("csdf"), + item => item.Name.Equals("bsdf"), item => item.Name.Equals("asdf")); } } - - [Theory()] - [InlineData(SortDirection.Asc)] - [InlineData(SortDirection.Desc)] - public void CursorListSortOnIntValue(SortDirection direction) - { - CursorList cursor = new CursorList(); - cursor.Add(new {Name = "asdf", PartyId = 1111}); - cursor.Add(new {Name = "bsdf", PartyId = 2222}); - cursor.Add(new {Name = "csdf", PartyId = 3333}); - - List result = cursor.WithSort("PartyId", direction).Get(); - - if(direction == SortDirection.Desc) - { - Assert.Collection(cursor, - item => item.Equals(new {Name = "asdf", PartyId = 1111}), - item => item.Equals(new {Name = "bsdf", PartyId = 2222}), - item => item.Equals(new {Name = "csdf", PartyId = 3333})); - } - else - { - Assert.Collection(cursor, - item => item.Equals(new {Name = "csdf", PartyId = 3333}), - item => item.Equals(new {Name = "bsdf", PartyId = 2222}), - item => item.Equals(new {Name = "asdf", PartyId = 1111})); - - } - } } } diff --git a/AuroraSignal/Src/Augments/Party.cs b/AuroraSignal/Src/Augments/Party.cs new file mode 100644 index 0000000..52c697f --- /dev/null +++ b/AuroraSignal/Src/Augments/Party.cs @@ -0,0 +1,9 @@ +using Aurora.Cursor; + +namespace Aurora.Services.Signal +{ + public partial class Party : ICursorObject + { + } +} + diff --git a/AuroraSignal/Src/Cursor/Cursor.cs b/AuroraSignal/Src/Cursor/Cursor.cs new file mode 100644 index 0000000..b740951 --- /dev/null +++ b/AuroraSignal/Src/Cursor/Cursor.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +#nullable enable +namespace Aurora.Cursor +{ + public enum SortDirection + { + Asc, + Desc, + } + + public class Cursor where T : ICursorObject + { + private CursorList _list; + + private string? _previousPageToken; + private string? _nextPageToken; + private int _pageSize; + private Func, string> _sortDelgate; + private SortDirection _direction; + public Cursor(ref CursorList list) + { + this._list = list; + this._previousPageToken = string.Empty; + this._nextPageToken = string.Empty; + this._pageSize = 10; + this._sortDelgate = delegate (KeyValuePair item) + { + return item.Value.Id; + }; + } + + public CursorResult GetNextPage() + { + List> tmpList; + + // Sort reference list + if (this._direction == SortDirection.Desc) + { + tmpList = this._list.OrderByDescending(this._sortDelgate).ToList(); + + } + else + { + tmpList = this._list.OrderBy(this._sortDelgate).ToList(); + } + + if (tmpList == null) + { + throw new System.NullReferenceException(); + } + + int startIdx = 0; + if (!string.IsNullOrEmpty(this._nextPageToken)) + { + // TODO find another way to index into the list that's not a regular array search + startIdx = tmpList.FindIndex(item => item.Key == this._nextPageToken); + } + + int endIdx = startIdx + this._pageSize; + + List selection = new List(); + + // Get page + for (int i = startIdx; i < tmpList.Count && i < endIdx; i++) + { + selection.Add(tmpList.ElementAt(i).Value); + } + + return new CursorResult + { + NextPageToken = selection[selection.Count - 1].Id, + PrevPageToken = selection[0].Id, + Count = this._list.Count, + Result = selection + }; + } + + public CursorResult GetPreviousPage() + { + throw new NotImplementedException(); + } + + public Cursor WithNextPage(string nextPageToken) + { + this._nextPageToken = nextPageToken; + return this; + } + + public Cursor WithPreviousPage(string prevPageToken) + { + this._previousPageToken = prevPageToken; + return this; + } + + public Cursor WithSort(Func, string> sortDelegate, SortDirection direction) + { + this._sortDelgate = sortDelegate; + this._direction = direction; + return this; + } + + public Cursor WithSize(int size) + { + this._pageSize = size; + return this; + } + } + +} \ No newline at end of file diff --git a/AuroraSignal/Src/Cursor/CursorList.cs b/AuroraSignal/Src/Cursor/CursorList.cs new file mode 100644 index 0000000..fbff1f3 --- /dev/null +++ b/AuroraSignal/Src/Cursor/CursorList.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using System.Collections; +using System; +using System.Linq; +using Aurora.Utils; + +#nullable enable +namespace Aurora.Cursor +{ + + public class CursorList : SortedList where T : ICursorObject + { + + public CursorList() + { + } + + public CursorList Add(T item) + { + string itemHashId = HashUtil.GetHash(new string[] { item.Id, item.GetHashCode().ToString() }).ToString(); + bool res = this.TryAdd(itemHashId, item); + + if (res == false) + { + throw new System.Exception("Failed to add item to cursor list"); + } + return this; + } + + + } +} \ No newline at end of file diff --git a/AuroraSignal/Src/Cursor/CursorObject.cs b/AuroraSignal/Src/Cursor/CursorObject.cs new file mode 100644 index 0000000..cca1779 --- /dev/null +++ b/AuroraSignal/Src/Cursor/CursorObject.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Aurora.Cursor +{ + public interface ICursorObject + { + string Id { get; set; } + } +} diff --git a/AuroraSignal/Src/Cursor/CursorResult.cs b/AuroraSignal/Src/Cursor/CursorResult.cs new file mode 100644 index 0000000..ab50c6a --- /dev/null +++ b/AuroraSignal/Src/Cursor/CursorResult.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +namespace Aurora.Cursor +{ + public class CursorResult + { + public CursorResult() + { + Result = new List(); + } + + public CursorResult(CursorResult cpy) + { + NextPageToken = cpy.NextPageToken; + PrevPageToken = cpy.PrevPageToken; + Result = cpy.Result; + Count = cpy.Count; + } + + public string NextPageToken { get; set; } + public string PrevPageToken { get; set; } + public List Result { get; set; } + public int Count { get; set; } + } +} diff --git a/AuroraSignal/Src/CursorList.cs b/AuroraSignal/Src/CursorList.cs deleted file mode 100644 index 3a29106..0000000 --- a/AuroraSignal/Src/CursorList.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System.Collections.Generic; - -namespace Aurora -{ - public enum SortDirection { - Asc, - Desc, - } - - public class CursorList : List - { - private string _orderBy; - private SortDirection _direction; - private string _previousPageToken; - private string _nextPageToken; - private int _pageSize; - - public CursorList(){ - this._direction = SortDirection.Desc; - this._orderBy = string.Empty; - this._previousPageToken = string.Empty; - this._nextPageToken = string.Empty; - this._pageSize = 10; - } - - public CursorList WithNextPage(string nextPageToken){ - this._nextPageToken = nextPageToken; - return this; - } - - public CursorList WithPreviousPage(string prevPageToken){ - this._previousPageToken = prevPageToken; - return this; - } - - public CursorList WithSort(string orderBy, SortDirection direction ) { - this._orderBy = orderBy; - this._direction = direction; - return this; - } - - public CursorList WithSize(int size){ - this._pageSize = size; - return this; - } - - public List Get(){ - if(this._nextPageToken != string.Empty && this._previousPageToken != string.Empty){ - throw new System.InvalidOperationException("Cannot specify both next and previous page tokens"); - } - - List tmpList = new List(this); - - - tmpList.Sort(delegate(T first, T second){ - object firstVal = first.GetType().GetProperty(this._orderBy).GetValue(first, null); - object secondVal = first.GetType().GetProperty(this._orderBy).GetValue(second, null); - int compare = 0; - - if(firstVal == null && secondVal == null) - { - compare = 0; - } - else if(firstVal == null) - { - compare = 1; - } - else if(secondVal == null) - { - compare = -1; - } - else - { - - // Determine number or string types - if(firstVal is string) - { - string firstStr = firstVal as string; - string secondStr = secondVal as string; - compare = firstStr.CompareTo(secondStr); - } else if(firstVal is int) - { - int? firstInt = firstVal as int?; - int? secondInt = secondVal as int?; - compare = firstInt > secondInt ? 1 : -1; - } - } - return this._direction == SortDirection.Asc ? compare : compare * -1; - }); - - return tmpList.GetRange(0, this._pageSize > tmpList.Count ? tmpList.Count : this._pageSize); - } - } -} \ No newline at end of file diff --git a/AuroraSignal/Src/Protos/signal.proto b/AuroraSignal/Src/Protos/signal.proto index 66c12ee..5d62e9c 100644 --- a/AuroraSignal/Src/Protos/signal.proto +++ b/AuroraSignal/Src/Protos/signal.proto @@ -54,7 +54,7 @@ service Signal { message Party { //The resource name of the party string name = 1; - string party_id = 2; + string id = 2; string display_name = 3; string description = 4; string host_ip = 5; @@ -63,7 +63,7 @@ message Party { message PartyListItem { string name = 1; - string party_id = 2; + string id = 2; } message ListPartiesRequest { diff --git a/AuroraSignal/Src/Services/Signal/SignalService.cs b/AuroraSignal/Src/Services/Signal/SignalService.cs index 6e68a67..8a59f50 100644 --- a/AuroraSignal/Src/Services/Signal/SignalService.cs +++ b/AuroraSignal/Src/Services/Signal/SignalService.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading.Tasks; using Grpc.Core; using Microsoft.Extensions.Logging; +using Aurora.Cursor; namespace Aurora.Services.Signal { diff --git a/AuroraSignal/Src/Utils/HashUtil.cs b/AuroraSignal/Src/Utils/HashUtil.cs new file mode 100644 index 0000000..0644870 --- /dev/null +++ b/AuroraSignal/Src/Utils/HashUtil.cs @@ -0,0 +1,25 @@ +using System.Security.Cryptography; +using System.Text; +using System; + +namespace Aurora.Utils +{ + public class HashUtil + { + public static Guid GetHash(string[] inputs) + { + string input = ""; + foreach (string str in inputs) + { + input += str; + } + + byte[] stringbytes = Encoding.UTF8.GetBytes(input); + byte[] hashedBytes = new System.Security.Cryptography + .SHA1CryptoServiceProvider() + .ComputeHash(stringbytes); + Array.Resize(ref hashedBytes, 16); + return new Guid(hashedBytes); + } + } +} diff --git a/workspace.code-workspace b/workspace.code-workspace index a0878cd..d491373 100644 --- a/workspace.code-workspace +++ b/workspace.code-workspace @@ -7,6 +7,9 @@ "settings": { "files.exclude": { "**/obj": true - } + }, + "dotnet-test-explorer.testProjectPath": "./AuroraSignal.test", + "editor.formatOnSave": true, + "editor.defaultFormatter": "ms-dotnettools.csharp" } }