/* * Copyright (C) 2021 Anton Romanov - All Rights Reserved * You may use, distribute and modify this code, please write to: romanov73@gmail.com. * */ package ru.ulstu.db; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import ru.ulstu.datamodel.ts.TimeSeries; import ru.ulstu.db.model.TimeSeriesMeta; import ru.ulstu.db.model.TimeSeriesSet; import ru.ulstu.service.UtilService; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @Service public class DbFileService implements DbService { @Value("${time-series.db-path}") private String timeSeriesDbPath; @Override public List getSets() { return Arrays.stream(Objects.requireNonNull(new File(timeSeriesDbPath).listFiles(File::isDirectory))) .map(TimeSeriesSet::new) .collect(Collectors.toList()); } @Override public List getTimeSeriesMeta(TimeSeriesSet timeSeriesSet) throws IOException { validateTimeSeriesSet(timeSeriesSet); List list = new ArrayList<>(); for (File file : getTimeSeriesMetaFiles(timeSeriesSet)) { list.add(new ObjectMapper().readValue(Paths.get(timeSeriesDbPath, file.getName()).toFile(), TimeSeriesMeta.class)); } return list; } @Override public TimeSeries getTimeSeries(TimeSeriesSet timeSeriesSet, String timeSeriesKey) throws IOException { validateTimeSeriesSet(timeSeriesSet); validateTimeSeries(timeSeriesSet, timeSeriesKey); File timeSeriesFile = getTimeSeriesFile(timeSeriesSet, timeSeriesKey); BufferedReader csvReader = new BufferedReader(new FileReader(timeSeriesFile)); String row; TimeSeries result = new TimeSeries(timeSeriesKey); while ((row = csvReader.readLine()) != null) { TimeSeries partOfTimeSeries = new UtilService().getTimeSeriesFromDateValueString(row); if (partOfTimeSeries.getLength() > 0) { result.getValues().addAll(partOfTimeSeries.getValues()); } } csvReader.close(); return result; } @Override public boolean addNewSet(String key) { TimeSeriesSet timeSeriesSet = new TimeSeriesSet(key); if (isTimeSeriesSetExists(timeSeriesSet)) { throw new RuntimeException(String.format("Time series set %s already exists", timeSeriesSet.getKey())); } else { return Paths.get(timeSeriesDbPath, timeSeriesSet.getKey()).toFile().mkdirs(); } } @Override public boolean addTimeSeries(TimeSeriesSet timeSeriesSet, TimeSeries timeSeries) throws IOException { validateTimeSeriesSet(timeSeriesSet); BufferedWriter writer = new BufferedWriter(new FileWriter(Paths.get(timeSeriesDbPath, timeSeriesSet.getKey()).toFile())); writer.write(new UtilService().getTimeSeriesToDateValueString(timeSeries)); writer.close(); return true; } private void validateTimeSeriesSet(TimeSeriesSet timeSeriesSet) { if (!isTimeSeriesSetExists(timeSeriesSet)) { throw new RuntimeException(String.format("Time series set %s not exists", timeSeriesSet.getKey())); } } private void validateTimeSeries(TimeSeriesSet timeSeriesSet, String timeSeriesKey) { if (Arrays.stream(Objects.requireNonNull(Paths.get(timeSeriesDbPath, timeSeriesSet.getKey()).toFile().listFiles(f -> f.getName().equals(timeSeriesKey)))).findAny().isEmpty()) { throw new RuntimeException(String.format("Time series %s not exists", timeSeriesKey)); } } private boolean isTimeSeriesSetExists(TimeSeriesSet timeSeriesSet) { return Arrays.stream(Objects.requireNonNull(new File(timeSeriesDbPath).listFiles(File::isDirectory))) .anyMatch(d -> d.getName().equals(timeSeriesSet.getKey())); } private List getTimeSeriesMetaFiles(TimeSeriesSet timeSeriesSet) { return Arrays.asList(Objects.requireNonNull(Paths.get(timeSeriesDbPath, timeSeriesSet.getKey()).toFile().listFiles(f -> f.getName().endsWith(".meta")))); } private File getTimeSeriesFile(TimeSeriesSet timeSeriesSet, String timeSeriesKey) { return Arrays.stream(Objects.requireNonNull(Paths.get(timeSeriesDbPath, timeSeriesSet.getKey()).toFile().listFiles(f -> f.getName().equals(timeSeriesKey)))) .findAny() .orElse(null); } }