Giter Site home page Giter Site logo

neo4j-sproc-compiler's Introduction

Neo4j stored procedure compiler

Build Status

This is a annotation processor that will verify your stored procedures at compile time.

While most of the basic checks can be performed, you still need some unit tests to verify some runtime behaviours.

What does it do?

Once the stored procedure compiler is added into your project classpath (see Maven/Gradle instructions below), it will trigger compilation failures if any of the following requirements is not met:

  • @Context fields must be public and non-final
  • all other fields must be static
  • Map record fields/procedure parameters must define their key type as String
  • @Procedure|@UserFunction class must define a public constructor with no arguments
  • @Procedure method must return a Stream
  • @Procedure|@UserFunction parameter and record types must be supported
  • @Procedure|@UserFunction parameters must be annotated with @Name
  • @UserFunction cannot be defined in the root namespace
  • all visited @Procedure|@UserFunction names must be unique*

*A deployed Neo4j instance can aggregate stored procedures from different JARs. Inter-JAR naming conflict cannot be detected by an annotation processor. By definition, it can only inspect one compilation unit at a time.

DSV export

The compiler can also export metadata to DSV (Delimiter-Separated Values) files. To make it work, you need to specify the following options (by passing -A${CONFIGURATION_KEY}=${value} to the Java compiler (where ${CONFIGURATION_KEY} is one of the keys listed below):

  • GeneratedDocumentationPath: mandatory - the folder path in which the files are going to be generated in. If not specified, the export won't be done.

  • Documentation.FieldDelimiter: optional (default: ,) - the delimiter of values within a row

  • Documentation.DelimitedFirstField: optional (default: false) - the first column of each row (headers included) is prefixed with the configured separator

  • Documentation.QuotedFields: optional (default: true) - whether column values are quoted or not

  • Documentation.ExportGrouping: optional (default: SINGLE) - comma-separated values of grouping strategy. The data is exported to a single place (SINGLE), to a single place per enclosing package (PACKAGE), to a single place per enclosing class (CLASS). For now, "place" may mean one or two files, depending on Documentation.ExportSplit.

  • Documentation.ExportSplit: optional (default: NONE) - whether to split data by kind (KIND, e.g. procedure vs. function) or not (NONE).

  • Documentation.ExportedHeaders: optional (default: *) - delimiter-separated values which define custom ordering and filtering of the available headers. They are not to be quoted (regardless of Documentation.QuotedFields setting), have to be separated by the configured delimiter (see Documentation.FieldDelimiter) and the first header must not be prefixed, even if Documentation.DelimitedFirstField is enabled. The available headers are (in default order):

    • type: 'procedure' or 'function' for now
    • name: procedure/function logical name
    • description: optional procedure/function description
    • execution mode: configured execution mode
    • location: fully qualified method name defining the procedure/function
    • deprecated by: optional replacement of the procedure/function

Use the processor

Maven

SNAPSHOT repository

If you do not plan to test the development version, you can skip this section.

Add to <repositories> section:

   <repository>
      <id>sonatype-snapshot-repo</id>
      <name>Sonatype SNAPSHOT repository</name>
      <layout>default</layout>
      <releases>
         <enabled>false</enabled>
      </releases>
      <snapshots>
         <enabled>true</enabled>
      </snapshots>
      <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
   </repository>

Dependency

Add the dependency simply as follows:

<dependency>
   <groupId>net.biville.florent</groupId>
   <artifactId>neo4j-sproc-compiler</artifactId>
   <version><!-- check last release on https://search.maven.org --></version>
   <scope>provided</scope>
   <optional>true</optional>
</dependency>

Gradle

SNAPSHOT repository

If you do not plan to test the development version, you can skip this section.

Just add to your repositories:

maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }

Dependency

Add to your dependencies:

compileOnly group: 'net.biville.florent', name: 'neo4j-sproc-compiler', version:'/* check last release on https://search.maven.org */'

neo4j-sproc-compiler's People

Contributors

dependabot[bot] avatar fbiville avatar fpavageau avatar knutwalker avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

neo4j-sproc-compiler's Issues

Validate record field types

A record can only have public fields, and they must be of the following type:

  • String
  • Long
  • long
  • Double
  • double
  • Number
  • Boolean
  • boolean
  • Path
  • Node
  • Relationship
  • java.util.Map<String,Object>
  • java.util.List of any type in this list, including java.util.List
  • Object

Validate @Context fields

The field must be public and non-final and only those types are allowed:

  • GraphDatabaseService
  • org.neo4j.logging.Log

The project cannot be built

Running mvn clean package works fine, but mvn clean install fails because it cannot find GPG:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-gpg-plugin:1.6:sign (sign-artifacts) on project neo4j-sproc-compiler-parent: Unable to execute gpg command: Error while executing process. Cannot run program "gpg": error=2, No such file or directory -> [Help 1]

Should this be a mandatory step? Can't it be limited to releases?

Change test-jar packaging

The idea of producing a test-jar from processor module is to extract all procedures/functions supposed to be processed without errors and invoke them in integration tests.

While the current approach works, it's hacky at best and not well supported by the IDE.
The test procedures should belong to src/test/java.

I see two ways of doing this:

  • having a separate module that produces a JAR made of valid procedures/functions
  • move the valid procedures/functions into some sub-directory of src/test/java (not src/test/resources like now) and properly create a test JAR with only these classes.

Expose option to customize file grouping|splitting

Three grouping options (that can be added up -> n executions for n selections):

  • ONE_FILE: everything is written to a single file
  • ONE_FILE_PER_PACKAGE : 1 file is generated per package
  • ONE_FILE_PER_CLASS : 1 file is generated per class

Two splitting options:

  • NONE: procedure and functions are in the same file
  • TYPE_SPLIT: procedure and functions are in different files

Procedures (and functions) can have a custom name

Currently, the unicity validation steps rely on the default name, which may not be correct as the procedure can define a custom name.

In Neo 3.1, functions and procedures have 3 ways of naming (in ascending order of priority):

  • the default one (package + method name)
  • value()
  • name()

Fix type export

There is a glitch with exported types:

  • return types are fully qualified
  • parameter types are simple and raw (no generics)

Instead, it should be simple raw names.
In the case of user-defined procedures, the record type should not be printed but all its fields' simple and raw types.

The generic information should be printed if and only if the exporter is configured to do so.

Demo+doc

Demo integration with Maven, Gradle and Intellij

Improve CSV processing

  • do not output parameter type qualified names (use simple names instead)
  • output empty strings instead of "N/A" for missing values
  • introduce type field : function or procedure
  • switch from CSV to DSV where the delimiter is a compiler option
  • allow custom export of columns

Fix package name collision

Until #44 is solved, the only possible generation strategy is as follows: one file per package is generated. However, the filename corresponds to the simple package name and not its fully qualified name.

This obviously causes problems if different subpackages share the same simple name.

Enforce UTF8 when writing DSV

DsvSerializer uses FileWriter1 which means the system default locale will determine the encoding. We discovered this when running in a Docker container where the locale was POSIX, and any non-ASCII characters used for delimiters or in Strings in proc annotations were garbled. It would be better to enforce UTF8, or make the encoding configurable if there is a use case for other encodings.

The constructors of this class assume that the default character encoding and the default byte-buffer size are acceptable. To specify these values yourself, construct an OutputStreamWriter on a FileOutputStream.2

Validate procedure input type

Only those types are valid:

  • String
  • Long
  • long
  • Double
  • double
  • Number
  • Boolean
  • boolean
  • java.util.Map<String,Object>
  • java.util.List of any type in this list, including java.util.List
  • Object

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.