Query and display phenomena
This commit is contained in:
@@ -45,22 +45,22 @@ object Main {
|
||||
// } yield re
|
||||
|
||||
val formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmm")
|
||||
val from = LocalDateTime.parse("20240110_1000", formatter)
|
||||
val to = LocalDateTime.parse("20240111_1000", formatter)
|
||||
// val cities = NonEmptyList.of("Ainaži", "Rīga", "Kolka", "Vičaki")
|
||||
val from = LocalDateTime.parse("20240207_1000", formatter)
|
||||
val to = LocalDateTime.parse("20240208_1400", formatter)
|
||||
val cities = NonEmptyList.of("Ainaži", "Rīga", "Kolka", "Vičaki")
|
||||
// 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 {
|
||||
postgresService <- PostgresService.of(xa)
|
||||
re <- postgresService.queryCityAllFields("Rīga", from, to)
|
||||
re <- postgresService.query(query)
|
||||
} yield re
|
||||
|
||||
// val jssson = re.map(result => ResponseWrapper(result, query))
|
||||
// .map(responseWrapper => responseWrapper.asJson.pretty)
|
||||
|
||||
println(re.unsafeRunSync())
|
||||
println(re.unsafeRunSync().asJson.pretty)
|
||||
|
||||
|
||||
// println(jssson.unsafeRunSync())
|
||||
|
||||
@@ -11,8 +11,12 @@ import java.time.{LocalDate, LocalDateTime, OffsetDateTime}
|
||||
import doobie.postgres.implicits._
|
||||
import org.typelevel.log4cats.Logger
|
||||
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 shapeless.syntax.std.tuple.productTupleOps
|
||||
|
||||
import io.circe._
|
||||
import io.circe.parser._
|
||||
|
||||
import java.time.temporal.ChronoUnit
|
||||
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]]] = {
|
||||
if (userQuery.field == "phenomena") { // this handles strings
|
||||
// TODO query list and distinct values from phenomena
|
||||
IO(Map()) // empty result
|
||||
if (userQuery.field == "phenomena") {
|
||||
val query =
|
||||
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(
|
||||
AggregateKey.Max,
|
||||
AggregateKey.Min,
|
||||
|
||||
@@ -93,7 +93,9 @@ object Aggregate {
|
||||
implicit val stringListListEncoder: Encoder[StringListList] = Encoder.instance { sllValue =>
|
||||
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 = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component } from "solid-js";
|
||||
import { Component, Match, Switch } from "solid-js";
|
||||
|
||||
import { CityChart } from "../../components/chart/CityChart";
|
||||
import { DataQuery } from "../helpers";
|
||||
@@ -7,11 +7,14 @@ export const GridResult: Component<{ city: string, query: DataQuery, result: any
|
||||
return (
|
||||
<div class="item">
|
||||
<h4>{ city }</h4>
|
||||
{
|
||||
isDateNumber(result)
|
||||
? <CityChart city={()=>city} data={()=>result} query={()=>query}/>
|
||||
: <p>{ result }</p>
|
||||
}
|
||||
<Switch fallback={<p>{ result }</p>}>
|
||||
<Match when={query.field === "phenomena"}>
|
||||
{ result.join(", ") }
|
||||
</Match>
|
||||
<Match when={isDateNumber(result)}>
|
||||
<CityChart city={()=>city} data={()=>result} query={()=>query}/>
|
||||
</Match>
|
||||
</Switch>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user