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

Allow describing an index from a given Type. #525

Closed
wants to merge 52 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
9cbde32
Use System.Text.Json as the default serializer (#504)
sebastienros Dec 22, 2023
263f1d4
remake DescribeContext<>.For
hyzx86 Dec 28, 2023
8fa1f8e
fix UnitTest
hyzx86 Dec 28, 2023
cc9cc7e
Update README.md
hyzx86 Dec 29, 2023
c6c65cd
Update README.md
hyzx86 Dec 29, 2023
d4645fa
Avoid InvalidCastException
Dec 29, 2023
2fd4d5b
fix type cache clear
Dec 29, 2023
23f9c6b
Update README.md
hyzx86 Dec 29, 2023
25f4198
clear code style
Dec 29, 2023
e373ca0
Merge branch 'dynamicIndexType' of https://github.com/hyzx86/yessql i…
Dec 29, 2023
482ed90
Update PropertyIndex.cs
hyzx86 Dec 29, 2023
f850380
Simplify and Cleanup
MikeAlhayek Dec 29, 2023
86d4302
Moving the test. Test should fail MySQL for verification.
MikeAlhayek Dec 29, 2023
74936c1
Fix MySQL error
MikeAlhayek Dec 29, 2023
2c69da9
Last tewaks
MikeAlhayek Dec 29, 2023
144d363
If the same name type is already cached, it should be removed from th…
hyzx86 Dec 30, 2023
fbabfc5
add Dynamic Type UnitTest
hyzx86 Dec 31, 2023
1d5e8a6
validate index type instance
hyzx86 Dec 31, 2023
e83d236
remove error check
hyzx86 Dec 31, 2023
5371cd1
Emulating the usage scenario in OrchardCore, the store may be initial…
hyzx86 Dec 31, 2023
5df8f36
update unit test
hyzx86 Dec 31, 2023
df795ab
add IndexTypeCacheProvider
hyzx86 Jan 1, 2024
f74cc3e
Update test/YesSql.Tests/Indexes/DynamicTypeGeneratorSample.cs
hyzx86 Jan 2, 2024
355b69a
Update test/YesSql.Tests/Indexes/DynamicTypeGeneratorSample.cs
hyzx86 Jan 2, 2024
6122ff4
Update test/YesSql.Tests/Indexes/PropertyIndex.cs
hyzx86 Jan 2, 2024
135d110
Update test/YesSql.Tests/Indexes/DynamicTypeGeneratorSample.cs
hyzx86 Jan 2, 2024
5ee8f86
Update test/YesSql.Tests/Indexes/DynamicTypeGeneratorSample.cs
hyzx86 Jan 2, 2024
c500f20
Update test/YesSql.Tests/Indexes/DynamicTypeGeneratorSample.cs
hyzx86 Jan 2, 2024
b074891
Update test/YesSql.Tests/Indexes/DynamicTypeGeneratorSample.cs
hyzx86 Jan 2, 2024
10cdf25
Update test/YesSql.Tests/Indexes/DynamicTypeGeneratorSample.cs
hyzx86 Jan 2, 2024
7c18fb9
Update test/YesSql.Tests/Indexes/DynamicTypeGeneratorSample.cs
hyzx86 Jan 2, 2024
a52b5a4
Update test/YesSql.Tests/CoreTests.cs
hyzx86 Jan 2, 2024
c213254
Update src/YesSql.Abstractions/Indexes/DescribeContext.cs
hyzx86 Jan 2, 2024
01d217f
fix code format
hyzx86 Jan 2, 2024
e458a98
use vitrual methods instead Interface
hyzx86 Jan 2, 2024
554794d
use session.RegisterIndexes to instead store.RegisterIndexes<Property…
hyzx86 Jan 2, 2024
b945de0
Update test/YesSql.Tests/CoreTests.cs
hyzx86 Jan 2, 2024
be8d8f3
Update src/YesSql.Core/Commands/IndexCommand.cs
hyzx86 Jan 2, 2024
ebc0b32
Update src/YesSql.Abstractions/Indexes/IndexTypeCacheProvider.cs
hyzx86 Jan 2, 2024
bc1d2e7
Update src/YesSql.Abstractions/Indexes/IndexTypeCacheProvider.cs
hyzx86 Jan 2, 2024
72002c8
Update src/YesSql.Abstractions/Indexes/DescribeContext.cs
hyzx86 Jan 2, 2024
16acf5e
Update src/YesSql.Abstractions/IStore.cs
hyzx86 Jan 2, 2024
212a333
add UpdateTypeCache Sample
hyzx86 Jan 2, 2024
c40413d
Merge branch 'dynamicIndexType' of https://github.com/hyzx86/yessql i…
hyzx86 Jan 2, 2024
b0bf2ef
update default index cache
Jan 3, 2024
d5429ea
Restoring the test code
Jan 3, 2024
cd0928a
rename
Jan 3, 2024
784b81c
update unit test
Jan 3, 2024
88d1a56
Merge branch 'main' into release/5.0
MikeAlhayek Jan 26, 2024
ac2d719
merg from 5.x
hyzx86 Feb 26, 2024
8e31c26
Merge branch 'dynamicIndexType' of https://github.com/hyzx86/yessql i…
hyzx86 Feb 26, 2024
2b836e8
Merge remote-tracking branch 'origin/main' into dynamicIndexType
hyzx86 Apr 10, 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
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,29 @@ A .NET document database interface for relational databases, because in SQL we (
[![NuGet](https://img.shields.io/nuget/v/YesSql.svg)](https://www.nuget.org/packages/YesSql)
[![MyGet](https://img.shields.io/myget/yessql/vpre/yessql.svg?label=MyGet)](https://www.myget.org/feed/yessql/package/nuget/yessql)

Dynamic index type support
-------------------

```c#
public class PropertyDynamicIndexProvider : IndexProvider<Property>
{
public override void Describe(DescribeContext<Property> context)
{
var propertyType = typeof(PropertyIndex);
context
.For(propertyType) //Specify a type directly
.Map(property => new PropertyIndex
{
Name = property.Name,
ForRent = property.ForRent,
IsOccupied = property.IsOccupied,
Location = property.Location
});
}
}
```

MikeAlhayek marked this conversation as resolved.
Show resolved Hide resolved

How does it work ?
-------------------

Expand Down
15 changes: 14 additions & 1 deletion src/YesSql.Abstractions/Indexes/DescribeContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,19 @@ public IEnumerable<IndexDescriptor> Describe(params Type[] types)
});
}

public IMapFor<T, IIndex> For(Type indexType)
{
return For<IIndex, object>(indexType);
}
MikeAlhayek marked this conversation as resolved.
Show resolved Hide resolved
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved
public IMapFor<T, TIndex> For<TIndex>() where TIndex : IIndex
{
return For<TIndex, object>();
}

public IMapFor<T, TIndex> For<TIndex, TKey>() where TIndex : IIndex
{
return For<TIndex, object>(null);
MikeAlhayek marked this conversation as resolved.
Show resolved Hide resolved
}
MikeAlhayek marked this conversation as resolved.
Show resolved Hide resolved
public IMapFor<T, TIndex> For<TIndex, TKey>(Type indexType) where TIndex : IIndex
{
List<IDescribeFor> descriptors;

Expand All @@ -40,6 +47,12 @@ public IMapFor<T, TIndex> For<TIndex, TKey>() where TIndex : IIndex
}

var describeFor = new IndexDescriptor<T, TIndex, TKey>();

if (indexType != null)
MikeAlhayek marked this conversation as resolved.
Show resolved Hide resolved
{
describeFor.IndexType = indexType;
}

descriptors.Add(describeFor);

return describeFor;
Expand Down
3 changes: 1 addition & 2 deletions src/YesSql.Abstractions/Indexes/DescribeFor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ public class IndexDescriptor<T, TIndex, TKey> : IDescribeFor, IMapFor<T, TIndex>
private Func<object, bool> _filter;

public PropertyInfo GroupProperty { get; set; }
public Type IndexType { get { return typeof(TIndex); } }

public Type IndexType { get; set; } = typeof(TIndex);
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved
public Func<object, bool> Filter => _filter;

public IGroupFor<TIndex> Map(Func<T, IEnumerable<TIndex>> map)
Expand Down
12 changes: 9 additions & 3 deletions src/YesSql.Core/Commands/IndexCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public abstract class IndexCommand : IIndexCommand
protected readonly IStore _store;

private static readonly ConcurrentDictionary<PropertyInfo, PropertyInfoAccessor> PropertyAccessors = new();
private static readonly ConcurrentDictionary<string, PropertyInfo[]> TypeProperties = new();
private static readonly ConcurrentDictionary<Type, PropertyInfo[]> TypeProperties = new();
private static readonly ConcurrentDictionary<CompoundKey, string> InsertsList = new();
private static readonly ConcurrentDictionary<CompoundKey, string> UpdatesList = new();

Expand Down Expand Up @@ -67,13 +67,19 @@ protected static void GetProperties(DbCommand command, object item, string suffi

protected static PropertyInfo[] TypePropertiesCache(Type type)
{
if (TypeProperties.TryGetValue(type.FullName, out var pis))
if (TypeProperties.TryGetValue(type, out var pis))
{
return pis;
}
//Avoid InvalidCastException
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved
var exists = TypeProperties.Keys.FirstOrDefault(x => x.FullName == type.FullName);
if (exists != null)
{
TypeProperties.Remove(exists, out _);
}

var properties = type.GetProperties().Where(IsWriteable).ToArray();
TypeProperties[type.FullName] = properties;
TypeProperties[type] = properties;
return properties;
}

Expand Down
16 changes: 16 additions & 0 deletions test/YesSql.Tests/Indexes/PropertyIndex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,20 @@ public override void Describe(DescribeContext<Property> context)
});
}
}
public class PropertyDynamicIndexProvider : IndexProvider<Property>
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved
{
public override void Describe(DescribeContext<Property> context)
{
var propertyType = typeof(PropertyIndex);
context
.For(propertyType)
.Map(property => new PropertyIndex
{
Name = property.Name,
ForRent = property.ForRent,
IsOccupied = property.IsOccupied,
Location = property.Location
});
}
}
}
45 changes: 45 additions & 0 deletions test/YesSql.Tests/SqliteTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,50 @@ await builder

await session.SaveAsync(property);
}

[Fact]
public async Task ShouldDynamicIndexPropertyKeys()
{
await using (var connection = _store.Configuration.ConnectionFactory.CreateConnection())
{
await connection.OpenAsync();

await using var transaction = await connection.BeginTransactionAsync(_store.Configuration.IsolationLevel);
var builder = new SchemaBuilder(_store.Configuration, transaction);

await builder
.DropMapIndexTableAsync<PropertyIndex>();

await builder
.CreateMapIndexTableAsync<PropertyIndex>(column => column
.Column<string>(nameof(PropertyIndex.Name), col => col.WithLength(4000))
.Column<bool>(nameof(PropertyIndex.ForRent))
.Column<bool>(nameof(PropertyIndex.IsOccupied))
.Column<string>(nameof(PropertyIndex.Location), col => col.WithLength(4000))
);

await builder
MikeAlhayek marked this conversation as resolved.
Show resolved Hide resolved
.AlterTableAsync(nameof(PropertyIndex), table => table
.CreateIndex("IDX_Property", "Name", "ForRent", "IsOccupied", "Location"));

await transaction.CommitAsync();
}

_store.RegisterIndexes<PropertyDynamicIndexProvider>();

await using var session = _store.CreateSession();
var property = new Property
{
Name = new string('*', 4000),
IsOccupied = true,
ForRent = true,
Location = new string('*', 4000)
};

await session.SaveAsync(property);
await session.SaveChangesAsync();
var idx = await session.Query<Property, PropertyIndex>(x => x.Id == 1).ListAsync();
Assert.NotEmpty(idx);
}
}
}