Skip to content

Commit

Permalink
After rebase fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
nirinchev committed Sep 16, 2020
1 parent a9efc1c commit 75865ee
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 144 deletions.
2 changes: 1 addition & 1 deletion Realm/Realm/Handles/CollectionHandleBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public PrimitiveValue GetPrimitiveAtIndex(int index, PropertyType type)
{
var result = new PrimitiveValue
{
type = type
Type = type
};

GetPrimitiveAtIndexCore((IntPtr)index, ref result, out var nativeException);
Expand Down
4 changes: 2 additions & 2 deletions Realm/Realm/Handles/ObjectHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ protected override void Unbind()

public PrimitiveValue GetPrimitive(ColumnKey columnKey, PropertyType type)
{
var result = new PrimitiveValue { type = type };
var result = new PrimitiveValue { Type = type };

NativeMethods.get_primitive(this, columnKey, ref result, out var nativeException);
nativeException.ThrowIfNecessary();
Expand Down Expand Up @@ -263,7 +263,7 @@ public void AddInt64(ColumnKey columnKey, long value)

public void SetPrimitiveUnique(ColumnKey columnKey, PrimitiveValue value)
{
if (!GetPrimitive(columnKey, value.type).Equals(value))
if (!GetPrimitive(columnKey, value.Type).Equals(value))
{
throw new InvalidOperationException("Once set, primary key properties may not be modified.");
}
Expand Down
4 changes: 2 additions & 2 deletions Realm/Realm/Linq/RealmResultsVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -817,11 +817,11 @@ private static void AddQueryForConvertibleTypes(ColumnKey columnKey, object valu
decimalValue = (Decimal128)Convert.ChangeType(value, typeof(Decimal128));
}

action(columnKey, PrimitiveValue.Create(decimalValue, PropertyType.Decimal));
action(columnKey, PrimitiveValue.Decimal(decimalValue));
}
else if (columnType == typeof(decimal))
{
action(columnKey, PrimitiveValue.Create((decimal)Convert.ChangeType(value, typeof(decimal)), PropertyType.Decimal));
action(columnKey, PrimitiveValue.Decimal((decimal)Convert.ChangeType(value, typeof(decimal))));
}
else
{
Expand Down
240 changes: 104 additions & 136 deletions Realm/Realm/Native/PrimitiveValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
////////////////////////////////////////////////////////////////////////////

using System;
using System.Linq;
using System.Runtime.InteropServices;
using MongoDB.Bson;
using Realms.Helpers;
Expand All @@ -30,232 +29,201 @@ internal struct PrimitiveValue
{
[FieldOffset(0)]
[MarshalAs(UnmanagedType.U1)]
internal PropertyType type;
public PropertyType Type;

[FieldOffset(1)]
[MarshalAs(UnmanagedType.I1)]
internal bool has_value;
private bool has_value;

[FieldOffset(8)]
[MarshalAs(UnmanagedType.I1)]
internal bool bool_value;
private bool bool_value;

[FieldOffset(8)]
internal long int_value;
private long int_value;

[FieldOffset(8)]
internal float float_value;
private float float_value;

[FieldOffset(8)]
internal double double_value;
private double double_value;

[FieldOffset(8)]
internal ulong low_bits;
private ulong low_bits;

[FieldOffset(16)]
internal ulong high_bits;
private ulong high_bits;

[FieldOffset(16)]
internal uint object_id_remainder;
private uint object_id_remainder;

public static PrimitiveValue Bool(bool value)
{
return new PrimitiveValue
{
type = PropertyType.Bool,
Type = PropertyType.Bool,
has_value = true,
bool_value = value
};
}

public static PrimitiveValue NullableBool(bool? value) => new PrimitiveValue
{
type = PropertyType.NullableBool,
Type = PropertyType.NullableBool,
has_value = value.HasValue,
bool_value = value.GetValueOrDefault()
};

public static PrimitiveValue Int(long value) => new PrimitiveValue
{
type = PropertyType.Int,
Type = PropertyType.Int,
has_value = true,
int_value = value
};

public static PrimitiveValue NullableInt(long? value) => new PrimitiveValue
{
type = PropertyType.NullableInt,
Type = PropertyType.NullableInt,
has_value = value.HasValue,
int_value = value.GetValueOrDefault()
};

public static PrimitiveValue Float(float value) => new PrimitiveValue
{
type = PropertyType.Float,
Type = PropertyType.Float,
has_value = true,
float_value = value
};

public static PrimitiveValue NullableFloat(float? value) => new PrimitiveValue
{
type = PropertyType.NullableFloat,
Type = PropertyType.NullableFloat,
has_value = value.HasValue,
float_value = value.GetValueOrDefault()
};

public static PrimitiveValue Double(double value) => new PrimitiveValue
{
type = PropertyType.Double,
Type = PropertyType.Double,
has_value = true,
double_value = value
};

public static PrimitiveValue NullableDouble(double? value) => new PrimitiveValue
{
type = PropertyType.NullableDouble,
Type = PropertyType.NullableDouble,
has_value = value.HasValue,
double_value = value.GetValueOrDefault()
};

public static PrimitiveValue Date(DateTimeOffset value) => new PrimitiveValue
{
type = PropertyType.Date,
Type = PropertyType.Date,
has_value = true,
int_value = value.ToUniversalTime().Ticks
};

public static PrimitiveValue NullableDate(DateTimeOffset? value) => new PrimitiveValue
{
type = PropertyType.NullableDate,
Type = PropertyType.NullableDate,
has_value = value.HasValue,
int_value = value.GetValueOrDefault().ToUniversalTime().Ticks
};

public static PrimitiveValue Decimal(Decimal128 value) => new PrimitiveValue
{
Type = PropertyType.Decimal,
has_value = true,
high_bits = value.GetIEEEHighBits(),
low_bits = value.GetIEEELowBits()
};

public static PrimitiveValue NullableDecimal(Decimal128? value) => new PrimitiveValue
{
Type = PropertyType.NullableDecimal,
has_value = value.HasValue,
high_bits = value.GetValueOrDefault().GetIEEEHighBits(),
low_bits = value.GetValueOrDefault().GetIEEELowBits()
};

public static PrimitiveValue ObjectId(ObjectId value) => throw new NotImplementedException();

public static PrimitiveValue NullableObjectId(ObjectId? value) => throw new NotImplementedException();

public static PrimitiveValue Create<T>(T value, PropertyType type)
{
var result = new PrimitiveValue
return type switch
{
type = type,
has_value = true
PropertyType.Bool => Bool(Operator.Convert<T, bool>(value)),
PropertyType.NullableBool => NullableBool(Operator.Convert<T, bool?>(value)),
PropertyType.Int => Int(Operator.Convert<T, long>(value)),
PropertyType.NullableInt => NullableInt(Operator.Convert<T, long?>(value)),
PropertyType.Float => Float(Operator.Convert<T, float>(value)),
PropertyType.NullableFloat => NullableFloat(Operator.Convert<T, float?>(value)),
PropertyType.Double => Double(Operator.Convert<T, double>(value)),
PropertyType.NullableDouble => NullableDouble(Operator.Convert<T, double?>(value)),
PropertyType.Date => Date(Operator.Convert<T, DateTimeOffset>(value)),
PropertyType.NullableDate => NullableDate(Operator.Convert<T, DateTimeOffset?>(value)),
PropertyType.Decimal => Decimal(Operator.Convert<T, Decimal128>(value)),
PropertyType.NullableDecimal => NullableDecimal(Operator.Convert<T, Decimal128?>(value)),
PropertyType.ObjectId => ObjectId(Operator.Convert<T, ObjectId>(value)),
PropertyType.NullableObjectId => NullableObjectId(Operator.Convert<T, ObjectId?>(value)),
_ => throw new NotSupportedException($"PrimitiveType {type} is not supported."),
};

switch (type)
{
case PropertyType.Bool:
result.bool_value = Operator.Convert<T, bool>(value);
break;
case PropertyType.NullableBool:
var boolValue = Operator.Convert<T, bool?>(value);
result.has_value = boolValue.HasValue;
result.bool_value = boolValue.GetValueOrDefault();
break;
case PropertyType.Int:
result.int_value = Operator.Convert<T, long>(value);
break;
case PropertyType.NullableInt:
var longValue = Operator.Convert<T, long?>(value);
result.has_value = longValue.HasValue;
result.int_value = longValue.GetValueOrDefault();
break;
case PropertyType.Float:
result.float_value = Operator.Convert<T, float>(value);
break;
case PropertyType.NullableFloat:
var floatValue = Operator.Convert<T, float?>(value);
result.has_value = floatValue.HasValue;
result.float_value = floatValue.GetValueOrDefault();
break;
case PropertyType.Double:
result.double_value = Operator.Convert<T, double>(value);
break;
case PropertyType.NullableDouble:
var doubleValue = Operator.Convert<T, double?>(value);
result.has_value = doubleValue.HasValue;
result.double_value = doubleValue.GetValueOrDefault();
break;
case PropertyType.Date:
result.int_value = Operator.Convert<T, DateTimeOffset>(value).ToUniversalTime().Ticks;
break;
case PropertyType.NullableDate:
var dateValue = Operator.Convert<T, DateTimeOffset?>(value);
result.has_value = dateValue.HasValue;
result.int_value = dateValue.GetValueOrDefault().ToUniversalTime().Ticks;
break;
case PropertyType.Decimal:
var decimalValue = Operator.Convert<T, Decimal128>(value);
result.high_bits = decimalValue.GetIEEEHighBits();
result.low_bits = decimalValue.GetIEEELowBits();
break;
case PropertyType.NullableDecimal:
var nullableDecimalValue = Operator.Convert<T, Decimal128?>(value);
result.has_value = nullableDecimalValue.HasValue;

var actualValue = nullableDecimalValue.GetValueOrDefault();
result.high_bits = actualValue.GetIEEEHighBits();
result.low_bits = actualValue.GetIEEELowBits();
break;
case PropertyType.ObjectId:
var objectIdBytes = Operator.Convert<T, ObjectId>(value).ToByteArray();
result.low_bits = BitConverter.ToUInt64(objectIdBytes, 0);
result.object_id_remainder = BitConverter.ToUInt32(objectIdBytes, 8);
break;
case PropertyType.NullableObjectId:
var objectId = Operator.Convert<T, ObjectId?>(value);
result.has_value = objectId.HasValue;

var actualObjectIdBytes = objectId.GetValueOrDefault().ToByteArray();
result.low_bits = BitConverter.ToUInt64(actualObjectIdBytes, 0);
result.object_id_remainder = BitConverter.ToUInt32(actualObjectIdBytes, 8);
break;
default:
throw new NotSupportedException($"PrimitiveType {type} is not supported.");
}

return result;
}

public bool ToBool() => bool_value;

public bool? ToNullableBool() => has_value ? bool_value : (bool?)null;

public long ToInt() => int_value;

public long? ToNullableInt() => has_value ? int_value : (long?)null;

public T ToIntegral<T>() => Operator.Convert<long, T>(int_value);

public T ToNullableIntegral<T>() => Operator.Convert<long?, T>(has_value ? int_value : (long?)null);

public float ToFloat() => float_value;

public float? ToNullableFloat() => has_value ? float_value : (float?)null;

public double ToDouble() => double_value;

public double? ToNullableDouble() => has_value ? double_value : (double?)null;

public DateTimeOffset ToDate() => new DateTimeOffset(int_value, TimeSpan.Zero);

public DateTimeOffset? ToNullableDate() => has_value ? new DateTimeOffset(int_value, TimeSpan.Zero) : (DateTimeOffset?)null;

public Decimal128 ToDecimal() => Decimal128.FromIEEEBits(high_bits, low_bits);

public Decimal128? ToNullableDecimal() => has_value ? Decimal128.FromIEEEBits(high_bits, low_bits) : (Decimal128?)null;

public ObjectId ToObjectId() => throw new NotImplementedException();

public ObjectId? ToNullableObjectId() => has_value ? throw new NotImplementedException() : (ObjectId?)null;

public T Get<T>()
{
switch (type)
return Type switch
{
case PropertyType.Bool:
return Operator.Convert<bool, T>(bool_value);
case PropertyType.NullableBool:
return Operator.Convert<bool?, T>(has_value ? bool_value : (bool?)null);
case PropertyType.Int:
return Operator.Convert<long, T>(int_value);
case PropertyType.NullableInt:
return Operator.Convert<long?, T>(has_value ? int_value : (long?)null);
case PropertyType.Float:
return Operator.Convert<float, T>(float_value);
case PropertyType.NullableFloat:
return Operator.Convert<float?, T>(has_value ? float_value : (float?)null);
case PropertyType.Double:
return Operator.Convert<double, T>(double_value);
case PropertyType.NullableDouble:
return Operator.Convert<double?, T>(has_value ? double_value : (double?)null);
case PropertyType.Date:
return Operator.Convert<DateTimeOffset, T>(new DateTimeOffset(int_value, TimeSpan.Zero));
case PropertyType.NullableDate:
return Operator.Convert<DateTimeOffset?, T>(has_value ? new DateTimeOffset(int_value, TimeSpan.Zero) : (DateTimeOffset?)null);
case PropertyType.Decimal:
return Operator.Convert<Decimal128, T>(Decimal128.FromIEEEBits(high_bits, low_bits));
case PropertyType.NullableDecimal:
return Operator.Convert<Decimal128?, T>(has_value ? Decimal128.FromIEEEBits(high_bits, low_bits) : (Decimal128?)null);
case PropertyType.ObjectId:
var bytes = BitConverter.GetBytes(low_bits).Concat(BitConverter.GetBytes(object_id_remainder));
return Operator.Convert<ObjectId, T>(new ObjectId(bytes.ToArray()));
case PropertyType.NullableObjectId:
if (has_value)
{
return Operator.Convert<ObjectId?, T>(null);
}

var nullableBytes = BitConverter.GetBytes(low_bits).Concat(BitConverter.GetBytes(object_id_remainder));
return Operator.Convert<ObjectId, T>(new ObjectId(nullableBytes.ToArray()));
default:
throw new NotSupportedException($"PrimitiveType {type} is not supported.");
}
PropertyType.Bool => Operator.Convert<bool, T>(ToBool()),
PropertyType.NullableBool => Operator.Convert<bool?, T>(ToNullableBool()),
PropertyType.Int => ToIntegral<T>(),
PropertyType.NullableInt => ToNullableIntegral<T>(),
PropertyType.Float => Operator.Convert<float, T>(ToFloat()),
PropertyType.NullableFloat => Operator.Convert<float?, T>(ToNullableFloat()),
PropertyType.Double => Operator.Convert<double, T>(ToDouble()),
PropertyType.NullableDouble => Operator.Convert<double?, T>(ToNullableDouble()),
PropertyType.Date => Operator.Convert<DateTimeOffset, T>(ToDate()),
PropertyType.NullableDate => Operator.Convert<DateTimeOffset?, T>(ToNullableDate()),
PropertyType.Decimal => Operator.Convert<Decimal128, T>(ToDecimal()),
PropertyType.NullableDecimal => Operator.Convert<Decimal128?, T>(ToNullableDecimal()),
PropertyType.ObjectId => Operator.Convert<ObjectId, T>(ToObjectId()),
PropertyType.NullableObjectId => Operator.Convert<ObjectId?, T>(ToNullableObjectId()),
_ => throw new NotSupportedException($"PrimitiveType {Type} is not supported."),
};
}
}
}
1 change: 1 addition & 0 deletions Realm/Realm/Realm.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<RootNamespace>Realms</RootNamespace>
<StyleCopTreatErrorsAsWarnings>true</StyleCopTreatErrorsAsWarnings>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>8.0</LangVersion>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Title>Realm</Title>
<ReleaseNotes>https://realm.io/docs/dotnet/latest/api/CHANGELOG.html</ReleaseNotes>
Expand Down
Loading

0 comments on commit 75865ee

Please sign in to comment.