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;
4using System.Reflection;
5using System.Threading.Tasks;
15
17{
22 {
23 private static readonly MethodInfo findMethodGeneric = GetFindMethod();
24
37 : base(new ScriptNode[] { Type, Offset, MaxCount, Filter, SortOrder },
38 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Vector },
40 {
41 }
42
43 private static MethodInfo GetFindMethod()
44 {
45 Type T = typeof(Database);
46 foreach (MethodInfo MI in T.GetTypeInfo().GetDeclaredMethods("Find"))
47 {
48 ParameterInfo[] P = MI.GetParameters();
49 if (P.Length != 4 ||
50 P[0].ParameterType != typeof(int) ||
51 P[1].ParameterType != typeof(int) ||
52 P[2].ParameterType != typeof(Filter) ||
53 P[3].ParameterType != typeof(string[]))
54 {
55 continue;
56 }
57
58 return MI;
59 }
60
61 return null;
62 }
63
67 public override string[] DefaultArgumentNames
68 {
69 get
70 {
71 return new string[]
72 {
73 "Type",
74 "Offset",
75 "MaxCount",
76 "Filter",
77 "SortOrder"
78 };
79 }
80 }
81
85 public override string FunctionName => nameof(FindObjects);
86
91 public override bool IsAsynchronous => true;
92
100 {
101 return this.EvaluateAsync(Arguments, Variables).Result;
102 }
103
110 public override async Task<IElement> EvaluateAsync(IElement[] Arguments, Variables Variables)
111 {
112 if (!(Arguments[0].AssociatedObjectValue is Type T))
113 throw new ScriptRuntimeException("First parameter must be a type.", this);
114
115 int Offset = (int)Expression.ToDouble(Arguments[1].AssociatedObjectValue);
116 int MaxCount = (int)Expression.ToDouble(Arguments[2].AssociatedObjectValue);
117 object FilterObj = Arguments[3].AssociatedObjectValue;
118 Filter Filter = FilterObj as Filter;
119 IVector V = Arguments[4] as IVector;
120 int i, c = V.Dimension;
121 string[] SortOrder = new string[c];
122
123 for (i = 0; i < c; i++)
124 SortOrder[i] = ToString(V.GetElement(i)) ?? string.Empty;
125
126 if (Filter is null && !(FilterObj is null))
127 {
128 Expression Exp = new Expression(FilterObj.ToString(), this.Expression.Source);
129 Filter = await this.ConvertAsync(Exp.Root, Variables);
130 }
131
132 MethodInfo MI = findMethodGeneric.MakeGenericMethod(new Type[] { T });
133 object Result = MI.Invoke(null, new object[] { Offset, MaxCount, Filter, SortOrder });
134 Result = await WaitPossibleTask(Result);
135
136 if (Result is IEnumerable E)
137 {
139
140 foreach (object Element in E)
141 Elements.Add(Expression.Encapsulate(Element));
142
143 return new ObjectVector(Elements);
144 }
145 else
146 return Expression.Encapsulate(Result);
147 }
148
149 private async Task<Filter> ConvertAsync(ScriptNode Node, Variables Variables)
150 {
151 if (Node is null)
152 return null;
153 else if (Node is And And)
154 {
155 return new FilterAnd(await this.ConvertAsync(And.LeftOperand, Variables),
156 await this.ConvertAsync(And.RightOperand, Variables));
157 }
158 else if (Node is Or Or)
159 {
160 return new FilterOr(await this.ConvertAsync(Or.LeftOperand, Variables),
161 await this.ConvertAsync(Or.RightOperand, Variables));
162 }
163 else if (Node is Operators.Dual.And And2)
164 {
165 return new FilterAnd(await this.ConvertAsync(And2.LeftOperand, Variables),
166 await this.ConvertAsync(And2.RightOperand, Variables));
167 }
168 else if (Node is Operators.Dual.Or Or2)
169 {
170 return new FilterOr(await this.ConvertAsync(Or2.LeftOperand, Variables),
171 await this.ConvertAsync(Or2.RightOperand, Variables));
172 }
173 else if (Node is Not Not)
174 return new FilterNot(await this.ConvertAsync(Not.Operand, Variables));
175 else if (Node is EqualTo EQ)
176 {
177 KeyValuePair<string, object> P = await this.CheckBinaryOperator(EQ, Variables);
178 return new FilterFieldEqualTo(P.Key, P.Value);
179 }
180 else if (Node is NotEqualTo NEQ)
181 {
182 KeyValuePair<string, object> P = await this.CheckBinaryOperator(NEQ, Variables);
183 return new FilterFieldNotEqualTo(P.Key, P.Value);
184 }
185 else if (Node is LesserThan LT)
186 {
187 KeyValuePair<string, object> P = await this.CheckBinaryOperator(LT, Variables);
188 return new FilterFieldLesserThan(P.Key, P.Value);
189 }
190 else if (Node is GreaterThan GT)
191 {
192 KeyValuePair<string, object> P = await this.CheckBinaryOperator(GT, Variables);
193 return new FilterFieldGreaterThan(P.Key, P.Value);
194 }
195 else if (Node is LesserThanOrEqualTo LTE)
196 {
197 KeyValuePair<string, object> P = await this.CheckBinaryOperator(LTE, Variables);
198 return new FilterFieldLesserOrEqualTo(P.Key, P.Value);
199 }
200 else if (Node is GreaterThanOrEqualTo GTE)
201 {
202 KeyValuePair<string, object> P = await this.CheckBinaryOperator(GTE, Variables);
203 return new FilterFieldGreaterOrEqualTo(P.Key, P.Value);
204 }
205 else if (Node is Range Range)
206 {
208 throw new ScriptRuntimeException("Middle operands in ternary filter operators need to be a variable references, as they refer to field names.", this);
209
210 string FieldName = v.VariableName;
211 object Min = (await Range.LeftOperand.EvaluateAsync(Variables)).AssociatedObjectValue;
212 object Max = (await Range.RightOperand.EvaluateAsync(Variables)).AssociatedObjectValue;
213
214 Filter[] Filters = new Filter[2];
215
217 Filters[0] = new FilterFieldGreaterOrEqualTo(FieldName, Min);
218 else
219 Filters[0] = new FilterFieldGreaterThan(FieldName, Min);
220
222 Filters[1] = new FilterFieldLesserOrEqualTo(FieldName, Max);
223 else
224 Filters[1] = new FilterFieldLesserThan(FieldName, Max);
225
226 return new FilterAnd(Filters);
227 }
228 else if (Node is Like)
229 {
230 KeyValuePair<string, object> P = await this.CheckBinaryOperator((BinaryOperator)Node, Variables);
231 string RegEx = Database.WildcardToRegex(P.Value is string s ? s : Expression.ToExpressionString(P.Value), "*");
232 return new FilterFieldLikeRegEx(P.Key, RegEx);
233 }
234 else if (Node is NotLike)
235 {
236 KeyValuePair<string, object> P = await this.CheckBinaryOperator((BinaryOperator)Node, Variables);
237 string RegEx = Database.WildcardToRegex(P.Value is string s ? s : Expression.ToExpressionString(P.Value), "*");
238 return new FilterNot(new FilterFieldLikeRegEx(P.Key, RegEx));
239 }
240 else
241 throw new ScriptRuntimeException("Invalid operation for filters: " + Node.GetType().FullName, this);
242 }
243
244 private async Task<KeyValuePair<string, object>> CheckBinaryOperator(BinaryOperator Operator, Variables Variables)
245 {
246 if (!(Operator.LeftOperand is VariableReference v))
247 throw new ScriptRuntimeException("Left operands in binary filter operators need to be a variable references, as they refer to field names.", this);
248
249 return new KeyValuePair<string, object>(v.VariableName, (await Operator.RightOperand.EvaluateAsync(Variables)).AssociatedObjectValue);
250 }
251 }
252}
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:21
static string WildcardToRegex(string s, string Wildcard)
Converts a wildcard string to a regular expression string.
Definition: Database.cs:2426
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
A chunked list is a linked list of chunks of objects of type T .
Definition: ChunkedList.cs:54
Base class for all types of elements.
Definition: Element.cs:14
Class managing a script expression.
Definition: Expression.cs:41
ScriptNode Root
Root script node.
Definition: Expression.cs:4496
static IElement Encapsulate(object Value)
Encapsulates an object.
Definition: Expression.cs:5241
static double ToDouble(object Object)
Converts an object to a double value.
Definition: Expression.cs:5110
static string ToExpressionString(object Value)
Converts an object to a string, that can be parsed as part of an expression.
Definition: Expression.cs:5052
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
override string ToString()
Definition: ScriptNode.cs:359
static async Task< object > WaitPossibleTask(object Result)
Waits for any asynchronous process to terminate.
Definition: ScriptNode.cs:441
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:22
override string[] DefaultArgumentNames
Default Argument names
Definition: FindObjects.cs:68
override string FunctionName
Name of the function
Definition: FindObjects.cs:85
override async Task< IElement > EvaluateAsync(IElement[] Arguments, Variables Variables)
Evaluates the function.
Definition: FindObjects.cs:110
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:36
override IElement Evaluate(IElement[] Arguments, Variables Variables)
Evaluates the function.
Definition: FindObjects.cs:99
override bool IsAsynchronous
If the node (or its decendants) include asynchronous evaluation. Asynchronous nodes should be evaluat...
Definition: FindObjects.cs:91
Collection of variables.
Definition: Variables.cs:25
Basic interface for all types of elements.
Definition: IElement.cs:21
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