From 913cb2deabdc22fa0e441ae436acef99ce8972b0 Mon Sep 17 00:00:00 2001 From: David Fauth Date: Fri, 5 Jan 2024 09:35:54 -0500 Subject: [PATCH] Updated for Neo4j 5.15 / Added License Updated for Neo4j 5.15 Added MIT License Added procedures to write to database --- CHANGELOG.md | 5 + Documentation.md | 61 ++++++++++++ MIT-LICENSE.txt | 21 +++++ README.md | 4 +- pom.xml | 4 +- src/main/java/com/neo4jh3/uber/Uberh3.java | 103 ++++++++++++++++++++- src/test/java/com/neo4jh3/Neo4jH3Test.java | 2 +- 7 files changed, 192 insertions(+), 8 deletions(-) create mode 100644 MIT-LICENSE.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index a2bac97..f960cc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# CHANGELOG - 5.15 - 2023-12-127 +* [Updated] - Tested through Neo4j 5.15 +* [Added] - Added MIT license. +* [Added] - Added two new procedures that write to the Neo4j database. These are com.neo4jh3.writeH3StringToDB and com.neo4jh3.writeH3ToDB. These procedures take a list of hex addresses, a Label, a Property and a transaction size and write the results to the database. If you are using these procedures, it is highly recommended that you have a constraint or index for the Label and Property. + # CHANGELOG - 5.14 - 2023-12-12 * [Updated] - Updated pom.xml to add multi-release plugin. There have been some changes to Neo4j 5.14 where Neo4j 5.14 supports both Java 17 and Java 21. The multi-release ensures that Neo4j will start with the plugin installed. diff --git a/Documentation.md b/Documentation.md index cff31ac..713b405 100644 --- a/Documentation.md +++ b/Documentation.md @@ -1482,8 +1482,69 @@ If h3CellIdExpr is invalid, the function returns -1 CALL com.neo4jh3. tochildrenString('85283473fffffff',-1) yield value return value; "-2" +## Experimental - Added in version 5.15.0 + +## com.neo4jh3.writeH3ToDB( ListOfCells, Neo4j Label, Neo4j Property, Transaction Size ) +Writes the H3 indexes to the Neo4j database using a user provided Label and Property. + +### Syntax +CALL com.neo4jh3.writeH3ToDB(listCells, strLabel, strProperty, txSize) yield value return value; + +### Arguments +* listCells: A LIST of LONG values representing an H3 cell ID. +* strLabel: A STRING indicating what Neo4j Label will be applied to the nodes. +* strProperty: A STRING indicating what Neo4j Property will be applied to the nodes. +* txSize: A LONG indicating the number of nodes to create in each transaction. + +### Returns +A STRING indicating completion. + +### Error conditions +If the strLabel or strProperty is empty, the procedure returns "-5" + +### Example + call com.neo4jh3.polygonToCells(value.Geometry,[],9,'lonlat') yield value as h3 + with collect(h3) as ch3 + call com.neo4jh3.writeH3ToDB(ch3,'Hex','hexAddress9') yield value return value; + "Finished" + + call com.neo4jh3.polygonToCells(value.Geometry,[],9,'lonlat') yield value as h3 + with collect(h3) as ch3 + call com.neo4jh3.writeH3ToDB(ch3,'','') yield value return value; + "-5" + +## com.neo4jh3.writeH3ToDBString( ListOfCells, Neo4j Label, Neo4j Property, Transaction Size ) +Writes the H3 indexes to the Neo4j database using a user provided Label and Property. + +### Syntax +CALL com.neo4jh3.writeH3ToDBString(listCells, strLabel, strProperty, txSize) yield value return value; + +### Arguments +* listCells: A LIST of STRING values representing an H3 cell ID. +* strLabel: A STRING indicating what Neo4j Label will be applied to the nodes. +* strProperty: A STRING indicating what Neo4j Property will be applied to the nodes. +* txSize: A LONG indicating the number of nodes to create in each transaction. + +### Returns +A STRING indicating completion. + +### Error conditions +If the strLabel or strProperty is empty, the procedure returns "-5" + +### Example + call com.neo4jh3.polygonToCellsString(value.Geometry,[],9,'lonlat') yield value as h3 + with collect(h3) as ch3 + call com.neo4jh3.writeH3ToDBString(ch3,'Hex','hexAddress9') yield value return value; + "Finished" + + call com.neo4jh3.polygonToCellsString(value.Geometry,[],9,'lonlat') yield value as h3 + with collect(h3) as ch3 + call com.neo4jh3.writeH3ToDBString(ch3,'','') yield value return value; + "-5" + ## Error Codes * -1 or "-1" : Invalid H3 Address * -2 or "-2" : Invalid Resolution * -3 or "-3" : Invalid Latitude * -4 or "-4" : Invalid Longitude +* -5 or "-5" : Empty Label and/or Property diff --git a/MIT-LICENSE.txt b/MIT-LICENSE.txt new file mode 100644 index 0000000..d297e90 --- /dev/null +++ b/MIT-LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023-2024 David Fauth and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 353c422..299474e 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,8 @@ project, simply package the project with maven: mvn clean package -This will produce a jar-file, `neo4jh3-5.13.0.jar`, -that can be copied to the `plugin` directory of your Neo4j instance. +This will produce a jar-file, `neo4jh3-5.15.0.jar`, +that can be copied to the `plugins` directory of your Neo4j instance. cp target/neo4jh3-5.13.0.jar neo4j-enterprise-5.x.0/plugins/. diff --git a/pom.xml b/pom.xml index 7c2dd4d..b0e1e73 100644 --- a/pom.xml +++ b/pom.xml @@ -6,10 +6,10 @@ com.neo4jh3 neo4jh3 - 5.14.0 + 5.15.0 - 5.14.0 + 5.15.0 1.2 3.13.0 4.1.1 diff --git a/src/main/java/com/neo4jh3/uber/Uberh3.java b/src/main/java/com/neo4jh3/uber/Uberh3.java index 3562209..c82c56a 100755 --- a/src/main/java/com/neo4jh3/uber/Uberh3.java +++ b/src/main/java/com/neo4jh3/uber/Uberh3.java @@ -12,8 +12,11 @@ import org.apache.commons.math3.util.Precision; import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.graphdb.Label; +import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Transaction; import org.neo4j.procedure.*; +import org.neo4j.procedure.builtin.BuiltInDbmsProcedures.StringResult; import java.io.IOException; import java.util.*; @@ -28,7 +31,7 @@ public class Uberh3 { public Transaction tx; private final static int DEFAULT_H3_RESOLUTION = 9; - private final static String NEO4J_H3_VERSION = "5.14.0"; + private final static String NEO4J_H3_VERSION = "5.15.0"; private static H3Core h3 = null; @@ -2427,6 +2430,102 @@ public Stream uncompactString(@Name("listCells") List l } } + // Experimental write to db procedure +@Procedure(name = "com.neo4jh3.writeH3ToDB", mode = Mode.WRITE) +@Description("CALL com.neo4jh3.writeH3ToDB(listCells, strLabel, strProperty, txSize)") +public Stream writeH3ToDB(@Name("listCells") List listCells, @Name("strLabel") String strLabel, @Name("strProperty") String strProperty, @Name("txSize") Long txSize) throws InterruptedException { + String returnMessage = ""; + if (listCells == null) { + throw new InterruptedException("invalid list of hex addresses"); + } + if (strLabel.isBlank() || strProperty.isBlank()){ + returnMessage = "-5"; + //throw new InterruptedException("Empty Label and/or Property"); + } else { + if (txSize < 1) { + txSize = 10000L; + } + Integer count = 0; + Long curRes = 0L; + Throwable txEx = null; + ListIterator iterator = listCells.listIterator(); + Transaction tx = db.beginTx(); + try { + while (iterator.hasNext()) { + curRes = iterator.next(); + Node h3Node = tx.findNode(Label.label(strLabel), strProperty, curRes); + if (h3Node == null) { + h3Node = tx.createNode(Label.label(strLabel)); + h3Node.setProperty(strProperty,curRes); + } + + if (count % txSize == 0) { + tx.commit(); + tx = db.beginTx(); + } + count++; + } + tx.commit(); + } catch (Throwable ex) { + txEx = ex; + System.out.println(ex); + } + } + if (returnMessage.isBlank()){ + return Stream.of(new StringResult("Finished")); + } else { + return Stream.of(new StringResult(returnMessage)); + } +} + + // Experimental write to db procedure +@Procedure(name = "com.neo4jh3.writeH3StringToDB", mode = Mode.WRITE) +@Description("CALL com.neo4jh3.writeH3StringToDB(listCells, strLabel, strProperty, txSize)") +public Stream writeH3StringToDB(@Name("listCells") List listCells, @Name("strLabel") String strLabel, @Name("strProperty") String strProperty, @Name("txSize") Long txSize) throws InterruptedException { + String returnMessage = ""; + if (listCells == null) { + throw new InterruptedException("invalid list of hex addresses"); + } + if (strLabel.isBlank() || strProperty.isBlank()){ + returnMessage = "Empty Label and/or Property"; + //throw new InterruptedException("Empty Label and/or Property"); + } else { + if (txSize < 1) { + txSize = 10000L; + } + Integer count = 0; + String curRes = ""; + Throwable txEx = null; + ListIterator iterator = listCells.listIterator(); + Transaction tx = db.beginTx(); + try { + while (iterator.hasNext()) { + curRes = iterator.next(); + Node h3Node = tx.findNode(Label.label(strLabel), strProperty, curRes); + if (h3Node == null) { + h3Node = tx.createNode(Label.label(strLabel)); + h3Node.setProperty(strProperty,curRes); + } + + if (count % txSize == 0) { + tx.commit(); + tx = db.beginTx(); + } + count++; + } + tx.commit(); + } catch (Throwable ex) { + txEx = ex; + System.out.println(ex); + } + } + if (returnMessage.isBlank()){ + return Stream.of(new StringResult("Finished")); + } else { + return Stream.of(new StringResult(returnMessage)); + } +} + private static double distance(double lat1, double lon1, double lat2, double lon2, String unit) { @@ -2447,7 +2546,5 @@ private static double distance(double lat1, double lon1, double lat2, double lon return (dist); } } - - } diff --git a/src/test/java/com/neo4jh3/Neo4jH3Test.java b/src/test/java/com/neo4jh3/Neo4jH3Test.java index a443d3e..1c220ad 100644 --- a/src/test/java/com/neo4jh3/Neo4jH3Test.java +++ b/src/test/java/com/neo4jh3/Neo4jH3Test.java @@ -122,7 +122,7 @@ public void should_return_hex_address() throws InterruptedException { } result = session.run("RETURN com.neo4jh3.version() AS value"); - assertEquals("\"5.14.0\"", result.single().get("value").toString()); + assertEquals("\"5.15.0\"", result.single().get("value").toString()); result = session.run("RETURN com.neo4jh3.cellToLatLngString('892830926cfffff') AS value"); assertEquals("\"37.564248,-122.325306\"", result.single().get("value").toString());