Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
SourceReference.cs
1using System;
2using System.Collections.Generic;
3using System.Reflection;
4using System.Threading.Tasks;
5using System.Xml;
6using Waher.Events;
15
17{
22 {
23 private ScriptNode source;
24 private ScriptNode alias;
25
34 : this(Source, null, Start, Length, Expression)
35 {
36 }
37
47 : base(Start, Length, Expression)
48 {
49 this.source = Source;
50 this.source?.SetParent(this);
51
52 this.alias = Alias;
53 this.alias?.SetParent(this);
54 }
55
61 public override async Task<IDataSource> GetSource(Variables Variables)
62 {
63 string Alias;
64
65 if (this.alias is null)
66 Alias = string.Empty;
67 else if (this.alias is VariableReference Ref)
68 Alias = Ref.VariableName;
69 else
70 Alias = (await this.alias.EvaluateAsync(Variables)).AssociatedObjectValue?.ToString();
71
72 if (this.source is VariableReference Ref2)
73 return GetDataSource(Ref2, Alias, Variables);
74 else
75 {
76 if (this.source is IEvaluateAsync AsyncSource)
77 return GetDataSource(string.Empty, Alias, await AsyncSource.EvaluateAsync(Variables), this.source);
78 else
79 return GetDataSource(string.Empty, Alias, await this.source.EvaluateAsync(Variables), this.source);
80 }
81 }
82
83 private static IDataSource GetDataSource(string Name, string Alias, IElement E, ScriptNode Source)
84 {
85 object Obj = E.AssociatedObjectValue;
86
87 if (Obj is IToMatrix ToMatrix)
88 {
89 E = ToMatrix.ToMatrix();
91 }
92
93 if (Obj is Type T)
94 return new TypeSource(T, Alias);
95 else if (Obj is string s)
96 return new CollectionSource(s, Alias);
97 else if (E is ObjectMatrix OM && OM.HasColumnNames)
98 return new VectorSource(Name, Alias, VectorSource.ToGenericObjectVector(OM), Source);
99 else if (E is IVector V)
100 return new VectorSource(Name, Alias, V, Source);
101 else if (Obj is XmlDocument Doc)
102 return new XmlSource(Name, Alias, Doc, Source);
103 else if (Obj is XmlNode N)
104 return new XmlSource(Name, Alias, N, Source);
105 else if (Obj is IDataSource DataSource)
106 return DataSource;
107
108 throw new ScriptRuntimeException("Data source type not supported: " + E.AssociatedObjectValue?.GetType()?.FullName, Source);
109 }
110
111 private static IDataSource GetDataSource(VariableReference Source, string Alias, Variables Variables)
112 {
113 string Name = Source.VariableName;
114
115 if (Variables.TryGetVariable(Name, out Variable v))
116 return GetDataSource(Name, Alias, v.ValueElement, Source);
117
118 if (Expression.TryGetConstant(Name, Variables, out IElement ValueElement))
119 return GetDataSource(Name, Alias, ValueElement, Source);
120
121 if (Types.TryGetQualifiedNames(Name, out string[] QualifiedNames))
122 {
123 if (QualifiedNames.Length == 1)
124 {
125 Type T = Types.GetType(QualifiedNames[0]);
126
127 if (!(T is null))
128 return new TypeSource(T, Alias);
129 }
130 else
131 {
132 List<KeyValuePair<string, object>> TypesWithCollectionNames = null;
133 Type TypeWithCollection = null;
134 bool CollectionUnique = true;
135
136 foreach (string QualifiedName in QualifiedNames)
137 {
138 Type T = Types.GetType(QualifiedName);
139 if (T is null)
140 continue;
141
142 TypeInfo TI = T.GetTypeInfo();
143 int Nr = 1;
144
145 if (!(TI.GetCustomAttribute<CollectionNameAttribute>() is null))
146 {
147 if (TypeWithCollection is null)
148 TypeWithCollection = T;
149 else
150 {
151 CollectionUnique = false;
152
153 if (TypesWithCollectionNames is null)
154 {
155 TypesWithCollectionNames = new List<KeyValuePair<string, object>>
156 {
157 new KeyValuePair<string, object>("Type " + Nr.ToString(), TypeWithCollection.FullName)
158 };
159
160 Nr++;
161 }
162
163 TypesWithCollectionNames.Add(new KeyValuePair<string, object>(Nr.ToString(), T.FullName));
164 Nr++;
165 }
166 }
167 }
168
169 if (TypeWithCollection is null)
170 {
171 Log.Warning("A collection was referenced using a relative type name. The type does not have a collection name defined. To avoid confusion, reference the collection name as a string constant instead of a variable reference.",
172 Name, string.Empty, "DBOpt");
173 }
174 else
175 {
176 if (CollectionUnique)
177 {
178 Log.Warning("A collection was referenced using a relative type name. Multiple types are available with the same relative type name, but only one had a collection name defined for it. Using this type. Use fully.qualified type names to avoid confusion.",
179 Name, TypeWithCollection.FullName, "DBOpt");
180
181 return new TypeSource(TypeWithCollection, Alias);
182 }
183 else
184 {
185 Log.Error("A collection was referenced using a relative type name. Multiple types are available with the same relative type name and with collection names. Use fully.qualified type names to avoid confusion.",
186 Name, string.Empty, "DBOpt", TypesWithCollectionNames.ToArray());
187 }
188 }
189 }
190 }
191
192 return new CollectionSource(Name, Alias);
193 }
194
202 public override bool ForAllChildNodes(ScriptNodeEventHandler Callback, object State, SearchMethod Order)
203 {
204 if (Order == SearchMethod.DepthFirst)
205 {
206 if (!(this.source?.ForAllChildNodes(Callback, State, Order) ?? true) ||
207 !(this.alias?.ForAllChildNodes(Callback, State, Order) ?? true))
208 {
209 return false;
210 }
211 }
212
213 ScriptNode NewNode;
214 bool b;
215
216 if (!(this.source is null))
217 {
218 b = !Callback(this.source, out NewNode, State);
219 if (!(NewNode is null))
220 {
221 this.source = NewNode;
222 this.source.SetParent(this);
223 }
224
225 if (b || (Order == SearchMethod.TreeOrder && !this.source.ForAllChildNodes(Callback, State, Order)))
226 return false;
227 }
228
229 if (!(this.alias is null))
230 {
231 b = !Callback(this.alias, out NewNode, State);
232 if (!(NewNode is null))
233 {
234 this.alias = NewNode;
235 this.alias.SetParent(this);
236 }
237
238 if (b || (Order == SearchMethod.TreeOrder && !this.alias.ForAllChildNodes(Callback, State, Order)))
239 return false;
240 }
241
242 if (Order == SearchMethod.BreadthFirst)
243 {
244 if (!(this.source?.ForAllChildNodes(Callback, State, Order) ?? true) ||
245 !(this.alias?.ForAllChildNodes(Callback, State, Order) ?? true))
246 {
247 return false;
248 }
249 }
250
251 return true;
252 }
253
255 public override bool Equals(object obj)
256 {
257 return (obj is SourceReference O &&
258 AreEqual(this.source, O.source) &&
259 AreEqual(this.alias, O.alias) &&
260 base.Equals(obj));
261 }
262
264 public override int GetHashCode()
265 {
266 int Result = base.GetHashCode();
267 Result ^= Result << 5 ^ GetHashCode(this.source);
268 Result ^= Result << 5 ^ GetHashCode(this.alias);
269
270 return Result;
271 }
272
273 }
274}
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:13
static void Warning(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs a warning event.
Definition: Log.cs:566
static void Error(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs an error event.
Definition: Log.cs:682
This attribute defines the name of the collection that will house objects of this type.
Static class that dynamically manages types and interfaces available in the runtime environment.
Definition: Types.cs:14
static Type GetType(string FullName)
Gets a type, given its full name.
Definition: Types.cs:41
static bool TryGetQualifiedNames(string UnqualifiedName, out string[] QualifiedNames)
Gets an array (possibly null) of qualified names relating to an unqualified name.
Definition: Types.cs:243
Class managing a script expression.
Definition: Expression.cs:39
static bool TryGetConstant(string Name, Variables Variables, out IElement ValueElement)
Tries to get a constant value, given its name.
Definition: Expression.cs:3307
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 bool AreEqual(ScriptNode S1, ScriptNode S2)
Compares if two script nodes are equal.
Definition: ScriptNode.cs:275
int Start
Start position in script expression.
Definition: ScriptNode.cs:92
void SetParent(ScriptNode Parent)
Sets the parent node. Can only be used when expression is being parsed.
Definition: ScriptNode.cs:132
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
Represents a variable reference.
bool HasColumnNames
If the matrix has column names defined.
ToMatrix(ScriptNode Operand, bool NullCheck, int Start, int Length, Expression Expression)
To-Matrix operator.
Definition: ToMatrix.cs:22
Abstract base class for source definitions
override async Task< IDataSource > GetSource(Variables Variables)
Gets the actual data source, from its definition.
override bool ForAllChildNodes(ScriptNodeEventHandler Callback, object State, SearchMethod Order)
Calls the callback method for all child nodes.
SourceReference(ScriptNode Source, int Start, int Length, Expression Expression)
Direct reference to a data source.
SourceReference(ScriptNode Source, ScriptNode Alias, int Start, int Length, Expression Expression)
Direct reference to a data source.
Data Source defined by a collection name
Data Source defined by a type definition
Definition: TypeSource.cs:21
static ObjectVector ToGenericObjectVector(ObjectMatrix ResultSet)
Converts an object matrix, with named columns, to a vector of objects ex nihilo.
Contains information about a variable.
Definition: Variable.cs:10
Collection of variables.
Definition: Variables.cs:25
virtual bool TryGetVariable(string Name, out Variable Variable)
Tries to get a variable object, given its name.
Definition: Variables.cs:52
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
Interface for script nodes with asynchronous evaluation
Interface for objects that can be converted into matrices.
Definition: IToMatrix.cs:9
Interface for data sources that can be used in SQL statements.
Definition: IDataSource.cs:13
delegate bool ScriptNodeEventHandler(ScriptNode Node, out ScriptNode NewNode, object State)
Delegate for ScriptNode callback methods.
SearchMethod
Method to traverse the expression structure
Definition: ScriptNode.cs:38