From a52a91d6a96529dbefaae9f682af3a6025190e8d Mon Sep 17 00:00:00 2001 From: Yves Fischer Date: Fri, 5 Jun 2015 22:33:32 +0200 Subject: some things work --- src/main/scala/org/xapek/influxdb/Influxdb.scala | 165 +++++++++++++++++++++++ src/main/scala/org/xapek/influxdb/Main.scala | 39 ++++++ src/main/scala/org/xapek/influxdb/Sized.scala | 53 ++++++++ 3 files changed, 257 insertions(+) create mode 100644 src/main/scala/org/xapek/influxdb/Influxdb.scala create mode 100644 src/main/scala/org/xapek/influxdb/Main.scala create mode 100644 src/main/scala/org/xapek/influxdb/Sized.scala (limited to 'src/main/scala/org/xapek/influxdb') 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 -- cgit v1.2.1