WIP
parent
26276074cc
commit
aa65fc9f4e
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
namespace ln.types
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
public static bool AreEqual<T>(this T[] me,T[] you)
|
||||
{
|
||||
if (me.Length != you.Length)
|
||||
return false;
|
||||
|
||||
for (int n = 0; n < me.Length; n++)
|
||||
if (!me[n].Equals(you[n]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,6 +57,9 @@
|
|||
<Compile Include="odb\PreparedObject.cs" />
|
||||
<Compile Include="odb\ODBObjectWriter.cs" />
|
||||
<Compile Include="odb\ODBObjectReader.cs" />
|
||||
<Compile Include="odb\ODBFileStorage.cs" />
|
||||
<Compile Include="odb\Storage.cs" />
|
||||
<Compile Include="Extensions.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="sync\" />
|
||||
|
|
209
odb/ODB.cs
209
odb/ODB.cs
|
@ -16,7 +16,7 @@ using Castle.Components.DictionaryAdapter;
|
|||
using System.Linq;
|
||||
namespace ln.types.odb
|
||||
{
|
||||
public class ODB<T> : ODB
|
||||
public class ODB<T> : ODB where T: IPersistent
|
||||
{
|
||||
public T Root
|
||||
{
|
||||
|
@ -29,40 +29,35 @@ namespace ln.types.odb
|
|||
}
|
||||
}
|
||||
|
||||
public partial class ODB
|
||||
public class ODB
|
||||
{
|
||||
public object RootObject { get; protected set; }
|
||||
|
||||
public String BasePath { get; set; }
|
||||
|
||||
private ProxyGenerator proxyGenerator = new ProxyGenerator();
|
||||
private Dictionary<Guid, WeakReference<IPersistent>> persistentObjects = new Dictionary<Guid, WeakReference<IPersistent>>();
|
||||
private Dictionary<Guid, IPersistent> persistentProxies = new Dictionary<Guid, IPersistent>();
|
||||
public IPersistent RootObject { get; protected set; }
|
||||
|
||||
|
||||
private Type RootType;
|
||||
private Storage Storage { get; set; }
|
||||
|
||||
private Dictionary<Guid, PreparedObject> objectCache = new Dictionary<Guid, PreparedObject>();
|
||||
|
||||
public ODB(string basePath)
|
||||
{
|
||||
BasePath = Path.GetFullPath(basePath);
|
||||
if (!Directory.Exists(BasePath))
|
||||
{
|
||||
Directory.CreateDirectory(BasePath);
|
||||
}
|
||||
Storage = new ODBFileStorage(basePath);
|
||||
}
|
||||
|
||||
public ODB(String basePath, Type rootType)
|
||||
: this(basePath)
|
||||
{
|
||||
RootType = rootType;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
public ODB(String basePath,object rootObject)
|
||||
public ODB(String basePath,IPersistent rootObject)
|
||||
: this(basePath)
|
||||
{
|
||||
RootType = rootObject.GetType();
|
||||
RootObject = rootObject;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
|
@ -73,84 +68,59 @@ namespace ln.types.odb
|
|||
string rootHint = Path.Combine(BasePath, "root.hint");
|
||||
if (File.Exists(rootHint))
|
||||
{
|
||||
using (ObjectReader objectReader = new ObjectReader(rootHint))
|
||||
{
|
||||
Guid persistenceID = objectReader.Read<Guid>();
|
||||
RootObject = GetPersistent(persistenceID);
|
||||
}
|
||||
string rootID = File.ReadAllText(rootHint);
|
||||
Guid persistenceID = Guid.Parse(rootID);
|
||||
RootObject = LoadPersistent(persistenceID);
|
||||
}
|
||||
else
|
||||
{
|
||||
RootObject = Activator.CreateInstance(RootType);
|
||||
RootObject = (IPersistent)Activator.CreateInstance(RootType);
|
||||
string rootID = RootObject.GetPersistenceID().ToString();
|
||||
SavePersistent(RootObject);
|
||||
File.WriteAllText(rootHint, rootID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(Guid persistenceID)
|
||||
{
|
||||
string fn = Path.Combine(GetPersistentPath(persistenceID), String.Format("{0}.0",persistenceID));
|
||||
return File.Exists(fn);
|
||||
}
|
||||
|
||||
IPersistent LoadPersistent(Guid guid)
|
||||
{
|
||||
IPersistent o = GetCachedPersistent(guid);
|
||||
if (o == null)
|
||||
{
|
||||
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return o;
|
||||
return Storage.Contains(persistenceID) || objectCache.ContainsKey(persistenceID);
|
||||
}
|
||||
|
||||
public void SavePersistent(IPersistent o) => SavePersistent(o, true);
|
||||
public void SavePersistent(IPersistent o,bool recurse)
|
||||
{
|
||||
SaveCollector saveCollector = new SaveCollector(this);
|
||||
saveCollector.AddPersistent(o, recurse);
|
||||
|
||||
foreach (Guid persistenceID in saveCollector.GetCollectedPersistenceIDs())
|
||||
lock (this)
|
||||
{
|
||||
SaveBytes(persistenceID, saveCollector.GetPersistentBytes(persistenceID));
|
||||
SaveCollector saveCollector = new SaveCollector(this);
|
||||
saveCollector.Add(o);
|
||||
|
||||
foreach (PreparedObject preparedObject in saveCollector.PreparedToSave)
|
||||
{
|
||||
Storage.Store(preparedObject);
|
||||
objectCache[preparedObject.PersistenceID] = preparedObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* File I/O */
|
||||
private string GetPersistentPath(Guid persistenceID)
|
||||
public T LoadPersistent<T>(Guid persistenceID) => (T)LoadPersistent(persistenceID);
|
||||
public IPersistent LoadPersistent(Guid persistenceID)
|
||||
{
|
||||
byte[] idBytes = persistenceID.ToByteArray();
|
||||
return Path.Combine(BasePath, BitConverter.ToString(idBytes, 0, 4));
|
||||
}
|
||||
if (!Contains(persistenceID))
|
||||
throw new KeyNotFoundException();
|
||||
|
||||
private void SaveBytes(Guid persistenceID,byte[] bytes)
|
||||
{
|
||||
String p = GetPersistentPath(persistenceID);
|
||||
String fnbase = Path.Combine(p, persistenceID.ToString());
|
||||
|
||||
if (!Directory.Exists(p))
|
||||
Directory.CreateDirectory(p);
|
||||
|
||||
String fnn = String.Format("{0}.new", fnbase);
|
||||
|
||||
using (FileStream fs = new FileStream(fnn, FileMode.CreateNew))
|
||||
PreparedObject preparedObject = GetCachedPersistent(persistenceID);
|
||||
if (preparedObject == null)
|
||||
{
|
||||
fs.Write(bytes,0,bytes.Length);
|
||||
fs.Close();
|
||||
preparedObject = new PreparedObject(this, typeof(IPersistent), persistenceID);
|
||||
if (!Storage.Load(preparedObject))
|
||||
throw new IOException(String.Format("unable to load IPersistent({0})",persistenceID));
|
||||
|
||||
preparedObject.CreateInstance();
|
||||
objectCache.Add(persistenceID,preparedObject);
|
||||
}
|
||||
|
||||
for (int n=5;n>0;n--)
|
||||
{
|
||||
string fn1 = String.Format("{0}.{1}",fnbase,n-1);
|
||||
string fn2 = String.Format("{0}.{1}", fnbase, n);
|
||||
|
||||
if (File.Exists(fn1))
|
||||
File.Move(fn1, fn2);
|
||||
}
|
||||
|
||||
string fn = String.Format("{0}.{1}", fnbase, 0);
|
||||
File.Move(fnn, fn);
|
||||
return preparedObject.Instance;
|
||||
}
|
||||
|
||||
|
||||
|
@ -159,119 +129,50 @@ namespace ln.types.odb
|
|||
|
||||
|
||||
|
||||
private IPersistent GetCachedPersistent(Guid persistenceID)
|
||||
private PreparedObject GetCachedPersistent(Guid persistenceID)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (persistentObjects.ContainsKey(persistenceID))
|
||||
if (objectCache.ContainsKey(persistenceID))
|
||||
{
|
||||
WeakReference<IPersistent> weak = persistentObjects[persistenceID];
|
||||
IPersistent persistent = null;
|
||||
|
||||
if (weak.TryGetTarget(out persistent))
|
||||
{
|
||||
return persistent;
|
||||
}
|
||||
else
|
||||
{
|
||||
persistentObjects.Remove(persistenceID);
|
||||
}
|
||||
return objectCache[persistenceID];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* GetPersistent(..): Return Instance of an IPersistent (may be a proxy)
|
||||
*
|
||||
**/
|
||||
public IPersistent GetPersistent(Guid persistenceID)
|
||||
{
|
||||
if (Guid.Empty.Equals(persistenceID))
|
||||
return null;
|
||||
|
||||
if (persistentObjects.ContainsKey(persistenceID))
|
||||
{
|
||||
IPersistent o = GetCachedPersistent(persistenceID);
|
||||
if (o == null)
|
||||
{
|
||||
o = LoadPersistent(persistenceID);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
class SaveCollector
|
||||
{
|
||||
public ODB ODB { get; }
|
||||
|
||||
public Guid[] GetCollectedPersistenceIDs()
|
||||
{
|
||||
return persistentBytes.Keys.ToArray();
|
||||
}
|
||||
public IEnumerable<PreparedObject> PreparedToSave => preparedObjects.Values;
|
||||
|
||||
public byte[] GetPersistentBytes(Guid persistenceID)
|
||||
{
|
||||
return persistentBytes[persistenceID];
|
||||
}
|
||||
|
||||
private Dictionary<Guid, byte[]> persistentBytes = new Dictionary<Guid, byte[]>();
|
||||
private Dictionary<Guid, PreparedObject> preparedObjects = new Dictionary<Guid, PreparedObject>();
|
||||
|
||||
public SaveCollector(ODB odb)
|
||||
{
|
||||
ODB = odb;
|
||||
}
|
||||
|
||||
public void AddPersistent(IPersistent persistent,bool recurse)
|
||||
public void Add(IPersistent persistent)
|
||||
{
|
||||
MemoryStream objectStream = new MemoryStream();
|
||||
ODBObjectWriter objectWriter = new ODBObjectWriter(ODB, objectStream);
|
||||
objectWriter.Write(persistent);
|
||||
PreparedObject preparedObject = new PreparedObject(ODB,persistent);
|
||||
PreparedObject cachedObject = ODB.GetCachedPersistent(preparedObject.PersistenceID);
|
||||
|
||||
persistentBytes.Add(persistent.GetPersistenceID(), objectStream.ToArray());
|
||||
|
||||
if (recurse)
|
||||
if (!preparedObject.InstanceEquals(cachedObject) && !preparedObjects.ContainsKey(preparedObject.PersistenceID))
|
||||
{
|
||||
foreach (IPersistent referencedPersistent in objectWriter.ReferencedPersistents)
|
||||
preparedObjects.Add(preparedObject.PersistenceID, preparedObject);
|
||||
|
||||
foreach (IPersistent referencedPersistent in preparedObject.ReferencedPersistents)
|
||||
{
|
||||
AddPersistent(referencedPersistent,recurse);
|
||||
Add(referencedPersistent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (IPersistent referencedPersistent in objectWriter.ReferencedPersistents)
|
||||
{
|
||||
if (!ODB.Contains(referencedPersistent.GetPersistenceID()))
|
||||
{
|
||||
AddPersistent(referencedPersistent, recurse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class LazyInterceptor : IInterceptor
|
||||
{
|
||||
ODB odb;
|
||||
WeakReference<IPersistent> target = null;
|
||||
|
||||
public LazyInterceptor(ODB odb, Guid persistentID)
|
||||
{
|
||||
this.odb = odb;
|
||||
}
|
||||
|
||||
public void Intercept(IInvocation invocation)
|
||||
{
|
||||
object t = target;
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
// /**
|
||||
// * File: ODB.cs
|
||||
// * Author: haraldwolff
|
||||
// *
|
||||
// * This file and it's content is copyrighted by the Author and / or copyright holder.
|
||||
// * Any use wihtout proper permission is illegal and may lead to legal actions.
|
||||
// *
|
||||
// *
|
||||
// **/
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using Castle.DynamicProxy;
|
||||
using ln.types.serialize;
|
||||
using Castle.Components.DictionaryAdapter;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
namespace ln.types.odb
|
||||
{
|
||||
public class ODBFileStorage : Storage
|
||||
{
|
||||
public String BasePath { get; set; }
|
||||
public int StorageVersion { get; } = 0x01;
|
||||
|
||||
public ODBFileStorage(string basePath)
|
||||
{
|
||||
BasePath = Path.GetFullPath(basePath);
|
||||
if (!Directory.Exists(BasePath))
|
||||
{
|
||||
Directory.CreateDirectory(BasePath);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetPersistentPath(Guid persistenceID)
|
||||
{
|
||||
byte[] idBytes = persistenceID.ToByteArray();
|
||||
return Path.Combine(BasePath, BitConverter.ToString(idBytes, 0, 4));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override bool Contains(Guid persistenceID)
|
||||
{
|
||||
string fn = Path.Combine(GetPersistentPath(persistenceID), String.Format("{0}.0", persistenceID));
|
||||
return File.Exists(fn);
|
||||
}
|
||||
|
||||
public override bool Store(PreparedObject preparedObject)
|
||||
{
|
||||
string targetPath = GetPersistentPath(preparedObject.PersistenceID);
|
||||
String fnbase = Path.Combine(targetPath, preparedObject.PersistenceID.ToString());
|
||||
|
||||
if (!Directory.Exists(targetPath))
|
||||
Directory.CreateDirectory(targetPath);
|
||||
|
||||
String fnn = String.Format("{0}.new", fnbase);
|
||||
|
||||
using (FileStream fs = new FileStream(fnn, FileMode.CreateNew))
|
||||
{
|
||||
ToStream(preparedObject, fs);
|
||||
fs.Close();
|
||||
}
|
||||
|
||||
for (int n = 5; n > 0; n--)
|
||||
{
|
||||
string fn1 = String.Format("{0}.{1}", fnbase, n - 1);
|
||||
string fn2 = String.Format("{0}.{1}", fnbase, n);
|
||||
|
||||
if (File.Exists(fn1))
|
||||
File.Move(fn1, fn2);
|
||||
}
|
||||
|
||||
string fn = String.Format("{0}.{1}", fnbase, 0);
|
||||
File.Move(fnn, fn);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override bool Load(PreparedObject preparedObject)
|
||||
{
|
||||
string targetPath = GetPersistentPath(preparedObject.PersistenceID);
|
||||
String fnbase = Path.Combine(targetPath, preparedObject.PersistenceID.ToString());
|
||||
string fn = String.Format("{0}.0", fnbase);
|
||||
|
||||
using (FileStream fs = new FileStream(fn, FileMode.Open))
|
||||
{
|
||||
FromStream(fs, preparedObject);
|
||||
fs.Close();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ToStream(PreparedObject preparedObject,Stream stream)
|
||||
{
|
||||
using (BinaryWriter writer = new BinaryWriter(stream))
|
||||
{
|
||||
writer.Write(StorageVersion);
|
||||
writer.Write(DateTimeOffset.Now.ToUnixTimeMilliseconds());
|
||||
writer.Write(preparedObject.PreparedType.Assembly.FullName);
|
||||
writer.Write(preparedObject.PreparedType.FullName);
|
||||
|
||||
string[] fieldNames = preparedObject.StoredFieldNames;
|
||||
|
||||
writer.Write(fieldNames.Length);
|
||||
foreach (String fieldName in fieldNames)
|
||||
{
|
||||
byte[] fieldBytes = preparedObject.GetFieldBytes(fieldName);
|
||||
writer.Write(fieldName);
|
||||
writer.Write(fieldBytes.Length);
|
||||
writer.Write(fieldBytes);
|
||||
}
|
||||
|
||||
writer.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void FromStream(Stream stream,PreparedObject preparedObject)
|
||||
{
|
||||
using (BinaryReader reader = new BinaryReader(stream))
|
||||
{
|
||||
if (reader.ReadInt32() != StorageVersion)
|
||||
throw new FormatException("Unsupported Storage Version");
|
||||
|
||||
DateTime timestamp = DateTimeOffset.FromUnixTimeMilliseconds(reader.ReadInt64()).DateTime;
|
||||
|
||||
string assemblyName = reader.ReadString();
|
||||
string typeName = reader.ReadString();
|
||||
|
||||
Assembly assembly = Assembly.Load(assemblyName);
|
||||
Type targetType = assembly.GetType(typeName);
|
||||
|
||||
preparedObject.ReConfigure(targetType,timestamp);
|
||||
|
||||
int nStoredFields = reader.ReadInt32();
|
||||
|
||||
for (int n = 0; n < nStoredFields; n++)
|
||||
{
|
||||
string fieldName = reader.ReadString();
|
||||
int nBytes = reader.ReadInt32();
|
||||
byte[] fieldBytes = reader.ReadBytes(nBytes);
|
||||
preparedObject.SetFieldBytes(fieldName, fieldBytes);
|
||||
}
|
||||
|
||||
reader.Close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -27,7 +27,7 @@ namespace ln.types.odb
|
|||
if (re is Guid)
|
||||
{
|
||||
Guid persistenceID = (Guid)re;
|
||||
IPersistent persistent = ODB.GetPersistent(persistenceID);
|
||||
IPersistent persistent = ODB.LoadPersistent(persistenceID);
|
||||
return persistent;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace ln.types.odb
|
|||
get {
|
||||
Guid persistentID = index[n];
|
||||
if (!persistentInstances.ContainsKey(persistentID))
|
||||
persistentInstances[persistentID] = (T)ODB.GetPersistent(persistentID);
|
||||
persistentInstances[persistentID] = (T)ODB.LoadPersistent(persistentID);
|
||||
|
||||
return persistentInstances[persistentID];
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ using System.Collections.Generic;
|
|||
using System.CodeDom;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
namespace ln.types.odb
|
||||
{
|
||||
public class PreparedObject
|
||||
|
@ -24,7 +25,13 @@ namespace ln.types.odb
|
|||
public IPersistent Instance { get; set; }
|
||||
public Guid PersistenceID { get; private set; }
|
||||
|
||||
List<Guid> referencedPersistents = new List<Guid>();
|
||||
public string[] StoredFieldNames => fieldStore.Keys.ToArray();
|
||||
|
||||
public IEnumerable<Guid> ReferencedPersistentIDs => referencedPersistentIDs;
|
||||
public IEnumerable<IPersistent> ReferencedPersistents => referencedPersistents;
|
||||
|
||||
List<Guid> referencedPersistentIDs = new List<Guid>();
|
||||
HashSet<IPersistent> referencedPersistents = new HashSet<IPersistent>();
|
||||
Dictionary<string, byte[]> fieldStore = new Dictionary<string, byte[]>();
|
||||
|
||||
public PreparedObject(ODB odb,Type preparedType,Guid persistenceID)
|
||||
|
@ -46,49 +53,77 @@ namespace ln.types.odb
|
|||
SyncFromInstance();
|
||||
}
|
||||
|
||||
private IEnumerable<FieldInfo> GetAllFields(Type type)
|
||||
{
|
||||
if (type == typeof(object))
|
||||
{
|
||||
return new FieldInfo[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetAllFields(type.BaseType).Concat(type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly));
|
||||
}
|
||||
}
|
||||
|
||||
private void SyncFromInstance()
|
||||
{
|
||||
referencedPersistents.Clear();
|
||||
referencedPersistentIDs.Clear();
|
||||
FieldInfo[] fields = GetAllFields(PreparedType).ToArray();
|
||||
|
||||
foreach (FieldInfo fieldInfo in PreparedType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
||||
foreach (FieldInfo fieldInfo in fields)
|
||||
{
|
||||
object value = fieldInfo.GetValue(Instance);
|
||||
if (value == null)
|
||||
if (!fieldInfo.IsStatic)
|
||||
{
|
||||
fieldStore[fieldInfo.Name] = new byte[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
MemoryStream objectStream = new MemoryStream();
|
||||
ODBObjectWriter objectWriter = new ODBObjectWriter(objectStream);
|
||||
object value = fieldInfo.GetValue(Instance);
|
||||
if (value == null)
|
||||
{
|
||||
fieldStore[fieldInfo.Name] = new byte[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
MemoryStream objectStream = new MemoryStream();
|
||||
ODBObjectWriter objectWriter = new ODBObjectWriter(objectStream);
|
||||
|
||||
objectWriter.Write(value);
|
||||
objectWriter.Write(value);
|
||||
|
||||
fieldStore[fieldInfo.Name] = objectStream.ToArray();
|
||||
referencedPersistents.AddRange(objectWriter.ReferencedPersistentIDs);
|
||||
fieldStore[fieldInfo.Name] = objectStream.ToArray();
|
||||
referencedPersistentIDs.AddRange(objectWriter.ReferencedPersistentIDs);
|
||||
foreach (IPersistent persistent in objectWriter.ReferencedPersistents)
|
||||
referencedPersistents.Add(persistent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void SyncToInstance()
|
||||
{
|
||||
foreach (FieldInfo fieldInfo in PreparedType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
||||
foreach (FieldInfo fieldInfo in GetAllFields(PreparedType))
|
||||
{
|
||||
byte[] bytes = fieldStore[fieldInfo.Name];
|
||||
if (bytes.Length == 0)
|
||||
if (!fieldInfo.IsStatic)
|
||||
{
|
||||
fieldInfo.SetValue(Instance, null);
|
||||
} else
|
||||
{
|
||||
MemoryStream objectStream = new MemoryStream(fieldStore[fieldInfo.Name]);
|
||||
ODBObjectReader objectReader = new ODBObjectReader(ODB, objectStream);
|
||||
byte[] bytes = fieldStore[fieldInfo.Name];
|
||||
if (bytes.Length == 0)
|
||||
{
|
||||
fieldInfo.SetValue(Instance, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
MemoryStream objectStream = new MemoryStream(fieldStore[fieldInfo.Name]);
|
||||
ODBObjectReader objectReader = new ODBObjectReader(ODB, objectStream);
|
||||
|
||||
object value = objectReader.Read();
|
||||
fieldInfo.SetValue(Instance, value);
|
||||
object value = objectReader.Read();
|
||||
fieldInfo.SetValue(Instance, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void ReConfigure(Type targetType,DateTime timestamp)
|
||||
{
|
||||
Timestamp = timestamp;
|
||||
PreparedType = targetType;
|
||||
fieldStore.Clear();
|
||||
Instance = null;
|
||||
}
|
||||
|
||||
public byte[] GetFieldBytes(string fieldName)
|
||||
{
|
||||
|
@ -108,11 +143,20 @@ namespace ln.types.odb
|
|||
|
||||
public bool InstanceEquals(PreparedObject other)
|
||||
{
|
||||
if (other == null)
|
||||
return false;
|
||||
|
||||
if (Equals(other))
|
||||
{
|
||||
foreach (String fieldName in fieldStore.Keys)
|
||||
{
|
||||
if (!Object.Equals(fieldStore[fieldName], other.fieldStore[fieldName]))
|
||||
byte[] me = fieldStore[fieldName];
|
||||
byte[] you = other.fieldStore[fieldName];
|
||||
|
||||
File.WriteAllBytes("me.bin", me);
|
||||
File.WriteAllBytes("you.bin", you);
|
||||
|
||||
if (!me.AreEqual(you))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
namespace ln.types.odb
|
||||
{
|
||||
public abstract class Storage
|
||||
{
|
||||
public Storage()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public abstract bool Contains(Guid persistenceID);
|
||||
|
||||
public abstract bool Store(PreparedObject preparedObject);
|
||||
public abstract bool Load(PreparedObject preparedObject);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -173,7 +173,7 @@ namespace ln.types.serialize
|
|||
private void WriteType(Type type)
|
||||
{
|
||||
WriteByte('T');
|
||||
WriteValue(type.Assembly.FullName);
|
||||
WriteValue(type.Assembly.GetName().Name);
|
||||
if (type.IsGenericType)
|
||||
WriteValue(type.GetGenericTypeDefinition().FullName);
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue