Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
FindObjects.cs
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Reflection;
5using System.Threading.Tasks;
14
16{
21 {
22 private static readonly MethodInfo findMethodGeneric = GetFindMethod();
23
36 : base(new ScriptNode[] { Type, Offset, MaxCount, Filter, SortOrder },
37 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Vector },
39 {
40 }
41
42 private static MethodInfo GetFindMethod()
43 {
44 Type T = typeof(Database);
45 foreach (MethodInfo MI in T.GetTypeInfo().GetDeclaredMethods("Find"))
46 {
47 ParameterInfo[] P = MI.GetParameters();
48 if (P.Length != 4 ||
49 P[0].ParameterType != typeof(int) ||
50 P[1].ParameterType != typeof(int) ||
51 P[2].ParameterType != typeof(Filter) ||
52 P[3].ParameterType != typeof(string[]))
53 {
54 continue;
55 }
56
57 return MI;
58 }
59
60 return null;
61 }
62
66 public override string[] DefaultArgumentNames
67 {
68 get
69 {
70 return new string[]
71 {
72 "Type",
73 "Offset",
74 "MaxCount",
75 "Filter",
76 "SortOrder"
77 };
78 }
79 }
80
84 public override string FunctionName => nameof(FindObjects);
85
90 public override bool IsAsynchronous => true;
91
99 {
100 return this.EvaluateAsync(Arguments, Variables).Result;
101 }
102
109 public override async Task<IElement> EvaluateAsync(IElement[] Arguments, Variables Variables)
110 {
111 if (!(Arguments[0].AssociatedObjectValue is Type T))
112 throw new ScriptRuntimeException("First parameter must be a type.", this);
113
114 int Offset = (int)Expression.ToDouble(Arguments[1].AssociatedObjectValue);
115 int MaxCount = (int)Expression.ToDouble(Arguments[2].AssociatedObjectValue);
116 object FilterObj = Arguments[3].AssociatedObjectValue;
117 Filter Filter = FilterObj as Filter;
118 IVector V = Arguments[4] as IVector;
119 int i, c = V.Dimension;
120 string[] SortOrder = new string[c];
121
122 for (i = 0; i < c; i++)
123 SortOrder[i] = V.GetElement(i).AssociatedObjectValue.ToString();
124
125 if (Filter is null && !(FilterObj is null))
126 {
127 Expression Exp = new Expression(FilterObj.ToString(), this.Expression.Source);
128 Filter = await this.ConvertAsync(Exp.Root, Variables);
129 }
130
131 MethodInfo MI = findMethodGeneric.MakeGenericMethod(new Type[] { T });
132 object Result = MI.Invoke(null, new object[] { Offset, MaxCount, Filter, SortOrder });
133 Result = await WaitPossibleTask(Result);
134
135 if (Result is IEnumerable E)
136 {
137 LinkedList<IElement> Elements = new LinkedList<IElement>();
138 IEnumerator e = E.GetEnumerator();
139 while (e.MoveNext())
140 Elements.AddLast(Expression.Encapsulate(e.Current));
141
142 return new ObjectVector(Elements);
143 }
144 else
145 return Expression.Encapsulate(Result);
146 }
147
148 private async Task<Filter> ConvertAsync(ScriptNode Node, Variables Variables)
149 {
150 if (Node is null)
151 return null;
152 else if (Node is And And)
153 {
154 return new FilterAnd(await this.ConvertAsync(And.LeftOperand, Variables),
155 await this.ConvertAsync(And.RightOperand, Variables));
156 }
157 else if (Node is Or Or)
158 {
159 return new FilterOr(await this.ConvertAsync(Or.LeftOperand, Variables),
160 await this.ConvertAsync(Or.RightOperand, Variables));
161 }
162 else if (Node is Operators.Dual.And And2)
163 {
164 return new FilterAnd(await this.ConvertAsync(And2.LeftOperand, Variables),
165 await this.ConvertAsync(And2.RightOperand, Variables));
166 }
167 else if (Node is Operators.Dual.Or Or2)
168 {
169 return new FilterOr(await this.ConvertAsync(Or2.LeftOperand, Variables),
170 await this.ConvertAsync(Or2.RightOperand, Variables));
171 }
172 else if (Node is Not Not)
173 return new FilterNot(await this.ConvertAsync(Not.Operand, Variables));
174 else if (Node is EqualTo EQ)
175 {
176 KeyValuePair<string, object> P = await this.CheckBinaryOperator(EQ, Variables);
177 return new FilterFieldEqualTo(P.Key, P.Value);
178 }
179 else if (Node is NotEqualTo NEQ)
180 {
181 KeyValuePair<string, object> P = await this.CheckBinaryOperator(NEQ, Variables);
182 return new FilterFieldNotEqualTo(P.Key, P.Value);
183 }
184 else if (Node is LesserThan LT)
185 {
186 KeyValuePair<string, object> P = await this.CheckBinaryOperator(LT, Variables);
187 return new FilterFieldLesserThan(P.Key, P.Value);
188 }
189 else if (Node is GreaterThan GT)
190 {
191 KeyValuePair<string, object> P = await this.CheckBinaryOperator(GT, Variables);
192 return new FilterFieldGreaterThan(P.Key, P.Value);
193 }
194 else if (Node is LesserThanOrEqualTo LTE)
195 {
196 KeyValuePair<string, object> P = await this.CheckBinaryOperator(LTE, Variables);
197 return new FilterFieldLesserOrEqualTo(P.Key, P.Value);
198 }
199 else if (Node is GreaterThanOrEqualTo GTE)
200 {
201 KeyValuePair<string, object> P = await this.CheckBinaryOperator(GTE, Variables);
202 return new FilterFieldGreaterOrEqualTo(P.Key, P.Value);
203 }
204 else if (Node is Range Range)
205 {
207 throw new ScriptRuntimeException("Middle operands in ternary filter operators need to be a variable references, as they refer to field names.", this);
208
209 string FieldName = v.VariableName;
210 object Min = (await Range.LeftOperand.EvaluateAsync(Variables)).AssociatedObjectValue;
211 object Max = (await Range.RightOperand.EvaluateAsync(Variables)).AssociatedObjectValue;
212
213 Filter[] Filters = new Filter[2];
214
216 Filters[0] = new FilterFieldGreaterOrEqualTo(FieldName, Min);
217 else
218 Filters[0] = new FilterFieldGreaterThan(FieldName, Min);
219
221 Filters[1] = new FilterFieldLesserOrEqualTo(FieldName, Max);
222 else
223 Filters[1] = new FilterFieldLesserThan(FieldName, Max);
224
225 return new FilterAnd(Filters);
226 }
227 else if (Node is Like)
228 {
229 KeyValuePair<string, object> P = await this.CheckBinaryOperator((BinaryOperator)Node, Variables);
230 string RegEx = Database.WildcardToRegex(P.Value is string s ? s : Expression.ToString(P.Value), "*");
231 return new FilterFieldLikeRegEx(P.Key, RegEx);
232 }
233 else if (Node is NotLike)
234 {
235 KeyValuePair<string, object> P = await this.CheckBinaryOperator((BinaryOperator)Node, Variables);
236 string RegEx = Database.WildcardToRegex(P.Value is string s ? s : Expression.ToString(P.Value), "*");
237 return new FilterNot(new FilterFieldLikeRegEx(P.Key, RegEx));
238 }
239 else
240 throw new ScriptRuntimeException("Invalid operation for filters: " + Node.GetType().FullName, this);
241 }
242
243 private async Task<KeyValuePair<string, object>> CheckBinaryOperator(BinaryOperator Operator, Variables Variables)
244 {
245 if (!(Operator.LeftOperand is VariableReference v))
246 throw new ScriptRuntimeException("Left operands in binary filter operators need to be a variable references, as they refer to field names.", this);
247
248 return new KeyValuePair<string, object>(v.VariableName, (await Operator.RightOperand.EvaluateAsync(Variables)).AssociatedObjectValue);
249 }
250 }
251}
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:19
static string WildcardToRegex(string s, string Wildcard)
Converts a wildcard string to a regular expression string.
Definition: Database.cs:1631
This filter selects objects that conform to all child-filters provided.
Definition: FilterAnd.cs:10
This filter selects objects that have a named field equal to a given value.
This filter selects objects that have a named field greater or equal to a given value.
This filter selects objects that have a named field greater than a given value.
This filter selects objects that have a named field lesser or equal to a given value.
This filter selects objects that have a named field lesser than a given value.
This filter selects objects that have a named field matching a given regular expression.
This filter selects objects that have a named field not equal to a given value.
Base class for all filter classes.
Definition: Filter.cs:15
This filter selects objects that does not conform to the child-filter provided.
Definition: FilterNot.cs:7
This filter selects objects that conform to any of the child-filters provided.
Definition: FilterOr.cs:10
Class managing a script expression.
Definition: Expression.cs:39
ScriptNode Root
Root script node.
Definition: Expression.cs:4299
static IElement Encapsulate(object Value)
Encapsulates an object.
Definition: Expression.cs:4955
static double ToDouble(object Object)
Converts an object to a double value.
Definition: Expression.cs:4824
static string ToString(double Value)
Converts a value to a string, that can be parsed as part of an expression.
Definition: Expression.cs:4496
Base class for all binary operators.
ScriptNode RightOperand
Right operand.
ScriptNode LeftOperand
Left operand.
Base class for multivariate funcions.
ScriptNode[] Arguments
Function arguments.
Base class for all nodes in a parsed script tree.
Definition: ScriptNode.cs:69
int Length
Length of expression covered by node.
Definition: ScriptNode.cs:101
static async Task< object > WaitPossibleTask(object Result)
Waits for any asynchronous process to terminate.
Definition: ScriptNode.cs:417
Expression Expression
Expression of which the node is a part.
Definition: ScriptNode.cs:177
int Start
Start position in script expression.
Definition: ScriptNode.cs:92
virtual Task< IElement > EvaluateAsync(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection. This method should be ...
Definition: ScriptNode.cs:158
ScriptNode MiddleOperand
Middle operand.
Represents a variable reference.
bool LeftInclusive
If the value specified by BinaryOperator.LeftOperand is included in the range.
Definition: Range.cs:41
bool RightInclusive
If the value specified by BinaryOperator.RightOperand is included in the range.
Definition: Range.cs:46
Finds objects in the object database.
Definition: FindObjects.cs:21
override string[] DefaultArgumentNames
Default Argument names
Definition: FindObjects.cs:67
override string FunctionName
Name of the function
Definition: FindObjects.cs:84
override async Task< IElement > EvaluateAsync(IElement[] Arguments, Variables Variables)
Evaluates the function.
Definition: FindObjects.cs:109
FindObjects(ScriptNode Type, ScriptNode Offset, ScriptNode MaxCount, ScriptNode Filter, ScriptNode SortOrder, int Start, int Length, Expression Expression)
Finds object in the object database.
Definition: FindObjects.cs:35
override IElement Evaluate(IElement[] Arguments, Variables Variables)
Evaluates the function.
Definition: FindObjects.cs:98
override bool IsAsynchronous
If the node (or its decendants) include asynchronous evaluation. Asynchronous nodes should be evaluat...
Definition: FindObjects.cs:90
Collection of variables.
Definition: Variables.cs:25
Basic interface for all types of elements.
Definition: IElement.cs:20
object AssociatedObjectValue
Associated object value.
Definition: IElement.cs:33
Basic interface for vectors.
Definition: IVector.cs:9
int Dimension
Dimension of vector.
Definition: IVector.cs:14
IElement GetElement(int Index)
Gets an element of the vector.
ArgumentType
Type of parameter used in a function definition or a lambda definition.
Definition: IFunction.cs:9