Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/liquigraph/trinity
Cypher executor in the JVM | Neo4j v2 and v3 | Embedded/HTTP/Bolt
https://github.com/liquigraph/trinity
cypher jvm neo4j
Last synced: about 23 hours ago
JSON representation
Cypher executor in the JVM | Neo4j v2 and v3 | Embedded/HTTP/Bolt
- Host: GitHub
- URL: https://github.com/liquigraph/trinity
- Owner: liquigraph
- License: apache-2.0
- Archived: true
- Created: 2017-07-02T14:42:08.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2018-01-03T15:39:00.000Z (about 7 years ago)
- Last Synced: 2024-12-20T03:14:24.918Z (about 1 month ago)
- Topics: cypher, jvm, neo4j
- Language: Java
- Homepage:
- Size: 186 KB
- Stars: 5
- Watchers: 5
- Forks: 1
- Open Issues: 5
-
Metadata Files:
- Readme: README.adoc
- License: LICENSE
Awesome Lists containing this project
README
= Trinity
https://neo4j.com/[Neo4j] is a graph database.
https://neo4j.com/developer/cypher-query-language/[Cypher] is Neo4j's query language.
Trinity is the preferred choice to run Cypher queries for client applications and
libraries running on the Java Virtual Machine.== Build status
image:https://travis-ci.org/liquigraph/trinity.svg?branch=master["Build Status", link="https://travis-ci.org/liquigraph/trinity"]
image:https://maven-badges.herokuapp.com/maven-central/org.liquigraph.trinity/trinity-parent/badge.svg["Maven Central", link="http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.liquigraph.trinity%22%20AND%20a%3A%22trinity-parent%22%20AND%20p%3A%22pom%22"]== Why Trinity?
While working on http://www.liquigraph.org/[Liquigraph], we realized that
having to keep several branches per Neo4j version was a pain.This was mainly due to the fact there was no JDBC driver supporting both Neo4j v2 and Neo4j v3.
Moreover, we did not need a full-fledged JDBC implementation, we just needed
to run Cypher queries.And then, Trinity was born! With a simple API in mind, some build and
implementation tricks to work around Neo4j incompatibilities,
we achieved what we wanted: having a single way to run Cypher with any
Neo4j setup.Why the name?
. Because badass women for the win!
. And also because https://twitter.com/fbiville/status/905850499215347715[Twitter]!== Minimum Viable Snippet
=== Bolt
[source,java]
----
package in.da.matrix;import org.liquigraph.trinity.bolt.BoltClient;
import org.neo4j.driver.v1.AuthToken;
import org.neo4j.driver.v1.AuthTokens;
import org.neo4j.driver.v1.GraphDatabase;import java.util.List;
public class TrinityBoltExample {
public static void main(String[] args) {
AuthToken authentication = AuthTokens.basic("neo4j", "toto");
try (BoltClient trinity =
new BoltClient(GraphDatabase.driver("bolt://localhost:7687", authentication))) {trinity.runSingleTransaction("MATCH (n:Crew) RETURN COUNT(n)")
.consume(
(List errors) -> {
// do something amazingly useful
},
(List data) -> {
// do something usefully amazing with it
}
);
}
}
}----
=== HTTP
[source,java]
----
package in.da.matrix;import org.liquigraph.trinity.Data;
import org.liquigraph.trinity.Either;
import org.liquigraph.trinity.Fault;
import org.liquigraph.trinity.http.BasicAuthenticator;
import org.liquigraph.trinity.http.HttpClient;
import java.util.List;
import okhttp3.OkHttpClient;public class TrinityHttpExample {
public static void main(String... args) {
// if auth is disabled, just use: new HttpClient("http://localhost:7474")
HttpClient trinity = new HttpClient(
"http://localhost:7474",
okHttpClient("neo4j", "s3cr3t")
);Either, List> either =
trinity.runSingleTransaction("MATCH (n:Crew) RETURN COUNT(n)");if (either.isRight()) {
List data = either.getRight();
// do something usefully amazing with it
}
else {
List errors = either.getLeft();
// do something amazingly useful
}
}private static OkHttpClient okHttpClient(String username, String password) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder = builder.authenticator(new BasicAuthenticator(username, password));
return builder.build();
}
}
----
=== Embedded for Neo4j v3[source,java]
----
package in.da.matrix;import org.liquigraph.trinity.neo4jv3.EmbeddedClient;
import org.liquigraph.trinity.Data;
import org.liquigraph.trinity.Either;
import org.liquigraph.trinity.Fault;
import java.nio.file.Paths;
import java.util.List;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;public class TrinityEmbeddedV3Example {
public static void main(String... args) {
File path = Paths.get("some", "path").toFile();
EmbeddedClient trinity = new EmbeddedClient(graphDatabase(path));Either, List> either =
trinity.runSingleTransaction("MATCH (n:Crew) RETURN COUNT(n)");if (either.isRight()) {
List data = either.getRight();
// do something usefully amazing with it
}
else {
List errors = either.getLeft();
// do something amazingly useful
}
}private static GraphDatabaseService graphDatabase(File path) {
return new GraphDatabaseFactory().newEmbeddedDatabase(path);
}
}
----=== Embedded for Neo4j v2
[source,java]
----
package in.da.matrix;import org.liquigraph.trinity.neo4jv2.EmbeddedClient;
import org.liquigraph.trinity.Data;
import org.liquigraph.trinity.Either;
import org.liquigraph.trinity.Fault;
import java.util.List;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;public class TrinityEmbeddedV2Example {
public static void main(String... args) {
EmbeddedClient trinity = new EmbeddedClient(graphDatabase("/some/path"));Either, List> either =
trinity.runSingleTransaction("MATCH (n:Crew) RETURN COUNT(n)");if (either.isRight()) {
List data = either.getRight();
// do something usefully amazing with it
}
else {
List errors = either.getLeft();
// do something amazingly useful
}
}private static GraphDatabaseService graphDatabase(String path) {
return new GraphDatabaseFactory().newEmbeddedDatabase(path);
}
}
----== Download
=== Application developers
Picking the right implementation is just a matter of selecting the right artifact:
[cols="3*", options="header"]
.Trinity artefact matrix (_pun absolutely intended_)
|===
|Artifact coordinates
|Version of Neo4j
|JRE prerequisites|`trinity-embedded-2x`
|2.0.0 to latest 2.x
|JRE 7 or later|`trinity-embedded-3x`
|3.0.0 to latest 3.x
|JRE 8 or later|`trinity-http`
|2.0.0 to latest 3.x
|JRE 7 or later|`trinity-bolt`
|3.0.0 to latest 3.x
|JRE 8 or later
|===[NOTE]
====
Trinity `groupId` is always `org.liquigraph.trinity`.
If you pick Trinity for Neo4j embedded v2, then you must add the dependency:[source,xml]
----org.liquigraph.trinity
trinity-embedded-2x
----
======= Library developers
If you develop a library that needs to support several Neo4j setups as well,
you can pick any of the two bundles:- Neo4j 2:
[source,xml]
----org.liquigraph.trinity
trinity-neo4j-v2
----
- Neo4j 3:
[source,xml]
----org.liquigraph.trinity
trinity-neo4j-v3
----
[NOTE]
====
These two bundles cannot be included together, as they require different versions of Neo4j and JRE.
====Please note that Trinity instance discovery is implemented
via the good old Java https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html[Service Provider Interfaces].To retrieve a Trinity instance, one just needs to include one of the two
bundles and use `org.liquigraph.trinity.CypherClientLookup` like in the example below:[source,java]
----
package in.da.matrix;import org.liquigraph.trinity.CypherClientLookup;
import org.liquigraph.trinity.CypherTransport;
import org.liquigraph.trinity.OngoingTransaction;
import org.liquigraph.trinity.Optional; // for trinity-neo4j-v2
import java.util.Optional; // for trinity-neo4j-v3
import java.util.Properties;public class TrinityHttpDiscoveryExample {
public static void main(String... args) {
CypherClientLookup lookup = new CypherClientLookup();
Optional> maybeTrinity = lookup.getInstance(
CypherTransport.HTTP,
httpProperties()
);// trinity-neo4j-v3 users can rely on the primitive Java 8 Optional
// they are encouraged to use instead maybeTrinity.ifPresent(trinity -> ...)
if (maybeTrinity.isPresent()) {
CypherClient trinity = maybeTrinity.get();
// then you can run Cypher queries as in the above examples
}
}private static Properties httpProperties() {
Properties props = new Properties();
props.setProperty("cypher.http.baseurl", "http://localhost:7474");
props.setProperty("cypher.http.username", "neo4j");
props.setProperty("cypher.http.password", "s3cr3t");
return props;
}
}
----