Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
24e6376
add deadline
github-classroom[bot] Nov 27, 2025
2abfe99
Merge pull request #1 from ithsjava25/main
annikaholmqvist94 Dec 2, 2025
643768b
Add initial repository interfaces and JDBC implementations
annikaholmqvist94 Dec 2, 2025
82e1be0
Implement SQL-based login validation in JdbcAccountRepository
annikaholmqvist94 Dec 2, 2025
b161192
Add SQL-based account creation to JdbcAccountRepository
annikaholmqvist94 Dec 2, 2025
ffb31be
Implement SQL-based password update in JdbcAccountRepository
annikaholmqvist94 Dec 2, 2025
004c36a
Implement SQL-based account deletion in JdbcAccountRepository
annikaholmqvist94 Dec 2, 2025
d62076c
Add SQL-based MoonMission repository with initial methods
annikaholmqvist94 Dec 2, 2025
d94ebdf
Implement SQL-based mission counting by year in JdbcMoonMissionReposi…
annikaholmqvist94 Dec 2, 2025
b5582c1
Add user login handling and initialization of repositories in Main class
annikaholmqvist94 Dec 2, 2025
eb4ec2b
Add main menu and moon mission listing/retrieval methods to Main class
annikaholmqvist94 Dec 2, 2025
78ff8b9
Add method to count missions by year in Main class
annikaholmqvist94 Dec 2, 2025
9da5060
Add account creation, password update, and deletion methods to Main c…
annikaholmqvist94 Dec 2, 2025
bb9f1e2
Refactor MoonMission model and repository to include detailed attribu…
annikaholmqvist94 Dec 2, 2025
3009139
Refactor repositories to use `DataSource` abstraction; centralize con…
annikaholmqvist94 Dec 3, 2025
fac4064
Refactor repositories to use `DataSource` abstraction; centralize con…
annikaholmqvist94 Dec 3, 2025
ec2d55f
Generate username during account creation, fix JdbcMoonMissionReposit…
annikaholmqvist94 Dec 5, 2025
1e06b64
Fix mission ID type in JdbcMoonMissionRepository; update label in Mai…
annikaholmqvist94 Dec 8, 2025
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
12 changes: 12 additions & 0 deletions src/main/java/com/example/AccountRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.example;

public interface AccountRepository {

boolean isValidLogin(String username, String password);

boolean createAccount(String firstName, String lastName, String ssn, String password);

boolean updatePassword(long userId, String newPassword);

boolean deleteAccount(long userId);
}
11 changes: 11 additions & 0 deletions src/main/java/com/example/DataSource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example;

import java.sql.Connection;
import java.sql.SQLException;

// define a new standard method for connection
public interface DataSource {

Connection getConnection() throws SQLException;

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

import java.sql.*;

public class JdbcAccountRepository implements AccountRepository{

//Fetching Datasource object
private final DataSource dataSource;


//injection the datasource object into the constructor:
public JdbcAccountRepository(DataSource dataSource){
this.dataSource=dataSource;
}


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

try(
Connection connection= dataSource.getConnection();
PreparedStatement ps= connection.prepareStatement(sql)
) {
ps.setString(1, username);
ps.setString(2, password);

try(ResultSet rs = ps.executeQuery()) {
if (rs.next()){
return rs.getInt(1)>0;
}
}

} catch (SQLException e){
System.err.println("Database error during login validation: " + e.getMessage());
return false;
}

return false;

}

@Override
public boolean createAccount(String firstName, String lastName, String ssn, String password) {

// concatenation of firstname and lastname to create username (name column in sql) for proper usage of the app.
String username = firstName.substring(0, Math.min(firstName.length(), 3)) +
lastName.substring(0, Math.min(lastName.length(), 3));

String sql= "INSERT INTO account (first_name, last_name, ssn, password, name) VALUES (?, ?, ?, ?, ?)";

try(Connection connection= dataSource.getConnection();
PreparedStatement ps= connection.prepareStatement(sql)){

ps.setString(1, firstName);
ps.setString(2, lastName);
ps.setString(3, ssn);
ps.setString(4, password);
ps.setString(5, username);

int rowsAffected= ps.executeUpdate();
return rowsAffected>0;
} catch (SQLException e){
System.err.println("Could not create account: " + e.getMessage());
return false;
}
}

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

try(Connection connection= dataSource.getConnection();
PreparedStatement ps=connection.prepareStatement(sql)){

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

int rowsAffected=ps.executeUpdate();
return rowsAffected>0;

}catch (SQLException e){
System.err.println(" Could not update password: " + e.getMessage());
return false;
}
}

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

try(Connection connection= dataSource.getConnection();
PreparedStatement ps=connection.prepareStatement(sql)){

ps.setLong(1, userId);

int rowsAffected=ps.executeUpdate();
return rowsAffected>0;

}catch (SQLException e){
System.err.println(" Could not delete account: " + e.getMessage());
return false;
}


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

import java.sql.*;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class JdbcMoonMissionRepository implements MoonMissionRepository{

//declare datasource object
private final DataSource dataSource;


// inject into contructor:
public JdbcMoonMissionRepository(DataSource dataSource){
this.dataSource=dataSource;
}

@Override
public List<String> findAllSpacecraftNames() {
List<String> names = new ArrayList<>();

String sql= "SELECT spacecraft FROM moon_mission ORDER BY launch_date";

try( Connection connection= dataSource.getConnection();
Statement statement= connection.createStatement();
ResultSet rs= statement.executeQuery(sql)) {

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

}
} catch (SQLException e){
System.err.println(" Failure to find names: " +e.getMessage());

}

return names;
}

@Override
public Optional<MoonMission> findById(long missionId) {
String sql = "SELECT mission_id, spacecraft, launch_date, carrier_rocket, operator, mission_type, outcome FROM moon_mission WHERE mission_id = ?";

try( Connection connection= dataSource.getConnection();
PreparedStatement ps= connection.prepareStatement(sql)){

ps.setLong(1, missionId);

try(ResultSet rs = ps.executeQuery()){
if(rs.next()){
//Map to MoonMission object:
MoonMission mission= new MoonMission(
rs.getLong("mission_id"),
rs.getString("spacecraft"),
rs.getObject("launch_date", LocalDate.class),
rs.getString("carrier_rocket"),
rs.getString("operator"),
rs.getString("mission_type"),
rs.getString("outcome")
);

return Optional.of(mission);
}
}
}catch (SQLException e){
System.err.println(" Failure in receiving mission per ID: " + e.getMessage());
}
return Optional.empty();
}

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

try( Connection connection=dataSource.getConnection();
PreparedStatement ps=connection.prepareStatement(sql)){

ps.setInt(1, year);

try(ResultSet rs=ps.executeQuery()){
if(rs.next()){
//Result is COUNT(*) column 1:
return rs.getInt(1);
}
}
} catch (SQLException e ){
System.err.println(" Failure in counting missions per year: " + e.getMessage());
}
//return 0 if no results are found:
return 0;
}
}
Loading
Loading