mirror of https://github.com/halo-dev/halo
Add post backup for contents and content_patch_logs (#1669)
* feat: Add post backup for contents and content_patch_logspull/1786/head
parent
0f33ee167c
commit
d438163c04
|
@ -1,10 +1,10 @@
|
||||||
package run.halo.app.service;
|
package run.halo.app.service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import run.halo.app.exception.NotFoundException;
|
|
||||||
import run.halo.app.model.entity.Content.ContentDiff;
|
import run.halo.app.model.entity.Content.ContentDiff;
|
||||||
import run.halo.app.model.entity.Content.PatchedContent;
|
import run.halo.app.model.entity.Content.PatchedContent;
|
||||||
import run.halo.app.model.entity.ContentPatchLog;
|
import run.halo.app.model.entity.ContentPatchLog;
|
||||||
|
import run.halo.app.service.base.CrudService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Content patch log service.
|
* Content patch log service.
|
||||||
|
@ -12,7 +12,7 @@ import run.halo.app.model.entity.ContentPatchLog;
|
||||||
* @author guqing
|
* @author guqing
|
||||||
* @since 2022-01-04
|
* @since 2022-01-04
|
||||||
*/
|
*/
|
||||||
public interface ContentPatchLogService {
|
public interface ContentPatchLogService extends CrudService<ContentPatchLog, Integer> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create or update content patch log by post content.
|
* Create or update content patch log by post content.
|
||||||
|
@ -42,13 +42,6 @@ public interface ContentPatchLogService {
|
||||||
*/
|
*/
|
||||||
ContentDiff generateDiff(Integer postId, String content, String originalContent);
|
ContentDiff generateDiff(Integer postId, String content, String originalContent);
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates or updates the {@link ContentPatchLog}.
|
|
||||||
*
|
|
||||||
* @param contentPatchLog param to create or update
|
|
||||||
*/
|
|
||||||
void save(ContentPatchLog contentPatchLog);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the patch log record of the draft status of the content by post id.
|
* Gets the patch log record of the draft status of the content by post id.
|
||||||
*
|
*
|
||||||
|
@ -57,15 +50,6 @@ public interface ContentPatchLogService {
|
||||||
*/
|
*/
|
||||||
ContentPatchLog getDraftByPostId(Integer postId);
|
ContentPatchLog getDraftByPostId(Integer postId);
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets content patch log by id.
|
|
||||||
*
|
|
||||||
* @param id id
|
|
||||||
* @return a content patch log
|
|
||||||
* @throws NotFoundException if record not found.
|
|
||||||
*/
|
|
||||||
ContentPatchLog getById(Integer id);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets content patch log by post id.
|
* Gets content patch log by post id.
|
||||||
*
|
*
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -47,6 +48,8 @@ import run.halo.app.model.dto.post.BasePostDetailDTO;
|
||||||
import run.halo.app.model.entity.Attachment;
|
import run.halo.app.model.entity.Attachment;
|
||||||
import run.halo.app.model.entity.Category;
|
import run.halo.app.model.entity.Category;
|
||||||
import run.halo.app.model.entity.CommentBlackList;
|
import run.halo.app.model.entity.CommentBlackList;
|
||||||
|
import run.halo.app.model.entity.Content;
|
||||||
|
import run.halo.app.model.entity.ContentPatchLog;
|
||||||
import run.halo.app.model.entity.Journal;
|
import run.halo.app.model.entity.Journal;
|
||||||
import run.halo.app.model.entity.JournalComment;
|
import run.halo.app.model.entity.JournalComment;
|
||||||
import run.halo.app.model.entity.Link;
|
import run.halo.app.model.entity.Link;
|
||||||
|
@ -73,6 +76,8 @@ import run.halo.app.service.AttachmentService;
|
||||||
import run.halo.app.service.BackupService;
|
import run.halo.app.service.BackupService;
|
||||||
import run.halo.app.service.CategoryService;
|
import run.halo.app.service.CategoryService;
|
||||||
import run.halo.app.service.CommentBlackListService;
|
import run.halo.app.service.CommentBlackListService;
|
||||||
|
import run.halo.app.service.ContentPatchLogService;
|
||||||
|
import run.halo.app.service.ContentService;
|
||||||
import run.halo.app.service.JournalCommentService;
|
import run.halo.app.service.JournalCommentService;
|
||||||
import run.halo.app.service.JournalService;
|
import run.halo.app.service.JournalService;
|
||||||
import run.halo.app.service.LinkService;
|
import run.halo.app.service.LinkService;
|
||||||
|
@ -96,6 +101,7 @@ import run.halo.app.utils.DateUtils;
|
||||||
import run.halo.app.utils.FileUtils;
|
import run.halo.app.utils.FileUtils;
|
||||||
import run.halo.app.utils.HaloUtils;
|
import run.halo.app.utils.HaloUtils;
|
||||||
import run.halo.app.utils.JsonUtils;
|
import run.halo.app.utils.JsonUtils;
|
||||||
|
import run.halo.app.utils.VersionUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Backup service implementation.
|
* Backup service implementation.
|
||||||
|
@ -141,6 +147,10 @@ public class BackupServiceImpl implements BackupService {
|
||||||
|
|
||||||
private final PostService postService;
|
private final PostService postService;
|
||||||
|
|
||||||
|
private final ContentService contentService;
|
||||||
|
|
||||||
|
private final ContentPatchLogService contentPatchLogService;
|
||||||
|
|
||||||
private final PostCategoryService postCategoryService;
|
private final PostCategoryService postCategoryService;
|
||||||
|
|
||||||
private final PostCommentService postCommentService;
|
private final PostCommentService postCommentService;
|
||||||
|
@ -171,7 +181,9 @@ public class BackupServiceImpl implements BackupService {
|
||||||
CommentBlackListService commentBlackListService, JournalService journalService,
|
CommentBlackListService commentBlackListService, JournalService journalService,
|
||||||
JournalCommentService journalCommentService, LinkService linkService, LogService logService,
|
JournalCommentService journalCommentService, LinkService linkService, LogService logService,
|
||||||
MenuService menuService, OptionService optionService, PhotoService photoService,
|
MenuService menuService, OptionService optionService, PhotoService photoService,
|
||||||
PostService postService, PostCategoryService postCategoryService,
|
PostService postService, ContentService contentService,
|
||||||
|
ContentPatchLogService contentPatchLogService,
|
||||||
|
PostCategoryService postCategoryService,
|
||||||
PostCommentService postCommentService, PostMetaService postMetaService,
|
PostCommentService postCommentService, PostMetaService postMetaService,
|
||||||
PostTagService postTagService, SheetService sheetService,
|
PostTagService postTagService, SheetService sheetService,
|
||||||
SheetCommentService sheetCommentService, SheetMetaService sheetMetaService,
|
SheetCommentService sheetCommentService, SheetMetaService sheetMetaService,
|
||||||
|
@ -189,6 +201,8 @@ public class BackupServiceImpl implements BackupService {
|
||||||
this.optionService = optionService;
|
this.optionService = optionService;
|
||||||
this.photoService = photoService;
|
this.photoService = photoService;
|
||||||
this.postService = postService;
|
this.postService = postService;
|
||||||
|
this.contentService = contentService;
|
||||||
|
this.contentPatchLogService = contentPatchLogService;
|
||||||
this.postCategoryService = postCategoryService;
|
this.postCategoryService = postCategoryService;
|
||||||
this.postCommentService = postCommentService;
|
this.postCommentService = postCommentService;
|
||||||
this.postMetaService = postMetaService;
|
this.postMetaService = postMetaService;
|
||||||
|
@ -358,6 +372,8 @@ public class BackupServiceImpl implements BackupService {
|
||||||
data.put("options", optionService.listAll());
|
data.put("options", optionService.listAll());
|
||||||
data.put("photos", photoService.listAll());
|
data.put("photos", photoService.listAll());
|
||||||
data.put("posts", postService.listAll());
|
data.put("posts", postService.listAll());
|
||||||
|
data.put("contents", contentService.listAll());
|
||||||
|
data.put("content_patch_logs", contentPatchLogService.listAll());
|
||||||
data.put("post_categories", postCategoryService.listAll());
|
data.put("post_categories", postCategoryService.listAll());
|
||||||
data.put("post_comments", postCommentService.listAll());
|
data.put("post_comments", postCommentService.listAll());
|
||||||
data.put("post_metas", postMetaService.listAll());
|
data.put("post_metas", postMetaService.listAll());
|
||||||
|
@ -438,6 +454,11 @@ public class BackupServiceImpl implements BackupService {
|
||||||
};
|
};
|
||||||
HashMap<String, Object> data = mapper.readValue(jsonContent, typeRef);
|
HashMap<String, Object> data = mapper.readValue(jsonContent, typeRef);
|
||||||
|
|
||||||
|
String version = (String) Objects.requireNonNullElse(data.get("version"), "");
|
||||||
|
if (!VersionUtil.hasSameMajorAndMinorVersion(HaloConst.HALO_VERSION, version)) {
|
||||||
|
throw new IllegalArgumentException("导入数据的主次版本号与当前系统版本号不匹配,不支持导入!");
|
||||||
|
}
|
||||||
|
|
||||||
List<Attachment> attachments = Arrays.asList(mapper
|
List<Attachment> attachments = Arrays.asList(mapper
|
||||||
.readValue(mapper.writeValueAsString(data.get("attachments")), Attachment[].class));
|
.readValue(mapper.writeValueAsString(data.get("attachments")), Attachment[].class));
|
||||||
attachmentService.createInBatch(attachments);
|
attachmentService.createInBatch(attachments);
|
||||||
|
@ -490,6 +511,16 @@ public class BackupServiceImpl implements BackupService {
|
||||||
.asList(mapper.readValue(mapper.writeValueAsString(data.get("posts")), Post[].class));
|
.asList(mapper.readValue(mapper.writeValueAsString(data.get("posts")), Post[].class));
|
||||||
postService.createInBatch(posts);
|
postService.createInBatch(posts);
|
||||||
|
|
||||||
|
List<Content> contents = Arrays
|
||||||
|
.asList(
|
||||||
|
mapper.readValue(mapper.writeValueAsString(data.get("contents")), Content[].class));
|
||||||
|
contentService.createInBatch(contents);
|
||||||
|
|
||||||
|
List<ContentPatchLog> contentPatchLogs = Arrays
|
||||||
|
.asList(mapper.readValue(mapper.writeValueAsString(data.get("content_patch_logs")),
|
||||||
|
ContentPatchLog[].class));
|
||||||
|
contentPatchLogService.createInBatch(contentPatchLogs);
|
||||||
|
|
||||||
List<PostCategory> postCategories = Arrays.asList(mapper
|
List<PostCategory> postCategories = Arrays.asList(mapper
|
||||||
.readValue(mapper.writeValueAsString(data.get("post_categories")),
|
.readValue(mapper.writeValueAsString(data.get("post_categories")),
|
||||||
PostCategory[].class));
|
PostCategory[].class));
|
||||||
|
|
|
@ -16,6 +16,7 @@ import run.halo.app.model.enums.PostStatus;
|
||||||
import run.halo.app.repository.ContentPatchLogRepository;
|
import run.halo.app.repository.ContentPatchLogRepository;
|
||||||
import run.halo.app.repository.ContentRepository;
|
import run.halo.app.repository.ContentRepository;
|
||||||
import run.halo.app.service.ContentPatchLogService;
|
import run.halo.app.service.ContentPatchLogService;
|
||||||
|
import run.halo.app.service.base.AbstractCrudService;
|
||||||
import run.halo.app.utils.PatchUtils;
|
import run.halo.app.utils.PatchUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +26,8 @@ import run.halo.app.utils.PatchUtils;
|
||||||
* @since 2022-01-04
|
* @since 2022-01-04
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class ContentPatchLogServiceImpl implements ContentPatchLogService {
|
public class ContentPatchLogServiceImpl extends AbstractCrudService<ContentPatchLog, Integer>
|
||||||
|
implements ContentPatchLogService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* base version of content patch log.
|
* base version of content patch log.
|
||||||
|
@ -38,6 +40,7 @@ public class ContentPatchLogServiceImpl implements ContentPatchLogService {
|
||||||
|
|
||||||
public ContentPatchLogServiceImpl(ContentPatchLogRepository contentPatchLogRepository,
|
public ContentPatchLogServiceImpl(ContentPatchLogRepository contentPatchLogRepository,
|
||||||
ContentRepository contentRepository) {
|
ContentRepository contentRepository) {
|
||||||
|
super(contentPatchLogRepository);
|
||||||
this.contentPatchLogRepository = contentPatchLogRepository;
|
this.contentPatchLogRepository = contentPatchLogRepository;
|
||||||
this.contentRepository = contentRepository;
|
this.contentRepository = contentRepository;
|
||||||
}
|
}
|
||||||
|
@ -83,12 +86,6 @@ public class ContentPatchLogServiceImpl implements ContentPatchLogService {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void save(ContentPatchLog contentPatchLog) {
|
|
||||||
contentPatchLogRepository.save(contentPatchLog);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ContentPatchLog createDraftContent(Integer postId, Integer version,
|
private ContentPatchLog createDraftContent(Integer postId, Integer version,
|
||||||
String formatContent, String originalContent) {
|
String formatContent, String originalContent) {
|
||||||
ContentPatchLog contentPatchLog =
|
ContentPatchLog contentPatchLog =
|
||||||
|
|
|
@ -76,7 +76,7 @@ public class ContentServiceImpl extends AbstractCrudService<Content, Integer>
|
||||||
}
|
}
|
||||||
contentPatchLog.setStatus(PostStatus.PUBLISHED);
|
contentPatchLog.setStatus(PostStatus.PUBLISHED);
|
||||||
contentPatchLog.setPublishTime(new Date());
|
contentPatchLog.setPublishTime(new Date());
|
||||||
contentPatchLogService.save(contentPatchLog);
|
contentPatchLogService.create(contentPatchLog);
|
||||||
|
|
||||||
Content postContent = getById(postId);
|
Content postContent = getById(postId);
|
||||||
postContent.setPatchLogId(contentPatchLog.getId());
|
postContent.setPatchLogId(contentPatchLog.getId());
|
||||||
|
|
|
@ -645,6 +645,8 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
List<Post> allPostList = listAll();
|
List<Post> allPostList = listAll();
|
||||||
List<PostMarkdownVO> result = new ArrayList<>(allPostList.size());
|
List<PostMarkdownVO> result = new ArrayList<>(allPostList.size());
|
||||||
for (Post post : allPostList) {
|
for (Post post : allPostList) {
|
||||||
|
Content postContent = getContentById(post.getId());
|
||||||
|
post.setContent(PatchedContent.of(postContent));
|
||||||
result.add(convertToPostMarkdownVo(post));
|
result.add(convertToPostMarkdownVo(post));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -29,4 +29,17 @@ public final class VersionUtil {
|
||||||
return leftVersion.compareTo(rightVersion) >= 0;
|
return leftVersion.compareTo(rightVersion) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare two versions to see if they have the same major and minor versions.
|
||||||
|
*
|
||||||
|
* @param left version A to compare
|
||||||
|
* @param right version B to compare
|
||||||
|
* @return {@code true} if they have the same major and minor version.
|
||||||
|
*/
|
||||||
|
public static boolean hasSameMajorAndMinorVersion(String left, String right) {
|
||||||
|
Version leftVersion = Version.resolve(left).orElse(Version.emptyVersion());
|
||||||
|
Version rightVersion = Version.resolve(right).orElse(Version.emptyVersion());
|
||||||
|
return leftVersion.getMajor() == rightVersion.getMajor()
|
||||||
|
&& leftVersion.getMinor() == rightVersion.getMinor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package run.halo.app.utils;
|
package run.halo.app.utils;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
@ -33,4 +34,23 @@ class VersionUtilTest {
|
||||||
assertTrue(VersionUtil.compareVersion(HaloConst.UNKNOWN_VERSION, randomVersion));
|
assertTrue(VersionUtil.compareVersion(HaloConst.UNKNOWN_VERSION, randomVersion));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void hasSameMajorAndMinorVersionTest() {
|
||||||
|
assertThat(
|
||||||
|
VersionUtil.hasSameMajorAndMinorVersion(HaloConst.UNKNOWN_VERSION, "1.4.0")).isFalse();
|
||||||
|
|
||||||
|
assertThat(VersionUtil.hasSameMajorAndMinorVersion("1.3.1", "1.5.8")).isFalse();
|
||||||
|
|
||||||
|
assertThat(VersionUtil.hasSameMajorAndMinorVersion("1.2.4.alpha-1", "1.3.5")).isFalse();
|
||||||
|
|
||||||
|
assertThat(VersionUtil.hasSameMajorAndMinorVersion("0.0.4", "0.0.1")).isTrue();
|
||||||
|
|
||||||
|
assertThat(VersionUtil.hasSameMajorAndMinorVersion("1.0.4", "1.0.5-alpha.1")).isTrue();
|
||||||
|
|
||||||
|
assertThat(VersionUtil.hasSameMajorAndMinorVersion("1.0.4", "1.0.5-rc.1")).isTrue();
|
||||||
|
|
||||||
|
assertThat(VersionUtil.hasSameMajorAndMinorVersion("2.0.0", "2.0.1")).isTrue();
|
||||||
|
|
||||||
|
assertThat(VersionUtil.hasSameMajorAndMinorVersion(null, null)).isTrue();
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue