// /** // * 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(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(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(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(string propertyName, IEnumerable 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(string propertyName, Predicate predicate) => IF(IndexPath.TranslatePropertyPath(typeof(T),propertyName), predicate); public static Query IF(string propertyName,Predicate predicate) { return new IMPL.IF(propertyName, predicate); } public abstract IEnumerable Execute(IStorage storage); class IMPL { public class IF : Query { public string PropertyName { get; } public Predicate Predicate { get; } public IF(string propertyName,Predicate predicate) { PropertyName = propertyName; Predicate = predicate; } public override IEnumerable 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 Execute(IStorage storage) { BTree firstSet = new BTree(); firstSet.AddRange( Query.Execute(storage) ); foreach (Query aQuery in Queries) { if (firstSet.Count == 0) return new Guid[0]; BTree nextSet = new BTree(); 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 Execute(IStorage storage) { BTree result = new BTree(); 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 Execute(IStorage storage) { BTree notSet = new BTree(); BTree result = new BTree(); notSet.AddRange(Query.Execute(storage)); foreach (Guid documentID in storage.GetDocumentIDs()) { if (!notSet.ContainsKey(documentID)) result.Add(documentID); } return result.Keys; } } } } }