Skip to content

Commit

Permalink
Merge pull request #26 from AElfProject/release/1.0.0
Browse files Browse the repository at this point in the history
Release v1.0.0
  • Loading branch information
jason-aelf authored Aug 7, 2024
2 parents 80f7347 + e8a631b commit 034e667
Show file tree
Hide file tree
Showing 36 changed files with 1,288 additions and 284 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/nuget-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Publish NuGet Package

on:
push:
tags:
- "v*.*.*"

jobs:
publish:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.0.x'

- name: Restore dependencies
run: dotnet restore

- name: Get the version from git tags
id: get_version
run: |
TAG=$(git describe --tags --abbrev=0)
VERSION=${TAG#v}
echo "VERSION=$VERSION" >> $GITHUB_ENV
- name: Build the project
run: dotnet build --configuration Release --no-restore

- name: Pack the NuGet package
run: dotnet pack --configuration Release --no-build --output ./nupkg -p:PackageVersion=${{ env.VERSION }}

- name: Publish the NuGet package
env:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
run: dotnet nuget push ./nupkg/*.nupkg --api-key $NUGET_API_KEY --source https://api.nuget.org/v3/index.json
55 changes: 55 additions & 0 deletions .github/workflows/test-with-code-coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Test with code coverage

on:
push:
branches:
- '**'

env:
DOTNET_INSTALL_DIR: "./.dotnet"

jobs:
test:
runs-on: ubuntu-20.04
permissions:
pull-requests: write
contents: write
services:
elasticsearch:
image: elasticsearch:7.17.0
ports:
- 9200:9200
options: -e="discovery.type=single-node" -e="xpack.security.enabled=false" --health-cmd="curl http://localhost:9200/_cluster/health" --health-interval=10s --health-timeout=5s --health-retries=10
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup dotnet
uses: actions/setup-dotnet@v4
with:
dotnet-version: '7.0'
- name: Verify Elasticsearch connection
env:
ELASTIC_SEARCH_URL: http://127.0.0.1:${{ job.services.elasticsearch.ports[9200] }}
run: |
echo $ELASTIC_SEARCH_URL
curl -fsSL "$ELASTIC_SEARCH_URL/_cat/health?h=status"
- name: Install dependencies
run: dotnet restore --verbosity quiet

- name: Build
run: dotnet build --no-restore /clp:ErrorsOnly /p:GeneratePackageOnBuild=false --verbosity quiet

- name: Test
run: |
for name in `ls ./test/*.Tests/*.csproj | awk '{print $NF}'`;
do
dotnet test ${name} --no-restore --no-build --logger trx --settings CodeCoverage.runsettings --results-directory coverage --collect:"XPlat Code Coverage"
done
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
files: coverage/*/coverage.cobertura.xml
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,17 @@ protected override async Task<List<string>> GetCollectionNameAsync(List<Collecti
{
if (!_shardingKeyProvider.IsShardingCollection())
return new List<string> { GetDefaultCollectionName() };

var shardKeyCollectionNames = await _shardingKeyProvider.GetCollectionNameAsync(conditions);
var routeKeyCollectionNames =
await _collectionRouteKeyProvider.GetCollectionNameAsync(conditions);

if (shardKeyCollectionNames.Count > 0 && routeKeyCollectionNames.Count > 0)
var shardKeyCollectionNames = await _shardingKeyProvider.GetCollectionNameAsync(conditions);
if (shardKeyCollectionNames.IsNullOrEmpty())
{
return shardKeyCollectionNames.Intersect(routeKeyCollectionNames).ToList();
return await _collectionRouteKeyProvider.GetCollectionNameAsync(conditions);
}
return shardKeyCollectionNames.Concat(routeKeyCollectionNames).ToList();

return shardKeyCollectionNames;
}

protected override async Task<List<string>> GetCollectionNameByEntityAsync(TEntity entity)
protected override async Task<List<string>> GetCollectionNameByEntityAsync(TEntity entity)
{
if (entity == null)
return new List<string> { GetDefaultCollectionName() };
Expand All @@ -65,15 +63,15 @@ protected override async Task<List<string>> GetCollectionNameByEntityAsync(List<
{
if (entities == null || entities.Count == 0)
return new List<string> { GetDefaultCollectionName() };

return _shardingKeyProvider.IsShardingCollection()
? await _shardingKeyProvider.GetCollectionNameAsync(entities)
: new List<string> { GetDefaultCollectionName() };
}

protected override async Task<string> GetCollectionNameByIdAsync<TKey>(TKey id)
{
if (!_shardingKeyProvider.IsShardingCollection())
if (!_shardingKeyProvider.IsShardingCollection())
return GetDefaultCollectionName();
return await _collectionRouteKeyProvider.GetCollectionNameAsync(id.ToString());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Text;
using AElf.EntityMapping.Elasticsearch.Options;
using Elasticsearch.Net;
using Microsoft.Extensions.Options;
Expand All @@ -20,6 +21,20 @@ public ElasticsearchClientProvider(IOptions<ElasticsearchOptions> options)
var uris = options.Value.Uris.ConvertAll(x => new Uri(x));
var connectionPool = new StaticConnectionPool(uris);
var settings = new ConnectionSettings(connectionPool);
// .DisableDirectStreaming();
// .OnRequestCompleted(callDetails =>
// {
// // Print Request DSL
// if (callDetails.RequestBodyInBytes != null)
// {
// Console.WriteLine($"Request JSON: {Encoding.UTF8.GetString(callDetails.RequestBodyInBytes)}");
// }
// // // Print Response Data
// // if (callDetails.ResponseBodyInBytes != null)
// // {
// // Console.WriteLine($"Response JSON: {Encoding.UTF8.GetString(callDetails.ResponseBodyInBytes)}");
// // }
// });
_elasticClient = new ElasticClient(settings);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.ObjectModel;
using System.Linq.Expressions;
using AElf.EntityMapping.Linq;
using Nest;
using Remotion.Linq;
using Remotion.Linq.Clauses;
Expand All @@ -25,26 +26,26 @@ public QueryAggregator GenerateElasticQuery<T>(QueryModel queryModel)
QueryAggregator = new QueryAggregator();
VisitQueryModel(queryModel);
return QueryAggregator;
}
}

public override void VisitQueryModel(QueryModel queryModel)
{
queryModel.SelectClause.Accept(this, queryModel);
queryModel.MainFromClause.Accept(this, queryModel);
VisitBodyClauses(queryModel.BodyClauses, queryModel);
VisitResultOperators(queryModel.ResultOperators, queryModel);
}

public override void VisitMainFromClause(MainFromClause fromClause, QueryModel queryModel)
{
if (fromClause.FromExpression is SubQueryExpression subQueryExpression)
{
VisitQueryModel(subQueryExpression.QueryModel);
}

base.VisitMainFromClause(fromClause, queryModel);
}

public override void VisitWhereClause(WhereClause whereClause, QueryModel queryModel, int index)
{
var tree = new GeneratorExpressionTreeVisitor<TU>(_propertyNameInferrerParser);
Expand All @@ -66,62 +67,110 @@ public override void VisitWhereClause(WhereClause whereClause, QueryModel queryM

QueryAggregator.Query = query;
}

base.VisitWhereClause(whereClause, queryModel, index);
}

protected override void VisitResultOperators(ObservableCollection<ResultOperatorBase> resultOperators,
QueryModel queryModel)
{
foreach (var resultOperator in resultOperators)
{
if (resultOperator is SkipResultOperator skipResultOperator)
switch (resultOperator)
{
QueryAggregator.Skip = skipResultOperator.GetConstantCount();
}

if (resultOperator is TakeResultOperator takeResultOperator)
{
QueryAggregator.Take = takeResultOperator.GetConstantCount();
}

if (resultOperator is GroupResultOperator groupResultOperator)
{
var members = new List<Tuple<string, Type>>();

switch (groupResultOperator.KeySelector)
case SkipResultOperator skipResultOperator:
QueryAggregator.Skip = skipResultOperator.GetConstantCount();
break;
case TakeResultOperator takeResultOperator:
QueryAggregator.Take = takeResultOperator.GetConstantCount();
break;
case GroupResultOperator groupResultOperator:
{
case MemberExpression memberExpression:
members.Add(new Tuple<string, Type>(memberExpression.Member.Name, memberExpression.Type));
break;
case NewExpression newExpression:
members.AddRange(newExpression.Arguments
.Cast<MemberExpression>()
.Select(memberExpression => new Tuple<string, Type>(memberExpression.Member.Name, memberExpression.Type)));
break;
var members = new List<Tuple<string, Type>>();

switch (groupResultOperator.KeySelector)
{
case MemberExpression memberExpression:
members.Add(new Tuple<string, Type>(GetFullNameKey(memberExpression), memberExpression.Type));
break;
case NewExpression newExpression:
members.AddRange(newExpression.Arguments
.Cast<MemberExpression>()
.Select(memberExpression => new Tuple<string, Type>(GetFullNameKey(memberExpression), memberExpression.Type)));
break;
}

members.ForEach(property => { QueryAggregator.GroupByExpressions.Add(new GroupByProperties(property.Item1, property.Item2)); });
break;
}

members.ForEach(property =>
{
QueryAggregator.GroupByExpressions.Add(new GroupByProperties(property.Item1, property.Item2));
});
case AfterResultOperator afterResultOperator:
QueryAggregator.After = afterResultOperator.GetConstantPosition();
break;
}
}

base.VisitResultOperators(resultOperators, queryModel);
}


private string GetFullNameKey(MemberExpression memberExpression)
{
var key = _propertyNameInferrerParser.Parser(memberExpression.Member.Name);
while (memberExpression.Expression != null)
{
memberExpression = memberExpression.Expression as MemberExpression;
if (memberExpression == null)
{
break;
}

key = _propertyNameInferrerParser.Parser(memberExpression.Member.Name) + "." + key;
return key;
}

return key;
}


public override void VisitOrderByClause(OrderByClause orderByClause, QueryModel queryModel, int index)
{
foreach (var ordering in orderByClause.Orderings)
{
var memberExpression = (MemberExpression) ordering.Expression;
var memberExpression = (MemberExpression)ordering.Expression;
var direction = orderByClause.Orderings[0].OrderingDirection;
var propertyName = memberExpression.Member.Name;
var type = memberExpression.Type;
QueryAggregator.OrderByExpressions.Add(new OrderProperties(propertyName, type, direction));
//get full property path if there is sub object
string propertyName = GetFullPropertyPath(memberExpression);

if (!string.IsNullOrEmpty(propertyName))
{
var type = memberExpression.Type;
QueryAggregator.OrderByExpressions.Add(new OrderProperties(propertyName, type, direction));
}
}

base.VisitOrderByClause(orderByClause, queryModel, index);
}

private string GetFullPropertyPath(Expression expression)
{
switch (expression)
{
case MemberExpression memberExpression:
var parentPath = GetFullPropertyPath(memberExpression.Expression);
var currentMemberName = _propertyNameInferrerParser.Parser(memberExpression.Member.Name);
return string.IsNullOrEmpty(parentPath) ? currentMemberName : $"{parentPath}.{currentMemberName}";

case MethodCallExpression methodCallExpression:
// Handles method calls like 'get_Item', which are usually associated with indexed access to collections
if (methodCallExpression.Method.Name.Equals("get_Item") && methodCallExpression.Object != null)
{
// Assuming this is an indexed access to an array or list, we will ignore the index and use only the name of the collection
var collectionPath = GetFullPropertyPath(methodCallExpression.Object);
return collectionPath; // Returns the path of the collection directly, without adding an index
}
break;
}

return null;
}
}
}
Loading

0 comments on commit 034e667

Please sign in to comment.