v0.2.0 Switch to mongoDB
This commit is contained in:
parent
3d2a1cdf68
commit
e22d2b6fca
9 changed files with 62 additions and 292 deletions
29
pom.xml
29
pom.xml
|
|
@ -27,7 +27,7 @@
|
|||
<url/>
|
||||
</scm>
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<java.version>21</java.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
|
||||
|
|
@ -67,35 +67,10 @@
|
|||
<version>3.5.6-Final</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
|
||||
<!-- <dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
<version>3.3.4</version>
|
||||
</dependency> -->
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.github.gwenn/sqlite-dialect -->
|
||||
<dependency>
|
||||
<groupId>com.github.gwenn</groupId>
|
||||
<artifactId>sqlite-dialect</artifactId>
|
||||
<version>0.1.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc -->
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.45.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
<version>3.3.4</version>
|
||||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
|||
|
|
@ -1,18 +1,16 @@
|
|||
package io.titan.portfolio.controller;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
// import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
// import org.springframework.web.bind.annotation.GetMapping;
|
||||
// import org.springframework.web.bind.annotation.PathVariable;
|
||||
// import org.springframework.web.bind.annotation.PostMapping;
|
||||
// import org.springframework.web.bind.annotation.PutMapping;
|
||||
// import org.springframework.web.bind.annotation.RequestBody;
|
||||
// import org.springframework.web.bind.annotation.RequestMapping;
|
||||
// import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import io.titan.portfolio.model.Education;
|
||||
import io.titan.portfolio.service.EducationService;
|
||||
|
|
@ -29,74 +27,35 @@ public class EducationController {
|
|||
}
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<List<Education>> getAllEducation() {
|
||||
List<Education> educations = educationService.getAllEducation();
|
||||
return ResponseEntity.ok(educations);
|
||||
List<Education> getAllEducation(){
|
||||
return educationService.getAllEducation();
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ResponseEntity<Education> getEducationById(@PathVariable Long id) {
|
||||
ResponseEntity<Education> getEducationById(@PathVariable String id) {
|
||||
return educationService.getEducationById(id)
|
||||
.map(ResponseEntity::ok)
|
||||
.orElse(ResponseEntity.notFound().build());
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<Education> createEducation(@RequestBody Education education) {
|
||||
try {
|
||||
Education createdEducation = educationService.createEducation(education);
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(createdEducation);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.badRequest().body(null);
|
||||
}
|
||||
ResponseEntity<Void> createEducation(@RequestBody Education education) {
|
||||
educationService.createEducation(education);
|
||||
return ResponseEntity.status(HttpStatus.CREATED).build();
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public ResponseEntity<Education> updateEducation(@PathVariable Long id, @RequestBody Education education) {
|
||||
ResponseEntity<Education> updateEducation(@PathVariable String id, @RequestBody Education education) {
|
||||
if (!id.equals(education.id())) {
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
try {
|
||||
Education updatedEducation = educationService.updateEducation(education);
|
||||
return ResponseEntity.ok(updatedEducation);
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
return ResponseEntity.notFound().build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.badRequest().body(null);
|
||||
}
|
||||
educationService.updateEducation(education);
|
||||
return ResponseEntity.ok(education);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public ResponseEntity<Void> deleteEducation(@PathVariable Long id) {
|
||||
try {
|
||||
educationService.deleteEducation(id);
|
||||
return ResponseEntity.noContent().build();
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
}
|
||||
|
||||
@ExceptionHandler(EmptyResultDataAccessException.class)
|
||||
public ResponseEntity<String> handleNotFound(EmptyResultDataAccessException e) {
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(IllegalArgumentException.class)
|
||||
public ResponseEntity<String> handleBadRequest(IllegalArgumentException e) {
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(DataAccessException.class)
|
||||
public ResponseEntity<String> handleDataAccessException(DataAccessException e) {
|
||||
// Log the exception
|
||||
e.printStackTrace();
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An unexpected error occurred");
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseEntity<String> handleGeneralException(Exception e) {
|
||||
// Log the exception
|
||||
e.printStackTrace();
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An unexpected error occurred");
|
||||
ResponseEntity<Void> deleteEducation(@PathVariable String id) {
|
||||
boolean deleted = educationService.deleteEducation(id);
|
||||
return deleted ? ResponseEntity.ok().build() : ResponseEntity.notFound().build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,19 @@
|
|||
package io.titan.portfolio.model;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Document(collection = "education")
|
||||
public record Education(
|
||||
Long id,
|
||||
@Id String id,
|
||||
String title,
|
||||
String organization,
|
||||
String logo,
|
||||
String location,
|
||||
String duration,
|
||||
Integer fromDate,
|
||||
Integer toDate,
|
||||
String description,
|
||||
List<String> achievements,
|
||||
List<String> skills,
|
||||
|
|
@ -17,13 +22,13 @@ public record Education(
|
|||
String techStackTitle
|
||||
) {
|
||||
public Education() {
|
||||
this(null, null, null, null, null, null, null, null, null, null, null, null);
|
||||
this(null, null, null, null, null, null, null, null, null, null, null, null, null);
|
||||
}
|
||||
|
||||
public Education(String title, String organization, String logo, String location, String duration,
|
||||
public Education(String title, String organization, String logo, String location, Integer fromDate, Integer toDate,
|
||||
String description, List<String> achievements, List<String> skills,
|
||||
List<String> techStack, String skillsTitle, String techStackTitle) {
|
||||
this(null, title, organization, logo, location, duration, description,
|
||||
this(null, title, organization, logo, location, fromDate, toDate, description,
|
||||
achievements, skills, techStack, skillsTitle, techStackTitle);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,119 +1,22 @@
|
|||
package io.titan.portfolio.repository;
|
||||
|
||||
import io.titan.portfolio.model.Education;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.support.GeneratedKeyHolder;
|
||||
import org.springframework.jdbc.support.KeyHolder;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.Statement;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
// import org.springframework.jdbc.core.JdbcTemplate;
|
||||
// import org.springframework.jdbc.core.RowMapper;
|
||||
// import org.springframework.jdbc.support.GeneratedKeyHolder;
|
||||
// import org.springframework.jdbc.support.KeyHolder;
|
||||
// import org.springframework.stereotype.Repository;
|
||||
|
||||
// import java.sql.PreparedStatement;
|
||||
// import java.sql.Statement;
|
||||
// import java.util.Arrays;
|
||||
// import java.util.List;
|
||||
// import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public class EducationRepository {
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
public interface EducationRepository extends MongoRepository<Education, String>{
|
||||
|
||||
public EducationRepository(JdbcTemplate jdbcTemplate) {
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
}
|
||||
|
||||
private static final RowMapper<Education> EDUCATION_ROW_MAPPER = (rs, rowNum) -> new Education(
|
||||
rs.getLong("id"),
|
||||
rs.getString("title"),
|
||||
rs.getString("organization"),
|
||||
rs.getString("logo"),
|
||||
rs.getString("location"),
|
||||
rs.getString("duration"),
|
||||
rs.getString("description"),
|
||||
Arrays.asList(rs.getString("achievements").split(",")),
|
||||
Arrays.asList(rs.getString("skills").split(",")),
|
||||
Arrays.asList(rs.getString("tech_stack").split(",")),
|
||||
rs.getString("skills_title"),
|
||||
rs.getString("tech_stack_title")
|
||||
);
|
||||
|
||||
public List<Education> findAll() {
|
||||
String sql = "SELECT * FROM Education";
|
||||
return jdbcTemplate.query(sql, EDUCATION_ROW_MAPPER);
|
||||
}
|
||||
|
||||
public Optional<Education> findById(Long id) {
|
||||
String sql = "SELECT * FROM Education WHERE id = ?";
|
||||
List<Education> results = jdbcTemplate.query(sql, EDUCATION_ROW_MAPPER, id);
|
||||
return results.isEmpty() ? Optional.empty() : Optional.of(results.get(0));
|
||||
}
|
||||
|
||||
public Education save(Education education) {
|
||||
String sql = "INSERT INTO Education (title, organization, logo, location, duration, description, " +
|
||||
"achievements, skills, tech_stack, skills_title, tech_stack_title) " +
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
|
||||
KeyHolder keyHolder = new GeneratedKeyHolder();
|
||||
jdbcTemplate.update(connection -> {
|
||||
PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
|
||||
ps.setString(1, education.title());
|
||||
ps.setString(2, education.organization());
|
||||
ps.setString(3, education.logo());
|
||||
ps.setString(4, education.location());
|
||||
ps.setString(5, education.duration());
|
||||
ps.setString(6, education.description());
|
||||
ps.setString(7, String.join(",", education.achievements()));
|
||||
ps.setString(8, String.join(",", education.skills()));
|
||||
ps.setString(9, String.join(",", education.techStack()));
|
||||
ps.setString(10, education.skillsTitle());
|
||||
ps.setString(11, education.techStackTitle());
|
||||
return ps;
|
||||
}, keyHolder);
|
||||
|
||||
Long generatedId = keyHolder.getKey().longValue();
|
||||
return new Education(
|
||||
generatedId,
|
||||
education.title(),
|
||||
education.organization(),
|
||||
education.logo(),
|
||||
education.location(),
|
||||
education.duration(),
|
||||
education.description(),
|
||||
education.achievements(),
|
||||
education.skills(),
|
||||
education.techStack(),
|
||||
education.skillsTitle(),
|
||||
education.techStackTitle()
|
||||
);
|
||||
}
|
||||
|
||||
public void update(Education education) {
|
||||
String sql = "UPDATE Education SET title = ?, organization = ?, logo = ?, location = ?, " +
|
||||
"duration = ?, description = ?, achievements = ?, skills = ?, tech_stack = ?, " +
|
||||
"skills_title = ?, tech_stack_title = ? WHERE id = ?";
|
||||
jdbcTemplate.update(sql,
|
||||
education.title(),
|
||||
education.organization(),
|
||||
education.logo(),
|
||||
education.location(),
|
||||
education.duration(),
|
||||
education.description(),
|
||||
String.join(",", education.achievements()),
|
||||
String.join(",", education.skills()),
|
||||
String.join(",", education.techStack()),
|
||||
education.skillsTitle(),
|
||||
education.techStackTitle(),
|
||||
education.id()
|
||||
);
|
||||
}
|
||||
|
||||
public boolean existsById(Long id) {
|
||||
String sql = "SELECT COUNT(*) FROM Education WHERE id = ?";
|
||||
Integer count = jdbcTemplate.queryForObject(sql, Integer.class, id);
|
||||
return count != null && count > 0;
|
||||
}
|
||||
|
||||
public void deleteById(Long id) {
|
||||
String sql = "DELETE FROM Education WHERE id = ?";
|
||||
jdbcTemplate.update(sql, id);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,6 @@ package io.titan.portfolio.service;
|
|||
|
||||
import io.titan.portfolio.model.Education;
|
||||
import io.titan.portfolio.repository.EducationRepository;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -19,76 +15,27 @@ public class EducationService{
|
|||
this.educationRepository = educationRepository;
|
||||
}
|
||||
|
||||
public List<Education> getAllEducation() {
|
||||
try {
|
||||
return educationRepository.findAll();
|
||||
} catch (DataAccessException e) {
|
||||
// Log the error
|
||||
System.err.println("Error retrieving all education records: " + e.getMessage());
|
||||
throw new RuntimeException("Failed to retrieve education records", e);
|
||||
}
|
||||
public List<Education> getAllEducation(){
|
||||
return educationRepository.findAll();
|
||||
}
|
||||
|
||||
public Optional<Education> getEducationById(Long id) {
|
||||
try {
|
||||
return educationRepository.findById(id);
|
||||
} catch (DataAccessException e) {
|
||||
// Log the error
|
||||
System.err.println("Error retrieving education by id: " + e.getMessage());
|
||||
throw new RuntimeException("Failed to retrieve education record", e);
|
||||
}
|
||||
public Optional<Education> getEducationById(String id){
|
||||
return educationRepository.findById(id);
|
||||
}
|
||||
|
||||
public Education createEducation(Education education) {
|
||||
try {
|
||||
return educationRepository.save(education);
|
||||
} catch (DataIntegrityViolationException e) {
|
||||
// Log the error
|
||||
System.err.println("Error creating education record: " + e.getMessage());
|
||||
throw new IllegalArgumentException("Invalid education data: " + e.getMessage());
|
||||
} catch (DataAccessException e) {
|
||||
// Log the error
|
||||
System.err.println("Error creating education record: " + e.getMessage());
|
||||
throw new RuntimeException("Failed to create education record", e);
|
||||
}
|
||||
return educationRepository.save(education);
|
||||
}
|
||||
|
||||
public Education updateEducation(Education education) {
|
||||
try {
|
||||
if (!educationRepository.existsById(education.id())) {
|
||||
throw new EmptyResultDataAccessException("Education record not found with id: " + education.id(), 1);
|
||||
}
|
||||
educationRepository.update(education);
|
||||
return education;
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
// Log the error
|
||||
System.err.println("Education record not found: " + e.getMessage());
|
||||
throw e;
|
||||
} catch (DataIntegrityViolationException e) {
|
||||
// Log the error
|
||||
System.err.println("Error updating education record: " + e.getMessage());
|
||||
throw new IllegalArgumentException("Invalid education data: " + e.getMessage());
|
||||
} catch (DataAccessException e) {
|
||||
// Log the error
|
||||
System.err.println("Error updating education record: " + e.getMessage());
|
||||
throw new RuntimeException("Failed to update education record", e);
|
||||
}
|
||||
public void updateEducation(Education education) {
|
||||
educationRepository.save(education);
|
||||
}
|
||||
|
||||
public void deleteEducation(Long id) {
|
||||
try {
|
||||
if (!educationRepository.existsById(id)) {
|
||||
throw new EmptyResultDataAccessException("Education record not found with id: " + id, 1);
|
||||
}
|
||||
public boolean deleteEducation(String id) {
|
||||
if (educationRepository.existsById(id)) {
|
||||
educationRepository.deleteById(id);
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
// Log the error
|
||||
System.err.println("Education record not found: " + e.getMessage());
|
||||
throw e;
|
||||
} catch (DataAccessException e) {
|
||||
// Log the error
|
||||
System.err.println("Error deleting education record: " + e.getMessage());
|
||||
throw new RuntimeException("Failed to delete education record", e);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,5 @@
|
|||
spring.datasource.url=jdbc:sqlite:titan.db
|
||||
spring.datasource.driver-class-name=org.sqlite.JDBC
|
||||
|
||||
spring.sql.init.mode=always
|
||||
spring.sql.init.schema-locations=classpath:education_schema.sql
|
||||
|
||||
spring.application.name=demo
|
||||
spring.data.mongodb.uri=mongodb://portfolio_user:portfolio_P%40ssword@localhost:27017/portfolio_db
|
||||
spring.application.name=titan_backend
|
||||
spring.devtools.restart.enabled=true
|
||||
|
||||
server.port=8282
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
CREATE TABLE IF NOT EXISTS Education (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
title TEXT NOT NULL,
|
||||
organization TEXT NOT NULL,
|
||||
logo TEXT,
|
||||
location TEXT,
|
||||
duration TEXT,
|
||||
description TEXT,
|
||||
achievements TEXT,
|
||||
skills TEXT,
|
||||
tech_stack TEXT,
|
||||
skills_title TEXT,
|
||||
tech_stack_title TEXT
|
||||
);
|
||||
BIN
titan.db
BIN
titan.db
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
0.1.2
|
||||
0.2.0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue