commit ba408ee0a2699adf02368775d36994a74fccc5fb Author: Florian THIERRY Date: Thu Mar 21 14:26:09 2024 +0100 Initial commit. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..3c72628 --- /dev/null +++ b/pom.xml @@ -0,0 +1,62 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.2.3 + + + org.codiki + database-extractor + 0.0.1-SNAPSHOT + database-extractor + Demo project for Spring Boot + + 21 + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + + org.projectlombok + lombok + true + + + org.postgresql + postgresql + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/src/main/java/org/codiki/databaseextractor/DatabaseExtractorApplication.java b/src/main/java/org/codiki/databaseextractor/DatabaseExtractorApplication.java new file mode 100644 index 0000000..684f3df --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/DatabaseExtractorApplication.java @@ -0,0 +1,13 @@ +package org.codiki.databaseextractor; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DatabaseExtractorApplication { + + public static void main(String[] args) { + SpringApplication.run(DatabaseExtractorApplication.class, args); + } + +} diff --git a/src/main/java/org/codiki/databaseextractor/controller/ExportController.java b/src/main/java/org/codiki/databaseextractor/controller/ExportController.java new file mode 100644 index 0000000..857df52 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/controller/ExportController.java @@ -0,0 +1,158 @@ +package org.codiki.databaseextractor.controller; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.Buffer; +import java.util.List; + +import org.codiki.databaseextractor.entity.previous.OldCategory; +import org.codiki.databaseextractor.entity.previous.Image; +import org.codiki.databaseextractor.entity.previous.Post; +import org.codiki.databaseextractor.entity.previous.OldUser; +import org.codiki.databaseextractor.entity.previous.Version; +import org.codiki.databaseextractor.entity.wrapper.*; +import org.codiki.databaseextractor.mapper.CategoryMapper; +import org.codiki.databaseextractor.mapper.PictureMapper; +import org.codiki.databaseextractor.mapper.PublicationMapper; +import org.codiki.databaseextractor.mapper.UserMapper; +import org.codiki.databaseextractor.repository.CategoryRepository; +import org.codiki.databaseextractor.repository.ImageRepository; +import org.codiki.databaseextractor.repository.PostRepository; +import org.codiki.databaseextractor.repository.UserRepository; +import org.codiki.databaseextractor.repository.VersionRepository; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/export") +public class ExportController { + private final CategoryRepository categoryRepository; + private final ImageRepository imageRepository; + private final PostRepository postRepository; + private final UserRepository userRepository; + private final VersionRepository versionRepository; + private final UserMapper userMapper; + private final PictureMapper pictureMapper; + private final CategoryMapper categoryMapper; + private final PublicationMapper publicationMapper; + + public ExportController( + CategoryRepository categoryRepository, + ImageRepository imageRepository, + PostRepository postRepository, + UserRepository userRepository, + VersionRepository versionRepository, + UserMapper userMapper, + PictureMapper pictureMapper, + CategoryMapper categoryMapper, PublicationMapper publicationMapper + ) { + this.categoryRepository = categoryRepository; + this.postRepository = postRepository; + this.userRepository = userRepository; + this.imageRepository = imageRepository; + this.versionRepository = versionRepository; + this.userMapper = userMapper; + this.pictureMapper = pictureMapper; + this.categoryMapper = categoryMapper; + this.publicationMapper = publicationMapper; + } + + @GetMapping + public void exportDatabase() { + List oldCategories = extractCategories(); + List images = extractImages(); + List posts = extractPosts(); + List oldUsers = extractUsers(); + List versions = extractVersions(); + + List users = userMapper.mapFrom(oldUsers); + List pictures = pictureMapper.mapFrom(images, users); + List categories = categoryMapper.mapFrom(oldCategories); + List publications = publicationMapper.mapFrom(posts, users, categories, pictures); + List nonCodikiPictures = publicationMapper.extractNonCodikiPictures(publications, pictures); + + generateSqlScript(users, pictures, categories, publications); + System.out.println("yo"); + } + + private void generateSqlScript( + List users, + List pictures, + List categories, + List publications + ) { + String sqlScriptFilePath = "/Users/florian_thierry/Documents/Developpement/codiki-database-extractor/codiki_export.sql"; + try(FileWriter fileWriter = new FileWriter(sqlScriptFilePath); + BufferedWriter writer = new BufferedWriter(fileWriter)) { + + writeUsersQuery(writer, users); + writePicturesQuery(writer, pictures); + writeCategoriesQuery(writer, categories); + writePublicationsQuery(writer, publications); + } catch (IOException exception) { + System.out.println("An error occured while writing SQL script file"); + } + } + + private void writeUsersQuery(BufferedWriter writer, List users) throws IOException { + writer.write("-- Users insertion\n"); + writer.write("INSERT INTO \"user\" (id, pseudo, email, password, photo_id) VALUES\n"); + writeEntitiesQueryPart(writer, users); + } + + private void writePicturesQuery(BufferedWriter writer, List pictures) throws IOException { + writer.write("\n"); + writer.write("-- Pictures insertion\n"); + writer.write("INSERT INTO picture (id, publisher_id) VALUES\n"); + writeEntitiesQueryPart(writer, pictures); + } + + private void writeCategoriesQuery(BufferedWriter writer, List categories) throws IOException { + writer.write("\n"); + writer.write("-- Categories insertion\n"); + writer.write("INSERT INTO category (id, name, parent_category_id) VALUES\n"); + writeEntitiesQueryPart(writer, categories); + } + + private void writePublicationsQuery(BufferedWriter writer, List publications) throws IOException { + writer.write("\n"); + writer.write("-- Publications insertion\n"); + writer.write("INSERT INTO publication (id, key, title, text, description, creation_date, illustration_id, author_id, category_id) VALUES\n"); + writeEntitiesQueryPart(writer, publications); + } + + private void writeEntitiesQueryPart(BufferedWriter writer, List entities) throws IOException { + for (int i = 0; i < entities.size(); i++) { + var entity = entities.get(i); + writer.write(entity.buildSqlFragment()); + if (i == entities.size() - 1) { + writer.write(";"); + } else { + writer.write(","); + } + writer.write("\n"); + } + } + + private List extractCategories() { + return categoryRepository.findAll(); + } + + private List extractImages() { + return imageRepository.findAll(); + } + + private List extractPosts() { + return postRepository.findAll(); + } + + private List extractUsers() { + return userRepository.findAll(); + } + + private List extractVersions() { + return versionRepository.findAll(); + } +} diff --git a/src/main/java/org/codiki/databaseextractor/entity/next/Author.java b/src/main/java/org/codiki/databaseextractor/entity/next/Author.java new file mode 100644 index 0000000..2596882 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/next/Author.java @@ -0,0 +1,9 @@ +package org.codiki.databaseextractor.entity.next; + +import java.util.UUID; + +public record Author( + UUID id, + String name, + String image +) { } diff --git a/src/main/java/org/codiki/databaseextractor/entity/next/Category.java b/src/main/java/org/codiki/databaseextractor/entity/next/Category.java new file mode 100644 index 0000000..ca1948c --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/next/Category.java @@ -0,0 +1,11 @@ +package org.codiki.databaseextractor.entity.next; + +import java.util.List; +import java.util.UUID; + +public record Category( + UUID id, + String name, + List subCategories, + UUID parentCategoryId +) {} diff --git a/src/main/java/org/codiki/databaseextractor/entity/next/Picture.java b/src/main/java/org/codiki/databaseextractor/entity/next/Picture.java new file mode 100644 index 0000000..30de7e4 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/next/Picture.java @@ -0,0 +1,10 @@ +package org.codiki.databaseextractor.entity.next; + +import java.io.File; +import java.util.UUID; + +public record Picture( + UUID id, + UUID publisherId, + File contentFile +) {} diff --git a/src/main/java/org/codiki/databaseextractor/entity/next/Publication.java b/src/main/java/org/codiki/databaseextractor/entity/next/Publication.java new file mode 100644 index 0000000..bd82752 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/next/Publication.java @@ -0,0 +1,17 @@ +package org.codiki.databaseextractor.entity.next; + +import java.time.ZonedDateTime; +import java.util.UUID; + +public record Publication( + UUID id, + String key, + String title, + String text, + String description, + ZonedDateTime creationDate, + UUID illustrationId, + UUID categoryId, + UUID authorId +) { +} diff --git a/src/main/java/org/codiki/databaseextractor/entity/next/User.java b/src/main/java/org/codiki/databaseextractor/entity/next/User.java new file mode 100644 index 0000000..53f1821 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/next/User.java @@ -0,0 +1,13 @@ +package org.codiki.databaseextractor.entity.next; + +import java.util.List; +import java.util.UUID; + +public record User( + UUID id, + String pseudo, + String email, + String password, + UUID photoId, + List roles +) {} diff --git a/src/main/java/org/codiki/databaseextractor/entity/next/UserRole.java b/src/main/java/org/codiki/databaseextractor/entity/next/UserRole.java new file mode 100644 index 0000000..14d75fe --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/next/UserRole.java @@ -0,0 +1,22 @@ +package org.codiki.databaseextractor.entity.next; + +import java.util.Optional; +import java.util.stream.Stream; + +public enum UserRole { + STANDARD, + ADMIN; + + public static Optional from(String roleAsString) { + return Stream.of(UserRole.values()) + .filter(role -> role.name().equals(roleAsString)) + .findFirst(); + } + + public static Optional from(int roleId) { + return Stream.of(UserRole.values()) + .filter(role -> role.ordinal() == roleId) + .findFirst(); + } +} + diff --git a/src/main/java/org/codiki/databaseextractor/entity/previous/Image.java b/src/main/java/org/codiki/databaseextractor/entity/previous/Image.java new file mode 100644 index 0000000..292dacf --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/previous/Image.java @@ -0,0 +1,27 @@ +package org.codiki.databaseextractor.entity.previous; + +import java.util.Date; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@Table(name = "image") +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class Image { + @Id + private Long id; + private String link; + private Date date; + @Column(name = "user_id") + private int publisherId; +} diff --git a/src/main/java/org/codiki/databaseextractor/entity/previous/OldCategory.java b/src/main/java/org/codiki/databaseextractor/entity/previous/OldCategory.java new file mode 100644 index 0000000..23aa77c --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/previous/OldCategory.java @@ -0,0 +1,32 @@ +package org.codiki.databaseextractor.entity.previous; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonView; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Inheritance; +import jakarta.persistence.InheritanceType; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@Table(name = "category") +@Inheritance(strategy = InheritanceType.JOINED) +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class OldCategory { + @Id + private Long id; + private String name; + private Long creatorId; + @OneToMany(mappedBy = "mainCategory") + private List listSubCategories; +} diff --git a/src/main/java/org/codiki/databaseextractor/entity/previous/OldSubCategory.java b/src/main/java/org/codiki/databaseextractor/entity/previous/OldSubCategory.java new file mode 100644 index 0000000..e014feb --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/previous/OldSubCategory.java @@ -0,0 +1,23 @@ +package org.codiki.databaseextractor.entity.previous; + +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@Table(name = "sub_category") +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class OldSubCategory extends OldCategory { + @ManyToOne + @JoinColumn(name = "main_category") + private OldCategory mainCategory; +} diff --git a/src/main/java/org/codiki/databaseextractor/entity/previous/OldUser.java b/src/main/java/org/codiki/databaseextractor/entity/previous/OldUser.java new file mode 100644 index 0000000..e5044fa --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/previous/OldUser.java @@ -0,0 +1,31 @@ +package org.codiki.databaseextractor.entity.previous; + +import java.util.Date; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@Table(name = "`user`") +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class OldUser { + @Id + private Long id; + private String key; + private String name; + private String email; + private String password; + private Date inscriptionDate; + private int roleId; + @Column(name = "image") + private String imageLink; +} diff --git a/src/main/java/org/codiki/databaseextractor/entity/previous/Post.java b/src/main/java/org/codiki/databaseextractor/entity/previous/Post.java new file mode 100644 index 0000000..5e24c57 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/previous/Post.java @@ -0,0 +1,34 @@ +package org.codiki.databaseextractor.entity.previous; + +import java.util.Date; + +import static jakarta.persistence.TemporalType.TIMESTAMP; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@Table(name = "post") +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class Post { + @Id + private Long id; + private String key; + private String title; + private String text; + private String description; + @Temporal(TIMESTAMP) + private Date creationDate; + private String image; + private Long creatorId; + private Long categoryId; +} diff --git a/src/main/java/org/codiki/databaseextractor/entity/previous/Version.java b/src/main/java/org/codiki/databaseextractor/entity/previous/Version.java new file mode 100644 index 0000000..e6f7423 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/previous/Version.java @@ -0,0 +1,26 @@ +package org.codiki.databaseextractor.entity.previous; + +import java.util.List; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@Table(name = "version") +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class Version { + @Id + private Long id; + private String number; + @OneToMany(mappedBy = "version") + private List revisions; +} diff --git a/src/main/java/org/codiki/databaseextractor/entity/previous/VersionRevision.java b/src/main/java/org/codiki/databaseextractor/entity/previous/VersionRevision.java new file mode 100644 index 0000000..5e506f3 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/previous/VersionRevision.java @@ -0,0 +1,27 @@ +package org.codiki.databaseextractor.entity.previous; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@Table(name = "version_revision") +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class VersionRevision { + @Id + private Long id; + private String text; + private boolean bugfix; + @ManyToOne + @JoinColumn(name = "version_id") + private Version version; +} diff --git a/src/main/java/org/codiki/databaseextractor/entity/wrapper/CategoryWrapper.java b/src/main/java/org/codiki/databaseextractor/entity/wrapper/CategoryWrapper.java new file mode 100644 index 0000000..7050774 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/wrapper/CategoryWrapper.java @@ -0,0 +1,19 @@ +package org.codiki.databaseextractor.entity.wrapper; + +import org.codiki.databaseextractor.entity.next.Category; +import org.codiki.databaseextractor.entity.previous.OldCategory; + +public record CategoryWrapper( + OldCategory oldCategory, + Category category +) implements SqlFragmentGenerator { + @Override + public String buildSqlFragment() { + return String.format( + "('%s', '%s', %s)", + category.id(), + category.name(), + "NULL" + ); + } +} diff --git a/src/main/java/org/codiki/databaseextractor/entity/wrapper/NonCodikiPicture.java b/src/main/java/org/codiki/databaseextractor/entity/wrapper/NonCodikiPicture.java new file mode 100644 index 0000000..f1a967b --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/wrapper/NonCodikiPicture.java @@ -0,0 +1,7 @@ +package org.codiki.databaseextractor.entity.wrapper; + +public record NonCodikiPicture( + PublicationWrapper associatedPublication, + String pictureExternalLink +) { +} diff --git a/src/main/java/org/codiki/databaseextractor/entity/wrapper/PictureWrapper.java b/src/main/java/org/codiki/databaseextractor/entity/wrapper/PictureWrapper.java new file mode 100644 index 0000000..3b026e2 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/wrapper/PictureWrapper.java @@ -0,0 +1,18 @@ +package org.codiki.databaseextractor.entity.wrapper; + +import org.codiki.databaseextractor.entity.next.Picture; +import org.codiki.databaseextractor.entity.previous.Image; + +public record PictureWrapper( + Image image, + Picture picture +) implements SqlFragmentGenerator { + @Override + public String buildSqlFragment() { + return String.format( + "('%s', '%s')", + picture.id(), + picture.publisherId() + ); + } +} diff --git a/src/main/java/org/codiki/databaseextractor/entity/wrapper/PublicationWrapper.java b/src/main/java/org/codiki/databaseextractor/entity/wrapper/PublicationWrapper.java new file mode 100644 index 0000000..ba4dd51 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/wrapper/PublicationWrapper.java @@ -0,0 +1,28 @@ +package org.codiki.databaseextractor.entity.wrapper; + +import org.codiki.databaseextractor.entity.next.Publication; +import org.codiki.databaseextractor.entity.previous.Post; + +import java.time.format.DateTimeFormatter; + +public record PublicationWrapper( + Post post, + Publication publication +) implements SqlFragmentGenerator { + private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + @Override + public String buildSqlFragment() { + return String.format( + "('%s', '%s', '%s', '%s', '%s', '%s', %s, '%s', '%s')", + publication.id(), + publication.key(), + publication.title().replaceAll("'", "''"), + publication.text().replaceAll("'", "''"), + publication.description().replaceAll("'", "''"), + String.format("%s +01:00", publication.creationDate().format(DATE_TIME_FORMATTER)), + publication.illustrationId() == null ? "NULL" : String.format("'%s'", publication().illustrationId()), + publication.authorId(), + publication.categoryId() + ); + } +} diff --git a/src/main/java/org/codiki/databaseextractor/entity/wrapper/SqlFragmentGenerator.java b/src/main/java/org/codiki/databaseextractor/entity/wrapper/SqlFragmentGenerator.java new file mode 100644 index 0000000..0726084 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/wrapper/SqlFragmentGenerator.java @@ -0,0 +1,5 @@ +package org.codiki.databaseextractor.entity.wrapper; + +public interface SqlFragmentGenerator { + String buildSqlFragment(); +} diff --git a/src/main/java/org/codiki/databaseextractor/entity/wrapper/UserWrapper.java b/src/main/java/org/codiki/databaseextractor/entity/wrapper/UserWrapper.java new file mode 100644 index 0000000..6fdfadb --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/entity/wrapper/UserWrapper.java @@ -0,0 +1,21 @@ +package org.codiki.databaseextractor.entity.wrapper; + +import org.codiki.databaseextractor.entity.next.User; +import org.codiki.databaseextractor.entity.previous.OldUser; + +public record UserWrapper( + OldUser oldUser, + User user +) implements SqlFragmentGenerator { + @Override + public String buildSqlFragment() { + return String.format( + "('%s', '%s', '%s', '%s', %s)", + user.id(), + user.pseudo(), + user.email(), + user.password(), + user.photoId() == null ? "NULL" : String.format("'%s'", user.photoId()) + ); + } +} diff --git a/src/main/java/org/codiki/databaseextractor/helper/CategoryHelper.java b/src/main/java/org/codiki/databaseextractor/helper/CategoryHelper.java new file mode 100644 index 0000000..d754e3a --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/helper/CategoryHelper.java @@ -0,0 +1,18 @@ +package org.codiki.databaseextractor.helper; + +import static java.util.Collections.emptyList; + +import java.util.List; +import java.util.Optional; + +import org.codiki.databaseextractor.entity.wrapper.CategoryWrapper; +import org.springframework.stereotype.Component; + +@Component +public class CategoryHelper { + public Optional findByOldCategoryId(List allCategories, Long mainCategoryId) { + return allCategories.stream() + .filter(category -> category.oldCategory().getId().equals(mainCategoryId)) + .findFirst(); + } +} diff --git a/src/main/java/org/codiki/databaseextractor/helper/UserHelper.java b/src/main/java/org/codiki/databaseextractor/helper/UserHelper.java new file mode 100644 index 0000000..5ca1d5a --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/helper/UserHelper.java @@ -0,0 +1,16 @@ +package org.codiki.databaseextractor.helper; + +import java.util.List; +import java.util.Optional; + +import org.codiki.databaseextractor.entity.wrapper.UserWrapper; +import org.springframework.stereotype.Component; + +@Component +public class UserHelper { + public Optional findByOldUserId(List users, int oldUserId) { + return users.stream() + .filter(user -> user.oldUser().getId().intValue() == oldUserId) + .findFirst(); + } +} diff --git a/src/main/java/org/codiki/databaseextractor/mapper/CategoryMapper.java b/src/main/java/org/codiki/databaseextractor/mapper/CategoryMapper.java new file mode 100644 index 0000000..d77d3e5 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/mapper/CategoryMapper.java @@ -0,0 +1,56 @@ +package org.codiki.databaseextractor.mapper; + +import static java.util.Collections.emptyList; + +import java.util.List; +import java.util.UUID; + +import org.codiki.databaseextractor.entity.next.Category; +import org.codiki.databaseextractor.entity.previous.OldCategory; +import org.codiki.databaseextractor.entity.wrapper.CategoryWrapper; +import org.codiki.databaseextractor.helper.CategoryHelper; +import org.springframework.stereotype.Component; + +@Component +public class CategoryMapper { + private final CategoryHelper categoryHelper; + + public CategoryMapper(CategoryHelper categoryHelper) { + this.categoryHelper = categoryHelper; + } + + public List mapFrom(List oldCategories) { + List allCategories = oldCategories.stream() + .map(oldCategory -> { + Category category = new Category( + UUID.randomUUID(), + oldCategory.getName(), + emptyList(), + null + ); + + return new CategoryWrapper(oldCategory, category); + }) + .toList(); + return allCategories.stream() + .map(category -> { + List subCategories = category.oldCategory() + .getListSubCategories() + .stream() + .map(subCategory -> categoryHelper.findByOldCategoryId(allCategories, subCategory.getId()) + .orElseThrow(() -> new RuntimeException("No category wrapper found for sub category " + subCategory.getId()))) + .toList(); + + Category categoryWithSubCategories = new Category( + category.category().id(), + category.category().name(), + subCategories.stream() + .map(CategoryWrapper::category) + .toList(), + null + ); + return new CategoryWrapper(category.oldCategory(), categoryWithSubCategories); + }) + .toList(); + } +} diff --git a/src/main/java/org/codiki/databaseextractor/mapper/PictureMapper.java b/src/main/java/org/codiki/databaseextractor/mapper/PictureMapper.java new file mode 100644 index 0000000..b587d98 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/mapper/PictureMapper.java @@ -0,0 +1,41 @@ +package org.codiki.databaseextractor.mapper; + +import java.util.List; +import java.util.UUID; + +import org.codiki.databaseextractor.entity.next.Picture; +import org.codiki.databaseextractor.entity.next.User; +import org.codiki.databaseextractor.entity.previous.Image; +import org.codiki.databaseextractor.entity.previous.OldUser; +import org.codiki.databaseextractor.entity.wrapper.PictureWrapper; +import org.codiki.databaseextractor.entity.wrapper.UserWrapper; +import org.codiki.databaseextractor.helper.UserHelper; +import org.springframework.stereotype.Component; + +@Component +public class PictureMapper { + private final UserHelper userHelper; + + public PictureMapper(UserHelper userHelper) { + this.userHelper = userHelper; + } + + public List mapFrom(List images, List users) { + return images.stream() + .map(image -> { + int oldPublisherId = image.getPublisherId(); + + UserWrapper publisher = userHelper.findByOldUserId(users, oldPublisherId) + .orElseThrow(() -> new RuntimeException("Aucun publieur trouvé pour l'image " + image.getId())); + + Picture picture = new Picture( + UUID.randomUUID(), + publisher.user().id(), + null + ); + + return new PictureWrapper(image, picture); + }) + .toList(); + } +} diff --git a/src/main/java/org/codiki/databaseextractor/mapper/PublicationMapper.java b/src/main/java/org/codiki/databaseextractor/mapper/PublicationMapper.java new file mode 100644 index 0000000..2734c32 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/mapper/PublicationMapper.java @@ -0,0 +1,70 @@ +package org.codiki.databaseextractor.mapper; + +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import org.codiki.databaseextractor.entity.next.Publication; +import org.codiki.databaseextractor.entity.previous.Post; +import org.codiki.databaseextractor.entity.wrapper.*; +import org.springframework.stereotype.Component; + +import static java.util.Objects.isNull; + +@Component +public class PublicationMapper { + + public List mapFrom( + List posts, + List users, + List categories, + List pictures) { + return posts.stream() + .map(post -> { + CategoryWrapper publicationCategory = categories.stream() + .filter(category -> category.oldCategory().getId().equals(post.getCategoryId())) + .findFirst() + .orElseThrow(() -> new RuntimeException("No any category found for post " + post.getId())); + + UserWrapper publicationAuthor = users.stream() + .filter(user -> user.oldUser().getId().equals(post.getCreatorId())) + .findFirst() + .orElseThrow(() -> new RuntimeException("No any author found for post " + post.getId())); + + Optional publicationIllustrationId = Optional.of(post.getImage()) + .filter(imageLink -> imageLink.startsWith("https://codiki.org/api/images/")) + .map(imageLink -> imageLink.substring("https://codiki.org/api/images/".length())) + .flatMap(imageKey -> findPictureByLink(pictures, imageKey)) + .map(picture -> picture.picture().id()); + + Publication publication = new Publication( + UUID.randomUUID(), + post.getKey(), + post.getTitle(), + post.getText(), + post.getDescription(), + ZonedDateTime.ofInstant(post.getCreationDate().toInstant(), ZoneId.systemDefault()), + publicationIllustrationId.orElse(null), + publicationCategory.category().id(), + publicationAuthor.user().id() + ); + return new PublicationWrapper(post, publication); + }) + .toList(); + } + + private Optional findPictureByLink(List pictures, String pictureLink) { + return pictures.stream() + .filter(picture -> picture.image().getLink().equals(pictureLink)) + .findFirst(); + } + + public List extractNonCodikiPictures(List publications, List pictures) { + return publications.stream() + .filter(publication -> isNull(publication.publication().illustrationId())) + .map(publication -> new NonCodikiPicture(publication, publication.post().getImage())) + .toList(); + } +} diff --git a/src/main/java/org/codiki/databaseextractor/mapper/UserMapper.java b/src/main/java/org/codiki/databaseextractor/mapper/UserMapper.java new file mode 100644 index 0000000..8226fa4 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/mapper/UserMapper.java @@ -0,0 +1,35 @@ +package org.codiki.databaseextractor.mapper; + +import java.util.List; +import java.util.UUID; + +import org.codiki.databaseextractor.entity.next.User; +import org.codiki.databaseextractor.entity.next.UserRole; +import org.codiki.databaseextractor.entity.previous.OldUser; +import org.codiki.databaseextractor.entity.wrapper.UserWrapper; +import org.springframework.stereotype.Component; + +@Component +public class UserMapper { + public List mapFrom(List oldUsers) { + return oldUsers.stream() + .map(oldUser -> { + User user = mapFrom(oldUser); + return new UserWrapper(oldUser, user); + }) + .toList(); + } + + private static User mapFrom(OldUser user) { + return new User( + UUID.randomUUID(), + user.getName(), + user.getEmail(), + user.getPassword(), + null, + UserRole.from(user.getRoleId()) + .stream() + .toList() + ); + } +} diff --git a/src/main/java/org/codiki/databaseextractor/repository/CategoryRepository.java b/src/main/java/org/codiki/databaseextractor/repository/CategoryRepository.java new file mode 100644 index 0000000..13ba4c1 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/repository/CategoryRepository.java @@ -0,0 +1,7 @@ +package org.codiki.databaseextractor.repository; + +import org.codiki.databaseextractor.entity.previous.OldCategory; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CategoryRepository extends JpaRepository { +} diff --git a/src/main/java/org/codiki/databaseextractor/repository/ImageRepository.java b/src/main/java/org/codiki/databaseextractor/repository/ImageRepository.java new file mode 100644 index 0000000..17abeb7 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/repository/ImageRepository.java @@ -0,0 +1,7 @@ +package org.codiki.databaseextractor.repository; + +import org.codiki.databaseextractor.entity.previous.Image; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ImageRepository extends JpaRepository { +} diff --git a/src/main/java/org/codiki/databaseextractor/repository/PostRepository.java b/src/main/java/org/codiki/databaseextractor/repository/PostRepository.java new file mode 100644 index 0000000..ffa7abb --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/repository/PostRepository.java @@ -0,0 +1,7 @@ +package org.codiki.databaseextractor.repository; + +import org.codiki.databaseextractor.entity.previous.Post; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PostRepository extends JpaRepository { +} diff --git a/src/main/java/org/codiki/databaseextractor/repository/UserRepository.java b/src/main/java/org/codiki/databaseextractor/repository/UserRepository.java new file mode 100644 index 0000000..5ec8189 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/repository/UserRepository.java @@ -0,0 +1,7 @@ +package org.codiki.databaseextractor.repository; + +import org.codiki.databaseextractor.entity.previous.OldUser; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { +} diff --git a/src/main/java/org/codiki/databaseextractor/repository/VersionRepository.java b/src/main/java/org/codiki/databaseextractor/repository/VersionRepository.java new file mode 100644 index 0000000..91a8c53 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/repository/VersionRepository.java @@ -0,0 +1,7 @@ +package org.codiki.databaseextractor.repository; + +import org.codiki.databaseextractor.entity.previous.Version; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface VersionRepository extends JpaRepository { +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..7f6d121 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,9 @@ +spring: + datasource: + driverClassName: org.postgresql.Driver + url: jdbc:postgresql://localhost:50001/codiki_prod + username: codiki_admin + password: password + +server: + port: 8765 diff --git a/src/test/java/org/codiki/databaseextractor/DatabaseExtractorApplicationTests.java b/src/test/java/org/codiki/databaseextractor/DatabaseExtractorApplicationTests.java new file mode 100644 index 0000000..b5320e6 --- /dev/null +++ b/src/test/java/org/codiki/databaseextractor/DatabaseExtractorApplicationTests.java @@ -0,0 +1,13 @@ +package org.codiki.databaseextractor; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class DatabaseExtractorApplicationTests { + + @Test + void contextLoads() { + } + +}