-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generifying SQL sources and time series
- Loading branch information
1 parent
180855f
commit 04ca5d0
Showing
11 changed files
with
278 additions
and
237 deletions.
There are no files selected for viewing
26 changes: 26 additions & 0 deletions
26
src/main/java/edu/ie3/datamodel/exceptions/InvalidColumnNameException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* © 2021. TU Dortmund University, | ||
* Institute of Energy Systems, Energy Efficiency and Energy Economics, | ||
* Research group Distribution grid planning and operation | ||
*/ | ||
package edu.ie3.datamodel.exceptions; | ||
|
||
/** | ||
* Exception that is thrown whenever data columns are not as expected. | ||
* | ||
* @version 0.1 | ||
* @since 10.12.20 | ||
*/ | ||
public class InvalidColumnNameException extends RuntimeException { | ||
public InvalidColumnNameException(final String message, final Throwable cause) { | ||
super(message, cause); | ||
} | ||
|
||
public InvalidColumnNameException(final Throwable cause) { | ||
super(cause); | ||
} | ||
|
||
public InvalidColumnNameException(final String message) { | ||
super(message); | ||
} | ||
} |
26 changes: 0 additions & 26 deletions
26
src/main/java/edu/ie3/datamodel/exceptions/InvalidWeatherColumnNameException.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
115 changes: 115 additions & 0 deletions
115
src/main/java/edu/ie3/datamodel/io/source/sql/SqlDataSource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/* | ||
* © 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.source.sql; | ||
|
||
import edu.ie3.datamodel.exceptions.InvalidColumnNameException; | ||
import edu.ie3.datamodel.io.connectors.SqlConnector; | ||
import edu.ie3.datamodel.io.source.csv.CsvDataSource; | ||
import edu.ie3.util.StringUtils; | ||
import java.sql.PreparedStatement; | ||
import java.sql.ResultSet; | ||
import java.sql.SQLException; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public abstract class SqlDataSource<T> { | ||
|
||
protected static final Logger log = LoggerFactory.getLogger(CsvDataSource.class); | ||
|
||
private final SqlConnector connector; | ||
|
||
public SqlDataSource(SqlConnector connector) { | ||
this.connector = connector; | ||
} | ||
|
||
/** | ||
* Determine the corresponding database column name based on the provided factory field parameter | ||
* name. Needed to support camel as well as snake case database column names. | ||
* | ||
* @param factoryColumnName the name of the field parameter set in the entity factory | ||
* @param connector the sql connector of this source | ||
* @param tableName the table name where the data is stored | ||
* @return the column name that corresponds to the provided field parameter or an empty optional | ||
* if no matching column can be found | ||
*/ | ||
protected static String getDbColumnName( | ||
String factoryColumnName, SqlConnector connector, String tableName) { | ||
try { | ||
ResultSet rs = | ||
connector.getConnection().getMetaData().getColumns(null, null, tableName, null); | ||
|
||
while (rs.next()) { | ||
String databaseColumnName = rs.getString("COLUMN_NAME"); | ||
if (StringUtils.snakeCaseToCamelCase(databaseColumnName) | ||
.equalsIgnoreCase(factoryColumnName)) { | ||
return databaseColumnName; | ||
} | ||
} | ||
} catch (SQLException ex) { | ||
log.error( | ||
"Cannot connect to database to retrieve db column name for factory column name '{}' in table '{}'", | ||
factoryColumnName, | ||
tableName, | ||
ex); | ||
} | ||
throw new InvalidColumnNameException( | ||
"Cannot find column for '" | ||
+ factoryColumnName | ||
+ "' in provided times series data configuration." | ||
+ "Please ensure that the database connection is working and the column names are correct!"); | ||
} | ||
|
||
interface AddParams { | ||
/** | ||
* Enhance a PreparedStatement by inserting parameters for wildcards | ||
* | ||
* @param ps the PreparedStatement to enhance | ||
* @throws SQLException if anything goes wrong during preparation of the query | ||
*/ | ||
void addParams(PreparedStatement ps) throws SQLException; | ||
} | ||
|
||
/** | ||
* Executes the prepared statement after possibly adding parameters to the query using the given | ||
* function. Finally, processes the results and creates a list of time based values via field map | ||
* extraction. | ||
* | ||
* @param query the query to use | ||
* @param addParams function that possibly adds parameters to query | ||
* @return a list of resulting entities | ||
*/ | ||
protected List<T> executeQuery(String query, AddParams addParams) { | ||
try (PreparedStatement ps = connector.getConnection().prepareStatement(query)) { | ||
addParams.addParams(ps); | ||
|
||
ResultSet resultSet = ps.executeQuery(); | ||
List<Map<String, String>> fieldMaps = connector.extractFieldMaps(resultSet); | ||
|
||
return fieldMaps.stream() | ||
.map(this::createEntity) | ||
.flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty)) | ||
.collect(Collectors.toList()); | ||
} catch (SQLException e) { | ||
log.error("Error during execution of query " + query, e); | ||
} | ||
|
||
return Collections.emptyList(); | ||
} | ||
|
||
/** | ||
* Instantiates an entity produced by this source given the required field value map. | ||
* | ||
* @param fieldToValues map of fields to their respective values | ||
* @return the entity if instantiation succeeds | ||
*/ | ||
protected abstract Optional<T> createEntity(Map<String, String> fieldToValues); | ||
} |
Oops, something went wrong.