DataService to save last 24h of data
This commit is contained in:
@@ -18,17 +18,11 @@ object DBService {
|
||||
}
|
||||
}
|
||||
|
||||
class DBService(log: Logger[IO]) {
|
||||
class DBService(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
|
||||
|
||||
def readFile(fileName: String): IO[List[String]] = {
|
||||
val file = new File(dataPath, fileName)
|
||||
val sourceResource = Resource.fromAutoCloseable(IO(Source.fromFile(file)))
|
||||
sourceResource.use(source => IO(source.getLines().take(nonDuplicatedLines).toList)).handleError(_ => List.empty)
|
||||
}
|
||||
|
||||
private def readFileNames(path: String): IO[List[String]] =
|
||||
IO(new File(path).listFiles.toList.map(_.getName))
|
||||
.handleError(_ => List.empty)
|
||||
@@ -46,14 +40,6 @@ class DBService(log: Logger[IO]) {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
def save(fileName: String, content: String): IO[Either[Throwable, String]] = {
|
||||
val path = Paths.get(s"$dataPath/$fileName")
|
||||
IO(Files.writeString(path, content))
|
||||
@@ -64,8 +50,22 @@ class DBService(log: Logger[IO]) {
|
||||
)
|
||||
}
|
||||
|
||||
def readFile(fileName: String): IO[List[String]] = {
|
||||
val file = new File(dataPath, fileName)
|
||||
val sourceResource = Resource.fromAutoCloseable(IO(Source.fromFile(file)))
|
||||
sourceResource.use(source => IO(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]] = {
|
||||
def getDates: IO[List[LocalDate]] = {
|
||||
val formatter = DateTimeFormatter.ofPattern("yyyyMMdd")
|
||||
for {
|
||||
fileNames <- readFileNames(dataPath)
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package db
|
||||
|
||||
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 java.time.{Instant, LocalDate, LocalDateTime, ZoneId}
|
||||
|
||||
trait DataServiceTrait {
|
||||
def save(fileName: String, content: String): IO[Either[Throwable, 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]]
|
||||
}
|
||||
|
||||
object DataService {
|
||||
def of(dbService: DBService): IO[DataService] = {
|
||||
for {
|
||||
log <- Slf4jLogger.create[IO]
|
||||
fileNameService = new FileNameService()
|
||||
fileNames <- fileNameService.generateLast24Hours
|
||||
contents <- fileNames.traverse(fileName => dbService.readFile(fileName)
|
||||
.map(content => (fileName, content)))
|
||||
state = contents.toMap
|
||||
stateRef <- Ref.of[IO, Map[String, List[String]]](state)
|
||||
} yield new DataService(dbService, new FileNameService(), log, stateRef)
|
||||
}
|
||||
}
|
||||
class DataService private(
|
||||
dbService: DBService,
|
||||
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[Either[Throwable, String]] = {
|
||||
dbService.save(fileName, content).flatMap {
|
||||
case Right(savedFileName) =>
|
||||
state.update(st => st.updated(savedFileName, content.split("\n").toList)) *>
|
||||
filterState *>
|
||||
logState.as(Right(savedFileName))
|
||||
case e@Left(_) => IO.pure(e)
|
||||
}
|
||||
}
|
||||
|
||||
def readFile(fileName: String): IO[List[String]] = dbService.readFile(fileName)
|
||||
|
||||
def getInRange(from: LocalDateTime, to: LocalDateTime): IO[List[String]] = dbService.getInRange(from, to)
|
||||
|
||||
def getDates: IO[List[LocalDate]] = dbService.getDates
|
||||
|
||||
def getDateFileNames(date: LocalDate): IO[List[String]] = dbService.getDateFileNames(date)
|
||||
|
||||
// TODO implement getting full data from state
|
||||
def getLast24Hours: IO[List[String]] = {
|
||||
state.get.map(_.keys.toList.sorted)
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ object Main {
|
||||
for {
|
||||
log <- Slf4jLogger.create[IO]
|
||||
dbService <- DBService.of
|
||||
dates <- dbService.getDates()
|
||||
dates <- dbService.getDates
|
||||
_ <- log.info(s"$dates")
|
||||
} yield ()
|
||||
}
|
||||
@@ -41,9 +41,17 @@ object Main {
|
||||
} yield ()
|
||||
}
|
||||
|
||||
private def testDataService: IO[Unit] = {
|
||||
for {
|
||||
dbService <- DBService.of
|
||||
dataService <- DataService.of(dbService)
|
||||
} yield ()
|
||||
}
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
// testGetInRange.unsafeRunSync()
|
||||
// testGetDates.unsafeRunSync()
|
||||
testGetDate.unsafeRunSync()
|
||||
// testGetDate.unsafeRunSync()
|
||||
testDataService.unsafeRunSync()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user