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