REQ-3540: 备份
This commit is contained in:
parent
7cbb6fd549
commit
91747f3eea
@ -60,7 +60,7 @@ public class IndexNodeDao extends ServiceImpl<IndexNodeMapper, IndexNode> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public IndexNode findValidChildByName(IndexNodeParentScope parentNode, IndexNodeType nodeType, String name) {
|
public IndexNode findValidChildByName(IndexNodeParentScope parentNode, IndexNodeType nodeType, String name) {
|
||||||
return parentOrScopeQuery(parentNode) //
|
return parentOrScopeRootQuery(parentNode) //
|
||||||
.eq(IndexNode::getName, name) //
|
.eq(IndexNode::getName, name) //
|
||||||
.eq(IndexNode::getNodeType, nodeType) //
|
.eq(IndexNode::getNodeType, nodeType) //
|
||||||
.eq(IndexNode::getState, IndexNodeState.VALID) //
|
.eq(IndexNode::getState, IndexNodeState.VALID) //
|
||||||
@ -70,7 +70,7 @@ public class IndexNodeDao extends ServiceImpl<IndexNodeMapper, IndexNode> {
|
|||||||
|
|
||||||
public List<IndexNode> findValidChildrenNameRightLike(IndexNodeParentScope parentNode, IndexNodeType nodeType,
|
public List<IndexNode> findValidChildrenNameRightLike(IndexNodeParentScope parentNode, IndexNodeType nodeType,
|
||||||
String name) {
|
String name) {
|
||||||
return parentOrScopeQuery(parentNode) //
|
return parentOrScopeRootQuery(parentNode) //
|
||||||
.likeRight(IndexNode::getName, name) //
|
.likeRight(IndexNode::getName, name) //
|
||||||
.eq(IndexNode::getNodeType, nodeType) //
|
.eq(IndexNode::getNodeType, nodeType) //
|
||||||
.eq(IndexNode::getState, IndexNodeState.VALID) //
|
.eq(IndexNode::getState, IndexNodeState.VALID) //
|
||||||
@ -140,9 +140,9 @@ public class IndexNodeDao extends ServiceImpl<IndexNodeMapper, IndexNode> {
|
|||||||
.update();
|
.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private LambdaQueryChainWrapper<IndexNode> parentOrScopeQuery(IndexNodeParentScope parentScope) {
|
private LambdaQueryChainWrapper<IndexNode> parentOrScopeRootQuery(IndexNodeParentScope parentScope) {
|
||||||
if (StringUtils.isBlank(parentScope.parentCode()))
|
if (StringUtils.isBlank(parentScope.parentCode()))
|
||||||
return scopeQuery(parentScope.nodeScope());
|
return scopeQuery(parentScope.nodeScope()).eq(IndexNode::getParentCode, "");
|
||||||
return lambdaQuery().eq(IndexNode::getParentCode, parentScope.parentCode());
|
return lambdaQuery().eq(IndexNode::getParentCode, parentScope.parentCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -148,6 +148,10 @@ public class IndexNode extends BaseEntity<IndexNode> implements NodeValue, Index
|
|||||||
return Path.wrap(path);
|
return Path.wrap(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean idEquals(IndexNode n1, IndexNode n2) {
|
||||||
|
return Objects.equals(n1.getId(), n2.getId());
|
||||||
|
}
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
@JSONField(serialize = false, deserialize = false)
|
@JSONField(serialize = false, deserialize = false)
|
||||||
public boolean isFile() {
|
public boolean isFile() {
|
||||||
|
|||||||
@ -172,7 +172,6 @@ public class IndexManager {
|
|||||||
BizAssertions.assertFalse(srcNode.isDirectory() && destParentNode.isFile(), "不能移动文件夹到文件下");
|
BizAssertions.assertFalse(srcNode.isDirectory() && destParentNode.isFile(), "不能移动文件夹到文件下");
|
||||||
return async(() -> {
|
return async(() -> {
|
||||||
RootNode<IndexNode> moveRoot = TreeBuilder.build(collectValidSubtreeAsValueRoot(srcNode));
|
RootNode<IndexNode> moveRoot = TreeBuilder.build(collectValidSubtreeAsValueRoot(srcNode));
|
||||||
//noinspection SpringTransactionalMethodCallsInspection
|
|
||||||
return transaction.execute(unused -> connectNodes(moveRoot, destParentNode));
|
return transaction.execute(unused -> connectNodes(moveRoot, destParentNode));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -181,8 +180,7 @@ public class IndexManager {
|
|||||||
public IndexNode copySubTree(IndexNode src, @Nullable IndexNode destParent, CopyNodeVisitor copyNodeVisitor) {
|
public IndexNode copySubTree(IndexNode src, @Nullable IndexNode destParent, CopyNodeVisitor copyNodeVisitor) {
|
||||||
RootNode<IndexNode> srcRoot = TreeUtils.transform(collectValidSubtreeAsValueRoot(src), IndexNode.class);
|
RootNode<IndexNode> srcRoot = TreeUtils.transform(collectValidSubtreeAsValueRoot(src), IndexNode.class);
|
||||||
srcRoot.walkDown(copyNodeVisitor);
|
srcRoot.walkDown(copyNodeVisitor);
|
||||||
List<IndexNode> copiedNodes = TreeUtils.collectValues(srcRoot);
|
indexNodeDao.saveBatch(TreeUtils.collectValues(srcRoot));
|
||||||
indexNodeDao.saveBatch(copiedNodes);
|
|
||||||
return connectNodes(srcRoot, destParent);
|
return connectNodes(srcRoot, destParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,20 +195,14 @@ public class IndexManager {
|
|||||||
/**
|
/**
|
||||||
* connect tree nodes and resolve name issue
|
* connect tree nodes and resolve name issue
|
||||||
*/
|
*/
|
||||||
@BizTransactional
|
private IndexNode connectNodes(RootNode<IndexNode> connectRoot, @Nullable IndexNode destParent) {
|
||||||
public IndexNode connectNodes(RootNode<IndexNode> connectRoot, @Nullable IndexNode destParent) {
|
|
||||||
// rebuild parent id, parent code and the most important path
|
// rebuild parent id, parent code and the most important path
|
||||||
connectRoot.walkDown(new ConnectNodeVisitor(destParent));
|
connectRoot.walkDown(new ConnectNodeVisitor(destParent));
|
||||||
indexNodeDao.connectNodes(TreeUtils.collectValues(connectRoot));
|
indexNodeDao.connectNodes(TreeUtils.collectValues(connectRoot));
|
||||||
IndexNode copiedRoot = connectRoot.getChildren().get(0).<IndexNode> asValueNode().getValue();
|
IndexNode copiedRoot = connectRoot.getChildren().get(0).<IndexNode> asValueNode().getValue();
|
||||||
// resolve the name issue
|
// resolve the name issue
|
||||||
if (destParent != null) {
|
if (destParent != null)
|
||||||
String newName = indexSupport.lockAndMaybeIncrChildName(destParent, copiedRoot.getNodeType(),
|
indexSupport.incrNameIfDuplicate(destParent, copiedRoot.getNodeType(), copiedRoot);
|
||||||
copiedRoot.getName());
|
|
||||||
// don't update if the name is good
|
|
||||||
if (!copiedRoot.getName().equals(newName))
|
|
||||||
indexNodeDao.rename(copiedRoot.getCode(), newName);
|
|
||||||
}
|
|
||||||
// get the coped root with full props
|
// get the coped root with full props
|
||||||
return indexNodeDao.findOrNull(copiedRoot.getCode());
|
return indexNodeDao.findOrNull(copiedRoot.getCode());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import cn.axzo.nanopart.doc.file.index.copy.SetScopeProcessor;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
@ -31,6 +30,7 @@ import cn.axzo.nanopart.doc.dao.DocLockDao;
|
|||||||
import cn.axzo.nanopart.doc.dao.IndexNodeDao;
|
import cn.axzo.nanopart.doc.dao.IndexNodeDao;
|
||||||
import cn.axzo.nanopart.doc.entity.IndexNode;
|
import cn.axzo.nanopart.doc.entity.IndexNode;
|
||||||
import cn.axzo.nanopart.doc.entity.domain.Path;
|
import cn.axzo.nanopart.doc.entity.domain.Path;
|
||||||
|
import cn.axzo.nanopart.doc.file.index.copy.SetScopeProcessor;
|
||||||
import cn.axzo.nanopart.doc.file.index.domain.NameUsedException;
|
import cn.axzo.nanopart.doc.file.index.domain.NameUsedException;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -97,15 +97,17 @@ class IndexSupport {
|
|||||||
BizAssertions.assertFalse(parent.isFile(), "不能在文件下建立文件夹");
|
BizAssertions.assertFalse(parent.isFile(), "不能在文件下建立文件夹");
|
||||||
}
|
}
|
||||||
|
|
||||||
String lockAndMaybeIncrChildName(IndexNode parentNode, IndexNodeType nodeType, String name) {
|
void incrNameIfDuplicate(IndexNode parentNode, IndexNodeType nodeType, IndexNode rename) {
|
||||||
lockParentAndReleaseOnCommit(parentNode);
|
lockParentAndReleaseOnCommit(parentNode);
|
||||||
IndexNode sameName = indexNodeDao.findValidChildByName(parentNode, nodeType, name);
|
List<IndexNode> nameLikeNodes = indexNodeDao.findValidChildrenNameRightLike(parentNode, nodeType,
|
||||||
if (sameName == null)
|
rename.getName());
|
||||||
return name;
|
if (nameLikeNodes.size() == 1 && IndexNode.idEquals(rename, nameLikeNodes.get(0)))
|
||||||
List<IndexNode> nameLikeNodes = indexNodeDao.findValidChildrenNameRightLike(parentNode, nodeType, name);
|
return;
|
||||||
Pattern pattern = Pattern.compile(Pattern.quote(name) + "\\((\\d+)\\)");
|
Pattern pattern = Pattern.compile(Pattern.quote(rename.getName()) + "\\((\\d+)\\)");
|
||||||
int maxSeq = 0;
|
int maxSeq = 0;
|
||||||
for (IndexNode indexNode : nameLikeNodes) {
|
for (IndexNode indexNode : nameLikeNodes) {
|
||||||
|
if (indexNode.getId().equals(rename.getId()))
|
||||||
|
continue;
|
||||||
Matcher matcher = pattern.matcher(indexNode.getName());
|
Matcher matcher = pattern.matcher(indexNode.getName());
|
||||||
if (matcher.matches()) {
|
if (matcher.matches()) {
|
||||||
int seq = Integer.parseInt(matcher.group(1));
|
int seq = Integer.parseInt(matcher.group(1));
|
||||||
@ -114,7 +116,8 @@ class IndexSupport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
maxSeq = maxSeq == 0 ? 1 : maxSeq + 1;
|
maxSeq = maxSeq == 0 ? 1 : maxSeq + 1;
|
||||||
return String.format("%s(%d)", name, maxSeq);
|
String newName = String.format("%s(%d)", rename.getName(), maxSeq);
|
||||||
|
indexNodeDao.rename(rename.getCode(), newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ensureChildNameNotUsed(NodeCreate create, IndexNodeType nodeType) {
|
void ensureChildNameNotUsed(NodeCreate create, IndexNodeType nodeType) {
|
||||||
|
|||||||
@ -17,10 +17,11 @@ import cn.axzo.nanopart.doc.entity.IndexNode;
|
|||||||
@Mapper
|
@Mapper
|
||||||
public interface IndexNodeMapper extends BaseMapper<IndexNode> {
|
public interface IndexNodeMapper extends BaseMapper<IndexNode> {
|
||||||
|
|
||||||
@Insert("<script>\n" + "INSERT INTO doc_index_node (code, parent_id, root_code, path)\n" + "VALUES\n"
|
@Insert("<script>\n" + "INSERT INTO doc_index_node (code, parent_id, parent_code, root_code, path)\n" + "VALUES\n"
|
||||||
+ " <foreach collection='nodes' item='node' separator=','>\n"
|
+ " <foreach collection='nodes' item='node' separator=','>\n"
|
||||||
+ " (#{node.code}, #{node.parentId}, #{node.rootCode}, #{node.path})\n" + "</foreach>\n"
|
+ " (#{node.code}, #{node.parentId}, #{node.parentCode}, #{node.rootCode}, #{node.path})\n" + "</foreach>\n"
|
||||||
+ " ON DUPLICATE KEY UPDATE parent_id = values(parent_id),\n"
|
+ " ON DUPLICATE KEY UPDATE parent_id = values(parent_id),\n"
|
||||||
|
+ " parent_code = values(parent_code),\n"
|
||||||
+ " root_code = values(root_code),\n"
|
+ " root_code = values(root_code),\n"
|
||||||
+ " path = values(path)\n" + "</script>")
|
+ " path = values(path)\n" + "</script>")
|
||||||
void connectNodes(@Param("nodes") List<IndexNode> nodes);
|
void connectNodes(@Param("nodes") List<IndexNode> nodes);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user