> testLogRecords = lookupLogRecordsForClass(OutputWorker.class);
+
+ Assertions.assertFalse(testLogRecords
+ .stream()
+ .anyMatch(logRecord -> logRecord
+ .message()
+ .equals(userLoggedInMessage.toString())));
}
}
diff --git a/shared/src/main/java/com/fagi/db/LogBasedDatabase.java b/shared/src/main/java/com/fagi/db/LogBasedDatabase.java
index 9c369048..b4aeda95 100644
--- a/shared/src/main/java/com/fagi/db/LogBasedDatabase.java
+++ b/shared/src/main/java/com/fagi/db/LogBasedDatabase.java
@@ -1,7 +1,16 @@
package com.fagi.db;
-import java.io.*;
-import java.util.*;
+import com.fagi.logging.FagiLogger;
+import com.fagi.logging.FagiLoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -70,8 +79,8 @@
* Error Handling:
* The database handles various error conditions gracefully:
*
- * - Corrupted Log entries are skipped with warnings to stderr
- * - Malformed entries are ignored during startup
+ * - Corrupted Log entries are skipped with warnings logged to WARNING
+ * - Malformed entries are ignored during startup and logged to WARNING
* - I/O errors during writes throw RuntimeException
*
*
@@ -87,6 +96,7 @@
* @see com.fagi.utility.Checksum
*/
public class LogBasedDatabase implements AutoCloseable {
+ private static final FagiLogger LOGGER = FagiLoggerFactory.createLogger(LogBasedDatabase.class);
enum DBOperation {
PUT,
@@ -125,11 +135,11 @@ enum DBOperation {
*
* @param filePath the path to the database Log file, must not be null
* @throws DatabaseInitializeException if the database cannot be initialized due to:
- *
- * - I/O errors when creating/opening the Log file
- * - Permission issue with the file or directory
- * - Corruption in the existing Log file that prevents loading
- *
+ *
+ * - I/O errors when creating/opening the Log file
+ * - Permission issue with the file or directory
+ * - Corruption in the existing Log file that prevents loading
+ *
*/
public LogBasedDatabase(String filePath) throws DatabaseInitializeException {
this.logFilePath = filePath;
@@ -144,7 +154,10 @@ public LogBasedDatabase(String filePath) throws DatabaseInitializeException {
loadFromLog();
} catch (IOException e) {
close();
- throw new DatabaseInitializeException("Failed to initialize database", e);
+ throw new DatabaseInitializeException(
+ "Failed to initialize database",
+ e
+ );
} catch (DatabaseInitializeException e) {
close();
throw e;
@@ -158,14 +171,14 @@ public LogBasedDatabase(String filePath) throws DatabaseInitializeException {
* It bypasses normal file initialization and error handling. The provided
* FileWriter must be properly configured for append mode.
*
- * @param filePath the path to the database log file, used for identification
+ * @param filePath the path to the database log file, used for identification
* @param logWriter the FileWriter to use for logging operations, must not be null
* @throws DatabaseInitializeException if the database cannot be initialized due to:
- *
- * - I/O errors when creating/opening the Log file
- * - Permission issue with the file or directory
- * - Corruption in the existing Log file that prevents loading
- *
+ *
+ * - I/O errors when creating/opening the Log file
+ * - Permission issue with the file or directory
+ * - Corruption in the existing Log file that prevents loading
+ *
*/
public LogBasedDatabase(
String filePath,
@@ -190,14 +203,12 @@ public LogBasedDatabase(
* Performance: O(1) time complexity. Constant time regardless
* of database size.
*
- * @param id the record identifier, must not be null
- * @param key the field key, must not be null
+ * @param id the record identifier, must not be null
+ * @param key the field key, must not be null
* @param value the field value, must not be null
* @throws IllegalArgumentException if any parameter is null
- * @throws DatabaseUpdateException if the write operation fails due to I/O errors
- *
- * @snippet
- * {@code
+ * @throws DatabaseUpdateException if the write operation fails due to I/O errors
+ * @snippet {@code
* db.put("user123", "name", "Alice");
* db.put("user123", "email", "alice@example.com");
* db.put("user123", "status", "active");
@@ -245,13 +256,11 @@ public void put(
*
* Performance: O(1) time complexity. Direct hash map lookup.
*
- * @param id the record identifier to look up, must not be null
+ * @param id the record identifier to look up, must not be null
* @param key the field key to retrieve, must not be null
* @return the field value, or {@code null} if the record or field doesn't exist
* @throws IllegalArgumentException if the id or key is null
- *
- * @snippet
- * {@code
+ * @snippet {@code
* String email = db.get("user123", "email"); // Returns "alice@example.com" or null
* String phone = db.get("user123", "phone"); // Returns null if field doesn't exist
* String name = db.get("nonexistent", "name"); // Returns null if record doesn't exist
@@ -288,8 +297,7 @@ public String get(
* @param id the record identifier to retrieve, must not be null
* @return a copy of all fields for the record, or {@code null} if the record doesn't exist
* @throws IllegalArgumentException if id is null
- * @snippet
- * {@code
+ * @snippet {@code
* Map user = db.get("user123");
* if (user != null) {
* String name = user.get("name"); // "Alice Johnson"
@@ -344,7 +352,8 @@ private void loadFromLog() throws DatabaseInitializeException {
String[] parts = line.split("\\|");
if (parts.length < 5) {
- System.err.println("Malformed entry at line " + lineNumber);
+ int malformedLine = lineNumber;
+ LOGGER.warning(() -> "Malformed entry at line " + malformedLine);
continue;
}
@@ -358,7 +367,8 @@ private void loadFromLog() throws DatabaseInitializeException {
);
if (!calculateChecksum(originalEntry).equals(storedChecksum)) {
- System.err.println("Corruption detected at line " + lineNumber);
+ int corruptLine = lineNumber;
+ LOGGER.warning(() -> "Corruption detected at line " + corruptLine);
continue;
}
@@ -405,9 +415,9 @@ private void processLogEntry(String[] parts) {
* Appends an operation to the Log file with checksum verification.
*
* @param operation the operator type (e.g. "PUT")
- * @param id the record identifier
- * @param key the field key
- * @param value the field value
+ * @param id the record identifier
+ * @param key the field key
+ * @param value the field value
* @throws DatabaseUpdateException if the write operations fails
*/
private void appendToLog(
@@ -450,14 +460,12 @@ private void appendToLog(
* Performance: O(n) where n is the total number of records.
* Performance degrades linearly with database size.
*
- * @param fieldName the name of the field to match against, must not be null
+ * @param fieldName the name of the field to match against, must not be null
* @param fieldValue the value to search for, must not be null
* @return a List or records (as maps) that contain the specified field-value pair,
- * empty List if no matches found, never null
+ * empty List if no matches found, never null
* @throws IllegalArgumentException if fieldName or fieldValue is null
- *
- * @snippet
- * {@code
+ * @snippet {@code
* // Find all active users
* List
*/
@@ -499,15 +507,13 @@ public List