Fix parsing db url, remove 24h state, add db saving

This commit is contained in:
Guntis Smaukstelis
2023-12-10 20:37:53 +02:00
parent f956d658d5
commit 8f2ade2fcf
5 changed files with 51 additions and 41 deletions
+5
View File
@@ -37,6 +37,11 @@ npm run dev
- Shell script - Shell script
- Fly.io - Fly.io
## Database
```
SELECT * FROM public.weather WHERE datetime > '2023-12-9T00:00:00+00'::timestamptz;
DELETE FROM public.weather
```
## Docker ## Docker
``` ```
+1 -1
View File
@@ -9,7 +9,7 @@ import server.Server
object Main extends IOApp { object Main extends IOApp {
def run(args: List[String]): IO[ExitCode] = { def run(args: List[String]): IO[ExitCode] = {
// postgres://weather_tool:XID547uldXliJBa@weather-tool-db.flycast:5432/weather_tool?sslmode=disable // postgres://weather_tool:XID547uldXliJBa@weather-tool-db.flycast:5432/weather_tool?sslmode=disable
// println(System.getenv("DATABASE_URL")) // println(System.getenv("DATABASE_URL"))
for { for {
transactor <- DBConnection.transactor[IO] transactor <- DBConnection.transactor[IO]
+10 -8
View File
@@ -6,24 +6,26 @@ import pureconfig._
import pureconfig.generic.auto._ import pureconfig.generic.auto._
import pureconfig.error.ConfigReaderFailures import pureconfig.error.ConfigReaderFailures
import java.net.URI
import scala.util.Try import scala.util.Try
case class PostgresConfig(url: String, username: String, password: String) case class PostgresConfig(url: String, username: String, password: String)
object DBConnection { object DBConnection {
private def getDatabaseUrl: String = private def getDatabaseUrl: String =
sys.env.getOrElse("DATABASE_URL", sys.env.getOrElse("DATABASE_URL", "postgres://postgres:mysecretpassword@localhost:5432/weather-tool")
"postgres://postgres:mysecretpassword@localhost:5432/weather-tool")
private def parseUrl(url: String): Either[String, PostgresConfig] = { private def parseUrl(url: String): Either[String, PostgresConfig] = {
Try { Try {
val uri = new java.net.URI(if (url.startsWith("jdbc:")) url.substring(5) else url) val raw = URI.create(url)
val userInfo = uri.getUserInfo.split(":")
val username = userInfo(0)
val password = userInfo(1)
val dbUrl = s"jdbc:postgresql://${uri.getHost}:${uri.getPort}${uri.getPath}"
println(s"u: $username, p: $password, u: $url") val name = raw.getPath.substring(1)
println("")
val dbUrl = s"jdbc:postgresql://${raw.getHost}:${raw.getPort}${raw.getPath}?${raw.getQuery}"
val username = raw.getUserInfo.split(":")(0)
val password = raw.getUserInfo.split(":")(1)
println(s"n: $name u: $username, p: $password, url: $url")
PostgresConfig(dbUrl, username, password) PostgresConfig(dbUrl, username, password)
}.toEither.left.map(_.getMessage) }.toEither.left.map(_.getMessage)
+32 -29
View File
@@ -26,47 +26,50 @@ object DataService {
): IO[DataService] = { ): IO[DataService] = {
for { for {
log <- Slf4jLogger.create[IO] log <- Slf4jLogger.create[IO]
fileNameService = new FileNameService() // fileNameService = new FileNameService()
fileNames <- fileNameService.generateLast24Hours // fileNames <- fileNameService.generateLast24Hours
contents <- fileNames.traverse(fileName => fileService.readFile(fileName) // contents <- fileNames.traverse(fileName => fileService.readFile(fileName)
.map(content => (fileName, content))) // .map(content => (fileName, content)))
state = contents.toMap // state = contents.toMap
stateRef <- Ref.of[IO, Map[String, List[String]]](state) // stateRef <- Ref.of[IO, Map[String, List[String]]](state)
} yield new DataService(fileService, postgresService, new FileNameService(), log, stateRef) } yield new DataService(fileService, postgresService, log)
// } yield new DataService(fileService, postgresService, new FileNameService(), log)
// } yield new DataService(fileService, postgresService, new FileNameService(), log, stateRef)
// } yield new DataService(fileService, new FileNameService(), log, stateRef) // } yield new DataService(fileService, new FileNameService(), log, stateRef)
} }
} }
class DataService private( class DataService private(
fileService: FileService, fileService: FileService,
postgresService: PostgresService, postgresService: PostgresService,
fileNameService: FileNameService, // fileNameService: FileNameService,
log: Logger[IO], log: Logger[IO],
private val state: Ref[IO, Map[String, List[String]]] // private val state: Ref[IO, Map[String, List[String]]]
) extends DataServiceTrait { ) extends DataServiceTrait {
private def logState: IO[Unit] = { // private def logState: IO[Unit] = {
state.get.flatMap(currentState => log.info(s"State keys: ${currentState.keys.size}")) // state.get.flatMap(currentState => log.info(s"State keys: ${currentState.keys.size}"))
} // }
//
private def filterState: IO[Unit] = { // private def filterState: IO[Unit] = {
fileNameService.generateLast24Hours.flatMap { last24Hours => // fileNameService.generateLast24Hours.flatMap { last24Hours =>
state.update(st => st.filterKeys(last24Hours.contains).toMap) // state.update(st => st.filterKeys(last24Hours.contains).toMap)
} // }
} // }
def save(fileName: String, content: String): IO[String] = { def save(fileName: String, content: String): IO[String] = {
// TODO replace unsafeRunSync to redeemWith // TODO replace unsafeRunSync to redeemWith
postgresService.save(fileName, content).unsafeRunSync() postgresService.save(fileName, content).unsafeRunSync()
// TODO delete this // TODO delete this
fileService.save(fileName, content).redeemWith( fileService.save(fileName, content)
error => IO.raiseError(error), // fileService.save(fileName, content).redeemWith(
savedFileName => { // error => IO.raiseError(error),
state.update(st => st.updated(savedFileName, content.split("\n").toList)) *> // savedFileName => {
filterState *> // state.update(st => st.updated(savedFileName, content.split("\n").toList)) *>
logState.as(savedFileName) // filterState *>
} // logState.as(savedFileName)
).onError(error => log.info(s"errr... $error")) // }
// ).onError(error => log.info(s"errr... $error"))
} }
def readFile(fileName: String): IO[List[String]] = fileService.readFile(fileName) def readFile(fileName: String): IO[List[String]] = fileService.readFile(fileName)
@@ -83,7 +86,7 @@ class DataService private(
def getDateFileNames(date: LocalDate): IO[List[String]] = fileService.getDateFileNames(date) def getDateFileNames(date: LocalDate): IO[List[String]] = fileService.getDateFileNames(date)
// TODO implement getting full data from state // TODO implement getting full data from state
def getLast24Hours: IO[List[String]] = { // def getLast24Hours: IO[List[String]] = {
state.get.map(_.keys.toList.sorted) // state.get.map(_.keys.toList.sorted)
} // }
} }
+3 -3
View File
@@ -106,9 +106,9 @@ class Server(dataService: DataService, fetch: FetchService, log: Logger[IO]) {
dataService.readFile(fileName).flatMap(content => Ok(content.asJson)) dataService.readFile(fileName).flatMap(content => Ok(content.asJson))
// http://0.0.0.0:8080/api/getLast24hours // http://0.0.0.0:8080/api/getLast24hours
case GET -> Root / "getLast24hours" => { // case GET -> Root / "getLast24hours" => {
dataService.getLast24Hours.flatMap(content => Ok(content.asJson.pretty)) // dataService.getLast24Hours.flatMap(content => Ok(content.asJson.pretty))
} // }
// http://0.0.0.0:8080/api/help // http://0.0.0.0:8080/api/help
case GET -> Root / "help" => { case GET -> Root / "help" => {