diff --git a/src/main/java/org/codiki/databaseextractor/controller/ExportController.java b/src/main/java/org/codiki/databaseextractor/controller/ExportController.java index 857df52..29802c9 100644 --- a/src/main/java/org/codiki/databaseextractor/controller/ExportController.java +++ b/src/main/java/org/codiki/databaseextractor/controller/ExportController.java @@ -1,9 +1,6 @@ package org.codiki.databaseextractor.controller; -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.Buffer; +import java.util.ArrayList; import java.util.List; import org.codiki.databaseextractor.entity.previous.OldCategory; @@ -37,16 +34,21 @@ public class ExportController { private final PictureMapper pictureMapper; private final CategoryMapper categoryMapper; private final PublicationMapper publicationMapper; + private final SqlScriptGenerator sqlScriptGenerator; + private final PictureFileHandler pictureFileHandler; public ExportController( - CategoryRepository categoryRepository, - ImageRepository imageRepository, - PostRepository postRepository, - UserRepository userRepository, - VersionRepository versionRepository, - UserMapper userMapper, - PictureMapper pictureMapper, - CategoryMapper categoryMapper, PublicationMapper publicationMapper + CategoryRepository categoryRepository, + ImageRepository imageRepository, + PostRepository postRepository, + UserRepository userRepository, + VersionRepository versionRepository, + UserMapper userMapper, + PictureMapper pictureMapper, + CategoryMapper categoryMapper, + PublicationMapper publicationMapper, + SqlScriptGenerator sqlScriptGenerator, + PictureFileHandler pictureFileHandler ) { this.categoryRepository = categoryRepository; this.postRepository = postRepository; @@ -57,102 +59,32 @@ public class ExportController { this.pictureMapper = pictureMapper; this.categoryMapper = categoryMapper; this.publicationMapper = publicationMapper; + this.sqlScriptGenerator = sqlScriptGenerator; + this.pictureFileHandler = pictureFileHandler; } @GetMapping public void exportDatabase() { - List oldCategories = extractCategories(); - List images = extractImages(); - List posts = extractPosts(); - List oldUsers = extractUsers(); - List versions = extractVersions(); + List oldCategories = categoryRepository.findAll(); + List images = imageRepository.findAll(); + List posts = postRepository.findAll(); + List oldUsers = userRepository.findAll(); + List versions = versionRepository.findAll(); List users = userMapper.mapFrom(oldUsers); List pictures = pictureMapper.mapFrom(images, users); + PictureWrapper defaultPicture = pictureMapper.createDefaultPicture(users); List categories = categoryMapper.mapFrom(oldCategories); - List publications = publicationMapper.mapFrom(posts, users, categories, pictures); + List publications = publicationMapper.mapFrom(posts, users, categories, pictures, defaultPicture); List nonCodikiPictures = publicationMapper.extractNonCodikiPictures(publications, pictures); - generateSqlScript(users, pictures, categories, publications); + List allPictures = new ArrayList<>(pictures); + allPictures.add(defaultPicture); + sqlScriptGenerator.generateSqlScript(users, allPictures, categories, publications); + + pictureFileHandler.copyPictureFilesWithNewFileNames(pictures); + 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/controller/PictureFileHandler.java b/src/main/java/org/codiki/databaseextractor/controller/PictureFileHandler.java new file mode 100644 index 0000000..98a07f1 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/controller/PictureFileHandler.java @@ -0,0 +1,49 @@ +package org.codiki.databaseextractor.controller; + +import org.codiki.databaseextractor.entity.wrapper.PictureWrapper; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +@Component +public class PictureFileHandler { + private final String picturesSourceFolderPath; + private final String picturesTargetFolderPath; + + public PictureFileHandler( + @Value("${application.pictures.folders.sources}") + String picturesSourceFolderPath, + @Value("${application.pictures.folders.targets}") + String picturesTargetFolderPath) { + this.picturesSourceFolderPath = picturesSourceFolderPath; + this.picturesTargetFolderPath = picturesTargetFolderPath; + } + + public void copyPictureFilesWithNewFileNames(List pictures) { + for (var picture : pictures) { + String sourceFilePath = buildPictureSourceFilePath(picture); + String targetFilePath = buildPictureTargetFilePath(picture); + try { + Files.copy(Path.of(sourceFilePath), Path.of(targetFilePath)); + } catch (IOException exception) { + throw new RuntimeException("An error occured while copying picture " + picture.picture().id(), exception); + } + } + } + + private String buildPictureSourceFilePath(PictureWrapper picture) { + return String.format("%s/%s", picturesSourceFolderPath, picture.image().getLink()); + } + + private String buildPictureTargetFilePath(PictureWrapper picture) { + return String.format("%s/%s", picturesTargetFolderPath, picture.picture().id()); + } + + public boolean exists(PictureWrapper picture) { + return Files.exists(Path.of(buildPictureSourceFilePath(picture))); + } +} diff --git a/src/main/java/org/codiki/databaseextractor/controller/SqlScriptGenerator.java b/src/main/java/org/codiki/databaseextractor/controller/SqlScriptGenerator.java new file mode 100644 index 0000000..c4b27d6 --- /dev/null +++ b/src/main/java/org/codiki/databaseextractor/controller/SqlScriptGenerator.java @@ -0,0 +1,77 @@ +package org.codiki.databaseextractor.controller; + +import org.codiki.databaseextractor.entity.wrapper.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.util.List; + +@Component +public class SqlScriptGenerator { + private final String sqlScriptFilePath; + + public SqlScriptGenerator(@Value("${application.sql-script.target-folder-path}") String sqlScriptFilePath) { + this.sqlScriptFilePath = sqlScriptFilePath; + } + + public void generateSqlScript( + List users, + List pictures, + List categories, + List publications + ) { + 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"); + } + } +} diff --git a/src/main/java/org/codiki/databaseextractor/mapper/PictureMapper.java b/src/main/java/org/codiki/databaseextractor/mapper/PictureMapper.java index b587d98..bf70841 100644 --- a/src/main/java/org/codiki/databaseextractor/mapper/PictureMapper.java +++ b/src/main/java/org/codiki/databaseextractor/mapper/PictureMapper.java @@ -3,6 +3,7 @@ package org.codiki.databaseextractor.mapper; import java.util.List; import java.util.UUID; +import org.codiki.databaseextractor.controller.PictureFileHandler; import org.codiki.databaseextractor.entity.next.Picture; import org.codiki.databaseextractor.entity.next.User; import org.codiki.databaseextractor.entity.previous.Image; @@ -15,9 +16,11 @@ import org.springframework.stereotype.Component; @Component public class PictureMapper { private final UserHelper userHelper; + private final PictureFileHandler pictureFileHandler; - public PictureMapper(UserHelper userHelper) { + public PictureMapper(UserHelper userHelper, PictureFileHandler pictureFileHandler) { this.userHelper = userHelper; + this.pictureFileHandler = pictureFileHandler; } public List mapFrom(List images, List users) { @@ -36,6 +39,16 @@ public class PictureMapper { return new PictureWrapper(image, picture); }) + .filter(pictureFileHandler::exists) .toList(); } + + public PictureWrapper createDefaultPicture(List users) { + UserWrapper administrator = users.stream() + .filter(user -> user.user().email().equals("admin@admin.adm")) + .findFirst() + .orElseThrow(() -> new RuntimeException("No admin user found for default picture creation.")); + + return new PictureWrapper(null, new Picture(UUID.randomUUID(), administrator.user().id(), null)); + } } diff --git a/src/main/java/org/codiki/databaseextractor/mapper/PublicationMapper.java b/src/main/java/org/codiki/databaseextractor/mapper/PublicationMapper.java index 2734c32..2cd6ecc 100644 --- a/src/main/java/org/codiki/databaseextractor/mapper/PublicationMapper.java +++ b/src/main/java/org/codiki/databaseextractor/mapper/PublicationMapper.java @@ -20,7 +20,7 @@ public class PublicationMapper { List posts, List users, List categories, - List pictures) { + List pictures, PictureWrapper defaultPicture) { return posts.stream() .map(post -> { CategoryWrapper publicationCategory = categories.stream() @@ -33,11 +33,12 @@ public class PublicationMapper { .findFirst() .orElseThrow(() -> new RuntimeException("No any author found for post " + post.getId())); - Optional publicationIllustrationId = Optional.of(post.getImage()) + UUID 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()); + .map(picture -> picture.picture().id()) + .orElse(defaultPicture.picture().id()); Publication publication = new Publication( UUID.randomUUID(), @@ -46,7 +47,7 @@ public class PublicationMapper { post.getText(), post.getDescription(), ZonedDateTime.ofInstant(post.getCreationDate().toInstant(), ZoneId.systemDefault()), - publicationIllustrationId.orElse(null), + publicationIllustrationId, publicationCategory.category().id(), publicationAuthor.user().id() ); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 7f6d121..57ce818 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -7,3 +7,11 @@ spring: server: port: 8765 + +application: + sql-script: + target-folder-path: /Users/florian_thierry/Documents/Developpement/codiki-database-extractor/codiki_export.sql + pictures: + folders: + sources: /Users/florian_thierry/Documents/Developpement/codiki-database-extractor/pictures/sources + targets: /Users/florian_thierry/Documents/Developpement/codiki-database-extractor/pictures/targets