You can update your copy of Ocular using the command line tools by running
sl update ocular.
When you update, Ocular automatically backs up the files in your workspace, including custom policies. You'll be provided information about the backup process and asked to review any discrepancies between the newly-downloaded files and the existing files in the backup directory.
0.4.1: OverflowDb Traversals
This release introduces a major rearchitecture of the cpg query language (CPGQL). Most changes happened under the hood, however there are a few changes that are user facing. The migration should be straightforward, and in any case we're here to help.
Background: CPGQL was previously based on the Gremlin graph traversal language (accessible via
.raw), and is now based on OverflowDb Traversal. The main drivers behind this change are: better performance, less complexity and fewer dependencies. OverflowDb Traversal is a Scala collection with additional graph steps, which means we now inherit many useful steps from the rich Scala standard collection library, where previously convertions between Traversal and Scala collections were needed.
At the same time, Traversal offers largely the same steps and semantics as its TinkerPop predecessor.
Here are the most important new parts - from our experience the swap of
where accounts for 90% of user-facing changes:
filter(A => Boolean): just like any other Scala collection, filter now simply takes a predicate (it used to take a Traversal).
where(trav: Traversal[A] => Traversal[_]): preserves elements if the provided traversal has at least one result. This is what filter used to be. Effectively,
filterOnEnd- this is now simply
repeatnow has a builder DSL to configure it's behaviour, which is more specific and easier to understand than tinkerpop's api, which relied on the order of modulators in the traversal. For example, in tinkerpop
.emit.repeat(Traversal)means "emit everything", while
.repeat(Traversal).emitmeans "emit all but the first element". In OverflowDb Traversal this behaviour is more explicit:
Some more examples for the migration:
repeatuses depth first search (DFS) by default and can be configured to use breadth first search (BFS) instead. Tinkerpop has a long standing issue that it claims to use DFS but actually uses BFS, and also cannot be configured to use one or the other.
.startstep only exists for
NewNode, not for other collections any more. Instead, use the standard scala collection mechanism
.clonedoesn't exist any more - note that Traversals typically have Iterator semantics, i.e. they are consumed during iteration:
If you want to execute your traversals multiple times, simply define them as a function (
def) rather than a value (
Please let us know if you need help with your migration!
Bleeding edge / power users only:
8) If you used the underlying tinkerpop api and OverflowDb types (e.g. via
.raw), your scripts may be subject to additional changes, due to the removal of the Tinkerpop dependency and renames in OverflowDb types:
- all Tinkerpop types are gone: