From 30b8fb2841cea343a97e360b930ce03569ddd6aa Mon Sep 17 00:00:00 2001 From: lengleng Date: Sat, 13 May 2023 00:35:52 +0000 Subject: [PATCH 01/14] =?UTF-8?q?:recycle:=20configJs=20=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20@ResponseBody=20=E6=B3=A8=E8=A7=A3?= =?UTF-8?q?=E5=A3=B0=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lengleng --- .../org/ssssssss/magicapi/core/web/MagicWorkbenchController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicWorkbenchController.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicWorkbenchController.java index 705bae42..d48c9688 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicWorkbenchController.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicWorkbenchController.java @@ -252,6 +252,7 @@ public class MagicWorkbenchController extends MagicController implements MagicEx } @RequestMapping(value = "/config-js") + @ResponseBody @Valid(requireLogin = false) public void configJs(MagicHttpServletResponse response) throws IOException { response.setContentType("application/javascript"); -- Gitee From 0b256d16ec33dc3381f4a635089b34642d0a2fef Mon Sep 17 00:00:00 2001 From: taogang Date: Thu, 13 Jul 2023 20:07:57 +0800 Subject: [PATCH 02/14] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8Dspringboot=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E9=85=8D=E7=BD=AEserver.servlet.context-path=20?= =?UTF-8?q?=E6=97=B6=EF=BC=8Cswagger=E8=AE=BF=E9=97=AE=E8=B5=84=E6=BA=9040?= =?UTF-8?q?4=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../magicapi/springdoc/MagicSpringDocConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/MagicSpringDocConfiguration.java b/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/MagicSpringDocConfiguration.java index b071e758..a3a15d20 100644 --- a/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/MagicSpringDocConfiguration.java +++ b/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/MagicSpringDocConfiguration.java @@ -87,7 +87,7 @@ public class MagicSpringDocConfiguration implements MagicPluginConfiguration { } else { urls = new HashSet<>(urls); } - urls.add(new SwaggerUrl(springDocConfig.getGroupName(), springDocConfig.getLocation(), null)); + urls.add(new SwaggerUrl(springDocConfig.getGroupName(), servletContext.getContextPath() + springDocConfig.getLocation(), null)); params.put("urls", urls); return params; } -- Gitee From aecad288325ec19f44eae470b7eccf5ad4605922 Mon Sep 17 00:00:00 2001 From: hepengfei Date: Mon, 7 Aug 2023 11:19:53 +0800 Subject: [PATCH 03/14] https://gitee.com/ssssssss-team/magic-api/issues/I7R1ED --- .../magic-api-plugin-nebula/pom.xml | 33 ++++ .../nebula/MagicNebulaConfiguration.java | 104 ++++++++++++ .../magicapi/nebula/NebulaModule.java | 157 ++++++++++++++++++ .../magicapi/nebula/NebulaPoolProperties.java | 141 ++++++++++++++++ .../ssssssss/magicapi/nebula/model/Edge.java | 69 ++++++++ .../magicapi/nebula/model/NebulaModel.java | 69 ++++++++ .../ssssssss/magicapi/nebula/model/Node.java | 36 ++++ .../magicapi/nebula/response/EdgeElement.java | 14 ++ .../magicapi/nebula/response/EdgeId.java | 50 ++++++ .../magicapi/nebula/response/Element.java | 26 +++ .../nebula/response/NebulaJsonBody.java | 132 +++++++++++++++ .../magicapi/nebula/response/Vertex.java | 14 ++ .../main/resources/META-INF/spring.factories | 1 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + magic-api-plugins/pom.xml | 1 + 15 files changed, 848 insertions(+) create mode 100644 magic-api-plugins/magic-api-plugin-nebula/pom.xml create mode 100644 magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/MagicNebulaConfiguration.java create mode 100644 magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/NebulaModule.java create mode 100644 magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/NebulaPoolProperties.java create mode 100644 magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/Edge.java create mode 100644 magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/NebulaModel.java create mode 100644 magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/Node.java create mode 100644 magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/EdgeElement.java create mode 100644 magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/EdgeId.java create mode 100644 magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/Element.java create mode 100644 magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/NebulaJsonBody.java create mode 100644 magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/Vertex.java create mode 100644 magic-api-plugins/magic-api-plugin-nebula/src/main/resources/META-INF/spring.factories create mode 100644 magic-api-plugins/magic-api-plugin-nebula/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/magic-api-plugins/magic-api-plugin-nebula/pom.xml b/magic-api-plugins/magic-api-plugin-nebula/pom.xml new file mode 100644 index 00000000..43e906d0 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-nebula/pom.xml @@ -0,0 +1,33 @@ + + 4.0.0 + + org.ssssssss + magic-api-plugins + 2.1.1 + + + magic-api-plugin-nebula + jar + + magic-api-plugin-nebula + + + UTF-8 + 3.5.0 + + + + + com.vesoft + client + ${vesoft.version} + + + guava + com.google.guava + + + + + diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/MagicNebulaConfiguration.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/MagicNebulaConfiguration.java new file mode 100644 index 00000000..6837fb39 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/MagicNebulaConfiguration.java @@ -0,0 +1,104 @@ +package org.ssssssss.magicapi.nebula; + + +import com.vesoft.nebula.client.graph.NebulaPoolConfig; +import com.vesoft.nebula.client.graph.data.HostAddress; +import com.vesoft.nebula.client.graph.net.NebulaPool; +import com.vesoft.nebula.client.graph.net.Session; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.ssssssss.magicapi.core.config.MagicAPIProperties; +import org.ssssssss.magicapi.core.config.MagicPluginConfiguration; +import org.ssssssss.magicapi.core.model.Plugin; +import org.ssssssss.magicapi.utils.Assert; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * Nebula自动配置类 + */ + +@Configuration +@EnableConfigurationProperties(NebulaPoolProperties.class) +public class MagicNebulaConfiguration implements MagicPluginConfiguration { + private static final Logger logger = LoggerFactory.getLogger(MagicNebulaConfiguration.class); + + private NebulaPoolProperties nebulaPoolProperties; + + private final MagicAPIProperties properties; + + public MagicNebulaConfiguration(MagicAPIProperties properties, NebulaPoolProperties nebulaPoolProperties) { + this.properties = properties; + this.nebulaPoolProperties = nebulaPoolProperties; + } + + /** + * 创建nebula pool + * @param nebulaPoolProperties + * @return + */ + @Bean + public NebulaPool nebulaPool(@Autowired NebulaPoolProperties nebulaPoolProperties) { + Session session = null; + try { + + NebulaPoolConfig nebulaPoolConfig = buildNebulaPoolConfig(nebulaPoolProperties); + Assert.isNotBlank(nebulaPoolProperties.getHostAddress(), "nebula.hostAddress 不能为空, 格式为 ip:port,ip:port 配置多个地址用逗号分隔"); + String[] hostAddress = nebulaPoolProperties.getHostAddress().split(","); + List addresses = Arrays.stream(hostAddress).map(address -> { + String[] ipAndPort = address.split(":"); + Assert.isTrue(ipAndPort.length == 2, "nebula.hostAddress 格式错误, 格式为 ip:port,ip:port 配置多个地址用逗号分隔"); + return new HostAddress(ipAndPort[0], Integer.parseInt(ipAndPort[1])); + }).collect(Collectors.toList()); + + NebulaPool pool = new NebulaPool(); + pool.init(addresses, nebulaPoolConfig); + session = pool.getSession(nebulaPoolProperties.getUserName(), nebulaPoolProperties.getPassword(), nebulaPoolProperties.isReconnect()); + return pool; + } catch (Exception e) { + logger.error("初始化nebula pool 异常", e); + throw new RuntimeException(e); + } finally { + logger.info("初始化nebula pool 完成"); + Optional.ofNullable(session).ifPresent(Session::release); + } + } + + /** + * 注入模块 + * @return + */ + @Bean + public NebulaModule nebulaModule() { + return new NebulaModule(); + } + + @Override + public Plugin plugin() { + return new Plugin("Nebula"); + } + + + public NebulaPoolConfig buildNebulaPoolConfig(NebulaPoolProperties nebulaPoolProperties) { + + NebulaPoolConfig nebulaPoolConfig = new NebulaPoolConfig(); + //将nebulaPoolProperties的同名属性赋值到nebulaPoolConfig + nebulaPoolConfig.setMinConnSize(nebulaPoolProperties.getMinConnsSize()); + nebulaPoolConfig.setSslParam(nebulaPoolProperties.getSslParam()); + nebulaPoolConfig.setWaitTime(nebulaPoolProperties.getWaitTime()); + nebulaPoolConfig.setTimeout(nebulaPoolProperties.getTimeout()); + nebulaPoolConfig.setMaxConnSize(nebulaPoolProperties.getMaxConnsSize()); + nebulaPoolConfig.setIntervalIdle(nebulaPoolProperties.getIntervalIdle()); + nebulaPoolConfig.setMinClusterHealthRate(nebulaPoolProperties.getMinClusterHealthRate()); + nebulaPoolConfig.setIdleTime(nebulaPoolProperties.getIdleTime()); + nebulaPoolConfig.setEnableSsl(nebulaPoolProperties.isEnableSsl()); + return nebulaPoolConfig; + } +} diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/NebulaModule.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/NebulaModule.java new file mode 100644 index 00000000..4d3aa3fa --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/NebulaModule.java @@ -0,0 +1,157 @@ +package org.ssssssss.magicapi.nebula; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.vesoft.nebula.client.graph.data.ResultSet; +import com.vesoft.nebula.client.graph.net.NebulaPool; +import com.vesoft.nebula.client.graph.net.Session; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.ssssssss.magicapi.core.annotation.MagicModule; +import org.ssssssss.magicapi.nebula.model.Edge; +import org.ssssssss.magicapi.nebula.model.NebulaModel; +import org.ssssssss.magicapi.nebula.model.Node; +import org.ssssssss.magicapi.nebula.response.*; +import org.ssssssss.script.annotation.Comment; + +import java.util.HashMap; +import java.util.List; +import java.util.Optional; + + +@MagicModule("nebula") +public class NebulaModule { + + @Autowired + private NebulaPool nebulaPool; + + @Autowired + private NebulaPoolProperties nebulaPoolProperties; + + private static final Logger logger = LoggerFactory.getLogger(NebulaModule.class); + + + /** + * 执行ngsl脚本, 返回json格式结果 + * + * @param script + * @return + */ + @Comment("执行ngsl脚本, 返回json格式结果") + public Object executeJson(String script) { + Session session = getNebulaSession(); + try { + String json = session.executeJson(script); + return json; + } catch (Exception e) { + logger.error("执行Nebula脚本异常, script: {}", script, e); + throw new RuntimeException(e); + } finally { + Optional.ofNullable(session).ifPresent(Session::release); + } + } + + + /** + * 执行ngsl脚本, 并解析为可视化格式 + * + * @param script + * @return + */ + @Comment("执行ngsl脚本, 返回json格式结果, 并解析为可视化格式") + public NebulaModel executeNebulaModel(String script) { + Session session = getNebulaSession(); + try { + String json = session.executeJson(script); + return convert(json); + } catch (Exception e) { + logger.error("执行Nebula脚本异常, script: {}", script, e); + throw new RuntimeException(e); + } finally { + Optional.ofNullable(session).ifPresent(Session::release); + } + } + + + /** + * 执行ngsl脚本, 返回ResultSet格式结果, 不可直接使用 + * + * @param script + * @return + */ + @Comment("执行ngsl脚本, 返回ResultSet格式结果, 无法直接使用") + public Object execute(String script) { + Session session = getNebulaSession(); + try { + ResultSet resultSet = session.execute(script); + return resultSet; + } catch (Exception e) { + logger.error("执行Nebula脚本异常, script: {}", script, e); + throw new RuntimeException(e); + } finally { + Optional.ofNullable(session).ifPresent(Session::release); + } + } + + public Session getNebulaSession() { + try { + return nebulaPool.getSession(nebulaPoolProperties.getUserName(), nebulaPoolProperties.getPassword(), nebulaPoolProperties.isReconnect()); + } catch (NoSuchBeanDefinitionException e) { + throw new RuntimeException(String.format("NebulaPool 未初始化, 或初始化异常, 请检查配置文件")); + } catch (Exception e) { + logger.error("获取nebula session 异常", e); + throw new RuntimeException(e); + } + } + + @Comment("解析nebula结果为可视化格式") + public NebulaModel convert(String json) throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + NebulaJsonBody response = objectMapper.readValue(json, NebulaJsonBody.class); + + //状态码不为0则为异常, 解析提示异常信息 + if (response.getErrorCode() != 0) { + logger.error("执行Nebula脚本异常, script: {}, errorMsg: {}", json, response.getErrorMsg()); + throw new RuntimeException(response.getErrorMsg()); + } + + NebulaModel nebulaModel = new NebulaModel(); + HashMap nodeEdges = new HashMap<>(); + List datas = response.getResults().get(0).getData(); + for (int index = 0; index < datas.size(); index++) { + List> meta = datas.get(index).getMeta(); + List>> row = datas.get(index).getRow(); + for (int i = 0; i < meta.get(0).size(); i++) { + Element element = meta.get(0).get(i); + HashMap elementDetail = row.get(0).get(i); + Node node = new Node(); + Edge edge = new Edge(); + + if (element instanceof Vertex) { + node.setId(((Vertex) element).getId()); + node.getProp().putAll(elementDetail); + nebulaModel.addNode(node); + + } else if (element instanceof EdgeElement) { + edge.getProp().putAll(elementDetail); + EdgeId id = ((EdgeElement) element).getId(); + edge.setTarget(id.getDst()); + edge.setSource(id.getSrc()); + edge.setLabel(id.getName()); + edge.setValue(id.getRanking()); + nebulaModel.getEdges().add(edge); + + nodeEdges.put(id.getDst(), nodeEdges.getOrDefault(id.getDst(), 0) + 1); + nodeEdges.put(id.getSrc(), nodeEdges.getOrDefault(id.getSrc(), 0) + 1); + } + } + // 补充节点边的数量值 + for (Node node : nebulaModel.getNodes()) { + node.setEdgeSize(nodeEdges.getOrDefault(node.getId(), 0)); + } + } + return nebulaModel; + } + +} diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/NebulaPoolProperties.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/NebulaPoolProperties.java new file mode 100644 index 00000000..7f4c28a2 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/NebulaPoolProperties.java @@ -0,0 +1,141 @@ +package org.ssssssss.magicapi.nebula; + +import com.vesoft.nebula.client.graph.data.SSLParam; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.boot.context.properties.ConfigurationProperties; + + +@ConfigurationProperties(prefix = "nebula") +public class NebulaPoolProperties { + + /** nebula 服务地址, 多个则逗号分割, 格式为 ip:port */ + private String hostAddress; + /** nebula 用户名 */ + private String userName; + /** nebula 密码 */ + private String password; + + private boolean reconnect = true; + /** nebula 连接池最小连接数 */ + private int minConnsSize = 0; + /** nebula 连接池最大连接数 */ + private int maxConnsSize = 10; + /** nebula 连接池最大等待时间 */ + private int timeout = 0; + /** nebula 连接池空闲时间 */ + private int idleTime = 0; + /** nebula 连接池心跳间隔 */ + private int intervalIdle = -1; + + private int waitTime = 0; + + private double minClusterHealthRate = 1.0; + + private boolean enableSsl = false; + + private SSLParam sslParam = null; + + public String getHostAddress() { + return hostAddress; + } + + public void setHostAddress(String hostAddress) { + this.hostAddress = hostAddress; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public boolean isReconnect() { + return reconnect; + } + + public void setReconnect(boolean reconnect) { + this.reconnect = reconnect; + } + + public int getMinConnsSize() { + return minConnsSize; + } + + public void setMinConnsSize(int minConnsSize) { + this.minConnsSize = minConnsSize; + } + + public int getMaxConnsSize() { + return maxConnsSize; + } + + public void setMaxConnsSize(int maxConnsSize) { + this.maxConnsSize = maxConnsSize; + } + + public int getTimeout() { + return timeout; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public int getIdleTime() { + return idleTime; + } + + public void setIdleTime(int idleTime) { + this.idleTime = idleTime; + } + + public int getIntervalIdle() { + return intervalIdle; + } + + public void setIntervalIdle(int intervalIdle) { + this.intervalIdle = intervalIdle; + } + + public int getWaitTime() { + return waitTime; + } + + public void setWaitTime(int waitTime) { + this.waitTime = waitTime; + } + + public double getMinClusterHealthRate() { + return minClusterHealthRate; + } + + public void setMinClusterHealthRate(double minClusterHealthRate) { + this.minClusterHealthRate = minClusterHealthRate; + } + + public boolean isEnableSsl() { + return enableSsl; + } + + public void setEnableSsl(boolean enableSsl) { + this.enableSsl = enableSsl; + } + + public SSLParam getSslParam() { + return sslParam; + } + + public void setSslParam(SSLParam sslParam) { + this.sslParam = sslParam; + } +} diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/Edge.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/Edge.java new file mode 100644 index 00000000..8ef9b90e --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/Edge.java @@ -0,0 +1,69 @@ +package org.ssssssss.magicapi.nebula.model; + +import java.util.HashMap; + +/** + * 描述node的方向的边 + */ +public class Edge { + + /** + * 起始节点的id + */ + private String source; + + /** + * 终止节点的id + */ + private String target; + + /** + * 边描述 + */ + private String label; + + + private String value; + + private HashMap prop = new HashMap<>(); + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public HashMap getProp() { + return prop; + } + + public void setProp(HashMap prop) { + this.prop = prop; + } +} diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/NebulaModel.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/NebulaModel.java new file mode 100644 index 00000000..72d9a38e --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/NebulaModel.java @@ -0,0 +1,69 @@ +package org.ssssssss.magicapi.nebula.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.ssssssss.script.annotation.Comment; + +import java.util.*; + +/** + * 经过加工后的nebula数据结构, 用于前端数据展示 + * 目前很多前端组件库支持这种数据, 并可视化展示, 如ntV G6等 + * @see AntV G6 + */ +public class NebulaModel { + + @JsonIgnore + private List nodeIds = new ArrayList<>(); + + /** + * 包含的节点集合 + */ + @Comment("包含的节点集合") + private List nodes = new ArrayList<>(); + + /** + * 包含的边集合 + */ + + @Comment("包含的边集合") + private List edges = new ArrayList<>(); + + public List getNodeIds() { + return nodeIds; + } + + public void setNodeIds(List nodeIds) { + this.nodeIds = nodeIds; + } + + public List getNodes() { + return nodes; + } + + public void setNodes(List nodes) { + this.nodes = nodes; + } + + public List getEdges() { + return edges; + } + + public void setEdges(List edges) { + this.edges = edges; + } + + /** + * 添加节点, 根据id去重 + * @param node + */ + @Comment("添加节点, 根据id去重") + public void addNode(Node node) { + String nodeId = Objects.toString(node.getId(), null); + if (nodeIds.contains(nodeId)) { + return; + } + nodeIds.add(nodeId); + nodes.add(node); + } + +} \ No newline at end of file diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/Node.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/Node.java new file mode 100644 index 00000000..7faf2b54 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/Node.java @@ -0,0 +1,36 @@ +package org.ssssssss.magicapi.nebula.model; + +import java.util.HashMap; + +public class Node { + + private String id; + + private int EdgeSize; + + private HashMap prop = new HashMap<>(); + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public int getEdgeSize() { + return EdgeSize; + } + + public void setEdgeSize(int edgeSize) { + EdgeSize = edgeSize; + } + + public HashMap getProp() { + return prop; + } + + public void setProp(HashMap prop) { + this.prop = prop; + } +} diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/EdgeElement.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/EdgeElement.java new file mode 100644 index 00000000..864dc6e8 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/EdgeElement.java @@ -0,0 +1,14 @@ +package org.ssssssss.magicapi.nebula.response; + +public class EdgeElement extends Element { + + private EdgeId id; + + public EdgeId getId() { + return id; + } + + public void setId(EdgeId id) { + this.id = id; + } +} diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/EdgeId.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/EdgeId.java new file mode 100644 index 00000000..1c706278 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/EdgeId.java @@ -0,0 +1,50 @@ +package org.ssssssss.magicapi.nebula.response; + +public class EdgeId { + + private String ranking; + private String name; + private Integer type; + private String dst; + private String src; + + public String getRanking() { + return ranking; + } + + public void setRanking(String ranking) { + this.ranking = ranking; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + public String getDst() { + return dst; + } + + public void setDst(String dst) { + this.dst = dst; + } + + public String getSrc() { + return src; + } + + public void setSrc(String src) { + this.src = src; + } +} diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/Element.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/Element.java new file mode 100644 index 00000000..69642344 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/Element.java @@ -0,0 +1,26 @@ +package org.ssssssss.magicapi.nebula.response; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + property = "type") +@JsonSubTypes(value = { + @JsonSubTypes.Type(value = EdgeElement.class, name = "edge"), + @JsonSubTypes.Type(value = Vertex.class, name = "vertex") +}) +public abstract class Element { + + protected String type; + + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + +} diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/NebulaJsonBody.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/NebulaJsonBody.java new file mode 100644 index 00000000..03652c54 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/NebulaJsonBody.java @@ -0,0 +1,132 @@ +package org.ssssssss.magicapi.nebula.response; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.HashMap; +import java.util.List; + +public class NebulaJsonBody { + private List errors; + private List results; + + public List getErrors() { + return errors; + } + + public void setErrors(List errors) { + this.errors = errors; + } + + + public int getErrorCode() { + return this.errors.get(0).getCode(); + } + + public String getErrorMsg() { + return this.errors.get(0).getMessage(); + } + + public List getResults() { + return results; + } + + public void setResults(List results) { + this.results = results; + } + + + public static class NebulaError { + private int code; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + } + + public static class Result { + @JsonProperty("spaceName") + private String spaceName; + private List data; + private List columns; + private NebulaError errors; + @JsonProperty("latencyInUs") + private long latencyInUs; + + public String getSpaceName() { + return spaceName; + } + + public void setSpaceName(String spaceName) { + this.spaceName = spaceName; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public List getColumns() { + return columns; + } + + public void setColumns(List columns) { + this.columns = columns; + } + + public NebulaError getErrors() { + return errors; + } + + public void setErrors(NebulaError errors) { + this.errors = errors; + } + + public long getLatencyInUs() { + return latencyInUs; + } + + public void setLatencyInUs(long latencyInUs) { + this.latencyInUs = latencyInUs; + } + } + + public static class Data { + private List> meta; + private List>> row; + + public List> getMeta() { + return meta; + } + + public void setMeta(List> meta) { + this.meta = meta; + } + + public List>> getRow() { + return row; + } + + public void setRow(List>> row) { + this.row = row; + } + } +} + + + diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/Vertex.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/Vertex.java new file mode 100644 index 00000000..43dbded6 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/Vertex.java @@ -0,0 +1,14 @@ +package org.ssssssss.magicapi.nebula.response; + +public class Vertex extends Element { + + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/resources/META-INF/spring.factories b/magic-api-plugins/magic-api-plugin-nebula/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..5c0648a4 --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.ssssssss.magicapi.nebula.MagicNebulaConfiguration \ No newline at end of file diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/magic-api-plugins/magic-api-plugin-nebula/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..e77bfd5f --- /dev/null +++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.ssssssss.magicapi.nebula.MagicNebulaConfiguration \ No newline at end of file diff --git a/magic-api-plugins/pom.xml b/magic-api-plugins/pom.xml index f63a46e2..2522a3a6 100644 --- a/magic-api-plugins/pom.xml +++ b/magic-api-plugins/pom.xml @@ -23,6 +23,7 @@ magic-api-plugin-elasticsearch magic-api-plugin-cluster magic-api-plugin-git + magic-api-plugin-nebula -- Gitee From 5310bab4bef67d7d803852d36359d38bf6ef93a8 Mon Sep 17 00:00:00 2001 From: txk <1754875134@qq.com> Date: Fri, 11 Aug 2023 11:02:03 +0800 Subject: [PATCH 04/14] =?UTF-8?q?db=E6=A8=A1=E5=9D=97=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=9F=BA=E4=BA=8Ejdbc=E7=9A=84=E5=AD=98=E5=82=A8=E8=BF=87?= =?UTF-8?q?=E7=A8=8B=E5=8F=8A=E5=87=BD=E6=95=B0=E8=B0=83=E7=94=A8=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../magicapi/modules/db/SQLModule.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/SQLModule.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/SQLModule.java index f6cb2268..77e19b51 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/SQLModule.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/SQLModule.java @@ -780,4 +780,64 @@ public class SQLModule implements DynamicAttribute, Dynami } } + @Comment("调用存储过程方法") + public Object callPro( + @Comment(name = "procName", value = "存储过程名称") String procName, + @Comment(name = "list", value = "[{\"p\":\"参数名\",\"io\":\"i/o/io\",\"t\":\"java.sql.Types\",\"v\":\"参数值\"}]") List> list) { + List strings = new ArrayList<>(); + for (Map ignored : list) { + strings.add("?"); + } + String result = String.join(",", strings); + final String callProcedureSql = "call " + procName + "(" + result + ")"; + return this.call(callProcedureSql, list); + } + + @Comment("调用函数方法") + public Object callFun( + @Comment(name = "funcName", value = "函数名称") String procName, + @Comment(name = "list", value = "[{\"p\":\"参数名\",\"io\":\"i/o/io\",\"t\":\"java.sql.type\",\"v\":\"参数值\"}]") List> list) { + List strings = new ArrayList<>(); + for (Map ignored : list) { + strings.add("?"); + } + String result = String.join(",", strings); + final String callFunctionSql = "{call " + procName + "(" + result + ")}"; + return this.call(callFunctionSql, list); + } + + private Object call(String sql, List> list) { + List params = new ArrayList<>(); + for (Map map : list) { + String paramName = (String) map.get("p"); + int type = (int) map.get("t"); + if ("i".equals(map.get("io"))) { + params.add(new SqlParameter(paramName, type)); + } else if ("o".equals(map.get("io"))) { + params.add(new SqlOutParameter(paramName, type)); + } else { + params.add(new SqlInOutParameter(paramName, type)); + } + } + final String callFunctionSql = sql; + return this.dataSourceNode.getJdbcTemplate().call( + con -> { + CallableStatement statement = con.prepareCall(callFunctionSql); + for (int i = 0; i < list.size(); i++) { + Map map = list.get(i); + Object param = map.get("v"); + int type = (int) map.get("t"); + if ("i".equals(map.get("io"))) { + statement.setObject(i + 1, param); + } else if ("o".equals(map.get("io"))) { + statement.registerOutParameter(i + 1, type); + } else { + statement.setObject(i + 1, param); + statement.registerOutParameter(i + 1, type); + } + } + return statement; + }, params); + } + } -- Gitee From b3417809ef6da05aa6f54d08af236e034b79c8e0 Mon Sep 17 00:00:00 2001 From: hepengfei Date: Wed, 16 Aug 2023 09:36:56 +0800 Subject: [PATCH 05/14] https://gitee.com/ssssssss-team/magic-api/issues/I7R1ED --- .../nebula\346\217\222\344\273\266.md" | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 "magic-api-plugins/magic-api-plugin-nebula/nebula\346\217\222\344\273\266.md" diff --git "a/magic-api-plugins/magic-api-plugin-nebula/nebula\346\217\222\344\273\266.md" "b/magic-api-plugins/magic-api-plugin-nebula/nebula\346\217\222\344\273\266.md" new file mode 100644 index 00000000..62317085 --- /dev/null +++ "b/magic-api-plugins/magic-api-plugin-nebula/nebula\346\217\222\344\273\266.md" @@ -0,0 +1,99 @@ +--- +title: nebula插件 +date: 2023-08-16 09:16:55 +--- + +### 引入依赖 + +```xml + + + org.ssssssss + magic-api-plugin-nebula + magic-api-lastest-version + +``` + +### 配置 + +```yml +nebula: + hostAddress: ${NEBULA_HOSTADDRESS:localhost:9669} + userName: ${NEBULA_USERNAME:root} + password: ${NEBULA_PASSWORD:nebula} + +``` + +### 使用 + +```js +import nebula; +var ngsl = + """" + USE db_name;MATCH p_=(p:`assignee`)-[*3]-(p2:`transferor`) where id(p2) == "阿里巴巴" or id(p)== "阿里巴巴" RETURN p_ limit 1000' + """ +var resultJson = nebula.executeJson(ngsl) +nebula.convert(resultJson) + + +nebula.executeNebulaModel(ngsl) + +其他支持的方法不太常用, 这里不再一一列举, 可参考源码 +org.ssssssss.magicapi.nebula.NebulaModule +``` + +#### 返回的数据格式为: +``` + 该结构的数据可被很多前端组件库支持进行可视化展示 +``` +如: [angv G6](http://antv-2018.alipay.com/zh-cn/g6/3.x/demo/index.html) + + +```json +{ + "code": 0, + "message": "success", + "data": { + "nodes": [ + { + "edgeSize": 1, + "assignee.name": "中航纽赫融资租赁(上海)有限公司", + "type": "vertex", + "assignee.addr": "上海市中国(上海)自由贸易试验区正定路530号A5库区集中辅助区三层318室", + "assignee.legal_person": "周勇", + "registrant.addr": "上海市浦东新区南泉路1261号", + "registrant.name": "中航国际租赁有限公司", + "id": "中航纽赫融资租赁(上海)有限公司", + "assignee.type": "企业" + }, + { + "edgeSize": 15, + "type": "vertex", + "transferor.name": "陕西海富融资租赁有限公司", + "transferor.legal_person": "刘子瑜", + "transferor.type": "企业", + "transferor.addr": "陕西省西安市西安经济技术开发区未央路170号赛高城市广场2号楼企业总部大厦26层05单元", + "registrant.addr": "广东省深圳市前海深港合作区南山街道梦海大厦5035号前海华润金融中心T5写字楼1808", + "registrant.name": "深圳前海盈峰商业保理有限公司", + "id": "陕西海富融资租赁有限公司" + }, ... + ], + "edges": [ + { + "dst": "陕西海富融资租赁有限公司", + "src": "中航纽赫融资租赁(上海)有限公司", + "source": "中航纽赫融资租赁(上海)有限公司", + "label": "trans_with", + "type": "edge", + "target": "陕西海富融资租赁有限公司", + "name": "trans_with", + "ranking": 0, + "value": 0 + },... + ] + }, + "timestamp": 1692149280167, + "requestTime": 1692149280143, + "executeTime": 24 +} +``` \ No newline at end of file -- Gitee From 42ee588afcf98289a6263edd884b1547f36a09b4 Mon Sep 17 00:00:00 2001 From: jmxd <838425805@qq.com> Date: Mon, 21 Aug 2023 16:22:21 +0800 Subject: [PATCH 06/14] =?UTF-8?q?=E8=A1=A5=E5=85=85=E7=BC=BA=E5=B0=91?= =?UTF-8?q?=E7=9A=84else=E5=88=86=E6=94=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../magicapi/core/web/MagicWorkbenchController.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicWorkbenchController.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicWorkbenchController.java index d48c9688..f8bf186a 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicWorkbenchController.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicWorkbenchController.java @@ -264,9 +264,10 @@ public class MagicWorkbenchController extends MagicController implements MagicEx if (path.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX)) { path = path.substring(ResourceUtils.CLASSPATH_URL_PREFIX.length()); bytes = IoUtils.bytes(new ClassPathResource(path).getInputStream()); + } else { + File file = ResourceUtils.getFile(configuration.getEditorConfig()); + bytes = Files.readAllBytes(Paths.get(file.toURI())); } - File file = ResourceUtils.getFile(configuration.getEditorConfig()); - bytes = Files.readAllBytes(Paths.get(file.toURI())); } catch (IOException e) { logger.warn("读取编辑器配置文件{}失败", configuration.getEditorConfig()); } @@ -278,6 +279,7 @@ public class MagicWorkbenchController extends MagicController implements MagicEx } @RequestMapping("/download") + @ResponseBody @Valid(authorization = Authorization.DOWNLOAD) public void download(String groupId, @RequestBody(required = false) List resources, MagicHttpServletRequest request, MagicHttpServletResponse response) throws IOException { isTrue(allowVisit(request, Authorization.DOWNLOAD), PERMISSION_INVALID); -- Gitee From 46c8ab9e5b1c1ffe2c65e1c8e4c44d6a89ae8f30 Mon Sep 17 00:00:00 2001 From: txk <1754875134@qq.com> Date: Mon, 21 Aug 2023 19:33:05 +0800 Subject: [PATCH 07/14] =?UTF-8?q?db=E6=A8=A1=E5=9D=97=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=9F=BA=E4=BA=8Ejdbc=E7=9A=84=E5=AD=98=E5=82=A8=E8=BF=87?= =?UTF-8?q?=E7=A8=8B=E5=8F=8A=E5=87=BD=E6=95=B0=E8=B0=83=E7=94=A8=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../magicapi/modules/db/SQLModule.java | 83 +++++------- .../magicapi/modules/db/model/StoreMode.java | 7 + .../modules/db/model/StoredParam.java | 123 ++++++++++++++++++ .../modules/db/mybatis/TextSqlNode.java | 102 ++++++++++++--- 4 files changed, 251 insertions(+), 64 deletions(-) create mode 100644 magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoreMode.java create mode 100644 magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoredParam.java diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/SQLModule.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/SQLModule.java index 77e19b51..6bf875b3 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/SQLModule.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/SQLModule.java @@ -1,5 +1,7 @@ package org.ssssssss.magicapi.modules.db; +import com.sun.org.apache.bcel.internal.generic.NEW; +import org.apache.commons.beanutils.BeanMap; import org.apache.commons.lang3.StringUtils; import org.springframework.jdbc.core.*; import org.springframework.jdbc.support.GeneratedKeyHolder; @@ -16,6 +18,9 @@ import org.ssssssss.magicapi.modules.db.dialect.Dialect; import org.ssssssss.magicapi.modules.db.inteceptor.NamedTableInterceptor; import org.ssssssss.magicapi.modules.db.inteceptor.SQLInterceptor; import org.ssssssss.magicapi.modules.db.model.Page; +import org.ssssssss.magicapi.modules.db.model.SqlMode; +import org.ssssssss.magicapi.modules.db.model.StoreMode; +import org.ssssssss.magicapi.modules.db.model.StoredParam; import org.ssssssss.magicapi.modules.db.provider.PageProvider; import org.ssssssss.magicapi.modules.db.table.NamedTable; import org.ssssssss.magicapi.core.interceptor.ResultProvider; @@ -23,6 +28,8 @@ import org.ssssssss.magicapi.utils.ScriptManager; import org.ssssssss.script.MagicScriptContext; import org.ssssssss.script.annotation.Comment; import org.ssssssss.script.functions.DynamicAttribute; +import org.ssssssss.script.parsing.GenericTokenParser; +import org.ssssssss.script.parsing.ast.literal.BooleanLiteral; import org.ssssssss.script.parsing.ast.statement.ClassConverter; import org.ssssssss.script.reflection.JavaReflection; import org.ssssssss.script.runtime.RuntimeContext; @@ -31,6 +38,8 @@ import java.beans.Transient; import java.lang.reflect.Field; import java.sql.*; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -81,6 +90,7 @@ public class SQLModule implements DynamicAttribute, Dynami private long ttl; private String logicDeleteColumn; private String logicDeleteValue; + public static List params; public SQLModule() { @@ -780,60 +790,37 @@ public class SQLModule implements DynamicAttribute, Dynami } } - @Comment("调用存储过程方法") - public Object callPro( - @Comment(name = "procName", value = "存储过程名称") String procName, - @Comment(name = "list", value = "[{\"p\":\"参数名\",\"io\":\"i/o/io\",\"t\":\"java.sql.Types\",\"v\":\"参数值\"}]") List> list) { - List strings = new ArrayList<>(); - for (Map ignored : list) { - strings.add("?"); - } - String result = String.join(",", strings); - final String callProcedureSql = "call " + procName + "(" + result + ")"; - return this.call(callProcedureSql, list); + @Comment("调用过程") + public Object call(RuntimeContext runtimeContext, + @Comment(name = "sqlOrXml", value = "`SQL`语句或`xml`") String sqlOrXml) { + return call(runtimeContext, sqlOrXml, null); + } + private Object call(RuntimeContext runtimeContext, + @Comment(name = "sqlOrXml", value = "`SQL`语句或`xml`") String sqlOrXml, + @Comment(name = "params", value = "变量信息") Map params){ + return call(new BoundSql(runtimeContext, sqlOrXml, params, this),runtimeContext); } - @Comment("调用函数方法") - public Object callFun( - @Comment(name = "funcName", value = "函数名称") String procName, - @Comment(name = "list", value = "[{\"p\":\"参数名\",\"io\":\"i/o/io\",\"t\":\"java.sql.type\",\"v\":\"参数值\"}]") List> list) { - List strings = new ArrayList<>(); - for (Map ignored : list) { - strings.add("?"); - } - String result = String.join(",", strings); - final String callFunctionSql = "{call " + procName + "(" + result + ")}"; - return this.call(callFunctionSql, list); + @Transient + public Object call(BoundSql boundSql,RuntimeContext runtimeContext) { + assertDatasourceNotNull(); + return boundSql.execute(this.sqlInterceptors, () -> call(boundSql)); } - private Object call(String sql, List> list) { - List params = new ArrayList<>(); - for (Map map : list) { - String paramName = (String) map.get("p"); - int type = (int) map.get("t"); - if ("i".equals(map.get("io"))) { - params.add(new SqlParameter(paramName, type)); - } else if ("o".equals(map.get("io"))) { - params.add(new SqlOutParameter(paramName, type)); - } else { - params.add(new SqlInOutParameter(paramName, type)); - } - } - final String callFunctionSql = sql; + private Object call(BoundSql boundSql) { return this.dataSourceNode.getJdbcTemplate().call( con -> { - CallableStatement statement = con.prepareCall(callFunctionSql); - for (int i = 0; i < list.size(); i++) { - Map map = list.get(i); - Object param = map.get("v"); - int type = (int) map.get("t"); - if ("i".equals(map.get("io"))) { - statement.setObject(i + 1, param); - } else if ("o".equals(map.get("io"))) { - statement.registerOutParameter(i + 1, type); - } else { - statement.setObject(i + 1, param); - statement.registerOutParameter(i + 1, type); + CallableStatement statement = con.prepareCall(boundSql.getSql()); + Object[] parameters = boundSql.getParameters(); + for (int i = 0; i < parameters.length; i++) { + StoredParam storedParam = (StoredParam) parameters[i]; + if (storedParam.getInOut() == StoreMode.IN) { + statement.setObject(i + 1, storedParam.getValue()); + } else if (storedParam.getInOut() == StoreMode.OUT) { + statement.registerOutParameter(i + 1, storedParam.getType()); + } else if (storedParam.getInOut() == StoreMode.INOUT) { + statement.setObject(i + 1, storedParam.getValue()); + statement.registerOutParameter(i + 1, storedParam.getType()); } } return statement; diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoreMode.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoreMode.java new file mode 100644 index 00000000..9404d536 --- /dev/null +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoreMode.java @@ -0,0 +1,7 @@ +package org.ssssssss.magicapi.modules.db.model; + +public enum StoreMode { + INOUT, + IN, + OUT +} diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoredParam.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoredParam.java new file mode 100644 index 00000000..7b86d901 --- /dev/null +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoredParam.java @@ -0,0 +1,123 @@ +package org.ssssssss.magicapi.modules.db.model; + +import java.sql.Types; +import java.util.Objects; + +/** + * 过程入参 + */ +public class StoredParam { + //参数SQL类型 + private Integer type; + + //入出参 + private StoreMode inOut; + + //参数值 + private Object value; + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + public StoreMode getInOut() { + return inOut; + } + + public void setInOut(StoreMode inOut) { + this.inOut = inOut; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + public static int paramType(String type){ + if (Objects.equals(type, "BIT")) { + return Types.BIT; + } else if (Objects.equals(type, "TINYINT")) { + return Types.TINYINT; + } else if (Objects.equals(type, "SMALLINT")) { + return Types.SMALLINT; + } else if (Objects.equals(type, "INTEGER")) { + return Types.INTEGER; + } else if (Objects.equals(type, "BIGINT")) { + return Types.BIGINT; + } else if (Objects.equals(type, "FLOAT")) { + return Types.FLOAT; + } else if (Objects.equals(type, "REAL")) { + return Types.REAL; + } else if (Objects.equals(type, "NUMERIC")) { + return Types.NUMERIC; + } else if (Objects.equals(type, "DECIMAL")) { + return Types.DECIMAL; + } else if (Objects.equals(type, "CHAR")) { + return Types.CHAR; + } else if (Objects.equals(type, "VARCHAR")) { + return Types.VARCHAR; + } else if (Objects.equals(type, "LONGVARCHAR")) { + return Types.LONGVARCHAR; + } else if (Objects.equals(type, "DATE")) { + return Types.DATE; + } else if (Objects.equals(type, "TIME")) { + return Types.TIME; + } else if (Objects.equals(type, "TIMESTAMP")) { + return Types.TIMESTAMP; + } else if (Objects.equals(type, "BINARY")) { + return Types.BINARY; + } else if (Objects.equals(type, "VARBINARY")) { + return Types.VARBINARY; + } else if (Objects.equals(type, "LONGVARBINARY")) { + return Types.LONGVARBINARY; + } else if (Objects.equals(type, "NULL")) { + return Types.NULL; + } else if (Objects.equals(type, "OTHER")) { + return Types.OTHER; + } else if (Objects.equals(type, "JAVA_OBJECT")) { + return Types.JAVA_OBJECT; + } else if (Objects.equals(type, "DISTINCT")) { + return Types.DISTINCT; + } else if (Objects.equals(type, "STRUCT")) { + return Types.STRUCT; + } else if (Objects.equals(type, "ARRAY")) { + return Types.ARRAY; + } else if (Objects.equals(type, "BLOB")) { + return Types.BLOB; + } else if (Objects.equals(type, "CLOB")) { + return Types.CLOB; + } else if (Objects.equals(type, "REF")) { + return Types.REF; + } else if (Objects.equals(type, "DATALINK")) { + return Types.DATALINK; + } else if (Objects.equals(type, "BOOLEAN")) { + return Types.BOOLEAN; + } else if (Objects.equals(type, "ROWID")) { + return Types.ROWID; + } else if (Objects.equals(type, "NCHAR")) { + return Types.NCHAR; + } else if (Objects.equals(type, "NVARCHAR")) { + return Types.NVARCHAR; + } else if (Objects.equals(type, "LONGNVARCHAR")) { + return Types.LONGNVARCHAR; + } else if (Objects.equals(type, "NCLOB")) { + return Types.NCLOB; + } else if (Objects.equals(type, "SQLXML")) { + return Types.SQLXML; + } else if (Objects.equals(type, "REF_CURSOR")) { + return Types.REF_CURSOR; + } else if (Objects.equals(type, "TIME_WITH_TIMEZONE")) { + return Types.TIME_WITH_TIMEZONE; + } else if (Objects.equals(type, "TIMESTAMP_WITH_TIMEZONE")) { + return Types.TIMESTAMP_WITH_TIMEZONE; + } + return Types.NULL; + } +} diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/mybatis/TextSqlNode.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/mybatis/TextSqlNode.java index 7e198e83..45165439 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/mybatis/TextSqlNode.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/mybatis/TextSqlNode.java @@ -1,12 +1,18 @@ package org.ssssssss.magicapi.modules.db.mybatis; +import org.springframework.jdbc.core.SqlInOutParameter; +import org.springframework.jdbc.core.SqlOutParameter; +import org.springframework.jdbc.core.SqlParameter; +import org.ssssssss.magicapi.modules.db.SQLModule; +import org.ssssssss.magicapi.modules.db.model.StoreMode; +import org.ssssssss.magicapi.modules.db.model.StoredParam; import org.ssssssss.magicapi.utils.ScriptManager; import org.ssssssss.script.functions.StreamExtension; import org.ssssssss.script.parsing.GenericTokenParser; import org.ssssssss.script.parsing.ast.literal.BooleanLiteral; -import java.util.List; -import java.util.Map; +import java.sql.Types; +import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -27,6 +33,18 @@ public class TextSqlNode extends SqlNode { private static final GenericTokenParser IF_PARAM_TOKEN_PARSER = new GenericTokenParser("?{", ",", true); + private static final GenericTokenParser OUT_PARAM_TOKEN_PARSER = new GenericTokenParser("@{", ",", true); + + private static final GenericTokenParser OUT_TOKEN_PARSER = new GenericTokenParser("@{", "}", true); + + private static final GenericTokenParser TYPE_TOKEN_PARSER = new GenericTokenParser(",", "}", true); + + private static final GenericTokenParser INOUT_TOKEN_PARSER = new GenericTokenParser("@{", "(", true); + + private static final GenericTokenParser IN_PARAM_TOKEN_PARSER = new GenericTokenParser("#{", ",", true); + + private static final GenericTokenParser PARAM_TOKEN_PARSER = new GenericTokenParser("(", ")", true); + /** * SQL */ @@ -37,6 +55,7 @@ public class TextSqlNode extends SqlNode { } public static String parseSql(String sql, Map varMap, List parameters) { + SQLModule.params = new ArrayList<>(); // 处理?{}参数 sql = IF_TOKEN_PARSER.parse(sql.trim(), text -> { AtomicBoolean ifTrue = new AtomicBoolean(false); @@ -50,21 +69,72 @@ public class TextSqlNode extends SqlNode { sql = CONCAT_TOKEN_PARSER.parse(sql, text -> String.valueOf(ScriptManager.executeExpression(text, varMap))); // 处理#{}参数 sql = REPLACE_TOKEN_PARSER.parse(sql, text -> { - Object value = ScriptManager.executeExpression(text, varMap); - if (value == null) { - parameters.add(null); - return "?"; - } - try { - //对集合自动展开 - List objects = StreamExtension.arrayLikeToList(value); - parameters.addAll(objects); - return IntStream.range(0, objects.size()).mapToObj(t -> "?").collect(Collectors.joining(",")); - } catch (Exception e) { - parameters.add(value); - return "?"; - } + StoredParam storedParam = new StoredParam(); + if (text.indexOf(",") > 0) { + IN_PARAM_TOKEN_PARSER.parse("#{" + text, param -> { + PARAM_TOKEN_PARSER.parse(param,variable -> { + Object value = ScriptManager.executeExpression(variable, varMap); + storedParam.setValue(value); + storedParam.setInOut(StoreMode.IN); + TYPE_TOKEN_PARSER.parse(text + "}", type -> { + storedParam.setType(StoredParam.paramType(type)); + SQLModule.params.add(new SqlParameter(param, StoredParam.paramType(type))); + return null; + }); + parameters.add(storedParam); + return null; + }); + return null; + }); + return "?"; + } else { + Object value = ScriptManager.executeExpression(text, varMap); + if (value == null) { + parameters.add(null); + return "?"; + } + try { + //对集合自动展开 + List objects = StreamExtension.arrayLikeToList(value); + parameters.addAll(objects); + return IntStream.range(0, objects.size()).mapToObj(t -> "?").collect(Collectors.joining(",")); + } catch (Exception e) { + parameters.add(value); + return "?"; + } + } }); + + sql = OUT_TOKEN_PARSER.parse(sql,text -> { + StoredParam storedParam = new StoredParam(); + String val = OUT_PARAM_TOKEN_PARSER.parse("@{" + text, param -> { + TYPE_TOKEN_PARSER.parse(text + "}", type -> { + if (param.indexOf("(") > 0) { + PARAM_TOKEN_PARSER.parse(param,variable -> { + Object value = ScriptManager.executeExpression(variable, varMap); + storedParam.setValue(value); + storedParam.setInOut(StoreMode.INOUT); + storedParam.setType(StoredParam.paramType(type)); + return null; + }); + INOUT_TOKEN_PARSER.parse("@{" + param, inoutParam -> { + SQLModule.params.add(new SqlInOutParameter(inoutParam, StoredParam.paramType(type))); + return null; + }); + } else { + Object value = ScriptManager.executeExpression(param, varMap); + storedParam.setValue(value); + storedParam.setInOut(StoreMode.OUT); + storedParam.setType(StoredParam.paramType(type)); + SQLModule.params.add(new SqlOutParameter(param, StoredParam.paramType(type))); + } + return null; + }); + parameters.add(storedParam); + return null; + }); + return "?"; + }); return sql; } -- Gitee From d67fd0325a0e3399dc55ea877dcee4711157a4f4 Mon Sep 17 00:00:00 2001 From: jmxd <838425805@qq.com> Date: Tue, 22 Aug 2023 10:54:52 +0800 Subject: [PATCH 08/14] =?UTF-8?q?=E5=AD=98=E5=82=A8=E8=BF=87=E7=A8=8B?= =?UTF-8?q?=E5=8E=BB=E9=99=A4=E5=AF=B9#{xxx(),=20varchar}=20=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E7=9A=84=E8=A7=A3=E6=9E=90=EF=BC=8C=E5=AF=B9=E4=BA=8E?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E7=B1=BB=E5=9E=8B=E4=B8=8D=E5=8C=BA=E5=88=86?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F=E5=86=99=E5=A4=84=E7=90=86=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../magicapi/modules/db/SQLModule.java | 29 ++--- .../magicapi/modules/db/model/SqlTypes.java | 25 ++++ .../modules/db/model/StoredParam.java | 82 +----------- .../modules/db/mybatis/TextSqlNode.java | 121 +++++++----------- 4 files changed, 85 insertions(+), 172 deletions(-) create mode 100644 magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/SqlTypes.java diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/SQLModule.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/SQLModule.java index 6bf875b3..78a01b88 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/SQLModule.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/SQLModule.java @@ -1,48 +1,38 @@ package org.ssssssss.magicapi.modules.db; -import com.sun.org.apache.bcel.internal.generic.NEW; -import org.apache.commons.beanutils.BeanMap; import org.apache.commons.lang3.StringUtils; import org.springframework.jdbc.core.*; import org.springframework.jdbc.support.GeneratedKeyHolder; -import org.ssssssss.magicapi.core.model.Options; -import org.ssssssss.magicapi.modules.DynamicModule; -import org.ssssssss.magicapi.modules.db.dialect.DialectAdapter; -import org.ssssssss.magicapi.datasource.model.MagicDynamicDataSource; -import org.ssssssss.magicapi.datasource.model.MagicDynamicDataSource.DataSourceNode; import org.ssssssss.magicapi.core.annotation.MagicModule; import org.ssssssss.magicapi.core.context.RequestContext; import org.ssssssss.magicapi.core.context.RequestEntity; +import org.ssssssss.magicapi.core.interceptor.ResultProvider; +import org.ssssssss.magicapi.core.model.Options; +import org.ssssssss.magicapi.datasource.model.MagicDynamicDataSource; +import org.ssssssss.magicapi.datasource.model.MagicDynamicDataSource.DataSourceNode; +import org.ssssssss.magicapi.modules.DynamicModule; import org.ssssssss.magicapi.modules.db.cache.SqlCache; import org.ssssssss.magicapi.modules.db.dialect.Dialect; +import org.ssssssss.magicapi.modules.db.dialect.DialectAdapter; import org.ssssssss.magicapi.modules.db.inteceptor.NamedTableInterceptor; import org.ssssssss.magicapi.modules.db.inteceptor.SQLInterceptor; import org.ssssssss.magicapi.modules.db.model.Page; -import org.ssssssss.magicapi.modules.db.model.SqlMode; +import org.ssssssss.magicapi.modules.db.model.SqlTypes; import org.ssssssss.magicapi.modules.db.model.StoreMode; import org.ssssssss.magicapi.modules.db.model.StoredParam; import org.ssssssss.magicapi.modules.db.provider.PageProvider; import org.ssssssss.magicapi.modules.db.table.NamedTable; -import org.ssssssss.magicapi.core.interceptor.ResultProvider; import org.ssssssss.magicapi.utils.ScriptManager; import org.ssssssss.script.MagicScriptContext; import org.ssssssss.script.annotation.Comment; import org.ssssssss.script.functions.DynamicAttribute; -import org.ssssssss.script.parsing.GenericTokenParser; -import org.ssssssss.script.parsing.ast.literal.BooleanLiteral; import org.ssssssss.script.parsing.ast.statement.ClassConverter; -import org.ssssssss.script.reflection.JavaReflection; import org.ssssssss.script.runtime.RuntimeContext; import java.beans.Transient; -import java.lang.reflect.Field; import java.sql.*; import java.util.*; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; /** * 数据库查询模块 @@ -53,9 +43,6 @@ import java.util.stream.Stream; public class SQLModule implements DynamicAttribute, DynamicModule { static { try { - Field[] fields = Types.class.getFields(); - Map mappings = Stream.of(fields) - .collect(Collectors.toMap(field -> field.getName().toLowerCase(), field -> (Integer) JavaReflection.getFieldValue(Types.class, field))); ClassConverter.register("sql", (value, params) -> { if (params == null || params.length == 0) { return value; @@ -67,7 +54,7 @@ public class SQLModule implements DynamicAttribute, Dynami if (StringUtils.isBlank(target)) { return value; } - Integer sqlType = mappings.get(target.toLowerCase()); + Integer sqlType = SqlTypes.getSqlType(target); return sqlType == null ? value : new SqlParameterValue(sqlType, target, value); }); } catch (Exception ignored) { diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/SqlTypes.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/SqlTypes.java new file mode 100644 index 00000000..02b30cc8 --- /dev/null +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/SqlTypes.java @@ -0,0 +1,25 @@ +package org.ssssssss.magicapi.modules.db.model; + +import org.ssssssss.script.reflection.JavaReflection; + +import java.lang.reflect.Field; +import java.sql.Types; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class SqlTypes { + + private static final Map SQL_TYPE_MAPPINGS; + + static { + Field[] fields = Types.class.getFields(); + SQL_TYPE_MAPPINGS = Stream.of(fields) + .collect(Collectors.toMap(field -> field.getName().toLowerCase(), field -> (Integer) JavaReflection.getFieldValue(Types.class, field))); + } + + + public static Integer getSqlType(String type){ + return SQL_TYPE_MAPPINGS.get(type.toLowerCase()); + } +} diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoredParam.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoredParam.java index 7b86d901..7e43fafe 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoredParam.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoredParam.java @@ -1,12 +1,12 @@ package org.ssssssss.magicapi.modules.db.model; import java.sql.Types; -import java.util.Objects; /** * 过程入参 */ public class StoredParam { + //参数SQL类型 private Integer type; @@ -41,83 +41,7 @@ public class StoredParam { } public static int paramType(String type){ - if (Objects.equals(type, "BIT")) { - return Types.BIT; - } else if (Objects.equals(type, "TINYINT")) { - return Types.TINYINT; - } else if (Objects.equals(type, "SMALLINT")) { - return Types.SMALLINT; - } else if (Objects.equals(type, "INTEGER")) { - return Types.INTEGER; - } else if (Objects.equals(type, "BIGINT")) { - return Types.BIGINT; - } else if (Objects.equals(type, "FLOAT")) { - return Types.FLOAT; - } else if (Objects.equals(type, "REAL")) { - return Types.REAL; - } else if (Objects.equals(type, "NUMERIC")) { - return Types.NUMERIC; - } else if (Objects.equals(type, "DECIMAL")) { - return Types.DECIMAL; - } else if (Objects.equals(type, "CHAR")) { - return Types.CHAR; - } else if (Objects.equals(type, "VARCHAR")) { - return Types.VARCHAR; - } else if (Objects.equals(type, "LONGVARCHAR")) { - return Types.LONGVARCHAR; - } else if (Objects.equals(type, "DATE")) { - return Types.DATE; - } else if (Objects.equals(type, "TIME")) { - return Types.TIME; - } else if (Objects.equals(type, "TIMESTAMP")) { - return Types.TIMESTAMP; - } else if (Objects.equals(type, "BINARY")) { - return Types.BINARY; - } else if (Objects.equals(type, "VARBINARY")) { - return Types.VARBINARY; - } else if (Objects.equals(type, "LONGVARBINARY")) { - return Types.LONGVARBINARY; - } else if (Objects.equals(type, "NULL")) { - return Types.NULL; - } else if (Objects.equals(type, "OTHER")) { - return Types.OTHER; - } else if (Objects.equals(type, "JAVA_OBJECT")) { - return Types.JAVA_OBJECT; - } else if (Objects.equals(type, "DISTINCT")) { - return Types.DISTINCT; - } else if (Objects.equals(type, "STRUCT")) { - return Types.STRUCT; - } else if (Objects.equals(type, "ARRAY")) { - return Types.ARRAY; - } else if (Objects.equals(type, "BLOB")) { - return Types.BLOB; - } else if (Objects.equals(type, "CLOB")) { - return Types.CLOB; - } else if (Objects.equals(type, "REF")) { - return Types.REF; - } else if (Objects.equals(type, "DATALINK")) { - return Types.DATALINK; - } else if (Objects.equals(type, "BOOLEAN")) { - return Types.BOOLEAN; - } else if (Objects.equals(type, "ROWID")) { - return Types.ROWID; - } else if (Objects.equals(type, "NCHAR")) { - return Types.NCHAR; - } else if (Objects.equals(type, "NVARCHAR")) { - return Types.NVARCHAR; - } else if (Objects.equals(type, "LONGNVARCHAR")) { - return Types.LONGNVARCHAR; - } else if (Objects.equals(type, "NCLOB")) { - return Types.NCLOB; - } else if (Objects.equals(type, "SQLXML")) { - return Types.SQLXML; - } else if (Objects.equals(type, "REF_CURSOR")) { - return Types.REF_CURSOR; - } else if (Objects.equals(type, "TIME_WITH_TIMEZONE")) { - return Types.TIME_WITH_TIMEZONE; - } else if (Objects.equals(type, "TIMESTAMP_WITH_TIMEZONE")) { - return Types.TIMESTAMP_WITH_TIMEZONE; - } - return Types.NULL; + Integer sqlType = SqlTypes.getSqlType(type); + return sqlType == null ? Types.NULL : sqlType; } } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/mybatis/TextSqlNode.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/mybatis/TextSqlNode.java index 45165439..d5be12be 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/mybatis/TextSqlNode.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/mybatis/TextSqlNode.java @@ -35,15 +35,13 @@ public class TextSqlNode extends SqlNode { private static final GenericTokenParser OUT_PARAM_TOKEN_PARSER = new GenericTokenParser("@{", ",", true); - private static final GenericTokenParser OUT_TOKEN_PARSER = new GenericTokenParser("@{", "}", true); + private static final GenericTokenParser OUT_TOKEN_PARSER = new GenericTokenParser("@{", "}", true); - private static final GenericTokenParser TYPE_TOKEN_PARSER = new GenericTokenParser(",", "}", true); + private static final GenericTokenParser TYPE_TOKEN_PARSER = new GenericTokenParser(",", "}", true); - private static final GenericTokenParser INOUT_TOKEN_PARSER = new GenericTokenParser("@{", "(", true); + private static final GenericTokenParser INOUT_TOKEN_PARSER = new GenericTokenParser("@{", "(", true); - private static final GenericTokenParser IN_PARAM_TOKEN_PARSER = new GenericTokenParser("#{", ",", true); - - private static final GenericTokenParser PARAM_TOKEN_PARSER = new GenericTokenParser("(", ")", true); + private static final GenericTokenParser PARAM_TOKEN_PARSER = new GenericTokenParser("(", ")", true); /** * SQL @@ -55,7 +53,7 @@ public class TextSqlNode extends SqlNode { } public static String parseSql(String sql, Map varMap, List parameters) { - SQLModule.params = new ArrayList<>(); + SQLModule.params = new ArrayList<>(); // 处理?{}参数 sql = IF_TOKEN_PARSER.parse(sql.trim(), text -> { AtomicBoolean ifTrue = new AtomicBoolean(false); @@ -69,72 +67,51 @@ public class TextSqlNode extends SqlNode { sql = CONCAT_TOKEN_PARSER.parse(sql, text -> String.valueOf(ScriptManager.executeExpression(text, varMap))); // 处理#{}参数 sql = REPLACE_TOKEN_PARSER.parse(sql, text -> { - StoredParam storedParam = new StoredParam(); - if (text.indexOf(",") > 0) { - IN_PARAM_TOKEN_PARSER.parse("#{" + text, param -> { - PARAM_TOKEN_PARSER.parse(param,variable -> { - Object value = ScriptManager.executeExpression(variable, varMap); - storedParam.setValue(value); - storedParam.setInOut(StoreMode.IN); - TYPE_TOKEN_PARSER.parse(text + "}", type -> { - storedParam.setType(StoredParam.paramType(type)); - SQLModule.params.add(new SqlParameter(param, StoredParam.paramType(type))); - return null; - }); - parameters.add(storedParam); - return null; - }); - return null; - }); - return "?"; - } else { - Object value = ScriptManager.executeExpression(text, varMap); - if (value == null) { - parameters.add(null); - return "?"; - } - try { - //对集合自动展开 - List objects = StreamExtension.arrayLikeToList(value); - parameters.addAll(objects); - return IntStream.range(0, objects.size()).mapToObj(t -> "?").collect(Collectors.joining(",")); - } catch (Exception e) { - parameters.add(value); - return "?"; - } - } + Object value = ScriptManager.executeExpression(text, varMap); + if (value == null) { + parameters.add(null); + return "?"; + } + try { + //对集合自动展开 + List objects = StreamExtension.arrayLikeToList(value); + parameters.addAll(objects); + return IntStream.range(0, objects.size()).mapToObj(t -> "?").collect(Collectors.joining(",")); + } catch (Exception e) { + parameters.add(value); + return "?"; + } + }); + sql = OUT_TOKEN_PARSER.parse(sql, text -> { + StoredParam storedParam = new StoredParam(); + String val = OUT_PARAM_TOKEN_PARSER.parse("@{" + text, param -> { + TYPE_TOKEN_PARSER.parse(text + "}", type -> { + if (param.indexOf("(") > 0) { + PARAM_TOKEN_PARSER.parse(param, variable -> { + Object value = ScriptManager.executeExpression(variable, varMap); + storedParam.setValue(value); + storedParam.setInOut(StoreMode.INOUT); + storedParam.setType(StoredParam.paramType(type)); + return null; + }); + INOUT_TOKEN_PARSER.parse("@{" + param, inoutParam -> { + SQLModule.params.add(new SqlInOutParameter(inoutParam, StoredParam.paramType(type))); + return null; + }); + } else { + Object value = ScriptManager.executeExpression(param, varMap); + storedParam.setValue(value); + storedParam.setInOut(StoreMode.OUT); + storedParam.setType(StoredParam.paramType(type)); + SQLModule.params.add(new SqlOutParameter(param, StoredParam.paramType(type))); + } + return null; + }); + parameters.add(storedParam); + return null; + }); + return "?"; }); - - sql = OUT_TOKEN_PARSER.parse(sql,text -> { - StoredParam storedParam = new StoredParam(); - String val = OUT_PARAM_TOKEN_PARSER.parse("@{" + text, param -> { - TYPE_TOKEN_PARSER.parse(text + "}", type -> { - if (param.indexOf("(") > 0) { - PARAM_TOKEN_PARSER.parse(param,variable -> { - Object value = ScriptManager.executeExpression(variable, varMap); - storedParam.setValue(value); - storedParam.setInOut(StoreMode.INOUT); - storedParam.setType(StoredParam.paramType(type)); - return null; - }); - INOUT_TOKEN_PARSER.parse("@{" + param, inoutParam -> { - SQLModule.params.add(new SqlInOutParameter(inoutParam, StoredParam.paramType(type))); - return null; - }); - } else { - Object value = ScriptManager.executeExpression(param, varMap); - storedParam.setValue(value); - storedParam.setInOut(StoreMode.OUT); - storedParam.setType(StoredParam.paramType(type)); - SQLModule.params.add(new SqlOutParameter(param, StoredParam.paramType(type))); - } - return null; - }); - parameters.add(storedParam); - return null; - }); - return "?"; - }); return sql; } -- Gitee From dc99453d9cd7b9cb3d67832505244bd462ecf70a Mon Sep 17 00:00:00 2001 From: jmxd <838425805@qq.com> Date: Wed, 23 Aug 2023 10:39:39 +0800 Subject: [PATCH 09/14] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E5=AD=98=E5=82=A8=E8=BF=87=E7=A8=8B?= =?UTF-8?q?=E5=87=BA=E5=8F=82=E4=B8=8D=E6=8C=87=E5=AE=9A=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../magicapi/modules/db/BoundSql.java | 18 ++++++ .../magicapi/modules/db/SQLModule.java | 59 ++++++++----------- .../magicapi/modules/db/model/SqlTypes.java | 10 +++- .../magicapi/modules/db/model/StoreMode.java | 7 --- .../modules/db/model/StoredParam.java | 47 --------------- .../modules/db/mybatis/TextSqlNode.java | 57 ++++++++---------- 6 files changed, 77 insertions(+), 121 deletions(-) delete mode 100644 magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoreMode.java delete mode 100644 magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoredParam.java diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/BoundSql.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/BoundSql.java index bad6ae16..6d47e29f 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/BoundSql.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/BoundSql.java @@ -1,5 +1,7 @@ package org.ssssssss.magicapi.modules.db; +import org.springframework.jdbc.core.SqlOutParameter; +import org.springframework.jdbc.core.SqlParameter; import org.ssssssss.magicapi.core.context.RequestContext; import org.ssssssss.magicapi.core.context.RequestEntity; import org.ssssssss.magicapi.modules.db.inteceptor.SQLInterceptor; @@ -8,9 +10,11 @@ import org.ssssssss.magicapi.modules.db.mybatis.SqlNode; import org.ssssssss.magicapi.modules.db.mybatis.TextSqlNode; import org.ssssssss.script.runtime.RuntimeContext; +import java.sql.Types; import java.util.*; import java.util.function.Supplier; import java.util.regex.Pattern; +import java.util.stream.Collectors; /** * SQL参数处理 @@ -137,6 +141,20 @@ public class BoundSql { return parameters.toArray(); } + public List getDeclareParameters(){ + return this.parameters.stream() + .map(it -> { + if(it instanceof SqlParameter){ + SqlParameter p = (SqlParameter) it; + if(p.getName() != null){ + return new SqlOutParameter(p.getName(), p.getSqlType()); + } + } + return new SqlParameter(Types.NULL); + }) + .collect(Collectors.toList()); + } + /** * 设置要执行的参数 */ diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/SQLModule.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/SQLModule.java index 78a01b88..4ee5cc0b 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/SQLModule.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/SQLModule.java @@ -18,8 +18,6 @@ import org.ssssssss.magicapi.modules.db.inteceptor.NamedTableInterceptor; import org.ssssssss.magicapi.modules.db.inteceptor.SQLInterceptor; import org.ssssssss.magicapi.modules.db.model.Page; import org.ssssssss.magicapi.modules.db.model.SqlTypes; -import org.ssssssss.magicapi.modules.db.model.StoreMode; -import org.ssssssss.magicapi.modules.db.model.StoredParam; import org.ssssssss.magicapi.modules.db.provider.PageProvider; import org.ssssssss.magicapi.modules.db.table.NamedTable; import org.ssssssss.magicapi.utils.ScriptManager; @@ -777,41 +775,32 @@ public class SQLModule implements DynamicAttribute, Dynami } } - @Comment("调用过程") + @Comment("调用存储过程") public Object call(RuntimeContext runtimeContext, @Comment(name = "sqlOrXml", value = "`SQL`语句或`xml`") String sqlOrXml) { - return call(runtimeContext, sqlOrXml, null); - } - private Object call(RuntimeContext runtimeContext, - @Comment(name = "sqlOrXml", value = "`SQL`语句或`xml`") String sqlOrXml, - @Comment(name = "params", value = "变量信息") Map params){ - return call(new BoundSql(runtimeContext, sqlOrXml, params, this),runtimeContext); - } - - @Transient - public Object call(BoundSql boundSql,RuntimeContext runtimeContext) { - assertDatasourceNotNull(); - return boundSql.execute(this.sqlInterceptors, () -> call(boundSql)); - } - - private Object call(BoundSql boundSql) { - return this.dataSourceNode.getJdbcTemplate().call( - con -> { - CallableStatement statement = con.prepareCall(boundSql.getSql()); - Object[] parameters = boundSql.getParameters(); - for (int i = 0; i < parameters.length; i++) { - StoredParam storedParam = (StoredParam) parameters[i]; - if (storedParam.getInOut() == StoreMode.IN) { - statement.setObject(i + 1, storedParam.getValue()); - } else if (storedParam.getInOut() == StoreMode.OUT) { - statement.registerOutParameter(i + 1, storedParam.getType()); - } else if (storedParam.getInOut() == StoreMode.INOUT) { - statement.setObject(i + 1, storedParam.getValue()); - statement.registerOutParameter(i + 1, storedParam.getType()); - } - } - return statement; - }, params); + assertDatasourceNotNull(); + BoundSql boundSql = new BoundSql(runtimeContext, sqlOrXml, Collections.emptyMap(), this); + return boundSql.execute(this.sqlInterceptors, () -> this.dataSourceNode.getJdbcTemplate().call( + con -> { + CallableStatement statement = con.prepareCall(boundSql.getSql()); + Object[] parameters = boundSql.getParameters(); + for (int i = 0, size = parameters.length; i < size; i++) { + Object parameter = parameters[i]; + if (parameter instanceof SqlOutParameter) { + SqlOutParameter sop = (SqlOutParameter)parameter; + statement.registerOutParameter(i + 1, sop.getSqlType()); + } else if(parameter instanceof SqlParameterValue){ + SqlParameterValue spv = (SqlParameterValue)parameter; + if(spv.getName() != null){ + statement.registerOutParameter(i + 1, spv.getSqlType()); + } + statement.setObject(i + 1, spv.getValue()); + } else { + statement.setObject(i + 1, parameter); + } + } + return statement; + }, boundSql.getDeclareParameters())); } } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/SqlTypes.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/SqlTypes.java index 02b30cc8..86f11953 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/SqlTypes.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/SqlTypes.java @@ -20,6 +20,14 @@ public class SqlTypes { public static Integer getSqlType(String type){ - return SQL_TYPE_MAPPINGS.get(type.toLowerCase()); + return getSqlType(type, true); + } + + public static Integer getSqlType(String type, boolean defaultNull){ + Integer value = SQL_TYPE_MAPPINGS.get(type.toLowerCase()); + if(value == null && defaultNull){ + return Types.NULL; + } + return value; } } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoreMode.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoreMode.java deleted file mode 100644 index 9404d536..00000000 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoreMode.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.ssssssss.magicapi.modules.db.model; - -public enum StoreMode { - INOUT, - IN, - OUT -} diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoredParam.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoredParam.java deleted file mode 100644 index 7e43fafe..00000000 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/model/StoredParam.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.ssssssss.magicapi.modules.db.model; - -import java.sql.Types; - -/** - * 过程入参 - */ -public class StoredParam { - - //参数SQL类型 - private Integer type; - - //入出参 - private StoreMode inOut; - - //参数值 - private Object value; - - public Integer getType() { - return type; - } - - public void setType(Integer type) { - this.type = type; - } - - public StoreMode getInOut() { - return inOut; - } - - public void setInOut(StoreMode inOut) { - this.inOut = inOut; - } - - public Object getValue() { - return value; - } - - public void setValue(Object value) { - this.value = value; - } - - public static int paramType(String type){ - Integer sqlType = SqlTypes.getSqlType(type); - return sqlType == null ? Types.NULL : sqlType; - } -} diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/mybatis/TextSqlNode.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/mybatis/TextSqlNode.java index d5be12be..b5b669d9 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/mybatis/TextSqlNode.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/mybatis/TextSqlNode.java @@ -2,18 +2,20 @@ package org.ssssssss.magicapi.modules.db.mybatis; import org.springframework.jdbc.core.SqlInOutParameter; import org.springframework.jdbc.core.SqlOutParameter; -import org.springframework.jdbc.core.SqlParameter; +import org.springframework.jdbc.core.SqlParameterValue; import org.ssssssss.magicapi.modules.db.SQLModule; -import org.ssssssss.magicapi.modules.db.model.StoreMode; -import org.ssssssss.magicapi.modules.db.model.StoredParam; +import org.ssssssss.magicapi.modules.db.model.SqlTypes; import org.ssssssss.magicapi.utils.ScriptManager; import org.ssssssss.script.functions.StreamExtension; import org.ssssssss.script.parsing.GenericTokenParser; import org.ssssssss.script.parsing.ast.literal.BooleanLiteral; import java.sql.Types; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -41,8 +43,6 @@ public class TextSqlNode extends SqlNode { private static final GenericTokenParser INOUT_TOKEN_PARSER = new GenericTokenParser("@{", "(", true); - private static final GenericTokenParser PARAM_TOKEN_PARSER = new GenericTokenParser("(", ")", true); - /** * SQL */ @@ -83,31 +83,26 @@ public class TextSqlNode extends SqlNode { } }); sql = OUT_TOKEN_PARSER.parse(sql, text -> { - StoredParam storedParam = new StoredParam(); - String val = OUT_PARAM_TOKEN_PARSER.parse("@{" + text, param -> { - TYPE_TOKEN_PARSER.parse(text + "}", type -> { - if (param.indexOf("(") > 0) { - PARAM_TOKEN_PARSER.parse(param, variable -> { - Object value = ScriptManager.executeExpression(variable, varMap); - storedParam.setValue(value); - storedParam.setInOut(StoreMode.INOUT); - storedParam.setType(StoredParam.paramType(type)); - return null; - }); - INOUT_TOKEN_PARSER.parse("@{" + param, inoutParam -> { - SQLModule.params.add(new SqlInOutParameter(inoutParam, StoredParam.paramType(type))); - return null; - }); - } else { - Object value = ScriptManager.executeExpression(param, varMap); - storedParam.setValue(value); - storedParam.setInOut(StoreMode.OUT); - storedParam.setType(StoredParam.paramType(type)); - SQLModule.params.add(new SqlOutParameter(param, StoredParam.paramType(type))); - } - return null; - }); - parameters.add(storedParam); + // 获取类型 + AtomicInteger sqlType = new AtomicInteger(Types.NULL); + TYPE_TOKEN_PARSER.parse(text + "}", type -> { + sqlType.set(SqlTypes.getSqlType(type, true)); + return null; + }); + // 获取名称 + OUT_PARAM_TOKEN_PARSER.parse("@{" + text, param -> { + int index = param.indexOf("("); + if (index > 0) { + // 获取入参值 + String value = param.substring(index + 1, param.lastIndexOf(")")); + INOUT_TOKEN_PARSER.parse("@{" + param, inoutParam -> { + SqlInOutParameter p = new SqlInOutParameter(inoutParam, sqlType.get()); + parameters.add(new SqlParameterValue(p, ScriptManager.executeExpression(value, varMap))); + return null; + }); + } else { + parameters.add(new SqlOutParameter(param, sqlType.get())); + } return null; }); return "?"; -- Gitee From c291c876095bf5869d12fed5381b9c541b13bf3b Mon Sep 17 00:00:00 2001 From: jmxd <838425805@qq.com> Date: Wed, 23 Aug 2023 11:16:15 +0800 Subject: [PATCH 10/14] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E8=AF=BB=E5=8F=96=E9=85=8D=E7=BD=AE=E6=97=B6=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E7=9A=84=E9=9D=9E=E5=BF=85=E8=A6=81=E5=AD=97=E6=AE=B5=20https:?= =?UTF-8?q?//github.com/ssssssss-team/magic-api/issues/80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../magicapi/core/web/MagicWorkbenchController.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicWorkbenchController.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicWorkbenchController.java index f8bf186a..2311adcb 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicWorkbenchController.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/web/MagicWorkbenchController.java @@ -80,8 +80,15 @@ public class MagicWorkbenchController extends MagicController implements MagicEx @GetMapping("/config.json") @Valid(requireLogin = false) @ResponseBody - public MagicAPIProperties readConfig() { - return properties; + public Map readConfig() { + Map configJson = new HashMap<>(); + configJson.put("persistenceResponseBody", properties.isPersistenceResponseBody()); + configJson.put("version", properties.getVersion()); + configJson.put("web", properties.getWeb()); + configJson.put("prefix", properties.getPrefix()); + configJson.put("autoImportModuleList", properties.getAutoImportModuleList()); + configJson.put("autoImportPackage", properties.getAutoImportPackage()); + return configJson; } @GetMapping(value = "/classes.txt", produces = "text/plain") -- Gitee From 4aefaf571c9d3067a041e3394902e02a418395ed Mon Sep 17 00:00:00 2001 From: jmxd <838425805@qq.com> Date: Wed, 23 Aug 2023 11:25:58 +0800 Subject: [PATCH 11/14] =?UTF-8?q?=20=E4=B8=AD=E7=9A=84=20open?= =?UTF-8?q?=E3=80=81close=E3=80=81separator=E6=B7=BB=E5=8A=A0=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC=20#I6S2NN?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../magicapi/modules/db/mybatis/MybatisParser.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/mybatis/MybatisParser.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/mybatis/MybatisParser.java index c24df0b2..6e552fc8 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/mybatis/MybatisParser.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/db/mybatis/MybatisParser.java @@ -83,9 +83,9 @@ public class MybatisParser { Node node = stream.consume(); ForeachSqlNode foreachSqlNode = new ForeachSqlNode(); foreachSqlNode.setCollection(getNodeAttributeValue(node, "collection")); - foreachSqlNode.setSeparator(getNodeAttributeValue(node, "separator")); - foreachSqlNode.setClose(getNodeAttributeValue(node, "close")); - foreachSqlNode.setOpen(getNodeAttributeValue(node, "open")); + foreachSqlNode.setSeparator(getNodeAttributeValue(node, "separator", ",")); + foreachSqlNode.setClose(getNodeAttributeValue(node, "close", ")")); + foreachSqlNode.setOpen(getNodeAttributeValue(node, "open", "(")); foreachSqlNode.setItem(getNodeAttributeValue(node, "item")); foreachSqlNode.setIndex(getNodeAttributeValue(node, "index")); return processChildren(foreachSqlNode, node); @@ -118,8 +118,12 @@ public class MybatisParser { return processChildren(new WhereSqlNode(), stream.consume()); } - private static String getNodeAttributeValue(Node node, String attributeKey) { + private static String getNodeAttributeValue(Node node, String attributeKey, String defaultValue) { Node item = node.getAttributes().getNamedItem(attributeKey); - return item != null ? item.getNodeValue() : null; + return item != null ? item.getNodeValue() : defaultValue; + } + + private static String getNodeAttributeValue(Node node, String attributeKey) { + return getNodeAttributeValue(node, attributeKey, null); } } -- Gitee From 0d3e021f6c304591cb70ecc5b8a5d653ac3f199d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E6=96=B0?= <718949661@qq.com> Date: Thu, 7 Sep 2023 14:03:50 +0800 Subject: [PATCH 12/14] =?UTF-8?q?http=E6=A8=A1=E5=9D=97=E6=B7=BB=E5=8A=A0e?= =?UTF-8?q?xpectString=E6=96=B9=E6=B3=95=EF=BC=8C=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=AD=97=E7=AC=A6=E4=B8=B2=E6=97=B6=E5=8F=8D?= =?UTF-8?q?=E5=BA=8F=E5=88=97=E5=8C=96=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/ssssssss/magicapi/modules/http/HttpModule.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/modules/http/HttpModule.java b/magic-api/src/main/java/org/ssssssss/magicapi/modules/http/HttpModule.java index eebb894c..81b6cba7 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/modules/http/HttpModule.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/modules/http/HttpModule.java @@ -133,6 +133,12 @@ public class HttpModule { return this; } + @Comment("设置返回值为`String`") + public HttpModule expectString() { + this.responseType = String.class; + return this; + } + @Comment("发送`POST`请求") public ResponseEntity post() { this.method(HttpMethod.POST); -- Gitee From b82fa1f2ccf007f4882fb40c438e182de0a67752 Mon Sep 17 00:00:00 2001 From: taogang Date: Mon, 11 Sep 2023 20:51:39 +0800 Subject: [PATCH 13/14] =?UTF-8?q?fix:=E6=8E=A5=E5=8F=A3=E9=80=89=E9=A1=B9?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/ssssssss/magicapi/core/model/Options.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/model/Options.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/model/Options.java index 6ae1fb2e..21c26538 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/model/Options.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/model/Options.java @@ -33,9 +33,9 @@ public enum Options { REQUIRE_LOGIN("该接口需要登录才允许访问", "require_login", "true"), /** - * 该接口需要不登录也可访问 + * 该接口不需要登录也可访问 */ - ANONYMOUS("该接口需要不登录也可访问", "anonymous", "true"), + ANONYMOUS("该接口不需要登录也可访问", "anonymous", "true"), /** * 不接收未经定义的参数 -- Gitee From 41f2cf53c60b834ad5636282535e457d79dbecab Mon Sep 17 00:00:00 2001 From: taogang Date: Mon, 11 Sep 2023 21:35:45 +0800 Subject: [PATCH 14/14] =?UTF-8?q?feat:springdoc=20=E5=9C=A8=E7=BA=BF?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E6=A0=B9=E6=8D=AE=E6=8E=A5=E5=8F=A3=E6=9C=80?= =?UTF-8?q?=E5=A4=96=E5=B1=82=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84=E5=88=86?= =?UTF-8?q?=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../springdoc/MagicSpringDocConfiguration.java | 1 - .../springdoc/entity/SwaggerProvider.java | 15 ++++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/MagicSpringDocConfiguration.java b/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/MagicSpringDocConfiguration.java index a3a15d20..f370a02a 100644 --- a/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/MagicSpringDocConfiguration.java +++ b/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/MagicSpringDocConfiguration.java @@ -96,7 +96,6 @@ public class MagicSpringDocConfiguration implements MagicPluginConfiguration { private void createSwaggerProvider(ObjectProvider requestMagicDynamicRegistryObjectProvider, MagicResourceService magicResourceService, ServletContext servletContext) throws NoSuchMethodException { - Mapping mapping = Mapping.create(requestMappingHandlerMapping); RequestMappingInfo requestMappingInfo = mapping.paths(springDocConfig.getLocation()).build(); SwaggerEntity.License license = new SwaggerEntity.License("MIT", "https://gitee.com/ssssssss-team/magic-api/blob/master/LICENSE"); diff --git a/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/entity/SwaggerProvider.java b/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/entity/SwaggerProvider.java index 7a69584e..f930fc0d 100644 --- a/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/entity/SwaggerProvider.java +++ b/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/entity/SwaggerProvider.java @@ -4,10 +4,7 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.ResponseBody; import org.ssssssss.magicapi.core.config.MagicConfiguration; -import org.ssssssss.magicapi.core.model.ApiInfo; -import org.ssssssss.magicapi.core.model.BaseDefinition; -import org.ssssssss.magicapi.core.model.DataType; -import org.ssssssss.magicapi.core.model.Path; +import org.ssssssss.magicapi.core.model.*; import org.ssssssss.magicapi.core.service.MagicResourceService; import org.ssssssss.magicapi.core.service.impl.RequestMagicDynamicRegistry; import org.ssssssss.magicapi.utils.JsonUtils; @@ -73,7 +70,7 @@ public class SwaggerProvider { swaggerEntity.addSecurity(securityMap); for (ApiInfo info : infos) { - String groupName = magicResourceService.getGroupName(info.getGroupId()).replace("/", "-"); + String groupName = getRootGroupName(info.getGroupId()); String requestPath = PathUtils.replaceSlash(this.prefix + magicResourceService.getGroupPath(info.getGroupId()) + "/" + info.getPath()); SwaggerEntity.Path path = new SwaggerEntity.Path(info.getId()); path.addTag(groupName); @@ -123,6 +120,14 @@ public class SwaggerProvider { return swaggerEntity; } + private String getRootGroupName(String groupId) { + Group group = magicResourceService.getGroup(groupId); + if (!Objects.equals(group.getParentId(), "0")) { + return getRootGroupName(group.getParentId()); + } + return group.getName(); + } + private List> parseParameters(ApiInfo info) { List> parameters = new ArrayList<>(); info.getParameters().forEach(it -> parameters.add(SwaggerEntity.createParameter(it.isRequired(), it.getName(), VAR_NAME_QUERY, it.getDataType().getJavascriptType(), it.getDescription(), it.getValue()))); -- Gitee