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

Implement Mixed data type #2252

Merged
merged 101 commits into from
Apr 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
6ec51e3
Complete refactor of RealmMetadata and use of TableKey for handles
papafe Feb 1, 2021
20bf84a
Updated core
papafe Feb 11, 2021
998280d
Corrected core branch
papafe Feb 11, 2021
e18c5d5
Revert "Corrected core branch"
papafe Feb 11, 2021
f372d24
Updated core commit
papafe Feb 12, 2021
887952a
Update for CI
papafe Feb 12, 2021
253651f
Corrected core
papafe Feb 12, 2021
c9e14a1
Small corrections
papafe Feb 12, 2021
fc124a4
Added initial test case
papafe Dec 10, 2020
1f4054f
Added corrections
papafe Dec 10, 2020
5715f3c
Corrected name
papafe Dec 10, 2020
eaa3611
Correction to comments
papafe Dec 15, 2020
f1caacb
Added nullability of Mixed
papafe Dec 15, 2020
35feaea
Added special case for realm value type in weaver
papafe Dec 15, 2020
7ee6524
Correction to order of call
papafe Dec 17, 2020
66f7bef
Added first step
papafe Dec 17, 2020
508c475
Added example of test
papafe Dec 21, 2020
16515b4
Added comments
papafe Jan 18, 2021
93858a7
Added missing case in equality
papafe Jan 27, 2021
a92a620
Adde ground cases
papafe Jan 27, 2021
2f23feb
Added Tests for Nullable
papafe Jan 27, 2021
5cf6602
Added new tests
papafe Jan 29, 2021
afb6b5d
Added table_key return value
papafe Feb 12, 2021
9f3b982
Improved tests
papafe Feb 16, 2021
b06d209
Simplified weaver
papafe Feb 16, 2021
790a3ff
Small corrections
papafe Feb 16, 2021
d368d84
Removed argument fromc RealmCollectionBase
papafe Feb 16, 2021
f6839de
Improvements
papafe Feb 16, 2021
e36078d
Added back test for lists
papafe Feb 16, 2021
52514a8
Updated core
papafe Feb 16, 2021
9d780aa
Merge branch 'master' into fp/mixed-2066
papafe Feb 17, 2021
34045e0
Removed unused variable
papafe Feb 17, 2021
c9f092e
Getting tablekey from get methods in collections
papafe Feb 17, 2021
891ef6f
Small corrections
papafe Feb 19, 2021
b60eb89
Corrections to the way table_key is retrieved
papafe Feb 19, 2021
cbf5b55
Passing tablekey in primitive value
papafe Feb 19, 2021
39304da
Added list notification tests + corrected error in wrappers
papafe Feb 22, 2021
4a06c3a
Removed useless part from tests.proj
papafe Feb 22, 2021
f01d25b
Added tests for dictionary and removed testcasesource
papafe Feb 22, 2021
f342d46
Final corrections
papafe Feb 22, 2021
3c880ee
Removed comment
papafe Feb 22, 2021
0d75f21
Corrections according to PR
papafe Feb 23, 2021
0d728ec
Corrected operator
papafe Feb 23, 2021
f681ab9
Small correction according to PR
papafe Feb 23, 2021
e5a992c
Changed the way find works in results
papafe Feb 24, 2021
732716f
Added test for indexOf with list
papafe Feb 24, 2021
fcce038
Added special case for strings
papafe Feb 25, 2021
972aace
Added tests
papafe Feb 25, 2021
3cadd05
Merge branch 'master' into fp/mixed-2066
papafe Feb 25, 2021
bc88d0c
Improving tests
papafe Feb 26, 2021
5bd7d1f
Simplified code
papafe Feb 26, 2021
336ee64
Added query for realmvaluetype
papafe Feb 26, 2021
d11b3a2
Updated core to latest v11
papafe Mar 1, 2021
6b0bddc
Refactoring of test cases
papafe Mar 1, 2021
a9f83c5
Huge refactoring of collection tests
papafe Mar 3, 2021
26bf4e9
Continued refactoring
papafe Mar 3, 2021
183931a
Updated to latest core-v11
papafe Mar 15, 2021
578343e
Revert "Updated to latest core-v11"
papafe Mar 15, 2021
f9ea2eb
Correction to test object
papafe Mar 16, 2021
842b550
Small refactoring, updated core branch
papafe Mar 18, 2021
ceecde0
Improved testing for queries
papafe Mar 18, 2021
08ec7e1
Test improvements
papafe Mar 18, 2021
d4576d8
Correction to dynamic
papafe Mar 18, 2021
c0ad860
Added dynamic tests
papafe Mar 19, 2021
46d26cd
Moved dynamic tests
papafe Mar 19, 2021
6c8afde
removed unnecessary method
papafe Mar 19, 2021
fadf7b3
Small corrections
papafe Mar 19, 2021
ae03f99
Added test for dictionaries
papafe Mar 22, 2021
7d6d3a0
Small corrections
papafe Mar 23, 2021
41a3657
Refactored listOfPrimitiveTests
papafe Mar 23, 2021
191d17d
Removed collection tests
papafe Mar 23, 2021
ea904ea
Small correction pre-pr
papafe Mar 23, 2021
37ae69a
Merge branch 'master' into fp/mixed-2066
papafe Mar 23, 2021
18b5875
Equality improvements
papafe Mar 24, 2021
9c3fe88
Added set tests
papafe Mar 25, 2021
b6d9b38
Fixes
papafe Mar 26, 2021
6f2fc99
Added decimal test for set
papafe Mar 29, 2021
3c92079
wip
nirinchev Mar 25, 2021
4bfd19c
Add dictionary tests
nirinchev Mar 26, 2021
1e33a76
Small corrections
papafe Mar 30, 2021
b5a3079
Merge branch 'master' into fp/mixed-2066
papafe Mar 30, 2021
91fd11a
Additions
papafe Mar 30, 2021
03acc26
Merge branch 'ni/dictionary-e2e' into fp/mixed-2066
papafe Mar 30, 2021
6ef4d08
Added generic properties tests and Set/Dict<RealmValue> tests
papafe Mar 30, 2021
b7c0b10
Simplified tests
papafe Mar 30, 2021
46b759e
Updated changelog
papafe Mar 31, 2021
690c1ba
Corrected collection tests for queries (and updated core version)
papafe Apr 6, 2021
5930f23
Small corrections
papafe Apr 7, 2021
44f422a
Increased core version plus small fix
papafe Apr 7, 2021
15cf649
Small correction
papafe Apr 7, 2021
8279c5b
Improvements
papafe Apr 7, 2021
48d02c4
Merge branch 'master' into fp/mixed-2066
papafe Apr 7, 2021
cbde2f7
Added corrections for sync tests
papafe Apr 8, 2021
218a4c2
Correction to query in wrappers
papafe Apr 8, 2021
4ec51e0
Added ObjectType
papafe Apr 9, 2021
42638db
Merge branch 'master' into fp/mixed-2066
papafe Apr 9, 2021
37620f5
From merge
papafe Apr 9, 2021
06c5385
Changes with Nikola
papafe Apr 9, 2021
29a9aa0
Store the looked up schema in the binding context (#2328)
nirinchev Apr 12, 2021
665b985
Final cleanup
nirinchev Apr 12, 2021
fd09cc1
Merge branch 'master' into fp/mixed-2066
nirinchev Apr 12, 2021
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
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,24 @@
var obj = new MyObject();
obj.Denominations.Add("quarter", 0.25d);
```
* Add support for `RealmValue` data type. This new type can represent any valid Realm data type, including objects. Collections (lists, sets and dictionaries) of `RealmValue` are also supported, but 'RealmValue' cannot contain collections. Please note that a property of type `RealmValue` cannot be nullable, but can contain null, represented by the value `RealmValue.Null`. (PR [#2252](https://github.com/realm/realm-dotnet/pull/2252))

```csharp
public class MyObject : RealmObject
{
public RealmValue MyValue { get; set; }
}

var obj = new MyObject();
obj.MyValue = RealmValue.Null;
obj.MyValue = 1;
obj.MyValue = "abc";

if (obj.Type == RealmValueType.String)
{
var myString = obj.MyValue.AsString();
}
```
* Added support for value substitution in string based queries. This enables expressions following [this syntax](https://github.com/realm/realm-js/blob/master/docs/tutorials/query-language.md): `realm.All<T>().Filter("field1 = $0 && field2 = $1", 123, "some-string-value")`. (Issue [#1822](https://github.com/realm/realm-dotnet/issues/1822))
* Reduced the size of the native binaries by ~5%. (PR [#2239](https://github.com/realm/realm-dotnet/pull/2239))
* Added a new class - `Logger`, which allows you to override the default logger implementation (previously writing to `stdout` or `stderr`) with a custom one by setting
Expand Down
5 changes: 5 additions & 0 deletions Realm/Realm.Weaver/Extensions/PropertyDefinitionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ internal static bool IsString(this PropertyDefinition property)
return property.PropertyType.FullName == StringTypeName;
}

internal static bool IsRealmValue(this PropertyDefinition property)
{
return property.PropertyType.FullName == RealmValueTypeName;
}

internal static bool IsDescendantOf(this PropertyDefinition property, TypeReference other)
{
return property.PropertyType.Resolve().BaseType.IsSameAs(other);
Expand Down
51 changes: 30 additions & 21 deletions Realm/Realm.Weaver/RealmWeaver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ internal partial class Weaver
internal const string ObjectIdTypeName = "MongoDB.Bson.ObjectId";
internal const string DateTimeOffsetTypeName = "System.DateTimeOffset";
internal const string GuidTypeName = "System.Guid";
internal const string RealmValueTypeName = "Realms.RealmValue";
internal const string NullableCharTypeName = "System.Nullable`1<System.Char>";
internal const string NullableByteTypeName = "System.Nullable`1<System.Byte>";
internal const string NullableInt16TypeName = "System.Nullable`1<System.Int16>";
Expand All @@ -63,7 +64,7 @@ internal partial class Weaver
internal const string NullableObjectIdTypeName = "System.Nullable`1<MongoDB.Bson.ObjectId>";
internal const string NullableGuidTypeName = "System.Nullable`1<System.Guid>";

private static readonly HashSet<string> _primitiveValueTypes = new HashSet<string>
private static readonly HashSet<string> _realmValueTypes = new HashSet<string>
{
CharTypeName,
SingleTypeName,
Expand All @@ -72,8 +73,8 @@ internal partial class Weaver
DecimalTypeName,
Decimal128TypeName,
ObjectIdTypeName,
GuidTypeName,
DateTimeOffsetTypeName,
GuidTypeName,
NullableCharTypeName,
NullableSingleTypeName,
NullableDoubleTypeName,
Expand All @@ -100,7 +101,8 @@ internal partial class Weaver
$"System.Nullable`1<Realms.RealmInteger`1<{Int32TypeName}>>",
$"System.Nullable`1<Realms.RealmInteger`1<{Int64TypeName}>>",
ByteArrayTypeName,
StringTypeName
StringTypeName,
RealmValueTypeName,
};

private static readonly IEnumerable<string> _primaryKeyTypes = new[]
Expand Down Expand Up @@ -372,7 +374,7 @@ private WeavePropertyResult WeaveProperty(PropertyDefinition prop, TypeDefinitio
return WeavePropertyResult.Error($"{type.Name}.{prop.Name} has [Backlink] applied, but is not IQueryable.");
}

if (_primitiveValueTypes.Contains(prop.PropertyType.FullName))
if (_realmValueTypes.Contains(prop.PropertyType.FullName))
{
if (prop.SetMethod == null)
{
Expand All @@ -389,7 +391,7 @@ private WeavePropertyResult WeaveProperty(PropertyDefinition prop, TypeDefinitio
var genericArguments = ((GenericInstanceType)prop.PropertyType).GenericArguments;
var elementType = genericArguments.Last();
if (!elementType.Resolve().IsValidRealmObjectBaseInheritor(_references) &&
!_primitiveValueTypes.Contains(elementType.FullName))
!_realmValueTypes.Contains(elementType.FullName))
{
return WeavePropertyResult.Error($"{type.Name}.{prop.Name} is an {collectionType} but its generic type is {elementType.Name} which is not supported by Realm.");
}
Expand Down Expand Up @@ -540,13 +542,16 @@ private void ReplaceGetter(PropertyDefinition prop, string columnName, MethodRef
convertType = _references.RealmObjectBase;
}

var convertMethod = new MethodReference("op_Explicit", convertType, _references.RealmValue)
if (!prop.IsRealmValue())
{
Parameters = { new ParameterDefinition(_references.RealmValue) },
HasThis = false
};
var convertMethod = new MethodReference("op_Explicit", convertType, _references.RealmValue)
{
Parameters = { new ParameterDefinition(_references.RealmValue) },
HasThis = false
};

il.InsertBefore(start, il.Create(OpCodes.Call, convertMethod));
il.InsertBefore(start, il.Create(OpCodes.Call, convertMethod));
}

// This only happens when we have a relationship - explicitly cast.
if (convertType != prop.PropertyType)
Expand Down Expand Up @@ -718,19 +723,22 @@ private void ReplaceSetter(PropertyDefinition prop, FieldReference backingField,
il.Append(il.Create(OpCodes.Ldstr, columnName));
il.Append(il.Create(OpCodes.Ldarg_1));

var convertType = prop.PropertyType;
if (prop.ContainsRealmObject(_references) || prop.ContainsEmbeddedObject(_references))
if (!prop.IsRealmValue())
{
convertType = _references.RealmObjectBase;
}
var convertType = prop.PropertyType;
if (prop.ContainsRealmObject(_references) || prop.ContainsEmbeddedObject(_references))
{
convertType = _references.RealmObjectBase;
}

var convertMethod = new MethodReference("op_Implicit", _references.RealmValue, _references.RealmValue)
{
Parameters = { new ParameterDefinition(convertType) },
HasThis = false
};
var convertMethod = new MethodReference("op_Implicit", _references.RealmValue, _references.RealmValue)
{
Parameters = { new ParameterDefinition(convertType) },
HasThis = false
};

il.Append(il.Create(OpCodes.Call, convertMethod));
il.Append(il.Create(OpCodes.Call, convertMethod));
}

il.Append(il.Create(OpCodes.Call, setValueReference));
il.Append(il.Create(OpCodes.Ret));
Expand Down Expand Up @@ -762,7 +770,7 @@ private TypeDefinition WeaveRealmObjectHelper(TypeDefinition realmObjectType, Me
*foreach* non-list woven property in castInstance's schema
*if* castInstace.field is a RealmObject descendant
castInstance.Realm.Add(castInstance.field, update);
castInstance.Field = castInstance.field;
castInstance.Property = castInstance.Field;
*else if* property is PK
*do nothing*
*else if* property is [Required] or nullable
Expand Down Expand Up @@ -845,6 +853,7 @@ private TypeDefinition WeaveRealmObjectHelper(TypeDefinition realmObjectType, Me
property.PropertyType.IsRealmInteger(out _, out _) || // structs are not implicitly falsy/truthy so the IL is significantly different; we can optimize this case in the future
property.IsDecimal() ||
property.IsDecimal128() ||
property.IsRealmValue() ||
property.IsObjectId() ||
property.IsGuid();

Expand Down
1 change: 0 additions & 1 deletion Realm/Realm/DatabaseTypes/RealmCollectionBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ public abstract class RealmCollectionBase<T>
IThreadConfined,
IMetadataObject
{
protected static readonly RealmValueType _argumentType = typeof(T).ToPropertyType(out _).ToRealmValueType();
protected static readonly bool _isEmbedded = typeof(T).IsEmbeddedObject() || (typeof(T).IsClosedGeneric(typeof(KeyValuePair<,>), out var typeArgs) && typeArgs.Last().IsEmbeddedObject());

private readonly List<NotificationCallbackDelegate<T>> _callbacks = new List<NotificationCallbackDelegate<T>>();
Expand Down
4 changes: 2 additions & 2 deletions Realm/Realm/DatabaseTypes/RealmDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public bool Remove(KeyValuePair<string, TValue> item)

public bool TryGetValue(string key, out TValue value)
{
if (key != null && _dictionaryHandle.TryGet(key, Metadata, Realm, out var realmValue))
if (key != null && _dictionaryHandle.TryGet(key, Realm, out var realmValue))
{
value = realmValue.As<TValue>();
return true;
Expand Down Expand Up @@ -224,7 +224,7 @@ private static string ValidateKey(string key)

internal override CollectionHandleBase GetOrCreateHandle() => _dictionaryHandle;

protected override KeyValuePair<string, TValue> GetValueAtIndex(int index) => _dictionaryHandle.GetValueAtIndex<TValue>(index, Metadata, Realm);
protected override KeyValuePair<string, TValue> GetValueAtIndex(int index) => _dictionaryHandle.GetValueAtIndex<TValue>(index, Realm);

void INotifiable<DictionaryHandle.DictionaryChangeSet>.NotifyCallbacks(DictionaryHandle.DictionaryChangeSet? changes, NativeException? exception)
{
Expand Down
2 changes: 1 addition & 1 deletion Realm/Realm/DatabaseTypes/RealmList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public void Move(int sourceIndex, int targetIndex)

internal override RealmCollectionBase<T> CreateCollection(Realm realm, CollectionHandleBase handle) => new RealmList<T>(realm, (ListHandle)handle, Metadata);

protected override T GetValueAtIndex(int index) => _listHandle.GetValueAtIndex(index, Metadata, Realm).As<T>();
protected override T GetValueAtIndex(int index) => _listHandle.GetValueAtIndex(index, Realm).As<T>();

DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression expression) => new MetaRealmList(expression, this);
}
Expand Down
4 changes: 2 additions & 2 deletions Realm/Realm/DatabaseTypes/RealmSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public bool Add(T value)
{
var realmValue = Operator.Convert<T, RealmValue>(value);

if (_argumentType == RealmValueType.Object)
if (realmValue.Type == RealmValueType.Object)
{
var robj = realmValue.AsRealmObject<RealmObject>();
if (!robj.IsManaged)
Expand Down Expand Up @@ -96,7 +96,7 @@ public override bool Contains(T value)

internal override CollectionHandleBase GetOrCreateHandle() => _setHandle;

protected override T GetValueAtIndex(int index) => _setHandle.GetValueAtIndex(index, Metadata, Realm).As<T>();
protected override T GetValueAtIndex(int index) => _setHandle.GetValueAtIndex(index, Realm).As<T>();

#region Set methods

Expand Down
Loading