-
Notifications
You must be signed in to change notification settings - Fork 59
Labb3 #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Labb3 #9
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,3 +22,4 @@ public static void start() { | |
| } | ||
| } | ||
| } | ||
| // klar | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,36 +1,222 @@ | ||||||||||||||||||||||
| package com.example; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| import com.example.datasource.SimpleDriverManagerDataSource; | ||||||||||||||||||||||
| import com.example.model.Account; | ||||||||||||||||||||||
| import com.example.model.MoonMission; | ||||||||||||||||||||||
| import com.example.repository.AccountRepository; | ||||||||||||||||||||||
| import com.example.repository.JdbcAccountRepository; | ||||||||||||||||||||||
| import com.example.repository.JdbcMoonMissionRepository; | ||||||||||||||||||||||
| import com.example.repository.MoonMissionRepository; | ||||||||||||||||||||||
| import org.testcontainers.shaded.org.checkerframework.checker.units.qual.A; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| import javax.sql.DataSource; | ||||||||||||||||||||||
| import java.sql.Connection; | ||||||||||||||||||||||
| import java.sql.DriverManager; | ||||||||||||||||||||||
| import java.sql.SQLException; | ||||||||||||||||||||||
| import java.sql.SQLOutput; | ||||||||||||||||||||||
| import java.util.Arrays; | ||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||
| import java.util.Optional; | ||||||||||||||||||||||
| import java.util.Scanner; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| public class Main { | ||||||||||||||||||||||
| private final AccountRepository accountRepository; | ||||||||||||||||||||||
| private final MoonMissionRepository missionRepository; | ||||||||||||||||||||||
| private final Scanner scanner; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| public Main(AccountRepository accountRepository, MoonMissionRepository missionRepository) { | ||||||||||||||||||||||
| this.accountRepository = accountRepository; | ||||||||||||||||||||||
| this.missionRepository = missionRepository; | ||||||||||||||||||||||
| this.scanner = new Scanner(System.in); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| public static void main(String[] args) { | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| static void main(String[] args) { | ||||||||||||||||||||||
| if (isDevMode(args)) { | ||||||||||||||||||||||
| DevDatabaseInitializer.start(); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| new Main().run(); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| public void run() { | ||||||||||||||||||||||
| // Resolve DB settings with precedence: System properties -> Environment variables | ||||||||||||||||||||||
| public Main() { | ||||||||||||||||||||||
| String jdbcUrl = resolveConfig("APP_JDBC_URL", "APP_JDBC_URL"); | ||||||||||||||||||||||
| String dbUser = resolveConfig("APP_DB_USER", "APP_DB_USER"); | ||||||||||||||||||||||
| String dbPass = resolveConfig("APP_DB_PASS", "APP_DB_PASS"); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (jdbcUrl == null || dbUser == null || dbPass == null) { | ||||||||||||||||||||||
| throw new IllegalStateException( | ||||||||||||||||||||||
| "Missing DB configuration. Provide APP_JDBC_URL, APP_DB_USER, APP_DB_PASS " + | ||||||||||||||||||||||
| "as system properties (-Dkey=value) or environment variables."); | ||||||||||||||||||||||
| "Missing DB configuration. Provide APP_JDBC_URL, APP_DB_USER, APP_DB_PASS \" +\n" + | ||||||||||||||||||||||
| "\"as system properties (-Dkey=value) or environment variables.\""); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
46
to
49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Malformed exception message with literal The string concatenation creates a malformed message with a literal if (jdbcUrl == null || dbUser == null || dbPass == null) {
throw new IllegalStateException(
- "Missing DB configuration. Provide APP_JDBC_URL, APP_DB_USER, APP_DB_PASS \" +\n" +
- "\"as system properties (-Dkey=value) or environment variables.\"");
+ "Missing DB configuration. Provide APP_JDBC_URL, APP_DB_USER, APP_DB_PASS " +
+ "as system properties (-Dkey=value) or environment variables.");
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| try (Connection connection = DriverManager.getConnection(jdbcUrl, dbUser, dbPass)) { | ||||||||||||||||||||||
| System.out.println("✓ Database connection successful!"); | ||||||||||||||||||||||
| } catch (SQLException e) { | ||||||||||||||||||||||
| throw new RuntimeException(e); | ||||||||||||||||||||||
| throw new RuntimeException("Failed to connect to database. Check your configuration.", e); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| DataSource dataSource = new SimpleDriverManagerDataSource(jdbcUrl, dbUser, dbPass); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| this.accountRepository = new JdbcAccountRepository(dataSource); | ||||||||||||||||||||||
| this.missionRepository = new JdbcMoonMissionRepository(dataSource); | ||||||||||||||||||||||
| this.scanner = new Scanner(System.in); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| public void run() { | ||||||||||||||||||||||
| System.out.println("=== Moon Mission Database === \n"); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (!login()) { | ||||||||||||||||||||||
| System.out.println("Login invalid. Exiting..."); | ||||||||||||||||||||||
| return; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| boolean running = true; | ||||||||||||||||||||||
| while (running) { | ||||||||||||||||||||||
| printMenu(); | ||||||||||||||||||||||
| int choice = getIntInput(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| switch (choice) { | ||||||||||||||||||||||
| case 1 -> listMoonMissions(); | ||||||||||||||||||||||
| case 2 -> getMissionById(); | ||||||||||||||||||||||
| case 3 -> countMissionsByYear(); | ||||||||||||||||||||||
| case 4 -> createAccount(); | ||||||||||||||||||||||
| case 5 -> updateAccountPassword(); | ||||||||||||||||||||||
| case 6 -> deleteAccount(); | ||||||||||||||||||||||
| case 0 -> { | ||||||||||||||||||||||
| running = false; | ||||||||||||||||||||||
| System.out.println("Goodbye!"); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| default -> System.out.println("Invalid option!"); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| scanner.close(); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| private boolean login() { | ||||||||||||||||||||||
| System.out.print("Username: "); | ||||||||||||||||||||||
| String username = scanner.nextLine().trim(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| System.out.print("Password: "); | ||||||||||||||||||||||
| String password = scanner.nextLine().trim(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Optional<Account> accountOpt = accountRepository.findByUsernameAndPassword(username, password); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (accountOpt.isPresent()) { | ||||||||||||||||||||||
| Account account = accountOpt.get(); | ||||||||||||||||||||||
| System.out.println("✓ Login successful! Welcome, " + account.name() + "\n"); | ||||||||||||||||||||||
| return true; | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| System.out.println("Invalid username or password."); | ||||||||||||||||||||||
| return false; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| private void printMenu() { | ||||||||||||||||||||||
| System.out.println("\n=== Menu ==="); | ||||||||||||||||||||||
| System.out.println("1) List moon missions"); | ||||||||||||||||||||||
| System.out.println("2) Get a moon mission by mission_id"); | ||||||||||||||||||||||
| System.out.println("3) Count missions for a given year"); | ||||||||||||||||||||||
| System.out.println("4) Create an account"); | ||||||||||||||||||||||
| System.out.println("5) Update an account password"); | ||||||||||||||||||||||
| System.out.println("6) Delete an account"); | ||||||||||||||||||||||
| System.out.println("0) Exit"); | ||||||||||||||||||||||
| System.out.print("Choose option: "); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| private void listMoonMissions () { | ||||||||||||||||||||||
| System.out.println("\n --- Moon Missions ---"); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| List<String> spacecrafts = missionRepository.findAllSpaceCraftNames(); | ||||||||||||||||||||||
| spacecrafts.forEach(System.out::println); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| private void getMissionById() { | ||||||||||||||||||||||
| System.out.print("Enter mission_id: "); | ||||||||||||||||||||||
| int missionId = getIntInput(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Optional<MoonMission> missionOpt = missionRepository.findById(missionId); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (missionOpt.isPresent()) { | ||||||||||||||||||||||
| MoonMission mission = missionOpt.get(); | ||||||||||||||||||||||
| System.out.println("\n--- Mission Details ---"); | ||||||||||||||||||||||
| System.out.println("Mission ID: " + mission.missionId()); | ||||||||||||||||||||||
| System.out.println("Spacecraft: " + mission.spacecraft()); | ||||||||||||||||||||||
| System.out.println("Launch Date: " + mission.launchDate()); | ||||||||||||||||||||||
| System.out.println("Carrier Rocket: " + mission.carrierRocket()); | ||||||||||||||||||||||
| System.out.println("Operator: " + mission.operator()); | ||||||||||||||||||||||
| System.out.println("Mission Type: " + mission.missionType()); | ||||||||||||||||||||||
| System.out.println("Outcome: " + mission.outcome()); | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| System.out.println("Mission not found."); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| private void countMissionsByYear() { | ||||||||||||||||||||||
| System.out.print("Enter year: "); | ||||||||||||||||||||||
| int year = getIntInput(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| int count = missionRepository.countByYear(year); | ||||||||||||||||||||||
| System.out.println("Missions launched in " + year + ": " + count); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| private void createAccount() { | ||||||||||||||||||||||
| System.out.print("First name: "); | ||||||||||||||||||||||
| String firstName = scanner.nextLine().trim(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| System.out.print("Last name: "); | ||||||||||||||||||||||
| String lastName = scanner.nextLine().trim(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| System.out.print("SSN: "); | ||||||||||||||||||||||
| String ssn = scanner.nextLine().trim(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| System.out.print("Password: "); | ||||||||||||||||||||||
| String password = scanner.nextLine().trim(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| int userId = accountRepository.create(firstName, lastName, ssn, password); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (userId > 0) { | ||||||||||||||||||||||
| System.out.println("✓ Account created successfully! User ID: " + userId); | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| System.out.println("Failed to create account."); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| private void updateAccountPassword() { | ||||||||||||||||||||||
| System.out.print("Enter user_id: "); | ||||||||||||||||||||||
| int userId = getIntInput(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| System.out.print("Enter new password: "); | ||||||||||||||||||||||
| String newPassword = scanner.nextLine().trim(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| boolean success = accountRepository.updatePassword(userId, newPassword); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (success) { | ||||||||||||||||||||||
| System.out.println("✓ Password updated successfully!"); | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| System.out.println("User not found."); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| private void deleteAccount() { | ||||||||||||||||||||||
| System.out.print("Enter user_id: "); | ||||||||||||||||||||||
| int userId = getIntInput(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| boolean success = accountRepository.delete(userId); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (success) { | ||||||||||||||||||||||
| System.out.println("✓ Account deleted successfully!"); | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| System.out.println("User not found."); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| private int getIntInput() { | ||||||||||||||||||||||
| while(true) { | ||||||||||||||||||||||
| try { | ||||||||||||||||||||||
| String input = scanner.nextLine().trim(); | ||||||||||||||||||||||
| return Integer.parseInt(input); | ||||||||||||||||||||||
| } catch (NumberFormatException e) { | ||||||||||||||||||||||
| System.out.println("Invalid number. Try again: "); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| //Todo: Starting point for your code | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /** | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| package com.example.datasource; | ||
|
|
||
| import javax.sql.DataSource; | ||
| import java.sql.Connection; | ||
| import java.sql.DriverManager; | ||
| import java.sql.SQLException; | ||
| import java.util.logging.Logger; | ||
|
|
||
| public class SimpleDriverManagerDataSource implements DataSource { | ||
|
|
||
| private final String url; | ||
| private final String username; | ||
| private final String password; | ||
|
|
||
| public SimpleDriverManagerDataSource(String url, String username, String password) { | ||
| this.url = url; | ||
| this.username = username; | ||
| this.password = password; | ||
| } | ||
|
|
||
| @Override | ||
| public Connection getConnection() throws SQLException { | ||
| return DriverManager.getConnection(url, username, password); | ||
| } | ||
|
|
||
| @Override | ||
| public Connection getConnection(String username, String password) throws SQLException { | ||
| return DriverManager.getConnection(url, username, password); | ||
| } | ||
|
|
||
| @Override | ||
| public java.io.PrintWriter getLogWriter() { return null; } | ||
|
|
||
| @Override | ||
| public void setLogWriter(java.io.PrintWriter out) {} | ||
|
|
||
| @Override | ||
| public void setLoginTimeout(int seconds) {} | ||
|
|
||
| @Override | ||
| public int getLoginTimeout() { return 0; } | ||
|
|
||
| @Override | ||
| public Logger getParentLogger() { return null; } | ||
|
|
||
| @Override | ||
| public <T> T unwrap(Class<T> iface) { return null; } | ||
|
|
||
| @Override | ||
| public boolean isWrapperFor(Class<?> iface) { return false; } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package com.example.model; | ||
|
|
||
| public record Account( | ||
| int userID, | ||
| String name, | ||
| String ssn, | ||
| String password | ||
| ) { | ||
| public Account { | ||
| if(name == null || name.isBlank()) { | ||
| throw new IllegalArgumentException("Name cannot be blank"); | ||
| } | ||
| if (ssn == null || ssn.isBlank()) { | ||
| throw new IllegalArgumentException("SSN cannot be blank"); | ||
| } | ||
| if (password == null || password.isBlank()) { | ||
| throw new IllegalArgumentException("Password cannot be blank"); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| package com.example.model; | ||
|
|
||
| import java.time.LocalDate; | ||
|
|
||
| public record MoonMission( | ||
| int missionId, | ||
| String spacecraft, | ||
| LocalDate launchDate, | ||
| String carrierRocket, | ||
| String operator, | ||
| String missionType, | ||
| String outcome | ||
| ) { | ||
| public MoonMission { | ||
| if (spacecraft == null || spacecraft.isBlank()) { | ||
| throw new IllegalArgumentException("Spacecraft cannot be blank"); | ||
| } | ||
| if (launchDate == null) { | ||
| throw new IllegalArgumentException("Launch date cannot be null"); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.example.repository; | ||
|
|
||
| import com.example.model.Account; | ||
|
|
||
| import java.util.Optional; | ||
|
|
||
| public interface AccountRepository { | ||
|
|
||
| Optional<Account> findByUsernameAndPassword (String username, String password); | ||
|
|
||
| int create (String firstName, String lastName, String ssn, String password); | ||
|
|
||
| boolean updatePassword(int userId, String newPassword); | ||
|
|
||
| boolean delete(int userId); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Remove unused imports.
Several imports are not used and should be removed:
org.testcontainers.shaded.org.checkerframework.checker.units.qual.Ajava.sql.SQLOutput📝 Committable suggestion
🤖 Prompt for AI Agents