package ru.charm.back.dao; import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import ru.charm.back.model.Gender; import ru.charm.back.model.Profile; import ru.charm.back.model.Role; import ru.charm.back.model.Status; import java.sql.*; import java.sql.Date; import java.util.*; @Slf4j @NoArgsConstructor(access = AccessLevel.PRIVATE) public class ProfileDao { private static final ProfileDao INSTANCE = new ProfileDao(); public static final String URL = "jdbc:postgresql://localhost:5434/charm_repository"; public static final String USER = "postgres"; public static final String PASSWORD = "123456"; @SneakyThrows public static ProfileDao getInstance() { Class.forName("org.postgresql.Driver"); return INSTANCE; } public Profile save(Profile profile) { try ( Connection connection = DriverManager.getConnection(URL, USER, PASSWORD); Statement statement = connection.createStatement(); ) { String sql = "INSERT INTO profile(email, password) VALUES ('%s', '%s')".formatted(profile.getEmail(), profile.getPassword()); int insertCount = statement.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS); ResultSet res = statement.getGeneratedKeys(); if (res.next()) { profile.setId(res.getLong("id")); } return profile; } catch (SQLException e) { throw new RuntimeException(e); } } public Optional findById(Long id) { try ( Connection connection = DriverManager.getConnection(URL, USER, PASSWORD); Statement statement = connection.createStatement(); ) { String sql = "SELECT * FROM profile WHERE id = %s".formatted(id); ResultSet res = statement.executeQuery(sql); Profile profile = null; if (res.next()) { profile = mapToProfile(res); } return Optional.ofNullable(profile); } catch (SQLException e) { throw new RuntimeException(e); } } public List findAll() { try ( Connection connection = DriverManager.getConnection(URL, USER, PASSWORD); Statement statement = connection.createStatement(); ) { String sql = "SELECT * FROM profile" ; ResultSet res = statement.executeQuery(sql); List profiles = new ArrayList<>(); while (res.next()) { profiles.add(mapToProfile(res)); } return profiles; } catch (SQLException e) { throw new RuntimeException(e); } } public Optional findByEmailAndPassword(String email, String password) { try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD); Statement stmt = conn.createStatement()) { //language=POSTGRES-PSQL String sql = "SELECT * FROM profile WHERE email = '%s' AND password = '%s'"; ResultSet rs = stmt.executeQuery(String.format(sql, email, password)); Profile profile = null; if (rs.next()) { profile = mapToProfile(rs); } return Optional.ofNullable(profile); } catch (SQLException e) { throw new RuntimeException(e); } } public void update(Profile profile) { try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD); Statement stmt = conn.createStatement()) { List args = new ArrayList<>(); StringBuilder queryBuilder = new StringBuilder("UPDATE profile SET email = '%s', password = '%s'"); args.add(profile.getEmail()); args.add(profile.getPassword()); if (profile.getName() != null) { queryBuilder.append(", name = '%s'"); args.add(profile.getName()); } if (profile.getSurname() != null) { queryBuilder.append(", surname = '%s'"); args.add(profile.getSurname()); } if (profile.getBirthDate() != null) { queryBuilder.append(", birth_date = '%s'"); args.add(Date.valueOf(profile.getBirthDate())); } if (profile.getAbout() != null) { queryBuilder.append(", about = '%s'"); args.add(profile.getAbout()); } if (profile.getGender() != null) { queryBuilder.append(", gender = '%s'"); args.add(profile.getGender()); } if (profile.getStatus() != null) { queryBuilder.append(", status = '%s'"); args.add(profile.getStatus()); } if (profile.getPhoto() != null) { queryBuilder.append(", photo = '%s'"); args.add(profile.getPhoto()); } queryBuilder.append(" WHERE id = %s"); args.add(profile.getId()); String sql = queryBuilder.toString().formatted(args.toArray()); log.debug("Final update sql: {}", sql); int updateCount = stmt.executeUpdate(sql); log.debug("Update count: {}", updateCount); } catch (SQLException e) { throw new RuntimeException(e); } } public boolean delete(Long id) { try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD); Statement stmt = conn.createStatement()) { //language=POSTGRES-PSQL String sql = "DELETE FROM profile WHERE id = %s".formatted(id); int deleteCount = stmt.executeUpdate(sql); log.debug("Delete count: {}", deleteCount); return deleteCount > 0; } catch (SQLException e) { throw new RuntimeException(e); } } public Set getAllEmails() { try ( Connection connection = DriverManager.getConnection(URL, USER, PASSWORD); Statement statement = connection.createStatement(); ) { String sql = "SELECT email FROM profile" ; ResultSet res = statement.executeQuery(sql); ArrayList emails = new ArrayList<>(); while (res.next()) { emails.add(res.getString("email")); } return new HashSet<>(emails); } catch (SQLException e) { throw new RuntimeException(e); } } public Optional findByEmail(String email) { try ( Connection connection = DriverManager.getConnection(URL, USER, PASSWORD); Statement statement = connection.createStatement(); ) { String sql = "SELECT * FROM profile WHERE email = '%s'".formatted(email); ResultSet res = statement.executeQuery(sql); Profile profile = null; if (res.next()) { profile = mapToProfile(res); } return Optional.ofNullable(profile); } catch (SQLException e) { throw new RuntimeException(e); } } public Boolean existsByEmail(String email) { try ( Connection connection = DriverManager.getConnection(URL, USER, PASSWORD); Statement statement = connection.createStatement(); ) { String sql = "SELECT * FROM profile WHERE email = '%s'".formatted(email); ResultSet res = statement.executeQuery(sql); return res.next(); } catch (SQLException e) { throw new RuntimeException(e); } } private Profile mapToProfile(ResultSet rs) throws SQLException { Profile result = new Profile(); result.setId(rs.getLong("id")); result.setEmail(rs.getString("email")); result.setPassword(rs.getString("password")); result.setName(rs.getString("name")); result.setSurname(rs.getString("surname")); Date birthDate = rs.getDate("birth_date"); if (birthDate != null) { result.setBirthDate(birthDate.toLocalDate()); } result.setAbout(rs.getString("about")); String gender = rs.getString("gender"); if (gender != null) { result.setGender(Gender.valueOf(gender)); } result.setPhoto(rs.getString("photo")); String status = rs.getString("status"); if (status != null) { result.setStatus(Status.valueOf(status)); } String role = rs.getString("role"); if (role != null) { result.setRole(Role.valueOf(role)); } return result; } }