grupo-abraxas / slothql Goto Github PK
View Code? Open in Web Editor NEWGraph Query Language for Scala
License: MIT License
Graph Query Language for Scala
License: MIT License
Transformer
typeclass, introduced as solution for issue #30 cannot apply/chain multiple transformations
due to diverging implicit expansion
errors.
Support matching edges of any direction: --
, -
.
TODO: -
syntax fragment breaks IDE compatibility.
Given two queries
q1 = MATCH $pattern1 RETURN $result1
q2 = MATCH $pattern2 RETURN $result2
The merged query should be
q1 ∪ q2 = MATCH $pattern1, $pattern2 RETURN $result1, $result2
Introduce shorter syntax for common functions (over nodes/relations).
labels
type
id
count
keys
Function1
- Func1Arrow
Compose
typeclass instance)ScalaExpr
arrows to Func1Arrow
Id
SelectField
FMap
MBind
Split
SelectIn
While Split
is a bundle of arrows with common source that represents a kind of product, similar coproduct representation Choose
is needed.
When mapping a composed arrow with a Functor, the associativity property does not comply.
Functor.map(sel3 ∘ (sel2 ∘ sel1)).to[DBArrow] // Compiles
Functor.map((sel3 ∘ sel2) ∘ sel1).to[DBArrow] // Does not compile
The problem appears because the mapping is defined for a composition sel2 ∘ sel1
, not for the underlying arrows.
Introduce graph traversal syntax for building dynamic queries.
Boilerplate reduction.
A schema should define model's representation as a sub-graph. Static = compile time.
Use pattern match if
guard for constructing WHERE
cypher clause.
Introduce syntax for paginating query results.
Use arrows from #38.
ScalaExpr
Id
- identity arrow (self selection)SelectField
- expression representing selection of a field of an ADT (case class)FMap
- expression representing functor map
operationMBind
- expression representing monadic bind / flatMap
operationSelectIn
Option
/ Either
projection valueEither
projectionsStatic alias renamer (with fresh names generation) is required for merging queries.
Support matching directed edges without assigning aliases: ->
, <-
.
Typeclasses:
AllAliases
HasAlias
RenameAlias
(todo)Introduce syntax for cypher lists:
[ ..., ... ]
in
expression+
concatenationDefine Functor
s for mapping ScalaExpr
arrows to GraphPath
.
Id
⇒ Initial
SelectField
depends on graph representation of selected field
Node
⇒ RelationTarget ∘ OutgoingRelation
Relation
⇒ OutgoingRelation
Property
⇒ PropSelection
FMap
⇒ ?MBind
⇒ ?SelectIn
⇒ ?Arrow.Split
⇒ ?Arrow.Composition
⇒ ?While transformations by different functions can be chained
object F1 extends Poly1{
implicit def impl[A]: Case.Aux[Lit[A], Lit[A with X]] = at[Lit[A]](_.asInstanceOf[Lit[A with X]])
}
object F2 extends Poly1{
implicit def call[A, Func0 <: String, Params0 <: HList](
implicit copy: Copy[Call.Aux[A, Func0, Params0], Witness.`'params`.Field[Lit[Float] :: Lit[Boolean] :: HNil] :: HNil]
): Case.Aux[Call.Aux[A, Func0, Params0], copy.Out] =
at[Call.Aux[A, Func0, Params0]](copy(_, 'params ->> (Lit(1.2f) :: Lit(true) :: HNil) :: HNil))
}
Transform(Transform(call, F2), F1)
A single polymorphic function, defining all the transformations, doesn't work because of diverging implicit expansion
object F3 extends Poly1 {
implicit def call[A, Func0 <: String, Params0 <: HList](
implicit copy: Copy[Call.Aux[A, Func0, Params0], Witness.`'params`.Field[Lit[Float] :: Lit[Boolean] :: HNil] :: HNil]
): Case.Aux[Call.Aux[A, Func0, Params0], copy.Out] =
at[Call.Aux[A, Func0, Params0]](copy(_, 'params ->> (Lit(1.2f) :: Lit(true) :: HNil) :: HNil))
implicit def lit[A]: Case.Aux[Lit[A], Lit[A with X]] = at[Lit[A]](_.asInstanceOf[Lit[A with X]])
}
Transform(call, F3)
// diverging implicit expansion for type Transform[Call.Aux[String,String("foo"),shapeless.::[Lit[String],shapeless.::[Lit[String],shapeless.HNil]]],TestTransform.F3_2.type]
// starting with method noStringChildren in object TestTransform
Introduce syntax for ordering query results.
trait Arrow0[Object] {
type Source <: Object
type Target <: Object
}
type Arrow = Arrow0[Any]
Introduce syntax for equality/inequality expressions:
=
<>
<
>
<=
>=
IS NULL
IS NOT NULL
CaseDef
; right now the underlying CaseDef
s are also modifiedExpr
are no longer neededSupport matching a single vertex.
Support matching relation length.
len ::= ∗ | ∗d | ∗d1.. | ∗..d2 | ∗d1..d2 where d,d1,d2 ∈ N
Introduce syntax for built-in functions calls.
In Scala 2.10, scala.reflect.ClassManifest are deprecated, and it is planned to deprecate scala.reflect.Manifest in favor of TypeTags and ClassTags in an upcoming point release. Thus, it is advisable to migrate any Manifest-based APIs to use Tags.
CypherFragment
s should include full type information about their sub-fragments.
This information is to be used for static query analysis and manipulation.
Given two queries
q1 = MATCH $pattern1 RETURN $result1
q2 = MATCH $pattern2 RETURN $result2
The merged query should be
q1 ∪ q2 = MATCH $pattern1, $pattern2 RETURN $result1, $result2
The template is a string containing placeholders that are substituted with parameter values at runtime. While it is possible to run non-parameterized Cypher, good programming practice is to use parameters in Cypher statements. This allows for caching of statements within the Cypher engine, which is beneficial for performance.
(Neo4J developer manual)
Arrow composition must be associative:
(a ∘ b) ∘ c == a ∘ (b ∘ c)
Vertex
and Edge
extractors now require outer parentheses in the pattern. It should not.
Now | Should be |
---|---|
case (v@Vertex(...)) <(edge)- ... |
case v@Vertex(...) <(edge)- ... |
Vars are used in generated code for
GraphElem
aliaseswhere
clauseRemove them if possible.
See also #27.
A polymorphic mapper is required for transforming Cypher trees at compile-time.
Functors should map high-level expressions to an intermediate level, not to cypher fragments directly.
This layer should describe the paths (arrows) within an abstract graph.
Those paths should then be mapped to cypher expressions.
This layer will also serve as a base for introducing gremlin-like syntax in the future.
TODO
Support returning errors in transaction monad.
Error:(296, 23) diverging implicit expansion for type com.abraxas.slothql.util.Transform[com.abraxas.slothql.Call.Aux[Int,String("parseInt"),shapeless.::[com.abraxas.slothql.Call.Aux[String,String("foo"),shapeless.::[com.abraxas.slothql.Lit[String],shapeless.::[com.abraxas.slothql.Lit[String],shapeless.HNil]]],shapeless.HNil]],com.abraxas.slothql.TestTransform.F2.type]
starting with method transformHCons in object Transform
Introduce syntax for boolean expressions:
OR
AND
XOR
NOT
TBD: I'm not really confident with Category Theory, so I'll fill the description after a couple of discussions.
compose
andThen
A ~> (B, C, D, E)
(A, B, C, D) ~> (A, E, C, D)
, similar to first
/second
(A, B, C) ~> D
Selector
is an optic that preserves selection path at type-level.
A schema should define model's representation as a sub-graph. Dynamic = runtime.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.