Skip to content

Laboration3#19

Open
mattiasbarth wants to merge 5 commits intomainfrom
laboration3
Open

Laboration3#19
mattiasbarth wants to merge 5 commits intomainfrom
laboration3

Conversation

@mattiasbarth
Copy link

@mattiasbarth mattiasbarth commented Dec 14, 2025

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

  • Added user login with credential verification
  • Introduced interactive menu system for account and mission management
  • Added operations to list, retrieve, count, create, update, and delete accounts

Documentation

  • Updated README with badge link

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 14, 2025

Walkthrough

The 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

Cohort / File(s) Summary
Documentation
README.md
Added Markdown badge link line at the top of the document.
Formatting
src/main/java/com/example/DevDatabaseInitializer.java
Added trailing newline at end of file.
Core Application Logic
src/main/java/com/example/Main.java
Consolidated imports; introduced runApplication flow replacing previous placeholder; added login credential verification against database with failed-login exit option; implemented menu-driven interface with list, retrieve, count, create, update, and delete operations for accounts and missions; added Scanner-based input mechanism and exitAfterLogin state; introduced helper methods for login, credential checking, menu loop, menu display, mission queries, account management, and input reading; implemented database interactions using PreparedStatements.

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Areas requiring extra attention:

  • Database interaction correctness and PreparedStatement parameter binding in login and CRUD operations
  • Input validation and error handling for user-supplied data (username, password, account fields)
  • SQL injection prevention (verify all queries use parameterized statements)
  • Password handling practices and whether credentials are properly validated against database records
  • Menu loop logic and state management for the exitAfterLogin flag and exit conditions

Poem

🐰 A login screen hops into view,
Credentials checked, credentials true!
Menus bloom with options bright,
CRUD operations left and right,
Moon missions dance in database light! 🌙

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Laboration3' is vague and generic, providing no meaningful information about the actual changes (login flow, menu interface, database interactions, README updates). Consider a more descriptive title such as 'Add user login and account management interface' or 'Implement database-driven login and CRUD operations for accounts' to clearly communicate the main changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (8)
src/main/java/com/example/Main.java (8)

39-40: Consider consistent visibility and field placement.

The scanner field is package-private while exitAfterLogin is private. For consistency, consider making both private. Also, note that this Scanner wraps System.in which 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 PreparedStatement does close its ResultSet per 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: Add strip() to input and wrap ResultSet in try-with-resources.

The id input is not stripped unlike other inputs in this file, and the ResultSet should 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: Add strip() 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 ResultSet on 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 use INSERT ... 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

📥 Commits

Reviewing files that changed from the base of the PR and between e629e94 and 28f4bde.

📒 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant