WIP
parent
f80a158dcb
commit
5dcb7f60ec
|
@ -1,6 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using ln.logging;
|
||||
using System.ComponentModel;
|
||||
namespace ln.types
|
||||
{
|
||||
|
||||
|
@ -43,11 +46,26 @@ namespace ln.types
|
|||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Argument container.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class parses command line arguments to a list of predefined well known arguments.
|
||||
/// Remaining arguments will be found in <c>AdditionalArguments</c>.
|
||||
///
|
||||
/// <c>ArgumentContainer</c> also provides a global command line option:
|
||||
/// --change-static <para>typename</para> <para>fieldname</para> <para>value</para>
|
||||
/// It may be used multiple times on the command line.
|
||||
/// It will load the type referenced by the qualified name <para>typename</para> and try to set the static field <para>fieldname</para> to <para>value</para>.
|
||||
/// <para>value</para> will be casted to field type via Convert.ChangeType(...)
|
||||
/// </remarks>
|
||||
public class ArgumentContainer
|
||||
{
|
||||
List<Argument> arguments;
|
||||
List<String> additionalArguments;
|
||||
|
||||
public string[] AdditionalArguments => additionalArguments.ToArray();
|
||||
|
||||
public ArgumentContainer()
|
||||
{
|
||||
arguments = new List<Argument>();
|
||||
|
@ -138,10 +156,21 @@ namespace ln.types
|
|||
if (currentOption[1].Equals('-'))
|
||||
{
|
||||
String aname = currentOption.Substring(2);
|
||||
Argument argument = this[aname];
|
||||
argument.IsSet = true;
|
||||
if (argument.NeedsValue)
|
||||
argument.Value = q.Dequeue();
|
||||
|
||||
if (aname.Equals("change-static"))
|
||||
{
|
||||
string typeName = q.Dequeue();
|
||||
string fieldName = q.Dequeue();
|
||||
string value = q.Dequeue();
|
||||
ChangeStatic(typeName, fieldName, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Argument argument = this[aname];
|
||||
argument.IsSet = true;
|
||||
if (argument.NeedsValue)
|
||||
argument.Value = q.Dequeue();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -161,5 +190,17 @@ namespace ln.types
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ChangeStatic(string typeName,string fieldname,string value)
|
||||
{
|
||||
Type type = Type.GetType(typeName);
|
||||
Logging.Log(LogLevel.INFO, "ArgumentContainer: ChangeStatic: Type: {0}",type);
|
||||
|
||||
FieldInfo fieldInfo = type.GetField(fieldname, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
Logging.Log(LogLevel.INFO, "ArgumentContainer: ChangeStatic: Field: {0} {1}", fieldname, fieldInfo);
|
||||
|
||||
object castValue = Convert.ChangeType(value, fieldInfo.FieldType);
|
||||
fieldInfo.SetValue(null,castValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace ln.types
|
|||
elements.Add(e);
|
||||
return elements.ToArray();
|
||||
}
|
||||
public static T[] Remove<T>(this T[] me,IEnumerable<T> remove)
|
||||
public static T[] Remove<T>(this T[] me, IEnumerable<T> remove)
|
||||
{
|
||||
HashSet<T> elements = new HashSet<T>(me);
|
||||
foreach (T e in remove)
|
||||
|
@ -33,7 +33,7 @@ namespace ln.types
|
|||
}
|
||||
|
||||
|
||||
public static bool AreEqual<T>(this T[] me,T[] you)
|
||||
public static bool AreEqual<T>(this T[] me, T[] you)
|
||||
{
|
||||
if (me.Length != you.Length)
|
||||
return false;
|
||||
|
@ -73,34 +73,34 @@ namespace ln.types
|
|||
stream.Write(BitConverter.GetBytes(i).BigEndian(), 0, 4);
|
||||
}
|
||||
|
||||
public static long ReadLong(this Stream stream)
|
||||
{
|
||||
byte[] b = new byte[8];
|
||||
stream.Read(b, 0, 8);
|
||||
return BitConverter.ToInt64(b, 0);
|
||||
}
|
||||
public static void WriteLong(this Stream stream, long i)
|
||||
{
|
||||
stream.Write(BitConverter.GetBytes(i), 0, 8);
|
||||
}
|
||||
public static ulong ReadULong(this Stream stream)
|
||||
{
|
||||
byte[] b = new byte[8];
|
||||
stream.Read(b, 0, 8);
|
||||
return BitConverter.ToUInt64(b.BigEndian(), 0);
|
||||
}
|
||||
public static void WriteULong(this Stream stream, ulong i)
|
||||
{
|
||||
stream.Write(BitConverter.GetBytes(i).BigEndian(), 0, 8);
|
||||
}
|
||||
public static long ReadLong(this Stream stream)
|
||||
{
|
||||
byte[] b = new byte[8];
|
||||
stream.Read(b, 0, 8);
|
||||
return BitConverter.ToInt64(b, 0);
|
||||
}
|
||||
public static void WriteLong(this Stream stream, long i)
|
||||
{
|
||||
stream.Write(BitConverter.GetBytes(i), 0, 8);
|
||||
}
|
||||
public static ulong ReadULong(this Stream stream)
|
||||
{
|
||||
byte[] b = new byte[8];
|
||||
stream.Read(b, 0, 8);
|
||||
return BitConverter.ToUInt64(b.BigEndian(), 0);
|
||||
}
|
||||
public static void WriteULong(this Stream stream, ulong i)
|
||||
{
|
||||
stream.Write(BitConverter.GetBytes(i).BigEndian(), 0, 8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void WriteBytes(this Stream stream,byte[] bytes)
|
||||
public static void WriteBytes(this Stream stream, byte[] bytes)
|
||||
{
|
||||
stream.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
public static byte[] ReadBytes(this Stream stream,int length)
|
||||
public static byte[] ReadBytes(this Stream stream, int length)
|
||||
{
|
||||
byte[] bytes = new byte[length];
|
||||
stream.Read(bytes, 0, length);
|
||||
|
@ -181,7 +181,7 @@ namespace ln.types
|
|||
if (BitConverter.IsLittleEndian == bigEndian)
|
||||
Array.Reverse(bytes);
|
||||
return bytes;
|
||||
|
||||
|
||||
}
|
||||
public static int GetInt(this byte[] bytes, bool bigEndian = false) => GetInt(bytes, 0, bigEndian);
|
||||
public static int GetInt(this byte[] bytes, int offset, bool bigEndian = false)
|
||||
|
@ -240,9 +240,8 @@ namespace ln.types
|
|||
}
|
||||
|
||||
|
||||
|
||||
public static T[] Slice<T>(this T[] me, int offset) => Slice(me, offset, me.Length - offset);
|
||||
public static T[] Slice<T>(this T[] me,int offset,int length)
|
||||
public static T[] Slice<T>(this T[] me, int offset, int length)
|
||||
{
|
||||
T[] slice = new T[length];
|
||||
Array.Copy(me, offset, slice, 0, length);
|
||||
|
@ -261,7 +260,7 @@ namespace ln.types
|
|||
|
||||
byte[] section = bytes.Slice(n, len);
|
||||
|
||||
for (int i=0;i<16;i++)
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (i < section.Length)
|
||||
stringBuilder.AppendFormat("{0:X2} ", section[i]);
|
||||
|
@ -284,6 +283,36 @@ namespace ln.types
|
|||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
public static Decimal ToDecimal(this double v)
|
||||
{
|
||||
if (v <= (double)Decimal.MinValue)
|
||||
return decimal.MinValue;
|
||||
if (v >= (double)Decimal.MaxValue)
|
||||
return decimal.MaxValue;
|
||||
|
||||
return new Decimal(v);
|
||||
}
|
||||
}
|
||||
public static class DateTimeExtensions
|
||||
{
|
||||
public static DateTime EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
|
||||
|
||||
public static DateTime FromUnixTimeSeconds(double seconds)
|
||||
{
|
||||
return EPOCH.AddSeconds(seconds);
|
||||
}
|
||||
public static DateTime FromUnixTimeMilliseconds(double milliseconds)
|
||||
{
|
||||
return EPOCH.AddMilliseconds(milliseconds);
|
||||
}
|
||||
|
||||
public static double ToUnixTimeSeconds(this DateTime dateTime)
|
||||
{
|
||||
return (dateTime - EPOCH).TotalSeconds;
|
||||
}
|
||||
public static double ToUnixTimeMilliseconds(this DateTime dateTime)
|
||||
{
|
||||
return (dateTime - EPOCH).TotalMilliseconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,6 +118,9 @@
|
|||
<Compile Include="odb\ng\mappings\ListMapping.cs" />
|
||||
<Compile Include="odb\ng\Reference.cs" />
|
||||
<Compile Include="stream\CharStream.cs" />
|
||||
<Compile Include="odb\ng\Query.cs" />
|
||||
<Compile Include="odb\ng\IStorage.cs" />
|
||||
<Compile Include="odb\ng\Document.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="sync\" />
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace ln.types.odb
|
|||
{
|
||||
Type ceType = byReferenceAttribute.ElementType ?? fieldInfo.FieldType;
|
||||
String cAlias = byReferenceAttribute.Alias ?? ceType.FullName;
|
||||
MappedCollection mappedCollection = document.Collection.ODB.GetCollection(ceType,cAlias);
|
||||
MappedCollection mappedCollection = ODBCollection.CurrentODB.Value.GetCollection(ceType,cAlias);
|
||||
|
||||
ODBValue refID = document[fieldInfo.Name];
|
||||
fieldInfo.SetValue(o, mappedCollection.SelectByID(refID));
|
||||
|
|
|
@ -201,6 +201,7 @@ namespace ln.types.odb
|
|||
return null;
|
||||
|
||||
ODBDocument document = new ODBDocument(storageBytes, 0, storageBytes.Length);
|
||||
document.Collection = this.Collection;
|
||||
return document;
|
||||
}
|
||||
|
||||
|
@ -322,7 +323,12 @@ namespace ln.types.odb
|
|||
|
||||
public IEnumerator<ODBValue> GetEnumerator()
|
||||
{
|
||||
return idLookup.Keys.GetEnumerator();
|
||||
ODBValue[] docIDs;
|
||||
lock (this)
|
||||
{
|
||||
docIDs = idLookup.Keys.ToArray();
|
||||
}
|
||||
return ((IEnumerable<ODBValue>)docIDs).GetEnumerator();
|
||||
}
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
}
|
||||
|
|
|
@ -10,10 +10,13 @@ using System.ComponentModel.Design.Serialization;
|
|||
using System.ComponentModel;
|
||||
using ln.logging;
|
||||
using ln.types.btree;
|
||||
using System.Threading;
|
||||
namespace ln.types.odb
|
||||
{
|
||||
public partial class ODBCollection : IEnumerable<ODBDocument>, IDisposable
|
||||
{
|
||||
public static ThreadLocal<ODB> CurrentODB { get; } = new ThreadLocal<ODB>();
|
||||
|
||||
public ODB ODB { get; }
|
||||
public String CollectionName { get; }
|
||||
|
||||
|
@ -127,14 +130,16 @@ namespace ln.types.odb
|
|||
{
|
||||
lock (this)
|
||||
{
|
||||
CurrentODB.Value = this.ODB;
|
||||
|
||||
if (documentCache.ContainsKey(documentID))
|
||||
return documentCache[documentID];
|
||||
|
||||
ODBDocument doc = Index.LoadDocument(documentID);
|
||||
if (!object.ReferenceEquals(doc,null))
|
||||
if (!object.ReferenceEquals(doc, null))
|
||||
documentCache.Add(doc);
|
||||
|
||||
if (!object.ReferenceEquals(null,doc))
|
||||
if (!object.ReferenceEquals(null, doc))
|
||||
doc.Collection = this;
|
||||
|
||||
return doc;
|
||||
|
@ -204,7 +209,12 @@ namespace ln.types.odb
|
|||
|
||||
public IEnumerator<ODBDocument> GetEnumerator()
|
||||
{
|
||||
foreach (ODBValue id in documentIndex.ToArray())
|
||||
ODBValue[] docIDs = null;
|
||||
lock (this)
|
||||
{
|
||||
docIDs = documentIndex.ToArray();
|
||||
}
|
||||
foreach (ODBValue id in docIDs)
|
||||
{
|
||||
yield return GetDocumentByID(id);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using ln.types.odb.values;
|
||||
using System.Linq;
|
||||
namespace ln.types.odb.ng
|
||||
{
|
||||
public class Document : ODBValue
|
||||
{
|
||||
private Dictionary<ODBValue, ODBValue> properties = new Dictionary<ODBValue, ODBValue>();
|
||||
|
||||
public Document()
|
||||
:base(0x1000)
|
||||
{
|
||||
ID = Guid.NewGuid();
|
||||
}
|
||||
|
||||
public Guid ID { get; }
|
||||
public DateTime StorageTimeStamp { get; private set; }
|
||||
|
||||
public ODBCollection Collection { get; internal set; }
|
||||
|
||||
public Document(Guid documentID,byte[] bytes)
|
||||
: this(documentID, bytes, 0, bytes.Length)
|
||||
{ }
|
||||
public Document(Guid documentID,byte[] bytes,int offset,int length)
|
||||
:this()
|
||||
{
|
||||
ID = documentID;
|
||||
|
||||
int endOffset = offset + length;
|
||||
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);
|
||||
properties.Add(propName, propValue);
|
||||
}
|
||||
|
||||
if (offset > endOffset)
|
||||
throw new FormatException("Document deserialization read behind end of buffer");
|
||||
}
|
||||
|
||||
public ODBValue this[ODBValue propName]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (properties.ContainsKey(propName))
|
||||
return properties[propName];
|
||||
return ODBNull.Instance;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (ODBNull.Instance.Equals(value) && properties.ContainsKey(propName))
|
||||
{
|
||||
properties.Remove(propName);
|
||||
}
|
||||
else
|
||||
{
|
||||
properties[propName] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<ODBValue> Keys => properties.Keys;
|
||||
|
||||
public override int CompareLevel => 128;
|
||||
|
||||
public bool Contains(ODBValue propName)
|
||||
{
|
||||
return !ODBNull.Instance.Equals(this[propName]);
|
||||
}
|
||||
|
||||
public override byte[] ToStorage()
|
||||
{
|
||||
MemoryStream stream = new MemoryStream();
|
||||
BinaryWriter writer = new BinaryWriter(stream);
|
||||
|
||||
writer.Write(properties.Count);
|
||||
|
||||
foreach (ODBValue propName in properties.Keys)
|
||||
{
|
||||
ODBValue propValue = properties[propName];
|
||||
propName.Store(writer);
|
||||
propValue.Store(writer);
|
||||
}
|
||||
|
||||
return stream.ToArray();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("[Document ID={0} {1}]", ID.ToString(),String.Join(" ",properties.Select(kv=> String.Format("{0}={1}",kv.Key,kv.Value))));
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ID.GetHashCode();
|
||||
}
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is ODBDocument)
|
||||
{
|
||||
ODBDocument you = obj as ODBDocument;
|
||||
return ID.Equals(you.ID);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool ContentEquals(ODBDocument other)
|
||||
{
|
||||
if (object.ReferenceEquals(null, other))
|
||||
return false;
|
||||
|
||||
ODBValue[] keys = Keys.Union(other.Keys).ToArray();
|
||||
|
||||
foreach (ODBValue key in keys)
|
||||
{
|
||||
ODBValue value = this[key];
|
||||
if (!value.ValueEquals(other[key]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool ValueEquals(ODBValue other)
|
||||
{
|
||||
return ContentEquals(other as ODBDocument);
|
||||
}
|
||||
|
||||
public int CompareContent(ODBDocument 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);
|
||||
|
||||
if (c != 0)
|
||||
return c;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override int CompareInType(ODBValue other)
|
||||
{
|
||||
return CompareContent(other as ODBDocument);
|
||||
}
|
||||
public override int CompareValueInType(ODBValue other)
|
||||
{
|
||||
return CompareContent(other as ODBDocument);
|
||||
}
|
||||
|
||||
static Document()
|
||||
{
|
||||
RegisterDeserializer(0x1001, (b,o,l) => new Document(Guid.Empty,b,o,l));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
namespace ln.types.odb.ng
|
||||
{
|
||||
public interface IStorage
|
||||
{
|
||||
bool Open();
|
||||
void Close();
|
||||
bool IsOpen { get; }
|
||||
|
||||
ODBDocument Load(Guid documentID);
|
||||
ODBDocument Save(ODBDocument document);
|
||||
|
||||
IEnumerable<Guid> GetDocumentIDs();
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using ln.types.net;
|
||||
|
||||
namespace ln.types.odb.ng
|
||||
{
|
||||
|
@ -98,6 +99,11 @@ namespace ln.types.odb.ng
|
|||
(mapper, oval) => oval.AsBool
|
||||
);
|
||||
|
||||
RegisterMapping<IPv4>(
|
||||
(mapper, value) => new ODBUInteger(value.AsUInt),
|
||||
(mapper, oval) => new IPv4(oval.AsUInt)
|
||||
);
|
||||
|
||||
RegisterMapping(typeof(object),new mappings.ObjectMapping());
|
||||
}
|
||||
|
||||
|
|
|
@ -50,13 +50,13 @@ namespace ln.types.odb.ng
|
|||
}
|
||||
}
|
||||
|
||||
//public IEnumerable Select(Query query)
|
||||
//{
|
||||
// lock (this)
|
||||
// {
|
||||
// return new MappedEnumeration(this, query.Execute(DocumentCollection).ToArray());
|
||||
// }
|
||||
//}
|
||||
public IEnumerable Select(Query query)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
return new ObjectEnumeration(this, query.Execute(DocumentCollection).ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool Ensure(object o)
|
||||
|
@ -247,24 +247,45 @@ namespace ln.types.odb.ng
|
|||
return DocumentCollection.Index.Select((arg) => ODBMapper.UnmapValue(IDType, arg)).ToArray();
|
||||
}
|
||||
|
||||
//public MappedEnumeration GetEnumeration()
|
||||
//{
|
||||
// lock (this)
|
||||
// {
|
||||
// return new MappedEnumeration(this, DocumentCollection.Index.ToArray());
|
||||
// }
|
||||
//}
|
||||
public IEnumerable GetEnumeration()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
return new ObjectEnumeration(this, DocumentCollection.Index.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator GetEnumerator()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
//return GetEnumeration().GetEnumerator();
|
||||
return GetEnumeration().GetEnumerator();
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
DocumentCollection = null;
|
||||
}
|
||||
|
||||
|
||||
class ObjectEnumeration : IEnumerable
|
||||
{
|
||||
ObjectCollection collection;
|
||||
IEnumerable<ODBValue> documentIDs;
|
||||
|
||||
public ObjectEnumeration(ObjectCollection collection,IEnumerable<ODBValue> documentIDs)
|
||||
{
|
||||
this.collection = collection;
|
||||
this.documentIDs = documentIDs;
|
||||
}
|
||||
|
||||
public IEnumerator GetEnumerator()
|
||||
{
|
||||
foreach (ODBValue documentID in this.documentIDs)
|
||||
{
|
||||
yield return this.collection.SelectByID(documentID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -275,6 +296,7 @@ namespace ln.types.odb.ng
|
|||
:base(odbmapper,typeof(T))
|
||||
{}
|
||||
|
||||
public IEnumerable<T> SelectQuery(Query query) => base.Select(query).Cast<T>();
|
||||
public T Select(object id) => (T)base.SelectByID(id);
|
||||
|
||||
public bool Ensure(T o) => base.Ensure(o);
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
// /**
|
||||
// * File: Query.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.Collections.Generic;
|
||||
using ln.types.odb.values;
|
||||
using ln.types.btree;
|
||||
using System.Linq;
|
||||
using ln.types.odb.index;
|
||||
namespace ln.types.odb.ng
|
||||
{
|
||||
public abstract class Query
|
||||
{
|
||||
private Query()
|
||||
{
|
||||
}
|
||||
|
||||
public static Query AND(Query query,params Query[] queries)
|
||||
{
|
||||
return new IMPL.AND(query, queries);
|
||||
}
|
||||
public static Query OR(Query query, params Query[] queries)
|
||||
{
|
||||
return new IMPL.OR(query, queries);
|
||||
}
|
||||
public static Query NOT(Query query)
|
||||
{
|
||||
return new IMPL.NOT(query);
|
||||
}
|
||||
|
||||
public static Query Equals<T>(string propertyName, object value) => Equals(IndexPath.TranslatePropertyPath(typeof(T), propertyName), ODBMapper.Default.MapValue(value));
|
||||
public static Query Equals(String propertyName, ODBValue value)
|
||||
{
|
||||
if (object.ReferenceEquals(value,null))
|
||||
value = ODBNull.Instance;
|
||||
|
||||
return IF(propertyName, (v) => value.ValueEquals(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)
|
||||
{
|
||||
if (object.ReferenceEquals(value, null))
|
||||
value = ODBNull.Instance;
|
||||
|
||||
return IF(propertyName, (v) => !value.ValueEquals(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)
|
||||
{
|
||||
return IF(propertyName, (v) => values.Contains(v));
|
||||
}
|
||||
|
||||
public static Query Contains<T, A>(string propertyName, IEnumerable<A> values)
|
||||
{
|
||||
ODBValue[] oValues = values.Select(v => ODBMapper.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)
|
||||
{
|
||||
return new IMPL.IF(propertyName, predicate);
|
||||
}
|
||||
|
||||
|
||||
public abstract IEnumerable<ODBValue> Execute(ODBCollection collection);
|
||||
|
||||
|
||||
class IMPL
|
||||
{
|
||||
public class IF : Query
|
||||
{
|
||||
public string PropertyName { get; }
|
||||
public Predicate<ODBValue> Predicate { get; }
|
||||
|
||||
public IF(string propertyName,Predicate<ODBValue> predicate)
|
||||
{
|
||||
PropertyName = propertyName;
|
||||
Predicate = predicate;
|
||||
}
|
||||
|
||||
public override IEnumerable<ODBValue> Execute(ODBCollection collection)
|
||||
{
|
||||
return collection.QueryIDs(PropertyName,Predicate);
|
||||
}
|
||||
}
|
||||
|
||||
public class AND : Query
|
||||
{
|
||||
public Query Query { get; }
|
||||
public Query[] Queries { get; }
|
||||
|
||||
public AND(Query query, params Query[] queries)
|
||||
{
|
||||
Query = query;
|
||||
Queries = queries;
|
||||
}
|
||||
|
||||
public override IEnumerable<ODBValue> Execute(ODBCollection collection)
|
||||
{
|
||||
BTree<ODBValue> firstSet = new BTree<ODBValue>(ODBValue.Compare);
|
||||
|
||||
firstSet.AddRange(
|
||||
Query.Execute(collection)
|
||||
);
|
||||
|
||||
foreach (Query aQuery in Queries)
|
||||
{
|
||||
if (firstSet.Count == 0)
|
||||
return new ODBValue[0];
|
||||
|
||||
BTree<ODBValue> nextSet = new BTree<ODBValue>(ODBValue.Compare);
|
||||
|
||||
foreach (ODBValue documentID in aQuery.Execute(collection))
|
||||
{
|
||||
if (firstSet.ContainsKey(documentID))
|
||||
nextSet.Add(documentID);
|
||||
}
|
||||
|
||||
firstSet = nextSet;
|
||||
}
|
||||
|
||||
return firstSet.Keys;
|
||||
}
|
||||
}
|
||||
|
||||
public class OR : Query
|
||||
{
|
||||
public Query Query { get; }
|
||||
public Query[] Queries { get; }
|
||||
|
||||
public OR(Query query, params Query[] queries)
|
||||
{
|
||||
Query = query;
|
||||
Queries = queries;
|
||||
}
|
||||
|
||||
public override IEnumerable<ODBValue> Execute(ODBCollection collection)
|
||||
{
|
||||
BTree<ODBValue> result = new BTree<ODBValue>(ODBValue.Compare);
|
||||
|
||||
result.TryAddRange(
|
||||
Query.Execute(collection)
|
||||
);
|
||||
|
||||
foreach (Query aQuery in Queries)
|
||||
{
|
||||
foreach (ODBValue documentID in aQuery.Execute(collection))
|
||||
result.TryAdd(documentID);
|
||||
}
|
||||
|
||||
return result.Keys;
|
||||
}
|
||||
}
|
||||
public class NOT : Query
|
||||
{
|
||||
public Query Query { get; }
|
||||
|
||||
public NOT(Query query)
|
||||
{
|
||||
Query = query;
|
||||
}
|
||||
|
||||
public override IEnumerable<ODBValue> Execute(ODBCollection collection)
|
||||
{
|
||||
BTree<ODBValue> notSet = new BTree<ODBValue>();
|
||||
BTree<ODBValue> result = new BTree<ODBValue>();
|
||||
|
||||
notSet.AddRange(Query.Execute(collection));
|
||||
|
||||
foreach (ODBValue documentID in collection.Index)
|
||||
{
|
||||
if (!notSet.ContainsKey(documentID))
|
||||
result.Add(documentID);
|
||||
}
|
||||
|
||||
return result.Keys;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,6 +15,8 @@ namespace ln.types.odb.values
|
|||
{
|
||||
public ODBValue ODBValue { get; private set; }
|
||||
public Type TargetType { get; private set; }
|
||||
|
||||
public override uint AsUInt => ODBValue.AsUInt;
|
||||
|
||||
internal ODBTypedValue()
|
||||
: base(0x0020)
|
||||
|
|
|
@ -21,6 +21,7 @@ using System.IO;
|
|||
* 0x0020 ODBTypedMapping
|
||||
*
|
||||
* 0x1000 ODBDocument
|
||||
* 0x1001 Document (ln.types.odb.ng)
|
||||
*
|
||||
*
|
||||
*
|
||||
|
|
|
@ -27,6 +27,22 @@ namespace ln.types.rpc
|
|||
modules.Add(moduleName, rpcModule);
|
||||
}
|
||||
|
||||
public void Remove(string moduleName)
|
||||
{
|
||||
modules.Remove(moduleName);
|
||||
}
|
||||
public void Remove(object moduleInstance)
|
||||
{
|
||||
foreach (RPCModule module in modules.Values)
|
||||
{
|
||||
if (module.ModuleInstance == moduleInstance)
|
||||
{
|
||||
modules.Remove(module.Name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RPCResult Invoke(RPCCall call)
|
||||
{
|
||||
if ((call.ModuleName != null) && !modules.ContainsKey(call.ModuleName))
|
||||
|
@ -86,9 +102,29 @@ namespace ln.types.rpc
|
|||
ParameterInfo[] paramterInfos = methodInfo.GetParameters();
|
||||
|
||||
object[] parameters = new object[paramterInfos.Length];
|
||||
for (int n=0;n<parameters.Length;n++)
|
||||
for (int n = 0; n < parameters.Length; n++)
|
||||
{
|
||||
parameters[n] = Convert.ChangeType(call.Parameters[n], paramterInfos[n].ParameterType);
|
||||
Type pType = paramterInfos[n].ParameterType;
|
||||
if (pType.Equals(typeof(Guid)))
|
||||
{
|
||||
parameters[n] = Guid.Parse(call.Parameters[n].ToString());
|
||||
} else if (pType.IsArray)
|
||||
{
|
||||
Type eType = pType.GetElementType();
|
||||
object[] src = (object[])call.Parameters[n];
|
||||
Array a = Array.CreateInstance(eType, src.Length);
|
||||
|
||||
for (int m=0;m<src.Length;m++)
|
||||
{
|
||||
a.SetValue(Convert.ChangeType(src[m], eType), m);
|
||||
}
|
||||
|
||||
parameters[n] = a;
|
||||
}
|
||||
else
|
||||
{
|
||||
parameters[n] = Convert.ChangeType(call.Parameters[n], paramterInfos[n].ParameterType);
|
||||
}
|
||||
}
|
||||
|
||||
object result = methodInfo.Invoke(ModuleInstance, parameters);
|
||||
|
|
|
@ -10,6 +10,8 @@ namespace ln.types.threads
|
|||
|
||||
public class Pool : IDisposable
|
||||
{
|
||||
public static bool DEBUG = false;
|
||||
|
||||
public PoolThread[] PoolThreads
|
||||
{
|
||||
get
|
||||
|
@ -330,11 +332,6 @@ namespace ln.types.threads
|
|||
break;
|
||||
}
|
||||
|
||||
if (Pool.poolThreads.Count > 4)
|
||||
{
|
||||
Logging.Log(LogLevel.DEBUGDETAIL, "--");
|
||||
}
|
||||
|
||||
if (poolJob != null)
|
||||
{
|
||||
State = PoolThreadState.WORKING;
|
||||
|
|
|
@ -93,7 +93,7 @@ namespace ln.types.threads
|
|||
|
||||
JobState = PoolJobState.DONE;
|
||||
|
||||
if ((State != null) && !String.Empty.Equals(State))
|
||||
if (Pool.DEBUG && (State != null) && !String.Empty.Equals(State))
|
||||
Logging.Log(LogLevel.DEBUG, "PoolJob exited normally with State={0}", State);
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
Loading…
Reference in New Issue