Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ Keep the JAR and launch script together when moving the application.

- The application creates and initializes `database.db` in its working
directory using `src/main/resources/sql/init.sql`.
- Repository queries live in domain-specific folders under
`src/main/resources/sql` (for example, `bill/get.sql`). Paths are registered
in the `SqlQuery` enum and loaded with `SqlLoader.load(SqlQuery.BILL_GET)`,
using UTF-8 decoding and caching. When adding a query, add its SQL file and
enum entry; tests verify that every entry has a non-empty resource.
- Running `./gradlew run` uses the repository root; the packaged launch
commands above use `build/libs/`. Each location has its own database.
- Reports are written to `report.pdf` in the working directory, replacing
Expand Down
39 changes: 39 additions & 0 deletions src/main/java/openconsignment/common/SqlLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package openconsignment.common;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public final class SqlLoader {

private static final Map<SqlQuery, String> CACHE = new ConcurrentHashMap<>();

private SqlLoader() {}

/** Loads and caches the UTF-8 SQL resource registered for the query. */
public static String load(SqlQuery query) throws SQLException {
String cachedSql = CACHE.get(query);
if (cachedSql != null) {
return cachedSql;
}

String sql = readResource(query.resourcePath());
String previousSql = CACHE.putIfAbsent(query, sql);
return previousSql != null ? previousSql : sql;
}

static String readResource(String name) throws SQLException {
String path = "/sql/" + name;
try (InputStream stream = SqlLoader.class.getResourceAsStream(path)) {
if (stream == null) {
throw new SQLException("SQL resource not found: " + path);
}
return new String(stream.readAllBytes(), StandardCharsets.UTF_8);
} catch (IOException ex) {
throw new SQLException("Failed to read SQL resource: " + path, ex);
}
}
}
62 changes: 62 additions & 0 deletions src/main/java/openconsignment/common/SqlQuery.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package openconsignment.common;

/** Catalog of repository SQL resources, with paths relative to the classpath's /sql directory. */
public enum SqlQuery {
BILL_SAVE("bill/save.sql"),
BILL_SAVE_LR("bill/save-lr.sql"),
BILL_GET("bill/get.sql"),
BILL_GET_LRS("bill/get-lrs.sql"),
BILL_DELETE("bill/delete.sql"),
BILL_DELETE_LRS("bill/delete-lrs.sql"),
BILL_GET_ALL("bill/get-all.sql"),

BUYER_SAVE("buyer/save.sql"),
BUYER_DELETE("buyer/delete.sql"),
BUYER_RENAME("buyer/rename.sql"),
BUYER_GET_ALL("buyer/get-all.sql"),

COLLECTION_PENDING_BILLS_FOR_BUYER("collection/pending-bills-for-buyer.sql"),
COLLECTION_PENDING_AMOUNT_FOR_BILL("collection/pending-amount-for-bill.sql"),
COLLECTION_SAVE("collection/save.sql"),
COLLECTION_SAVE_ITEM("collection/save-item.sql"),
COLLECTION_LAST_VOUCHER("collection/last-voucher.sql"),
COLLECTION_GET_ITEMS("collection/get-items.sql"),
COLLECTION_GET("collection/get.sql"),
COLLECTION_DELETE("collection/delete.sql"),
COLLECTION_DELETE_ITEMS("collection/delete-items.sql"),
COLLECTION_GET_ALL("collection/get-all.sql"),
COLLECTION_DETAILS_FOR_BUYER("collection/details-for-buyer.sql"),

PAYMENT_SAVE("payment/save.sql"),
PAYMENT_SAVE_ITEM("payment/save-item.sql"),
PAYMENT_PENDING_BILLS_FOR_SUPPLIER("payment/pending-bills-for-supplier.sql"),
PAYMENT_PENDING_AMOUNT_FOR_BILL("payment/pending-amount-for-bill.sql"),
PAYMENT_LAST_VOUCHER("payment/last-voucher.sql"),
PAYMENT_GET_ITEMS("payment/get-items.sql"),
PAYMENT_GET("payment/get.sql"),
PAYMENT_DELETE("payment/delete.sql"),
PAYMENT_DELETE_ITEMS("payment/delete-items.sql"),
PAYMENT_GET_ALL("payment/get-all.sql"),
PAYMENT_DETAILS_FOR_SUPPLIER("payment/details-for-supplier.sql"),

SUPPLIER_SAVE("supplier/save.sql"),
SUPPLIER_DELETE("supplier/delete.sql"),
SUPPLIER_RENAME("supplier/rename.sql"),
SUPPLIER_GET_ALL("supplier/get-all.sql"),

TRANSPORT_SAVE("transport/save.sql"),
TRANSPORT_DELETE("transport/delete.sql"),
TRANSPORT_RENAME("transport/rename.sql"),
TRANSPORT_GET_ALL("transport/get-all.sql"),
TRANSPORT_REPORT("transport/report.sql");

private final String resourcePath;

SqlQuery(String resourcePath) {
this.resourcePath = resourcePath;
}

public String resourcePath() {
return resourcePath;
}
}
22 changes: 9 additions & 13 deletions src/main/java/openconsignment/repository/BillRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
import openconsignment.common.SqlLoader;
import openconsignment.common.SqlQuery;
import openconsignment.entity.BillEntity;
import openconsignment.entity.LREntity;

Expand All @@ -23,13 +25,7 @@ public BillRepository(Connection conn) {

public void save(BillEntity billEntity) throws SQLException {
try {
// language=sql
String sql =
"INSERT INTO `Bill_Entry_Table`(`Supplier Name`,`Buyer Name`,`Bill No.`,`Bill Date`,`Transport`,`LR Date`,`Bill Amount`,`Collection Due`,`Due`) "
+ "VALUES (?,?,?,?,?,?,?,?,?) ON CONFLICT(`Bill No.`) DO UPDATE SET "
+ "`Supplier Name`=excluded.`Supplier Name`, `Buyer Name`=excluded.`Buyer Name`, `Bill Date`=excluded.`Bill Date`, "
+ "`Transport`=excluded.`Transport`, `LR Date`=excluded.`LR Date`, `Bill Amount`=excluded.`Bill Amount`, "
+ "`Collection Due`=excluded.`Collection Due`, `Due`=excluded.`Due`;";
String sql = SqlLoader.load(SqlQuery.BILL_SAVE);

conn.setAutoCommit(false);

Expand All @@ -49,7 +45,7 @@ public void save(BillEntity billEntity) throws SQLException {

if (null != billEntity.getLrEntities()) {
for (LREntity lr : billEntity.getLrEntities()) {
sql = "INSERT INTO `LR_Table`(`Bill No.`,`LR No.`,`PM`) VALUES (?,?,?)";
sql = SqlLoader.load(SqlQuery.BILL_SAVE_LR);
preparedStatement = conn.prepareStatement(sql);
preparedStatement.setString(1, billEntity.getBillNo());
preparedStatement.setString(2, lr.getLrNo());
Expand All @@ -67,7 +63,7 @@ public void save(BillEntity billEntity) throws SQLException {

public BillEntity getBill(String billNo) throws SQLException {
try {
String sql = "select * from `Bill_Entry_Table` where `Bill No.`=? collate nocase";
String sql = SqlLoader.load(SqlQuery.BILL_GET);
PreparedStatement preparedStatement = conn.prepareStatement(sql);
preparedStatement.setString(1, billNo);
ResultSet billResultSet = preparedStatement.executeQuery();
Expand All @@ -86,7 +82,7 @@ public BillEntity getBill(String billNo) throws SQLException {
.billAmount(billResultSet.getString("Bill Amount"))
.build();

sql = "select * from `LR_Table` where `Bill No.`=? collate nocase";
sql = SqlLoader.load(SqlQuery.BILL_GET_LRS);
preparedStatement = conn.prepareStatement(sql);
preparedStatement.setString(1, billNo);
ResultSet lrPmResultSet = preparedStatement.executeQuery();
Expand All @@ -110,12 +106,12 @@ public BillEntity getBill(String billNo) throws SQLException {
public void deleteBill(String billNo) throws SQLException {
try {
conn.setAutoCommit(false);
String sql = "DELETE FROM `Bill_Entry_Table` where `Bill No.`=? collate nocase";
String sql = SqlLoader.load(SqlQuery.BILL_DELETE);
PreparedStatement preparedStatement = conn.prepareStatement(sql);
preparedStatement.setString(1, billNo);
preparedStatement.execute();

String sql2 = "DELETE FROM `LR_Table` where `Bill No.`=? collate nocase";
String sql2 = SqlLoader.load(SqlQuery.BILL_DELETE_LRS);
preparedStatement = conn.prepareStatement(sql2);
preparedStatement.setString(1, billNo);
preparedStatement.execute();
Expand All @@ -131,7 +127,7 @@ public void deleteBill(String billNo) throws SQLException {
public List<BillEntity> getBills() throws SQLException {
List<BillEntity> res = new ArrayList<>();
try {
String sql = "SELECT * FROM `Bill_Entry_Table`;";
String sql = SqlLoader.load(SqlQuery.BILL_GET_ALL);
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Expand Down
11 changes: 6 additions & 5 deletions src/main/java/openconsignment/repository/BuyerRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
import openconsignment.common.SqlLoader;
import openconsignment.common.SqlQuery;

public class BuyerRepository {

Expand All @@ -21,7 +23,7 @@ public BuyerRepository(Connection conn) {

public void saveBuyer(String buyerName) throws SQLException {
try {
String sql = "INSERT INTO `Buyer_Master_Table`(`Name`) VALUES (?);";
String sql = SqlLoader.load(SqlQuery.BUYER_SAVE);
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, buyerName);
ps.execute();
Expand All @@ -33,7 +35,7 @@ public void saveBuyer(String buyerName) throws SQLException {

public void deleteBuyer(String buyerName) throws SQLException {
try {
String sql = "DELETE FROM `Buyer_Master_Table` WHERE name=?";
String sql = SqlLoader.load(SqlQuery.BUYER_DELETE);
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, buyerName);
ps.execute();
Expand All @@ -45,7 +47,7 @@ public void deleteBuyer(String buyerName) throws SQLException {

public void renameBuyer(String oldName, String newName) throws SQLException {
try {
String sql = "UPDATE `Buyer_Master_Table` SET Name=? WHERE Name=?";
String sql = SqlLoader.load(SqlQuery.BUYER_RENAME);
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, newName);
ps.setString(2, oldName);
Expand All @@ -59,8 +61,7 @@ public void renameBuyer(String oldName, String newName) throws SQLException {
public List<String> getAllBuyers() throws SQLException {
try {
List<String> buyerList = new ArrayList<>();
ResultSet buyerResultSet = conn.prepareStatement(
"select * from Buyer_Master_Table order by name collate nocase")
ResultSet buyerResultSet = conn.prepareStatement(SqlLoader.load(SqlQuery.BUYER_GET_ALL))
.executeQuery();
while (buyerResultSet.next()) {
buyerList.add(buyerResultSet.getString("name"));
Expand Down
Loading
Loading