summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/org/xapek/influxdb/Influxdb.scala165
-rw-r--r--src/main/scala/org/xapek/influxdb/Main.scala39
-rw-r--r--src/main/scala/org/xapek/influxdb/Sized.scala53
3 files changed, 257 insertions, 0 deletions
diff --git a/src/main/scala/org/xapek/influxdb/Influxdb.scala b/src/main/scala/org/xapek/influxdb/Influxdb.scala
new file mode 100644
index 0000000..15e2021
--- /dev/null
+++ b/src/main/scala/org/xapek/influxdb/Influxdb.scala
@@ -0,0 +1,165 @@
+package org.xapek.influxdb
+
+trait InfluxValue {
+ type JavaT
+ def toString(): String
+ def toJava: JavaT
+}
+
+class QueryBuilder1(select: Seq[InfluxColumn]) {
+ def FROM(table: String): QueryBuilder2 = {
+ new QueryBuilder2(select, table)
+ }
+}
+
+class QueryBuilder2(select: Seq[InfluxColumn], from: String) extends QueryBuilder1(select) {
+ def WHERE[E <: Expr](eq: E): QueryBuilder3[E] = {
+ new QueryBuilder3(eq, select, from)
+ }
+
+ override def toString(): String = {
+ "SELECT " + select.mkString(", ") + " FROM " + from
+ }
+}
+
+class QueryBuilder3[WhereT <: Expr](whereExpr: WhereT, select: Seq[InfluxColumn], from: String) extends QueryBuilder2(select, from) {
+ def &&[E2 <: Expr](other: E2): QueryBuilder3[AndExpr[WhereT, E2]] = {
+ new QueryBuilder3(new AndExpr(whereExpr, other), select, from)
+ }
+
+ def ||[E2 <: Expr](other: E2): QueryBuilder3[OrExpr[WhereT, E2]] = {
+ new QueryBuilder3(new OrExpr(whereExpr, other), select, from)
+ }
+
+ def GROUP_BY[ColumnT <% InfluxColumn](column: ColumnT): QueryBuilder4[WhereT] = {
+ new QueryBuilder4(List(column), whereExpr, select, from)
+ }
+
+ override def toString(): String = {
+ super.toString() + " WHERE " + whereExpr.toString()
+ }
+}
+
+class QueryBuilder4[WhereT <: Expr](groupBy: Seq[InfluxColumn], whereExpr: WhereT, select: Seq[InfluxColumn], from: String) extends QueryBuilder3(whereExpr, select, from) {
+ def <<=[ColumnT <% InfluxColumn](column: ColumnT): QueryBuilder4[WhereT] = {
+ val x: InfluxColumn = column
+ new QueryBuilder4(groupBy :+ x, whereExpr, select, from)
+ }
+
+ override def toString(): String = {
+ super.toString() + " GROUP BY " + groupBy.mkString(", ")
+ }
+}
+
+protected trait E {
+ def &&[E2 <: Expr](other: E2): AndExpr[this.type, E2]
+ def ||[E2 <: Expr](other: E2): OrExpr[this.type, E2]
+}
+
+abstract class Expr extends E {
+ def toString(): String
+
+ def &&[E2 <: Expr](other: E2) = {
+ new AndExpr(this, other)
+ }
+
+ def ||[E2 <: Expr](other: E2) = {
+ new OrExpr(this, other)
+ }
+
+ def test(other: Expr): Expr = {
+ return this
+ }
+}
+
+class ValueExpr[ValueT <: InfluxValue](val value: ValueT) extends Expr {
+ override def toString(): String = value.toString
+}
+
+abstract class BinaryOp[E1 <: E, E2 <: E](val op1: E1, val op2: E2) extends Expr {
+ def str: String
+ override def toString(): String = {
+ "(" + op1.toString() + " " + str + " " + op2.toString() + ")"
+ }
+}
+
+class AndExpr[E1 <: E, E2 <: E](op1: E1, op2: E2) extends BinaryOp[E1, E2](op1, op2) {
+ def str = "AND"
+}
+
+class OrExpr[E1 <: E, E2 <: E](op1: E1, op2: E2) extends BinaryOp[E1, E2](op1, op2) {
+ override def str = "OR"
+}
+
+class EqExpr[T <: InfluxValue](column: InfluxColumn, op: ValueExpr[T]) extends BinaryOp[InfluxColumn, ValueExpr[T]](column, op) {
+ def str = "=="
+}
+
+class NeqExpr[T <: InfluxValue](column: InfluxColumn, op: ValueExpr[T]) extends BinaryOp[InfluxColumn, ValueExpr[T]](column, op) {
+ def str = "=="
+}
+
+class InfluxString(val value: String) extends Expr with InfluxValue {
+ type JavaT = String
+ override def toString(): String = {
+ "'" + value.replace("\\", "\\\\").replace("'", "\\'") + "'" // TODO
+ }
+ override def toJava(): String = value
+}
+
+class InfluxNumber(val value: Number) extends Expr with InfluxValue {
+ type JavaT = Number
+
+ override def toString(): String = {
+ value.toString
+ }
+ override def toJava(): Number = value
+}
+
+class InfluxColumn(val name: String) extends Expr {
+ override def toString(): String = {
+ "\"" + name.replace("\\", "\\\\").replace("\"", "\\\"") + "\""
+ }
+
+ def ==[Z <: InfluxValue, ValueT <% Z](value: ValueT): EqExpr[Z] = {
+ new EqExpr(this, new ValueExpr(value))
+ }
+
+ def !=[Z <: InfluxValue, ValueT <% Z](value: ValueT): NeqExpr[Z] = {
+ new NeqExpr(this, new ValueExpr(value))
+ }
+}
+
+object Influxdb {
+ def SELECT(select: Seq[String]): QueryBuilder1 = {
+ new QueryBuilder1(select.map { x: String => influxColumn(x) })
+ }
+
+ def SELECT[ColumnT <% InfluxColumn](select: ColumnT): QueryBuilder1 = {
+ new QueryBuilder1(List(select))
+ }
+
+ def col(col: String): InfluxColumn = {
+ new InfluxColumn(col)
+ }
+
+ implicit def influxString(s: String): InfluxString = {
+ new InfluxString(s)
+ }
+
+ implicit def influxNumber(n: Int): InfluxNumber = {
+ new InfluxNumber(n)
+ }
+
+ implicit def influxNumber(n: Double): InfluxNumber = {
+ new InfluxNumber(n)
+ }
+
+ implicit def influxColumn(s: String): InfluxColumn = {
+ new InfluxColumn(s)
+ }
+
+ implicit def queryToString(q: QueryBuilder2): String = q.toString
+ implicit def queryToString[T <: Expr](q: QueryBuilder3[T]): String = q.toString
+ implicit def queryToString[T <: Expr](q: QueryBuilder4[T]): String = q.toString
+}
diff --git a/src/main/scala/org/xapek/influxdb/Main.scala b/src/main/scala/org/xapek/influxdb/Main.scala
new file mode 100644
index 0000000..c56d3bb
--- /dev/null
+++ b/src/main/scala/org/xapek/influxdb/Main.scala
@@ -0,0 +1,39 @@
+package org.xapek.influxdb
+
+import akka.actor.Actor
+import akka.actor.Props
+import akka.event.Logging
+import akka.actor.ActorDSL
+import akka.actor.ActorSystem
+import akka.actor.ActorLogging
+import org.xapek.influxdb.Influxdb._
+
+case class Row(columns: Seq[String])
+
+case class Write(measurement: String, columns: Seq[String])
+class GenericReader(query: String) extends Actor with ActorLogging {
+ def receive = {
+ case row: Row => log.info("Thanks for the pint: " + row.columns.toString())
+ }
+}
+
+object MyReader extends GenericReader(Influxdb SELECT "value" FROM "test" WHERE col("time") == 30)
+
+
+
+
+object Main {
+
+ def main(args: Array[String]): Unit = {
+ // val system = ActorSystem("test")
+ // val alice = system.actorOf(Props(MyReader), "alice")
+ //
+ // alice ! new Row(List("a"))
+ //
+ // system.shutdown()
+ //
+ // val x : Tuple2[Int,Int] = (1,2)
+
+ }
+}
+
diff --git a/src/main/scala/org/xapek/influxdb/Sized.scala b/src/main/scala/org/xapek/influxdb/Sized.scala
new file mode 100644
index 0000000..fc402cd
--- /dev/null
+++ b/src/main/scala/org/xapek/influxdb/Sized.scala
@@ -0,0 +1,53 @@
+package org.xapek.influxdb
+
+/**
+ * Partial re-implementation of Sized and Nat type from https://github.com/milessabin/shapeless
+ */
+
+/** Natural Number Type */
+trait Nat {
+ type N <: Nat
+}
+
+/** Successor */
+case class Succ[P <: Nat]() extends Nat {
+ type N = Succ[P]
+}
+
+/** Zero */
+class _0 extends Nat with Serializable {
+ type N = _0
+}
+
+/** Nat type to Int value conversion */
+trait ToInt[N <: Nat] extends Serializable {
+ def apply(): Int
+}
+
+object ToInt {
+ def apply[N <: Nat](implicit toInt: ToInt[N]): ToInt[N] = toInt
+
+ implicit val toInt0 = new ToInt[_0] {
+ def apply() = 1
+ }
+ implicit def toIntSucc[N <: Nat](implicit toIntN: ToInt[N]) = new ToInt[Succ[N]] {
+ def apply() = toIntN() + 1
+ }
+}
+
+/** Seq with size coded in type */
+class Sized[Repr, L <: Nat](val unsized: Seq[Repr]) extends AnyVal {
+ override def toString = unsized.toString
+}
+
+object SizedOp {
+ def wrap[Repr, L <: Nat](r: Repr) = new Sized[Repr, _0](List(r))
+
+ def add[Repr, L <: Nat](s: Sized[Repr, L], r: Repr) = new Sized[Repr, Succ[L]](s.unsized ++ List(r))
+
+ def toInt[N <: Nat](implicit toIntN: ToInt[N]) = toIntN()
+
+ def toInt(n: Nat)(implicit toIntN: ToInt[n.N]) = toIntN()
+
+ def count[Repr, M <: Nat](s: Sized[Repr, M])(implicit ev: ToInt[M]) = toInt[M]
+} \ No newline at end of file