Conversation
WalkthroughThe pull request adds user authentication and interactive menu functionality to the application. A login flow with database credential verification is introduced, followed by a menu-driven command-line interface supporting account and mission management operations (list, retrieve, count, create, update, delete). Changes
Sequence DiagramsequenceDiagram
participant User
participant App as Main Application
participant DB as Database
User->>App: Start Application
App->>App: Initialize Scanner
rect rgb(200, 220, 255)
Note over User,DB: Login Phase
App->>User: Prompt for username/password
User->>App: Enter credentials
App->>DB: checkCredentials(username, password)
DB->>App: Query account table
App->>App: Verify credentials
alt Credentials Valid
App->>App: Set logged in state
else Credentials Invalid
App->>User: Display error
App->>App: Exit application
end
end
rect rgb(220, 255, 220)
Note over User,DB: Menu Loop Phase
loop Until Exit
App->>User: Display menu options
User->>App: Select operation
alt List Missions
App->>DB: Query all moon_missions
DB->>App: Return missions
App->>User: Display missions
else Get Mission by ID
User->>App: Provide mission ID
App->>DB: Query moon_missions WHERE id
DB->>App: Return mission
App->>User: Display mission details
else Count Missions
User->>App: Provide year
App->>DB: Count missions WHERE year
DB->>App: Return count
App->>User: Display count
else Manage Accounts
User->>App: Provide account details
App->>DB: INSERT/UPDATE/DELETE account
DB->>App: Confirm operation
App->>User: Display result
else Exit
App->>User: Goodbye
App->>App: End program
end
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Areas requiring extra attention:
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (8)
src/main/java/com/example/Main.java (8)
39-40: Consider consistent visibility and field placement.The
scannerfield is package-private whileexitAfterLoginis private. For consistency, consider making both private. Also, note that this Scanner wrapsSystem.inwhich is correct not to close (would close the underlying stream).- Scanner scanner = new Scanner(System.in); - private boolean exitAfterLogin = false; + private final Scanner scanner = new Scanner(System.in); + private boolean exitAfterLogin = false;
74-83: Consider explicit ResultSet closure with try-with-resources.While closing the
PreparedStatementdoes close itsResultSetper JDBC spec, explicit management is clearer and safer.private boolean checkCredentials(Connection connection, String user, String pass) throws SQLException { String sql = "SELECT 1 FROM account WHERE name=? AND password=?"; try (PreparedStatement ps = connection.prepareStatement(sql)) { ps.setString(1, user); ps.setString(2, pass); - return ps.executeQuery().next(); + try (ResultSet rs = ps.executeQuery()) { + return rs.next(); + } } }
135-151: Addstrip()to input and wrap ResultSet in try-with-resources.The
idinput is not stripped unlike other inputs in this file, and theResultSetshould be explicitly managed.private void getMissionById(Connection connection) throws SQLException { System.out.print("Mission id: "); - String id = scanner.nextLine(); + String id = scanner.nextLine().strip(); String sql = "SELECT * FROM moon_mission WHERE mission_id=?"; try (PreparedStatement ps = connection.prepareStatement(sql)) { ps.setString(1, id); - ResultSet rs = ps.executeQuery(); - while (rs.next()) { - for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) { - System.out.print(rs.getString(i) + " "); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) { + System.out.print(rs.getString(i) + " "); + } + System.out.println(); } - System.out.println(); } } }
153-166: Addstrip()to year input and wrap ResultSet.Same consistency improvements as suggested for
getMissionById.private void countMissionsByYear(Connection connection) throws SQLException { System.out.print("Year: "); - String year = scanner.nextLine(); + String year = scanner.nextLine().strip(); String sql = "SELECT COUNT(*) FROM moon_mission WHERE YEAR(launch_date)=?"; try (PreparedStatement ps = connection.prepareStatement(sql)) { ps.setString(1, year); - ResultSet rs = ps.executeQuery(); - if (rs.next()) { - System.out.println("Missions launched in " + year + ": " + rs.getInt(1)); + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + System.out.println("Missions launched in " + year + ": " + rs.getInt(1)); + } } } }
168-205: Wrap ResultSet in try-with-resources and note potential race condition.The
ResultSeton line 183 should be explicitly closed. Additionally, the check-then-insert pattern has a TOCTOU (time-of-check to time-of-use) race condition in concurrent scenarios. For this lab exercise it's likely acceptable, but in production you'd use a unique constraint with proper exception handling or useINSERT ... ON DUPLICATE KEY.String checkSql = "SELECT COUNT(*) FROM account WHERE name=? OR ssn=?"; try (PreparedStatement ps = connection.prepareStatement(checkSql)) { ps.setString(1, username); ps.setString(2, ssn); - ResultSet rs = ps.executeQuery(); - if (rs.next() && rs.getInt(1) > 0) { - System.out.println("Account already exists."); - return; + try (ResultSet rs = ps.executeQuery()) { + if (rs.next() && rs.getInt(1) > 0) { + System.out.println("Account already exists."); + return; + } } }
207-229: Strip the user id input and consider removing inconsistent prompt.Line 209 should use
.strip()for consistency. Also, lines 227-228 add a "Press Enter to continue" prompt that doesn't exist in other methods—consider removing for consistency or adding to all methods.private void updateAccountPassword(Connection connection) throws SQLException { System.out.print("User id: "); - String id = scanner.nextLine(); + String id = scanner.nextLine().strip(); if (!accountExists(connection, id)) { System.out.println("User not found."); return; } //Ask for a valid password ie not blank String newPassword = readRequired("New password"); String sql = "UPDATE account SET password=? WHERE user_id=?"; try (PreparedStatement ps = connection.prepareStatement(sql)) { ps.setString(1, newPassword); ps.setString(2, id); ps.executeUpdate(); } System.out.println("Password updated."); - System.out.println("Press Enter to continue"); - scanner.nextLine(); }
231-246: Strip the user id input for consistency.private void deleteAccount(Connection connection) throws SQLException { System.out.print("User id to delete: "); - String id = scanner.nextLine(); + String id = scanner.nextLine().strip();
248-254: Wrap ResultSet in try-with-resources for explicit closure.Same pattern as
checkCredentials—consider explicit ResultSet management.private boolean accountExists(Connection connection, String id) throws SQLException { String sql = "SELECT 1 FROM account WHERE user_id=?"; try (PreparedStatement ps = connection.prepareStatement(sql)) { ps.setString(1, id); - return ps.executeQuery().next(); + try (ResultSet rs = ps.executeQuery()) { + return rs.next(); + } } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
README.md(1 hunks)src/main/java/com/example/DevDatabaseInitializer.java(1 hunks)src/main/java/com/example/Main.java(3 hunks)
🔇 Additional comments (4)
src/main/java/com/example/DevDatabaseInitializer.java (1)
24-24: LGTM!Trailing newline addition is a minor formatting improvement with no functional impact.
README.md (1)
1-1: LGTM!GitHub Classroom badge addition is appropriate for this repository.
src/main/java/com/example/Main.java (2)
256-265: LGTM!Good implementation of required input validation with clear user feedback. This correctly addresses the PR objective of preventing blank passwords.
85-106: LGTM!Clean switch expression syntax for menu handling. The menu loop logic is well-structured.
Fixade några saker som CodeRabbit klagade på.
Mer kommentarer till koden, var typ ingen innan.
Fixade en check så att nya password inte kan vara blankt
Summary by CodeRabbit
New Features
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.