Query and display phenomena
This commit is contained in:
@@ -45,22 +45,22 @@ object Main {
|
|||||||
// } yield re
|
// } yield re
|
||||||
|
|
||||||
val formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmm")
|
val formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmm")
|
||||||
val from = LocalDateTime.parse("20240110_1000", formatter)
|
val from = LocalDateTime.parse("20240207_1000", formatter)
|
||||||
val to = LocalDateTime.parse("20240111_1000", formatter)
|
val to = LocalDateTime.parse("20240208_1400", formatter)
|
||||||
// val cities = NonEmptyList.of("Ainaži", "Rīga", "Kolka", "Vičaki")
|
val cities = NonEmptyList.of("Ainaži", "Rīga", "Kolka", "Vičaki")
|
||||||
// val cities = NonEmptyList.of("Rīga")
|
// val cities = NonEmptyList.of("Rīga")
|
||||||
|
|
||||||
// val query = UserQuery(cities, "tempMax", AggregateKey.List, ChronoUnit.DAYS, from, to)
|
val query = UserQuery(cities, "phenomena", AggregateKey.List, ChronoUnit.DAYS, from, to)
|
||||||
|
|
||||||
val re = for {
|
val re = for {
|
||||||
postgresService <- PostgresService.of(xa)
|
postgresService <- PostgresService.of(xa)
|
||||||
re <- postgresService.queryCityAllFields("Rīga", from, to)
|
re <- postgresService.query(query)
|
||||||
} yield re
|
} yield re
|
||||||
|
|
||||||
// val jssson = re.map(result => ResponseWrapper(result, query))
|
// val jssson = re.map(result => ResponseWrapper(result, query))
|
||||||
// .map(responseWrapper => responseWrapper.asJson.pretty)
|
// .map(responseWrapper => responseWrapper.asJson.pretty)
|
||||||
|
|
||||||
println(re.unsafeRunSync())
|
println(re.unsafeRunSync().asJson.pretty)
|
||||||
|
|
||||||
|
|
||||||
// println(jssson.unsafeRunSync())
|
// println(jssson.unsafeRunSync())
|
||||||
|
|||||||
@@ -11,8 +11,12 @@ import java.time.{LocalDate, LocalDateTime, OffsetDateTime}
|
|||||||
import doobie.postgres.implicits._
|
import doobie.postgres.implicits._
|
||||||
import org.typelevel.log4cats.Logger
|
import org.typelevel.log4cats.Logger
|
||||||
import org.typelevel.log4cats.slf4j.Slf4jLogger
|
import org.typelevel.log4cats.slf4j.Slf4jLogger
|
||||||
import parse.Aggregate.{AggregateKey, AggregateValue, DoubleValue, TimeDoubleList, UserQuery}
|
import parse.Aggregate.{AggregateKey, AggregateValue, DistinctStringList, DoubleValue, TimeDoubleList, UserQuery}
|
||||||
import parse.{Parser, WeatherStationData}
|
import parse.{Parser, WeatherStationData}
|
||||||
|
import shapeless.syntax.std.tuple.productTupleOps
|
||||||
|
|
||||||
|
import io.circe._
|
||||||
|
import io.circe.parser._
|
||||||
|
|
||||||
import java.time.temporal.ChronoUnit
|
import java.time.temporal.ChronoUnit
|
||||||
import scala.util.matching.Regex
|
import scala.util.matching.Regex
|
||||||
@@ -101,9 +105,31 @@ class PostgresService(transactor: Transactor[IO], log: Logger[IO]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def query(userQuery: UserQuery): IO[Map[String, Option[AggregateValue]]] = {
|
def query(userQuery: UserQuery): IO[Map[String, Option[AggregateValue]]] = {
|
||||||
if (userQuery.field == "phenomena") { // this handles strings
|
if (userQuery.field == "phenomena") {
|
||||||
// TODO query list and distinct values from phenomena
|
val query =
|
||||||
IO(Map()) // empty result
|
fr"""
|
||||||
|
SELECT city, array_to_json(array_agg(phenomena)) AS aggregated_phenomena
|
||||||
|
FROM weather
|
||||||
|
WHERE """ ++ Fragments.in(fr"city", userQuery.cities) ++
|
||||||
|
fr" AND dateTime BETWEEN ${userQuery.from} AND ${userQuery.to}" ++
|
||||||
|
fr" GROUP BY city, phenomena"
|
||||||
|
|
||||||
|
query.query[(String, Option[String])]
|
||||||
|
.to[List]
|
||||||
|
.transact(transactor)
|
||||||
|
.map { resultList =>
|
||||||
|
resultList
|
||||||
|
.flatMap {
|
||||||
|
case (city, jsonOption) =>
|
||||||
|
jsonOption.flatMap { jsonString =>
|
||||||
|
parse(jsonString).toOption.flatMap(_.as[List[List[String]]].toOption.map(_.flatten.distinct))
|
||||||
|
}.map(phenomena => (city, phenomena.filter(_.nonEmpty)))
|
||||||
|
}
|
||||||
|
.groupBy(_._1)
|
||||||
|
.view.mapValues(_.flatMap(_._2).distinct).toMap
|
||||||
|
.map { case (city, phenomenaList) => city -> Option(DistinctStringList(phenomenaList)) }
|
||||||
|
}
|
||||||
|
|
||||||
} else if (List(
|
} else if (List(
|
||||||
AggregateKey.Max,
|
AggregateKey.Max,
|
||||||
AggregateKey.Min,
|
AggregateKey.Min,
|
||||||
|
|||||||
@@ -93,7 +93,9 @@ object Aggregate {
|
|||||||
implicit val stringListListEncoder: Encoder[StringListList] = Encoder.instance { sllValue =>
|
implicit val stringListListEncoder: Encoder[StringListList] = Encoder.instance { sllValue =>
|
||||||
Json.arr(sllValue.list.map(_.asJson): _*)
|
Json.arr(sllValue.list.map(_.asJson): _*)
|
||||||
}
|
}
|
||||||
implicit val distinctStringListEncoder: Encoder[DistinctStringList] = deriveEncoder[DistinctStringList]
|
implicit val distinctStringListEncoder: Encoder[DistinctStringList] = Encoder.instance { dslistValue =>
|
||||||
|
Json.arr(dslistValue.list.map(_.asJson): _*)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private def convertDateTime(granularity: ChronoUnit)(data: (LocalDateTime, _)): String = {
|
private def convertDateTime(granularity: ChronoUnit)(data: (LocalDateTime, _)): String = {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Component } from "solid-js";
|
import { Component, Match, Switch } from "solid-js";
|
||||||
|
|
||||||
import { CityChart } from "../../components/chart/CityChart";
|
import { CityChart } from "../../components/chart/CityChart";
|
||||||
import { DataQuery } from "../helpers";
|
import { DataQuery } from "../helpers";
|
||||||
@@ -7,11 +7,14 @@ export const GridResult: Component<{ city: string, query: DataQuery, result: any
|
|||||||
return (
|
return (
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<h4>{ city }</h4>
|
<h4>{ city }</h4>
|
||||||
{
|
<Switch fallback={<p>{ result }</p>}>
|
||||||
isDateNumber(result)
|
<Match when={query.field === "phenomena"}>
|
||||||
? <CityChart city={()=>city} data={()=>result} query={()=>query}/>
|
{ result.join(", ") }
|
||||||
: <p>{ result }</p>
|
</Match>
|
||||||
}
|
<Match when={isDateNumber(result)}>
|
||||||
|
<CityChart city={()=>city} data={()=>result} query={()=>query}/>
|
||||||
|
</Match>
|
||||||
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user