From d72dd2edaa58d3d7cf84d0b07f99337447514470 Mon Sep 17 00:00:00 2001 From: Yves Fischer Date: Sun, 7 Jun 2015 23:03:26 +0200 Subject: use Sized from shapeless --- src/main/scala/org/xapek/influxdb/Influxdb.scala | 106 +++++++++++++---------- src/main/scala/org/xapek/influxdb/Main.scala | 17 +++- src/main/scala/org/xapek/influxdb/Sized.scala | 56 ------------ 3 files changed, 72 insertions(+), 107 deletions(-) delete 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 index f5d33f4..7df8afa 100644 --- a/src/main/scala/org/xapek/influxdb/Influxdb.scala +++ b/src/main/scala/org/xapek/influxdb/Influxdb.scala @@ -9,58 +9,71 @@ import org.slf4j.LoggerFactory import org.json4s._ import org.json4s.jackson.JsonMethods._ import com.typesafe.scalalogging.Logger -import scala.util.parsing.json.JSONObject +import shapeless.Nat +import shapeless.Sized +import shapeless.Sized._ +import shapeless.syntax._ +import shapeless.syntax.NatOps +import shapeless.syntax.sized._ +import shapeless.Succ +import shapeless.ops.sized._ +import shapeless.ops.nat._ +import shapeless.ops._ + +abstract class QueryBuilderWithSelectAndFrom[L <: Nat]( + val columns: Sized[List[InfluxIdentifier], L], + val table: InfluxIdentifier) { + + def count()(implicit toInt: ToInt[L]) = toInt() + + def count1()(implicit toInt: ToInt[Succ[L]]) = toInt() //length + 1 (for "time") -abstract class QueryBuilderWithSelectAndFrom[L <: Nat, IdentT <% InfluxIdentifier]( - val columns: Sized[IdentT, L], - val table: IdentT) { def toString: String } -class QueryBuilderSelect[L <: Nat, IdentT <% InfluxIdentifier]( - val columns: Sized[IdentT, L]) { - def apply(column: IdentT) = - new QueryBuilderSelect(SizedOp.add(columns, column)) +class QueryBuilderSelect[L <: Nat]( + val columns: Sized[List[InfluxIdentifier], L]) { - def FROM(table: IdentT) = new QueryBuilderFrom(this, table) + def apply(column: String) = + new QueryBuilderSelect(columns :+ InfluxDB.influxIdentifier(column)) - implicit def influxIdentifier(s: String): InfluxIdentifier = { - new InfluxIdentifier(s) - } + def FROM(table: String) = new QueryBuilderFrom(this, InfluxDB.influxIdentifier(table)) override def toString() = "SELECT " + columns.unsized.mkString(", ") } -class QueryBuilderFrom[L <: Nat, IdentT <% InfluxIdentifier]( - select: QueryBuilderSelect[L, IdentT], - table: IdentT) - extends QueryBuilderWithSelectAndFrom[L, IdentT](select.columns, table) { +class QueryBuilderFrom[L <: Nat]( + select: QueryBuilderSelect[L], + table: InfluxIdentifier) + extends QueryBuilderWithSelectAndFrom[L](select.columns, table) { + def WHERE[WhereT <: Expr](where: WhereT) = new QueryBuilderWhere(this, where) override def toString() = select.toString() + " FROM " + table } -class QueryBuilderWhere[L <: Nat, IdentT <% InfluxIdentifier, WhereT <: Expr]( - val from: QueryBuilderFrom[L, IdentT], +class QueryBuilderWhere[L <: Nat, WhereT <: Expr]( + val from: QueryBuilderFrom[L], val where: WhereT) - extends QueryBuilderWithSelectAndFrom[L, IdentT](from.columns, from.table) { + extends QueryBuilderWithSelectAndFrom[L](from.columns, from.table) { - def GROUP_BY(column: IdentT) = - new QueryBuilderGroupBy(this, List(column)) + def GROUP_BY(column: String) = new QueryBuilderGroupBy(this, List(InfluxDB.influxIdentifier(column))) override def toString() = from.toString() + " WHERE " + where } -class QueryBuilderGroupBy[L <: Nat, IdentT <% InfluxIdentifier, WhereT <: Expr]( - where: QueryBuilderWhere[L, IdentT, WhereT], - var groupBy: Seq[IdentT]) - extends QueryBuilderWithSelectAndFrom[L, IdentT](where.columns, where.table) { +class QueryBuilderGroupBy[L <: Nat, WhereT <: Expr]( + where: QueryBuilderWhere[L, WhereT], + groupBy: Seq[InfluxIdentifier]) + extends QueryBuilderWithSelectAndFrom[L](where.columns, where.table) { + + def apply(column: String) = new QueryBuilderGroupBy(where, groupBy :+ InfluxDB.influxIdentifier(column)) +// { +// groupBy = groupBy :+ InfluxDB.influxIdentifier(column) +// this +// } - def apply(column: IdentT): QueryBuilderGroupBy[L, IdentT, WhereT] = { - groupBy = groupBy ++ List(column) - this - } override def toString() = where.toString() + " GROUP BY " + groupBy.mkString(", ") } @@ -97,6 +110,7 @@ final object BinaryOp { val OP_LT = "<" val OP_LE = "<=" } + class BinaryOp[E1 <: E, E2 <: E](val str: String, val op1: E1, val op2: E2) extends Expr { override def toString(): String = { "(" + op1.toString() + " " + str + " " + op2.toString() + ")" @@ -160,11 +174,14 @@ class InfluxIdentifier(val name: String) extends Expr { def <=[ToValueT <% ValueT, ValueT <: InfluxValue](value: ToValueT) = new BinaryOp(BinaryOp.OP_LE, this, new ValueExpr[ValueT](value)) + + implicit def influxIdentifier(s: String): InfluxIdentifier = new InfluxIdentifier(s) } case class JsonResult(series: List[JsonSeries], error: String) { def this(series: List[JsonSeries]) = this(series, null) } + case class JsonSeries(name: String, columns: List[String], values: List[List[Any]]) { override def toString() = values.map { _.map { _.getClass() } }.mkString(", ") } @@ -172,9 +189,9 @@ case class JsonSeries(name: String, columns: List[String], values: List[List[Any class InfluxdbError(val serverMessage: String) extends Exception(s"Server responded: $serverMessage") -class InfluxdbExecutor[L <: Nat, IdentT <% InfluxIdentifier]( +class InfluxdbExecutor[L <: Nat]( connection: InfluxDB, - query: QueryBuilderWithSelectAndFrom[L, IdentT])(implicit ev: ToInt[L]) { + query: QueryBuilderWithSelectAndFrom[L])(implicit toInt: ToInt[L]) { private val httpClient = HttpClients.createDefault(); private val logger = Logger(LoggerFactory.getLogger(getClass)) private val uriBuilder = new URIBuilder() @@ -194,8 +211,8 @@ class InfluxdbExecutor[L <: Nat, IdentT <% InfluxIdentifier]( // {"name":"esg", // "columns":["time","product_name","sku","price"], // "values":[ - // ["2015-06-05T09:30:13.084815572Z","Goldbarren 100g Heraeus","01011072",3400.73], - // ["2015-06-05T17:00:13.888788593Z","Goldbarren 100g Heraeus","01011072",3425.29]]}]}]} + // ["2015-06-05T09:30:13.084815572Z","GoldXXXeus","asd",3400.73], + // ["2015-06-05T17:00:13.888788593Z","GoldXXXaeus","asd",3425.29]]}]}]} uriBuilder.setParameter("q", query.toString()) val httpGet = new HttpGet(uriBuilder.build()) @@ -219,9 +236,9 @@ class InfluxdbExecutor[L <: Nat, IdentT <% InfluxIdentifier]( } val columns = query.columns - println(SizedOp.count(columns)) + println(query.count()) // toIntSucc(columns) -//collection.mutable.LinkedList + //collection.mutable.LinkedList List(columns.toString()) } } @@ -231,20 +248,17 @@ class InfluxDB(val database: String, val port: Int = 8086, val username: String = "", val password: String = "") { - def apply[L <: Nat, IdentT <% InfluxIdentifier]( - q: QueryBuilderWithSelectAndFrom[L, IdentT])(implicit ev: ToInt[L]) = { - new InfluxdbExecutor[L, IdentT](this, q) + def apply[L <: Nat](q: QueryBuilderWithSelectAndFrom[L])(implicit toInt: ToInt[L]) = { + new InfluxdbExecutor[L](this, q) } - - // def server(database: String, host: String, port: Long = 8080L, username: String = "", password: String = "") = - // 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 } object InfluxDB { - def SELECT(column: String) = - new QueryBuilderSelect(SizedOp.wrap(influxColumn(column))) + def SELECT(column: String) = { + new QueryBuilderSelect(Sized[List](influxIdentifier(column))) + } + + implicit def influxIdentifier(s: String): InfluxIdentifier = new InfluxIdentifier(s) implicit def influxString(s: String) = new InfluxString(s) @@ -254,8 +268,6 @@ object InfluxDB { implicit def influxDate(n: Date): InfluxDate = new InfluxDate(n) - implicit def influxColumn(s: String) = new InfluxIdentifier(s) - def col(col: String) = new InfluxIdentifier(col) def time = new InfluxIdentifier("time") diff --git a/src/main/scala/org/xapek/influxdb/Main.scala b/src/main/scala/org/xapek/influxdb/Main.scala index 0f9bc12..f2b5a65 100644 --- a/src/main/scala/org/xapek/influxdb/Main.scala +++ b/src/main/scala/org/xapek/influxdb/Main.scala @@ -9,6 +9,9 @@ import akka.actor.ActorLogging import org.xapek.influxdb.InfluxDB._ import java.util.Date import java.util.Calendar +import shapeless.Nat +import shapeless.Nat._ +import shapeless.ops.nat._ case class Row(columns: Seq[String]) @@ -26,7 +29,7 @@ object Main { def main(args: Array[String]): Unit = { val db = new InfluxDB("data", "localhost") - val s2 = SELECT("foo")("asd").FROM("table").WHERE(col("asd") == "asd") + val s2 = SELECT("foo")("asd")("ads") FROM ("asd") WHERE (col("asd") == "asd") val s3 = SELECT("foo")("bla")("baz") FROM "asd" WHERE time > "asd" @@ -38,9 +41,15 @@ object Main { calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - 2) // SELECT mean(price) FROM "esg" WHERE $timeFilter AND sku='01011072' GROUP BY time($interval) ORDER BY asc - val foo = db(SELECT("product_name")("sku")("price") FROM "esg" WHERE col("sku") == "01011072" && time > calendar.getTime) - .map({ x => x }) - println(foo) + val s4 = SELECT("product_name")("sku")("price") FROM "esg" WHERE col("sku") == "01011072" && time > calendar.getTime + val z = db(s4).map({ x => x }) + println(z) + + // val z = ToInt[s4.LT]() + // val foo = db(s4) + // .map({ x => x }) + // println(foo) + // val system = ActorSystem("test") // val alice = system.actorOf(Props(MyReader), "alice") // diff --git a/src/main/scala/org/xapek/influxdb/Sized.scala b/src/main/scala/org/xapek/influxdb/Sized.scala deleted file mode 100644 index 2b4e6cc..0000000 --- a/src/main/scala/org/xapek/influxdb/Sized.scala +++ /dev/null @@ -1,56 +0,0 @@ -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() = 0 - } - - 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 empty[Repr]() = new Sized[Repr, _0](List.empty[Repr]) - - def wrap[Repr, L <: Nat](r: Repr) = new Sized[Repr, Succ[_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