Cleanup fileservice and dataservice
This commit is contained in:
@@ -20,7 +20,6 @@ object DBConnection {
|
||||
val raw = URI.create(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)
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
package db
|
||||
|
||||
import cats.effect.unsafe.implicits.global
|
||||
import cats.effect.{Clock, IO, Ref}
|
||||
import cats.implicits.toTraverseOps
|
||||
import fetch.FileNameService
|
||||
import org.typelevel.log4cats.Logger
|
||||
import org.typelevel.log4cats.slf4j.Slf4jLogger
|
||||
import parse.Aggregate
|
||||
import parse.Aggregate.UserQuery
|
||||
|
||||
import java.time.{Instant, LocalDate, LocalDateTime, ZoneId}
|
||||
|
||||
trait DataServiceTrait {
|
||||
def save(fileName: String, content: String): IO[String]
|
||||
def readFile(fileName: String): IO[List[String]]
|
||||
def getInRange(from: LocalDateTime, to: LocalDateTime): IO[List[String]]
|
||||
def getDates: IO[List[LocalDate]]
|
||||
def getDateFileNames(date: LocalDate): IO[List[String]]
|
||||
|
||||
def getDatesByMonths(monthList: List[LocalDate]): IO[List[LocalDate]]
|
||||
}
|
||||
|
||||
object DataService {
|
||||
def of(
|
||||
fileService: FileService,
|
||||
postgresService: PostgresService
|
||||
): IO[DataService] = {
|
||||
for {
|
||||
log <- Slf4jLogger.create[IO]
|
||||
// fileNameService = new FileNameService()
|
||||
// fileNames <- fileNameService.generateLast24Hours
|
||||
// contents <- fileNames.traverse(fileName => fileService.readFile(fileName)
|
||||
// .map(content => (fileName, content)))
|
||||
// state = contents.toMap
|
||||
// stateRef <- Ref.of[IO, Map[String, List[String]]](state)
|
||||
} 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)
|
||||
}
|
||||
}
|
||||
class DataService private(
|
||||
fileService: FileService,
|
||||
postgresService: PostgresService,
|
||||
// fileNameService: FileNameService,
|
||||
log: Logger[IO],
|
||||
// private val state: Ref[IO, Map[String, List[String]]]
|
||||
) extends DataServiceTrait {
|
||||
|
||||
// private def logState: IO[Unit] = {
|
||||
// state.get.flatMap(currentState => log.info(s"State keys: ${currentState.keys.size}"))
|
||||
// }
|
||||
//
|
||||
// private def filterState: IO[Unit] = {
|
||||
// fileNameService.generateLast24Hours.flatMap { last24Hours =>
|
||||
// state.update(st => st.filterKeys(last24Hours.contains).toMap)
|
||||
// }
|
||||
// }
|
||||
|
||||
def save(fileName: String, content: String): IO[String] = {
|
||||
// TODO replace unsafeRunSync to redeemWith
|
||||
// postgresService.save(fileName, content).unsafeRunSync()
|
||||
// postgresService.save(fileName, content)
|
||||
|
||||
for {
|
||||
result <- fileService.save(fileName, content)
|
||||
_ <- postgresService.save(fileName, content)
|
||||
} yield result
|
||||
|
||||
// TODO delete this
|
||||
// fileService.save(fileName, content)
|
||||
|
||||
// fileService.save(fileName, content).redeemWith(
|
||||
// error => IO.raiseError(error),
|
||||
// savedFileName => {
|
||||
// state.update(st => st.updated(savedFileName, content.split("\n").toList)) *>
|
||||
// filterState *>
|
||||
// logState.as(savedFileName)
|
||||
// }
|
||||
// ).onError(error => log.info(s"errr... $error"))
|
||||
}
|
||||
|
||||
def readFile(fileName: String): IO[List[String]] = fileService.readFile(fileName)
|
||||
|
||||
def getDateTimeEntries(dateTime: LocalDateTime): IO[List[String]] = postgresService.getDateTimeEntries(dateTime)
|
||||
|
||||
def getInRange(from: LocalDateTime, to: LocalDateTime): IO[List[String]] = fileService.getInRange(from, to)
|
||||
|
||||
def query(userQuery: UserQuery): IO[Map[String, Option[Aggregate.AggregateValue]]] = postgresService.query(userQuery)
|
||||
|
||||
def getDates: IO[List[LocalDate]] = fileService.getDates
|
||||
|
||||
def getDatesByMonths(monthList: List[LocalDate]): IO[List[LocalDate]] = {
|
||||
// fileService.getDatesByMonths(monthList)
|
||||
postgresService.getDatesByMonths(monthList)
|
||||
}
|
||||
|
||||
def getDateFileNames(date: LocalDate): IO[List[String]] = {
|
||||
// fileService.getDateFileNames(date)
|
||||
postgresService.getDateFileNames(date)
|
||||
}
|
||||
|
||||
// TODO implement getting full data from state
|
||||
// def getLast24Hours: IO[List[String]] = {
|
||||
// state.get.map(_.keys.toList.sorted)
|
||||
// }
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
package db
|
||||
|
||||
import cats.effect.{IO, Resource}
|
||||
import cats.implicits.toTraverseOps
|
||||
import org.typelevel.log4cats.Logger
|
||||
import org.typelevel.log4cats.slf4j.Slf4jLogger
|
||||
|
||||
import java.io.File
|
||||
import java.nio.file.{Files, Paths}
|
||||
import java.time.{LocalDate, LocalDateTime}
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.concurrent.Executors
|
||||
import scala.concurrent.ExecutionContext
|
||||
import scala.io.Source
|
||||
import scala.util.Try
|
||||
|
||||
object FileService {
|
||||
def of: IO[FileService] = {
|
||||
Slf4jLogger.create[IO].map(logger => new FileService(logger))
|
||||
}
|
||||
}
|
||||
|
||||
class FileService(log: Logger[IO]) extends DataServiceTrait {
|
||||
private val dateFormatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmm")
|
||||
private val dataPath = "./data"
|
||||
private val nonDuplicatedLines = 34 // takes only first 34 lines of data as rest after 'Zosēni' is duplicated
|
||||
|
||||
private def readFileNames(path: String): IO[List[String]] =
|
||||
IO.blocking(new File(path).listFiles.toList.map(_.getName))
|
||||
.handleError(_ => List.empty)
|
||||
|
||||
private def inRange(fileName: String, from: LocalDateTime, to: LocalDateTime): Boolean = {
|
||||
def fileToDateTime(fileName: String): Option[LocalDateTime] = {
|
||||
val dateString = fileName.split("\\.").head
|
||||
Try(LocalDateTime.parse(dateString, dateFormatter)).toOption
|
||||
}
|
||||
|
||||
val fileDateTime = fileToDateTime(fileName.stripSuffix (".csv"))
|
||||
fileDateTime match {
|
||||
case Some (date) => date.plusSeconds (1).isAfter (from) && date.minusSeconds (1).isBefore (to)
|
||||
case None => false
|
||||
}
|
||||
}
|
||||
|
||||
def save(fileName: String, content: String): IO[String] = {
|
||||
val path = Paths.get(s"$dataPath/$fileName")
|
||||
IO(Files.writeString(path, content))
|
||||
.attempt
|
||||
.flatMap {
|
||||
case Left(error) => log.error(s"Write file '$fileName' failed with error: ${error.getMessage}") *> IO.raiseError(error)
|
||||
case Right(_) => log.info(s"write: $fileName").as(fileName)
|
||||
}
|
||||
}
|
||||
|
||||
def readFile(fileName: String): IO[List[String]] = {
|
||||
val file = new File(dataPath, fileName)
|
||||
val sourceResource = Resource.fromAutoCloseable(IO.blocking(Source.fromFile(file)))
|
||||
|
||||
sourceResource
|
||||
.use(source => IO.blocking(source.getLines().take(nonDuplicatedLines).toList))
|
||||
.handleError(_ => List.empty)
|
||||
}
|
||||
|
||||
def getInRange(from: LocalDateTime, to: LocalDateTime): IO[List[String]] = {
|
||||
for {
|
||||
fileNames <- readFileNames(dataPath)
|
||||
.map (_.filter (inRange (_, from, to)))
|
||||
fileLines <- fileNames.traverse(readFile)
|
||||
} yield fileLines.flatten
|
||||
}
|
||||
|
||||
// dates in which we have saved data
|
||||
def getDates: IO[List[LocalDate]] = {
|
||||
val formatter = DateTimeFormatter.ofPattern("yyyyMMdd")
|
||||
for {
|
||||
fileNames <- readFileNames(dataPath)
|
||||
datesStr <- IO(fileNames.map(_.take(8)).distinct) // take yyyyMMdd
|
||||
dates <- datesStr.traverse { str =>
|
||||
IO(LocalDate.parse(str, formatter)).option
|
||||
}.map(_.flatten)
|
||||
} yield dates.sorted
|
||||
}
|
||||
|
||||
def getDatesByMonths(monthList: List[LocalDate]): IO[List[LocalDate]] = {
|
||||
val dateFormatter = DateTimeFormatter.ofPattern("yyyyMMdd")
|
||||
val monthFormatter = DateTimeFormatter.ofPattern("yyyyMM")
|
||||
val monthStrList = monthList.map(_.format(monthFormatter))
|
||||
for {
|
||||
fileNames <- readFileNames(dataPath)
|
||||
datesStr <- IO(fileNames.map(_.take(8)).distinct) // take yyyyMMdd
|
||||
filteredDatesStr = datesStr.filter(date => monthStrList.contains(date.take(6)))
|
||||
dates <- filteredDatesStr.traverse { str =>
|
||||
IO(LocalDate.parse(str, dateFormatter)).option
|
||||
}.map(_.flatten)
|
||||
} yield dates.sorted
|
||||
}
|
||||
|
||||
def getDateFileNames(date: LocalDate): IO[List[String]] = {
|
||||
val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd")
|
||||
val dateStr: String = date.format(formatter)
|
||||
readFileNames(dataPath).map(_.filter(_.startsWith(dateStr)).sorted)
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ object PostgresService {
|
||||
}
|
||||
}
|
||||
|
||||
class PostgresService(transactor: Transactor[IO], log: Logger[IO]) extends DataServiceTrait {
|
||||
class PostgresService(transactor: Transactor[IO], log: Logger[IO]) {
|
||||
private val rigaZone = ZoneId.of("Europe/Riga")
|
||||
// in pgAdmin run: ```SET TIMEZONE = 'Europe/Riga';```
|
||||
|
||||
@@ -40,7 +40,6 @@ class PostgresService(transactor: Transactor[IO], log: Logger[IO]) extends DataS
|
||||
def query(userQuery: UserQuery): IO[Map[String, Option[AggregateValue]]] = {
|
||||
if (userQuery.field == "phenomena") { // this handles strings
|
||||
// TODO query list and distinct values from phenomena
|
||||
println("EMPTY RESULT!!!!!111")
|
||||
IO(Map()) // empty result
|
||||
} else if (List(
|
||||
AggregateKey.Max,
|
||||
@@ -145,7 +144,6 @@ class PostgresService(transactor: Transactor[IO], log: Logger[IO]) extends DataS
|
||||
}
|
||||
|
||||
} else {
|
||||
println("EMPTY RESULT!!!!!")
|
||||
IO(Map()) // empty result
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user