Skip to content
Closed
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/339Lr3BJ)
### How the tests work (and Docker requirement)

This project ships with an end‑to‑end CLI integration test suite that uses Testcontainers to spin up a temporary MySQL database.
Expand Down
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
<mockito.version>5.20.0</mockito.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>2.0.17</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/com/example/AccountRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example;

public interface AccountRepository {
boolean login(String username, String password);

long create(String first, String last, String ssn, String password);

boolean updatePassword(int userId, String newPassword);

boolean delete(int userId);

boolean exists(int userId);

}
108 changes: 108 additions & 0 deletions src/main/java/com/example/JdbcAccountRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package com.example;

import javax.sql.DataSource;
import java.sql.*;

public class JdbcAccountRepository implements AccountRepository {

private final DataSource ds;

public JdbcAccountRepository(DataSource ds) {
this.ds = ds;
}

@Override
public boolean login(String username, String password) {
String sql = "SELECT 1 FROM account WHERE name = ? AND password = ?";

try (Connection conn = ds.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {

ps.setString(1, username);
ps.setString(2, password);

try (ResultSet rs = ps.executeQuery()) {
return rs.next();
}

} catch (SQLException e) {
throw new RuntimeException(e);
}
}

@Override
public long create(String first, String last, String ssn, String password) {
String sql = "INSERT INTO account(first_name, last_name, ssn, password) VALUES (?, ?, ?, ?)";

try (Connection conn = ds.getConnection();
PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {

ps.setString(1, first);
ps.setString(2, last);
ps.setString(3, ssn);
ps.setString(4, password);

ps.executeUpdate();

ResultSet keys = ps.getGeneratedKeys();
if (keys.next()) {
return keys.getLong(1);
}
throw new RuntimeException("No ID returned!");

} catch (SQLException e) {
throw new RuntimeException(e);
}
}

@Override
public boolean updatePassword(int userId, String newPassword) {
String sql = "UPDATE account SET password = ? WHERE user_id = ?";

try (Connection conn = ds.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {

ps.setString(1, newPassword);
ps.setInt(2, userId);

return ps.executeUpdate() > 0;

} catch (SQLException e) {
throw new RuntimeException(e);
}
}

@Override
public boolean delete(int userId) {
String sql = "DELETE FROM account WHERE user_id = ?";

try (Connection conn = ds.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {

ps.setInt(1, userId);

return ps.executeUpdate() > 0;

} catch (SQLException e) {
throw new RuntimeException(e);
}
}

@Override
public boolean exists(int userId) {
String sql = "SELECT 1 FROM account WHERE user_id = ?";

try (Connection conn = ds.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {

ps.setInt(1, userId);
try (ResultSet rs = ps.executeQuery()) {
return rs.next();
}

} catch (SQLException e) {
throw new RuntimeException(e);
}
}

}
77 changes: 77 additions & 0 deletions src/main/java/com/example/JdbcMoonMissionRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.example;

import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class JdbcMoonMissionRepository implements MoonMissionRepository {

private final DataSource ds;

public JdbcMoonMissionRepository(DataSource ds) {
this.ds = ds;
}

@Override
public List<String> listSpacecraft() {
List<String> list = new ArrayList<>();
String sql = "SELECT spacecraft FROM moon_mission";

try (Connection conn = ds.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {

while (rs.next()) {
list.add(rs.getString("spacecraft"));
}

} catch (SQLException e) {
throw new RuntimeException(e);
}
return list;
}

@Override
public Mission getMissionById(long id) {
String sql = "SELECT mission_id, spacecraft FROM moon_mission WHERE mission_id = ?";

try (Connection conn = ds.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {

ps.setLong(1, id);

try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
return new Mission(
rs.getLong("mission_id"),
rs.getString("spacecraft")
);
}
return null;
}

} catch (SQLException e) {
throw new RuntimeException(e);
}
}

@Override
public int countByYear(int year) {
String sql = "SELECT COUNT(*) AS total FROM moon_mission WHERE YEAR(launch_date) = ?";

try (Connection conn = ds.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {

ps.setInt(1, year);

try (ResultSet rs = ps.executeQuery()) {
rs.next();
return rs.getInt("total");
}

} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
134 changes: 127 additions & 7 deletions src/main/java/com/example/Main.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
package com.example;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.*;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
public static final String RESET = "\u001B[0m";
public static final String RED = "\u001B[31m";
public static final String GREEN = "\u001B[32m";
public static final String YELLOW = "\u001B[33m";
public static final String BLUE = "\u001B[34m";


static void main(String[] args) {
if (isDevMode(args)) {
Expand All @@ -26,13 +33,126 @@ public void run() {
"as system properties (-Dkey=value) or environment variables.");
}

try (Connection connection = DriverManager.getConnection(jdbcUrl, dbUser, dbPass)) {
} catch (SQLException e) {
throw new RuntimeException(e);
}
DataSource ds = new SimpleDriverManagerDataSource(jdbcUrl, dbUser, dbPass);
AccountRepository accountRepo = new JdbcAccountRepository(ds);
MoonMissionRepository missionRepo = new JdbcMoonMissionRepository(ds);

//Todo: Starting point for your code
Scanner sc = new Scanner(System.in);

// Sign in
System.out.print("Enter username: ");
String username = sc.nextLine();
System.out.println("Enter password: ");
String password = sc.nextLine();

boolean validLogin = accountRepo.login(username, password);

if (!validLogin) {
System.out.println("Invalid username or password");
return;
}

System.out.println("Login successful!");

// Main menu
boolean isRunning = true;

while (isRunning) {
printMenu();
System.out.print("> ");
String option = sc.nextLine();

switch (option) {
case "1":
missionRepo.listSpacecraft().forEach(System.out::println);
break;

case "2":
System.out.print("Enter ID: ");
long id = Long.parseLong(sc.nextLine());
Mission m = missionRepo.getMissionById(id);
if (m == null) {
System.out.println("Mission not found");
} else {
System.out.println("Mission ID: " + m.missionId);
System.out.println("Spacecraft: " + m.spacecraft);
}
break;

case "3":
System.out.print("Enter year: ");
int year = Integer.parseInt(sc.nextLine());
int count = missionRepo.countByYear(year);
System.out.println(count + " missions in year " + year);
break;

case "4":
System.out.println("Enter your firstname: ");
String first = sc.nextLine();
System.out.println("Enter your lastname: ");
String last = sc.nextLine();
System.out.println("Enter your SSN: ");
String ssn = sc.nextLine();
System.out.println("Enter your password: ");
String pw = sc.nextLine();

long newId = accountRepo.create(first, last, ssn, pw);
System.out.println("Account created successfully! User ID: " + newId);
break;

case "5":
System.out.print("Enter your user ID: ");
int uid = Integer.parseInt(sc.nextLine());

// Check if account exists
if (!accountRepo.exists(uid)) {
System.out.println("Account not found!");
break;
}

// If exists --> create new passwrod
System.out.println("Enter your new password: ");
String newPw = sc.nextLine();

boolean updated = accountRepo.updatePassword(uid, newPw);
System.out.println(updated ? "Account updated!" : "Account not found!");

break;

case "6":
System.out.print("Enter your user ID: ");
int delId = Integer.parseInt(sc.nextLine());
boolean deleted = accountRepo.delete(delId);
System.out.println(deleted ? "Account deleted!" : "No account deleted.");
break;

case "0":
isRunning = false;
break;

default:
System.out.println("Invalid choice!");
}
}
}


private void printMenu() {
System.out.println(BLUE + " " + RESET);
System.out.println(BLUE + "------MAIN MENU------" + RESET);
System.out.println(BLUE + "1. List moon missions" + RESET);
System.out.println(BLUE + "2. Get mission by ID" + RESET);
System.out.println(BLUE + "3. Count missions by year" + RESET);
System.out.println(BLUE + "4. Create account" + RESET);
System.out.println(BLUE + "5. Update account password" + RESET);
System.out.println(BLUE + "6. Delete account" + RESET);
System.out.println(BLUE + "0. Exit" + RESET);
}




/**
* Determines if the application is running in development mode based on system properties,
* environment variables, or command-line arguments.
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/example/Mission.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example;

public class Mission {
public long missionId;
public String spacecraft;

public Mission(long missionId, String spacecraft) {
this.missionId = missionId;
this.spacecraft = spacecraft;
}
}
9 changes: 9 additions & 0 deletions src/main/java/com/example/MoonMissionRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.example;

import java.util.List;

public interface MoonMissionRepository {
List<String> listSpacecraft();
Mission getMissionById(long id);
int countByYear(int year);
}
Loading
Loading