Skip to content

Commit

Permalink
Restructuring SQL sources and introducing TimeSeriesTypeSource (#546)
Browse files Browse the repository at this point in the history
* Restructuring SQL sources and introducing TimeSeriesTypeSource

* Fixing/creating missing tests, introducing TimeSeriesUtils.isSchemeAccepted

* Fixing code smells

* More fixing of code smells

* Adapting changelog

* Fixing codacy issues

* Improving TypeEntry#equals

* Improving test a tiny bit

* Explicitly creating timeseries-id/time index

* Addressing reviewer's comments

Co-authored-by: t-ober <63147366+t-ober@users.noreply.github.com>
  • Loading branch information
sebastian-peter and t-ober committed Mar 16, 2022
1 parent 1935566 commit a10a543
Show file tree
Hide file tree
Showing 35 changed files with 708 additions and 363 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added
- SQL time series sources (`SqlTimeSeriesSource` and `SqlTimeSeriesMappingSource`) [#467](https://github.com/ie3-institute/PowerSystemDataModel/issues/467)
- SQL time series have a different structure than CSV counterparts [#545](https://github.com/ie3-institute/PowerSystemDataModel/issues/545)
- Graph with impedance weighted edges including facilities to create it [#440](https://github.com/ie3-institute/PowerSystemDataModel/issues/440)
- Introducing `SqlIndividualTimeSeriesMetaInformation` which provides sql table names [#513](https://github.com/ie3-institute/PowerSystemDataModel/issues/513)
- `TimeSeriesTypeSource` providing a source for the mapping of time series uuids to column schemes (previously provided by `TimeSeriesMappingSource`) [#515](https://github.com/ie3-institute/PowerSystemDataModel/issues/515)

### Fixed
- Reduced code smells [#492](https://github.com/ie3-institute/PowerSystemDataModel/issues/492)
Expand Down
21 changes: 11 additions & 10 deletions src/main/java/edu/ie3/datamodel/io/connectors/CsvFileConnector.java
Original file line number Diff line number Diff line change
Expand Up @@ -221,30 +221,32 @@ public BufferedReader initReader(String filePath) throws FileNotFoundException {
*
* @param timeSeriesUuid The time series in question
* @return An option on the queried information
* @deprecated since 3.0. Use {@link #individualTimeSeriesMetaInformation(UUID)} instead
* @deprecated since 3.0. Use {@link #getIndividualTimeSeriesMetaInformation()} instead
*/
@Deprecated(since = "3.0", forRemoval = true)
public Optional<edu.ie3.datamodel.io.csv.timeseries.IndividualTimeSeriesMetaInformation>
getIndividualTimeSeriesMetaInformation(UUID timeSeriesUuid) {
return individualTimeSeriesMetaInformation(timeSeriesUuid)
if (Objects.isNull(individualTimeSeriesMetaInformation))
individualTimeSeriesMetaInformation = buildIndividualTimeSeriesMetaInformation();

return Optional.ofNullable(individualTimeSeriesMetaInformation.get(timeSeriesUuid))
.map(edu.ie3.datamodel.io.csv.timeseries.IndividualTimeSeriesMetaInformation::new);
}

/**
* Get time series meta information for a given uuid.
* Get time series meta information
*
* <p>This method lazily evaluates the mapping from <i>all</i> time series files to their meta
* information.
*
* @param timeSeriesUuid The time series in question
* @return An option on the queried information
* @return All time series meta information
*/
public Optional<IndividualTimeSeriesMetaInformation> individualTimeSeriesMetaInformation(
UUID timeSeriesUuid) {
public Map<UUID, edu.ie3.datamodel.io.csv.CsvIndividualTimeSeriesMetaInformation>
getIndividualTimeSeriesMetaInformation() {
if (Objects.isNull(individualTimeSeriesMetaInformation))
individualTimeSeriesMetaInformation = buildIndividualTimeSeriesMetaInformation();

return Optional.ofNullable(individualTimeSeriesMetaInformation.get(timeSeriesUuid));
return individualTimeSeriesMetaInformation;
}

/**
Expand Down Expand Up @@ -485,9 +487,8 @@ public String getFullFilePath() {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof CsvIndividualTimeSeriesMetaInformation)) return false;
if (!(o instanceof CsvIndividualTimeSeriesMetaInformation that)) return false;
if (!super.equals(o)) return false;
CsvIndividualTimeSeriesMetaInformation that = (CsvIndividualTimeSeriesMetaInformation) o;
return fullFilePath.equals(that.fullFilePath);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,7 @@ public Writer append(char c) {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof BufferedCsvWriter)) return false;
BufferedCsvWriter that = (BufferedCsvWriter) o;
if (!(o instanceof BufferedCsvWriter that)) return false;
return Arrays.equals(headLineElements, that.headLineElements) && csvSep.equals(that.csvSep);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* © 2021. TU Dortmund University,
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
* Research group Distribution grid planning and operation
*/
package edu.ie3.datamodel.io.factory.timeseries;

import edu.ie3.datamodel.io.factory.EntityFactory;
import edu.ie3.datamodel.io.factory.SimpleEntityData;
import edu.ie3.datamodel.io.naming.timeseries.ColumnScheme;
import edu.ie3.datamodel.io.source.TimeSeriesTypeSource;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* Factory that creates {@link TimeSeriesTypeSource.TypeEntry} entities from source field mappings
*/
public class TimeSeriesTypeFactory
extends EntityFactory<TimeSeriesTypeSource.TypeEntry, SimpleEntityData> {
private static final String TIME_SERIES = "timeSeries";
private static final String COLUMN_SCHEME = "columnScheme";

public TimeSeriesTypeFactory() {
super(TimeSeriesTypeSource.TypeEntry.class);
}

@Override
protected List<Set<String>> getFields(SimpleEntityData data) {
return Collections.singletonList(
Stream.of(TIME_SERIES, COLUMN_SCHEME).collect(Collectors.toSet()));
}

@Override
protected TimeSeriesTypeSource.TypeEntry buildModel(SimpleEntityData data) {
UUID timeSeries = data.getUUID(TIME_SERIES);
ColumnScheme columnScheme = ColumnScheme.parse(data.getField(COLUMN_SCHEME)).orElseThrow();
return new TimeSeriesTypeSource.TypeEntry(timeSeries, columnScheme);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* © 2022. TU Dortmund University,
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
* Research group Distribution grid planning and operation
*/
package edu.ie3.datamodel.io.naming;

import edu.ie3.datamodel.io.naming.timeseries.ColumnScheme;

/** A naming strategy for database entities */
public class DatabaseNamingStrategy {

private static final String TIME_SERIES_PREFIX = "time_series_";

/**
* Provides the String that all time series tables are prefixed with
*
* @return the time series prefix
*/
public String getTimeSeriesPrefix() {
return TIME_SERIES_PREFIX;
}

/**
* Provides the name of a time series table given a column scheme
*
* @param columnScheme the column scheme of the source data
* @return the table name
*/
public String getTimeSeriesEntityName(ColumnScheme columnScheme) {
return TIME_SERIES_PREFIX + columnScheme.getScheme();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/
package edu.ie3.datamodel.io.source;

import edu.ie3.datamodel.io.naming.timeseries.IndividualTimeSeriesMetaInformation;
import edu.ie3.datamodel.models.input.InputEntity;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -39,20 +38,12 @@ default Optional<UUID> getTimeSeriesUuid(UUID modelIdentifier) {
*
* @param timeSeriesUuid Unique identifier of the time series in question
* @return An Option onto the meta information
* @deprecated since 3.0. Use {@link #timeSeriesMetaInformation(java.util.UUID)} instead
* @deprecated since 3.0. Use {@link TimeSeriesTypeSource#getTimeSeriesMetaInformation()} instead
*/
@Deprecated(since = "3.0", forRemoval = true)
Optional<edu.ie3.datamodel.io.csv.timeseries.IndividualTimeSeriesMetaInformation>
getTimeSeriesMetaInformation(UUID timeSeriesUuid);

/**
* Get an option on the given time series meta information
*
* @param timeSeriesUuid Unique identifier of the time series in question
* @return An Option onto the meta information
*/
Optional<IndividualTimeSeriesMetaInformation> timeSeriesMetaInformation(UUID timeSeriesUuid);

/** Class to represent one entry within the participant to time series mapping */
class MappingEntry extends InputEntity {
private final UUID participant;
Expand All @@ -75,9 +66,8 @@ public UUID getTimeSeries() {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof MappingEntry)) return false;
if (!(o instanceof MappingEntry that)) return false;
if (!super.equals(o)) return false;
MappingEntry that = (MappingEntry) o;
return participant.equals(that.participant) && timeSeries.equals(that.timeSeries);
}

Expand Down
23 changes: 2 additions & 21 deletions src/main/java/edu/ie3/datamodel/io/source/TimeSeriesSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
*/
package edu.ie3.datamodel.io.source;

import static edu.ie3.datamodel.io.naming.timeseries.ColumnScheme.*;

import edu.ie3.datamodel.io.naming.timeseries.ColumnScheme;
import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries;
import edu.ie3.datamodel.models.value.Value;
import edu.ie3.util.interval.ClosedInterval;
Expand All @@ -27,7 +24,8 @@ public interface TimeSeriesSource<V extends Value> extends DataSource {
* @param scheme the column scheme to check
* @return whether the scheme is accepted or not
* @deprecated since 3.0. Use {@link
* #isSchemeAccepted(edu.ie3.datamodel.io.naming.timeseries.ColumnScheme)} instead.
* TimeSeriesUtils#isSchemeAccepted(edu.ie3.datamodel.io.naming.timeseries.ColumnScheme)}
* instead.
*/
@Deprecated(since = "3.0", forRemoval = true)
static boolean isSchemeAccepted(edu.ie3.datamodel.io.csv.timeseries.ColumnScheme scheme) {
Expand All @@ -41,23 +39,6 @@ static boolean isSchemeAccepted(edu.ie3.datamodel.io.csv.timeseries.ColumnScheme
.contains(scheme);
}

/**
* Checks whether the given column scheme can be used with time series.
*
* @param scheme the column scheme to check
* @return whether the scheme is accepted or not
*/
static boolean isSchemeAccepted(ColumnScheme scheme) {
return EnumSet.of(
ACTIVE_POWER,
APPARENT_POWER,
ENERGY_PRICE,
APPARENT_POWER_AND_HEAT_DEMAND,
ACTIVE_POWER_AND_HEAT_DEMAND,
HEAT_DEMAND)
.contains(scheme);
}

/**
* Obtain the full time series
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* © 2022. TU Dortmund University,
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
* Research group Distribution grid planning and operation
*/
package edu.ie3.datamodel.io.source;

import edu.ie3.datamodel.io.naming.timeseries.ColumnScheme;
import edu.ie3.datamodel.io.naming.timeseries.IndividualTimeSeriesMetaInformation;
import edu.ie3.datamodel.models.input.InputEntity;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;

/** Source for all available time series with their {@link UUID} and {@link ColumnScheme} */
public interface TimeSeriesTypeSource extends DataSource {

/**
* Get a mapping from time series {@link UUID} to its meta information {@link
* IndividualTimeSeriesMetaInformation}
*
* @return that mapping
*/
Map<UUID, ? extends IndividualTimeSeriesMetaInformation> getTimeSeriesMetaInformation();

/** Class to represent one entry within the participant to time series mapping */
class TypeEntry extends InputEntity {
private final ColumnScheme columnScheme;

public TypeEntry(UUID timeSeries, ColumnScheme columnScheme) {
super(timeSeries);
this.columnScheme = columnScheme;
}

public UUID getTimeSeries() {
return getUuid();
}

public ColumnScheme getColumnScheme() {
return columnScheme;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof TypeEntry that)) return false;
if (!super.equals(o)) return false;
return columnScheme == that.columnScheme;
}

@Override
public int hashCode() {
return Objects.hash(super.hashCode(), columnScheme);
}

@Override
public String toString() {
return "TypeEntry{" + "uuid=" + getUuid() + ", columnScheme=" + columnScheme + '}';
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import edu.ie3.datamodel.io.factory.SimpleEntityData;
import edu.ie3.datamodel.io.factory.timeseries.TimeSeriesMappingFactory;
import edu.ie3.datamodel.io.naming.FileNamingStrategy;
import edu.ie3.datamodel.io.naming.timeseries.IndividualTimeSeriesMetaInformation;
import edu.ie3.datamodel.io.source.TimeSeriesMappingSource;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -43,17 +42,14 @@ public Map<UUID, UUID> getMapping() {
return mapping;
}

/** @deprecated since 3.0. Use {@link #timeSeriesMetaInformation(java.util.UUID)} instead */
/**
* @deprecated since 3.0. Use {@link CsvTimeSeriesTypeSource#getTimeSeriesMetaInformation()}
* instead
*/
@Override
@Deprecated(since = "3.0", forRemoval = true)
public Optional<edu.ie3.datamodel.io.csv.timeseries.IndividualTimeSeriesMetaInformation>
getTimeSeriesMetaInformation(UUID timeSeriesUuid) {
return connector.getIndividualTimeSeriesMetaInformation(timeSeriesUuid);
}

@Override
public Optional<IndividualTimeSeriesMetaInformation> timeSeriesMetaInformation(
UUID timeSeriesUuid) {
return connector.individualTimeSeriesMetaInformation(timeSeriesUuid);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries;
import edu.ie3.datamodel.models.timeseries.individual.TimeBasedValue;
import edu.ie3.datamodel.models.value.*;
import edu.ie3.datamodel.utils.TimeSeriesUtil;
import edu.ie3.datamodel.utils.TimeSeriesUtils;
import edu.ie3.util.interval.ClosedInterval;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
Expand Down Expand Up @@ -94,7 +94,7 @@ public static CsvTimeSeriesSource<? extends Value> getSource(
FileNamingStrategy fileNamingStrategy,
CsvIndividualTimeSeriesMetaInformation metaInformation)
throws SourceException {
if (!TimeSeriesSource.isSchemeAccepted(metaInformation.getColumnScheme()))
if (!TimeSeriesUtils.isSchemeAccepted(metaInformation.getColumnScheme()))
throw new SourceException(
"Unsupported column scheme '" + metaInformation.getColumnScheme() + "'.");

Expand Down Expand Up @@ -164,7 +164,7 @@ public IndividualTimeSeries<V> getTimeSeries() {

@Override
public IndividualTimeSeries<V> getTimeSeries(ClosedInterval<ZonedDateTime> timeInterval) {
return TimeSeriesUtil.trimTimeSeriesToInterval(timeSeries, timeInterval);
return TimeSeriesUtils.trimTimeSeriesToInterval(timeSeries, timeInterval);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* © 2022. TU Dortmund University,
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
* Research group Distribution grid planning and operation
*/
package edu.ie3.datamodel.io.source.csv;

import edu.ie3.datamodel.io.naming.FileNamingStrategy;
import edu.ie3.datamodel.io.naming.timeseries.IndividualTimeSeriesMetaInformation;
import edu.ie3.datamodel.io.source.TimeSeriesTypeSource;
import edu.ie3.datamodel.utils.TimeSeriesUtils;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
* CSV implementation for retrieving {@link TimeSeriesTypeSource} from input directory structures
*/
public class CsvTimeSeriesTypeSource extends CsvDataSource implements TimeSeriesTypeSource {

/**
* Creates a time series type source
*
* @param csvSep the CSV separator
* @param folderPath path that time series reside in
* @param fileNamingStrategy the file naming strategy
*/
public CsvTimeSeriesTypeSource(
String csvSep, String folderPath, FileNamingStrategy fileNamingStrategy) {
super(csvSep, folderPath, fileNamingStrategy);
}

@Override
public Map<UUID, ? extends IndividualTimeSeriesMetaInformation> getTimeSeriesMetaInformation() {
return connector.getIndividualTimeSeriesMetaInformation().entrySet().stream()
.filter(entry -> TimeSeriesUtils.isSchemeAccepted(entry.getValue().getColumnScheme()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
}

0 comments on commit a10a543

Please sign in to comment.