Skip to main content

drasi_functions_cypher/
lib.rs

1// Copyright 2024 The Drasi Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::sync::Arc;
16
17use drasi_core::evaluation::functions::*;
18
19use drasi_core::evaluation::functions::FunctionRegistry;
20#[cfg(test)]
21mod tests;
22
23pub trait CypherFunctionSet {
24    fn with_cypher_function_set(self) -> Arc<FunctionRegistry>;
25}
26
27impl CypherFunctionSet for Arc<FunctionRegistry> {
28    fn with_cypher_function_set(self) -> Arc<FunctionRegistry> {
29        register_default_cypher_functions(&self);
30        self
31    }
32}
33
34pub fn register_default_cypher_functions(registry: &FunctionRegistry) {
35    register_text_functions(registry);
36    register_numeric_functions(registry);
37    register_trigonometric_functions(registry);
38    register_cypher_scalar_functions(registry);
39    register_list_functions(registry);
40    register_metadata_functions(registry);
41    register_drasi_functions(registry);
42    register_context_mutators(registry);
43    register_aggregation_functions(registry);
44    register_temporal_instant_functions(registry);
45    register_temporal_duration_functions(registry);
46}
47
48fn register_text_functions(registry: &FunctionRegistry) {
49    registry.register_function("toUpper", Function::Scalar(Arc::new(ToUpper {})));
50    registry.register_function("toLower", Function::Scalar(Arc::new(ToLower {})));
51    registry.register_function("trim", Function::Scalar(Arc::new(Trim {})));
52    registry.register_function("ltrim", Function::Scalar(Arc::new(LTrim {})));
53    registry.register_function("rtrim", Function::Scalar(Arc::new(RTrim {})));
54    registry.register_function("reverse", Function::Scalar(Arc::new(Reverse {})));
55    registry.register_function("left", Function::Scalar(Arc::new(Left {})));
56    registry.register_function("right", Function::Scalar(Arc::new(Right {})));
57    registry.register_function("replace", Function::Scalar(Arc::new(Replace {})));
58    registry.register_function("split", Function::Scalar(Arc::new(Split {})));
59    registry.register_function("substring", Function::Scalar(Arc::new(Substring {})));
60    registry.register_function("toString", Function::Scalar(Arc::new(ToString {})));
61    registry.register_function(
62        "toStringOrNull",
63        Function::Scalar(Arc::new(ToStringOrNull {})),
64    );
65    registry.register_function("randomUUID", Function::Scalar(Arc::new(RandomUUID {})));
66}
67
68fn register_numeric_functions(registry: &FunctionRegistry) {
69    registry.register_function("abs", Function::Scalar(Arc::new(Abs {})));
70    registry.register_function("ceil", Function::Scalar(Arc::new(Ceil {})));
71    registry.register_function("floor", Function::Scalar(Arc::new(Floor {})));
72    registry.register_function("rand", Function::Scalar(Arc::new(Rand {})));
73    registry.register_function("round", Function::Scalar(Arc::new(Round {})));
74    registry.register_function("sign", Function::Scalar(Arc::new(Sign {})));
75}
76
77fn register_trigonometric_functions(registry: &FunctionRegistry) {
78    registry.register_function("cos", Function::Scalar(Arc::new(Cos {})));
79    registry.register_function("degrees", Function::Scalar(Arc::new(Degrees {})));
80    registry.register_function("pi", Function::Scalar(Arc::new(Pi {})));
81    registry.register_function("radians", Function::Scalar(Arc::new(Radians {})));
82    registry.register_function("sin", Function::Scalar(Arc::new(Sin {})));
83    registry.register_function("tan", Function::Scalar(Arc::new(Tan {})));
84}
85
86fn register_cypher_scalar_functions(registry: &FunctionRegistry) {
87    registry.register_function("char_length", Function::Scalar(Arc::new(CharLength {})));
88    registry.register_function(
89        "character_length",
90        Function::Scalar(Arc::new(CharLength {})),
91    );
92    registry.register_function("size", Function::Scalar(Arc::new(Size {})));
93    registry.register_function("toInteger", Function::Scalar(Arc::new(ToInteger {})));
94    registry.register_function(
95        "toIntegerOrNull",
96        Function::Scalar(Arc::new(ToIntegerOrNull {})),
97    );
98    registry.register_function("toFloat", Function::Scalar(Arc::new(ToFloat {})));
99    registry.register_function(
100        "toFloatOrNull",
101        Function::Scalar(Arc::new(ToFloatOrNull {})),
102    );
103    registry.register_function("toBoolean", Function::Scalar(Arc::new(ToBoolean {})));
104    registry.register_function(
105        "toBooleanOrNull",
106        Function::Scalar(Arc::new(ToBooleanOrNull {})),
107    );
108    registry.register_function("coalesce", Function::Scalar(Arc::new(Coalesce {})));
109    registry.register_function("nullIf", Function::Scalar(Arc::new(NullIf {})));
110    registry.register_function("isEmpty", Function::Scalar(Arc::new(IsEmpty {})));
111    registry.register_function("head", Function::Scalar(Arc::new(Head {})));
112    registry.register_function("last", Function::Scalar(Arc::new(CypherLast {})));
113    registry.register_function("timestamp", Function::Scalar(Arc::new(Timestamp {})));
114}
115
116fn register_list_functions(registry: &FunctionRegistry) {
117    registry.register_function("reduce", Function::LazyScalar(Arc::new(Reduce::new())));
118    registry.register_function("tail", Function::Scalar(Arc::new(Tail {})));
119    registry.register_function("range", Function::Scalar(Arc::new(Range {})));
120    registry.register_function("coll.distinct", Function::Scalar(Arc::new(Distinct {})));
121    registry.register_function("coll.indexOf", Function::Scalar(Arc::new(IndexOf {})));
122    registry.register_function("coll.insert", Function::Scalar(Arc::new(Insert {})));
123}
124
125fn register_metadata_functions(registry: &FunctionRegistry) {
126    registry.register_function("elementId", Function::Scalar(Arc::new(ElementId {})));
127    registry.register_function(
128        "drasi.changeDateTime",
129        Function::Scalar(Arc::new(ChangeDateTime {})),
130    );
131}
132
133fn register_drasi_functions(registry: &FunctionRegistry) {
134    registry.register_function("drasi.listMax", Function::Scalar(Arc::new(DrasiMax {})));
135    registry.register_function("drasi.listMin", Function::Scalar(Arc::new(DrasiMin {})));
136    registry.register_function("drasi.stdevp", Function::Scalar(Arc::new(DrasiStdevP {})));
137}
138
139fn register_context_mutators(registry: &FunctionRegistry) {
140    registry.register_function(
141        "retainHistory",
142        Function::ContextMutator(Arc::new(RetainHistory {})),
143    );
144}
145
146fn register_aggregation_functions(registry: &FunctionRegistry) {
147    registry.register_function("sum", Function::Aggregating(Arc::new(Sum {})));
148    registry.register_function("avg", Function::Aggregating(Arc::new(Avg {})));
149    registry.register_function("count", Function::Aggregating(Arc::new(Count {})));
150    registry.register_function("min", Function::Aggregating(Arc::new(Min {})));
151    registry.register_function("max", Function::Aggregating(Arc::new(Max {})));
152    registry.register_function("collect", Function::Aggregating(Arc::new(Collect {})));
153    registry.register_function(
154        "drasi.linearGradient",
155        Function::Aggregating(Arc::new(LinearGradient {})),
156    );
157    registry.register_function(
158        "drasi.last",
159        Function::Aggregating(Arc::new(AggregatingLast {})),
160    );
161}
162
163fn register_temporal_instant_functions(registry: &FunctionRegistry) {
164    registry.register_function("date", Function::Scalar(Arc::new(Date {})));
165    registry.register_function("date.truncate", Function::Scalar(Arc::new(Truncate {})));
166    registry.register_function(
167        "date.statement",
168        Function::Scalar(Arc::new(ClockFunction::new(
169            Clock::Statement,
170            ClockResult::Date,
171        ))),
172    );
173    registry.register_function(
174        "date.transaction",
175        Function::Scalar(Arc::new(ClockFunction::new(
176            Clock::Transaction,
177            ClockResult::Date,
178        ))),
179    );
180    registry.register_function(
181        "date.realtime",
182        Function::Scalar(Arc::new(ClockFunction::new(
183            Clock::RealTime,
184            ClockResult::Date,
185        ))),
186    );
187    registry.register_function("localtime", Function::Scalar(Arc::new(LocalTime {})));
188    registry.register_function(
189        "localtime.realtime",
190        Function::Scalar(Arc::new(ClockFunction::new(
191            Clock::RealTime,
192            ClockResult::LocalTime,
193        ))),
194    );
195    registry.register_function(
196        "localtime.transaction",
197        Function::Scalar(Arc::new(ClockFunction::new(
198            Clock::Transaction,
199            ClockResult::LocalTime,
200        ))),
201    );
202    registry.register_function(
203        "localtime.statement",
204        Function::Scalar(Arc::new(ClockFunction::new(
205            Clock::Statement,
206            ClockResult::LocalTime,
207        ))),
208    );
209    registry.register_function(
210        "localdatetime",
211        Function::Scalar(Arc::new(LocalDateTime {})),
212    );
213    registry.register_function(
214        "localdatetime.statement",
215        Function::Scalar(Arc::new(ClockFunction::new(
216            Clock::Statement,
217            ClockResult::LocalDateTime,
218        ))),
219    );
220    registry.register_function(
221        "localdatetime.transaction",
222        Function::Scalar(Arc::new(ClockFunction::new(
223            Clock::Transaction,
224            ClockResult::LocalDateTime,
225        ))),
226    );
227    registry.register_function(
228        "localdatetime.realtime",
229        Function::Scalar(Arc::new(ClockFunction::new(
230            Clock::RealTime,
231            ClockResult::LocalDateTime,
232        ))),
233    );
234    registry.register_function(
235        "time.realtime",
236        Function::Scalar(Arc::new(ClockFunction::new(
237            Clock::RealTime,
238            ClockResult::ZonedTime,
239        ))),
240    );
241    registry.register_function(
242        "time.statement",
243        Function::Scalar(Arc::new(ClockFunction::new(
244            Clock::Statement,
245            ClockResult::ZonedTime,
246        ))),
247    );
248    registry.register_function(
249        "time.transaction",
250        Function::Scalar(Arc::new(ClockFunction::new(
251            Clock::Transaction,
252            ClockResult::ZonedTime,
253        ))),
254    );
255    registry.register_function("time.truncate", Function::Scalar(Arc::new(Truncate {})));
256    registry.register_function("time", Function::Scalar(Arc::new(Time {})));
257    registry.register_function("datetime", Function::Scalar(Arc::new(DateTime {})));
258    registry.register_function(
259        "datetime.transaction",
260        Function::Scalar(Arc::new(ClockFunction::new(
261            Clock::Transaction,
262            ClockResult::ZonedDateTime,
263        ))),
264    );
265    registry.register_function(
266        "datetime.realtime",
267        Function::Scalar(Arc::new(ClockFunction::new(
268            Clock::RealTime,
269            ClockResult::ZonedDateTime,
270        ))),
271    );
272    registry.register_function(
273        "datetime.statement",
274        Function::Scalar(Arc::new(ClockFunction::new(
275            Clock::Statement,
276            ClockResult::ZonedDateTime,
277        ))),
278    );
279    registry.register_function("datetime.truncate", Function::Scalar(Arc::new(Truncate {})));
280    registry.register_function(
281        "localtime.truncate",
282        Function::Scalar(Arc::new(Truncate {})),
283    );
284    registry.register_function(
285        "localdatetime.truncate",
286        Function::Scalar(Arc::new(Truncate {})),
287    );
288}
289
290fn register_temporal_duration_functions(registry: &FunctionRegistry) {
291    registry.register_function("duration.between", Function::Scalar(Arc::new(Between {})));
292    registry.register_function("duration.inMonths", Function::Scalar(Arc::new(InMonths {})));
293    registry.register_function("duration.inDays", Function::Scalar(Arc::new(InDays {})));
294    registry.register_function(
295        "duration.inSeconds",
296        Function::Scalar(Arc::new(InSeconds {})),
297    );
298    registry.register_function("duration", Function::Scalar(Arc::new(DurationFunc {})));
299}