Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The Arrow query language offers SQL, Monoid comprehensions and LINQ style queries generalized to all data types.
- Loading branch information
Showing
57 changed files
with
2,307 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
dependencies { | ||
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" | ||
compile project(':arrow-annotations') | ||
compile project(':arrow-mtl') | ||
kapt project(':arrow-annotations-processor') | ||
kaptTest project(':arrow-annotations-processor') | ||
compileOnly project(':arrow-annotations-processor') | ||
testCompileOnly project(':arrow-annotations-processor') | ||
testCompile "io.kotlintest:kotlintest:$kotlinTestVersion" | ||
testCompile project(':arrow-test') | ||
} | ||
|
||
apply from: rootProject.file('gradle/gradle-mvn-push.gradle') | ||
apply plugin: 'kotlin-kapt' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Maven publishing configuration | ||
POM_NAME=Arrow Query Language | ||
POM_ARTIFACT_ID=arrow-query-language | ||
POM_PACKAGING=jar |
25 changes: 25 additions & 0 deletions
25
modules/aql/arrow-query-language/src/main/kotlin/arrow/aql/Count.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package arrow.aql | ||
|
||
import arrow.core.* | ||
import arrow.data.ForListK | ||
import arrow.data.fix | ||
import arrow.data.k | ||
import arrow.instances.monoid | ||
import arrow.typeclasses.Foldable | ||
|
||
interface Count<F> { | ||
|
||
fun foldable(): Foldable<F> | ||
|
||
fun <A, Z> Query<F, A, Z>.count(): Query<ForListK, Long, Long> = | ||
foldable().run { | ||
Query( | ||
select = ::identity, | ||
from = listOf(from.size(Long.monoid())).k() | ||
) | ||
} | ||
|
||
fun Query<ForListK, Long, Long>.value(): Long = | ||
this@value.from.fix().firstOrNone().getOrElse { 0L } | ||
|
||
} |
26 changes: 26 additions & 0 deletions
26
modules/aql/arrow-query-language/src/main/kotlin/arrow/aql/From.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package arrow.aql | ||
|
||
import arrow.core.Tuple2 | ||
import arrow.core.Tuple3 | ||
import arrow.core.toT | ||
import arrow.typeclasses.Applicative | ||
|
||
interface From<F> { | ||
|
||
fun applicative(): Applicative<F> | ||
|
||
infix fun <A, B> Source<F, A>.join(fb: Source<F, B>): Source<F, Tuple2<A, B>> = | ||
applicative().run { this@join.product(fb) } | ||
|
||
fun <A, B, C> Source<F, Tuple2<A, B>>.join(fc: Source<F, C>, dummy: Unit = Unit): Source<F, Tuple3<A, B, C>> = | ||
applicative().run { this@join.product(fc) } | ||
|
||
infix fun <A, B, Z, X> Query<F, A, Z>.join(query: Query<F, B, X>): Query<F, Tuple2<A, B>, Tuple2<Z, X>> = | ||
applicative().run { | ||
Query( | ||
select = { select(a) toT query.select(b) }, | ||
from = from.product(query.from) | ||
) | ||
} | ||
|
||
} |
29 changes: 29 additions & 0 deletions
29
modules/aql/arrow-query-language/src/main/kotlin/arrow/aql/GroupBy.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package arrow.aql | ||
|
||
import arrow.core.* | ||
import arrow.data.ForListK | ||
import arrow.data.fix | ||
import arrow.data.mapOf | ||
import arrow.typeclasses.Foldable | ||
|
||
interface GroupBy<F> { | ||
|
||
fun foldable(): Foldable<F> | ||
|
||
infix fun <A, Z, X> Query<F, A, Z>.groupBy(group: Z.() -> X): Query<ForId, Map<X, List<Z>>, Map<X, List<Z>>> = | ||
foldable().run { | ||
Query(select = ::identity, from = | ||
Id.just(from.foldLeft(emptyMap()) { map, a -> | ||
val z: Z = select.invoke(a) | ||
val key: X = group(z) | ||
val grouped: List<Z> = map[key]?.let { it + z } ?: listOf(z) | ||
map + mapOf(key toT grouped) | ||
})) | ||
} | ||
|
||
fun <Z, X> Query<ForListK, Map<X, List<Z>>, Map<X, List<Z>>>.value(): Map<X, List<Z>> = | ||
foldable().run { | ||
this@value.from.fix().firstOrNone().getOrElse { emptyMap() } | ||
} | ||
|
||
} |
60 changes: 60 additions & 0 deletions
60
modules/aql/arrow-query-language/src/main/kotlin/arrow/aql/OrderBy.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package arrow.aql | ||
|
||
import arrow.core.ForId | ||
import arrow.core.identity | ||
import arrow.core.value | ||
import arrow.instances.id.applicative.just | ||
import arrow.typeclasses.Foldable | ||
import arrow.typeclasses.Order | ||
|
||
sealed class Ord<X> { | ||
abstract val order: Order<X> | ||
data class Asc<X>(override val order: Order<X>) : Ord<X>() | ||
data class Desc<X>(override val order: Order<X>) : Ord<X>() | ||
} | ||
|
||
interface OrderBy<F> { | ||
|
||
fun foldable(): Foldable<F> | ||
|
||
private data class DelegatingComparator<A>(val ord: Ord<A>) : Comparator<A> { | ||
override fun compare(a: A, other: A): Int = ord.order.run { | ||
val comp = a.compareTo(other) | ||
when (ord) { | ||
is Ord.Asc<*> -> comp | ||
is Ord.Desc<*> -> -comp | ||
} | ||
} | ||
} | ||
|
||
infix fun <A, Z> Query<F, A, Z>.orderBy(ord: Ord<Z>): Query<ForId, List<Z>, List<Z>> = | ||
foldable().run { | ||
Query( | ||
select = ::identity, | ||
from = from.foldLeft(emptyList<Z>()) { list, a -> | ||
list + select(a) | ||
}.sortedWith(DelegatingComparator(ord)).just() | ||
) | ||
} | ||
|
||
infix fun <X, Z> Query<ForId, Map<X, List<Z>>, Map<X, List<Z>>>.orderMap(ord: Ord<X>): Query<ForId, Map<X, List<Z>>, Map<X, List<Z>>> { | ||
val sortedMap = from.value().toSortedMap(kotlin.Comparator { o1, o2 -> | ||
val result = ord.order.run { o1.compareTo(o2) } | ||
when (ord) { | ||
is Ord.Asc<*> -> -result | ||
is Ord.Desc<*> -> result | ||
} | ||
}) | ||
return Query( | ||
select = ::identity, | ||
from = sortedMap.toMap().just() | ||
) | ||
} | ||
|
||
fun <Z> Query<ForId, List<Z>, List<Z>>.value(): List<Z> = | ||
this@value.from.value() | ||
|
||
fun <Z, X> Query<ForId, Map<X, List<Z>>, Map<X, List<Z>>>.value(dummy: Unit = Unit): Map<X, List<Z>> = | ||
this@value.from.value() | ||
|
||
} |
6 changes: 6 additions & 0 deletions
6
modules/aql/arrow-query-language/src/main/kotlin/arrow/aql/Prelude.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package arrow.aql | ||
|
||
import arrow.Kind | ||
|
||
typealias Source<F, A> = Kind<F, A> | ||
typealias Selection<A, Z> = A.() -> Z |
6 changes: 6 additions & 0 deletions
6
modules/aql/arrow-query-language/src/main/kotlin/arrow/aql/Query.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package arrow.aql | ||
|
||
data class Query<out F, A, out Z>( | ||
val select: Selection<A, Z>, | ||
val from: Source<F, A> | ||
) |
29 changes: 29 additions & 0 deletions
29
modules/aql/arrow-query-language/src/main/kotlin/arrow/aql/Select.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package arrow.aql | ||
|
||
import arrow.typeclasses.Functor | ||
|
||
/** | ||
* SELECT * FROM Student | ||
* | ||
* listOf(1, 2, 3) | ||
* .select { it * 10 } | ||
* .value() | ||
* //listOf(10, 20, 30) | ||
*/ | ||
interface Select<F> { | ||
|
||
fun functor(): Functor<F> | ||
|
||
infix fun <A, Z> Source<F, A>.query(f: Source<F, A>.() -> Z): Z = | ||
f(this) | ||
|
||
infix fun <A, Z> Source<F, A>.select(f: Selection<A, Z>): Query<F, A, Z> = | ||
Query(f, this) | ||
|
||
fun <A> Source<F, A>.selectAll(): Query<F, A, A> = | ||
Query({ this }, this) | ||
|
||
fun <A, Z> Query<F, A, Z>.value(): Source<F, Z> = | ||
functor().run { from.map(select) } | ||
|
||
} |
25 changes: 25 additions & 0 deletions
25
modules/aql/arrow-query-language/src/main/kotlin/arrow/aql/Sum.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package arrow.aql | ||
|
||
import arrow.core.* | ||
import arrow.typeclasses.Foldable | ||
|
||
interface Sum<F> { | ||
|
||
fun foldable(): Foldable<F> | ||
|
||
infix fun <A, Z> Query<F, A, Z>.sum(f: A.() -> Long): Query<ForId, Long, Long> = | ||
foldable().run { | ||
Query( | ||
select = ::identity, | ||
from = Id(from.foldLeft(0L) { acc, a -> | ||
acc + f(a) | ||
}) | ||
) | ||
} | ||
|
||
fun Query<ForId, Long, Long>.value(): Long = | ||
foldable().run { | ||
this@value.from.value() | ||
} | ||
|
||
} |
23 changes: 23 additions & 0 deletions
23
modules/aql/arrow-query-language/src/main/kotlin/arrow/aql/Union.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package arrow.aql | ||
|
||
import arrow.core.identity | ||
import arrow.data.ForListK | ||
import arrow.data.ListK | ||
import arrow.data.k | ||
import arrow.instances.list.semigroupK.combineK | ||
import arrow.instances.listk.monoid.monoid | ||
import arrow.typeclasses.Foldable | ||
|
||
interface Union<F> { | ||
|
||
fun foldable(): Foldable<F> | ||
|
||
infix fun <A, B, Z> Query<F, A, Z>.union(query: Query<F, B, Z>): Query<ForListK, Z, Z> = | ||
foldable().run { | ||
val la: ListK<Z> = from.foldMap(ListK.monoid()) { listOf(select(it)).k() } | ||
val lb: ListK<Z> = query.from.foldMap(ListK.monoid()) { listOf(query.select(it)).k() } | ||
val result: ListK<Z> = la.combineK(lb).k() | ||
Query(select = ::identity, from = result) | ||
} | ||
|
||
} |
35 changes: 35 additions & 0 deletions
35
modules/aql/arrow-query-language/src/main/kotlin/arrow/aql/Where.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package arrow.aql | ||
|
||
import arrow.core.None | ||
import arrow.core.some | ||
import arrow.mtl.typeclasses.FunctorFilter | ||
|
||
interface Where<F> { | ||
|
||
fun functorFilter(): FunctorFilter<F> | ||
|
||
infix fun <A, Z> Query<F, A, Z>.where(predicate: A.() -> Boolean): Query<F, A, Z> = | ||
functorFilter().run { | ||
copy(from = from.mapFilter { | ||
if (predicate(it)) it.some() | ||
else None | ||
}) | ||
} | ||
|
||
infix fun <A, Z> Query<F, A, Z>.whereSelection(predicate: Z.() -> Boolean): Query<F, A, Z> = | ||
functorFilter().run { | ||
copy(from = from.mapFilter { | ||
if (predicate(select(it))) it.some() | ||
else None | ||
}) | ||
} | ||
|
||
infix fun <A, Z> Query<F, A, Z>.having(predicate: A.() -> Boolean): Query<F, A, Z> = | ||
functorFilter().run { | ||
copy(from = from.mapFilter { | ||
if (predicate(it)) it.some() | ||
else None | ||
}) | ||
} | ||
|
||
} |
47 changes: 47 additions & 0 deletions
47
modules/aql/arrow-query-language/src/main/kotlin/arrow/aql/instances/either.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package arrow.aql.instances | ||
|
||
import arrow.aql.* | ||
import arrow.core.Either | ||
import arrow.core.EitherPartialOf | ||
import arrow.extension | ||
import arrow.instances.either.applicative.applicative | ||
import arrow.instances.either.foldable.foldable | ||
import arrow.instances.either.functor.functor | ||
import arrow.instances.listk.foldable.foldable | ||
import arrow.typeclasses.Applicative | ||
import arrow.typeclasses.Foldable | ||
import arrow.typeclasses.Functor | ||
|
||
@extension interface EitherSelect<L> : Select<EitherPartialOf<L>> { | ||
override fun functor(): Functor<EitherPartialOf<L>> = Either.functor() | ||
} | ||
|
||
@extension | ||
interface EitherFrom<L> : From<EitherPartialOf<L>> { | ||
override fun applicative(): Applicative<EitherPartialOf<L>> = Either.applicative() | ||
} | ||
|
||
@extension | ||
interface EitherGroupBy<L> : GroupBy<EitherPartialOf<L>> { | ||
override fun foldable(): Foldable<EitherPartialOf<L>> = Either.foldable() | ||
} | ||
|
||
@extension | ||
interface EitherCount<L> : Count<EitherPartialOf<L>> { | ||
override fun foldable(): Foldable<EitherPartialOf<L>> = Either.foldable() | ||
} | ||
|
||
@extension | ||
interface EitherSum<L> : Sum<EitherPartialOf<L>> { | ||
override fun foldable(): Foldable<EitherPartialOf<L>> = Either.foldable() | ||
} | ||
|
||
@extension | ||
interface EitherOrderBy<L> : OrderBy<EitherPartialOf<L>> { | ||
override fun foldable(): Foldable<EitherPartialOf<L>> = Either.foldable() | ||
} | ||
|
||
@extension | ||
interface EitherUnion<L> : Union<EitherPartialOf<L>> { | ||
override fun foldable(): Foldable<EitherPartialOf<L>> = Either.foldable() | ||
} |
21 changes: 21 additions & 0 deletions
21
modules/aql/arrow-query-language/src/main/kotlin/arrow/aql/instances/eval.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package arrow.aql.instances | ||
|
||
import arrow.aql.From | ||
import arrow.aql.Select | ||
import arrow.core.Eval | ||
import arrow.core.ForEval | ||
import arrow.extension | ||
import arrow.instances.eval.applicative.applicative | ||
import arrow.instances.eval.functor.functor | ||
import arrow.typeclasses.Applicative | ||
import arrow.typeclasses.Functor | ||
|
||
@extension | ||
interface EvalSelect : Select<ForEval> { | ||
override fun functor(): Functor<ForEval> = Eval.functor() | ||
} | ||
|
||
@extension | ||
interface EvalFrom : From<ForEval> { | ||
override fun applicative(): Applicative<ForEval> = Eval.applicative() | ||
} |
20 changes: 20 additions & 0 deletions
20
modules/aql/arrow-query-language/src/main/kotlin/arrow/aql/instances/function0.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package arrow.aql.instances | ||
|
||
import arrow.aql.From | ||
import arrow.aql.Select | ||
import arrow.core.ForFunction0 | ||
import arrow.core.Function0 | ||
import arrow.extension | ||
import arrow.instances.function0.applicative.applicative | ||
import arrow.instances.function0.functor.functor | ||
import arrow.typeclasses.Applicative | ||
import arrow.typeclasses.Functor | ||
|
||
@extension interface Function0Select : Select<ForFunction0> { | ||
override fun functor(): Functor<ForFunction0> = Function0.functor() | ||
} | ||
|
||
@extension | ||
interface Function0From : From<ForFunction0> { | ||
override fun applicative(): Applicative<ForFunction0> = Function0.applicative() | ||
} |
Oops, something went wrong.