Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
sdbuehlmann committed Jan 18, 2024
1 parent 1ec413b commit 74a3083
Show file tree
Hide file tree
Showing 26 changed files with 472 additions and 349 deletions.
72 changes: 9 additions & 63 deletions src/main/java/ch/admin/bar/siardsuite/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import ch.admin.bar.siard2.api.Archive;
import ch.admin.bar.siardsuite.database.DatabaseConnectionFactory;
import ch.admin.bar.siardsuite.database.DatabaseInteractionService;
import ch.admin.bar.siardsuite.database.DatabaseLoadService;
import ch.admin.bar.siardsuite.database.DatabaseProperties;
import ch.admin.bar.siardsuite.database.DatabaseUploadService;
import ch.admin.bar.siardsuite.database.model.DbmsConnectionData;
import ch.admin.bar.siardsuite.database.model.LoadDatabaseInstruction;
import ch.admin.bar.siardsuite.database.model.UploadDatabaseInstruction;
import ch.admin.bar.siardsuite.model.Failure;
import ch.admin.bar.siardsuite.model.Model;
import ch.admin.bar.siardsuite.model.View;
Expand All @@ -15,11 +17,6 @@
import ch.admin.bar.siardsuite.view.RootStage;
import ch.admin.bar.siardsuite.visitor.ArchiveVisitor;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.collections.ObservableList;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.EventHandler;
import javafx.util.Pair;
import lombok.Getter;
import lombok.Setter;
import lombok.val;
Expand All @@ -28,7 +25,6 @@
import java.io.IOException;
import java.net.URI;
import java.nio.file.Paths;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand All @@ -42,43 +38,23 @@ public class Controller {
private Workflow workflow;
public String recentDatabaseConnection;

private final DatabaseInteractionService databaseInteractionService;

@Setter
@Getter
private Optional<DbmsConnectionData> tempConnectionData = Optional.empty();

public Optional<DbmsConnectionData> popTempConnectionData() {
val tempReturnValue = tempConnectionData;
tempConnectionData = Optional.empty();
return tempReturnValue;
}

public Controller(Model model) {
this.model = model;
this.databaseInteractionService = new DatabaseInteractionService(new DatabaseConnectionFactory(), model);
}

public void loadDatabase(final LoadDatabaseInstruction instruction) throws SQLException {
tmpArchive = model.initArchive();

val connection = instruction.getConnectionData().createConnection();

val dbLoadService = new DatabaseLoadService(
connection,
model,
tmpArchive,
instruction.isLoadOnlyMetadata(),
instruction.isViewsAsTables());

dbLoadService.setOnSucceeded(instruction.getOnSuccess());
dbLoadService.setOnFailed(instruction.getOnFailure());

dbLoadService.start();

dbLoadService.valueProperty().addListener(instruction.getOnSingleValueCompleted());
dbLoadService.progressProperty().addListener(instruction.getOnProgress());
public void loadDatabase(final LoadDatabaseInstruction instruction) {
databaseInteractionService.execute(instruction);
}

public void closeDbConnection() {
DatabaseConnectionFactory.disconnect();
public void uploadDatabase(final UploadDatabaseInstruction instruction) {
databaseInteractionService.execute(instruction);
}

public void updateConnectionData(String connectionUrl, String username, String databaseName, String password) {
Expand All @@ -92,35 +68,10 @@ public void updateSchemaMap(Map schemaMap) {
this.model.setSchemaMap(schemaMap);
}

public void onDatabaseUploadSuccess(EventHandler<WorkerStateEvent> workerStateEventEventHandler) {
this.databaseUploadService.setOnSucceeded(workerStateEventEventHandler);
}

public void onDatabaseUploadFailed(EventHandler<WorkerStateEvent> workerStateEventEventHandler) {
this.databaseUploadService.setOnFailed(workerStateEventEventHandler);
}

public void addDatabaseUploadingValuePropertyListener(ChangeListener<String> listener) {
this.databaseUploadService.valueProperty().addListener(listener);
}

public void addDatabaseUploadingProgressPropertyListener(ChangeListener<Number> listener) {
this.databaseUploadService.progressProperty().addListener(listener);
}

public Workflow getWorkflow() {
return workflow;
}


public void uploadArchive(EventHandler<WorkerStateEvent> onSuccess,
EventHandler<WorkerStateEvent> onFailure) throws SQLException {
this.databaseUploadService = DatabaseConnectionFactory.getInstance(model).createDatabaseUploader();
this.onDatabaseUploadSuccess(onSuccess);
this.onDatabaseUploadFailed(onFailure);
this.databaseUploadService.start();
}

public void cancelDownload() {
if (databaseLoadService != null && databaseLoadService.isRunning()) {
this.databaseLoadService.cancel();
Expand All @@ -136,7 +87,6 @@ public void cancelUpload() {
}

public void releaseResources() {
closeDbConnection();
removeTmpArchive();
}

Expand Down Expand Up @@ -231,10 +181,6 @@ public DatabaseProperties getDatabaseProps() {
return this.model.getDatabaseProps();
}

public StringProperty getDatabaseProduct() {
return this.model.getDatabaseProduct();
}

public List<String> getDatabaseTypes() {
return this.model.getDatabaseTypes();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,75 +1,50 @@
package ch.admin.bar.siardsuite.database;

import ch.admin.bar.siard2.api.Archive;
import ch.admin.bar.siardsuite.model.Model;
import ch.admin.bar.siardsuite.util.UserPreferences;
import ch.admin.bar.siardsuite.database.model.DbmsConnectionData;
import ch.admin.bar.siardsuite.util.preferences.UserPreferences;
import lombok.extern.slf4j.Slf4j;
import lombok.val;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.LOGIN_TIMEOUT;
import static ch.admin.bar.siardsuite.util.UserPreferences.NodePath.OPTIONS;

@Slf4j
public class DatabaseConnectionFactory {
private static DatabaseConnectionFactory instance;
private static Connection connection;
private static Model model;

private DatabaseConnectionFactory(Model model) throws SQLException {
DatabaseConnectionFactory.model = model;
loadDriver(DatabaseConnectionFactory.model.getDatabaseProps().product());
DriverManager.setLoginTimeout(Integer.parseInt(UserPreferences.node(OPTIONS).get(LOGIN_TIMEOUT.name(), "0")));
connection = DriverManager.getConnection(model.getConnectionUrl().get(),
model.getDatabaseUsername().get(), model.getDatabasePassword());
}

public static DatabaseConnectionFactory getInstance(Model model) throws SQLException {
if (instance == null || connection.isClosed()) {
instance = new DatabaseConnectionFactory(model);
}
return instance;
}

public DatabaseLoadService createDatabaseLoader(final Archive archive, boolean onlyMetaData, boolean viewsAsTables) {
return new DatabaseLoadService(connection, model, archive, onlyMetaData, viewsAsTables);
}

public DatabaseUploadService createDatabaseUploader() {
return new DatabaseUploadService(connection, model);
}

public static void disconnect() {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
public Connection createConnection(final DbmsConnectionData dbmsConnectionData) {
val options = UserPreferences.getStoredOptions();

loadDriverByClassName(dbmsConnectionData.getDbms().getDriverClassName());
DriverManager.setLoginTimeout(options.getLoginTimeout());

try {
return DriverManager.getConnection(
dbmsConnectionData.getJdbcConnectionString(),
dbmsConnectionData.getUser(),
dbmsConnectionData.getPassword());
} catch (SQLException e) {
throw new DatabaseConnectionException(
String.format("Failed to create connection '%s'", dbmsConnectionData),
e);
}
}
}

private void loadDriver(String product) {
Properties properties = new Properties();
try (InputStream is = getClass().getResourceAsStream("driver.properties")) {
properties.load(is);
} catch (IOException e) {
throw new RuntimeException(e);
}
String jdbcDriverClass = properties.getProperty(product);
if (jdbcDriverClass != null) {
try {
Class.forName(jdbcDriverClass);
} catch (ClassNotFoundException var7) {
throw new RuntimeException("Driver " + jdbcDriverClass + " could not be loaded!");
}
} else {
throw new RuntimeException("No driver found for sub scheme \"" + product + "\"!");
private static void loadDriverByClassName(String jdbcDriverClass) {
try {
Class.forName(jdbcDriverClass);
} catch (ClassNotFoundException var7) {
throw new DatabaseConnectionException("Driver " + jdbcDriverClass + " could not be loaded!");
}
}

}
private static class DatabaseConnectionException extends RuntimeException {
public DatabaseConnectionException(String message) {
super(message);
}

public DatabaseConnectionException(String message, Throwable cause) {
super(message, cause);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package ch.admin.bar.siardsuite.database;

import ch.admin.bar.siardsuite.database.model.LoadDatabaseInstruction;
import ch.admin.bar.siardsuite.database.model.UploadDatabaseInstruction;
import ch.admin.bar.siardsuite.model.Model;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.val;

import java.sql.Connection;
import java.sql.SQLException;

@Slf4j
@RequiredArgsConstructor
public class DatabaseInteractionService {

private final DatabaseConnectionFactory connectionFactory;

@Deprecated // TODO remove model
private final Model model;

public InstructionExecutionHandle execute(final LoadDatabaseInstruction instruction) {
val tempArchive = model.initArchive();
val connection = connectionFactory.createConnection(instruction.getConnectionData());

val dbLoadService = new DatabaseLoadService(
connection,
model,
tempArchive,
instruction.isLoadOnlyMetadata(),
instruction.isViewsAsTables());

dbLoadService.setOnSucceeded(event -> {
instruction.getOnSuccess().handle(event);
close(connection);
});
dbLoadService.setOnFailed(event -> {
instruction.getOnFailure().handle(event);
close(connection);
});

dbLoadService.start();

dbLoadService.valueProperty().addListener((observable, oldValue, newValue) -> {
instruction.getOnStepCompleted().changed(observable, oldValue, newValue);
});

dbLoadService.progressProperty().addListener((observable, oldValue, newValue) -> {
instruction.getOnProgress().changed(observable, oldValue, newValue);
});

return () -> {
dbLoadService.cancel();
close(connection);
};
}

public InstructionExecutionHandle execute(final UploadDatabaseInstruction instruction) {
val connection = connectionFactory.createConnection(instruction.getConnectionData());

val dbUploadService = new DatabaseUploadService(
connection,
model);

dbUploadService.setOnSucceeded(event -> {
instruction.getOnSuccess().handle(event);
close(connection);
});
dbUploadService.setOnFailed(event -> {
instruction.getOnFailure().handle(event);
close(connection);
});

dbUploadService.start();

dbUploadService.valueProperty().addListener(instruction.getOnStepCompleted());
dbUploadService.progressProperty().addListener(instruction.getOnProgress());

return () -> {
dbUploadService.cancel();
close(connection);
};
}

public interface InstructionExecutionHandle {
void cancel();
}

private static void close(final Connection connection) {
try {
connection.close();
} catch (SQLException e) {
log.error("Failed to close connection {} because: {}", connection, e);
}
}
}
Loading

0 comments on commit 74a3083

Please sign in to comment.