public static final Object formatValue(Class<?> clazz, Value value) { if(value.isNull()) return null; if(clazz.isAssignableFrom(Integer.class)) return (Integer)value.asInt(); if(clazz.isAssignableFrom(Short.class)) return Short.valueOf(value.asString()); if(clazz.isAssignableFrom(Character.class)) return (Character)value.asString().charAt(0); if(clazz.isAssignableFrom(Float.class)) return (Float)value.asFloat(); if(clazz.isAssignableFrom(Double.class)) return (Double)value.asDouble(); if(clazz.isAssignableFrom(Long.class)) return (Long)value.asLong(); if(clazz.isAssignableFrom(Number.class)) return value.asNumber(); if(clazz.isAssignableFrom(Boolean.class)) return (Boolean)value.asBoolean(); if(clazz.isAssignableFrom(byte[].class)) return value.asByteArray(); if(clazz.isAssignableFrom(LocalDate.class)) return value.asLocalDate(); if(clazz.isAssignableFrom(LocalTime.class)) return value.asLocalTime(); if(clazz.isAssignableFrom(LocalDateTime.class)) return value.asLocalDateTime(); if(clazz.isAssignableFrom(OffsetTime.class)) return value.asOffsetTime(); if(clazz.isAssignableFrom(IsoDuration.class)) return value.asIsoDuration(); if(clazz.isAssignableFrom(ZonedDateTime.class)) return value.asZonedDateTime(); if(clazz.isAssignableFrom(Date.class)) return LocalDateTimeOperation.toDate().convert(value.asLocalDateTime()); if(clazz.isAssignableFrom(String.class)) return formatToString(value); if(clazz.isAssignableFrom(Enum.class)) return MethodOperation.invoked(null , MethodOperation.getMethod(clazz , "valueOf" , String.class), value.asString()); throw new NotSupportConvertException(); }
@Test public void shouldCreateTheRelationshipAssociatedToANewStateHavingRequestedDate() { try (Driver driver = GraphDatabase .driver(neo4j.boltURI(), Config.build().withEncryption().toConfig()); Session session = driver.session()) { // Given Node entityA = initEntity(session); Node entityB = initEntity(session); String testType = "testType"; Long date = 593920000000L; // When String query = "MATCH (a:Entity), (b:Entity) WHERE id(a) = %d AND id(b) = %d WITH a, b CALL graph.versioner.relationship.create(a, b, '%s', {}, localdatetime('1988-10-27T02:46:40')) YIELD relationship RETURN relationship"; session.run(String.format(query, entityA.id(), entityB.id(), testType)); // Then String querySourceCurrent = "MATCH (e:Entity)-[r:CURRENT]->(:State)-[:%s]->(:R) WHERE id(e) = %d RETURN r"; Relationship currentRelationship = session.run(String.format(querySourceCurrent, testType, entityA.id())).single().get("r").asRelationship(); assertThat(currentRelationship) .matches(rel -> rel.containsKey("date") && rel.get("date").asLocalDateTime().equals(convertEpochToLocalDateTime(date))); } }
@Test public void shouldCreateAnEntityWithPropertiesWithAStateAndItsPropertiesWithAdditionalLabelAndDate() throws Throwable { // This is in a try-block, to make sure we close the driver after the test try (Driver driver = GraphDatabase .driver(neo4j.boltURI(), Config.build().withEncryption().toConfig()); Session session = driver.session()) { // When StatementResult result = session.run("CALL graph.versioner.init('Entity', {key:'value'}, {key:'value'}, 'Error', localdatetime('1988-10-27T02:46:40'))"); StatementResult entityResult = session.run("MATCH (e:Entity) RETURN properties(e) as props"); StatementResult stateResult = session.run("MATCH (s:State) RETURN s"); Node state = stateResult.single().get("s").asNode(); StatementResult stateProps = session.run("MATCH (s:State) RETURN properties(s) as props"); StatementResult currentResult = session.run("MATCH (e:Entity)-[:CURRENT]->(s:State) RETURN id(e) as id"); StatementResult hasStatusResult = session.run("MATCH (e:Entity)-[:HAS_STATE]->(s:State) RETURN id(e) as id"); StatementResult hasStatusDateResult = session.run("MATCH (e:Entity)-[rel:CURRENT]->(s:State) RETURN rel.date as date"); // Then assertThat(result.single().get("node").asNode().id(), equalTo(0L)); assertThat(entityResult.single().get("props").asMap().isEmpty(), equalTo(false)); assertThat(state.id(), equalTo(1L)); assertThat(stateProps.single().get("props").asMap().isEmpty(), equalTo(false)); assertThat(currentResult.single().get("id").asLong(), equalTo(0L)); assertThat(hasStatusResult.single().get("id").asLong(), equalTo(0L)); assertThat(state.hasLabel("Error"), equalTo(true)); assertThat(hasStatusDateResult.single().get("date").asLocalDateTime(), equalTo(convertEpochToLocalDateTime(593920000000L))); } }
@Test public void shouldCreateANewStateWithAdditionalLabelAndDate() throws Throwable { // This is in a try-block, to make sure we close the driver after the test try (Driver driver = GraphDatabase .driver(neo4j.boltURI(), Config.build().withEncryption().toConfig()); Session session = driver.session()) { // Given session.run("CREATE (e:Entity {key:'immutableValue'})-[:CURRENT {date:localdatetime('1988-10-27T00:00:00')}]->(s:State {key:'initialValue'})"); session.run("MATCH (e:Entity)-[:CURRENT]->(s:State) CREATE (e)-[:HAS_STATE {startDate:localdatetime('1988-10-27T00:00:00')}]->(s)"); // When StatementResult result = session.run("MATCH (e:Entity) WITH e CALL graph.versioner.update(e, {key:'newValue'}, 'Error', localdatetime('1988-10-27T02:46:40')) YIELD node RETURN node"); StatementResult countStateResult = session.run("MATCH (s:State) RETURN count(s) as s"); StatementResult nextResult = session.run("MATCH (s1:State)-[:PREVIOUS]->(s2:State) return s2"); StatementResult correctStateResult = session.run("MATCH (s1:State)-[:PREVIOUS]->(s2:State) WITH s1 MATCH (e:Entity)-[:CURRENT]->(s1) return e"); StatementResult currentStateResult = session.run("MATCH (e:Entity)-[:CURRENT]->(s) return s"); StatementResult dateResult = session.run("MATCH (e:Entity)-[r:CURRENT]->(s) RETURN r.date as relDate"); StatementResult hasStatusDateResult = session.run("MATCH (e:Entity)-[:CURRENT]->(s:State)-[:PREVIOUS]->(s2:State)<-[rel:HAS_STATE]-(e) RETURN rel.endDate as endDate"); // Then assertThat(countStateResult.single().get("s").asLong(), equalTo(2L)); assertThat(nextResult.single().get("s2").asNode().id(), equalTo(1L)); assertThat(correctStateResult.single().get("e").asNode().id(), equalTo(0L)); assertThat(currentStateResult.single().get("s").asNode().hasLabel("Error"), equalTo(true)); assertThat(dateResult.single().get("relDate").asLocalDateTime(), equalTo(convertEpochToLocalDateTime(593920000000L))); assertThat(hasStatusDateResult.single().get("endDate").asLocalDateTime(), equalTo(convertEpochToLocalDateTime(593920000000L))); } }
@Test public void shouldCreateAndPatchANewStateWithAdditionalLabelAndDate() throws Throwable { // This is in a try-block, to make sure we close the driver after the test try (Driver driver = GraphDatabase .driver(neo4j.boltURI(), Config.build().withEncryption().toConfig()); Session session = driver.session()) { // Given session.run("CREATE (e:Entity {key:'immutableValue'})-[:CURRENT {date:localdatetime('1988-10-27T00:00:00')}]->(s:State {key:'initialValue'})"); session.run("MATCH (e:Entity)-[:CURRENT]->(s:State) CREATE (e)-[:HAS_STATE {startDate:localdatetime('1988-10-27T00:00:00')}]->(s)"); // When StatementResult result = session.run("MATCH (e:Entity) WITH e CALL graph.versioner.patch(e, {key:'newValue', newKey:'newestValue'}, 'Error', localdatetime('1988-10-27T02:46:40')) YIELD node RETURN node"); Node currentState = result.single().get("node").asNode(); StatementResult countStateResult = session.run("MATCH (s:State) RETURN count(s) as s"); StatementResult nextResult = session.run("MATCH (s1:State)-[:PREVIOUS]->(s2:State) return s2"); StatementResult correctStateResult = session.run("MATCH (s1:State)-[:PREVIOUS]->(s2:State) WITH s1 MATCH (e:Entity)-[:CURRENT]->(s1) return e"); StatementResult currentStateResult = session.run("MATCH (e:Entity)-[:CURRENT]->(s) return s"); StatementResult dateResult = session.run("MATCH (e:Entity)-[r:CURRENT]->(s) RETURN r.date as relDate"); StatementResult hasStatusDateResult = session.run("MATCH (e:Entity)-[:CURRENT]->(s:State)-[:PREVIOUS]->(s2:State)<-[rel:HAS_STATE]-(e) RETURN rel.endDate as endDate"); // Then assertThat(countStateResult.single().get("s").asLong(), equalTo(2L)); assertThat(nextResult.single().get("s2").asNode().id(), equalTo(1L)); assertThat(correctStateResult.single().get("e").asNode().id(), equalTo(0L)); assertThat(currentStateResult.single().get("s").asNode().hasLabel("Error"), equalTo(true)); assertThat(dateResult.single().get("relDate").asLocalDateTime(), equalTo(convertEpochToLocalDateTime(593920000000L))); assertThat(hasStatusDateResult.single().get("endDate").asLocalDateTime(), equalTo(convertEpochToLocalDateTime(593920000000L))); assertThat(currentState.get("key").asString(), equalTo("newValue")); assertThat(currentState.get("newKey").asString(), equalTo("newestValue")); } }
@Test public void shouldCreateAndPatchANewStateWithAdditionalLabelAndDateButWithANewProp() throws Throwable { // This is in a try-block, to make sure we close the driver after the test try (Driver driver = GraphDatabase .driver(neo4j.boltURI(), Config.build().withEncryption().toConfig()); Session session = driver.session()) { // Given session.run("CREATE (e:Entity {key:'immutableValue'})-[:CURRENT {date:localdatetime('1988-10-27T00:00:00')}]->(s:State {key:'initialValue'})"); session.run("MATCH (e:Entity)-[:CURRENT]->(s:State) CREATE (e)-[:HAS_STATE {startDate:localdatetime('1988-10-27T00:00:00')}]->(s)"); // When StatementResult result = session.run("MATCH (e:Entity) WITH e CALL graph.versioner.patch(e, {newKey:'newestValue'}, 'Error', localdatetime('1988-10-27T02:46:40')) YIELD node RETURN node"); Node currentState = result.single().get("node").asNode(); StatementResult countStateResult = session.run("MATCH (s:State) RETURN count(s) as s"); StatementResult nextResult = session.run("MATCH (s1:State)-[:PREVIOUS]->(s2:State) return s2"); StatementResult correctStateResult = session.run("MATCH (s1:State)-[:PREVIOUS]->(s2:State) WITH s1 MATCH (e:Entity)-[:CURRENT]->(s1) return e"); StatementResult currentStateResult = session.run("MATCH (e:Entity)-[:CURRENT]->(s) return s"); StatementResult dateResult = session.run("MATCH (e:Entity)-[r:CURRENT]->(s) RETURN r.date as relDate"); StatementResult hasStatusDateResult = session.run("MATCH (e:Entity)-[:CURRENT]->(s:State)-[:PREVIOUS]->(s2:State)<-[rel:HAS_STATE]-(e) RETURN rel.endDate as endDate"); // Then assertThat(countStateResult.single().get("s").asLong(), equalTo(2L)); assertThat(nextResult.single().get("s2").asNode().id(), equalTo(1L)); assertThat(correctStateResult.single().get("e").asNode().id(), equalTo(0L)); assertThat(currentStateResult.single().get("s").asNode().hasLabel("Error"), equalTo(true)); assertThat(dateResult.single().get("relDate").asLocalDateTime(), equalTo(convertEpochToLocalDateTime(593920000000L))); assertThat(hasStatusDateResult.single().get("endDate").asLocalDateTime(), equalTo(convertEpochToLocalDateTime(593920000000L))); assertThat(currentState.get("key").asString(), equalTo("initialValue")); assertThat(currentState.get("newKey").asString(), equalTo("newestValue")); } }
@Test public void shouldCreateACopyOfTheGivenStateWithAdditionalDate() throws Throwable { // This is in a try-block, to make sure we close the driver after the test try (Driver driver = GraphDatabase .driver(neo4j.boltURI(), Config.build().withEncryption().toConfig()); Session session = driver.session()) { // Given session.run("CREATE (e:Entity {key:'immutableValue'})-[:CURRENT {date:localdatetime('1988-10-27T00:00:00')}]->(s:State {key:'initialValue', newKey:'oldestValue'})"); session.run("MATCH (e:Entity {key:'immutableValue'})-[:CURRENT {date:localdatetime('1988-10-27T00:00:00')}]->(s:State {key:'initialValue'}) CREATE (e)-[:HAS_STATE {startDate:localdatetime('1988-10-27T00:00:00')}]->(s)"); session.run("MATCH (e:Entity) CREATE (e)-[:HAS_STATE {startDate:localdatetime('1988-10-26T00:00:00'), endDate:localdatetime('1988-10-27T00:00:00')}]->(s:State:Test {newKey:'newestValue'})"); session.run("MATCH (sc:State)<-[:CURRENT]-(e:Entity)-[:HAS_STATE]->(s:Test) CREATE (sc)-[:PREVIOUS {date:localdatetime('1988-10-26T00:00:00')}]->(s)"); StatementResult stateResult = session.run("MATCH (s:Test) RETURN s"); Node originalState = stateResult.single().get("s").asNode(); // When StatementResult result = session.run("MATCH (e:Entity)-[:HAS_STATE]->(s:Test) WITH e, s CALL graph.versioner.patch.from(e, s, false, localdatetime('1988-10-27T02:46:40')) YIELD node RETURN node"); Node currentState = result.single().get("node").asNode(); StatementResult countStateResult = session.run("MATCH (s:State) RETURN count(s) as s"); StatementResult correctStateResult = session.run("MATCH (s1:State)-[:PREVIOUS]->(s2:State) WITH s1 MATCH (e:Entity)-[:CURRENT]->(s1) return e"); StatementResult dateResult = session.run("MATCH (e:Entity)-[r:CURRENT]->(s) RETURN r.date as relDate"); StatementResult hasStatusDateResult = session.run("MATCH (e:Entity)-[:CURRENT]->(s:State)-[:PREVIOUS]->(s2:State)<-[rel:HAS_STATE]-(e) RETURN rel.endDate as endDate"); // Then assertThat(countStateResult.single().get("s").asLong(), equalTo(3L)); assertThat(correctStateResult.single().get("e").asNode().id(), equalTo(0L)); assertThat(currentState.get("key").asString(), equalTo("initialValue")); assertThat(currentState.get("newKey").asString(), equalTo("newestValue")); assertThat(dateResult.single().get("relDate").asLocalDateTime(), equalTo(convertEpochToLocalDateTime(593920000000L))); assertThat(hasStatusDateResult.single().get("endDate").asLocalDateTime(), equalTo(convertEpochToLocalDateTime(593920000000L))); } }
@Test public void shouldCreateACopyOfTheGivenStateWithAdditionalDateButWithANewProp() throws Throwable { // This is in a try-block, to make sure we close the driver after the test try (Driver driver = GraphDatabase .driver(neo4j.boltURI(), Config.build().withEncryption().toConfig()); Session session = driver.session()) { // Given session.run("CREATE (e:Entity {key:'immutableValue'})-[:CURRENT {date:localdatetime('1988-10-27T00:00:00')}]->(s:State {key:'initialValue'})"); session.run("MATCH (e:Entity {key:'immutableValue'})-[:CURRENT {date:localdatetime('1988-10-27T00:00:00')}]->(s:State {key:'initialValue'}) CREATE (e)-[:HAS_STATE {startDate:localdatetime('1988-10-27T00:00:00')}]->(s)"); session.run("MATCH (e:Entity) CREATE (e)-[:HAS_STATE {startDate:localdatetime('1988-10-26T00:00:00'), endDate:localdatetime('1988-10-27T00:00:00')}]->(s:State:Test {newKey:'newestValue'})"); session.run("MATCH (sc:State)<-[:CURRENT]-(e:Entity)-[:HAS_STATE]->(s:Test) CREATE (sc)-[:PREVIOUS {date:localdatetime('1988-10-26T00:00:00')}]->(s)"); StatementResult stateResult = session.run("MATCH (s:Test) RETURN s"); Node originalState = stateResult.single().get("s").asNode(); // When StatementResult result = session.run("MATCH (e:Entity)-[:HAS_STATE]->(s:Test) WITH e, s CALL graph.versioner.patch.from(e, s, false,localdatetime('1988-10-27T02:46:40')) YIELD node RETURN node"); Node currentState = result.single().get("node").asNode(); StatementResult countStateResult = session.run("MATCH (s:State) RETURN count(s) as s"); StatementResult correctStateResult = session.run("MATCH (s1:State)-[:PREVIOUS]->(s2:State) WITH s1 MATCH (e:Entity)-[:CURRENT]->(s1) return e"); StatementResult dateResult = session.run("MATCH (e:Entity)-[r:CURRENT]->(s) RETURN r.date as relDate"); StatementResult hasStatusDateResult = session.run("MATCH (e:Entity)-[:CURRENT]->(s:State)-[:PREVIOUS]->(s2:State)<-[rel:HAS_STATE]-(e) RETURN rel.endDate as endDate"); // Then //assertThat(currentState.id(), equalTo(21L)); assertThat(countStateResult.single().get("s").asLong(), equalTo(3L)); assertThat(correctStateResult.single().get("e").asNode().id(), equalTo(0L)); assertThat(currentState.get("key").asString(), equalTo("initialValue")); assertThat(currentState.get("newKey").asString(), equalTo("newestValue")); assertThat(dateResult.single().get("relDate").asLocalDateTime(), equalTo(convertEpochToLocalDateTime(593920000000L))); assertThat(hasStatusDateResult.single().get("endDate").asLocalDateTime(), equalTo(convertEpochToLocalDateTime(593920000000L))); } }