TODO

This software has pre-release quality. The interface is not yet stable.

Neo4j::Driver

  • A uri string only containing protocol should yield the default host and port. For example, Neo4j::Driver->new('bolt:') should be enough to get a driver configured for bolt://localhost:7687.

Neo4j::Driver::Session

  • Sessions of some of the official drivers can have at most one transaction running at a time. This restriction is not necessary for this Perl driver when HTTP is used, but perhaps we should implement it anyway for consistency.

  • DBI uses begin_work in place of begin_transaction as a method name. Even though begin_work is shorter, it should not be the main method name because begin_transaction is well established in the official Neo4j drivers, and after all this is not DBI. However, as this is the only (almost) exact equivalence with DBI that we have, we should perhaps offer begin_work as an experimental alias at least.

  • Consider whether to offer transaction functions. If available, these should consist of subrefs passed to methods called write_transaction and read_transaction. These access modes are only an optimisation for Enterprise features. We don't target those at present, but read_transaction could then eventually be routed to a high-performance read-only server once clusters are supported. It would make sense to offer both methods right away even though initially they'd work exactly the same.

Neo4j::Driver::Transaction

  • The option to send multiple statements at once should no longer be exposed to the client. It should only be used internally for running statements lazily.

  • Consider unrolling deep_bless recursion. Based on initial profiling, this may save up to about 5% CPU time (for a specific HTTP test query cached in RAM, performance went from about 2700/s to 2850/s when skipping the call to deep_bless entirely). However, when accessing the database, the bottleneck is typically I/O (querying Neo4j itself instead of the RAM-cached response let the performance for the very same query drop down to 650/s when executed over HTTP). So this optimisation may not be worth it (OTOH, Bolt performance was something like 7000/s, so optimising deep_bless may be more useful there).

  • An alternative to using $client->{_res}->status_line (to get the HTTP error message) might be to call $client->getUseragent->add_handler(response_header => sub { $status_line = shift->status_line }). However, this is probably slower and would likely need to be run for each and every POST including those with 2xx status codes, which might not be acceptable.

  • Consider supporting re-using Record objects for query parameters in run. The Java and C# drivers do this.

  • Profile whether Tie::IxHash or sorting JSON:PP is quicker and adjust the code accordingly. Note, however, that the testing simulator requires fully sorted JSON, so Tie::IxHash may not be enough.

  • Investigate which JSON module is the best. While Cpanel::JSON::XS may have some advantages in terms of correctness (I think?), maybe JSON::MaybeXS is more compatible.

  • Run statements lazily: Just like with the official drivers, statements passed to run should be gathered until their results are actually accessed. Then, and only then, all statements gathered so far should be sent to the server using a single request. Challenges of this approach include that notifications are not associated with a single statement, so there must be an option to disable this behaviour; indeed, disabled should probably be the default when stats are requested. Additionally, there are some bugs with multiple statements (see tests non-arrayref individual statement and include empty statement). Since stats are now requested by default, this item might mean investing time in developing an optimisation feature that is almost never used. Since the server is often run on localhost anyway where latency is very close to zero, this item should not have high priority.

  • Replace old {} parameter style with new $ style; see https://neo4j.com/docs/cypher-manual/current/deprecations-additions-removals-compatibility/.

Neo4j::Driver::StatementResult

Neo4j::Driver::Record

Neo4j::Driver::ResultColumns

  • Bugfix: The get method behaves unpredictably for queries that have fields with conflicting indexes and keys such as RETURN 1, 0. It would technically be possible to distinguish between a key and an index by inspecting the scalar's FLAGS (namely, POK/IOK; see https://metacpan.org/pod/Devel::Peek#EXAMPLES and JSON::PP's _looks_like_number). Then get(0) would mean index 0 and get('0') would mean key 0. Not sure if this is the best approach though. (FWIW, it's exactly what the JS driver does.)

  • The list implementation is quite ugly and probably has bugs with regards to index/key collisions.

Neo4j::Driver::ResultSummary

  • Profile the server-side performance penalty of requesting stats for various kinds of queries. If the penalty turns out to be high, stats should perhaps have to be requested explicitly by clients (rather than being obtained by default, as with 0.13 and higher). However, using Bolt always provides stats, and different APIs for HTTP and Bolt seem like a bad idea.

  • Add timers.

Neo4j::Driver::SummaryCounters

  • use Class::Accessor::Fast 0.34;

Neo4j::Driver::Transport::HTTP

  • Profile whether X-Stream has any performance impact. Remove if in doubt, as we don't implement streaming (and have no plans to in the future, considering that Bolt should be used when speed is important).

  • Add Accept-Charset: UTF-8 header, I guess.

  • Since all methods in this class are private, they should perhaps all have names beginning with _ to make this perfectly clear. This might also help to improve POD coverage.

Neo4j::Driver::Type::*

  • Implement spatial and temporal types.

  • The eq and ne operators should be overloaded to allow for ID comparison on nodes and relationships.

  • Consider whether to use use overload '%{}' to allow direct access to e. g. properties using the pre-0.13 hashref syntax. See https://metacpan.org/pod/overload#Two-face-References for an example.