Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
JoinedObject.cs
1using System;
2using System.Collections.Generic;
3using System.Reflection;
4using System.Text;
9
11{
15 public class JoinedObject
16 {
17 private readonly Dictionary<string, Rec> properties = new Dictionary<string, Rec>();
18 private readonly Type leftType;
19 private readonly Type rightType;
20 private readonly GenericObject leftGen;
21 private readonly GenericObject rightGen;
22 private readonly object left;
23 private readonly object right;
24 private readonly string leftName;
25 private readonly string rightName;
26 private readonly bool hasLeftName;
27 private readonly bool hasRightName;
28 private readonly bool isLeftGen;
29 private readonly bool isRightGen;
30 private string objectId = null;
31
39 public JoinedObject(object Left, string LeftName, object Right, string RightName)
40 {
41 this.left = Left;
42 this.leftGen = Left as GenericObject;
43 this.leftType = this.left?.GetType();
44 this.leftName = LeftName;
45 this.hasLeftName = !string.IsNullOrEmpty(this.leftName);
46 this.isLeftGen = !(this.leftGen is null);
47 this.right = Right;
48 this.rightGen = Right as GenericObject;
49 this.rightType = this.right?.GetType();
50 this.rightName = RightName;
51 this.hasRightName = !string.IsNullOrEmpty(this.rightName);
52 this.isRightGen = !(this.rightGen is null);
53 }
54
60 public object this[string Index]
61 {
62 get
63 {
64 if (this.isLeftGen && this.leftGen.TryGetFieldValue(Index, out object Value))
65 return Value;
66 else if (this.isRightGen && this.rightGen.TryGetFieldValue(Index, out Value))
67 return Value;
68 else if (this.hasLeftName && string.Compare(Index, this.leftName, true) == 0)
69 return this.left;
70 else if (this.hasRightName && string.Compare(Index, this.rightName, true) == 0)
71 return this.right;
72
73 Rec Rec;
74
75 lock (this.properties)
76 {
77 if (!this.properties.TryGetValue(Index, out Rec))
78 {
79 Rec = this.GetRecLocked(Index);
80 this.properties[Index] = Rec;
81 }
82 }
83
84 if (!(Rec.PI is null))
85 {
86 if (Rec.Indexed)
87 return ScriptNode.UnnestPossibleTaskSync(Rec.PI.GetValue(Rec.Left ? this.left : this.right, new object[] { Index })); // TODO: Async
88 else
89 return ScriptNode.UnnestPossibleTaskSync(Rec.PI.GetValue(Rec.Left ? this.left : this.right)); // TODO: Async
90 }
91 else if (!(Rec.FI is null))
92 return ScriptNode.UnnestPossibleTaskSync(Rec.FI.GetValue(Rec.Left ? this.left : this.right)); // TODO: Async
93 else
94 return null;
95 }
96 }
97
98 private Rec GetRecLocked(string Index)
99 {
100 PropertyInfo PI;
101 FieldInfo FI;
102
103 if (!(this.leftType is null))
104 {
105 PI = this.leftType.GetRuntimeProperty(Index);
106 if (!(PI is null))
107 {
108 if (PI.CanRead && PI.GetMethod.IsPublic)
109 return new Rec() { PI = PI, Left = true };
110 else
111 return new Rec();
112 }
113
114 FI = this.leftType.GetRuntimeField(Index);
115 if (!(FI is null))
116 {
117 if (FI.IsPublic)
118 return new Rec() { FI = FI, Left = true };
119 else
120 return new Rec();
121 }
122
123 if (VectorIndex.TryGetIndexProperty(this.leftType, true, false, out PI, out _))
124 return new Rec() { PI = PI, Left = true, Indexed = true };
125 }
126
127 if (!(this.rightType is null))
128 {
129 PI = this.rightType.GetRuntimeProperty(Index);
130 if (!(PI is null))
131 {
132 if (PI.CanRead && PI.GetMethod.IsPublic)
133 return new Rec() { PI = PI };
134 else
135 return new Rec();
136 }
137
138 FI = this.rightType.GetRuntimeField(Index);
139 if (!(FI is null))
140 {
141 if (FI.IsPublic)
142 return new Rec() { FI = FI };
143 else
144 return new Rec();
145 }
146
147 if (VectorIndex.TryGetIndexProperty(this.rightType, true, false, out PI, out _))
148 return new Rec() { PI = PI, Indexed = true };
149 }
150
151 return new Rec();
152 }
153
154 private class Rec
155 {
156 public PropertyInfo PI;
157 public FieldInfo FI;
158 public bool Left;
159 public bool Indexed;
160 }
161
165 public string ObjectId
166 {
167 get
168 {
169 if (this.objectId is null)
170 {
171 StringBuilder sb = new StringBuilder();
172 object Id;
173
174 if (!(this.left is null))
175 {
176 Id = Database.TryGetObjectId(this.left).Result;
177 if (!(Id is null))
178 sb.Append(Id.ToString());
179 }
180
181 sb.Append(':');
182
183 if (!(this.right is null))
184 {
185 Id = Database.TryGetObjectId(this.right).Result;
186 if (!(Id is null))
187 sb.Append(Id.ToString());
188 }
189
190 this.objectId = sb.ToString();
191 }
192
193 return this.objectId;
194 }
195 }
196
198 public override bool Equals(object obj)
199 {
200 return (obj is JoinedObject Obj &&
201 this.ObjectId == Obj.ObjectId);
202 }
203
205 public override int GetHashCode()
206 {
207 return this.ObjectId.GetHashCode();
208
209 }
210 }
211}
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:19
static Task< object > TryGetObjectId(object Object)
Tries to get the Object ID of an object, if it exists.
Definition: Database.cs:1611
Generic object. Contains a sequence of properties.
Base class for all nodes in a parsed script tree.
Definition: ScriptNode.cs:69
static object UnnestPossibleTaskSync(object Result)
Checks if Result is an asynchronous results. If so, blocks the current thread until the result is co...
Definition: ScriptNode.cs:436
static bool TryGetIndexProperty(Type T, bool ForReading, bool ForWriting, out PropertyInfo PropertyInfo, out ParameterInfo[] Parameters)
Tries to get a one-dimensional index property of a Type.
Definition: VectorIndex.cs:133
JoinedObject(object Left, string LeftName, object Right, string RightName)
Represents a joined object.
Definition: JoinedObject.cs:39