Fixed semantics of ODBEntities
parent
71abdd8f00
commit
3d2f7a5ad0
|
@ -0,0 +1,78 @@
|
|||
// /**
|
||||
// * File: Cast.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.Reflection;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
namespace ln.types
|
||||
{
|
||||
public static class Cast
|
||||
{
|
||||
public static T To<T>(object value) => (T)To(value, typeof(T));
|
||||
public static object To(object value, Type targetType)
|
||||
{
|
||||
if (Object.ReferenceEquals(null, value))
|
||||
return null;
|
||||
|
||||
if (targetType.IsInstanceOfType(value))
|
||||
return value;
|
||||
|
||||
object casted;
|
||||
|
||||
if (
|
||||
!Implicit(value, targetType, out casted) &&
|
||||
!Implicit(value, value.GetType(), targetType, out casted) &&
|
||||
!Explicit(value, targetType, out casted) &&
|
||||
!Explicit(value, value.GetType(), targetType, out casted)
|
||||
)
|
||||
throw new InvalidCastException();
|
||||
return casted;
|
||||
}
|
||||
|
||||
public static bool Implicit(object value, Type type, out object casted) => Implicit(value, type, type, out casted);
|
||||
public static bool Implicit(object value, Type type, Type targetType, out object casted)
|
||||
{
|
||||
foreach (MethodInfo methodInfo in type.GetMethods(BindingFlags.Public | BindingFlags.Static))
|
||||
{
|
||||
if (methodInfo.Name.Equals("op_Implicit") && methodInfo.ReturnType.Equals(targetType))
|
||||
{
|
||||
ParameterInfo parameterInfo = methodInfo.GetParameters().FirstOrDefault();
|
||||
if ((parameterInfo != null) && (parameterInfo.ParameterType.Equals(value.GetType())))
|
||||
{
|
||||
casted = methodInfo.Invoke(null, new object[] { value });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
casted = null;
|
||||
return false;
|
||||
}
|
||||
public static bool Explicit(object value, Type type, out object casted) => Implicit(value, type, type, out casted);
|
||||
public static bool Explicit(object value, Type type, Type targetType, out object casted)
|
||||
{
|
||||
foreach (MethodInfo methodInfo in type.GetMethods(BindingFlags.Public | BindingFlags.Static))
|
||||
{
|
||||
if (methodInfo.Name.Equals("op_Explicit") && methodInfo.ReturnType.Equals(targetType))
|
||||
{
|
||||
ParameterInfo parameterInfo = methodInfo.GetParameters().FirstOrDefault();
|
||||
if ((parameterInfo != null) && (parameterInfo.ParameterType.Equals(value.GetType())))
|
||||
{
|
||||
casted = methodInfo.Invoke(null, new object[] { value });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
casted = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -46,7 +46,7 @@
|
|||
<Compile Include="odb\values\ODBGuid.cs" />
|
||||
<Compile Include="odb\values\ODBNull.cs" />
|
||||
<Compile Include="odb\values\ODBStringValue.cs" />
|
||||
<Compile Include="odb\values\ODBValue.cs" />
|
||||
<Compile Include="odb\values\ODBEntity.cs" />
|
||||
<Compile Include="odb\values\ODBInteger.cs" />
|
||||
<Compile Include="odb\values\ODBLong.cs" />
|
||||
<Compile Include="odb\values\ODBDouble.cs" />
|
||||
|
@ -94,7 +94,6 @@
|
|||
<Compile Include="threads\ThreadHelpers.cs" />
|
||||
<Compile Include="threads\DynamicPool.cs" />
|
||||
<Compile Include="threads\PoolThread.cs" />
|
||||
<Compile Include="odb\ng\DocumentChanges.cs" />
|
||||
<Compile Include="net\IPv6.cs" />
|
||||
<Compile Include="arithmetics\Words.cs" />
|
||||
<Compile Include="odb\ng\storage\bases\StorageBase.cs" />
|
||||
|
@ -112,6 +111,11 @@
|
|||
<Compile Include="odb\ng\storage\fs\FSStorageContainer.cs" />
|
||||
<Compile Include="threads\LockingException.cs" />
|
||||
<Compile Include="odb\ng\storage\bases\ChainedStorage.cs" />
|
||||
<Compile Include="odb\values\ODBValue.cs" />
|
||||
<Compile Include="Cast.cs" />
|
||||
<Compile Include="test\CacheTests.cs" />
|
||||
<Compile Include="test\ODBTests.cs" />
|
||||
<Compile Include="test\TypesTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="odb\" />
|
||||
|
|
|
@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||
# Visual Studio 15
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.types", "ln.types.csproj", "{8D9AB9A5-E513-4BA7-A450-534F6456BF28}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.types.test", "ln.types.test\ln.types.test.csproj", "{E39D8B11-7CF6-4C78-B723-F7E100121704}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.logging", "..\ln.logging\ln.logging.csproj", "{D471A566-9FB6-41B2-A777-3C32874ECD0E}"
|
||||
EndProject
|
||||
Global
|
||||
|
@ -17,10 +15,6 @@ Global
|
|||
{8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E39D8B11-7CF6-4C78-B723-F7E100121704}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E39D8B11-7CF6-4C78-B723-F7E100121704}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E39D8B11-7CF6-4C78-B723-F7E100121704}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E39D8B11-7CF6-4C78-B723-F7E100121704}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D471A566-9FB6-41B2-A777-3C32874ECD0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D471A566-9FB6-41B2-A777-3C32874ECD0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D471A566-9FB6-41B2-A777-3C32874ECD0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
|
|
@ -1,269 +0,0 @@
|
|||
// /**
|
||||
// * File: Program.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 ln.types.odb.ng.storage;
|
||||
using ln.types.odb.ng;
|
||||
using ln.logging;
|
||||
using System.Linq;
|
||||
using ln.types.threads;
|
||||
using System.Collections.Generic;
|
||||
using ln.types.odb.ng.mappings;
|
||||
using System.Net;
|
||||
using ln.types.odb.ng.storage.session;
|
||||
|
||||
namespace ln.types.test
|
||||
{
|
||||
class MainClass
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
IPv6 maskTest = IPv6.Parse("255.255.255.255");
|
||||
Console.WriteLine("Mask Test: {0} => {1}", maskTest.ToCIDR(), maskTest.Network.ToCIDR());
|
||||
for (int n=0;n<31;n++)
|
||||
{
|
||||
maskTest = new IPv6(maskTest, maskTest.Netmask-1);
|
||||
Console.WriteLine("Mask Test: {0} => {1}", maskTest.ToCIDR(), maskTest.Network.ToCIDR());
|
||||
}
|
||||
|
||||
ParseIPv6("1.2.3.4");
|
||||
ParseIPv6("10.112.0.0/10");
|
||||
|
||||
|
||||
ParseIPv6("::1234:5678:9ABC:DEF0");
|
||||
ParseIPv6("1234:5678:9ABC:DEF0::");
|
||||
|
||||
ParseIPv6("::");
|
||||
ParseIPv6(IPv6.V4Space.ToCIDR());
|
||||
ParseIPv6("::ffff:127.0.0.1");
|
||||
ParseIPv6("2001:db8::1428:57ab");
|
||||
|
||||
IPv6 ip = IPv6.V4Space;
|
||||
|
||||
Console.WriteLine("IPv4Space: {0}",ip.ToCIDR());
|
||||
|
||||
for (int n = 0; n < 10; n++)
|
||||
{
|
||||
ip++;
|
||||
Console.WriteLine("+1: {0}", ip.ToCIDR());
|
||||
}
|
||||
|
||||
for (int n = 0; n < 32; n++)
|
||||
{
|
||||
ip += 256;
|
||||
Console.WriteLine("+256: {0}", ip.ToCIDR());
|
||||
}
|
||||
|
||||
for (int n = 0; n < 32; n++)
|
||||
{
|
||||
ip += 1<<14;
|
||||
Console.WriteLine("+(1<<14): {0}", ip.ToCIDR());
|
||||
}
|
||||
|
||||
Console.WriteLine("->IPAddress: {0}", (IPAddress)ip);
|
||||
|
||||
IPAddress ip4 = IPAddress.Parse("10.112.1.254");
|
||||
Console.WriteLine("IP4 = {0} => {1}",ip4,(IPv6)ip4);
|
||||
|
||||
IPv6 ten = IPv6.Parse("::ffff:10.0.0.0/104");
|
||||
Console.WriteLine("Splitting Network: {0}",ten.ToCIDR());
|
||||
foreach (IPv6 subnet in ten.Split(8))
|
||||
Console.WriteLine(" {0}", subnet.ToCIDR());
|
||||
|
||||
IPv6 v6 = IPv6.Parse("2001:470:7408::/48");
|
||||
Console.WriteLine("Splitting Network: {0}", v6.ToCIDR());
|
||||
foreach (IPv6 subnet in v6.Split(4))
|
||||
Console.WriteLine(" {0}", subnet.ToCIDR());
|
||||
}
|
||||
|
||||
public static void ParseIPv6(string source)
|
||||
{
|
||||
IPv6 ip = IPv6.Parse(source);
|
||||
Console.WriteLine("IPv6: {0,40} => {1} [ {3,24} ] = {2}", source, ip.ToString(false),ip,ip.Network.ToCIDR());
|
||||
Console.WriteLine("CIDR: {0}", ip.ToCIDR());
|
||||
Console.WriteLine("(IPAddress) = {0}", (IPAddress)ip);
|
||||
}
|
||||
|
||||
public static void TestStorage(IStorageContainer container)
|
||||
{
|
||||
using (IStorage storage = container.GetStorage("test"))
|
||||
{
|
||||
|
||||
if (!storage.IsOpen)
|
||||
storage.Open();
|
||||
|
||||
foreach (Guid documentID in storage.GetDocumentIDs())
|
||||
{
|
||||
Logging.Log(LogLevel.INFO, "DocumentID: {0}", documentID);
|
||||
Document doc = storage.Load(documentID);
|
||||
Logging.Log(LogLevel.INFO, doc.ToString());
|
||||
doc["FeldC"] = doc["FeldC"].AsLong + 1;
|
||||
storage.Save(doc);
|
||||
}
|
||||
|
||||
Document document = new Document();
|
||||
|
||||
document["FeldA"] = "Ich bin das Feld A";
|
||||
document["FeldB"] = "Ich bin das Feld B";
|
||||
document["FeldC"] = new Random().Next();
|
||||
|
||||
storage.Save(document);
|
||||
storage.Save(document);
|
||||
}
|
||||
}
|
||||
public static void TestMapper(IStorageContainer container)
|
||||
{
|
||||
Mapper mapper = new Mapper(container);
|
||||
|
||||
Logging.Log(LogLevel.INFO, "Cleaning up Person store");
|
||||
foreach (Guid documentID in mapper.GetDocumentIDs<Person>())
|
||||
mapper.Delete<Person>(documentID);
|
||||
|
||||
Logging.Log(LogLevel.INFO, "Storage counts {0} entities", mapper.GetDocumentIDs<Person>().Count());
|
||||
|
||||
Person[] persons = new Person[15000];
|
||||
for (int n = 0; n < persons.Length; n++)
|
||||
persons[n] = new Person();
|
||||
|
||||
Logging.Log(LogLevel.INFO, "Created {0} persons", persons.Length);
|
||||
|
||||
Timing.Meassure("store persons", () =>
|
||||
{
|
||||
foreach (Person person in persons)
|
||||
mapper.Save(person);
|
||||
});
|
||||
|
||||
Guid[] documentIDs = mapper.GetDocumentIDs<Person>().ToArray();
|
||||
Random random = new Random();
|
||||
|
||||
//for (int n = 0; n < 20; n++)
|
||||
//{
|
||||
// Guid choosenID = documentIDs[random.Next(documentIDs.Length)];
|
||||
// Person person = mapper.Load<Person>(choosenID);
|
||||
|
||||
// Logging.Log(LogLevel.INFO, "Querying: {0}", person.FirstName);
|
||||
|
||||
// IEnumerable<Guid> ids = Timing.Meassure(() => mapper.GetDocumentIDs<Person>(Query.Equals<Person>("MiddleNames[]", person.FirstName)));
|
||||
// Guid[] matchedIDs = ids.ToArray();
|
||||
|
||||
// Logging.Log(LogLevel.INFO, "Found {0} persons.", matchedIDs.Length);
|
||||
//}
|
||||
|
||||
IODBMapping pMapping = mapper.GetMapping<Person>();
|
||||
|
||||
Person p1 = new Person();
|
||||
Document pd1 = pMapping.MapValue(mapper, p1) as Document;
|
||||
|
||||
p1.MiddleNames[1] = "N/A";
|
||||
|
||||
Document pd2 = pMapping.MapValue(mapper, p1) as Document;
|
||||
|
||||
DocumentChanges documentChanges = new DocumentChanges(pd1, pd2);
|
||||
Logging.Log(LogLevel.INFO, "DocumentChanges: \n{0}",String.Join("\n",documentChanges.Changes.Select((x)=>x.ToString())));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mapper.EnsureIndex<Person>("MiddleNames[]");
|
||||
mapper.EnsureIndex<Person>("FirstName");
|
||||
|
||||
Logging.Log(LogLevel.INFO, "using indeces");
|
||||
|
||||
for (int n = 0; n < 20; n++)
|
||||
{
|
||||
Guid choosenID = documentIDs[random.Next(documentIDs.Length)];
|
||||
Person person = mapper.Load<Person>(choosenID);
|
||||
|
||||
IEnumerable<Guid> ids = Timing.Meassure(() => mapper.GetDocumentIDs<Person>(Query.Equals<Person>("MiddleNames[]", person.FirstName)));
|
||||
Guid[] matchedIDs = ids.ToArray();
|
||||
Logging.Log(LogLevel.INFO, "Queried '{0}' with {1,4} matches", person.FirstName, matchedIDs.Length);
|
||||
|
||||
}
|
||||
|
||||
for (int n = 0; n < 20; n++)
|
||||
{
|
||||
Guid choosenID = documentIDs[random.Next(documentIDs.Length)];
|
||||
Person person = mapper.Load<Person>(choosenID);
|
||||
|
||||
IEnumerable<Guid> ids = Timing.Meassure(() => mapper.GetDocumentIDs<Person>(
|
||||
Query.AND(
|
||||
Query.Equals<Person>("MiddleNames[]", person.FirstName),
|
||||
Query.Equals<Person>("FirstName", person.FirstName)
|
||||
)
|
||||
)
|
||||
);
|
||||
Guid[] matchedIDs = ids.ToArray();
|
||||
Logging.Log(LogLevel.INFO, "Queried complex '{0}' with {1,4} matches", person.FirstName, matchedIDs.Length);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Person
|
||||
{
|
||||
static Random random = new Random();
|
||||
|
||||
static string[] firstNames = new string[]
|
||||
{
|
||||
"Harald","Simone","Viola","Antigona","Peter","Paul","Maria","Karel","Bruno","Ilse","Sonja","Ute","Justus","Niclas","Pascal"
|
||||
};
|
||||
static string[] lastNames = new string[]
|
||||
{
|
||||
"Wolff","Thobaben","Schmidt","Seefeld","van der Heide","Schuhmacher","Brommer","Günther","Freilauf","Unger","Thomalla","Christensen","Person","Forghammer"
|
||||
};
|
||||
|
||||
public string FirstName;
|
||||
public string LastName;
|
||||
public String[] MiddleNames;
|
||||
public int Age;
|
||||
|
||||
public Person()
|
||||
{
|
||||
FirstName = firstNames[random.Next(firstNames.Length)];
|
||||
LastName = lastNames[random.Next(lastNames.Length)];
|
||||
MiddleNames = new string[]
|
||||
{
|
||||
firstNames[random.Next(firstNames.Length)],
|
||||
firstNames[random.Next(firstNames.Length)],
|
||||
firstNames[random.Next(firstNames.Length)]
|
||||
};
|
||||
|
||||
Age = random.Next(120);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("[Person FirstName={0} LastName={1} Age={2}]",FirstName,LastName,Age);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MapableClass
|
||||
{
|
||||
public int ANumber { get; set; }
|
||||
public String MyString;
|
||||
|
||||
public MapableClass()
|
||||
{
|
||||
ANumber = new Random().Next();
|
||||
MyString = ANumber.ToString();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("[MapableClass ANumber={0} MyString={1}]",ANumber,MyString);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
// /**
|
||||
// * File: AssemblyInfo.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.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
// Information about this assembly is defined by the following attributes.
|
||||
// Change them to the values specific to your project.
|
||||
|
||||
[assembly: AssemblyTitle("ln.types.test")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
|
||||
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
|
||||
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
|
||||
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
// The following attributes are used to specify the signing key for the assembly,
|
||||
// if desired. See the Mono documentation for more information about signing.
|
||||
|
||||
//[assembly: AssemblyDelaySign(false)]
|
||||
//[assembly: AssemblyKeyFile("")]
|
|
@ -1,53 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{E39D8B11-7CF6-4C78-B723-F7E100121704}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>ln.types.test</RootNamespace>
|
||||
<AssemblyName>ln.types.test</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ExternalConsole>true</ExternalConsole>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ExternalConsole>true</ExternalConsole>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="nunit.framework">
|
||||
<Package>nunit</Package>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="TypesTests.cs" />
|
||||
<Compile Include="ODBTests.cs" />
|
||||
<Compile Include="CacheTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ln.types.csproj">
|
||||
<Project>{8D9AB9A5-E513-4BA7-A450-534F6456BF28}</Project>
|
||||
<Name>ln.types</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\ln.logging\ln.logging.csproj">
|
||||
<Project>{D471A566-9FB6-41B2-A777-3C32874ECD0E}</Project>
|
||||
<Name>ln.logging</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -5,14 +5,16 @@ using ln.types.odb.values;
|
|||
using System.Linq;
|
||||
namespace ln.types.odb.ng
|
||||
{
|
||||
public class Document : ODBValue
|
||||
public class Document : ODBEntity
|
||||
{
|
||||
private Dictionary<ODBValue, ODBValue> properties = new Dictionary<ODBValue, ODBValue>();
|
||||
public override ODBValue Identity => new ODBGuid(ID);
|
||||
|
||||
private Dictionary<ODBEntity, ODBEntity> properties = new Dictionary<ODBEntity, ODBEntity>();
|
||||
|
||||
public Document()
|
||||
:base(0x1001)
|
||||
{
|
||||
ID = Guid.NewGuid();
|
||||
ID = Guid.NewGuid();
|
||||
}
|
||||
|
||||
public Document(Guid id)
|
||||
|
@ -21,25 +23,26 @@ namespace ln.types.odb.ng
|
|||
ID = id;
|
||||
}
|
||||
|
||||
public Guid ID { get; internal set; }
|
||||
public Guid ID { get; }
|
||||
public DateTime StorageTimeStamp { get; set; }
|
||||
|
||||
public Document(Guid documentID,byte[] bytes)
|
||||
: this(documentID, bytes, 0, bytes.Length)
|
||||
{ }
|
||||
public Document(Guid documentID,byte[] bytes,int offset,int length)
|
||||
:this(documentID)
|
||||
public Document(byte[] bytes)
|
||||
: this(bytes, 0, bytes.Length)
|
||||
{}
|
||||
public Document(byte[] bytes,int offset,int length)
|
||||
:this(new Guid(bytes.Slice(offset, 16)))
|
||||
{
|
||||
ID = documentID;
|
||||
|
||||
int endOffset = offset + length;
|
||||
|
||||
offset += 16; // GUID (!!!) -> this(...)
|
||||
|
||||
int nProps = BitConverter.ToInt32(bytes, offset);
|
||||
offset += 4;
|
||||
|
||||
for (int n=0;n<nProps;n++)
|
||||
{
|
||||
ODBValue propName = ODBValue.Deserialize(bytes,ref offset);
|
||||
ODBValue propValue = ODBValue.Deserialize(bytes, ref offset);
|
||||
ODBEntity propName = ODBEntity.Deserialize(bytes,ref offset);
|
||||
ODBEntity propValue = ODBEntity.Deserialize(bytes, ref offset);
|
||||
properties.Add(propName, propValue);
|
||||
}
|
||||
|
||||
|
@ -47,7 +50,7 @@ namespace ln.types.odb.ng
|
|||
throw new FormatException("Document deserialization read behind end of buffer");
|
||||
}
|
||||
|
||||
public ODBValue this[ODBValue propName]
|
||||
public ODBEntity this[ODBEntity propName]
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -68,22 +71,26 @@ namespace ln.types.odb.ng
|
|||
}
|
||||
}
|
||||
}
|
||||
public ODBEntity this[string propName]
|
||||
{
|
||||
get => this[new ODBStringValue(propName)];
|
||||
set => this[new ODBStringValue(propName)] = value;
|
||||
}
|
||||
|
||||
public IEnumerable<ODBValue> Keys => properties.Keys;
|
||||
public IEnumerable<ODBEntity> Keys => properties.Keys;
|
||||
|
||||
public override int CompareLevel => 128;
|
||||
|
||||
public bool Contains(ODBValue propName)
|
||||
public bool Contains(string propName) => Contains(new ODBStringValue(propName));
|
||||
public bool Contains(ODBEntity propName)
|
||||
{
|
||||
return !ODBNull.Instance.Equals(this[propName]);
|
||||
}
|
||||
|
||||
public override ODBValue Clone()
|
||||
public override ODBEntity Clone()
|
||||
{
|
||||
Document clone = new Document(ID);
|
||||
clone.StorageTimeStamp = StorageTimeStamp;
|
||||
|
||||
foreach (ODBValue fieldName in properties.Keys)
|
||||
foreach (ODBEntity fieldName in properties.Keys)
|
||||
{
|
||||
clone[fieldName] = this[fieldName].Clone();
|
||||
}
|
||||
|
@ -94,24 +101,25 @@ namespace ln.types.odb.ng
|
|||
{
|
||||
target.properties.Clear();
|
||||
target.StorageTimeStamp = StorageTimeStamp;
|
||||
foreach (ODBValue fieldName in properties.Keys)
|
||||
foreach (ODBEntity fieldName in properties.Keys)
|
||||
{
|
||||
target[fieldName] = this[fieldName].Clone();
|
||||
}
|
||||
}
|
||||
|
||||
public override byte[] ToStorage()
|
||||
public override byte[] GetStorageBytes()
|
||||
{
|
||||
MemoryStream stream = new MemoryStream();
|
||||
BinaryWriter writer = new BinaryWriter(stream);
|
||||
|
||||
|
||||
writer.Write(ID.ToByteArray());
|
||||
writer.Write(properties.Count);
|
||||
|
||||
foreach (ODBValue propName in properties.Keys)
|
||||
foreach (ODBEntity propName in properties.Keys)
|
||||
{
|
||||
ODBValue propValue = properties[propName];
|
||||
propName.Store(writer);
|
||||
propValue.Store(writer);
|
||||
ODBEntity propValue = properties[propName];
|
||||
propName.Write(writer);
|
||||
propValue.Write(writer);
|
||||
}
|
||||
|
||||
return stream.ToArray();
|
||||
|
@ -136,37 +144,17 @@ namespace ln.types.odb.ng
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool ContentEquals(Document other)
|
||||
protected override int compare(ODBEntity e)
|
||||
{
|
||||
if (object.ReferenceEquals(null, other))
|
||||
return false;
|
||||
Document other = e as Document;
|
||||
ODBEntity[] keys = Keys.Union(other.Keys).ToArray();
|
||||
|
||||
ODBValue[] keys = Keys.Union(other.Keys).ToArray();
|
||||
|
||||
foreach (ODBValue key in keys)
|
||||
foreach (ODBEntity key in keys)
|
||||
{
|
||||
ODBValue value = this[key];
|
||||
if (!value.ValueEquals(other[key]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
ODBEntity mine = this[key];
|
||||
ODBEntity yours = other[key];
|
||||
|
||||
public override bool ValueEquals(ODBValue other)
|
||||
{
|
||||
return ContentEquals(other as Document);
|
||||
}
|
||||
|
||||
public int CompareContent(Document other)
|
||||
{
|
||||
ODBValue[] keys = Keys.Union(other.Keys).ToArray();
|
||||
|
||||
foreach (ODBValue key in keys)
|
||||
{
|
||||
ODBValue mine = this[key];
|
||||
ODBValue yours = other[key];
|
||||
|
||||
int c = ODBValue.Compare(mine, yours);
|
||||
int c = mine.CompareTo(yours);
|
||||
|
||||
if (c != 0)
|
||||
return c;
|
||||
|
@ -174,18 +162,11 @@ namespace ln.types.odb.ng
|
|||
return 0;
|
||||
}
|
||||
|
||||
public override int CompareInType(ODBValue other)
|
||||
{
|
||||
return CompareContent(other as Document);
|
||||
}
|
||||
public override int CompareValueInType(ODBValue other)
|
||||
{
|
||||
return CompareContent(other as Document);
|
||||
}
|
||||
public override T As<T>() => (T)Mapper.Default.UnmapValue(typeof(T), this);
|
||||
|
||||
static Document()
|
||||
{
|
||||
RegisterDeserializer(0x1001, (b,o,l) => new Document(Guid.Empty,b,o+16,l));
|
||||
RegisterDeserializer(0x1001, (b,o,l) => new Document(b,o+16,l));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ln.types.odb.values;
|
||||
using System.Xml.Serialization;
|
||||
using System.Linq;
|
||||
namespace ln.types.odb.ng
|
||||
{
|
||||
public class DocumentChanges
|
||||
{
|
||||
public Document Source { get; }
|
||||
public Document Destination { get; }
|
||||
|
||||
List<DocumentChange> changes = new List<DocumentChange>();
|
||||
public DocumentChange[] Changes => changes.ToArray();
|
||||
|
||||
|
||||
public DocumentChanges(Document src,Document dst)
|
||||
{
|
||||
Source = src;
|
||||
Destination = dst;
|
||||
|
||||
diffDocument(src, dst);
|
||||
}
|
||||
|
||||
private void diffDocument(Document src, Document dst) => diffDocument(new Stack<ODBValue>(), src, dst);
|
||||
private void diffDocument(Stack<ODBValue> path,Document src,Document dst)
|
||||
{
|
||||
HashSet<ODBValue> keys = new HashSet<ODBValue>(src.Keys);
|
||||
foreach (ODBValue key in dst.Keys)
|
||||
keys.Add(key);
|
||||
|
||||
foreach (ODBValue key in keys)
|
||||
{
|
||||
path.Push(key);
|
||||
diff(path, src[key], dst[key]);
|
||||
path.Pop();
|
||||
}
|
||||
}
|
||||
private void diffList(Stack<ODBValue> path,ODBList src,ODBList dst)
|
||||
{
|
||||
int commonLength = src.Count < dst.Count ? src.Count : dst.Count;
|
||||
|
||||
for (int i = 0; i < commonLength; i++)
|
||||
{
|
||||
path.Push(i);
|
||||
diff(path, src[i], dst[i]);
|
||||
path.Pop();
|
||||
}
|
||||
|
||||
for (int i = commonLength; i < src.Count; i++)
|
||||
{
|
||||
path.Push(i);
|
||||
diff(path, src[i], null);
|
||||
path.Pop();
|
||||
}
|
||||
for (int i = commonLength; i < dst.Count; i++)
|
||||
{
|
||||
path.Push(i);
|
||||
diff(path, ODBNull.Instance, dst[i]);
|
||||
path.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
private void diff(Stack<ODBValue> path,ODBValue srcValue,ODBValue dstValue)
|
||||
{
|
||||
if ((srcValue is ODBList) && (dstValue is ODBList))
|
||||
{
|
||||
diffList(path, srcValue as ODBList, dstValue as ODBList);
|
||||
}
|
||||
else if ((srcValue is Document) && (dstValue is Document))
|
||||
{
|
||||
diffDocument(path, srcValue as Document, dstValue as Document);
|
||||
}
|
||||
else if (!srcValue.Equals(dstValue))
|
||||
{
|
||||
changes.Add(new DocumentChange(path.Reverse(), dstValue));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class DocumentChange
|
||||
{
|
||||
public ODBValue[] Path { get; }
|
||||
|
||||
public ODBValue Key => Path[Path.Length - 1];
|
||||
public ODBValue Value { get; }
|
||||
|
||||
public DocumentChange(ODBValue value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
public DocumentChange(IEnumerable<ODBValue> path,ODBValue value)
|
||||
:this(value)
|
||||
{
|
||||
if (path is ODBValue[])
|
||||
Path = path as ODBValue[];
|
||||
else
|
||||
Path = path.ToArray();
|
||||
}
|
||||
|
||||
public void Apply(Document document)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("[DocumentChange Path={0} Value={1}]", String.Join("/", Path.Select((x) => x?.AsString)), Value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ namespace ln.types.odb.ng
|
|||
{
|
||||
public interface IODBMapping
|
||||
{
|
||||
ODBValue MapValue(Mapper mapper, object value);
|
||||
object UnmapValue(Mapper mapper, ODBValue oval);
|
||||
ODBEntity MapValue(Mapper mapper, object value);
|
||||
object UnmapValue(Mapper mapper, ODBEntity oval);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,8 +118,8 @@ namespace ln.types.odb.ng
|
|||
return storage.GetDocumentIDs();
|
||||
}
|
||||
|
||||
public IEnumerable<Guid> GetDocumentIDs<T>(string path, Predicate<ODBValue> predicate) => GetDocumentIDs(typeof(T), path, predicate);
|
||||
public IEnumerable<Guid> GetDocumentIDs(Type type, string path, Predicate<ODBValue> predicate)
|
||||
public IEnumerable<Guid> GetDocumentIDs<T>(string path, Predicate<ODBEntity> predicate) => GetDocumentIDs(typeof(T), path, predicate);
|
||||
public IEnumerable<Guid> GetDocumentIDs(Type type, string path, Predicate<ODBEntity> predicate)
|
||||
{
|
||||
IStorage storage = StorageContainer.GetStorage(type.FullName);
|
||||
return storage.GetDocumentIDs(path,predicate);
|
||||
|
|
|
@ -12,10 +12,10 @@ using ln.types.odb.ng.storage.fs;
|
|||
|
||||
namespace ln.types.odb.ng
|
||||
{
|
||||
public delegate ODBValue ODBMap(Mapper mapper, object value);
|
||||
public delegate object ODBUnmap(Mapper mapper, ODBValue oval);
|
||||
public delegate ODBValue ODBMap<T>(Mapper mapper, T value);
|
||||
public delegate T ODBUnmap<T>(Mapper mapper, ODBValue oval);
|
||||
public delegate ODBEntity ODBMap(Mapper mapper, object value);
|
||||
public delegate object ODBUnmap(Mapper mapper, ODBEntity oval);
|
||||
public delegate ODBEntity ODBMap<T>(Mapper mapper, T value);
|
||||
public delegate T ODBUnmap<T>(Mapper mapper, ODBEntity oval);
|
||||
|
||||
public partial class Mapper : IDisposable
|
||||
{
|
||||
|
@ -39,74 +39,74 @@ namespace ln.types.odb.ng
|
|||
|
||||
RegisterMapping<string>(
|
||||
(mapper, value) => new ODBStringValue(value),
|
||||
(mapper, oval) => oval.AsString
|
||||
(mapper, oval) => oval.As<String>()
|
||||
);
|
||||
RegisterMapping<int>(
|
||||
(mapper, value) => new ODBInteger(value),
|
||||
(mapper, oval) => oval.AsInt
|
||||
(mapper, oval) => oval.As<int>()
|
||||
);
|
||||
RegisterMapping<short>(
|
||||
(mapper, value) => new ODBInteger(value),
|
||||
(mapper, oval) => oval.AsShort
|
||||
(mapper, oval) => oval.As<short>()
|
||||
);
|
||||
RegisterMapping<byte>(
|
||||
(mapper, value) => new ODBInteger(value),
|
||||
(mapper, oval) => oval.AsByte
|
||||
(mapper, oval) => oval.As<Byte>()
|
||||
);
|
||||
|
||||
RegisterMapping<uint>(
|
||||
(mapper, value) => new ODBUInteger(value),
|
||||
(mapper, oval) => oval.AsUInt
|
||||
(mapper, oval) => oval.As<uint>()
|
||||
);
|
||||
RegisterMapping<ushort>(
|
||||
(mapper, value) => new ODBUInteger(value),
|
||||
(mapper, oval) => oval.AsUShort
|
||||
(mapper, oval) => oval.As<ushort>()
|
||||
);
|
||||
RegisterMapping<char>(
|
||||
(mapper, value) => new ODBUInteger(value),
|
||||
(mapper, oval) => oval.AsChar
|
||||
(mapper, oval) => oval.As<Char>()
|
||||
);
|
||||
|
||||
RegisterMapping<double>(
|
||||
(mapper, value) => new ODBDouble(value),
|
||||
(mapper, oval) => oval.AsDouble
|
||||
(mapper, oval) => oval.As<double>()
|
||||
);
|
||||
RegisterMapping<float>(
|
||||
(mapper, value) => new ODBDouble(value),
|
||||
(mapper, oval) => oval.AsFloat
|
||||
(mapper, oval) => oval.As<float>()
|
||||
);
|
||||
|
||||
RegisterMapping<DateTime>(
|
||||
(mapper, value) => new ODBLong(DateTime.MinValue.Equals(value) ? 0 : new DateTimeOffset(value.ToUniversalTime()).ToUnixTimeMilliseconds() ),
|
||||
(mapper, oval) => DateTimeOffset.FromUnixTimeMilliseconds(oval.AsLong).DateTime
|
||||
(mapper, oval) => DateTimeOffset.FromUnixTimeMilliseconds(oval.As<long>()).DateTime
|
||||
);
|
||||
RegisterMapping<TimeSpan>(
|
||||
(mapper, value) => new ODBDouble(value.TotalMilliseconds),
|
||||
(mapper, oval) => TimeSpan.FromMilliseconds(oval.AsDouble)
|
||||
(mapper, oval) => TimeSpan.FromMilliseconds(oval.As<double>())
|
||||
);
|
||||
|
||||
RegisterMapping<Guid>(
|
||||
(mapper, value) => new ODBGuid(value),
|
||||
(mapper, oval) => oval.AsGuid
|
||||
(mapper, oval) => oval.As<Guid>()
|
||||
);
|
||||
|
||||
RegisterMapping<long>(
|
||||
(mapper, value) => new ODBLong(value),
|
||||
(mapper, oval) => oval.AsLong
|
||||
(mapper, oval) => oval.As<long>()
|
||||
);
|
||||
RegisterMapping<ulong>(
|
||||
(mapper, value) => new ODBULong(value),
|
||||
(mapper, oval) => oval.AsULong
|
||||
(mapper, oval) => oval.As<ulong>()
|
||||
);
|
||||
|
||||
RegisterMapping<bool>(
|
||||
(mapper, value) => new ODBBool(value),
|
||||
(mapper, oval) => oval.AsBool
|
||||
(mapper, value) => (bool)value ? ODBBool.True : ODBBool.False,
|
||||
(mapper, oval) => oval.As<bool>()
|
||||
);
|
||||
|
||||
RegisterMapping<IPv4>(
|
||||
(mapper, value) => new ODBUInteger(value.AsUInt),
|
||||
(mapper, oval) => new IPv4(oval.AsUInt)
|
||||
(mapper, oval) => new IPv4(oval.As<uint>())
|
||||
);
|
||||
|
||||
ObjectMapping = new mappings.ObjectMapping();
|
||||
|
@ -216,7 +216,7 @@ namespace ln.types.odb.ng
|
|||
// return null;
|
||||
//}
|
||||
|
||||
public virtual ODBValue MapValue(object value)
|
||||
public virtual ODBEntity MapValue(object value)
|
||||
{
|
||||
if (value == null)
|
||||
return ODBNull.Instance;
|
||||
|
@ -227,7 +227,7 @@ namespace ln.types.odb.ng
|
|||
|
||||
throw new NotSupportedException(String.Format("Can't map {0} ({1})",value.GetType(),value));
|
||||
}
|
||||
public virtual object UnmapValue(Type targetType,ODBValue value)
|
||||
public virtual object UnmapValue(Type targetType,ODBEntity value)
|
||||
{
|
||||
if (ODBNull.Instance.Equals(value))
|
||||
return null;
|
||||
|
@ -235,22 +235,23 @@ namespace ln.types.odb.ng
|
|||
if (value is Document)
|
||||
{
|
||||
Document doc = value as Document;
|
||||
String asmname = doc["__asm__"].AsString;
|
||||
String typename = doc["__type__"].AsString;
|
||||
String asmname = doc["__asm__"].As<string>();
|
||||
String typename = doc["__type__"].As<string>();
|
||||
|
||||
if (typename != null)
|
||||
targetType = Type.GetType(String.Format("{0}, {1}",typename,asmname)); //Assembly.Load(asmname).GetType(typename);
|
||||
} else if (value is ODBTypedValue)
|
||||
{
|
||||
ODBTypedValue typedValue = value as ODBTypedValue;
|
||||
targetType = typedValue.TargetType;
|
||||
}
|
||||
//else if (value is ODBTypedValue)
|
||||
//{
|
||||
// ODBTypedValue typedValue = value as ODBTypedValue;
|
||||
// targetType = typedValue.TargetType;
|
||||
//}
|
||||
|
||||
IODBMapping mapping = GetMapping(targetType);
|
||||
if (mapping != null)
|
||||
return mapping.UnmapValue(this,value);
|
||||
|
||||
return Convert.ChangeType(value.Value, targetType);
|
||||
return value.As(targetType);
|
||||
}
|
||||
|
||||
public virtual object TryImplicitMapping(object value,Type targetType)
|
||||
|
|
|
@ -36,37 +36,37 @@ namespace ln.types.odb.ng
|
|||
}
|
||||
|
||||
public static Query Equals<T>(string propertyName, object value) => Equals(IndexPath.TranslatePropertyPath(typeof(T), propertyName), Mapper.Default.MapValue(value));
|
||||
public static Query Equals(String propertyName, ODBValue value)
|
||||
public static Query Equals(String propertyName, ODBEntity value)
|
||||
{
|
||||
if (object.ReferenceEquals(value,null))
|
||||
value = ODBNull.Instance;
|
||||
|
||||
return IF(propertyName, (v) => value.ValueEquals(v));
|
||||
return IF(propertyName, (v) => value.Equals(v));
|
||||
}
|
||||
public static Query EqualsNot<T>(string propertyName, ODBValue value) => EqualsNot(IndexPath.TranslatePropertyPath(typeof(T), propertyName), value);
|
||||
public static Query EqualsNot(String propertyName, ODBValue value)
|
||||
public static Query EqualsNot<T>(string propertyName, ODBEntity value) => EqualsNot(IndexPath.TranslatePropertyPath(typeof(T), propertyName), value);
|
||||
public static Query EqualsNot(String propertyName, ODBEntity value)
|
||||
{
|
||||
if (object.ReferenceEquals(value, null))
|
||||
value = ODBNull.Instance;
|
||||
|
||||
return IF(propertyName, (v) => !value.ValueEquals(v));
|
||||
return IF(propertyName, (v) => !value.Equals(v));
|
||||
}
|
||||
|
||||
public static Query Equals<T>(string propertyName, ODBValue[] values) => Equals(IndexPath.TranslatePropertyPath(typeof(T), propertyName), values);
|
||||
public static Query Equals(String propertyName, ODBValue[] values)
|
||||
public static Query Equals<T>(string propertyName, ODBEntity[] values) => Equals(IndexPath.TranslatePropertyPath(typeof(T), propertyName), values);
|
||||
public static Query Equals(String propertyName, ODBEntity[] values)
|
||||
{
|
||||
return IF(propertyName, (v) => values.Contains(v));
|
||||
}
|
||||
|
||||
public static Query Contains<T, A>(string propertyName, IEnumerable<A> values)
|
||||
{
|
||||
ODBValue[] oValues = values.Select(v => Mapper.Default.MapValue(v)).ToArray();
|
||||
ODBEntity[] oValues = values.Select(v => Mapper.Default.MapValue(v)).ToArray();
|
||||
return IF(IndexPath.TranslatePropertyPath(typeof(T), propertyName), v => oValues.Contains(v));
|
||||
}
|
||||
|
||||
|
||||
public static Query IF<T>(string propertyName, Predicate<ODBValue> predicate) => IF(IndexPath.TranslatePropertyPath(typeof(T),propertyName), predicate);
|
||||
public static Query IF(string propertyName,Predicate<ODBValue> predicate)
|
||||
public static Query IF<T>(string propertyName, Predicate<ODBEntity> predicate) => IF(IndexPath.TranslatePropertyPath(typeof(T),propertyName), predicate);
|
||||
public static Query IF(string propertyName,Predicate<ODBEntity> predicate)
|
||||
{
|
||||
return new IMPL.IF(propertyName, predicate);
|
||||
}
|
||||
|
@ -79,9 +79,9 @@ namespace ln.types.odb.ng
|
|||
public class IF : Query
|
||||
{
|
||||
public string PropertyName { get; }
|
||||
public Predicate<ODBValue> Predicate { get; }
|
||||
public Predicate<ODBEntity> Predicate { get; }
|
||||
|
||||
public IF(string propertyName,Predicate<ODBValue> predicate)
|
||||
public IF(string propertyName,Predicate<ODBEntity> predicate)
|
||||
{
|
||||
PropertyName = propertyName;
|
||||
Predicate = predicate;
|
||||
|
|
|
@ -18,14 +18,14 @@ namespace ln.types.odb.ng.index
|
|||
IndexName = IndexPath.Complete;
|
||||
}
|
||||
|
||||
public virtual void Replace(Guid documentID, ODBValue value) {
|
||||
public virtual void Replace(Guid documentID, ODBEntity value) {
|
||||
Remove(documentID);
|
||||
Add(documentID, value);
|
||||
}
|
||||
public abstract void Add(Guid documentID, ODBValue value);
|
||||
public abstract void Add(Guid documentID, ODBEntity value);
|
||||
public abstract void Remove(Guid documentID);
|
||||
|
||||
public abstract IEnumerable<Guid> GetDocumentIDs(Predicate<ODBValue> predicate);
|
||||
public abstract IEnumerable<Guid> GetDocumentIDs(Predicate<ODBEntity> predicate);
|
||||
|
||||
public abstract bool LoadIndex(string basePath, long lastCloseTimestamp);
|
||||
public abstract bool SaveIndex(string basePath, long lastCloseTimestamp);
|
||||
|
|
|
@ -25,16 +25,16 @@ namespace ln.types.odb.ng.index
|
|||
public abstract bool Ensure(Path path);
|
||||
public abstract bool Indexed(Path path);
|
||||
|
||||
public virtual void Replace(Guid documentID, ODBValue value)
|
||||
public virtual void Replace(Guid documentID, ODBEntity value)
|
||||
{
|
||||
Remove(documentID);
|
||||
Add(documentID, value);
|
||||
}
|
||||
public abstract void Add(Guid documentID, ODBValue value);
|
||||
public abstract void Add(Guid documentID, ODBEntity value);
|
||||
public abstract void Remove(Guid documentID);
|
||||
|
||||
public abstract IEnumerable<Guid> GetDocumentIDs(Path path, Predicate<ODBValue> predicate);
|
||||
public virtual IEnumerable<Guid> GetDocumentIDs(string path, Predicate<ODBValue> predicate)
|
||||
public abstract IEnumerable<Guid> GetDocumentIDs(Path path, Predicate<ODBEntity> predicate);
|
||||
public virtual IEnumerable<Guid> GetDocumentIDs(string path, Predicate<ODBEntity> predicate)
|
||||
{
|
||||
return GetDocumentIDs(SplitPath(path), predicate);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ namespace ln.types.odb.ng.index
|
|||
{
|
||||
}
|
||||
|
||||
public override IEnumerable<Guid> GetDocumentIDs(Path path, Predicate<ODBValue> predicate)
|
||||
public override IEnumerable<Guid> GetDocumentIDs(Path path, Predicate<ODBEntity> predicate)
|
||||
{
|
||||
return children[path.Element].GetDocumentIDs(path.Next, predicate);
|
||||
}
|
||||
|
@ -72,14 +72,14 @@ namespace ln.types.odb.ng.index
|
|||
next.Remove(documentID);
|
||||
}
|
||||
|
||||
public override void Add(Guid documentID, ODBValue value)
|
||||
public override void Add(Guid documentID, ODBEntity value)
|
||||
{
|
||||
foreach (string childName in children.Keys)
|
||||
{
|
||||
children[childName].Add(documentID, (value as Document)[childName]);
|
||||
}
|
||||
}
|
||||
public override void Replace(Guid documentID, ODBValue value)
|
||||
public override void Replace(Guid documentID, ODBEntity value)
|
||||
{
|
||||
foreach (string childName in children.Keys)
|
||||
{
|
||||
|
@ -126,7 +126,7 @@ namespace ln.types.odb.ng.index
|
|||
}
|
||||
|
||||
|
||||
public override IEnumerable<Guid> GetDocumentIDs(Path path, Predicate<ODBValue> predicate)
|
||||
public override IEnumerable<Guid> GetDocumentIDs(Path path, Predicate<ODBEntity> predicate)
|
||||
{
|
||||
return nextPath.GetDocumentIDs(path.Next, predicate);
|
||||
}
|
||||
|
@ -135,10 +135,10 @@ namespace ln.types.odb.ng.index
|
|||
{
|
||||
nextPath.Remove(documentID);
|
||||
}
|
||||
public override void Add(Guid documentID, ODBValue value)
|
||||
public override void Add(Guid documentID, ODBEntity value)
|
||||
{
|
||||
if (!ODBNull.Instance.Equals(value))
|
||||
foreach (ODBValue v in ((ODBList)value))
|
||||
foreach (ODBEntity v in ((ODBList)value))
|
||||
{
|
||||
nextPath.Add(documentID, v);
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ namespace ln.types.odb.ng.index
|
|||
|
||||
public override bool Indexed(Path path) => true;
|
||||
|
||||
public override IEnumerable<Guid> GetDocumentIDs(Path path, Predicate<ODBValue> predicate)
|
||||
public override IEnumerable<Guid> GetDocumentIDs(Path path, Predicate<ODBEntity> predicate)
|
||||
{
|
||||
return index.GetDocumentIDs(predicate);
|
||||
}
|
||||
|
@ -169,11 +169,11 @@ namespace ln.types.odb.ng.index
|
|||
index.Remove(documentID);
|
||||
}
|
||||
|
||||
public override void Add(Guid documentID, ODBValue value)
|
||||
public override void Add(Guid documentID, ODBEntity value)
|
||||
{
|
||||
index.Add(documentID, value);
|
||||
}
|
||||
public override void Replace(Guid documentID, ODBValue value)
|
||||
public override void Replace(Guid documentID, ODBEntity value)
|
||||
{
|
||||
index.Replace(documentID, value);
|
||||
}
|
||||
|
|
|
@ -10,18 +10,18 @@ namespace ln.types.odb.ng.index
|
|||
{
|
||||
public class SimpleIndex : Index
|
||||
{
|
||||
BTreeValueList<ODBValue, Guid> valueIndex = new BTreeValueList<ODBValue, Guid>();
|
||||
BTreeValueList<Guid, ODBValue> reverseIndex = new BTreeValueList<Guid, ODBValue>();
|
||||
BTreeValueList<ODBEntity, Guid> valueIndex = new BTreeValueList<ODBEntity, Guid>();
|
||||
BTreeValueList<Guid, ODBEntity> reverseIndex = new BTreeValueList<Guid, ODBEntity>();
|
||||
|
||||
public SimpleIndex(Path path)
|
||||
: base(path)
|
||||
{
|
||||
}
|
||||
|
||||
public override IEnumerable<Guid> GetDocumentIDs(Predicate<ODBValue> predicate)
|
||||
public override IEnumerable<Guid> GetDocumentIDs(Predicate<ODBEntity> predicate)
|
||||
{
|
||||
HashSet<Guid> matchedIDs = new HashSet<Guid>();
|
||||
foreach (ODBValue value in valueIndex.Keys)
|
||||
foreach (ODBEntity value in valueIndex.Keys)
|
||||
{
|
||||
if (predicate(value))
|
||||
foreach (Guid id in valueIndex[value])
|
||||
|
@ -30,7 +30,7 @@ namespace ln.types.odb.ng.index
|
|||
return matchedIDs;
|
||||
}
|
||||
|
||||
public override void Add(Guid documentID, ODBValue value)
|
||||
public override void Add(Guid documentID, ODBEntity value)
|
||||
{
|
||||
valueIndex.Add(value, documentID);
|
||||
reverseIndex.Add(documentID, value);
|
||||
|
@ -40,7 +40,7 @@ namespace ln.types.odb.ng.index
|
|||
{
|
||||
if (reverseIndex.ContainsKey(documentID))
|
||||
{
|
||||
foreach (ODBValue value in reverseIndex[documentID].ToArray())
|
||||
foreach (ODBEntity value in reverseIndex[documentID].ToArray())
|
||||
{
|
||||
valueIndex.Remove(value, documentID);
|
||||
}
|
||||
|
@ -54,9 +54,9 @@ namespace ln.types.odb.ng.index
|
|||
using (FileStream fileStream = new FileStream(System.IO.Path.Combine(basePath, String.Format("{0}.idx", IndexName)), FileMode.Open))
|
||||
{
|
||||
byte[] indexBytes = fileStream.ReadBytes((int)fileStream.Length);
|
||||
Document indexDocument = new Document(Guid.Empty, indexBytes, 16, indexBytes.Length - 16);
|
||||
Document indexDocument = new Document(indexBytes, 16, indexBytes.Length - 16);
|
||||
|
||||
long idxLastCloseTimestamp = indexDocument["LastCloseTimestamp"].AsLong;
|
||||
long idxLastCloseTimestamp = indexDocument["LastCloseTimestamp"].As<long>();
|
||||
if (idxLastCloseTimestamp != lastCloseTimestamp)
|
||||
{
|
||||
Logging.Log(LogLevel.WARNING, "Index timestamp {0} is not matching ( {1} != {2} )", IndexName, idxLastCloseTimestamp, lastCloseTimestamp);
|
||||
|
@ -64,13 +64,13 @@ namespace ln.types.odb.ng.index
|
|||
}
|
||||
else
|
||||
{
|
||||
foreach (ODBValue key in indexDocument.Keys)
|
||||
foreach (ODBEntity key in indexDocument.Keys)
|
||||
{
|
||||
if (key is ODBGuid)
|
||||
{
|
||||
Guid documentID = key.AsGuid;
|
||||
Guid documentID = key.As<Guid>();
|
||||
ODBList valueList = indexDocument[key] as ODBList;
|
||||
foreach (ODBValue value in valueList)
|
||||
foreach (ODBEntity value in valueList)
|
||||
{
|
||||
Add(documentID, value);
|
||||
}
|
||||
|
@ -85,16 +85,16 @@ namespace ln.types.odb.ng.index
|
|||
public override bool SaveIndex(string basePath, long lastCloseTimestamp)
|
||||
{
|
||||
Document indexDocument = new Document();
|
||||
indexDocument["LastCloseTimestamp"] = lastCloseTimestamp;
|
||||
indexDocument["LastCloseTimestamp"] = new ODBLong(lastCloseTimestamp);
|
||||
|
||||
foreach (Guid documentID in reverseIndex.Keys)
|
||||
{
|
||||
ODBList valueList = new ODBList();
|
||||
valueList.AddRange(reverseIndex[documentID]);
|
||||
indexDocument[documentID] = valueList;
|
||||
indexDocument[new ODBGuid(documentID)] = valueList;
|
||||
}
|
||||
|
||||
byte[] indexBytes = indexDocument.ToStorage();
|
||||
byte[] indexBytes = indexDocument.GetStorageBytes();
|
||||
|
||||
using (FileStream fileStream = new FileStream(System.IO.Path.Combine(basePath, String.Format("{0}.idx", IndexName)), FileMode.Create))
|
||||
{
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace ln.types.odb.ng.mappings
|
|||
return false;
|
||||
}
|
||||
|
||||
public object UnmapValue(Mapper mapper,ODBValue oval)
|
||||
public object UnmapValue(Mapper mapper,ODBEntity oval)
|
||||
{
|
||||
Document document = oval as Document;
|
||||
object o = Activator.CreateInstance(MappedType, true);
|
||||
|
@ -107,13 +107,13 @@ namespace ln.types.odb.ng.mappings
|
|||
public Document MapDocument(Mapper mapper,Guid documentID,object value)
|
||||
{
|
||||
Document document = new Document(documentID);
|
||||
document["__asm__"] = value.GetType().Assembly.GetName().Name;
|
||||
document["__type__"] = value.GetType().FullName;
|
||||
document["__asm__"] = new ODBStringValue(value.GetType().Assembly.GetName().Name);
|
||||
document["__type__"] = new ODBStringValue(value.GetType().FullName);
|
||||
|
||||
foreach (FieldInfo fieldInfo in mappedFields)
|
||||
{
|
||||
object fv = fieldInfo.GetValue(value);
|
||||
ODBValue ov = null;
|
||||
ODBEntity ov = null;
|
||||
|
||||
if (false) //(fieldInfo.GetCustomAttribute<ByReferenceAttribute>() != null)
|
||||
{
|
||||
|
@ -135,7 +135,7 @@ namespace ln.types.odb.ng.mappings
|
|||
return document;
|
||||
}
|
||||
|
||||
public ODBValue MapValue(Mapper mapper,object value)
|
||||
public ODBEntity MapValue(Mapper mapper,object value)
|
||||
{
|
||||
if (Object.ReferenceEquals(value, null))
|
||||
return ODBNull.Instance;
|
||||
|
@ -157,20 +157,20 @@ namespace ln.types.odb.ng.mappings
|
|||
public class ObjectMapping : IODBMapping
|
||||
{
|
||||
|
||||
public ODBValue MapValue(Mapper mapper, object value)
|
||||
public ODBEntity MapValue(Mapper mapper, object value)
|
||||
{
|
||||
return new Document();
|
||||
}
|
||||
|
||||
public object UnmapValue(Mapper mapper, ODBValue oval)
|
||||
public object UnmapValue(Mapper mapper, ODBEntity oval)
|
||||
{
|
||||
if (oval is Document)
|
||||
{
|
||||
Document document = oval as Document;
|
||||
if (!document.Contains("__type__"))
|
||||
if (!document.Contains(new ODBStringValue("__type__")))
|
||||
return new object();
|
||||
|
||||
Type dType = Type.GetType(String.Format("{0}, {1}",document["__type__"].AsString, document["__asm__"].AsString)); //Assembly.Load(document["__asm__"].AsString).GetType(document["__type__"].AsString);
|
||||
Type dType = Type.GetType(String.Format("{0}, {1}",document["__type__"].As<String>(), document["__asm__"].As<String>()));
|
||||
return mapper.UnmapValue(dType, oval);
|
||||
} else if (oval is ODBList)
|
||||
{
|
||||
|
@ -220,10 +220,12 @@ namespace ln.types.odb.ng.mappings
|
|||
|
||||
return array;
|
||||
}
|
||||
else
|
||||
else if (oval is ODBValue)
|
||||
{
|
||||
return oval.Value;
|
||||
return (oval as ODBValue).Value;
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace ln.types.odb.ng.mappings
|
|||
{
|
||||
}
|
||||
|
||||
public ODBValue MapValue(Mapper mapper, object value)
|
||||
public ODBEntity MapValue(Mapper mapper, object value)
|
||||
{
|
||||
Type dType = value.GetType();
|
||||
|
||||
|
@ -22,8 +22,8 @@ namespace ln.types.odb.ng.mappings
|
|||
IDictionary dictionary = value as IDictionary;
|
||||
Document document = new Document();
|
||||
|
||||
document["__asm__"] = value.GetType().Assembly.GetName().Name;
|
||||
document["__type__"] = value.GetType().FullName;
|
||||
document["__asm__"] = new ODBStringValue(value.GetType().Assembly.GetName().Name);
|
||||
document["__type__"] = new ODBStringValue(value.GetType().FullName);
|
||||
|
||||
Document kTypes = new Document();
|
||||
Document vTypes = new Document();
|
||||
|
@ -34,21 +34,21 @@ namespace ln.types.odb.ng.mappings
|
|||
foreach (object key in dictionary.Keys)
|
||||
{
|
||||
object v = dictionary[key];
|
||||
ODBValue okey = mapper.MapValue(key);
|
||||
ODBEntity okey = mapper.MapValue(key);
|
||||
|
||||
document[okey] = mapper.MapValue(v);
|
||||
kTypes[okey] = Mapper.GetTypeName(key?.GetType());
|
||||
vTypes[okey] = Mapper.GetTypeName(v?.GetType());
|
||||
kTypes[okey] = new ODBStringValue(Mapper.GetTypeName(key?.GetType()));
|
||||
vTypes[okey] = new ODBStringValue(Mapper.GetTypeName(v?.GetType()));
|
||||
}
|
||||
return document;
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public object UnmapValue(Mapper mapper, ODBValue oval)
|
||||
public object UnmapValue(Mapper mapper, ODBEntity oval)
|
||||
{
|
||||
Document document = oval as Document;
|
||||
Type dType = Type.GetType(String.Format("{0}, {1}",document["__type__"].AsString,document["__asm__"].AsString)); //;Assembly.Load(document["__asm__"].AsString).GetType(document["__type__"].AsString);
|
||||
Type dType = Type.GetType(String.Format("{0}, {1}",document["__type__"].As<String>(),document["__asm__"].As<String>())); //;Assembly.Load(document["__asm__"].AsString).GetType(document["__type__"].AsString);
|
||||
|
||||
if (dType.IsGenericType)
|
||||
{
|
||||
|
@ -62,13 +62,13 @@ namespace ln.types.odb.ng.mappings
|
|||
Document ktypes = document.Contains("__ktypes__") ? document["__ktypes__"] as Document : new Document();
|
||||
Document vtypes = document.Contains("__vtypes__") ? document["__vtypes__"] as Document : new Document();
|
||||
|
||||
foreach (ODBValue key in document.Keys)
|
||||
foreach (ODBEntity key in document.Keys)
|
||||
{
|
||||
string skey = key.AsString;
|
||||
string skey = key.As<String>();
|
||||
if (!skey.StartsWith("__", StringComparison.InvariantCulture) || !skey.EndsWith("__",StringComparison.InvariantCulture))
|
||||
{
|
||||
Type kt = ktypes.Contains(key) ? Type.GetType(ktypes[key].AsString) : kType;
|
||||
Type vt = vtypes.Contains(key) ? Type.GetType(vtypes[key].AsString) : vType;
|
||||
Type kt = ktypes.Contains(key) ? Type.GetType(ktypes[key].As<String>()) : kType;
|
||||
Type vt = vtypes.Contains(key) ? Type.GetType(vtypes[key].As<String>()) : vType;
|
||||
|
||||
dictionary.Add(mapper.UnmapValue(kt, key), mapper.UnmapValue(vt, document[key]));
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace ln.types.odb.ng.mappings
|
|||
return list;
|
||||
}
|
||||
|
||||
public object UnmapValue(Mapper mapper, ODBValue oval)
|
||||
public object UnmapValue(Mapper mapper, ODBEntity oval)
|
||||
{
|
||||
if (TargetType.IsArray)
|
||||
return UnmapArray(mapper, (ODBList)oval);
|
||||
|
@ -97,7 +97,7 @@ namespace ln.types.odb.ng.mappings
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ODBValue MapValue(Mapper mapper, object value)
|
||||
public ODBEntity MapValue(Mapper mapper, object value)
|
||||
{
|
||||
if (TargetType.IsArray)
|
||||
return MapArray(mapper, (Array)value);
|
||||
|
@ -131,7 +131,7 @@ namespace ln.types.odb.ng.mappings
|
|||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
foreach (ODBValue item in list)
|
||||
foreach (ODBEntity item in list)
|
||||
yield return (T)mapper.UnmapValue(TargetType, item);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,12 +13,12 @@ namespace ln.types.odb.ng.mappings
|
|||
this.unmap = unmap;
|
||||
}
|
||||
|
||||
public ODBValue MapValue(Mapper mapper, object value)
|
||||
public ODBEntity MapValue(Mapper mapper, object value)
|
||||
{
|
||||
return map(mapper, value);
|
||||
}
|
||||
|
||||
public object UnmapValue(Mapper mapper, ODBValue oval)
|
||||
public object UnmapValue(Mapper mapper, ODBEntity oval)
|
||||
{
|
||||
return unmap(mapper, oval);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace ln.types.odb.ng.storage
|
|||
|
||||
bool Contains(Guid documentID);
|
||||
IEnumerable<Guid> GetDocumentIDs();
|
||||
IEnumerable<Guid> GetDocumentIDs(string path,Predicate<ODBValue> predicate);
|
||||
IEnumerable<Guid> GetDocumentIDs(string path,Predicate<ODBEntity> predicate);
|
||||
DateTime GetStorageTimestamp(Guid documentID);
|
||||
|
||||
void EnsureIndex(params string[] path);
|
||||
|
|
|
@ -78,9 +78,9 @@ namespace ln.types.odb.ng.storage
|
|||
freeAreas.Add(fileArea);
|
||||
}
|
||||
}
|
||||
public OrganizedFileArea Store(ODBValue value)
|
||||
public OrganizedFileArea Store(ODBEntity value)
|
||||
{
|
||||
byte[] storageBytes = value.ToStorage();
|
||||
byte[] storageBytes = value.GetStorageBytes();
|
||||
return Store(storageBytes);
|
||||
}
|
||||
public OrganizedFileArea Store(byte[] bytes)
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace ln.types.odb.ng.storage.bases
|
|||
return Storage.GetDocumentIDs();
|
||||
}
|
||||
|
||||
public virtual IEnumerable<Guid> GetDocumentIDs(string path, Predicate<ODBValue> predicate)
|
||||
public virtual IEnumerable<Guid> GetDocumentIDs(string path, Predicate<ODBEntity> predicate)
|
||||
{
|
||||
return Storage.GetDocumentIDs(path, predicate);
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ namespace ln.types.odb.ng.storage.bases
|
|||
|
||||
/* Enumeration */
|
||||
public abstract IEnumerable<Guid> GetDocumentIDs();
|
||||
public abstract IEnumerable<Guid> GetDocumentIDs(string path, Predicate<ODBValue> predicate);
|
||||
public abstract IEnumerable<Guid> GetDocumentIDs(string path, Predicate<ODBEntity> predicate);
|
||||
|
||||
/* Indeces */
|
||||
public abstract void EnsureIndex(params string[] path);
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace ln.types.odb.ng.storage.cache
|
|||
|
||||
public override void EnsureIndex(params string[] path) => storage.EnsureIndex(path);
|
||||
public override IEnumerable<Guid> GetDocumentIDs() => storage.GetDocumentIDs();
|
||||
public override IEnumerable<Guid> GetDocumentIDs(string path, Predicate<ODBValue> predicate) => storage.GetDocumentIDs(path, predicate);
|
||||
public override IEnumerable<Guid> GetDocumentIDs(string path, Predicate<ODBEntity> predicate) => storage.GetDocumentIDs(path, predicate);
|
||||
|
||||
public override Document Load(Guid documentID)
|
||||
{
|
||||
|
|
|
@ -119,9 +119,9 @@ namespace ln.types.odb.ng.storage
|
|||
byte[] indexLstBytes = indexLst.ReadBytes((int)indexLst.Length);
|
||||
ODBList idxList = new ODBList(indexLstBytes, 0, indexLstBytes.Length);
|
||||
|
||||
foreach (ODBValue indexName in idxList)
|
||||
foreach (ODBEntity indexName in idxList)
|
||||
{
|
||||
indexRoot.Ensure(IndexPath.SplitPath(indexName.AsString));
|
||||
indexRoot.Ensure(IndexPath.SplitPath(indexName.As<String>()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,10 +165,10 @@ namespace ln.types.odb.ng.storage
|
|||
}
|
||||
|
||||
ODBList indexList = new ODBList();
|
||||
indexList.AddRange(indexNames.Select((x) => ODBValue.FromNative(x)));
|
||||
indexList.AddRange(indexNames.Select((x) => ODBEntity.FromNative(x)));
|
||||
|
||||
FileStream indexLst = new FileStream(System.IO.Path.Combine(StoragePath, "indeces.lst"), FileMode.Create);
|
||||
indexLst.WriteBytes(indexList.ToStorage());
|
||||
indexLst.WriteBytes(indexList.GetStorageBytes());
|
||||
indexLst.Close();
|
||||
indexLst.Dispose();
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ namespace ln.types.odb.ng.storage
|
|||
|
||||
try
|
||||
{
|
||||
return new Document(segment.ID, storageBytes) { StorageTimeStamp = segment.TimeStamp, };
|
||||
return new Document(storageBytes) { StorageTimeStamp = segment.TimeStamp, };
|
||||
} catch (Exception e)
|
||||
{
|
||||
Logging.Log(LogLevel.DEBUG, "Exception while Deserializing Document from FSStorage: {1} ID={0}",segment.ID,StoragePath);
|
||||
|
@ -220,7 +220,7 @@ namespace ln.types.odb.ng.storage
|
|||
if (GetDocumentLocked(document.ID))
|
||||
throw new LockingException();
|
||||
|
||||
byte[] storageBytes = document.ToStorage();
|
||||
byte[] storageBytes = document.GetStorageBytes();
|
||||
|
||||
SegmentedFile.Segment segment = PopUnusedSegment(storageBytes.Length);
|
||||
if (segment == null)
|
||||
|
@ -299,7 +299,7 @@ namespace ln.types.odb.ng.storage
|
|||
return default(DateTime);
|
||||
}
|
||||
|
||||
public override IEnumerable<Guid> GetDocumentIDs(string path, Predicate<ODBValue> predicate)
|
||||
public override IEnumerable<Guid> GetDocumentIDs(string path, Predicate<ODBEntity> predicate)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
|
|
|
@ -8,39 +8,36 @@
|
|||
// *
|
||||
// **/
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
namespace ln.types.odb.values
|
||||
{
|
||||
public class ODBBool : ODBValue
|
||||
{
|
||||
public override int CompareLevel => 254;
|
||||
public static ODBBool True = new ODBBool(true);
|
||||
public static ODBBool False = new ODBBool(false);
|
||||
|
||||
public ODBBool()
|
||||
:base(0x04)
|
||||
{}
|
||||
bool isTrue;
|
||||
|
||||
public ODBBool(bool b)
|
||||
:this()
|
||||
private ODBBool(bool b)
|
||||
:base(0x04,b)
|
||||
{
|
||||
Value = b;
|
||||
isTrue = b;
|
||||
}
|
||||
|
||||
public override byte[] ToStorage()
|
||||
{
|
||||
return new byte[] { AsBool ? (byte)0xFF : (byte)0x00 };
|
||||
}
|
||||
public override byte[] GetStorageBytes() => new byte[] { isTrue ? (byte)0xFF : (byte)0x00 };
|
||||
|
||||
public override int CompareInType(ODBValue other)
|
||||
protected override int compare(ODBEntity other)
|
||||
{
|
||||
if (AsBool == other.AsBool)
|
||||
if (Object.ReferenceEquals(this,other))
|
||||
return 0;
|
||||
if (AsBool)
|
||||
if (isTrue)
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static ODBBool()
|
||||
{
|
||||
RegisterDeserializer(0x04, (b, o, l) => new ODBBool(b[o] != 0));
|
||||
RegisterDeserializer(0x04, (b, o, l) => (b[o] != 0) ? True : False);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,27 +3,15 @@ namespace ln.types.odb.values
|
|||
{
|
||||
public class ODBDouble : ODBValue
|
||||
{
|
||||
public override int CompareLevel => 2;
|
||||
|
||||
public ODBDouble()
|
||||
:base(0x18)
|
||||
{
|
||||
}
|
||||
public ODBDouble(double value)
|
||||
: this()
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
:base(0x18,value)
|
||||
{}
|
||||
|
||||
public override byte[] ToStorage()
|
||||
public override byte[] GetStorageBytes() => BitConverter.GetBytes((double)Value);
|
||||
protected override int compare(ODBEntity other)
|
||||
{
|
||||
return BitConverter.GetBytes(AsDouble);
|
||||
}
|
||||
|
||||
public override int CompareInType(ODBValue other)
|
||||
{
|
||||
double a = AsDouble;
|
||||
double b = other.AsDouble;
|
||||
double a = (double)Value;
|
||||
double b = (double)(other as ODBValue).Value;
|
||||
|
||||
if (Math.Abs(a - b) < double.Epsilon)
|
||||
return 0;
|
||||
|
@ -34,9 +22,7 @@ namespace ln.types.odb.values
|
|||
|
||||
static ODBDouble()
|
||||
{
|
||||
RegisterDeserializer(0x0018, (b, o, l) => BitConverter.ToDouble(b, o));
|
||||
//RegisterValueFactory(typeof(double), v => new ODBDouble((double)v));
|
||||
//RegisterValueFactory(typeof(float), v => new ODBDouble((double)v));
|
||||
RegisterDeserializer(0x0018, (b, o, l) => new ODBDouble(BitConverter.ToDouble(b, o)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using ln.types.odb.ng;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
/**
|
||||
* typeCode list
|
||||
*
|
||||
* 0x0000 ODBNull
|
||||
* 0x0001 ODBStringValue
|
||||
* 0x0002 ODBList
|
||||
* 0x0003 ODBGuid
|
||||
* 0x0004 ODBBool
|
||||
*
|
||||
* 0x0010 ODBInteger
|
||||
* 0x0011 ODBUInteger
|
||||
* 0x0012 ODBLong
|
||||
* 0x0013 ODBULong
|
||||
*
|
||||
* 0x0018 ODBDouble
|
||||
*
|
||||
* 0x0020 ODBTypedMapping
|
||||
*
|
||||
* 0x1000 ODBDocument
|
||||
* 0x1001 Document (ln.types.odb.ng)
|
||||
*
|
||||
*
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
|
||||
namespace ln.types.odb.values
|
||||
{
|
||||
public delegate ODBEntity ODBValueFactory(object value);
|
||||
public delegate ODBEntity ODBDeserialize(byte[] storageBytes, int offset, int length);
|
||||
|
||||
/// <summary>
|
||||
/// ODBEntity. The base of all ODB types.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
///
|
||||
/// </remarks>
|
||||
///
|
||||
public abstract class ODBEntity : IComparable<ODBEntity>
|
||||
{
|
||||
int storageTypeCode;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the identity of this Entity.
|
||||
/// </summary>
|
||||
/// <value>The identity.</value>
|
||||
public virtual ODBValue Identity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Return a .NET native value / object that semantically equals this ODBEntity instance.
|
||||
/// </summary>
|
||||
/// <returns>The native .NET value</returns>
|
||||
/// <typeparam name="T">The type to which this ODBEntity should be casted/converted.</typeparam>
|
||||
public abstract T As<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Independently clone this instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For immutable values this returns the instance itself.
|
||||
/// Complex ODBEntities will return a copy of themself that is completly independend of the source.
|
||||
/// </remarks>
|
||||
/// <returns>The clone.</returns>
|
||||
public abstract ODBEntity Clone();
|
||||
|
||||
/// <summary>
|
||||
/// Implements the internal comparison within the same subclass of ODBEntity.
|
||||
/// </summary>
|
||||
/// <returns>The compare.</returns>
|
||||
/// <param name="other">Other.</param>
|
||||
protected abstract int compare(ODBEntity other);
|
||||
|
||||
|
||||
|
||||
|
||||
protected ODBEntity(int storageTypeCode)
|
||||
{
|
||||
this.storageTypeCode = storageTypeCode;
|
||||
}
|
||||
|
||||
|
||||
public int CompareTo(ODBEntity other)
|
||||
{
|
||||
if (storageTypeCode != other.storageTypeCode)
|
||||
return storageTypeCode - other.storageTypeCode;
|
||||
return compare(other);
|
||||
}
|
||||
|
||||
public abstract byte[] GetStorageBytes();
|
||||
public virtual void Write(BinaryWriter storage)
|
||||
{
|
||||
byte[] storageBytes = GetStorageBytes();
|
||||
|
||||
storage.Write(storageTypeCode);
|
||||
storage.Write(storageBytes.Length);
|
||||
storage.Write(storageBytes, 0, storageBytes.Length);
|
||||
}
|
||||
|
||||
public override int GetHashCode() => Identity.GetHashCode();
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is ODBEntity)
|
||||
return Identity.Equals((obj as ODBEntity).Identity);
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual object As(Type targetType)
|
||||
{
|
||||
MethodInfo methodInfo = GetType().GetMethod("As");
|
||||
return methodInfo.MakeGenericMethod(targetType).Invoke(this, new object[0]);
|
||||
}
|
||||
|
||||
public static bool operator <(ODBEntity a, ODBEntity b) => a.CompareTo(b) < 0;
|
||||
public static bool operator >(ODBEntity a, ODBEntity b) => a.CompareTo(b) > 0;
|
||||
public static bool operator <=(ODBEntity a, ODBEntity b) => a.CompareTo(b) <= 0;
|
||||
public static bool operator >=(ODBEntity a, ODBEntity b) => a.CompareTo(b) >= 0;
|
||||
public static bool operator ==(ODBEntity a, ODBEntity b) => (a is null) ? b is null : a.CompareTo(b) == 0;
|
||||
public static bool operator !=(ODBEntity a, ODBEntity b) => (a is null) ? !(b is null) : a.CompareTo(b) != 0;
|
||||
|
||||
//public static implicit operator ODBEntity(ValueType v)
|
||||
//{
|
||||
// return Mapper.Default.MapValue(v);
|
||||
//}
|
||||
//public static implicit operator ODBEntity(String v)
|
||||
//{
|
||||
// return Mapper.Default.MapValue(v);
|
||||
//}
|
||||
|
||||
public static ODBEntity FromNative(object v)
|
||||
{
|
||||
return Mapper.Default.MapValue(v);
|
||||
}
|
||||
|
||||
static Dictionary<int, ODBDeserialize> valueDeserializers = new Dictionary<int, ODBDeserialize>();
|
||||
public static void RegisterDeserializer(int storageTypeCode, ODBDeserialize deserialize)
|
||||
{
|
||||
valueDeserializers.Add(storageTypeCode, deserialize);
|
||||
}
|
||||
|
||||
public static ODBEntity Deserialize(byte[] buffer, ref int offset)
|
||||
{
|
||||
int storageTypeCode = BitConverter.ToInt32(buffer, offset);
|
||||
int storageLength = BitConverter.ToInt32(buffer, offset + 4);
|
||||
if (!valueDeserializers.ContainsKey(storageTypeCode))
|
||||
throw new KeyNotFoundException(String.Format("StorageTypeCode 0x{0:x8} at offset 0x{1:x8}",storageTypeCode,offset));
|
||||
|
||||
ODBEntity value = valueDeserializers[storageTypeCode](buffer, offset + 8, storageLength);
|
||||
offset += 8 + storageLength;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static ODBEntity Read(Stream stream)
|
||||
{
|
||||
int storageTypeCode = stream.ReadInteger();
|
||||
int storageLength = stream.ReadInteger();
|
||||
byte[] b = new byte[storageLength];
|
||||
stream.Read(b, 0, storageLength);
|
||||
|
||||
if (valueDeserializers.ContainsKey(storageTypeCode))
|
||||
return valueDeserializers[storageTypeCode](b, 0, storageLength);
|
||||
else
|
||||
throw new FormatException("wrong storage type code");
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("[{0} Identity={1}]", GetType().Name, Identity);
|
||||
}
|
||||
|
||||
static ODBEntity()
|
||||
{
|
||||
RuntimeHelpers.RunClassConstructor(typeof(ODBNull).TypeHandle);
|
||||
RuntimeHelpers.RunClassConstructor(typeof(Document).TypeHandle);
|
||||
RuntimeHelpers.RunClassConstructor(typeof(ODBList).TypeHandle);
|
||||
RuntimeHelpers.RunClassConstructor(typeof(ODBStringValue).TypeHandle);
|
||||
RuntimeHelpers.RunClassConstructor(typeof(ODBInteger).TypeHandle);
|
||||
RuntimeHelpers.RunClassConstructor(typeof(ODBUInteger).TypeHandle);
|
||||
RuntimeHelpers.RunClassConstructor(typeof(ODBLong).TypeHandle);
|
||||
RuntimeHelpers.RunClassConstructor(typeof(ODBULong).TypeHandle);
|
||||
RuntimeHelpers.RunClassConstructor(typeof(ODBDouble).TypeHandle);
|
||||
RuntimeHelpers.RunClassConstructor(typeof(ODBGuid).TypeHandle);
|
||||
RuntimeHelpers.RunClassConstructor(typeof(ODBBool).TypeHandle);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,39 +4,19 @@ namespace ln.types.odb.values
|
|||
{
|
||||
public class ODBGuid : ODBValue
|
||||
{
|
||||
public override int CompareLevel => 20;
|
||||
|
||||
public ODBGuid()
|
||||
:base(0x03)
|
||||
{
|
||||
Value = Guid.NewGuid();
|
||||
}
|
||||
:base(0x03, Guid.NewGuid())
|
||||
{}
|
||||
public ODBGuid(Guid guid)
|
||||
:this()
|
||||
{
|
||||
Value = guid;
|
||||
}
|
||||
:base(0x03,guid)
|
||||
{}
|
||||
|
||||
public override byte[] ToStorage()
|
||||
{
|
||||
return AsGuid.ToByteArray();
|
||||
}
|
||||
|
||||
static Guid FromByteArray(byte[] b,int offset)
|
||||
{
|
||||
byte[] s = new byte[16];
|
||||
Array.Copy(b, offset, s, 0, 16);
|
||||
return new Guid(s);
|
||||
}
|
||||
|
||||
public override int CompareInType(ODBValue other)
|
||||
{
|
||||
return AsGuid.CompareTo(other.AsGuid);
|
||||
}
|
||||
public override byte[] GetStorageBytes() => As<Guid>().ToByteArray();
|
||||
protected override int compare(ODBEntity other) => ((Guid)Value).CompareTo((other as ODBGuid).Value);
|
||||
|
||||
static ODBGuid()
|
||||
{
|
||||
RegisterDeserializer(0x03, (b,o,l) => FromByteArray(b,o));
|
||||
RegisterDeserializer(0x03, (b, o, l) => new ODBGuid(new Guid(b.Slice(o, 16))));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,55 +4,28 @@ namespace ln.types.odb.values
|
|||
{
|
||||
public class ODBInteger : ODBValue
|
||||
{
|
||||
public ODBInteger()
|
||||
: base(0x10)
|
||||
{
|
||||
}
|
||||
public ODBInteger(int i)
|
||||
: this()
|
||||
{
|
||||
Value = i;
|
||||
}
|
||||
|
||||
public override bool AsBool => AsInt != 0;
|
||||
|
||||
public override int CompareLevel => 0;
|
||||
|
||||
public override byte[] ToStorage() => BitConverter.GetBytes(AsInt);
|
||||
|
||||
public override int CompareInType(ODBValue other)
|
||||
{
|
||||
return AsInt - other.AsInt;
|
||||
}
|
||||
: base(0x10,i)
|
||||
{}
|
||||
public override byte[] GetStorageBytes() => BitConverter.GetBytes((int)Value);
|
||||
protected override int compare(ODBEntity other) => (int)Value - (int)(other as ODBValue).Value;
|
||||
|
||||
static ODBInteger()
|
||||
{
|
||||
RegisterDeserializer(0x10, (b, o, l) => BitConverter.ToInt32(b, o));
|
||||
//RegisterValueFactory(typeof(int), v => new ODBInteger((int)v));
|
||||
//RegisterValueFactory(typeof(short), v => new ODBInteger((int)(short)v));
|
||||
//RegisterValueFactory(typeof(byte), v => new ODBInteger((int)(byte)v));
|
||||
RegisterDeserializer(0x10, (b, o, l) => new ODBInteger(BitConverter.ToInt32(b, o)));
|
||||
}
|
||||
|
||||
}
|
||||
public class ODBUInteger : ODBValue
|
||||
{
|
||||
public override int CompareLevel => 5;
|
||||
|
||||
public ODBUInteger()
|
||||
: base(0x11)
|
||||
{
|
||||
}
|
||||
public ODBUInteger(uint i)
|
||||
: this()
|
||||
{
|
||||
Value = i;
|
||||
}
|
||||
: base(0x11,i)
|
||||
{}
|
||||
|
||||
public override byte[] ToStorage() => BitConverter.GetBytes(AsUInt);
|
||||
|
||||
public override int CompareInType(ODBValue other)
|
||||
public override byte[] GetStorageBytes() => BitConverter.GetBytes((uint)Value);
|
||||
protected override int compare(ODBEntity other)
|
||||
{
|
||||
long d = (long)AsUInt - (long)other.AsUInt;
|
||||
long d = (long)Value - (long)(other as ODBValue).Value;
|
||||
if (d == 0)
|
||||
return 0;
|
||||
if (d < 0)
|
||||
|
@ -62,10 +35,7 @@ namespace ln.types.odb.values
|
|||
|
||||
static ODBUInteger()
|
||||
{
|
||||
RegisterDeserializer(0x11, (b, o, l) => BitConverter.ToUInt32(b, o));
|
||||
//RegisterValueFactory(typeof(uint), v => new ODBUInteger((uint)v));
|
||||
//RegisterValueFactory(typeof(ushort), v => new ODBUInteger((uint)(ushort)v));
|
||||
//RegisterValueFactory(typeof(char), v => new ODBUInteger((uint)(char)v));
|
||||
RegisterDeserializer(0x11, (b, o, l) => new ODBUInteger(BitConverter.ToUInt32(b, o)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,11 +3,15 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Runtime.CompilerServices;
|
||||
using ln.types.odb.ng;
|
||||
namespace ln.types.odb.values
|
||||
{
|
||||
public class ODBList : ODBValue, IEnumerable<ODBValue>
|
||||
public class ODBList : ODBEntity, IEnumerable<ODBEntity>
|
||||
{
|
||||
List<ODBValue> items = new List<ODBValue>();
|
||||
Guid identity = Guid.NewGuid();
|
||||
public override ODBValue Identity => Identity;
|
||||
|
||||
List<ODBEntity> items = new List<ODBEntity>();
|
||||
|
||||
public ODBList()
|
||||
:base(0x02)
|
||||
|
@ -17,34 +21,36 @@ namespace ln.types.odb.values
|
|||
:this()
|
||||
{
|
||||
MemoryStream stream = new MemoryStream(bytes, offset, length);
|
||||
identity = new Guid(stream.ReadBytes(16));
|
||||
|
||||
int nItems = stream.ReadInteger();
|
||||
for (int n = 0; n < nItems; n++)
|
||||
items.Add(ODBValue.Read(stream));
|
||||
items.Add(ODBEntity.Read(stream));
|
||||
}
|
||||
|
||||
public ODBValue this[int i]
|
||||
public ODBEntity this[int i]
|
||||
{
|
||||
get => items[i];
|
||||
set => items[i] = value;
|
||||
}
|
||||
|
||||
public ODBValue this[ODBValue i]
|
||||
public ODBEntity this[ODBEntity i]
|
||||
{
|
||||
get => items[i.AsInt];
|
||||
set => items[i.AsInt] = value;
|
||||
get => items[i.As<int>()];
|
||||
set => items[i.As<int>()] = value;
|
||||
}
|
||||
|
||||
public void AddRange(IEnumerable<ODBValue> values)
|
||||
public void AddRange(IEnumerable<ODBEntity> values)
|
||||
{
|
||||
foreach (ODBValue value in values)
|
||||
foreach (ODBEntity value in values)
|
||||
Add(value);
|
||||
}
|
||||
|
||||
public void Add(ODBValue value)
|
||||
public void Add(ODBEntity value)
|
||||
{
|
||||
items.Add(value);
|
||||
}
|
||||
public void Remove(ODBValue value)
|
||||
public void Remove(ODBEntity value)
|
||||
{
|
||||
items.Remove(value);
|
||||
}
|
||||
|
@ -55,42 +61,32 @@ namespace ln.types.odb.values
|
|||
|
||||
public int Count => items.Count;
|
||||
|
||||
public override ODBValue Clone()
|
||||
public override ODBEntity Clone()
|
||||
{
|
||||
ODBList clone = new ODBList();
|
||||
clone.items.AddRange(this.items);
|
||||
return clone;
|
||||
clone.identity = identity;
|
||||
|
||||
foreach (ODBEntity item in items)
|
||||
clone.items.Add(item.Clone());
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
public override object Value {
|
||||
get
|
||||
{
|
||||
object[] a = new object[items.Count];
|
||||
((IList)items).CopyTo(a, 0);
|
||||
return a;
|
||||
}
|
||||
protected set
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override int CompareLevel => 253;
|
||||
|
||||
public override byte[] ToStorage()
|
||||
public override byte[] GetStorageBytes()
|
||||
{
|
||||
MemoryStream stream = new MemoryStream();
|
||||
BinaryWriter writer = new BinaryWriter(stream);
|
||||
|
||||
writer.Write(identity.ToByteArray());
|
||||
writer.Write(items.Count);
|
||||
|
||||
foreach (ODBValue value in items)
|
||||
value.Store(writer);
|
||||
foreach (ODBEntity value in items)
|
||||
value.Write(writer);
|
||||
|
||||
return stream.ToArray();
|
||||
}
|
||||
|
||||
public override int CompareInType(ODBValue other)
|
||||
protected override int compare(ODBEntity other)
|
||||
{
|
||||
ODBList you = other as ODBList;
|
||||
|
||||
|
@ -107,24 +103,7 @@ namespace ln.types.odb.values
|
|||
return 0;
|
||||
}
|
||||
|
||||
public override bool ValueEquals(ODBValue other)
|
||||
{
|
||||
if (other is ODBList)
|
||||
{
|
||||
ODBList you = other as ODBList;
|
||||
if (Count != you.Count)
|
||||
return false;
|
||||
|
||||
for (int n = 0; n < Count; n++)
|
||||
if (!this[n].ValueEquals(you[n]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public IEnumerator<ODBValue> GetEnumerator()
|
||||
public IEnumerator<ODBEntity> GetEnumerator()
|
||||
{
|
||||
return items.GetEnumerator();
|
||||
}
|
||||
|
@ -134,6 +113,8 @@ namespace ln.types.odb.values
|
|||
return items.GetEnumerator();
|
||||
}
|
||||
|
||||
public override T As<T>() => (T)Mapper.Default.UnmapValue(typeof(T), this);
|
||||
|
||||
static ODBList()
|
||||
{
|
||||
RegisterDeserializer(0x02, (b, o, l) => new ODBList(b,o,l));
|
||||
|
|
|
@ -4,23 +4,17 @@ namespace ln.types.odb.values
|
|||
{
|
||||
public class ODBLong : ODBValue
|
||||
{
|
||||
public ODBLong()
|
||||
: base(0x12)
|
||||
{
|
||||
}
|
||||
public ODBLong(long i)
|
||||
: this()
|
||||
{
|
||||
Value = i;
|
||||
}
|
||||
public ODBLong(long value)
|
||||
: base(0x12, value)
|
||||
{}
|
||||
|
||||
public override byte[] ToStorage() => BitConverter.GetBytes(AsLong);
|
||||
public override byte[] GetStorageBytes() => BitConverter.GetBytes(As<long>());
|
||||
|
||||
public override int CompareInType(ODBValue other)
|
||||
protected override int compare(ODBEntity other)
|
||||
{
|
||||
long a, b;
|
||||
a = AsLong;
|
||||
b = other.AsLong;
|
||||
a = (long)Value;
|
||||
b = (long)(other as ODBValue).Value;
|
||||
|
||||
long d = a - b;
|
||||
if (d == 0)
|
||||
|
@ -30,39 +24,28 @@ namespace ln.types.odb.values
|
|||
return 1;
|
||||
}
|
||||
|
||||
public override DateTime AsDateTime => DateTimeOffset.FromUnixTimeMilliseconds(AsLong).DateTime;
|
||||
public override TimeSpan AsTimeSpan => TimeSpan.FromMilliseconds(AsDouble);
|
||||
public static implicit operator DateTime(ODBLong l) => DateTimeOffset.FromUnixTimeMilliseconds((long)l.Value).DateTime;
|
||||
public static implicit operator TimeSpan(ODBLong l) => TimeSpan.FromMilliseconds((long)l.Value);
|
||||
|
||||
public override int CompareLevel => 1;
|
||||
|
||||
static ODBLong()
|
||||
{
|
||||
RegisterDeserializer(0x12, (b, o, l) => BitConverter.ToInt64(b, o));
|
||||
//RegisterValueFactory(typeof(long), v => new ODBLong((long)v));
|
||||
//RegisterValueFactory(typeof(DateTime), v => new ODBLong(new DateTimeOffset((DateTime)v).ToUnixTimeMilliseconds()));
|
||||
RegisterDeserializer(0x12, (b, o, l) => new ODBLong(BitConverter.ToInt64(b, o)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class ODBULong : ODBValue
|
||||
{
|
||||
public override int CompareLevel => 6;
|
||||
public ODBULong(ulong value)
|
||||
: base(0x13,value)
|
||||
{}
|
||||
|
||||
public ODBULong()
|
||||
: base(0x13)
|
||||
public override byte[] GetStorageBytes() => BitConverter.GetBytes(As<ulong>());
|
||||
protected override int compare(ODBEntity other)
|
||||
{
|
||||
}
|
||||
public ODBULong(ulong i)
|
||||
: this()
|
||||
{
|
||||
Value = i;
|
||||
}
|
||||
|
||||
public override byte[] ToStorage() => BitConverter.GetBytes(AsULong);
|
||||
|
||||
public override int CompareInType(ODBValue other)
|
||||
{
|
||||
ulong a = AsULong;
|
||||
ulong b = other.AsULong;
|
||||
ulong a = (ulong)Value;
|
||||
ulong b = (ulong)(other as ODBValue).Value;
|
||||
|
||||
if (a == b)
|
||||
return 0;
|
||||
|
@ -73,8 +56,7 @@ namespace ln.types.odb.values
|
|||
|
||||
static ODBULong()
|
||||
{
|
||||
RegisterDeserializer(0x13, (b, o, l) => BitConverter.ToUInt64(b, o));
|
||||
//RegisterValueFactory(typeof(ulong), v => new ODBULong((ulong)v));
|
||||
RegisterDeserializer(0x13, (b, o, l) => new ODBULong(BitConverter.ToUInt64(b, o)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,34 +6,19 @@ namespace ln.types.odb.values
|
|||
{
|
||||
public static readonly ODBNull Instance = new ODBNull();
|
||||
|
||||
public override int CompareLevel => 255;
|
||||
private ODBNull()
|
||||
: base(0x00,null)
|
||||
{}
|
||||
|
||||
public ODBNull()
|
||||
: base(0x00)
|
||||
{ }
|
||||
public override byte[] GetStorageBytes() => new byte[0];
|
||||
protected override int compare(ODBEntity other) => 0;
|
||||
|
||||
public override byte[] ToStorage()
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
public override int GetHashCode() => 0;
|
||||
public override bool Equals(object obj) => Object.ReferenceEquals(this, obj);
|
||||
|
||||
static ODBNull()
|
||||
{
|
||||
RegisterDeserializer(0x00, (b,o,l) => Instance);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return (object.ReferenceEquals(obj,null)) || (obj is ODBNull);
|
||||
}
|
||||
|
||||
public override int CompareInType(ODBValue other)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,39 +5,17 @@ namespace ln.types.odb.values
|
|||
{
|
||||
public class ODBStringValue : ODBValue
|
||||
{
|
||||
public override int CompareLevel => 10;
|
||||
|
||||
public ODBStringValue()
|
||||
: base(0x01)
|
||||
{ }
|
||||
|
||||
public ODBStringValue(String text)
|
||||
: this()
|
||||
{
|
||||
Value = text;
|
||||
}
|
||||
|
||||
public override byte[] ToStorage()
|
||||
{
|
||||
return Encoding.UTF8.GetBytes(AsString);
|
||||
}
|
||||
|
||||
public override int CompareInType(ODBValue other)
|
||||
{
|
||||
return AsString.CompareTo(other.AsString);
|
||||
}
|
||||
|
||||
public static implicit operator ODBStringValue(String text)
|
||||
{
|
||||
return new ODBStringValue(text);
|
||||
}
|
||||
public ODBStringValue(string s)
|
||||
: base(0x01,s)
|
||||
{}
|
||||
|
||||
public override byte[] GetStorageBytes() => Encoding.UTF8.GetBytes((string)Value);
|
||||
protected override int compare(ODBEntity other) => ((string)Value).CompareTo((other as ODBValue).Value);
|
||||
|
||||
static ODBStringValue()
|
||||
{
|
||||
RegisterDeserializer(0x01, (b, o, l) => new ODBStringValue(Encoding.UTF8.GetString(b, o, l)));
|
||||
// RegisterValueFactory(typeof(string), v => new ODBStringValue((string)v));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,74 +11,74 @@ using System;
|
|||
using System.IO;
|
||||
namespace ln.types.odb.values
|
||||
{
|
||||
public class ODBTypedValue : ODBValue
|
||||
{
|
||||
public ODBValue ODBValue { get; private set; }
|
||||
public Type TargetType { get; private set; }
|
||||
//public class ODBTypedValue : ODBEntity
|
||||
//{
|
||||
// public ODBEntity ODBValue { get; private set; }
|
||||
// public Type TargetType { get; private set; }
|
||||
|
||||
public override uint AsUInt => ODBValue.AsUInt;
|
||||
// public override uint AsUInt => ODBValue.AsUInt;
|
||||
|
||||
internal ODBTypedValue()
|
||||
: base(0x0020)
|
||||
{
|
||||
}
|
||||
public ODBTypedValue(Type targetType,ODBValue value)
|
||||
: this()
|
||||
{
|
||||
TargetType = targetType;
|
||||
ODBValue = value;
|
||||
}
|
||||
public ODBTypedValue(byte[] bytes,int offset,int length)
|
||||
: this()
|
||||
{
|
||||
String aname = ODBValue.Deserialize(bytes, ref offset).AsString;
|
||||
String tname = ODBValue.Deserialize(bytes, ref offset).AsString;
|
||||
ODBValue = ODBValue.Deserialize(bytes, ref offset);
|
||||
// internal ODBTypedValue()
|
||||
// : base(0x0020)
|
||||
// {
|
||||
// }
|
||||
// public ODBTypedValue(Type targetType,ODBEntity value)
|
||||
// : this()
|
||||
// {
|
||||
// TargetType = targetType;
|
||||
// ODBValue = value;
|
||||
// }
|
||||
// public ODBTypedValue(byte[] bytes,int offset,int length)
|
||||
// : this()
|
||||
// {
|
||||
// String aname = ODBEntity.Deserialize(bytes, ref offset).AsString;
|
||||
// String tname = ODBEntity.Deserialize(bytes, ref offset).AsString;
|
||||
// ODBValue = ODBEntity.Deserialize(bytes, ref offset);
|
||||
|
||||
TargetType = Type.GetType(String.Format("{0}, {1}", tname, aname));
|
||||
}
|
||||
// TargetType = Type.GetType(String.Format("{0}, {1}", tname, aname));
|
||||
// }
|
||||
|
||||
public override int CompareLevel => 126;
|
||||
// public override int CompareLevel => 126;
|
||||
|
||||
public override int CompareInType(ODBValue other)
|
||||
{
|
||||
ODBTypedValue typedValue = other as ODBTypedValue;
|
||||
return ODBValue.CompareTo(typedValue.ODBValue);
|
||||
}
|
||||
// public override int CompareInType(ODBEntity other)
|
||||
// {
|
||||
// ODBTypedValue typedValue = other as ODBTypedValue;
|
||||
// return ODBValue.CompareTo(typedValue.ODBValue);
|
||||
// }
|
||||
|
||||
public override byte[] ToStorage()
|
||||
{
|
||||
MemoryStream stream = new MemoryStream();
|
||||
BinaryWriter writer = new BinaryWriter(stream);
|
||||
// public override byte[] GetStorageBytes()
|
||||
// {
|
||||
// MemoryStream stream = new MemoryStream();
|
||||
// BinaryWriter writer = new BinaryWriter(stream);
|
||||
|
||||
ODBStringValue aname = TargetType.Assembly.GetName().Name;
|
||||
ODBStringValue tname = TargetType.FullName;
|
||||
// ODBStringValue aname = TargetType.Assembly.GetName().Name;
|
||||
// ODBStringValue tname = TargetType.FullName;
|
||||
|
||||
aname.Store(writer);
|
||||
tname.Store(writer);
|
||||
ODBValue.Store(writer);
|
||||
// aname.Write(writer);
|
||||
// tname.Write(writer);
|
||||
// ODBValue.Write(writer);
|
||||
|
||||
return stream.ToArray();
|
||||
}
|
||||
// return stream.ToArray();
|
||||
// }
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ODBValue.GetHashCode();
|
||||
}
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is ODBTypedValue)
|
||||
{
|
||||
ODBTypedValue typedValue = obj as ODBTypedValue;
|
||||
return ODBValue.Equals(typedValue.ODBValue);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// public override int GetHashCode()
|
||||
// {
|
||||
// return ODBValue.GetHashCode();
|
||||
// }
|
||||
// public override bool Equals(object obj)
|
||||
// {
|
||||
// if (obj is ODBTypedValue)
|
||||
// {
|
||||
// ODBTypedValue typedValue = obj as ODBTypedValue;
|
||||
// return ODBValue.Equals(typedValue.ODBValue);
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
|
||||
static ODBTypedValue()
|
||||
{
|
||||
RegisterDeserializer(0x0020, (b, o, l) => new ODBTypedValue(b,o,l));
|
||||
}
|
||||
}
|
||||
// static ODBTypedValue()
|
||||
// {
|
||||
// RegisterDeserializer(0x0020, (b, o, l) => new ODBTypedValue(b,o,l));
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
|
|
@ -1,251 +1,68 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using ln.types.odb.ng;
|
||||
|
||||
/**
|
||||
* typeCode list
|
||||
*
|
||||
* 0x0000 ODBNull
|
||||
* 0x0001 ODBStringValue
|
||||
* 0x0002 ODBList
|
||||
* 0x0003 ODBGuid
|
||||
* 0x0004 ODBBool
|
||||
*
|
||||
* 0x0010 ODBInteger
|
||||
* 0x0011 ODBUInteger
|
||||
* 0x0012 ODBLong
|
||||
* 0x0013 ODBULong
|
||||
*
|
||||
* 0x0018 ODBDouble
|
||||
*
|
||||
* 0x0020 ODBTypedMapping
|
||||
*
|
||||
* 0x1000 ODBDocument
|
||||
* 0x1001 Document (ln.types.odb.ng)
|
||||
*
|
||||
*
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
|
||||
// /**
|
||||
// * File: ODBValue.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;
|
||||
namespace ln.types.odb.values
|
||||
{
|
||||
public delegate ODBValue ODBValueFactory(object value);
|
||||
public delegate ODBValue ODBDeserialize(byte[] storageBytes, int offset, int length);
|
||||
|
||||
public abstract class ODBValue : IComparable<ODBValue>
|
||||
/// <summary>
|
||||
/// The base type of all immutable ODB types
|
||||
/// </summary>
|
||||
public abstract class ODBValue : ODBEntity
|
||||
{
|
||||
int storageTypeCode;
|
||||
public object Value { get; }
|
||||
|
||||
public virtual object Value { get; protected set; }
|
||||
|
||||
protected ODBValue(int storageTypeCode)
|
||||
{
|
||||
this.storageTypeCode = storageTypeCode;
|
||||
}
|
||||
public override ODBValue Identity => this;
|
||||
public override T As<T>() => Cast.To<T>(Value);
|
||||
public override ODBEntity Clone() => this;
|
||||
|
||||
protected ODBValue(int storageTypeCode, object value)
|
||||
: this(storageTypeCode)
|
||||
: base(storageTypeCode)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public abstract int CompareLevel { get; }
|
||||
public abstract int CompareInType(ODBValue other);
|
||||
public virtual int CompareValueInType(ODBValue other) => CompareInType(other);
|
||||
|
||||
public abstract byte[] ToStorage();
|
||||
|
||||
public object AsObject => Value;
|
||||
|
||||
public virtual string AsString
|
||||
{
|
||||
get
|
||||
{
|
||||
return Value?.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool AsBool
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)Value;
|
||||
}
|
||||
}
|
||||
public virtual byte AsByte => Convert.ToByte(Value);
|
||||
public virtual char AsChar => (char)Value;
|
||||
public virtual short AsShort => Convert.ToInt16(Value);
|
||||
public virtual int AsInt => Convert.ToInt32(Value);
|
||||
public virtual long AsLong => Convert.ToInt64(Value);
|
||||
public virtual ushort AsUShort => Convert.ToUInt16(Value);
|
||||
public virtual uint AsUInt => (uint)Value;
|
||||
public virtual ulong AsULong => (ulong)Value;
|
||||
|
||||
public virtual double AsDouble => (double)Value;
|
||||
public virtual float AsFloat => (float)Value;
|
||||
|
||||
public virtual Guid AsGuid => (Guid)Value;
|
||||
public virtual DateTime AsDateTime => (DateTime)Mapper.Default.UnmapValue(typeof(DateTime), this);
|
||||
public virtual TimeSpan AsTimeSpan => (TimeSpan)Mapper.Default.UnmapValue(typeof(TimeSpan), this);
|
||||
|
||||
public virtual ODBTypedValue AsTypedValue => this as ODBTypedValue;
|
||||
|
||||
public virtual Document AsDocument => (Document)this;
|
||||
|
||||
public virtual ODBValue Clone()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public virtual void Store(BinaryWriter storage)
|
||||
{
|
||||
byte[] storageBytes = ToStorage();
|
||||
|
||||
storage.Write(storageTypeCode);
|
||||
storage.Write(storageBytes.Length);
|
||||
storage.Write(storageBytes, 0, storageBytes.Length);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value.GetHashCode();
|
||||
}
|
||||
public override int GetHashCode() => Value.GetHashCode();
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is ODBValue)
|
||||
{
|
||||
ODBValue you = obj as ODBValue;
|
||||
return Value.Equals(you.Value);
|
||||
}
|
||||
return Value.Equals(obj);
|
||||
}
|
||||
|
||||
public virtual bool ValueEquals(ODBValue other)
|
||||
{
|
||||
return Equals(other);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <(ODBValue a, ODBValue b)
|
||||
{
|
||||
return a.CompareTo(b) < 0;
|
||||
}
|
||||
public static bool operator >(ODBValue a, ODBValue b)
|
||||
{
|
||||
return a.CompareTo(b) > 0;
|
||||
}
|
||||
public static bool operator <=(ODBValue a, ODBValue b)
|
||||
{
|
||||
return a.CompareTo(b) <= 0;
|
||||
}
|
||||
public static bool operator >=(ODBValue a, ODBValue b)
|
||||
{
|
||||
return a.CompareTo(b) >= 0;
|
||||
}
|
||||
public static bool operator ==(ODBValue a, ODBValue b)
|
||||
{
|
||||
if (Object.ReferenceEquals(a, null))
|
||||
return object.ReferenceEquals(b, null);
|
||||
return a.CompareTo(b) == 0;
|
||||
}
|
||||
public static bool operator !=(ODBValue a, ODBValue b)
|
||||
{
|
||||
return a.CompareTo(b) != 0;
|
||||
}
|
||||
|
||||
|
||||
public static implicit operator ODBValue(ValueType v)
|
||||
{
|
||||
return Mapper.Default.MapValue(v);
|
||||
}
|
||||
public static implicit operator ODBValue(String v)
|
||||
{
|
||||
return Mapper.Default.MapValue(v);
|
||||
}
|
||||
|
||||
public static ODBValue FromNative(object v)
|
||||
{
|
||||
return Mapper.Default.MapValue(v);
|
||||
}
|
||||
|
||||
static Dictionary<int, ODBDeserialize> valueDeserializers = new Dictionary<int, ODBDeserialize>();
|
||||
public static void RegisterDeserializer(int storageTypeCode, ODBDeserialize deserialize)
|
||||
{
|
||||
valueDeserializers.Add(storageTypeCode, deserialize);
|
||||
}
|
||||
|
||||
public static ODBValue Deserialize(byte[] buffer, ref int offset)
|
||||
{
|
||||
int storageTypeCode = BitConverter.ToInt32(buffer, offset);
|
||||
int storageLength = BitConverter.ToInt32(buffer, offset + 4);
|
||||
if (!valueDeserializers.ContainsKey(storageTypeCode))
|
||||
throw new KeyNotFoundException(String.Format("StorageTypeCode 0x{0:x8} at offset 0x{1:x8}",storageTypeCode,offset));
|
||||
|
||||
ODBValue value = valueDeserializers[storageTypeCode](buffer, offset + 8, storageLength);
|
||||
offset += 8 + storageLength;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static ODBValue Read(Stream stream)
|
||||
{
|
||||
int storageTypeCode = stream.ReadInteger();
|
||||
int storageLength = stream.ReadInteger();
|
||||
byte[] b = new byte[storageLength];
|
||||
stream.Read(b, 0, storageLength);
|
||||
|
||||
if (valueDeserializers.ContainsKey(storageTypeCode))
|
||||
return valueDeserializers[storageTypeCode](b, 0, storageLength);
|
||||
else
|
||||
throw new FormatException("wrong storage type code");
|
||||
}
|
||||
|
||||
public int CompareTo(ODBValue other)
|
||||
{
|
||||
if (CompareLevel != other.CompareLevel)
|
||||
return CompareLevel - other.CompareLevel;
|
||||
|
||||
return CompareInType(other);
|
||||
}
|
||||
public virtual int CompareValueTo(ODBValue other)
|
||||
{
|
||||
if (CompareLevel != other.CompareLevel)
|
||||
return CompareLevel - other.CompareLevel;
|
||||
|
||||
return CompareValueInType(other);
|
||||
return Object.Equals(Value, (obj as ODBValue).Value);
|
||||
if (obj is ODBEntity)
|
||||
return Identity.Equals((obj as ODBEntity).Identity);
|
||||
return false;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("[ODBValue Value={0}]", Value);
|
||||
return String.Format("[{0} Value={1}]", GetType().Name, Value);
|
||||
}
|
||||
|
||||
public static int Compare(ODBValue a,ODBValue b)
|
||||
{
|
||||
return a.CompareTo(b);
|
||||
}
|
||||
public static int CompareValue(ODBValue a, ODBValue b)
|
||||
{
|
||||
return a.CompareValueTo(b);
|
||||
}
|
||||
|
||||
static ODBValue()
|
||||
{
|
||||
new Document();
|
||||
new ODBNull();
|
||||
new ODBStringValue();
|
||||
new ODBBool();
|
||||
new ODBList();
|
||||
new ODBInteger();
|
||||
new ODBUInteger();
|
||||
new ODBLong();
|
||||
new ODBULong();
|
||||
new ODBDouble();
|
||||
new ODBGuid();
|
||||
new ODBTypedValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//public virtual string AsString => As<string>();
|
||||
//public virtual bool AsBool => As<bool>();
|
||||
//public virtual byte AsByte => As<byte>();
|
||||
//public virtual char AsChar => (char)Value;
|
||||
//public virtual short AsShort => Convert.ToInt16(Value);
|
||||
//public virtual int AsInt => Convert.ToInt32(Value);
|
||||
//public virtual long AsLong => Convert.ToInt64(Value);
|
||||
//public virtual ushort AsUShort => Convert.ToUInt16(Value);
|
||||
//public virtual uint AsUInt => (uint)Value;
|
||||
//public virtual ulong AsULong => (ulong)Value;
|
||||
|
||||
//public virtual double AsDouble => (double)Value;
|
||||
//public virtual float AsFloat => (float)Value;
|
||||
|
||||
//public virtual Guid AsGuid => (Guid)Value;
|
||||
//public virtual DateTime AsDateTime => (DateTime)Mapper.Default.UnmapValue(typeof(DateTime), this);
|
||||
//public virtual TimeSpan AsTimeSpan => (TimeSpan)Mapper.Default.UnmapValue(typeof(TimeSpan), this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,25 +132,25 @@ namespace ln.types.test
|
|||
{
|
||||
Document origin = new Document();
|
||||
|
||||
origin["FeldA"] = "OriginalA";
|
||||
origin["FeldB"] = "OriginalB";
|
||||
origin["FeldC"] = "OriginalC";
|
||||
origin["FeldA"] = new ODBStringValue("OriginalA");
|
||||
origin["FeldB"] = new ODBStringValue("OriginalB");
|
||||
origin["FeldC"] = new ODBStringValue("OriginalC");
|
||||
|
||||
storage1.Save(origin);
|
||||
|
||||
Document secondary = storage2.Load(origin.ID);
|
||||
|
||||
Assert.IsTrue(origin.ContentEquals(secondary));
|
||||
Assert.IsTrue(origin.CompareTo(secondary) == 0);
|
||||
|
||||
secondary["FeldB"] = "ZweiB";
|
||||
secondary["FeldB"] = new ODBStringValue("ZweiB");
|
||||
storage2.Save(secondary);
|
||||
|
||||
Assert.IsFalse(origin.ContentEquals(secondary));
|
||||
Assert.IsFalse(origin.CompareTo(secondary) == 0);
|
||||
|
||||
Document reloaded1 = storage1.Load(origin.ID);
|
||||
Assert.AreSame(reloaded1, origin);
|
||||
|
||||
Assert.IsTrue(secondary.ContentEquals(reloaded1));
|
||||
Assert.IsTrue(secondary.CompareTo(reloaded1) == 0);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue