|
@@ -197,6 +197,7 @@ namespace InABox.Core
|
|
{
|
|
{
|
|
using var stream = new MemoryStream();
|
|
using var stream = new MemoryStream();
|
|
obj.SerializeBinary(new CoreBinaryWriter(stream, settings));
|
|
obj.SerializeBinary(new CoreBinaryWriter(stream, settings));
|
|
|
|
+
|
|
return stream.ToArray();
|
|
return stream.ToArray();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -264,7 +265,7 @@ namespace InABox.Core
|
|
public bool IncludeNullables { get; set; }
|
|
public bool IncludeNullables { get; set; }
|
|
public string Version { get; set; }
|
|
public string Version { get; set; }
|
|
|
|
|
|
- public static BinarySerializationSettings Latest => V1_1;
|
|
|
|
|
|
+ public static BinarySerializationSettings Latest => V1_0;
|
|
|
|
|
|
public static BinarySerializationSettings V1_0 = new BinarySerializationSettings("1.0")
|
|
public static BinarySerializationSettings V1_0 = new BinarySerializationSettings("1.0")
|
|
{
|
|
{
|
|
@@ -573,17 +574,46 @@ namespace InABox.Core
|
|
DatabaseSchema.Properties(type)
|
|
DatabaseSchema.Properties(type)
|
|
.Where(x => !(x is StandardProperty st) || st.Property.GetCustomAttribute<DoNotSerialize>() == null);
|
|
.Where(x => !(x is StandardProperty st) || st.Property.GetCustomAttribute<DoNotSerialize>() == null);
|
|
|
|
|
|
- private static void WriteOriginalValues<TObject>(this CoreBinaryWriter writer, TObject obj)
|
|
|
|
- where TObject : BaseObject
|
|
|
|
|
|
+ private static void GetOriginalValues(BaseObject obj, string? parent, List<Tuple<Type, string, object?>> values)
|
|
{
|
|
{
|
|
- var originalValues = new List<Tuple<Type, string, object?>>();
|
|
|
|
|
|
+ parent = parent != null ? $"{parent}." : "";
|
|
|
|
+
|
|
foreach (var (key, value) in obj.OriginalValues)
|
|
foreach (var (key, value) in obj.OriginalValues)
|
|
{
|
|
{
|
|
- if (DatabaseSchema.Property(typeof(TObject), key) is IProperty prop)
|
|
|
|
|
|
+ if (DatabaseSchema.Property(obj.GetType(), key) is IProperty prop)
|
|
{
|
|
{
|
|
- originalValues.Add(new Tuple<Type, string, object?>(prop.PropertyType, key, value));
|
|
|
|
|
|
+ values.Add(new Tuple<Type, string, object?>(prop.PropertyType, parent + key, value));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ var props = obj.GetType().GetProperties().Where(x =>
|
|
|
|
+ x.GetCustomAttribute<DoNotSerialize>() == null
|
|
|
|
+ && x.GetCustomAttribute<DoNotPersist>() == null
|
|
|
|
+ && x.GetCustomAttribute<AggregateAttribute>() == null
|
|
|
|
+ && x.GetCustomAttribute<FormulaAttribute>() == null
|
|
|
|
+ && x.GetCustomAttribute<ConditionAttribute>() == null
|
|
|
|
+ && x.CanWrite);
|
|
|
|
+ foreach(var prop in props)
|
|
|
|
+ {
|
|
|
|
+ if (prop.PropertyType.GetInterfaces().Contains(typeof(IEnclosedEntity)))
|
|
|
|
+ {
|
|
|
|
+ if (prop.GetValue(obj) is BaseObject child)
|
|
|
|
+ GetOriginalValues(child, parent + prop.Name, values);
|
|
|
|
+ }
|
|
|
|
+ else if (prop.PropertyType.GetInterfaces().Contains(typeof(IEntityLink)))
|
|
|
|
+ {
|
|
|
|
+ if (prop.GetValue(obj) is BaseObject child && child.HasOriginalValue("ID"))
|
|
|
|
+ {
|
|
|
|
+ values.Add(new Tuple<Type, string, object?>(typeof(Guid), parent + prop.Name + ".ID", child.OriginalValues["ID"]));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static void WriteOriginalValues<TObject>(this CoreBinaryWriter writer, TObject obj)
|
|
|
|
+ where TObject : BaseObject
|
|
|
|
+ {
|
|
|
|
+ var originalValues = new List<Tuple<Type, string, object?>>();
|
|
|
|
+ GetOriginalValues(obj, null, originalValues);
|
|
|
|
|
|
writer.Write(originalValues.Count);
|
|
writer.Write(originalValues.Count);
|
|
foreach (var (type, key, value) in originalValues)
|
|
foreach (var (type, key, value) in originalValues)
|
|
@@ -601,7 +631,18 @@ namespace InABox.Core
|
|
var key = reader.ReadString();
|
|
var key = reader.ReadString();
|
|
if (DatabaseSchema.Property(typeof(TObject), key) is IProperty prop)
|
|
if (DatabaseSchema.Property(typeof(TObject), key) is IProperty prop)
|
|
{
|
|
{
|
|
- obj.OriginalValues[key] = reader.ReadBinaryValue(prop.PropertyType);
|
|
|
|
|
|
+ var value = reader.ReadBinaryValue(prop.PropertyType);
|
|
|
|
+ if (prop.Parent is null)
|
|
|
|
+ {
|
|
|
|
+ obj.OriginalValues[prop.Name] = value;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if(prop.Parent.Getter()(obj) is BaseObject parent)
|
|
|
|
+ {
|
|
|
|
+ parent.OriginalValues[prop.Name.Split('.').Last()] = value;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -639,6 +680,7 @@ namespace InABox.Core
|
|
where TObject : BaseObject, new()
|
|
where TObject : BaseObject, new()
|
|
{
|
|
{
|
|
var obj = new TObject();
|
|
var obj = new TObject();
|
|
|
|
+ obj.SetObserving(false);
|
|
|
|
|
|
var nProps = reader.ReadInt32();
|
|
var nProps = reader.ReadInt32();
|
|
for(int i = 0; i < nProps; ++i)
|
|
for(int i = 0; i < nProps; ++i)
|
|
@@ -649,6 +691,8 @@ namespace InABox.Core
|
|
}
|
|
}
|
|
reader.ReadOriginalValues(obj);
|
|
reader.ReadOriginalValues(obj);
|
|
|
|
|
|
|
|
+ obj.SetObserving(true);
|
|
|
|
+
|
|
return obj;
|
|
return obj;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -661,7 +705,7 @@ namespace InABox.Core
|
|
/// </remarks>
|
|
/// </remarks>
|
|
/// <typeparam name="TObject"></typeparam>
|
|
/// <typeparam name="TObject"></typeparam>
|
|
/// <param name="writer"></param>
|
|
/// <param name="writer"></param>
|
|
- /// <param name="entity"></param>
|
|
|
|
|
|
+ /// <param name="objects"></param>
|
|
public static void WriteObjects<TObject>(this CoreBinaryWriter writer, ICollection<TObject> objects)
|
|
public static void WriteObjects<TObject>(this CoreBinaryWriter writer, ICollection<TObject> objects)
|
|
where TObject : BaseObject, new()
|
|
where TObject : BaseObject, new()
|
|
{
|
|
{
|
|
@@ -685,7 +729,7 @@ namespace InABox.Core
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// The inverse of <see cref="WriteObjects{TObject}(CoreBinaryWriter, IList{TObject})"/>.
|
|
|
|
|
|
+ /// The inverse of <see cref="WriteObjects{TObject}(CoreBinaryWriter, ICollection{TObject})"/>.
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <typeparam name="TObject"></typeparam>
|
|
/// <typeparam name="TObject"></typeparam>
|
|
/// <param name="reader"></param>
|
|
/// <param name="reader"></param>
|
|
@@ -707,6 +751,7 @@ namespace InABox.Core
|
|
for(int i = 0; i < nObjs; ++i)
|
|
for(int i = 0; i < nObjs; ++i)
|
|
{
|
|
{
|
|
var obj = new TObject();
|
|
var obj = new TObject();
|
|
|
|
+ obj.SetObserving(false);
|
|
|
|
|
|
foreach(var property in properties)
|
|
foreach(var property in properties)
|
|
{
|
|
{
|
|
@@ -714,6 +759,8 @@ namespace InABox.Core
|
|
}
|
|
}
|
|
reader.ReadOriginalValues(obj);
|
|
reader.ReadOriginalValues(obj);
|
|
|
|
|
|
|
|
+ obj.SetObserving(true);
|
|
|
|
+
|
|
objs.Add(obj);
|
|
objs.Add(obj);
|
|
}
|
|
}
|
|
return objs;
|
|
return objs;
|