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 forbolt://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 ofbegin_transaction
as a method name. Even thoughbegin_work
is shorter, it should not be the main method name becausebegin_transaction
is well established in the official Neo4j drivers, and after all this is notDBI
. However, as this is the only (almost) exact equivalence withDBI
that we have, we should perhaps offerbegin_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
andread_transaction
. These access modes are only an optimisation for Enterprise features. We don't target those at present, butread_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 todeep_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 optimisingdeep_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 with2xx
status codes, which might not be acceptable.Consider supporting re-using
Record
objects for query parameters inrun
. The Java and C# drivers do this.Profile whether
Tie::IxHash
or sortingJSON:PP
is quicker and adjust the code accordingly. Note, however, that the testing simulator requires fully sorted JSON, soTie::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?), maybeJSON::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 testsnon-arrayref individual statement
andinclude 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
Bugfix:
get
should croak if the call is ambiguous (i. e., there's more than one field but the field to get is not specified by argument). Note, though, that the Python driver intentionally does deliver the first field only in this exact scenario (though its method is calledvalue
instead ofget
).Consider whether to implement methods to query the list of fields for this record (
keys
,has
,size
) and/or a mapping function for all fields (map
/forEach
). Given that this data should easily be available through the StatementResult object, these seem slightly superfluous though.Implement
graph
; see https://github.com/neo4j/neo4j/blob/3.5/community/server/src/main/java/org/neo4j/server/rest/transactional/GraphExtractionWriter.java, https://github.com/neo4j/neo4j-python-driver/wiki/1.6-changelog#160a1.
Neo4j::Driver::ResultColumns
Bugfix: The
get
method behaves unpredictably for queries that have fields with conflicting indexes and keys such asRETURN 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 andJSON::PP
's_looks_like_number
). Thenget(0)
would mean index0
andget('0')
would mean key0
. 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
andne
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.