1 package de.dlr.shepard.data.timeseries.daos;
2
3 import static de.dlr.shepard.common.util.CypherDslHelper.internalIdIs;
4 import static de.dlr.shepard.common.util.CypherDslHelper.notDeleted;
5 import static de.dlr.shepard.common.util.Neo4jLabels.HAS_TIMESERIES_TUPLE;
6 import static de.dlr.shepard.common.util.Neo4jLabels.IS_IN_CONTAINER;
7 import static de.dlr.shepard.common.util.Neo4jLabels.TIMESERIES;
8 import static de.dlr.shepard.common.util.Neo4jLabels.TIMESERIES_CONTAINER;
9 import static de.dlr.shepard.common.util.Neo4jLabels.TIMESERIES_TUPLE;
10 import static org.neo4j.cypherdsl.core.Cypher.match;
11 import static org.neo4j.cypherdsl.core.Cypher.node;
12
13 import de.dlr.shepard.common.neo4j.daos.GenericDAO;
14 import de.dlr.shepard.data.timeseries.model.Timeseries;
15 import de.dlr.shepard.data.timeseries.model.TimeseriesContainer;
16 import de.dlr.shepard.data.timeseries.model.TimeseriesTuple;
17 import jakarta.enterprise.context.RequestScoped;
18 import java.util.Collections;
19 import java.util.Map;
20 import java.util.NoSuchElementException;
21 import java.util.Optional;
22 import java.util.stream.Stream;
23 import java.util.stream.StreamSupport;
24 import org.neo4j.cypherdsl.core.Cypher;
25
26 @RequestScoped
27 public class TimeseriesDAO extends GenericDAO<Timeseries> {
28
29 @Override
30 public Class<Timeseries> getEntityType() {
31 return Timeseries.class;
32 }
33
34
35
36
37
38
39
40
41
42 private Stream<Timeseries> queryCypherWithRelations(String query) {
43 var result = session.query(query, Map.of(), true);
44 return StreamSupport.stream(result.spliterator(), false).map(resultEntry -> {
45 Timeseries tsObj = (Timeseries) resultEntry.get("ts");
46 TimeseriesContainer tscObj = (TimeseriesContainer) resultEntry.get("tsc");
47 TimeseriesTuple tsTupleObj = (TimeseriesTuple) resultEntry.get("tst");
48 tsObj.setContainer(tscObj);
49 tsObj.setTimeseriesTuple(tsTupleObj);
50 return tsObj;
51 });
52 }
53
54 public Stream<Timeseries> getAllTimeseriesInContainer(long containerId) {
55 var tsc = node(TIMESERIES_CONTAINER).named("tsc");
56 var ts = node(TIMESERIES).named("ts");
57 var tsTuple = node(TIMESERIES_TUPLE).named("tst");
58 var isInContainer = ts.relationshipTo(tsc, IS_IN_CONTAINER);
59 var hasTuple = ts.relationshipTo(tsTuple, HAS_TIMESERIES_TUPLE);
60 var query = match(isInContainer, hasTuple)
61 .where(internalIdIs(tsc, containerId).and(notDeleted(ts)))
62 .returning(ts, tsc, tsTuple)
63 .build()
64 .getCypher();
65 return queryCypherWithRelations(query);
66 }
67
68 public long getCurrentMaximumTimeseriesId() {
69 var ts = node(TIMESERIES);
70 var query = match(ts)
71 .returning(ts.property("timeseriesId"))
72 .orderBy(ts.property("timeseriesId").descending())
73 .limit(1)
74 .build()
75 .getCypher();
76 try {
77 return session.query(Long.class, query, Collections.emptyMap()).iterator().next();
78 } catch (NoSuchElementException e) {
79
80 return 0;
81 }
82 }
83
84 public Optional<Timeseries> findTimeseries(long containerId, TimeseriesTuple tsTuple) {
85 var tsTupleNode = node(TIMESERIES_TUPLE)
86 .withProperties(
87 "measurement",
88 Cypher.literalOf(tsTuple.getMeasurement()),
89 "device",
90 Cypher.literalOf(tsTuple.getDevice()),
91 "location",
92 Cypher.literalOf(tsTuple.getLocation()),
93 "symbolicName",
94 Cypher.literalOf(tsTuple.getSymbolicName()),
95 "field",
96 Cypher.literalOf(tsTuple.getField())
97 )
98 .named("tst");
99 var tsc = node(TIMESERIES_CONTAINER).named("tsc");
100 var ts = node(TIMESERIES).named("ts");
101 var query = match(tsTupleNode.relationshipFrom(ts, HAS_TIMESERIES_TUPLE).relationshipTo(tsc, IS_IN_CONTAINER))
102 .where(internalIdIs(tsc, containerId).and(notDeleted(ts)))
103 .returning(tsTupleNode, tsc, ts)
104 .build()
105 .getCypher();
106
107 return queryCypherWithRelations(query).findFirst();
108 }
109
110 public Optional<Timeseries> findByTimeseriesId(long timeseriesId) {
111 var ts = node(TIMESERIES).withProperties("timeseriesId", Cypher.literalOf(timeseriesId));
112 var related = Cypher.anyNode();
113 var rels = ts.relationshipTo(related);
114 var query = match(ts, rels, related).where(notDeleted(ts)).returning(ts, rels, related).build().getCypher();
115 return this.findByQuery(query).findFirst();
116 }
117
118 public void deleteAllTimeseriesInContainer(long containerId) {
119 var ts = node(TIMESERIES);
120 var tsc = node(TIMESERIES_CONTAINER);
121 var query = match(ts.relationshipTo(tsc, IS_IN_CONTAINER))
122 .where(internalIdIs(tsc, containerId))
123 .set(ts.property("deleted"), Cypher.literalOf(true))
124 .build()
125 .getCypher();
126 session.query(query, Collections.emptyMap());
127 }
128 }