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

RNET-1159: Flexible-schema POC #3630

Draft
wants to merge 55 commits into
base: fp/flexible-schema-epic
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
dff4cde
Using flexible-schema core branch
papafe Jun 13, 2024
571eca8
Added basis
papafe Jun 17, 2024
8457a1a
Added basic implementation for testing
papafe Jun 17, 2024
da57ca9
Modified source genrated
papafe Jun 17, 2024
38a9800
Added basic test
papafe Jun 17, 2024
7695a8c
Basic test passing [skip-ci]
papafe Jun 18, 2024
4462ec1
Updated core
papafe Jun 18, 2024
faa7df0
Removed unnecessary
papafe Jun 18, 2024
f532c84
Improved handling of lists and objects
papafe Jun 18, 2024
8d7da77
Various improvements
papafe Jun 19, 2024
78a1a13
Added configuration for flexible schema
papafe Jun 20, 2024
fbc1d36
Updated changelog
papafe Jun 20, 2024
a1eadde
Fixes
papafe Jun 20, 2024
243c782
Chwnged name
papafe Jun 24, 2024
1ca8e60
Test marshaled vector
papafe Jun 25, 2024
5c60adf
Improvements
papafe Jul 1, 2024
ee2e4b9
Various fixes
papafe Jul 10, 2024
ac19189
Updated core [skip-ci]
papafe Jul 10, 2024
0060357
Added try methods
papafe Jul 10, 2024
6c9e74d
Added extended schema
papafe Jul 17, 2024
69a8a39
rename
papafe Jul 17, 2024
c45ace8
Small fix
papafe Jul 17, 2024
3827790
Addded extended property object
papafe Jul 17, 2024
91baa53
Added hasProperty
papafe Jul 19, 2024
580f586
Corrected extra property
papafe Jul 19, 2024
b65caee
Moved tests to new file
papafe Jul 19, 2024
2f341e3
Added dictionary paths
papafe Jul 22, 2024
8af7de1
Added tests [skip-ci]
papafe Jul 22, 2024
9b5f498
Removed extended schema
papafe Jul 23, 2024
429de20
Added more tests and support for object schema enumeration
papafe Jul 24, 2024
2de80d7
Fixed TryGetPropertyIndex
papafe Jul 24, 2024
37d62fa
Simplified tryGetProperty index, extended object schema lazy initiali…
papafe Jul 25, 2024
d5f5b2c
Corrected property constructor and accessibility of some object handl…
papafe Jul 25, 2024
819b9aa
Corrected config name and restored dynamic access tests
papafe Jul 25, 2024
cbbe6c3
Small corrections
papafe Jul 25, 2024
3c03f3d
Merge branch 'fp/flexible-schema-epic' into fp/flexible-schema
papafe Jul 25, 2024
37d6f0a
wrapper correction
papafe Jul 26, 2024
02e731a
Correction for .net framework
papafe Jul 26, 2024
b66bd35
Slightl simplification
papafe Jul 29, 2024
705924b
Fixed schema
papafe Jul 30, 2024
b04c964
Removed extra method
papafe Aug 6, 2024
7d257df
Using tryget instead of get
papafe Aug 7, 2024
c86f704
Small improvements
papafe Aug 7, 2024
8c8a010
Fix for schema
papafe Aug 7, 2024
c949dd8
Corrected memory management
papafe Aug 7, 2024
a496b78
Corrected get
papafe Aug 7, 2024
45033bf
Added const
papafe Aug 7, 2024
3c2312f
Ignoring test
papafe Aug 7, 2024
84ecda3
Ignored correct test
papafe Aug 8, 2024
6863498
Some corrections
papafe Aug 8, 2024
9f620a5
Simplified Get and TryGet methods in DynamicApi
papafe Aug 8, 2024
bfc8d51
Removed tests for dynamic api on lists and simplified code
papafe Aug 8, 2024
52a5faa
Removed tryUnset
papafe Aug 9, 2024
04f8863
Small improvement
papafe Aug 12, 2024
187f501
Added stub for unmanaged object dynamic api
papafe Aug 12, 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
4 changes: 4 additions & 0 deletions Realm/Realm/Configurations/RealmConfigurationBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@
/// </value>
public ShouldCompactDelegate? ShouldCompactOnLaunch { get; set; }

//TODO Add docs

Check warning on line 92 in Realm/Realm/Configurations/RealmConfigurationBase.cs

View workflow job for this annotation

GitHub Actions / Verify TODOs

Realm/Realm/Configurations/RealmConfigurationBase.cs#L92

TODO entry doesn't have a link to Github issue or Jira ticket Add docs

Check warning on line 92 in Realm/Realm/Configurations/RealmConfigurationBase.cs

View workflow job for this annotation

GitHub Actions / Test Weaver (ubuntu-latest, linux-x64)

Check warning on line 92 in Realm/Realm/Configurations/RealmConfigurationBase.cs

View workflow job for this annotation

GitHub Actions / Test Weaver (macos-14, osx-arm64)

Check warning on line 92 in Realm/Realm/Configurations/RealmConfigurationBase.cs

View workflow job for this annotation

GitHub Actions / Test Source Generation

Check warning on line 92 in Realm/Realm/Configurations/RealmConfigurationBase.cs

View workflow job for this annotation

GitHub Actions / Test Weaver (windows-latest, win-x64)

Check warning on line 92 in Realm/Realm/Configurations/RealmConfigurationBase.cs

View workflow job for this annotation

GitHub Actions / Test Code Coverage

Single line comment should begin with a space. (https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1005.md) [/home/runner/work/realm-dotnet/realm-dotnet/Realm/Realm/Realm.csproj::TargetFramework=net8.0]

Check warning on line 92 in Realm/Realm/Configurations/RealmConfigurationBase.cs

View workflow job for this annotation

GitHub Actions / Package NuGet

public bool RelaxedSchema { get; set; }

Check warning on line 93 in Realm/Realm/Configurations/RealmConfigurationBase.cs

View workflow job for this annotation

GitHub Actions / Test Weaver (ubuntu-latest, linux-x64)

Check warning on line 93 in Realm/Realm/Configurations/RealmConfigurationBase.cs

View workflow job for this annotation

GitHub Actions / Test Weaver (macos-14, osx-arm64)

Check warning on line 93 in Realm/Realm/Configurations/RealmConfigurationBase.cs

View workflow job for this annotation

GitHub Actions / Test Source Generation

Check warning on line 93 in Realm/Realm/Configurations/RealmConfigurationBase.cs

View workflow job for this annotation

GitHub Actions / Test Weaver (windows-latest, win-x64)

Check warning on line 93 in Realm/Realm/Configurations/RealmConfigurationBase.cs

View workflow job for this annotation

GitHub Actions / Test Code Coverage

Elements should be documented (https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1600.md) [/home/runner/work/realm-dotnet/realm-dotnet/Realm/Realm/Realm.csproj::TargetFramework=net8.0]

Check warning on line 93 in Realm/Realm/Configurations/RealmConfigurationBase.cs

View workflow job for this annotation

GitHub Actions / Package NuGet


internal bool EnableCache = true;

/// <summary>
Expand Down Expand Up @@ -254,6 +257,7 @@
managed_config = GCHandle.ToIntPtr(managedConfig),
encryption_key = MarshaledVector<byte>.AllocateFrom(EncryptionKey, arena),
invoke_should_compact_callback = ShouldCompactOnLaunch != null,
relaxed_schema = RelaxedSchema,
};

return config;
Expand Down
22 changes: 20 additions & 2 deletions Realm/Realm/DatabaseTypes/Accessors/ManagedAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
{
private readonly Lazy<int> _hashCode;

private readonly Lazy<ObjectSchema> _objectSchema;

private readonly Lazy<DynamicObjectApi> _dynamicObjectApi;

private NotificationTokenHandle? _notificationToken;

private Action<string>? _onNotifyPropertyChanged;
Expand All @@ -60,7 +64,7 @@
public bool IsFrozen => Realm.IsFrozen;

/// <inheritdoc/>
public ObjectSchema ObjectSchema => Metadata.Schema;
public ObjectSchema ObjectSchema => _objectSchema.Value;

/// <inheritdoc/>
public int BacklinksCount => ObjectHandle?.GetBacklinkCount() ?? 0;
Expand All @@ -69,7 +73,7 @@
IThreadConfinedHandle IThreadConfined.Handle => ObjectHandle;

/// <inheritdoc/>
public DynamicObjectApi DynamicApi => new(this);
public DynamicObjectApi DynamicApi => _dynamicObjectApi.Value;

/// <inheritdoc/>
Metadata IMetadataObject.Metadata => Metadata;
Expand All @@ -82,6 +86,8 @@
#pragma warning restore CS8618
{
_hashCode = new(() => ObjectHandle!.GetObjHash());
_objectSchema = new(() => Realm!.Config.RelaxedSchema ? Metadata!.Schema.MakeCopyWithHandle(ObjectHandle!) : Metadata!.Schema);
_dynamicObjectApi = new(() => new DynamicManagedObjectApi(this));
}

[MemberNotNull(nameof(Realm), nameof(ObjectHandle), nameof(Metadata))]
Expand All @@ -108,12 +114,24 @@
return ObjectHandle.GetValue(propertyName, Metadata, Realm);
}

/// AddDocs
public bool TryGetValue(string propertyName, out RealmValue value)
{
return ObjectHandle.TryGetValue(propertyName, Metadata, Realm, out value);
}

/// <inheritdoc/>
public void SetValue(string propertyName, RealmValue val)
{
ObjectHandle.SetValue(propertyName, Metadata, val, Realm);
}

//TODO Add docs

Check warning on line 129 in Realm/Realm/DatabaseTypes/Accessors/ManagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Verify TODOs

Realm/Realm/DatabaseTypes/Accessors/ManagedAccessor.cs#L129

TODO entry doesn't have a link to Github issue or Jira ticket Add docs

Check warning on line 129 in Realm/Realm/DatabaseTypes/Accessors/ManagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Test Weaver (ubuntu-latest, linux-x64)

Check warning on line 129 in Realm/Realm/DatabaseTypes/Accessors/ManagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Test Weaver (macos-14, osx-arm64)

Check warning on line 129 in Realm/Realm/DatabaseTypes/Accessors/ManagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Test Source Generation

Check warning on line 129 in Realm/Realm/DatabaseTypes/Accessors/ManagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Test Weaver (windows-latest, win-x64)

Check warning on line 129 in Realm/Realm/DatabaseTypes/Accessors/ManagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Test Code Coverage

Single line comment should begin with a space. (https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1005.md) [/home/runner/work/realm-dotnet/realm-dotnet/Realm/Realm/Realm.csproj::TargetFramework=net8.0]

Check warning on line 129 in Realm/Realm/DatabaseTypes/Accessors/ManagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Package NuGet

public bool UnsetProperty(string propertyName)
{
return ObjectHandle.UnsetProperty(propertyName);
}

/// <inheritdoc/>
public void SetValueUnique(string propertyName, RealmValue val)
{
Expand Down
32 changes: 32 additions & 0 deletions Realm/Realm/DatabaseTypes/Accessors/UnmanagedAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@

private Action<string>? _onNotifyPropertyChanged;

//TODO we could initialize this lazily

Check warning on line 40 in Realm/Realm/DatabaseTypes/Accessors/UnmanagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Verify TODOs

Realm/Realm/DatabaseTypes/Accessors/UnmanagedAccessor.cs#L40

TODO entry doesn't have a link to Github issue or Jira ticket we could initialize this lazily

Check warning on line 40 in Realm/Realm/DatabaseTypes/Accessors/UnmanagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Test Weaver (ubuntu-latest, linux-x64)

Check warning on line 40 in Realm/Realm/DatabaseTypes/Accessors/UnmanagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Test Weaver (macos-14, osx-arm64)

Check warning on line 40 in Realm/Realm/DatabaseTypes/Accessors/UnmanagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Test Source Generation

Check warning on line 40 in Realm/Realm/DatabaseTypes/Accessors/UnmanagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Test Weaver (windows-latest, win-x64)

Check warning on line 40 in Realm/Realm/DatabaseTypes/Accessors/UnmanagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Test Code Coverage

Single line comment should begin with a space. (https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1005.md) [/home/runner/work/realm-dotnet/realm-dotnet/Realm/Realm/Realm.csproj::TargetFramework=net8.0]

Check warning on line 40 in Realm/Realm/DatabaseTypes/Accessors/UnmanagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Package NuGet

protected Dictionary<string, RealmValue> _extraProperties = new();

Check warning on line 41 in Realm/Realm/DatabaseTypes/Accessors/UnmanagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Test Weaver (ubuntu-latest, linux-x64)

Check warning on line 41 in Realm/Realm/DatabaseTypes/Accessors/UnmanagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Test Weaver (macos-14, osx-arm64)

Check warning on line 41 in Realm/Realm/DatabaseTypes/Accessors/UnmanagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Test Source Generation

Check warning on line 41 in Realm/Realm/DatabaseTypes/Accessors/UnmanagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Test Weaver (windows-latest, win-x64)

Check warning on line 41 in Realm/Realm/DatabaseTypes/Accessors/UnmanagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Test Code Coverage

Elements should be documented (https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1600.md) [/home/runner/work/realm-dotnet/realm-dotnet/Realm/Realm/Realm.csproj::TargetFramework=net8.0]

Check warning on line 41 in Realm/Realm/DatabaseTypes/Accessors/UnmanagedAccessor.cs

View workflow job for this annotation

GitHub Actions / Package NuGet


/// <inheritdoc/>
public bool IsManaged => false;

Expand Down Expand Up @@ -93,6 +96,10 @@
/// <inheritdoc/>
public abstract void SetValueUnique(string propertyName, RealmValue val);

public abstract bool TryGet(string propertyName, out RealmValue value);

public abstract bool Unset(string propertyName);

/// <inheritdoc/>
public virtual void SubscribeForNotifications(Action<string> notifyPropertyChangedDelegate)
{
Expand Down Expand Up @@ -168,5 +175,30 @@
{
throw new NotSupportedException("This should not be used for now");
}

public override bool TryGet(string propertyName, out RealmValue value)
{
return _extraProperties.TryGetValue(propertyName, out value);
}

public override bool Unset(string propertyName)
{
return _extraProperties.Remove(propertyName);
}

public bool TryGetExtraProperty(string propertyName, out RealmValue value)
{
return _extraProperties.TryGetValue(propertyName, out value);
}

public RealmValue GetExtraProperty(string propertyName)
{
return _extraProperties[propertyName];
}

public void SetExtraProperty(string propertyName, RealmValue val)
{
_extraProperties[propertyName] = val;
}
}
}
13 changes: 9 additions & 4 deletions Realm/Realm/DatabaseTypes/Metadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,19 @@ public Metadata(TableKey tableKey, IRealmObjectHelper helper, IDictionary<string
Schema = schema;
}

public IntPtr GetPropertyIndex(string propertyName)
public bool TryGetPropertyIndex(string propertyName, out IntPtr propertyIndex, bool throwOnMissing)
{
if (PropertyIndices.TryGetValue(propertyName, out var result))
if (PropertyIndices.TryGetValue(propertyName, out propertyIndex))
{
return result;
return true;
}

throw new MissingMemberException(Schema.Name, propertyName);
if (throwOnMissing)
{
throw new MissingMemberException(Schema.Name, propertyName);
}

return false;
}
}
}
235 changes: 235 additions & 0 deletions Realm/Realm/Dynamic/DynamicManagedObjectApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
////////////////////////////////////////////////////////////////////////////
//
// Copyright 2024 Realm Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License")
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using Realms.Helpers;
using Realms.Schema;

namespace Realms
{
/// <inheritdoc/>
public class DynamicManagedObjectApi : DynamicObjectApi
{
private readonly ManagedAccessor _managedAccessor;

private readonly bool _isRelaxedSchema;

internal DynamicManagedObjectApi(ManagedAccessor managedAccessor)
{
_managedAccessor = managedAccessor;
_isRelaxedSchema = managedAccessor.Realm.Config.RelaxedSchema;
}

/// <inheritdoc/>
public override RealmValue Get(string propertyName)
{
CheckGetPropertySuitability(propertyName);

return _managedAccessor.GetValue(propertyName);
}

/// <inheritdoc/>
public override T Get<T>(string propertyName)
{
return Get(propertyName).As<T>();
}

/// <inheritdoc/>
public override bool TryGet(string propertyName, out RealmValue propertyValue)
{
CheckGetPropertySuitability(propertyName);

return _managedAccessor.TryGetValue(propertyName, out propertyValue);
}

/// <inheritdoc/>
public override bool TryGet<T>(string propertyName, out T? propertyValue)
where T : default
{
var foundValue = TryGet(propertyName, out var val);
if (foundValue)
{
propertyValue = val.As<T>();
return true;
}

propertyValue = default;
return false;
}

/// <inheritdoc/>
public override void Set(string propertyName, RealmValue value)
{
if (GetModelProperty(propertyName, throwOnMissing: !_isRelaxedSchema) is Property property)
{
if (property.Type.IsComputed())
{
throw new NotSupportedException(
$"{_managedAccessor.ObjectSchema.Name}.{propertyName} is {property.GetDotnetTypeName()} (backlinks collection) and can't be set directly");
}

if (property.Type.IsCollection(out _))
{
throw new NotSupportedException(
$"{_managedAccessor.ObjectSchema.Name}.{propertyName} is {property.GetDotnetTypeName()} (collection) and can't be set directly.");
}

if (!property.Type.IsNullable() && value.Type == RealmValueType.Null)
{
throw new ArgumentException($"{_managedAccessor.ObjectSchema.Name}.{propertyName} is {property.GetDotnetTypeName()} which is not nullable, but the supplied value is <null>.");
}

if (!property.Type.IsRealmValue() && value.Type != RealmValueType.Null && property.Type.ToRealmValueType() != value.Type)
{
throw new ArgumentException($"{_managedAccessor.ObjectSchema.Name}.{propertyName} is {property.GetDotnetTypeName()} but the supplied value is {value.AsAny()?.GetType().Name} ({value}).");
}

if (property.IsPrimaryKey)
{
_managedAccessor.SetValueUnique(propertyName, value);
return;
}
}

_managedAccessor.SetValue(propertyName, value);
}

/// <inheritdoc/>
public override bool Unset(string propertyName)
{
return _managedAccessor.UnsetProperty(propertyName);
}

/// <inheritdoc/>
public override IQueryable<IRealmObjectBase> GetBacklinks(string propertyName)
{
var property = GetModelProperty(propertyName, PropertyTypeEx.IsComputed);

var resultsHandle = _managedAccessor.ObjectHandle.GetBacklinks(propertyName, _managedAccessor.Metadata);

var relatedMeta = _managedAccessor.Realm.Metadata[property.ObjectType!];
if (relatedMeta.Schema.BaseType == ObjectSchema.ObjectType.EmbeddedObject)
{
return new RealmResults<IEmbeddedObject>(_managedAccessor.Realm, resultsHandle, relatedMeta);
}

return new RealmResults<IRealmObject>(_managedAccessor.Realm, resultsHandle, relatedMeta);
}

/// <inheritdoc/>
public override IQueryable<IRealmObjectBase> GetBacklinksFromType(string fromObjectType, string fromPropertyName)
{
Argument.Ensure(_managedAccessor.Realm.Metadata.TryGetValue(fromObjectType, out var relatedMeta), $"Could not find schema for type {fromObjectType}", nameof(fromObjectType));

var resultsHandle = _managedAccessor.ObjectHandle.GetBacklinksForType(relatedMeta.TableKey, fromPropertyName, relatedMeta);
if (relatedMeta.Schema.BaseType == ObjectSchema.ObjectType.EmbeddedObject)
{
return new RealmResults<IEmbeddedObject>(_managedAccessor.Realm, resultsHandle, relatedMeta);
}

return new RealmResults<IRealmObject>(_managedAccessor.Realm, resultsHandle, relatedMeta);
}

/// <inheritdoc/>
public override IList<T> GetList<T>(string propertyName)
{
var property = GetModelProperty(propertyName, PropertyTypeEx.IsList);

var result = _managedAccessor.ObjectHandle.GetList<T>(_managedAccessor.Realm, propertyName, _managedAccessor.Metadata, property.ObjectType);
result.IsDynamic = true;
return result;
}

/// <inheritdoc/>
public override ISet<T> GetSet<T>(string propertyName)
{
var property = GetModelProperty(propertyName, PropertyTypeEx.IsSet);

var result = _managedAccessor.ObjectHandle.GetSet<T>(_managedAccessor.Realm, propertyName, _managedAccessor.Metadata, property.ObjectType);
result.IsDynamic = true;
return result;
}

/// <inheritdoc/>
public override IDictionary<string, T> GetDictionary<T>(string propertyName)
{
var property = GetModelProperty(propertyName, PropertyTypeEx.IsDictionary);

var result = _managedAccessor.ObjectHandle.GetDictionary<T>(_managedAccessor.Realm, propertyName, _managedAccessor.Metadata, property.ObjectType);
result.IsDynamic = true;
return result;
}

private void CheckGetPropertySuitability(string propertyName)
{
if (GetModelProperty(propertyName, throwOnMissing: !_isRelaxedSchema) is Property property)
{
if (property.Type.IsComputed())
{
throw new NotSupportedException(
$"{_managedAccessor.ObjectSchema.Name}.{propertyName} is {property.GetDotnetTypeName()} (backlinks collection) and can't be accessed using {nameof(Dynamic)}.{nameof(Get)}. Use {nameof(GetBacklinks)} instead.");
}

if (property.Type.IsCollection(out var collectionType) && collectionType == PropertyType.Set)
{
throw new NotSupportedException(
$"{_managedAccessor.ObjectSchema.Name}.{propertyName} is {property.GetDotnetTypeName()} and can't be accessed using {nameof(Dynamic)}.{nameof(Get)}. Use GetSet instead.");
}
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private Property? GetModelProperty(string propertyName, bool throwOnMissing)
{
Argument.NotNull(propertyName, nameof(propertyName));

if (!_managedAccessor.ObjectSchema.TryFindModelProperty(propertyName, out var property))
{
if (throwOnMissing)
{
throw new MissingMemberException(_managedAccessor.ObjectSchema.Name, propertyName);
}

return null;
}

return property;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private Property GetModelProperty(string propertyName, Func<PropertyType, bool> typeCheck, [CallerMemberName] string methodName = "")
{
Argument.NotNull(propertyName, nameof(propertyName));

if (!_managedAccessor.ObjectSchema.TryFindModelProperty(propertyName, out var property))
{
throw new MissingMemberException(_managedAccessor.ObjectSchema.Name, propertyName);
}

if (!typeCheck(property.Type))
{
throw new ArgumentException($"{_managedAccessor.ObjectSchema.Name}.{propertyName} is {property.GetDotnetTypeName()} which can't be accessed using {methodName}.");
}

return property;
}
}
}
Loading
Loading