Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v1.0.0 #26

Merged
merged 30 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e5555b1
feat: add GetCollectionNameAsync error log
AElfBourneShi Apr 16, 2024
e723fe0
feat: optimize log
AElfBourneShi Apr 16, 2024
499fb31
feat: add route key provider log
AElfBourneShi Apr 16, 2024
64b62f6
feat: optimize get route key collection search
AElfBourneShi Apr 16, 2024
49dce54
feat:test Sub object Query
louis4li Apr 18, 2024
93f344c
fix: query with multi field
Apr 18, 2024
75cdd01
Merge branch 'fix/search-null' into feature/fix-sub-object-qeury
Apr 18, 2024
deaadc6
feat: order by clause support sub object query
Apr 23, 2024
ef49dc9
feat: add wildcard query unit test
Apr 25, 2024
403cca3
feat: del duplicated code
Apr 25, 2024
cb15560
feat: del duplicate code
Apr 25, 2024
a3dc043
Merge pull request #15 from AElfProject/feature/fix-sub-object-query
louis4li Apr 25, 2024
08fbbcf
feat: optimize get index method
Apr 28, 2024
2dbd2e6
feat: add settings for create index
zhxymh May 8, 2024
f092b4f
Merge remote-tracking branch 'origin/feature/fix-sub-object-query' in…
zhxymh May 11, 2024
c5a50dc
feat: support search after
zhxymh May 13, 2024
5e5e37f
feat: support search after
zhxymh May 13, 2024
1236e21
fix: sub object order by & nested object order by query
AElfBourneShi May 21, 2024
f21dbbd
perf: optimize code
AElfBourneShi May 21, 2024
15e8b50
perf: optimize code
AElfBourneShi May 21, 2024
18a88d2
fix: GetCollectionName unit test
AElfBourneShi May 21, 2024
d1e121c
Merge remote-tracking branch 'origin/feature/fix-sub-object-query' in…
zhxymh May 21, 2024
f8b62de
Merge remote-tracking branch 'origin/feature/fix-sub-object-query' in…
zhxymh May 21, 2024
5ea9b61
Merge pull request #19 from AElfProject/feature/fix-sub-object-query
AElfBourneShi May 21, 2024
7a7f798
fix: get collection name unit test
AElfBourneShi May 21, 2024
63ee96f
Merge pull request #23 from AElfProject/fix/sub-object-orderby
AElfBourneShi May 22, 2024
5ae464d
Merge pull request #21 from AElfProject/feature/index-setting
zhxymh May 22, 2024
3e3d688
feat: merge origin/dev
zhxymh May 22, 2024
15f2e9e
Merge pull request #22 from AElfProject/feature/search-after
zhxymh May 22, 2024
e8a631b
Feature: delete index (#25)
AElfBourneShi Aug 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@
{
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);

Check warning on line 45 in src/AElf.EntityMapping.Elasticsearch/ElasticsearchCollectionNameProvider.cs

View check run for this annotation

Codecov / codecov/patch

src/AElf.EntityMapping.Elasticsearch/ElasticsearchCollectionNameProvider.cs#L45

Added line #L45 was not covered by tests
}
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 @@
{
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