Commit ff14a37a by inrgihc

接口调试日志

parent 22e478a4
...@@ -68,17 +68,17 @@ ...@@ -68,17 +68,17 @@
### 4、正在规划中的功能 ### 4、正在规划中的功能
- (1) 接口检索及说明文档 - (1) 接口检索功能
> 支持接口检索及接口入参出参说明文档。 > 支持类似百度搜索的接口搜索功能,方便接口查找
- (2) 支持接口的缓存配置功能 - (2) 支持接口的缓存配置功能
> 基于分布式缓存等构建支持接口的缓存配置功能。 > 基于分布式缓存等构建支持接口的缓存配置功能。
- (3) SQL结果集的出参格式转换 - (3) 接口入参支持对象及对象数组
> SQL查询结果集到接口出参相应的格式转换。 > 接口入参支持对象及对象数组,方便批量插入数据及查询的排序等功能.
- (4) 前端界面整体美化 - (4) 前端界面整体美化
> 美化界面的交互展示。 > 美化界面的交互展示,尤其是“拓扑结构”页面
## 二、编译打包 ## 二、编译打包
......
package com.gitee.sqlrest.core.dto;
import java.sql.Array;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.ibatis.reflection.ArrayUtil;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ExecuteSqlRecord {
private String sql;
private List<Object> parameter;
private Long costs;
protected String getParameterValueString() {
List<Object> typeList = new ArrayList<>(parameter.size());
for (Object value : parameter) {
if (value == null) {
typeList.add("null");
} else {
typeList.add(objectValueString(value) + "(" + value.getClass().getSimpleName() + ")");
}
}
final String parameters = typeList.toString();
return parameters.substring(1, parameters.length() - 1);
}
protected String objectValueString(Object value) {
if (value instanceof Array) {
try {
return ArrayUtil.toString(((Array) value).getArray());
} catch (SQLException e) {
return value.toString();
}
}
return value.toString();
}
public String getDisplayText() {
return "==> Preparing: " + sql.trim() + "\n"
+ "==> Parameters: " + getParameterValueString() + "\n"
+ "==> costs: " + costs + " ms";
}
}
...@@ -31,6 +31,8 @@ import javax.annotation.Resource; ...@@ -31,6 +31,8 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -142,7 +144,7 @@ public class ApiExecuteService { ...@@ -142,7 +144,7 @@ public class ApiExecuteService {
} else { } else {
if (isArray) { if (isArray) {
String[] values = request.getParameterValues(name); String[] values = request.getParameterValues(name);
if (null != values && values.length > 0) { if (ArrayUtils.isNotEmpty(values)) {
List list = Arrays.asList(values).stream() List list = Arrays.asList(values).stream()
.map(v -> type.getConverter().apply(v)) .map(v -> type.getConverter().apply(v))
.collect(Collectors.toList()); .collect(Collectors.toList());
...@@ -154,7 +156,7 @@ public class ApiExecuteService { ...@@ -154,7 +156,7 @@ public class ApiExecuteService {
} }
} else { } else {
String value = request.getParameter(name); String value = request.getParameter(name);
if (null == value) { if (StringUtils.isEmpty(value)) {
if (required) { if (required) {
invalidArgs.add(param); invalidArgs.add(param);
} else { } else {
......
package com.gitee.sqlrest.core.exec;
import com.gitee.sqlrest.core.dto.ExecuteSqlRecord;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public final class SqlExecuteLogger {
private static final ThreadLocal<List<ExecuteSqlRecord>> threadLocal = new ThreadLocal<>();
public static void init() {
threadLocal.set(new ArrayList<>());
}
public static void add(String sql, List parameters, Long costs) {
List<ExecuteSqlRecord> list = threadLocal.get();
if (null != list) {
list.add(new ExecuteSqlRecord(sql, parameters, costs));
}
}
public static List<ExecuteSqlRecord> get() {
List<ExecuteSqlRecord> list = threadLocal.get();
if (null == list) {
return Collections.emptyList();
}
return list;
}
public static void clear() {
threadLocal.remove();
}
}
...@@ -36,7 +36,10 @@ public class SqlExecutorService extends AbstractExecutorEngine { ...@@ -36,7 +36,10 @@ public class SqlExecutorService extends AbstractExecutorEngine {
SqlMeta sqlMeta = template.process(params); SqlMeta sqlMeta = template.process(params);
int page = PageSizeUtils.getPageFromParams(params); int page = PageSizeUtils.getPageFromParams(params);
int size = PageSizeUtils.getSizeFromParams(params); int size = PageSizeUtils.getSizeFromParams(params);
dataList.add(SqlJdbcUtils.execute(productType, connection, sqlMeta, strategy, page, size)); Object result = SqlJdbcUtils.execute(productType, connection, sqlMeta, strategy, page, size);
if (sqlMeta.isQuerySQL()) {
dataList.add(result);
}
} }
connection.commit(); connection.commit();
return dataList; return dataList;
......
...@@ -2,6 +2,7 @@ package com.gitee.sqlrest.core.exec.module; ...@@ -2,6 +2,7 @@ package com.gitee.sqlrest.core.exec.module;
import com.gitee.sqlrest.common.enums.NamingStrategyEnum; import com.gitee.sqlrest.common.enums.NamingStrategyEnum;
import com.gitee.sqlrest.common.enums.ProductTypeEnum; import com.gitee.sqlrest.common.enums.ProductTypeEnum;
import com.gitee.sqlrest.core.exec.SqlExecuteLogger;
import com.gitee.sqlrest.core.exec.annotation.Comment; import com.gitee.sqlrest.core.exec.annotation.Comment;
import com.gitee.sqlrest.core.exec.annotation.Module; import com.gitee.sqlrest.core.exec.annotation.Module;
import com.gitee.sqlrest.core.util.ConvertUtils; import com.gitee.sqlrest.core.util.ConvertUtils;
...@@ -14,6 +15,7 @@ import java.sql.ResultSet; ...@@ -14,6 +15,7 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
...@@ -63,7 +65,12 @@ public class DbVarModule { ...@@ -63,7 +65,12 @@ public class DbVarModule {
log.info("Enter selectAll() function, SQL:{},params:{}", sqlOrXml, params); log.info("Enter selectAll() function, SQL:{},params:{}", sqlOrXml, params);
SqlTemplate template = cfg.getTemplate(sqlOrXml); SqlTemplate template = cfg.getTemplate(sqlOrXml);
SqlMeta sqlMeta = template.process(params); SqlMeta sqlMeta = template.process(params);
return build(jdbcTemplate.queryForList(sqlMeta.getSql(), sqlMeta.getParameter().toArray())); long start = System.currentTimeMillis();
try {
return build(jdbcTemplate.queryForList(sqlMeta.getSql(), sqlMeta.getParameter().toArray()));
} finally {
SqlExecuteLogger.add(sqlMeta.getSql(), sqlMeta.getParameter(), System.currentTimeMillis() - start);
}
} }
@Comment("count所有数据的总数") @Comment("count所有数据的总数")
...@@ -72,7 +79,12 @@ public class DbVarModule { ...@@ -72,7 +79,12 @@ public class DbVarModule {
SqlTemplate template = cfg.getTemplate(sqlOrXml); SqlTemplate template = cfg.getTemplate(sqlOrXml);
SqlMeta sqlMeta = template.process(params); SqlMeta sqlMeta = template.process(params);
String countSql = String.format("select count(*) from (%s) a", sqlMeta.getSql()); String countSql = String.format("select count(*) from (%s) a", sqlMeta.getSql());
return jdbcTemplate.queryForObject(countSql, Integer.class, sqlMeta.getParameter().toArray()); long start = System.currentTimeMillis();
try {
return jdbcTemplate.queryForObject(countSql, Integer.class, sqlMeta.getParameter().toArray());
} finally {
SqlExecuteLogger.add(countSql, sqlMeta.getParameter(), System.currentTimeMillis() - start);
}
} }
@Comment("查询单条结果,并传入变量信息,查不到返回null") @Comment("查询单条结果,并传入变量信息,查不到返回null")
...@@ -80,19 +92,24 @@ public class DbVarModule { ...@@ -80,19 +92,24 @@ public class DbVarModule {
log.info("Enter selectOne() function, SQL:{},params:{}", sqlOrXml, params); log.info("Enter selectOne() function, SQL:{},params:{}", sqlOrXml, params);
SqlTemplate template = cfg.getTemplate(sqlOrXml); SqlTemplate template = cfg.getTemplate(sqlOrXml);
SqlMeta sqlMeta = template.process(params); SqlMeta sqlMeta = template.process(params);
return build(jdbcTemplate long start = System.currentTimeMillis();
.query(sqlMeta.getSql(), new ResultSetExtractor<Map<String, Object>>() { try {
private ColumnMapRowMapper mapper = new ColumnMapRowMapper(); return build(jdbcTemplate
.query(sqlMeta.getSql(), new ResultSetExtractor<Map<String, Object>>() {
@Override private ColumnMapRowMapper mapper = new ColumnMapRowMapper();
public Map<String, Object> extractData(ResultSet rs) throws SQLException, DataAccessException {
if (rs.next()) { @Override
return mapper.mapRow(rs, 0); public Map<String, Object> extractData(ResultSet rs) throws SQLException, DataAccessException {
if (rs.next()) {
return mapper.mapRow(rs, 0);
}
return null;
} }
return null; },
} sqlMeta.getParameter().toArray()));
}, } finally {
sqlMeta.getParameter().toArray())); SqlExecuteLogger.add(sqlMeta.getSql(), sqlMeta.getParameter(), System.currentTimeMillis() - start);
}
} }
@Comment("分页查询数据列表") @Comment("分页查询数据列表")
...@@ -106,7 +123,12 @@ public class DbVarModule { ...@@ -106,7 +123,12 @@ public class DbVarModule {
String pageSql = productType.getPageSql(sqlMeta.getSql(), page, size); String pageSql = productType.getPageSql(sqlMeta.getSql(), page, size);
List<Object> parameters = sqlMeta.getParameter(); List<Object> parameters = sqlMeta.getParameter();
this.productType.getPageConsumer().accept(page, size, parameters); this.productType.getPageConsumer().accept(page, size, parameters);
return build(jdbcTemplate.queryForList(pageSql, parameters.toArray())); long start = System.currentTimeMillis();
try {
return build(jdbcTemplate.queryForList(pageSql, parameters.toArray()));
} finally {
SqlExecuteLogger.add(sqlMeta.getSql(), parameters, System.currentTimeMillis() - start);
}
} }
@Comment("执行insert操作,返回插入主键") @Comment("执行insert操作,返回插入主键")
...@@ -116,14 +138,19 @@ public class DbVarModule { ...@@ -116,14 +138,19 @@ public class DbVarModule {
SqlMeta sqlMeta = template.process(params); SqlMeta sqlMeta = template.process(params);
List<Object> parameters = sqlMeta.getParameter(); List<Object> parameters = sqlMeta.getParameter();
GeneratedKeyHolder keyHolder = new GeneratedKeyHolder(); GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update( long start = System.currentTimeMillis();
connection -> { try {
PreparedStatement ps = connection.prepareStatement(sqlMeta.getSql(), Statement.RETURN_GENERATED_KEYS); jdbcTemplate.update(
new ArgumentPreparedStatementSetter(parameters.toArray()).setValues(ps); connection -> {
return ps; PreparedStatement ps = connection.prepareStatement(sqlMeta.getSql(), Statement.RETURN_GENERATED_KEYS);
}, new ArgumentPreparedStatementSetter(parameters.toArray()).setValues(ps);
keyHolder); return ps;
return build(keyHolder.getKeys()); },
keyHolder);
return build(keyHolder.getKeys());
} finally {
SqlExecuteLogger.add(sqlMeta.getSql(), parameters, System.currentTimeMillis() - start);
}
} }
@Comment("执行update操作,返回受影响行数") @Comment("执行update操作,返回受影响行数")
...@@ -132,13 +159,24 @@ public class DbVarModule { ...@@ -132,13 +159,24 @@ public class DbVarModule {
SqlTemplate template = cfg.getTemplate(sqlOrXml); SqlTemplate template = cfg.getTemplate(sqlOrXml);
SqlMeta sqlMeta = template.process(params); SqlMeta sqlMeta = template.process(params);
List<Object> parameters = sqlMeta.getParameter(); List<Object> parameters = sqlMeta.getParameter();
return jdbcTemplate.update(sqlMeta.getSql(), parameters.toArray()); long start = System.currentTimeMillis();
try {
return jdbcTemplate.update(sqlMeta.getSql(), parameters.toArray());
} finally {
SqlExecuteLogger.add(sqlMeta.getSql(), parameters, System.currentTimeMillis() - start);
}
} }
@Comment("批量执行操作,返回受影响的行数") @Comment("批量执行操作,返回受影响的行数")
public int batchUpdate(@Comment("sqlList") List<String> sqlList) { public int batchUpdate(@Comment("sqlList") List<String> sqlList) {
log.info("Enter batchUpdate() function, SQL:{},params:{}", sqlList); log.info("Enter batchUpdate() function, SQL:{},params:{}", sqlList);
return Arrays.stream(jdbcTemplate.batchUpdate(sqlList.toArray(new String[0]))).sum(); long start = System.currentTimeMillis();
try {
return Arrays.stream(jdbcTemplate.batchUpdate(sqlList.toArray(new String[0]))).sum();
} finally {
SqlExecuteLogger.add(sqlList.stream().collect(Collectors.joining(";")),
Collections.emptyList(), System.currentTimeMillis() - start);
}
} }
@Comment("执行delete操作,返回受影响行数") @Comment("执行delete操作,返回受影响行数")
...@@ -147,7 +185,12 @@ public class DbVarModule { ...@@ -147,7 +185,12 @@ public class DbVarModule {
SqlTemplate template = cfg.getTemplate(sqlOrXml); SqlTemplate template = cfg.getTemplate(sqlOrXml);
SqlMeta sqlMeta = template.process(params); SqlMeta sqlMeta = template.process(params);
List<Object> parameters = sqlMeta.getParameter(); List<Object> parameters = sqlMeta.getParameter();
return jdbcTemplate.update(sqlMeta.getSql(), parameters.toArray()); long start = System.currentTimeMillis();
try {
return jdbcTemplate.update(sqlMeta.getSql(), parameters.toArray());
} finally {
SqlExecuteLogger.add(sqlMeta.getSql(), parameters, System.currentTimeMillis() - start);
}
} }
} }
...@@ -19,8 +19,10 @@ import com.gitee.sqlrest.core.dto.ApiAssignmentSaveRequest; ...@@ -19,8 +19,10 @@ import com.gitee.sqlrest.core.dto.ApiAssignmentSaveRequest;
import com.gitee.sqlrest.core.dto.ApiDebugExecuteRequest; import com.gitee.sqlrest.core.dto.ApiDebugExecuteRequest;
import com.gitee.sqlrest.core.dto.AssignmentSearchRequest; import com.gitee.sqlrest.core.dto.AssignmentSearchRequest;
import com.gitee.sqlrest.core.dto.DataTypeFormatMapValue; import com.gitee.sqlrest.core.dto.DataTypeFormatMapValue;
import com.gitee.sqlrest.core.dto.ExecuteSqlRecord;
import com.gitee.sqlrest.core.dto.ScriptEditorCompletion; import com.gitee.sqlrest.core.dto.ScriptEditorCompletion;
import com.gitee.sqlrest.core.dto.SqlParamParseResponse; import com.gitee.sqlrest.core.dto.SqlParamParseResponse;
import com.gitee.sqlrest.core.exec.SqlExecuteLogger;
import com.gitee.sqlrest.core.exec.annotation.Comment; import com.gitee.sqlrest.core.exec.annotation.Comment;
import com.gitee.sqlrest.core.exec.engine.ApiExecutorEngineFactory; import com.gitee.sqlrest.core.exec.engine.ApiExecutorEngineFactory;
import com.gitee.sqlrest.core.exec.engine.impl.ScriptExecutorService; import com.gitee.sqlrest.core.exec.engine.impl.ScriptExecutorService;
...@@ -42,6 +44,7 @@ import java.io.File; ...@@ -42,6 +44,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -53,7 +56,6 @@ import java.util.stream.Stream; ...@@ -53,7 +56,6 @@ import java.util.stream.Stream;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -164,6 +166,22 @@ public class ApiAssignmentService { ...@@ -164,6 +166,22 @@ public class ApiAssignmentService {
throw new RuntimeException(String.format("[%s] value type invalid, %s", paramName, e.getMessage())); throw new RuntimeException(String.format("[%s] value type invalid, %s", paramName, e.getMessage()));
} }
} }
List<ParamValue> emptyList = request.getParamValues()
.stream().filter(i -> StringUtils.isBlank(i.getValue()))
.collect(Collectors.toList());
for (ParamValue paramValue : emptyList) {
ParamTypeEnum type = paramValue.getType();
if (!params.containsKey(paramValue.getName())) {
if (!paramValue.getRequired()) {
if (paramValue.getIsArray()) {
params.put(paramValue.getName(), Collections.emptyList());
} else {
params.put(paramValue.getName(), type.getConverter().apply(paramValue.getDefaultValue()));
}
}
}
}
} }
if (null == request.getNamingStrategy()) { if (null == request.getNamingStrategy()) {
...@@ -174,19 +192,26 @@ public class ApiAssignmentService { ...@@ -174,19 +192,26 @@ public class ApiAssignmentService {
ResultEntity entity; ResultEntity entity;
try { try {
SqlExecuteLogger.init();
HikariDataSource dataSource = DataSourceUtils.getHikariDataSource(dataSourceEntity, driverPath.getAbsolutePath()); HikariDataSource dataSource = DataSourceUtils.getHikariDataSource(dataSourceEntity, driverPath.getAbsolutePath());
List<Object> results = ApiExecutorEngineFactory List<Object> results = ApiExecutorEngineFactory
.getExecutor(request.getEngine(), dataSource, dataSourceEntity.getType()) .getExecutor(request.getEngine(), dataSource, dataSourceEntity.getType())
.execute(scripts, params, request.getNamingStrategy()); .execute(scripts, params, request.getNamingStrategy());
Object answer = results.size() > 1 ? results : results.get(0); Object answer = results.size() > 1 ? results : (1 == results.size()) ? results.get(0) : null;
Map<String, ParamTypeEnum> types = JacksonUtils.parseFieldTypes(results); Map<String, ParamTypeEnum> types = JacksonUtils.parseFieldTypes(results);
if (MapUtils.isNotEmpty(types)) { String logs = Optional.ofNullable(SqlExecuteLogger.get())
entity = ResultEntity.success(ImmutableMap.of("answer", answer, "types", types)); .orElseGet(ArrayList::new).stream().map(ExecuteSqlRecord::getDisplayText)
} else { .collect(Collectors.toList()).stream().collect(Collectors.joining("\n\n"));
entity = ResultEntity.failed("No result data set!"); entity = ResultEntity.success(
} ImmutableMap.of(
"answer", answer,
"logs", logs,
"types", types)
);
} catch (Exception e) { } catch (Exception e) {
entity = ResultEntity.failed(ExceptionUtil.getMessage(e)); entity = ResultEntity.failed(ExceptionUtil.getMessage(e));
} finally {
SqlExecuteLogger.clear();
} }
response.setStatus(HttpServletResponse.SC_OK); response.setStatus(HttpServletResponse.SC_OK);
...@@ -228,6 +253,9 @@ public class ApiAssignmentService { ...@@ -228,6 +253,9 @@ public class ApiAssignmentService {
if (null == request.getNamingStrategy()) { if (null == request.getNamingStrategy()) {
request.setNamingStrategy(NamingStrategyEnum.CAMEL_CASE); request.setNamingStrategy(NamingStrategyEnum.CAMEL_CASE);
} }
while (request.getPath().startsWith("/")) {
request.setPath(request.getPath().substring(1));
}
List<ApiContextEntity> contextList = getContextListEntity(request.getContextList()); List<ApiContextEntity> contextList = getContextListEntity(request.getContextList());
......
...@@ -2,6 +2,7 @@ package com.gitee.sqlrest.core.util; ...@@ -2,6 +2,7 @@ package com.gitee.sqlrest.core.util;
import com.gitee.sqlrest.common.enums.NamingStrategyEnum; import com.gitee.sqlrest.common.enums.NamingStrategyEnum;
import com.gitee.sqlrest.common.enums.ProductTypeEnum; import com.gitee.sqlrest.common.enums.ProductTypeEnum;
import com.gitee.sqlrest.core.exec.SqlExecuteLogger;
import com.gitee.sqlrest.template.SqlMeta; import com.gitee.sqlrest.template.SqlMeta;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
...@@ -21,11 +22,6 @@ public class SqlJdbcUtils { ...@@ -21,11 +22,6 @@ public class SqlJdbcUtils {
private static final int QUERY_TIMEOUT = 300; private static final int QUERY_TIMEOUT = 300;
public static boolean isQuerySQL(String sql) {
String upperSql = sql.toUpperCase().trim();
return upperSql.startsWith("SELECT") || upperSql.startsWith("WITH");
}
public static Function<String, String> getConverter(NamingStrategyEnum strategy) { public static Function<String, String> getConverter(NamingStrategyEnum strategy) {
return (null == strategy) ? Function.identity() : strategy.getFunction(); return (null == strategy) ? Function.identity() : strategy.getFunction();
} }
...@@ -33,7 +29,7 @@ public class SqlJdbcUtils { ...@@ -33,7 +29,7 @@ public class SqlJdbcUtils {
public static Object execute(ProductTypeEnum productType, Connection connection, SqlMeta sqlMeta, public static Object execute(ProductTypeEnum productType, Connection connection, SqlMeta sqlMeta,
NamingStrategyEnum strategy, int page, int size) throws SQLException { NamingStrategyEnum strategy, int page, int size) throws SQLException {
List<Object> paramValues = sqlMeta.getParameter(); List<Object> paramValues = sqlMeta.getParameter();
boolean isQuerySql = isQuerySQL(sqlMeta.getSql()); boolean isQuerySql = sqlMeta.isQuerySQL();
String sql = isQuerySql ? productType.getPageSql(sqlMeta.getSql(), page, size) : sqlMeta.getSql(); String sql = isQuerySql ? productType.getPageSql(sqlMeta.getSql(), page, size) : sqlMeta.getSql();
PreparedStatement statement = connection.prepareStatement(sql); PreparedStatement statement = connection.prepareStatement(sql);
statement.setQueryTimeout(QUERY_TIMEOUT); statement.setQueryTimeout(QUERY_TIMEOUT);
...@@ -46,32 +42,37 @@ public class SqlJdbcUtils { ...@@ -46,32 +42,37 @@ public class SqlJdbcUtils {
} }
log.info("ExecuteSQL:{}\n{}", sql, paramValues); log.info("ExecuteSQL:{}\n{}", sql, paramValues);
Function<String, String> converter = getConverter(strategy); long start = System.currentTimeMillis();
if (statement.execute()) { try {
try (ResultSet rs = statement.getResultSet()) { Function<String, String> converter = getConverter(strategy);
List<String> columns = new ArrayList<>(); if (statement.execute()) {
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) { try (ResultSet rs = statement.getResultSet()) {
String columnName = rs.getMetaData().getColumnLabel(i); List<String> columns = new ArrayList<>();
columns.add(columnName); for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
} String columnName = rs.getMetaData().getColumnLabel(i);
List<Map<String, Object>> list = new ArrayList<>(); columns.add(columnName);
while (rs.next()) { }
Map<String, Object> row = new LinkedHashMap<>(); List<Map<String, Object>> list = new ArrayList<>();
for (String column : columns) { while (rs.next()) {
try { Map<String, Object> row = new LinkedHashMap<>();
row.put(column, rs.getObject(column)); for (String column : columns) {
} catch (SQLException se) { try {
log.warn("Failed to call jdbc ResultSet::getObject(): {}", se.getMessage(), se); row.put(column, rs.getObject(column));
row.put(column, null); } catch (SQLException se) {
log.warn("Failed to call jdbc ResultSet::getObject(): {}", se.getMessage(), se);
row.put(column, null);
}
} }
list.add(ConvertUtils.to(row, converter));
} }
list.add(ConvertUtils.to(row, converter)); return list;
} }
return list; } else {
int updateCount = statement.getUpdateCount();
return "(" + updateCount + ") rows affected";
} }
} else { } finally {
int updateCount = statement.getUpdateCount(); SqlExecuteLogger.add(sql, paramValues, System.currentTimeMillis() - start);
return "(" + updateCount + ") rows affected";
} }
} }
......
...@@ -635,6 +635,9 @@ ...@@ -635,6 +635,9 @@
sort></json-viewer> sort></json-viewer>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="执行信息"> <el-tab-pane label="执行信息">
<div class="debug-console-log-text">
{{debugConsoleLog}}<br />
</div>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</el-col> </el-col>
...@@ -705,6 +708,7 @@ export default { ...@@ -705,6 +708,7 @@ export default {
inputParams: [], inputParams: [],
debugParams: [], debugParams: [],
debugResponse: {}, debugResponse: {},
debugConsoleLog: "",
outputParams: [], outputParams: [],
responseNamingStrategy: [], responseNamingStrategy: [],
responseTypeFormat: [], responseTypeFormat: [],
...@@ -1390,6 +1394,7 @@ export default { ...@@ -1390,6 +1394,7 @@ export default {
}, },
handleDebug: function () { handleDebug: function () {
this.debugResponse = {} this.debugResponse = {}
this.debugConsoleLog = ""
var sqls = [] var sqls = []
var isSql = true; var isSql = true;
if (this.createParam.engine === 'SQL') { if (this.createParam.engine === 'SQL') {
...@@ -1477,16 +1482,26 @@ export default { ...@@ -1477,16 +1482,26 @@ export default {
res => { res => {
if (0 === res.data.code) { if (0 === res.data.code) {
this.debugResponse = res.data.data.answer; this.debugResponse = res.data.data.answer;
this.debugConsoleLog = res.data.data.logs;
this.outputParams = []; this.outputParams = [];
let map = res.data.data.types; let map = res.data.data.types;
for (let key in map) { if (Object.keys(map).length === 0) {
this.outputParams.push( this.$alert("结果集内容为空", "提示信息",
{ {
name: key, confirmButtonText: "确定",
type: map[key], type: "info"
remark: null
} }
) );
} else {
for (let key in map) {
this.outputParams.push(
{
name: key,
type: map[key],
remark: null
}
)
}
} }
} else { } else {
if (res.data.message) { if (res.data.message) {
...@@ -1580,4 +1595,8 @@ export default { ...@@ -1580,4 +1595,8 @@ export default {
/deep/ .el-input.is-disabled .el-input__inner { /deep/ .el-input.is-disabled .el-input__inner {
color: #5f5e5e !important; color: #5f5e5e !important;
} }
.debug-console-log-text {
white-space: pre-line;
}
</style> </style>
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>SQLREST工具</title><link href=/static/css/app.d72e48888783ec7888daa8507773340a.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.b20a86b3cf44ea708af0.js></script><script type=text/javascript src=/static/js/vendor.6bde4750a07bb5a2f647.js></script><script type=text/javascript src=/static/js/app.5b13ca32f61140a99ff5.js></script></body></html> <!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>SQLREST工具</title><link href=/static/css/app.8f318ec480f6f58990bbc607de49592a.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.d2c25b0f76d62e67169a.js></script><script type=text/javascript src=/static/js/vendor.6bde4750a07bb5a2f647.js></script><script type=text/javascript src=/static/js/app.5b13ca32f61140a99ff5.js></script></body></html>
\ No newline at end of file \ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,c,f){for(var a,d,i,u=0,b=[];u<r.length;u++)d=r[u],t[d]&&b.push(t[d][0]),t[d]=0;for(a in c)Object.prototype.hasOwnProperty.call(c,a)&&(e[a]=c[a]);for(n&&n(r,c,f);b.length;)b.shift()();if(f)for(u=0;u<f.length;u++)i=o(o.s=f[u]);return i};var r={},t={24:0};function o(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,o){n=t[e]=[r,o]});n[2]=r;var c=document.getElementsByTagName("head")[0],f=document.createElement("script");f.type="text/javascript",f.charset="utf-8",f.async=!0,f.timeout=12e4,o.nc&&f.setAttribute("nonce",o.nc),f.src=o.p+"static/js/"+e+"."+{0:"4146c25475a3e18df991",1:"b17200cccd46e216dcb3",2:"140338f6a5528feea1a3",3:"776d791724a8de12ff9e",4:"f8494b8dd039413f79c8",5:"8fcbb35b45285576e78f",6:"8f85de06573e2a5f9562",7:"061807fe4716131f26f8",8:"d1391c270de5a9f111c5",9:"cbdb7fa4f5180acfbb03",10:"7eeaa94fd42d34a86b92",11:"096c0f0eaf2850056b7e",12:"85287d948c440f963d32",13:"4d2138ee1bee3ad573f4",14:"429592868e75adc95933",15:"3b3f0c03ff4fed9903cc",16:"9616cfe0a4f7517b0841",17:"b4bc5fa31e227bee8651",18:"5e7f065a8d031847e833",19:"3936346cb7e30aa279e2",20:"5ef9c751035ee9a08f94",21:"d8007e7169c085e13dab"}[e]+".js";var a=setTimeout(d,12e4);function d(){f.onerror=f.onload=null,clearTimeout(a);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return f.onerror=f.onload=d,c.appendChild(f),r},o.m=e,o.c=r,o.d=function(e,n,r){o.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="/",o.oe=function(e){throw console.error(e),e}}([]);
//# sourceMappingURL=manifest.b20a86b3cf44ea708af0.js.map
\ No newline at end of file
!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,o,a){for(var f,d,i,u=0,b=[];u<r.length;u++)d=r[u],t[d]&&b.push(t[d][0]),t[d]=0;for(f in o)Object.prototype.hasOwnProperty.call(o,f)&&(e[f]=o[f]);for(n&&n(r,o,a);b.length;)b.shift()();if(a)for(u=0;u<a.length;u++)i=c(c.s=a[u]);return i};var r={},t={24:0};function c(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,c),t.l=!0,t.exports}c.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,c){n=t[e]=[r,c]});n[2]=r;var o=document.getElementsByTagName("head")[0],a=document.createElement("script");a.type="text/javascript",a.charset="utf-8",a.async=!0,a.timeout=12e4,c.nc&&a.setAttribute("nonce",c.nc),a.src=c.p+"static/js/"+e+"."+{0:"32a67c5cdba64a33f31c",1:"b17200cccd46e216dcb3",2:"140338f6a5528feea1a3",3:"776d791724a8de12ff9e",4:"f8494b8dd039413f79c8",5:"8fcbb35b45285576e78f",6:"8f85de06573e2a5f9562",7:"061807fe4716131f26f8",8:"d1391c270de5a9f111c5",9:"cbdb7fa4f5180acfbb03",10:"7eeaa94fd42d34a86b92",11:"096c0f0eaf2850056b7e",12:"85287d948c440f963d32",13:"4d2138ee1bee3ad573f4",14:"429592868e75adc95933",15:"3b3f0c03ff4fed9903cc",16:"9616cfe0a4f7517b0841",17:"b4bc5fa31e227bee8651",18:"5e7f065a8d031847e833",19:"3936346cb7e30aa279e2",20:"5ef9c751035ee9a08f94",21:"d8007e7169c085e13dab"}[e]+".js";var f=setTimeout(d,12e4);function d(){a.onerror=a.onload=null,clearTimeout(f);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return a.onerror=a.onload=d,o.appendChild(a),r},c.m=e,c.c=r,c.d=function(e,n,r){c.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},c.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return c.d(n,"a",n),n},c.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},c.p="/",c.oe=function(e){throw console.error(e),e}}([]);
//# sourceMappingURL=manifest.d2c25b0f76d62e67169a.js.map
\ No newline at end of file
...@@ -9,7 +9,7 @@ public class SqlMeta { ...@@ -9,7 +9,7 @@ public class SqlMeta {
public SqlMeta(String sql, List<Object> parameter) { public SqlMeta(String sql, List<Object> parameter) {
super(); super();
this.sql = sql; this.sql = sql.trim();
this.parameter = parameter; this.parameter = parameter;
} }
...@@ -18,7 +18,7 @@ public class SqlMeta { ...@@ -18,7 +18,7 @@ public class SqlMeta {
} }
public void setSql(String sql) { public void setSql(String sql) {
this.sql = sql; this.sql = sql.trim();
} }
public List<Object> getParameter() { public List<Object> getParameter() {
...@@ -29,6 +29,11 @@ public class SqlMeta { ...@@ -29,6 +29,11 @@ public class SqlMeta {
this.parameter = parameter; this.parameter = parameter;
} }
public boolean isQuerySQL() {
String upperSql = sql.toUpperCase().trim();
return upperSql.startsWith("SELECT") || upperSql.startsWith("WITH");
}
@Override @Override
public String toString() { public String toString() {
return "SqlMeta [sql=" + sql + ", parameter=" + parameter + "]"; return "SqlMeta [sql=" + sql + ", parameter=" + parameter + "]";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment