Fix parsing db url, remove 24h state, add db saving
This commit is contained in:
@@ -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
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
@@ -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" => {
|
||||||
|
|||||||
Reference in New Issue
Block a user