forked from baking-bad/tzkt
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request baking-bad#17 from trilitech/palmer@functori@DAL-c…
…ommitment-indexing [DAL] Index DAL commitments
- Loading branch information
Showing
16 changed files
with
7,704 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Tzkt.Api.Models; | ||
using Tzkt.Api.Repositories; | ||
|
||
namespace Tzkt.Api.Controllers | ||
{ | ||
[ApiController] | ||
[Route("v1/dal")] | ||
public class DalController : ControllerBase | ||
{ | ||
private readonly DalRepository Dal; | ||
|
||
public DalController(DalRepository dal) | ||
{ | ||
Dal = dal; | ||
} | ||
|
||
#region commiments | ||
/// <summary> | ||
/// Get DAL commitments count | ||
/// </summary> | ||
/// <remarks> | ||
/// Returns total number of DAL commitments published. | ||
/// </remarks> | ||
/// <param name="hash">Filters by DAL commitment hash</param> | ||
/// <param name="level">Filters by level</param> | ||
/// <param name="slotIndex">Filters by slot-index</param> | ||
/// <param name="publisher">Filters by DAL commitment publisher</param> | ||
/// <returns></returns> | ||
[HttpGet("commitments/count")] | ||
public async Task<int> GetDalCommitmentsCount( | ||
DalCommitmentHashParameter hash, | ||
Int32Parameter level, | ||
Int32Parameter slotIndex, | ||
AccountParameter publisher) | ||
{ | ||
return await Dal.GetCommitmentsCount(hash, level, slotIndex, publisher); | ||
} | ||
|
||
/// <summary> | ||
/// Get DAL commitments information | ||
/// </summary> | ||
/// <remarks> | ||
/// Returns information of the DAL commitments published. | ||
/// </remarks> | ||
/// <param name="hash">Filters by DAL commitment hash</param> | ||
/// <param name="level">Filters by level</param> | ||
/// <param name="slotIndex">Filters by slot-index</param> | ||
/// <param name="publisher">Filters by DAL commitment publisher</param> | ||
/// <param name="select">Specify comma-separated list of fields to include into response or leave it undefined to return full object. If you select single field, response will be an array of values in both `.fields` and `.values` modes.</param> | ||
/// <param name="sort">Sorts DAL commitments by specified field. Supported fields: `level` (default), `slotIndex`.</param> | ||
/// <param name="offset">Specifies which or how many items should be skipped</param> | ||
/// <param name="limit">Maximum number of items to return</param> | ||
/// <returns></returns> | ||
[HttpGet("commitments")] | ||
public async Task<ActionResult<IEnumerable<DalCommitment>>> GetDalCommitments( | ||
DalCommitmentHashParameter hash, | ||
Int32Parameter level, | ||
Int32Parameter slotIndex, | ||
AccountParameter publisher, | ||
SelectParameter select, | ||
SortParameter sort, | ||
OffsetParameter offset, | ||
[Range(0, 10000)] int limit = 100) | ||
{ | ||
#region validate | ||
if (sort != null && !sort.Validate("level", "slotIndex")) | ||
return new BadRequest($"{nameof(sort)}", "Sorting by the specified field is not allowed."); | ||
#endregion | ||
|
||
if (select == null) | ||
return Ok(await Dal.GetCommitments(hash, level, slotIndex, publisher, sort, offset, limit)); | ||
|
||
if (select.Values != null) | ||
{ | ||
if (select.Values.Length == 1) | ||
return Ok(await Dal.GetCommitments(hash, level, slotIndex, publisher, sort, offset, limit, select.Values[0])); | ||
else | ||
return Ok(await Dal.GetCommitments(hash, level, slotIndex, publisher, sort, offset, limit, select.Values)); | ||
} | ||
else | ||
{ | ||
if (select.Fields.Length == 1) | ||
return Ok(await Dal.GetCommitments(hash, level, slotIndex, publisher, sort, offset, limit, select.Fields[0])); | ||
else | ||
{ | ||
return Ok(new SelectionResponse | ||
{ | ||
Cols = select.Fields, | ||
Rows = await Dal.GetCommitments(hash, level, slotIndex, publisher, sort, offset, limit, select.Fields) | ||
}); | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Get DAL commitments information by hash | ||
/// </summary> | ||
/// <remarks> | ||
/// Returns information of the DAL commitments published with the specified hash. | ||
/// </remarks> | ||
/// <param name="hash">DAL commitment hash</param> | ||
/// <param name="level">Filters by level</param> | ||
/// <param name="slotIndex">Filters by slot-index</param> | ||
/// <param name="publisher">Filters by DAL commitment publisher</param> | ||
/// <param name="select">Specify comma-separated list of fields to include into response or leave it undefined to return full object. If you select single field, response will be an array of values in both `.fields` and `.values` modes.</param> | ||
/// <param name="sort">Sorts DAL commitments by specified field. Supported fields: `level` (default), `slotIndex`.</param> | ||
/// <param name="offset">Specifies which or how many items should be skipped</param> | ||
/// <param name="limit">Maximum number of items to return</param> | ||
/// <returns></returns> | ||
[HttpGet("commitments/{hash}")] | ||
public async Task<ActionResult<IEnumerable<DalCommitment>>> GetDalCommitmentsByHash( | ||
[Required][DalCommitmentHash] string hash, | ||
Int32Parameter level, | ||
Int32Parameter slotIndex, | ||
AccountParameter publisher, | ||
SelectParameter select, | ||
SortParameter sort, | ||
OffsetParameter offset, | ||
[Range(0, 10000)] int limit = 100) | ||
=> | ||
await GetDalCommitments(new DalCommitmentHashParameter { Eq = hash }, level, slotIndex, publisher, select, sort, offset, limit); | ||
#endregion | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
namespace Tzkt.Api.Models | ||
{ | ||
public class DalCommitment | ||
{ | ||
/// <summary> | ||
/// Level at which the commitment has been published. | ||
/// </summary> | ||
public int Level { get; set; } | ||
|
||
/// <summary> | ||
/// Slot index associated with the commitment. | ||
/// </summary> | ||
public int SlotIndex { get; set; } | ||
|
||
/// <summary> | ||
/// Hash of the commitment. | ||
/// </summary> | ||
public string Hash { get; set; } | ||
|
||
/// <summary> | ||
/// Information about the account who has published the commitment. | ||
/// </summary> | ||
public Alias Publisher { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
using Microsoft.AspNetCore.Mvc.ModelBinding; | ||
|
||
namespace Tzkt.Api | ||
{ | ||
public class DalCommitmentHashBinder : IModelBinder | ||
{ | ||
public Task BindModelAsync(ModelBindingContext bindingContext) | ||
{ | ||
var model = bindingContext.ModelName; | ||
var hasValue = false; | ||
|
||
if (!bindingContext.TryGetDalCommitmentHash($"{model}", ref hasValue, out var value)) | ||
return Task.CompletedTask; | ||
|
||
if (!bindingContext.TryGetDalCommitmentHash($"{model}.eq", ref hasValue, out var eq)) | ||
return Task.CompletedTask; | ||
|
||
if (!bindingContext.TryGetDalCommitmentHash($"{model}.ne", ref hasValue, out var ne)) | ||
return Task.CompletedTask; | ||
|
||
if (!bindingContext.TryGetDalCommitmentHashList($"{model}.in", ref hasValue, out var @in)) | ||
return Task.CompletedTask; | ||
|
||
if (!bindingContext.TryGetDalCommitmentHashList($"{model}.ni", ref hasValue, out var ni)) | ||
return Task.CompletedTask; | ||
|
||
if (!hasValue) | ||
{ | ||
bindingContext.Result = ModelBindingResult.Success(null); | ||
return Task.CompletedTask; | ||
} | ||
|
||
bindingContext.Result = ModelBindingResult.Success(new DalCommitmentHashParameter | ||
{ | ||
Eq = value ?? eq, | ||
Ne = ne, | ||
In = @in, | ||
Ni = ni | ||
}); | ||
|
||
return Task.CompletedTask; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
using System.Text; | ||
using Microsoft.AspNetCore.Mvc; | ||
using NJsonSchema.Annotations; | ||
|
||
namespace Tzkt.Api | ||
{ | ||
[ModelBinder(BinderType = typeof(DalCommitmentHashBinder))] | ||
[JsonSchemaExtensionData("x-tzkt-extension", "query-parameter")] | ||
public class DalCommitmentHashParameter : INormalizable | ||
{ | ||
/// <summary> | ||
/// **Equal** filter mode (`.eq` suffix can be omitted, i.e. `?param=...` is the same as `?param.eq=...`). \ | ||
/// Specify an DAL commitment hash to get items where the specified field is equal to the specified value. | ||
/// | ||
/// Example: `?hash=sh...`. | ||
/// </summary> | ||
public string Eq { get; set; } | ||
|
||
/// <summary> | ||
/// **Not equal** filter mode. \ | ||
/// Specify an DAL commitment hash to get items where the specified field is not equal to the specified value. | ||
/// | ||
/// Example: `?hash.ne=sh...`. | ||
/// </summary> | ||
public string Ne { get; set; } | ||
|
||
/// <summary> | ||
/// **In list** (any of) filter mode. \ | ||
/// Specify a comma-separated list of DAL commitment hashes to get items where the specified field is equal to one of the specified values. | ||
/// | ||
/// Example: `?hash.in=hash1,hash2,hash3`. | ||
/// </summary> | ||
public List<string> In { get; set; } | ||
|
||
/// <summary> | ||
/// **Not in list** (none of) filter mode. \ | ||
/// Specify a comma-separated list of DAL commitment hashes to get items where the specified field is not equal to all the specified values. | ||
/// | ||
/// Example: `?hash.ni=hash1,hash2,hash3`. | ||
/// </summary> | ||
public List<string> Ni { get; set; } | ||
|
||
#region operators | ||
public static implicit operator DalCommitmentHashParameter(string value) => new() { Eq = value }; | ||
#endregion | ||
|
||
public string Normalize(string name) | ||
{ | ||
var sb = new StringBuilder(); | ||
|
||
if (Eq != null) | ||
{ | ||
sb.Append($"{name}.eq={Eq}&"); | ||
} | ||
|
||
if (Ne != null) | ||
{ | ||
sb.Append($"{name}.ne={Ne}&"); | ||
} | ||
|
||
if (In?.Count > 0) | ||
{ | ||
sb.Append($"{name}.in={string.Join(",", In.OrderBy(x => x))}&"); | ||
} | ||
|
||
if (Ni?.Count > 0) | ||
{ | ||
sb.Append($"{name}.ni={string.Join(",", Ni.OrderBy(x => x))}&"); | ||
} | ||
|
||
return sb.ToString(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.