197 lines
6.2 KiB
C#
197 lines
6.2 KiB
C#
|
// /**
|
|||
|
// * 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.btree;
|
|||
|
using System.Linq;
|
|||
|
using ln.types.odb.ng.index;
|
|||
|
using ln.types.odb.ng.storage;
|
|||
|
using ln.objects.catalog;
|
|||
|
|
|||
|
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), Mapper.Default.MapValue(value));
|
|||
|
public static Query Equals(String propertyName, ODBEntity value)
|
|||
|
{
|
|||
|
if (object.ReferenceEquals(value,null))
|
|||
|
value = ODBNull.Instance;
|
|||
|
|
|||
|
return IF(propertyName, (v) => value.CompareTo(v)==0);
|
|||
|
}
|
|||
|
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.CompareTo(v)!=0);
|
|||
|
}
|
|||
|
|
|||
|
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) => {
|
|||
|
foreach (ODBEntity value in values)
|
|||
|
if (value.CompareTo(v) == 0)
|
|||
|
return true;
|
|||
|
return false;
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
public static Query Contains<T, A>(string propertyName, IEnumerable<A> values)
|
|||
|
{
|
|||
|
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<ODBEntity> predicate) => IF(IndexPath.TranslatePropertyPath(typeof(T),propertyName), predicate);
|
|||
|
public static Query IF(string propertyName,Predicate<ODBEntity> predicate)
|
|||
|
{
|
|||
|
return new IMPL.IF(propertyName, predicate);
|
|||
|
}
|
|||
|
|
|||
|
public abstract IEnumerable<Guid> Execute(IStorage storage);
|
|||
|
|
|||
|
|
|||
|
class IMPL
|
|||
|
{
|
|||
|
public class IF : Query
|
|||
|
{
|
|||
|
public string PropertyName { get; }
|
|||
|
public Predicate<ODBEntity> Predicate { get; }
|
|||
|
|
|||
|
public IF(string propertyName,Predicate<ODBEntity> predicate)
|
|||
|
{
|
|||
|
PropertyName = propertyName;
|
|||
|
Predicate = predicate;
|
|||
|
}
|
|||
|
|
|||
|
public override IEnumerable<Guid> Execute(IStorage storage)
|
|||
|
{
|
|||
|
return storage.GetDocumentIDs(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<Guid> Execute(IStorage storage)
|
|||
|
{
|
|||
|
BTree<Guid> firstSet = new BTree<Guid>();
|
|||
|
|
|||
|
firstSet.AddRange(
|
|||
|
Query.Execute(storage)
|
|||
|
);
|
|||
|
|
|||
|
foreach (Query aQuery in Queries)
|
|||
|
{
|
|||
|
if (firstSet.Count == 0)
|
|||
|
return new Guid[0];
|
|||
|
|
|||
|
BTree<Guid> nextSet = new BTree<Guid>();
|
|||
|
|
|||
|
foreach (Guid documentID in aQuery.Execute(storage))
|
|||
|
{
|
|||
|
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<Guid> Execute(IStorage storage)
|
|||
|
{
|
|||
|
BTree<Guid> result = new BTree<Guid>();
|
|||
|
|
|||
|
result.TryAddRange(
|
|||
|
Query.Execute(storage)
|
|||
|
);
|
|||
|
|
|||
|
foreach (Query aQuery in Queries)
|
|||
|
{
|
|||
|
foreach (Guid documentID in aQuery.Execute(storage))
|
|||
|
result.TryAdd(documentID);
|
|||
|
}
|
|||
|
|
|||
|
return result.Keys;
|
|||
|
}
|
|||
|
}
|
|||
|
public class NOT : Query
|
|||
|
{
|
|||
|
public Query Query { get; }
|
|||
|
|
|||
|
public NOT(Query query)
|
|||
|
{
|
|||
|
Query = query;
|
|||
|
}
|
|||
|
|
|||
|
public override IEnumerable<Guid> Execute(IStorage storage)
|
|||
|
{
|
|||
|
BTree<Guid> notSet = new BTree<Guid>();
|
|||
|
BTree<Guid> result = new BTree<Guid>();
|
|||
|
|
|||
|
notSet.AddRange(Query.Execute(storage));
|
|||
|
|
|||
|
foreach (Guid documentID in storage.GetDocumentIDs())
|
|||
|
{
|
|||
|
if (!notSet.ContainsKey(documentID))
|
|||
|
result.Add(documentID);
|
|||
|
}
|
|||
|
|
|||
|
return result.Keys;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|