diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 210b5af..47cd00f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,32 +1,32 @@ -name: JavaFX Build (Gradle) - -on: - push: - pull_request: - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up JDK - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: 17 - cache: gradle - - - name: Make Gradle executable - run: chmod +x gradlew - - - name: Build using Gradle - run: ./gradlew clean build - - - name: Upload JAR artifact - uses: actions/upload-artifact@v4 - with: - name: satyam-consignment +name: JavaFX Build (Gradle) + +on: + push: + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + cache: gradle + + - name: Make Gradle executable + run: chmod +x gradlew + + - name: Build using Gradle + run: ./gradlew clean build + + - name: Upload JAR artifact + uses: actions/upload-artifact@v4 + with: + name: OpenConsignment path: build/libs/* \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 3e918a1..9d055b4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -32,6 +32,8 @@ dependencies { implementation(libs.javafx.graphics) implementation(libs.javafx.fxml) + implementation(libs.jgit) + compileOnly(libs.lombok) annotationProcessor(libs.lombok) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 92efa9f..77afec8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,65 +1,68 @@ -[versions] -javafx = "17.0.18" -controlsfx = "11.2.2" -jasperreports = "6.21.5" -sqlite = "3.34.0" -olap4j = "1.2.0" -#itext = "2.1.7" -lombok = "1.18.20" -dagger = "2.52" -testfx = "4.0.18" -testfxCore = "4.0.17" -monocle = "17.0.10" -hamcrest = "2.2" -#junit = "5.10.1" -junitbom = "5.10.2" +[versions] +javafx = "17.0.18" +controlsfx = "11.2.2" +jasperreports = "6.21.5" +sqlite = "3.34.0" +olap4j = "1.2.0" +#itext = "2.1.7" +lombok = "1.18.20" +dagger = "2.52" +testfx = "4.0.18" +testfxCore = "4.0.17" +monocle = "17.0.10" +hamcrest = "2.2" +#junit = "5.10.1" +junitbom = "5.10.2" mockito = "5.14.2" slf4j = "2.0.17" log4j = "2.24.3" snakeyaml = "2.3" - -spotless = "7.0.2" -shadow = "7.1.2" -javafxPlugin = "0.1.0" - -[libraries] -controlsfx = { module = "org.controlsfx:controlsfx", version.ref = "controlsfx" } -jasperreports = { module = "net.sf.jasperreports:jasperreports", version.ref = "jasperreports" } -sqlite = { module = "org.xerial:sqlite-jdbc", version.ref = "sqlite" } +jgit = "7.8.1.202611041320-r" + +spotless = "7.0.2" +shadow = "7.1.2" +javafxPlugin = "0.1.0" + +[libraries] +controlsfx = { module = "org.controlsfx:controlsfx", version.ref = "controlsfx" } +jasperreports = { module = "net.sf.jasperreports:jasperreports", version.ref = "jasperreports" } +sqlite = { module = "org.xerial:sqlite-jdbc", version.ref = "sqlite" } olap4j = { module = "org.olap4j:olap4j", version.ref = "olap4j" } slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" } snakeyaml = { module = "org.yaml:snakeyaml", version.ref = "snakeyaml" } log4j-slf4j2-impl = { module = "org.apache.logging.log4j:log4j-slf4j2-impl", version.ref = "log4j" } log4j-core = { module = "org.apache.logging.log4j:log4j-core", version.ref = "log4j" } -#itext = { module = "com.lowagie:itext", version.ref = "itext" } - -javafx-controls = { module = "org.openjfx:javafx-controls", version.ref = "javafx" } -javafx-base = { module = "org.openjfx:javafx-base", version.ref = "javafx" } -javafx-graphics = { module = "org.openjfx:javafx-graphics", version.ref = "javafx" } -javafx-fxml = { module = "org.openjfx:javafx-fxml", version.ref = "javafx" } - -lombok = { module = "org.projectlombok:lombok", version.ref = "lombok" } - -dagger = { module = "com.google.dagger:dagger", version.ref = "dagger" } -dagger-compiler = { module = "com.google.dagger:dagger-compiler", version.ref = "dagger" } - -testfx-junit5 = { module = "org.testfx:testfx-junit5", version.ref = "testfx" } -testfx-core = { module = "org.testfx:testfx-core", version.ref = "testfxCore" } -testfx-monocle = { module = "org.testfx:openjfx-monocle", version.ref = "monocle" } - -hamcrest = { module = "org.hamcrest:hamcrest", version.ref = "hamcrest" } - -#junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" } -#junit-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" } -junit-bom = { module = "org.junit:junit-bom", version.ref = "junitbom" } -junit-jupiter = { module = "org.junit.jupiter:junit-jupiter" } -junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher" } - -mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" } -mockito-junit-jupiter = { module = "org.mockito:mockito-junit-jupiter", version.ref = "mockito" } - -[plugins] -javafx = { id = "org.openjfx.javafxplugin", version.ref = "javafxPlugin" } -spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } -#shadow = { id = "com.gradleup.shadow", version.ref = "shadow" } +#itext = { module = "com.lowagie:itext", version.ref = "itext" } + +javafx-controls = { module = "org.openjfx:javafx-controls", version.ref = "javafx" } +javafx-base = { module = "org.openjfx:javafx-base", version.ref = "javafx" } +javafx-graphics = { module = "org.openjfx:javafx-graphics", version.ref = "javafx" } +javafx-fxml = { module = "org.openjfx:javafx-fxml", version.ref = "javafx" } + +jgit = { module = "org.eclipse.jgit:org.eclipse.jgit", version.ref = "jgit"} + +lombok = { module = "org.projectlombok:lombok", version.ref = "lombok" } + +dagger = { module = "com.google.dagger:dagger", version.ref = "dagger" } +dagger-compiler = { module = "com.google.dagger:dagger-compiler", version.ref = "dagger" } + +testfx-junit5 = { module = "org.testfx:testfx-junit5", version.ref = "testfx" } +testfx-core = { module = "org.testfx:testfx-core", version.ref = "testfxCore" } +testfx-monocle = { module = "org.testfx:openjfx-monocle", version.ref = "monocle" } + +hamcrest = { module = "org.hamcrest:hamcrest", version.ref = "hamcrest" } + +#junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" } +#junit-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" } +junit-bom = { module = "org.junit:junit-bom", version.ref = "junitbom" } +junit-jupiter = { module = "org.junit.jupiter:junit-jupiter" } +junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher" } + +mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" } +mockito-junit-jupiter = { module = "org.mockito:mockito-junit-jupiter", version.ref = "mockito" } + +[plugins] +javafx = { id = "org.openjfx.javafxplugin", version.ref = "javafxPlugin" } +spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } +#shadow = { id = "com.gradleup.shadow", version.ref = "shadow" } shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } diff --git a/scripts/configure-backup.py b/scripts/configure-backup.py index 28a5ce9..df7b9ae 100755 --- a/scripts/configure-backup.py +++ b/scripts/configure-backup.py @@ -69,6 +69,7 @@ def init_github_repository(): return github_username = "drcbabu81" repo_url = f"git@github.com:{github_username}/{repo_name}.git" + repo_url_https = f"https://github.com/{github_username}/{repo_name}.git" try: logger.info(f"cloning {repo_name}") @@ -76,6 +77,14 @@ def init_github_repository(): ["git", "clone", repo_url], check=True, capture_output=True, text=True ) + repo_path = os.path.abspath(repo_name) + + subprocess.run( + ["git", "remote", "add", "origin-https", repo_url_https], + cwd=repo_path, + check=True, capture_output=True, text=True + ) + if (Path(repo_name) / ".git").is_dir(): logger.info("clone successful") else: diff --git a/src/main/java/openconsignment/Launcher.java b/src/main/java/openconsignment/Launcher.java index 27773ab..4431331 100644 --- a/src/main/java/openconsignment/Launcher.java +++ b/src/main/java/openconsignment/Launcher.java @@ -8,14 +8,13 @@ import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.stage.Stage; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.Utils; import openconsignment.di.AppComponent; import openconsignment.di.DaggerAppComponent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@Slf4j public class Launcher extends Application { - private static final Logger logger = LoggerFactory.getLogger(Launcher.class); public static void main(String[] args) { launch(args); @@ -43,10 +42,10 @@ public void start(Stage stage) { stage.getIcons().add(new Image(resourceAsStream)); } stage.setTitle("OpenConsignment"); - logger.info("OpenConsignment started at {}", java.time.LocalDateTime.now()); + log.info("OpenConsignment started at {}", java.time.LocalDateTime.now()); } catch (Exception ex) { Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); } } } diff --git a/src/main/java/openconsignment/common/AppConfig.java b/src/main/java/openconsignment/common/AppConfig.java index 91fce8b..ec59801 100644 --- a/src/main/java/openconsignment/common/AppConfig.java +++ b/src/main/java/openconsignment/common/AppConfig.java @@ -9,23 +9,32 @@ @Setter @NoArgsConstructor public class AppConfig { - private String organizationName; + private String organization; + private String year; + private Github github; public static AppConfig forOrganization(String organizationName) { AppConfig configuration = new AppConfig(); - configuration.setOrganizationName(organizationName); + configuration.setOrganization(organizationName); configuration.validate(); return configuration; } - public String organizationName() { - return organizationName; + @Getter + @Setter + @NoArgsConstructor + public static class Github { + private String repository; + private String token; + private String username; + private String branch; + private String remote; } public void validate() { - if (organizationName == null || organizationName.isBlank()) { - throw new IllegalArgumentException("organizationName must not be blank"); + if (organization == null || organization.isBlank()) { + throw new IllegalArgumentException("organization must not be blank"); } - organizationName = organizationName.strip(); + organization = organization.strip(); } } diff --git a/src/main/java/openconsignment/common/Utils.java b/src/main/java/openconsignment/common/Utils.java index a1f3a42..81d56b0 100644 --- a/src/main/java/openconsignment/common/Utils.java +++ b/src/main/java/openconsignment/common/Utils.java @@ -3,11 +3,16 @@ import java.awt.*; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.MessageDigest; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; +import java.util.HexFormat; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -118,4 +123,19 @@ public static String nextVoucherNumber(String lastVoucher) { return "0"; } } + + public static String md5sum(Path path) throws Exception { + MessageDigest digest = MessageDigest.getInstance("MD5"); + + try (InputStream input = Files.newInputStream(path)) { + byte[] buffer = new byte[8192]; + int bytesRead; + + while ((bytesRead = input.read(buffer)) != -1) { + digest.update(buffer, 0, bytesRead); + } + } + + return HexFormat.of().formatHex(digest.digest()); + } } diff --git a/src/main/java/openconsignment/controller/MainController.java b/src/main/java/openconsignment/controller/MainController.java index 73a0e4e..80a3151 100644 --- a/src/main/java/openconsignment/controller/MainController.java +++ b/src/main/java/openconsignment/controller/MainController.java @@ -5,12 +5,18 @@ import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; +import javafx.scene.control.Alert; import javafx.scene.control.Button; -import javafx.scene.control.MenuItem; +import javafx.scene.control.ButtonType; import javafx.scene.layout.BorderPane; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import openconsignment.common.Utils; import openconsignment.common.ViewLoader; +import openconsignment.service.BackupService; +@Slf4j +@SuppressWarnings("unused") public class MainController implements Initializable { @FXML @@ -25,14 +31,13 @@ public class MainController implements Initializable { @FXML private Button master_btn; - @FXML - private MenuItem welcome_screen; - private final ViewLoader viewLoader; + private final BackupService backupService; @Inject - public MainController(ViewLoader viewLoader) { + public MainController(ViewLoader viewLoader, BackupService backupService) { this.viewLoader = viewLoader; + this.backupService = backupService; } @Override @@ -74,4 +79,96 @@ private void showCollectionHistory(ActionEvent event) { private void showPaymentHistory(ActionEvent event) { viewLoader.loadCenter("/fxml/history/PaymentHistory.fxml", root); } + + @FXML + private void showBillEntryScreen(ActionEvent event) { + viewLoader.loadCenter("/fxml/entry/BillEntry.fxml", root); + } + + @FXML + private void showCollectionEntryScreen(ActionEvent event) { + viewLoader.loadCenter("/fxml/entry/CollectionEntry.fxml", root); + } + + @FXML + private void showPaymentEntryScreen(ActionEvent event) { + viewLoader.loadCenter("/fxml/entry/PaymentEntry.fxml", root); + } + + @FXML + private void showSupplierLedger(ActionEvent event) { + viewLoader.loadCenter("/fxml/report/SupplierLedger.fxml", root); + } + + @FXML + private void showBuyerLedger(ActionEvent event) { + viewLoader.loadCenter("/fxml/report/BuyerLedger.fxml", root); + } + + @FXML + private void showTransportLedger(ActionEvent event) { + viewLoader.loadCenter("/fxml/report/TransportLedger.fxml", root); + } + + @FXML + private void showSupplierMaster(ActionEvent event) { + viewLoader.loadCenter("/fxml/master/MasterSupplier.fxml", root); + } + + @FXML + private void showBuyerMaster(ActionEvent event) { + viewLoader.loadCenter("/fxml/master/MasterBuyer.fxml", root); + } + + @FXML + private void showTransportMaster(ActionEvent event) { + viewLoader.loadCenter("/fxml/master/MasterTransport.fxml", root); + } + + @FXML + private void checkSync(ActionEvent event) { + boolean synced = false; + try { + synced = backupService.checkSync(); + } catch (Exception e) { + Utils.showAlert("Error", Alert.AlertType.ERROR); + } + + if (synced) { + Utils.showAlert("Data is Synced", Alert.AlertType.INFORMATION); + } else { + Utils.showAlert("Not Synced", Alert.AlertType.WARNING); + } + } + + @FXML + private void upload(ActionEvent event) { + try { + Alert alert = + new Alert(Alert.AlertType.CONFIRMATION, "Do you want to upload?", ButtonType.YES, ButtonType.NO); + if (alert.showAndWait().orElse(ButtonType.NO) != ButtonType.YES) { + return; + } + backupService.upload(); + Utils.showAlert("Successfully uploaded", Alert.AlertType.INFORMATION); + } catch (Exception e) { + log.error(e.toString()); + Utils.showAlert(e.toString(), Alert.AlertType.ERROR); + } + } + + public void download(ActionEvent actionEvent) { + try { + Alert alert = + new Alert(Alert.AlertType.CONFIRMATION, "Do you want to download?", ButtonType.YES, ButtonType.NO); + if (alert.showAndWait().orElse(ButtonType.NO) != ButtonType.YES) { + return; + } + backupService.download(); + Utils.showAlert("Successfully downloaded", Alert.AlertType.INFORMATION); + } catch (Exception e) { + log.error(e.toString()); + Utils.showAlert(e.toString(), Alert.AlertType.ERROR); + } + } } diff --git a/src/main/java/openconsignment/controller/WelcomeScreenController.java b/src/main/java/openconsignment/controller/WelcomeScreenController.java index 73e0d70..ba1f82e 100644 --- a/src/main/java/openconsignment/controller/WelcomeScreenController.java +++ b/src/main/java/openconsignment/controller/WelcomeScreenController.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.net.URL; +import java.sql.SQLException; import java.util.ResourceBundle; import javafx.event.ActionEvent; import javafx.fxml.FXML; @@ -9,21 +10,26 @@ import javafx.scene.control.Hyperlink; import javafx.scene.text.Text; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.AppConfig; import openconsignment.common.Utils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import openconsignment.di.DatabaseManager; +@Slf4j public class WelcomeScreenController implements Initializable { - private static final Logger logger = LoggerFactory.getLogger(WelcomeScreenController.class); private final AppConfig configuration; + private final DatabaseManager databaseManager; @FXML private Text organization_name; + @FXML + private Text year; + @Inject - public WelcomeScreenController(AppConfig configuration) { + public WelcomeScreenController(AppConfig configuration, DatabaseManager databaseManager) { this.configuration = configuration; + this.databaseManager = databaseManager; } @FXML @@ -35,12 +41,19 @@ private void handleOpenGithub(ActionEvent event) { Utils.launchBrowser(url); } catch (IOException ex) { Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); } } @Override public void initialize(URL url, ResourceBundle rb) { - organization_name.setText(configuration.organizationName()); + organization_name.setText(configuration.getOrganization()); + year.setText(configuration.getYear()); + try { + databaseManager.getConnection(); + } catch (SQLException e) { + log.error(e.toString()); + Utils.showAlert(e.toString()); + } } } diff --git a/src/main/java/openconsignment/controller/report/SupplierLedgerController.java b/src/main/java/openconsignment/controller/report/SupplierLedgerController.java index 340d15c..7f552c8 100644 --- a/src/main/java/openconsignment/controller/report/SupplierLedgerController.java +++ b/src/main/java/openconsignment/controller/report/SupplierLedgerController.java @@ -15,15 +15,14 @@ import javafx.scene.control.RadioButton; import javafx.scene.control.ToggleGroup; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import net.sf.jasperreports.engine.*; import openconsignment.common.Constants; import openconsignment.common.Utils; import openconsignment.service.SupplierService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@Slf4j public class SupplierLedgerController implements Initializable { - private static final Logger logger = LoggerFactory.getLogger(SupplierLedgerController.class); @FXML private ComboBox supplier_name_combo; @@ -57,7 +56,7 @@ public void initialize(URL url, ResourceBundle rb) { supplier_name_combo.setItems(FXCollections.observableArrayList(supplierList)); } catch (SQLException ex) { Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); } } @@ -70,7 +69,7 @@ private void generatePDF(ActionEvent event) { Utils.showAlert("Report Successfully Generated", AlertType.INFORMATION); } catch (IOException | SQLException | JRException ex) { Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); } } @@ -81,7 +80,7 @@ private void launchPdf(ActionEvent event) { Utils.showAlert("PDF opened successfully.", AlertType.INFORMATION); } catch (IOException ex) { Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); } } } diff --git a/src/main/java/openconsignment/di/ConfigurationModule.java b/src/main/java/openconsignment/di/ConfigurationModule.java index eb43f6c..5cc1d76 100644 --- a/src/main/java/openconsignment/di/ConfigurationModule.java +++ b/src/main/java/openconsignment/di/ConfigurationModule.java @@ -11,20 +11,18 @@ import java.nio.file.Files; import java.nio.file.Path; import javax.inject.Singleton; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.AppConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.Constructor; import org.yaml.snakeyaml.error.YAMLException; /** Creates the external configuration on first startup and provides validated settings from it. */ +@Slf4j @Module public final class ConfigurationModule { - private static final Logger logger = LoggerFactory.getLogger(ConfigurationModule.class); - private static final String CONFIGURATION_FILE = "application.yaml"; private static final String DEFAULTS_RESOURCE = "/" + CONFIGURATION_FILE; @@ -77,7 +75,7 @@ private static void initializeConfiguration(Path path) throws IOException { } try { Files.copy(defaults, path); - logger.info("Generated new application.yaml as it was missing at {}", path); + log.info("Generated new application.yaml as it was missing at {}", path); } catch (FileAlreadyExistsException ex) { // Another startup created the file; preserve it and load its contents. } diff --git a/src/main/java/openconsignment/di/DatabaseManager.java b/src/main/java/openconsignment/di/DatabaseManager.java new file mode 100644 index 0000000..fbcf1ca --- /dev/null +++ b/src/main/java/openconsignment/di/DatabaseManager.java @@ -0,0 +1,77 @@ +package openconsignment.di; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Objects; +import lombok.extern.slf4j.Slf4j; +import openconsignment.common.Constants; + +@Slf4j +public class DatabaseManager { + + private Connection connection; + + public DatabaseManager(Connection connection) { + this.connection = connection; + } + + public synchronized Connection getConnection() throws SQLException { + + if (connection == null || connection.isClosed()) { + connection = DriverManager.getConnection("jdbc:sqlite:" + Constants.DATABASE_FILE_NAME); + initDatabase(connection); + } + + return connection; + } + + public synchronized void closeConnection() throws SQLException { + + if (connection != null && !connection.isClosed()) { + connection.close(); + } + + connection = null; + } + + public synchronized void reopenConnection() throws SQLException { + closeConnection(); + getConnection(); + } + + private static void initDatabase(Connection conn) { + try { + String initSQL = getInitSQL(); + try (Statement st = conn.createStatement()) { + conn.setAutoCommit(false); + + for (String statement : initSQL.split(";")) { + String cleanedStatement = statement.trim(); + if (!cleanedStatement.isEmpty()) { + st.execute(cleanedStatement); + } + } + + conn.commit(); + } catch (Exception e) { + conn.rollback(); + throw e; + } finally { + conn.setAutoCommit(true); + } + } catch (Exception ex) { + log.error(ex.toString(), ex); + } + } + + private static String getInitSQL() throws IOException { + return new String( + Objects.requireNonNull(DatabaseModule.class.getResourceAsStream("/sql/init.sql")) + .readAllBytes(), + StandardCharsets.UTF_8); + } +} diff --git a/src/main/java/openconsignment/di/DatabaseModule.java b/src/main/java/openconsignment/di/DatabaseModule.java index c6ae947..29008b0 100644 --- a/src/main/java/openconsignment/di/DatabaseModule.java +++ b/src/main/java/openconsignment/di/DatabaseModule.java @@ -2,68 +2,15 @@ import dagger.Module; import dagger.Provides; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Objects; import javax.inject.Singleton; -import openconsignment.common.Constants; -import openconsignment.common.Utils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; @Module @SuppressWarnings("unused") public class DatabaseModule { - private static final Logger logger = LoggerFactory.getLogger(DatabaseModule.class); @Provides @Singleton - static Connection provideConnection() { - try { - Class.forName("org.sqlite.JDBC"); - Connection conn = DriverManager.getConnection("jdbc:sqlite:" + Constants.DATABASE_FILE_NAME); - initDatabase(conn); - return conn; - } catch (ClassNotFoundException | SQLException ex) { - Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); - throw new RuntimeException(ex); - } - } - - private static void initDatabase(Connection conn) { - try { - String initSQL = getInitSQL(); - try (Statement st = conn.createStatement()) { - conn.setAutoCommit(false); - - for (String statement : initSQL.split(";")) { - String cleanedStatement = statement.trim(); - if (!cleanedStatement.isEmpty()) { - st.execute(cleanedStatement); - } - } - - conn.commit(); - } catch (Exception e) { - conn.rollback(); - throw e; - } finally { - conn.setAutoCommit(true); - } - } catch (Exception ex) { - logger.error(ex.toString(), ex); - } - } - - private static String getInitSQL() throws IOException { - return new String( - Objects.requireNonNull(DatabaseModule.class.getResourceAsStream("/sql/init.sql")) - .readAllBytes(), - StandardCharsets.UTF_8); + static DatabaseManager provideDatabaseManager() { + return new DatabaseManager(null); } } diff --git a/src/main/java/openconsignment/repository/BillRepository.java b/src/main/java/openconsignment/repository/BillRepository.java index a1a5971..7c54187 100644 --- a/src/main/java/openconsignment/repository/BillRepository.java +++ b/src/main/java/openconsignment/repository/BillRepository.java @@ -1,38 +1,38 @@ package openconsignment.repository; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.SqlLoader; import openconsignment.common.SqlQuery; +import openconsignment.di.DatabaseManager; import openconsignment.entity.BillEntity; import openconsignment.entity.LREntity; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@Slf4j public class BillRepository { - private static final Logger logger = LoggerFactory.getLogger(BillRepository.class); - private final Connection conn; + private final DatabaseManager databaseManager; @Inject - public BillRepository(Connection conn) { - this.conn = conn; + public BillRepository(DatabaseManager databaseManager) { + this.databaseManager = databaseManager; } public void save(BillEntity billEntity) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.BILL_SAVE); - conn.setAutoCommit(false); + databaseManager.getConnection().setAutoCommit(false); deleteBill(billEntity.getBillNo()); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, billEntity.getSupplierName()); preparedStatement.setString(2, billEntity.getBuyerName()); preparedStatement.setString(3, billEntity.getBillNo()); @@ -47,17 +47,17 @@ public void save(BillEntity billEntity) throws SQLException { if (null != billEntity.getLrEntities()) { for (LREntity lr : billEntity.getLrEntities()) { sql = SqlLoader.load(SqlQuery.BILL_SAVE_LR); - preparedStatement = conn.prepareStatement(sql); + preparedStatement = databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, billEntity.getBillNo()); preparedStatement.setString(2, lr.getLrNo()); preparedStatement.setString(3, lr.getPm()); preparedStatement.execute(); } } - conn.commit(); + databaseManager.getConnection().commit(); } catch (SQLException ex) { - conn.rollback(); - logger.error(ex.toString(), ex); + databaseManager.getConnection().rollback(); + log.error(ex.toString(), ex); throw ex; } } @@ -65,7 +65,8 @@ public void save(BillEntity billEntity) throws SQLException { public BillEntity getBill(String billNo) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.BILL_GET); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, billNo); ResultSet billResultSet = preparedStatement.executeQuery(); @@ -84,7 +85,7 @@ public BillEntity getBill(String billNo) throws SQLException { .build(); sql = SqlLoader.load(SqlQuery.BILL_GET_LRS); - preparedStatement = conn.prepareStatement(sql); + preparedStatement = databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, billNo); ResultSet lrPmResultSet = preparedStatement.executeQuery(); @@ -99,28 +100,29 @@ public BillEntity getBill(String billNo) throws SQLException { billEntity.setLrEntities(lrpmList); return billEntity; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } public void deleteBill(String billNo) throws SQLException { try { - conn.setAutoCommit(false); + databaseManager.getConnection().setAutoCommit(false); String sql = SqlLoader.load(SqlQuery.BILL_DELETE); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, billNo); preparedStatement.execute(); String sql2 = SqlLoader.load(SqlQuery.BILL_DELETE_LRS); - preparedStatement = conn.prepareStatement(sql2); + preparedStatement = databaseManager.getConnection().prepareStatement(sql2); preparedStatement.setString(1, billNo); preparedStatement.execute(); - conn.commit(); + databaseManager.getConnection().commit(); } catch (SQLException ex) { - conn.rollback(); - logger.error(ex.toString(), ex); + databaseManager.getConnection().rollback(); + log.error(ex.toString(), ex); throw ex; } } @@ -129,7 +131,7 @@ public List getBills() throws SQLException { List res = new ArrayList<>(); try { String sql = SqlLoader.load(SqlQuery.BILL_GET_ALL); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ResultSet rs = ps.executeQuery(); while (rs.next()) { res.add(BillEntity.builder() @@ -145,7 +147,7 @@ public List getBills() throws SQLException { } return res; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } diff --git a/src/main/java/openconsignment/repository/BuyerRepository.java b/src/main/java/openconsignment/repository/BuyerRepository.java index 8e4d23f..1bcfd9b 100644 --- a/src/main/java/openconsignment/repository/BuyerRepository.java +++ b/src/main/java/openconsignment/repository/BuyerRepository.java @@ -1,35 +1,34 @@ package openconsignment.repository; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.SqlLoader; import openconsignment.common.SqlQuery; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import openconsignment.di.DatabaseManager; +@Slf4j public class BuyerRepository { - private static final Logger logger = LoggerFactory.getLogger(BuyerRepository.class); - private final Connection conn; + private final DatabaseManager databaseManager; @Inject - public BuyerRepository(Connection conn) { - this.conn = conn; + public BuyerRepository(DatabaseManager databaseManager) { + this.databaseManager = databaseManager; } public void saveBuyer(String buyerName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.BUYER_SAVE); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, buyerName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -37,11 +36,11 @@ public void saveBuyer(String buyerName) throws SQLException { public void deleteBuyer(String buyerName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.BUYER_DELETE); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, buyerName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -49,12 +48,12 @@ public void deleteBuyer(String buyerName) throws SQLException { public void renameBuyer(String oldName, String newName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.BUYER_RENAME); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, newName); ps.setString(2, oldName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -62,14 +61,16 @@ public void renameBuyer(String oldName, String newName) throws SQLException { public List getAllBuyers() throws SQLException { try { List buyerList = new ArrayList<>(); - ResultSet buyerResultSet = conn.prepareStatement(SqlLoader.load(SqlQuery.BUYER_GET_ALL)) + ResultSet buyerResultSet = databaseManager + .getConnection() + .prepareStatement(SqlLoader.load(SqlQuery.BUYER_GET_ALL)) .executeQuery(); while (buyerResultSet.next()) { buyerList.add(buyerResultSet.getString("name")); } return buyerList; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } diff --git a/src/main/java/openconsignment/repository/CollectionRepository.java b/src/main/java/openconsignment/repository/CollectionRepository.java index 41daf5c..81f9a36 100644 --- a/src/main/java/openconsignment/repository/CollectionRepository.java +++ b/src/main/java/openconsignment/repository/CollectionRepository.java @@ -1,36 +1,36 @@ package openconsignment.repository; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.SqlLoader; import openconsignment.common.SqlQuery; import openconsignment.common.Utils; +import openconsignment.di.DatabaseManager; import openconsignment.entity.BillEntity; import openconsignment.entity.CollectionEntity; import openconsignment.entity.CollectionItemEntity; import openconsignment.model.BuyerLedgerRow; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@Slf4j public class CollectionRepository { - private static final Logger logger = LoggerFactory.getLogger(CollectionRepository.class); - private final Connection conn; + private final DatabaseManager databaseManager; @Inject - public CollectionRepository(Connection conn) { - this.conn = conn; + public CollectionRepository(DatabaseManager databaseManager) { + this.databaseManager = databaseManager; } public List fetchPendingBillsForBuyer(String buyerName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.COLLECTION_PENDING_BILLS_FOR_BUYER); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, buyerName); ResultSet resultSet = preparedStatement.executeQuery(); @@ -45,7 +45,7 @@ public List fetchPendingBillsForBuyer(String buyerName) throws SQLEx } return res; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -53,7 +53,8 @@ public List fetchPendingBillsForBuyer(String buyerName) throws SQLEx public int fetchPendingAmountForBillNo(String billNo) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.COLLECTION_PENDING_AMOUNT_FOR_BILL); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, billNo); ResultSet resultSet = preparedStatement.executeQuery(); @@ -63,17 +64,18 @@ public int fetchPendingAmountForBillNo(String billNo) throws SQLException { return resultSet.getInt("pending_amount"); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } public void saveCollection(CollectionEntity collectionEntity) throws SQLException { try { - conn.setAutoCommit(false); + databaseManager.getConnection().setAutoCommit(false); deleteCollection(collectionEntity.getVoucherNo()); String sql = SqlLoader.load(SqlQuery.COLLECTION_SAVE); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, collectionEntity.getVoucherNo()); preparedStatement.setString(2, collectionEntity.getVoucherDate()); preparedStatement.setString(3, collectionEntity.getBuyerName()); @@ -85,7 +87,7 @@ public void saveCollection(CollectionEntity collectionEntity) throws SQLExceptio if (null != collectionEntity.getItems()) { for (CollectionItemEntity collectionItem : collectionEntity.getItems()) { - preparedStatement = conn.prepareStatement(sql); + preparedStatement = databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, collectionEntity.getVoucherNo()); preparedStatement.setString(2, collectionItem.getSupplierName()); preparedStatement.setString(3, collectionItem.getBillNo()); @@ -101,11 +103,11 @@ public void saveCollection(CollectionEntity collectionEntity) throws SQLExceptio } } - conn.commit(); + databaseManager.getConnection().commit(); } catch (SQLException ex) { - conn.rollback(); - logger.error(ex.toString(), ex); + databaseManager.getConnection().rollback(); + log.error(ex.toString(), ex); throw ex; } } @@ -113,11 +115,12 @@ public void saveCollection(CollectionEntity collectionEntity) throws SQLExceptio public String getLastVoucher() throws SQLException { try { String sql = SqlLoader.load(SqlQuery.COLLECTION_LAST_VOUCHER); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); ResultSet resultSet = preparedStatement.executeQuery(); return resultSet.getString("Max(`Voucher No.`)"); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -126,7 +129,8 @@ public CollectionEntity getCollection(String voucherNo) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.COLLECTION_GET_ITEMS); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, voucherNo); ResultSet collectionResultSet = preparedStatement.executeQuery(); @@ -146,7 +150,7 @@ public CollectionEntity getCollection(String voucherNo) throws SQLException { } sql = SqlLoader.load(SqlQuery.COLLECTION_GET); - preparedStatement = conn.prepareStatement(sql); + preparedStatement = databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, voucherNo); collectionResultSet = preparedStatement.executeQuery(); if (collectionResultSet.isClosed()) { @@ -161,31 +165,32 @@ public CollectionEntity getCollection(String voucherNo) throws SQLException { .items(collectionItemList) .build(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } public void deleteCollection(String voucherNo) throws SQLException { try { - conn.setAutoCommit(false); + databaseManager.getConnection().setAutoCommit(false); String sql = SqlLoader.load(SqlQuery.COLLECTION_DELETE); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, voucherNo); preparedStatement.execute(); sql = SqlLoader.load(SqlQuery.COLLECTION_DELETE_ITEMS); - preparedStatement = conn.prepareStatement(sql); + preparedStatement = databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, voucherNo); preparedStatement.execute(); - conn.commit(); + databaseManager.getConnection().commit(); } catch (SQLException ex) { Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); - conn.rollback(); + log.error(ex.toString(), ex); + databaseManager.getConnection().rollback(); } } @@ -193,7 +198,7 @@ public List getCollections() throws SQLException { try { List res = new ArrayList<>(); String sql = SqlLoader.load(SqlQuery.COLLECTION_GET_ALL); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ResultSet rs = ps.executeQuery(); while (rs.next()) { res.add(CollectionEntity.builder() @@ -206,7 +211,7 @@ public List getCollections() throws SQLException { } return res; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -214,7 +219,8 @@ public List getCollections() throws SQLException { public List getCollectionDetailsForBuyer(String buyerName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.COLLECTION_DETAILS_FOR_BUYER); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, buyerName); ResultSet resultSet = preparedStatement.executeQuery(); @@ -235,7 +241,7 @@ public List getCollectionDetailsForBuyer(String buyerName) throw } return res; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } diff --git a/src/main/java/openconsignment/repository/PaymentRepository.java b/src/main/java/openconsignment/repository/PaymentRepository.java index 89c1b11..0907049 100644 --- a/src/main/java/openconsignment/repository/PaymentRepository.java +++ b/src/main/java/openconsignment/repository/PaymentRepository.java @@ -1,38 +1,38 @@ package openconsignment.repository; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.SqlLoader; import openconsignment.common.SqlQuery; import openconsignment.common.Utils; +import openconsignment.di.DatabaseManager; import openconsignment.entity.BillEntity; import openconsignment.entity.PaymentEntity; import openconsignment.entity.PaymentItemEntity; import openconsignment.model.SupplierLedgerRow; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@Slf4j public class PaymentRepository { - private static final Logger logger = LoggerFactory.getLogger(PaymentRepository.class); - private final Connection conn; + private final DatabaseManager databaseManager; @Inject - public PaymentRepository(Connection conn) { - this.conn = conn; + public PaymentRepository(DatabaseManager databaseManager) { + this.databaseManager = databaseManager; } public void savePayment(PaymentEntity paymentEntity) throws SQLException { try { - conn.setAutoCommit(false); + databaseManager.getConnection().setAutoCommit(false); deletePayment(paymentEntity.getVoucherNo()); String sql = SqlLoader.load(SqlQuery.PAYMENT_SAVE); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, paymentEntity.getVoucherNo()); preparedStatement.setString(2, paymentEntity.getVoucherDate()); preparedStatement.setString(3, paymentEntity.getSupplierName()); @@ -44,7 +44,7 @@ public void savePayment(PaymentEntity paymentEntity) throws SQLException { if (null != paymentEntity.getItems()) { for (PaymentItemEntity paymentItem : paymentEntity.getItems()) { - preparedStatement = conn.prepareStatement(sql); + preparedStatement = databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, paymentEntity.getVoucherNo()); preparedStatement.setString(2, paymentItem.getBuyerName()); preparedStatement.setString(3, paymentItem.getBillNo()); @@ -59,17 +59,18 @@ public void savePayment(PaymentEntity paymentEntity) throws SQLException { preparedStatement.execute(); } } - conn.commit(); + databaseManager.getConnection().commit(); } catch (SQLException ex) { - conn.rollback(); - logger.error(ex.toString(), ex); + databaseManager.getConnection().rollback(); + log.error(ex.toString(), ex); } } public List fetchPendingBillsForSupplier(String supplierName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.PAYMENT_PENDING_BILLS_FOR_SUPPLIER); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, supplierName); ResultSet resultSet = preparedStatement.executeQuery(); @@ -84,7 +85,7 @@ public List fetchPendingBillsForSupplier(String supplierName) throws } return res; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -92,7 +93,8 @@ public List fetchPendingBillsForSupplier(String supplierName) throws public int fetchPendingAmountForBillNo(String billNo) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.PAYMENT_PENDING_AMOUNT_FOR_BILL); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, billNo); ResultSet resultSet = preparedStatement.executeQuery(); @@ -102,7 +104,7 @@ public int fetchPendingAmountForBillNo(String billNo) throws SQLException { return resultSet.getInt("pending_amount"); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -110,11 +112,12 @@ public int fetchPendingAmountForBillNo(String billNo) throws SQLException { public String getLastVoucher() throws SQLException { try { String sql = SqlLoader.load(SqlQuery.PAYMENT_LAST_VOUCHER); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); ResultSet resultSet = preparedStatement.executeQuery(); return resultSet.getString("Max(`Voucher No.`)"); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -122,7 +125,7 @@ public String getLastVoucher() throws SQLException { public PaymentEntity getPayment(String voucherNo) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.PAYMENT_GET_ITEMS); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, voucherNo); ResultSet rs = ps.executeQuery(); @@ -145,7 +148,7 @@ public PaymentEntity getPayment(String voucherNo) throws SQLException { sql = SqlLoader.load(SqlQuery.PAYMENT_GET); - ps = conn.prepareStatement(sql); + ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, voucherNo); rs = ps.executeQuery(); @@ -163,31 +166,32 @@ public PaymentEntity getPayment(String voucherNo) throws SQLException { } catch (SQLException ex) { Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } public void deletePayment(String voucherNo) throws SQLException { try { - conn.setAutoCommit(false); + databaseManager.getConnection().setAutoCommit(false); String sql = SqlLoader.load(SqlQuery.PAYMENT_DELETE); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, voucherNo); preparedStatement.execute(); sql = SqlLoader.load(SqlQuery.PAYMENT_DELETE_ITEMS); - preparedStatement = conn.prepareStatement(sql); + preparedStatement = databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, voucherNo); preparedStatement.execute(); - conn.commit(); + databaseManager.getConnection().commit(); } catch (SQLException ex) { Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); - conn.rollback(); + log.error(ex.toString(), ex); + databaseManager.getConnection().rollback(); } } @@ -195,7 +199,7 @@ public List getPayments() throws SQLException { try { List res = new ArrayList<>(); String sql = SqlLoader.load(SqlQuery.PAYMENT_GET_ALL); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ResultSet rs = ps.executeQuery(); while (rs.next()) { res.add(PaymentEntity.builder() @@ -208,7 +212,7 @@ public List getPayments() throws SQLException { } return res; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -216,7 +220,8 @@ public List getPayments() throws SQLException { public List getPaymentDetailsForSupplier(String supplierName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.PAYMENT_DETAILS_FOR_SUPPLIER); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, supplierName); ResultSet resultSet = preparedStatement.executeQuery(); @@ -237,7 +242,7 @@ public List getPaymentDetailsForSupplier(String supplierName) } return res; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } diff --git a/src/main/java/openconsignment/repository/SupplierRepository.java b/src/main/java/openconsignment/repository/SupplierRepository.java index 9534dbd..556a3a1 100644 --- a/src/main/java/openconsignment/repository/SupplierRepository.java +++ b/src/main/java/openconsignment/repository/SupplierRepository.java @@ -1,35 +1,34 @@ package openconsignment.repository; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.SqlLoader; import openconsignment.common.SqlQuery; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import openconsignment.di.DatabaseManager; +@Slf4j public class SupplierRepository { - private static final Logger logger = LoggerFactory.getLogger(SupplierRepository.class); - private final Connection conn; + private final DatabaseManager databaseManager; @Inject - public SupplierRepository(Connection conn) { - this.conn = conn; + public SupplierRepository(DatabaseManager databaseManager) { + this.databaseManager = databaseManager; } public void saveSupplier(String supplierName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.SUPPLIER_SAVE); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, supplierName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -37,11 +36,11 @@ public void saveSupplier(String supplierName) throws SQLException { public void deleteSupplier(String supplierName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.SUPPLIER_DELETE); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, supplierName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -49,12 +48,12 @@ public void deleteSupplier(String supplierName) throws SQLException { public void renameSupplier(String oldName, String newName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.SUPPLIER_RENAME); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, newName); ps.setString(2, oldName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -62,14 +61,16 @@ public void renameSupplier(String oldName, String newName) throws SQLException { public List getAllSuppliers() throws SQLException { try { List supplierList = new ArrayList<>(); - ResultSet supplierResultSet = conn.prepareStatement(SqlLoader.load(SqlQuery.SUPPLIER_GET_ALL)) + ResultSet supplierResultSet = databaseManager + .getConnection() + .prepareStatement(SqlLoader.load(SqlQuery.SUPPLIER_GET_ALL)) .executeQuery(); while (supplierResultSet.next()) { supplierList.add(supplierResultSet.getString("name")); } return supplierList; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } diff --git a/src/main/java/openconsignment/repository/TransportRepository.java b/src/main/java/openconsignment/repository/TransportRepository.java index b2679b1..44a5e9c 100644 --- a/src/main/java/openconsignment/repository/TransportRepository.java +++ b/src/main/java/openconsignment/repository/TransportRepository.java @@ -1,36 +1,35 @@ package openconsignment.repository; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.SqlLoader; import openconsignment.common.SqlQuery; +import openconsignment.di.DatabaseManager; import openconsignment.model.TransportLedgerRow; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@Slf4j public class TransportRepository { - private static final Logger logger = LoggerFactory.getLogger(TransportRepository.class); - private final Connection conn; + private final DatabaseManager databaseManager; @Inject - public TransportRepository(Connection conn) { - this.conn = conn; + public TransportRepository(DatabaseManager databaseManager) { + this.databaseManager = databaseManager; } public void saveTransport(String transportName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.TRANSPORT_SAVE); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, transportName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -38,11 +37,11 @@ public void saveTransport(String transportName) throws SQLException { public void deleteTransport(String transportName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.TRANSPORT_DELETE); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, transportName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -50,12 +49,12 @@ public void deleteTransport(String transportName) throws SQLException { public void renameTransport(String oldName, String newName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.TRANSPORT_RENAME); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, newName); ps.setString(2, oldName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -63,14 +62,16 @@ public void renameTransport(String oldName, String newName) throws SQLException public List getAllTransports() throws SQLException { try { List transportList = new ArrayList<>(); - ResultSet transportResultSet = conn.prepareStatement(SqlLoader.load(SqlQuery.TRANSPORT_GET_ALL)) + ResultSet transportResultSet = databaseManager + .getConnection() + .prepareStatement(SqlLoader.load(SqlQuery.TRANSPORT_GET_ALL)) .executeQuery(); while (transportResultSet.next()) { transportList.add(transportResultSet.getString("name")); } return transportList; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -82,7 +83,7 @@ public List getTransportReportFor(String transportName, Stri String sql = SqlLoader.load(SqlQuery.TRANSPORT_REPORT); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, transportName); ps.setString(2, fromDate); ps.setString(3, fromDate); @@ -105,7 +106,7 @@ public List getTransportReportFor(String transportName, Stri } return result; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } diff --git a/src/main/java/openconsignment/service/BackupService.java b/src/main/java/openconsignment/service/BackupService.java new file mode 100644 index 0000000..f3530e7 --- /dev/null +++ b/src/main/java/openconsignment/service/BackupService.java @@ -0,0 +1,238 @@ +package openconsignment.service; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.sql.SQLException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import javax.inject.Inject; +import javax.inject.Singleton; +import lombok.extern.slf4j.Slf4j; +import openconsignment.common.AppConfig; +import openconsignment.common.Constants; +import openconsignment.common.Utils; +import openconsignment.di.DatabaseManager; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.PullResult; +import org.eclipse.jgit.api.errors.EmptyCommitException; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.transport.PushResult; +import org.eclipse.jgit.transport.URIish; +import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; + +@Slf4j +@Singleton +public class BackupService { + + private final AppConfig appConfig; + private final DatabaseManager databaseManager; + + @Inject + public BackupService(AppConfig appConfig, DatabaseManager databaseManager) { + this.appConfig = appConfig; + this.databaseManager = databaseManager; + } + + private void cloneRepo() throws GitAPIException, IOException, URISyntaxException { + + log.info("executing git clone"); + + AppConfig.Github github = appConfig.getGithub(); + String repoPath = github.getRepository(); + String username = github.getUsername(); + String token = github.getToken(); + String branchName = github.getBranch(); + String remoteName = github.getRemote(); + + if (Files.exists(Path.of(repoPath))) { + log.info("skipping git clone as repo already exist"); + return; + } + + String repoUrl = "https://github.com/" + username + "/" + repoPath + ".git"; + + try (Git ignored = Git.cloneRepository() + .setURI(repoUrl) + .setDirectory(new File(repoPath)) + .setBranch(branchName) + .setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, token)) + .call()) { + + log.info("Authenticated clone successful"); + } + + try (Git git = Git.open(new File(repoPath))) { + + // HTTPS remote + git.remoteAdd() + .setName(remoteName) + .setUri(new URIish("https://github.com/" + username + "/" + repoPath + ".git")) + .call(); + + git.remoteSetUrl() + .setRemoteName("origin") + .setRemoteUri(new URIish("git@github.com:" + username + "/" + repoPath + ".git")) + .call(); + + if (null == git.getRepository().resolve("HEAD")) { + git.getRepository().updateRef("HEAD").link("refs/heads/" + branchName); + } + } + } + + public boolean checkSync() throws Exception { + log.info("executing called"); + try { + pull(); + return compareDatabaseHashes(); + } catch (Exception e) { + log.error("Error during git pull", e); + throw e; + } + } + + private String getRepoFileHash() throws Exception { + Path remotePath = Path.of(appConfig.getGithub().getRepository() + "/" + Constants.DATABASE_FILE_NAME); + if (!Files.exists(remotePath)) { + return ""; + } + return Utils.md5sum(remotePath); + } + + public boolean compareDatabaseHashes() throws Exception { + String localFileHash = Utils.md5sum(Path.of(Constants.DATABASE_FILE_NAME)); + String repoFileHash = getRepoFileHash(); + + boolean result = 0 == localFileHash.compareTo(repoFileHash); + log.info("CheckSync result = {}, localFileHash = {}, repoFileHash = {}", result, localFileHash, repoFileHash); + return result; + } + + private void copyRepoToLocal() throws IOException { + AppConfig.Github github = appConfig.getGithub(); + String repoPath = github.getRepository(); + + log.info("Copying {} to {}", repoPath, Constants.DATABASE_FILE_NAME); + Files.copy( + Path.of(new File(repoPath + "/" + Constants.DATABASE_FILE_NAME).toURI()), + Path.of(new File(Constants.DATABASE_FILE_NAME).toURI()), + StandardCopyOption.REPLACE_EXISTING); + log.info("Copied {} to {}", repoPath, Constants.DATABASE_FILE_NAME); + } + + private void pull() throws IOException, GitAPIException, URISyntaxException { + log.info("executing git pull"); + + AppConfig.Github github = appConfig.getGithub(); + + log.info("token is {}", github.getToken()); + + if (!Files.exists(Path.of(github.getRepository()))) { + log.info("cloning {}", github.getRepository()); + cloneRepo(); + log.info("cloned {}", github.getRepository()); + return; + } + + try (Git git = Git.open(new File(github.getRepository()))) { + + PullResult result = git.pull() + .setRemote(github.getRemote()) + .setRemoteBranchName(github.getBranch()) + .setCredentialsProvider( + new UsernamePasswordCredentialsProvider(github.getUsername(), github.getToken())) + .call(); + + if (result.isSuccessful()) { + log.info("Successfully pulled: {}", github.getBranch()); + } else { + throw new IllegalStateException("Pull failed for branch: " + github.getBranch()); + } + } + } + + public void download() throws GitAPIException, IOException, URISyntaxException, SQLException { + pull(); + copyRepoToLocal(); + databaseManager.reopenConnection(); + } + + private void copyLocalToRepo() throws IOException { + AppConfig.Github github = appConfig.getGithub(); + String repoPath = github.getRepository(); + + log.info("Copying {} to {}", Constants.DATABASE_FILE_NAME, repoPath); + Files.copy( + Path.of(new File(Constants.DATABASE_FILE_NAME).toURI()), + Path.of(new File(repoPath + "/" + Constants.DATABASE_FILE_NAME).toURI()), + StandardCopyOption.REPLACE_EXISTING); + log.info("Copied {} to {}", Constants.DATABASE_FILE_NAME, repoPath); + } + + private void addAndCommit() throws IOException, GitAPIException { + + log.info("executing add and commit"); + + AppConfig.Github github = appConfig.getGithub(); + String repoPath = github.getRepository(); + + try (Git git = Git.open(new File(repoPath))) { + + // Stage changes + git.add().addFilepattern(".").call(); + + // Current time in string + String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + + String repoFileHash = "null"; + try { + repoFileHash = getRepoFileHash(); + } catch (Exception e) { + log.error(e.toString()); + } + + String message = "Backed up at " + currentTime + "; database hash = " + repoFileHash; + + // Commit changes + RevCommit commit = + git.commit().setMessage(message).setAllowEmpty(false).call(); + + log.info("Commit: " + commit.getId().getName()); + } + } + + private void push() throws IOException, GitAPIException { + log.info("executing git push"); + + AppConfig.Github github = appConfig.getGithub(); + + log.info("pushing with token {}", github.getToken()); + + try (Git git = Git.open(new File(github.getRepository()))) { + Iterable results = git.push() + .setRemote(github.getRemote()) + .setCredentialsProvider( + new UsernamePasswordCredentialsProvider(github.getUsername(), github.getToken())) + .call(); + + for (PushResult result : results) { + log.info(result.getMessages()); + } + } + } + + public void upload() throws GitAPIException, IOException { + copyLocalToRepo(); + try { + addAndCommit(); + } catch (EmptyCommitException ex) { + log.info("swallowing EmptyCommitException"); + } + push(); + } +} diff --git a/src/main/java/openconsignment/service/BuyerService.java b/src/main/java/openconsignment/service/BuyerService.java index 823f1e6..7eb6aa4 100644 --- a/src/main/java/openconsignment/service/BuyerService.java +++ b/src/main/java/openconsignment/service/BuyerService.java @@ -49,7 +49,7 @@ public void renameBuyer(String oldName, String newName) throws SQLException { public void generatePdf(String buyerName, boolean isAgewise) throws SQLException, JRException { Map payload = new HashMap<>(); - payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.organizationName()); + payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.getOrganization()); payload.put("buyerName", buyerName); if (isAgewise) { diff --git a/src/main/java/openconsignment/service/SupplierService.java b/src/main/java/openconsignment/service/SupplierService.java index 7f8eb0e..a476ff3 100644 --- a/src/main/java/openconsignment/service/SupplierService.java +++ b/src/main/java/openconsignment/service/SupplierService.java @@ -50,7 +50,7 @@ public void renameSupplier(String oldName, String newName) throws SQLException { public void generatePdf(String supplierName, boolean isAgewise) throws SQLException, JRException { Map payload = new HashMap<>(); - payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.organizationName()); + payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.getOrganization()); payload.put("supplierName", supplierName); if (isAgewise) { diff --git a/src/main/java/openconsignment/service/TransportService.java b/src/main/java/openconsignment/service/TransportService.java index 8007adc..4785790 100644 --- a/src/main/java/openconsignment/service/TransportService.java +++ b/src/main/java/openconsignment/service/TransportService.java @@ -46,7 +46,7 @@ public void generatePdf(String transportName, String fromDate, String toDate) th transportRepository.getTransportReportFor(transportName, fromDate, toDate); Map payload = new HashMap<>(); - payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.organizationName()); + payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.getOrganization()); payload.put("transportName", transportName); payload.put("fromDate", fromDate); payload.put("toDate", toDate); diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index aada7ee..8167cdc 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1 +1,8 @@ -organizationName: "SATYAM AGENCIES" +organization: "SATYAM AGENCIES" +year: 2001-02 +github: + token: "" + username: "razdeep" + branch: "main" + remote: "origin-https" + repository: "Satyam-Database-2001-02" \ No newline at end of file diff --git a/src/main/resources/fxml/Main.fxml b/src/main/resources/fxml/Main.fxml index 6357a76..2f6c3a9 100644 --- a/src/main/resources/fxml/Main.fxml +++ b/src/main/resources/fxml/Main.fxml @@ -1,97 +1,144 @@ - - - - - - - - - - - -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/resources/fxml/WelcomeScreen.fxml b/src/main/resources/fxml/WelcomeScreen.fxml index 645c681..ad21a09 100644 --- a/src/main/resources/fxml/WelcomeScreen.fxml +++ b/src/main/resources/fxml/WelcomeScreen.fxml @@ -1,54 +1,68 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/fxml/report/BuyerLedger.fxml b/src/main/resources/fxml/report/BuyerLedger.fxml index d01305e..47ea9e7 100644 --- a/src/main/resources/fxml/report/BuyerLedger.fxml +++ b/src/main/resources/fxml/report/BuyerLedger.fxml @@ -3,12 +3,11 @@ - - + + @@ -50,4 +49,4 @@ - + diff --git a/src/main/resources/fxml/report/SupplierLedger.fxml b/src/main/resources/fxml/report/SupplierLedger.fxml index 4745eb1..3e8c83c 100644 --- a/src/main/resources/fxml/report/SupplierLedger.fxml +++ b/src/main/resources/fxml/report/SupplierLedger.fxml @@ -3,12 +3,11 @@ - - + + @@ -51,4 +50,4 @@ - + diff --git a/src/main/resources/fxml/report/TransportLedger.fxml b/src/main/resources/fxml/report/TransportLedger.fxml index 01aa234..02caf53 100644 --- a/src/main/resources/fxml/report/TransportLedger.fxml +++ b/src/main/resources/fxml/report/TransportLedger.fxml @@ -3,12 +3,11 @@ - - + + @@ -48,4 +47,4 @@ - + diff --git a/src/test/java/functional/WelcomeScreenTest.java b/src/test/java/functional/WelcomeScreenTest.java index 125cdca..406b6c5 100644 --- a/src/test/java/functional/WelcomeScreenTest.java +++ b/src/test/java/functional/WelcomeScreenTest.java @@ -2,6 +2,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import java.io.IOException; +import java.sql.SQLException; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; @@ -9,6 +11,8 @@ import javafx.stage.Stage; import openconsignment.common.AppConfig; import openconsignment.controller.WelcomeScreenController; +import openconsignment.di.DatabaseManager; +import openconsignment.repository.RepositoryTestSupport; import org.junit.jupiter.api.Test; import org.testfx.framework.junit5.ApplicationTest; @@ -16,8 +20,15 @@ class WelcomeScreenTest extends ApplicationTest { @Override public void start(Stage stage) throws Exception { FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/WelcomeScreen.fxml")); - loader.setControllerFactory( - type -> new WelcomeScreenController(AppConfig.forOrganization("Configured Organization"))); + loader.setControllerFactory(type -> { + try { + return new WelcomeScreenController( + AppConfig.forOrganization("Configured Organization"), + new DatabaseManager(RepositoryTestSupport.newInMemoryConnection())); + } catch (ClassNotFoundException | IOException | SQLException e) { + throw new RuntimeException(e); + } + }); Parent root = loader.load(); stage.setScene(new Scene(root)); stage.show(); diff --git a/src/test/java/openconsignment/di/ConfigurationModuleTest.java b/src/test/java/openconsignment/di/ConfigurationModuleTest.java index 0a09125..ee15ee2 100644 --- a/src/test/java/openconsignment/di/ConfigurationModuleTest.java +++ b/src/test/java/openconsignment/di/ConfigurationModuleTest.java @@ -30,7 +30,7 @@ void missingFileIsCopiedFromBundledResourceAndLoaded() throws IOException { AppConfig configuration = load(file); assertEquals(bundled, Files.readString(file)); - assertEquals(configuration.organizationName(), load(file).organizationName()); + assertEquals(configuration.getOrganization(), load(file).getOrganization()); } @Test @@ -42,33 +42,33 @@ void emptyExistingFileIsRejectedAndPreserved() throws IOException { } @Test - void loadsUtf8OrganizationNameAndTrimsWhitespace() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: \" Café Agencies \"\n"); + void loadsUtf8OrganizationAndTrimsWhitespace() throws IOException { + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: \" Café Agencies \"\n"); - assertEquals("Café Agencies", load(file).organizationName()); + assertEquals("Café Agencies", load(file).getOrganization()); } @Test void loadedConfigurationDoesNotChangeWhenFileIsEdited() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: First\n"); + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: First\n"); AppConfig configuration = load(file); - Files.writeString(file, "organizationName: Second\n"); + Files.writeString(file, "organization: Second\n"); - assertEquals("First", configuration.organizationName()); - assertEquals("Second", load(file).organizationName()); + assertEquals("First", configuration.getOrganization()); + assertEquals("Second", load(file).getOrganization()); } @Test - void rejectsBlankOrganizationName() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: \" \"\n"); + void rejectsBlankOrganization() throws IOException { + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: \" \"\n"); assertThrows(IllegalArgumentException.class, () -> load(file)); } @Test void rejectsMalformedYaml() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: [\n"); + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: [\n"); assertThrows(YAMLException.class, () -> load(file)); } @@ -83,16 +83,16 @@ void missingOrganizationNameIsRejectedWithoutBundledFallback() throws IOExceptio @Test void existingConfigurationIsLoadedWithoutBeingOverwritten() throws IOException { - String content = "# Custom settings\norganizationName: External Organization\n"; + String content = "# Custom settings\norganization: External Organization\n"; Path file = Files.writeString(tempDir.resolve("application.yaml"), content); - assertEquals("External Organization", load(file).organizationName()); + assertEquals("External Organization", load(file).getOrganization()); assertEquals(content, Files.readString(file)); } @Test void malformedConfigurationErrorIdentifiesSourceFile() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: [\n"); + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: [\n"); YAMLException error = assertThrows(YAMLException.class, () -> load(file)); @@ -134,14 +134,14 @@ void developmentRunUsesConfigurationInWorkingDirectory() throws IOException { @Test void bindsNumericScalarToStringProperty() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: 123\n"); + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: 123\n"); - assertEquals("123", load(file).organizationName()); + assertEquals("123", load(file).getOrganization()); } @Test void rejectsMappingOrganizationName() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: {name: Example}\n"); + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: {name: Example}\n"); assertThrows(YAMLException.class, () -> load(file)); } @@ -155,22 +155,22 @@ void rejectsNonMappingDocument() throws IOException { @Test void rejectsNullOrganizationName() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: null\n"); + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: null\n"); assertThrows(IllegalArgumentException.class, () -> load(file)); } @Test void rejectsEmptyOrganizationName() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: \"\"\n"); + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: \"\"\n"); assertThrows(IllegalArgumentException.class, () -> load(file)); } @Test void rejectsDuplicateKeys() throws IOException { - Path file = Files.writeString( - tempDir.resolve("application.yaml"), "organizationName: First\norganizationName: Second\n"); + Path file = + Files.writeString(tempDir.resolve("application.yaml"), "organization: First\norganization: Second\n"); assertThrows(YAMLException.class, () -> load(file)); } diff --git a/src/test/java/openconsignment/repository/BillRepositoryTest.java b/src/test/java/openconsignment/repository/BillRepositoryTest.java index 8347eae..19a8895 100644 --- a/src/test/java/openconsignment/repository/BillRepositoryTest.java +++ b/src/test/java/openconsignment/repository/BillRepositoryTest.java @@ -6,6 +6,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.List; +import openconsignment.di.DatabaseManager; import openconsignment.entity.BillEntity; import openconsignment.entity.LREntity; import org.junit.jupiter.api.AfterEach; @@ -20,7 +21,7 @@ class BillRepositoryTest { @BeforeEach void setUp() throws Exception { conn = RepositoryTestSupport.newInMemoryConnection(); - billRepository = new BillRepository(conn); + billRepository = new BillRepository(new DatabaseManager(conn)); } @AfterEach diff --git a/src/test/java/openconsignment/repository/BuyerRepositoryTest.java b/src/test/java/openconsignment/repository/BuyerRepositoryTest.java index 5cf9329..fa66dc6 100644 --- a/src/test/java/openconsignment/repository/BuyerRepositoryTest.java +++ b/src/test/java/openconsignment/repository/BuyerRepositoryTest.java @@ -5,6 +5,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.List; +import openconsignment.di.DatabaseManager; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -17,7 +18,7 @@ class BuyerRepositoryTest { @BeforeEach void setUp() throws Exception { conn = RepositoryTestSupport.newInMemoryConnection(); - buyerRepository = new BuyerRepository(conn); + buyerRepository = new BuyerRepository(new DatabaseManager(conn)); } @AfterEach diff --git a/src/test/java/openconsignment/repository/CollectionRepositoryTest.java b/src/test/java/openconsignment/repository/CollectionRepositoryTest.java index 31cf046..1b25160 100644 --- a/src/test/java/openconsignment/repository/CollectionRepositoryTest.java +++ b/src/test/java/openconsignment/repository/CollectionRepositoryTest.java @@ -6,6 +6,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.List; +import openconsignment.di.DatabaseManager; import openconsignment.entity.BillEntity; import openconsignment.entity.CollectionEntity; import openconsignment.entity.CollectionItemEntity; @@ -23,8 +24,8 @@ class CollectionRepositoryTest { @BeforeEach void setUp() throws Exception { conn = RepositoryTestSupport.newInMemoryConnection(); - collectionRepository = new CollectionRepository(conn); - billRepository = new BillRepository(conn); + collectionRepository = new CollectionRepository(new DatabaseManager(conn)); + billRepository = new BillRepository(new DatabaseManager(conn)); } @AfterEach diff --git a/src/test/java/openconsignment/repository/PaymentRepositoryTest.java b/src/test/java/openconsignment/repository/PaymentRepositoryTest.java index cbf797d..5e903ad 100644 --- a/src/test/java/openconsignment/repository/PaymentRepositoryTest.java +++ b/src/test/java/openconsignment/repository/PaymentRepositoryTest.java @@ -6,6 +6,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.List; +import openconsignment.di.DatabaseManager; import openconsignment.entity.BillEntity; import openconsignment.entity.PaymentEntity; import openconsignment.entity.PaymentItemEntity; @@ -23,8 +24,8 @@ class PaymentRepositoryTest { @BeforeEach void setUp() throws Exception { conn = RepositoryTestSupport.newInMemoryConnection(); - paymentRepository = new PaymentRepository(conn); - billRepository = new BillRepository(conn); + paymentRepository = new PaymentRepository(new DatabaseManager(conn)); + billRepository = new BillRepository(new DatabaseManager(conn)); } @AfterEach diff --git a/src/test/java/openconsignment/repository/RepositoryTestSupport.java b/src/test/java/openconsignment/repository/RepositoryTestSupport.java index 0fb52a2..4b892e6 100644 --- a/src/test/java/openconsignment/repository/RepositoryTestSupport.java +++ b/src/test/java/openconsignment/repository/RepositoryTestSupport.java @@ -8,11 +8,11 @@ import java.sql.Statement; import java.util.Objects; -final class RepositoryTestSupport { +public final class RepositoryTestSupport { private RepositoryTestSupport() {} - static Connection newInMemoryConnection() throws ClassNotFoundException, SQLException, IOException { + public static Connection newInMemoryConnection() throws ClassNotFoundException, SQLException, IOException { Class.forName("org.sqlite.JDBC"); Connection conn = DriverManager.getConnection("jdbc:sqlite::memory:"); try (Statement st = conn.createStatement()) { diff --git a/src/test/java/openconsignment/repository/SupplierRepositoryTest.java b/src/test/java/openconsignment/repository/SupplierRepositoryTest.java index e5efdfc..eaa5fb4 100644 --- a/src/test/java/openconsignment/repository/SupplierRepositoryTest.java +++ b/src/test/java/openconsignment/repository/SupplierRepositoryTest.java @@ -5,6 +5,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.List; +import openconsignment.di.DatabaseManager; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -17,7 +18,7 @@ class SupplierRepositoryTest { @BeforeEach void setUp() throws Exception { conn = RepositoryTestSupport.newInMemoryConnection(); - supplierRepository = new SupplierRepository(conn); + supplierRepository = new SupplierRepository(new DatabaseManager(conn)); } @AfterEach diff --git a/src/test/java/openconsignment/repository/TransportRepositoryTest.java b/src/test/java/openconsignment/repository/TransportRepositoryTest.java index b0b1165..3f480db 100644 --- a/src/test/java/openconsignment/repository/TransportRepositoryTest.java +++ b/src/test/java/openconsignment/repository/TransportRepositoryTest.java @@ -5,6 +5,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.List; +import openconsignment.di.DatabaseManager; import openconsignment.entity.BillEntity; import openconsignment.entity.LREntity; import openconsignment.model.TransportLedgerRow; @@ -21,8 +22,8 @@ class TransportRepositoryTest { @BeforeEach void setUp() throws Exception { conn = RepositoryTestSupport.newInMemoryConnection(); - transportRepository = new TransportRepository(conn); - billRepository = new BillRepository(conn); + transportRepository = new TransportRepository(new DatabaseManager(conn)); + billRepository = new BillRepository(new DatabaseManager(conn)); } @AfterEach