Skip to content
Open
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
65 changes: 31 additions & 34 deletions src/library/assistant/database/DatabaseHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ public final class DatabaseHandler {

private static final String DB_URL = "jdbc:derby:database;create=true";
private static Connection conn = null;
private static Statement stmt = null;

static {
createConnection();
Expand Down Expand Up @@ -109,39 +108,42 @@ private static void readDBTable(Set<String> set, DatabaseMetaData dbmeta, String
}

public ResultSet execQuery(String query) {
ResultSet result;
Statement stmt = null;
ResultSet result = null;
try {
stmt = conn.createStatement();
result = stmt.executeQuery(query);
stmt.closeOnCompletion();
}
catch (SQLException ex) {
System.out.println("Exception at execQuery:dataHandler" + ex.getLocalizedMessage());
LOGGER.log(Level.ERROR, "Exception at execQuery:dataHandler {}", ex.getLocalizedMessage());
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
LOGGER.log(Level.ERROR, "{}", e);
}
}
return null;
}
finally {
}
return result;
}

public boolean execAction(String qu) {
try {
stmt = conn.createStatement();
try (Statement stmt = conn.createStatement()) {
stmt.execute(qu);
return true;
}
catch (SQLException ex) {
JOptionPane.showMessageDialog(null, "Error:" + ex.getMessage(), "Error Occured", JOptionPane.ERROR_MESSAGE);
System.out.println("Exception at execQuery:dataHandler" + ex.getLocalizedMessage());
LOGGER.log(Level.ERROR, "Exception at execAction:dataHandler {}", ex.getLocalizedMessage());
return false;
}
finally {
}
}

public boolean deleteBook(Book book) {
try {
String deleteStatement = "DELETE FROM BOOK WHERE ID = ?";
PreparedStatement stmt = conn.prepareStatement(deleteStatement);
String deleteStatement = "DELETE FROM BOOK WHERE ID = ?";
try (PreparedStatement stmt = conn.prepareStatement(deleteStatement)) {
stmt.setString(1, book.getId());
int res = stmt.executeUpdate();
if (res == 1) {
Expand All @@ -155,9 +157,8 @@ public boolean deleteBook(Book book) {
}

public boolean isBookAlreadyIssued(Book book) {
try {
String checkstmt = "SELECT COUNT(*) FROM ISSUE WHERE bookid=?";
PreparedStatement stmt = conn.prepareStatement(checkstmt);
String checkstmt = "SELECT COUNT(*) FROM ISSUE WHERE bookid=?";
try (PreparedStatement stmt = conn.prepareStatement(checkstmt)) {
stmt.setString(1, book.getId());
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
Expand All @@ -173,9 +174,8 @@ public boolean isBookAlreadyIssued(Book book) {
}

public boolean deleteMember(MemberListController.Member member) {
try {
String deleteStatement = "DELETE FROM MEMBER WHERE id = ?";
PreparedStatement stmt = conn.prepareStatement(deleteStatement);
String deleteStatement = "DELETE FROM MEMBER WHERE id = ?";
try (PreparedStatement stmt = conn.prepareStatement(deleteStatement)) {
stmt.setString(1, member.getId());
int res = stmt.executeUpdate();
if (res == 1) {
Expand All @@ -189,9 +189,8 @@ public boolean deleteMember(MemberListController.Member member) {
}

public boolean isMemberHasAnyBooks(MemberListController.Member member) {
try {
String checkstmt = "SELECT COUNT(*) FROM ISSUE WHERE memberID=?";
PreparedStatement stmt = conn.prepareStatement(checkstmt);
String checkstmt = "SELECT COUNT(*) FROM ISSUE WHERE memberID=?";
try (PreparedStatement stmt = conn.prepareStatement(checkstmt)) {
stmt.setString(1, member.getId());
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
Expand All @@ -207,9 +206,8 @@ public boolean isMemberHasAnyBooks(MemberListController.Member member) {
}

public boolean updateBook(Book book) {
try {
String update = "UPDATE BOOK SET TITLE=?, AUTHOR=?, PUBLISHER=? WHERE ID=?";
PreparedStatement stmt = conn.prepareStatement(update);
String update = "UPDATE BOOK SET TITLE=?, AUTHOR=?, PUBLISHER=? WHERE ID=?";
try (PreparedStatement stmt = conn.prepareStatement(update)) {
stmt.setString(1, book.getTitle());
stmt.setString(2, book.getAuthor());
stmt.setString(3, book.getPublisher());
Expand All @@ -224,9 +222,8 @@ public boolean updateBook(Book book) {
}

public boolean updateMember(MemberListController.Member member) {
try {
String update = "UPDATE MEMBER SET NAME=?, EMAIL=?, MOBILE=? WHERE ID=?";
PreparedStatement stmt = conn.prepareStatement(update);
String update = "UPDATE MEMBER SET NAME=?, EMAIL=?, MOBILE=? WHERE ID=?";
try (PreparedStatement stmt = conn.prepareStatement(update)) {
stmt.setString(1, member.getName());
stmt.setString(2, member.getEmail());
stmt.setString(3, member.getMobile());
Expand Down Expand Up @@ -289,13 +286,13 @@ public ObservableList<PieChart.Data> getMemberGraphStatistics() {
}

private static void createTables(List<String> tableData) throws SQLException {
Statement statement = conn.createStatement();
statement.closeOnCompletion();
for (String command : tableData) {
System.out.println(command);
statement.addBatch(command);
try (Statement statement = conn.createStatement()) {
for (String command : tableData) {
System.out.println(command);
statement.addBatch(command);
}
statement.executeBatch();
}
statement.executeBatch();
}

public Connection getConnection() {
Expand Down
78 changes: 78 additions & 0 deletions test/library/assistant/database/DatabaseHandlerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package library.assistant.database;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class DatabaseHandlerTest {

@Mock
private Connection mockConnection;

@Mock
private Statement mockStatement;

@Mock
private ResultSet mockResultSet;

@Test
public void testExecQueryClosesStatementOnCompletion() throws Exception {
// Setup mock behavior
when(mockConnection.createStatement()).thenReturn(mockStatement);
when(mockStatement.executeQuery(anyString())).thenReturn(mockResultSet);

// Get instance (it's a singleton)
// This will trigger static initialization. Ensure libs are in classpath.
DatabaseHandler handler = DatabaseHandler.getInstance();

// Inject mock connection via reflection
Field connField = DatabaseHandler.class.getDeclaredField("conn");
connField.setAccessible(true);
connField.set(null, mockConnection); // static field

// Execute query
ResultSet rs = handler.execQuery("SELECT * FROM TEST");

// Verify statement creation and execution
verify(mockConnection).createStatement();
verify(mockStatement).executeQuery("SELECT * FROM TEST");

// Verify closeOnCompletion is called
verify(mockStatement).closeOnCompletion();
}

@Test
public void testExecActionClosesStatement() throws Exception {
// Setup mock behavior
when(mockConnection.createStatement()).thenReturn(mockStatement);
when(mockStatement.execute(anyString())).thenReturn(true);

// Get instance
DatabaseHandler handler = DatabaseHandler.getInstance();

// Inject mock connection via reflection
Field connField = DatabaseHandler.class.getDeclaredField("conn");
connField.setAccessible(true);
connField.set(null, mockConnection);

// Execute action
handler.execAction("UPDATE TEST SET A=1");

// Verify statement creation and execution
verify(mockConnection).createStatement();
verify(mockStatement).execute("UPDATE TEST SET A=1");

// Verify close is called
verify(mockStatement).close();
}
}