use of org.sagacity.sqltoy.exception.DataAccessException in project sagacity-sqltoy by chenrenfei.
the class QueryExecutorBuilder method dataAuthFilter.
/**
* @TODO 统一数据权限条件参数:1、前端没有传则自动填充;2、前端传值,对所传值进行是否超出授权数据范围校验
* @param unifyFieldsHandler
* @param sqlToyConfig
* @param fullParamNames
* @param fullParamValues
*/
private static void dataAuthFilter(IUnifyFieldsHandler unifyFieldsHandler, SqlToyConfig sqlToyConfig, String[] fullParamNames, Object[] fullParamValues) {
IgnoreKeyCaseMap<String, DataAuthFilterConfig> authFilterMap = (unifyFieldsHandler == null) ? null : unifyFieldsHandler.dataAuthFilters();
if (authFilterMap == null || authFilterMap.isEmpty()) {
return;
}
String paramName;
DataAuthFilterConfig dataAuthFilter;
for (int i = 0; i < fullParamNames.length; i++) {
paramName = fullParamNames[i];
if (authFilterMap.containsKey(paramName)) {
dataAuthFilter = authFilterMap.get(paramName);
// 实际传参值为空(或等于全新标记值),权限过滤配置了限制范围,则将实际权限数据值填充到条件参数中
if (StringUtil.isBlank(fullParamValues[i]) || equalChoiceAllValue(fullParamValues[i], dataAuthFilter.getChoiceAllValue())) {
// 实现统一传参
if (dataAuthFilter.getValues() != null) {
fullParamValues[i] = dataAuthFilter.getValues();
logger.debug("sqlId={} 参数:{} 前端未传值,由平台统一带入授权值!", sqlToyConfig.getId(), paramName);
}
} else // 数据权限指定了值,则进行值越权校验,超出范围抛出异常
if (dataAuthFilter.getValues() != null && dataAuthFilter.isForcelimit()) {
// 允许访问的值
Object[] dataAuthed;
if (dataAuthFilter.getValues().getClass().isArray()) {
dataAuthed = (Object[]) dataAuthFilter.getValues();
} else if (dataAuthFilter.getValues() instanceof Collection) {
dataAuthed = ((Collection) dataAuthFilter.getValues()).toArray();
} else {
dataAuthed = new Object[] { dataAuthFilter.getValues() };
}
Set<Object> authSet = new HashSet<Object>();
for (Object item : dataAuthed) {
if (item != null) {
if (dataAuthFilter.isIgnoreType()) {
authSet.add(item.toString());
} else {
authSet.add(item);
}
}
}
// 参数直接传递的值
Object[] pointValues;
if (fullParamValues[i].getClass().isArray()) {
pointValues = (Object[]) fullParamValues[i];
} else if (fullParamValues[i] instanceof Collection) {
pointValues = ((Collection) fullParamValues[i]).toArray();
} else {
pointValues = new Object[] { fullParamValues[i] };
}
// 校验实际传递的权限值是否在授权范围内
for (Object paramValue : pointValues) {
if (paramValue != null && !authSet.contains(dataAuthFilter.isIgnoreType() ? paramValue.toString() : paramValue)) {
throw new DataAccessException("参数:[" + paramName + "]参数对应的值:[" + paramValue + "] 超出授权范围(数据来源参见spring.sqltoy.unifyFieldsHandler配置的实现),请检查!");
}
}
}
}
}
}
use of org.sagacity.sqltoy.exception.DataAccessException in project sagacity-sqltoy by chenrenfei.
the class ResultUtils method getResultSet.
private static List getResultSet(SqlToyConfig sqlToyConfig, SqlToyContext sqlToyContext, Connection conn, ResultSet rs, UpdateRowHandler updateRowHandler, DecryptHandler decryptHandler, int rowCnt, HashMap<String, Integer> labelIndexMap, String[] labelNames, int startColIndex) throws Exception {
// 字段连接(多行数据拼接成一个数据,以一行显示)
LinkModel linkModel = sqlToyConfig.getLinkModel();
// update 2020-09-13 存在多列link(独立出去编写,避免对单列产生影响)
if (linkModel != null && linkModel.getColumns().length > 1) {
return getMoreLinkResultSet(sqlToyConfig, sqlToyContext, decryptHandler, conn, rs, rowCnt, labelIndexMap, labelNames, startColIndex);
}
List<List> items = new ArrayList();
// 判断是否有缓存翻译器定义
Boolean hasTranslate = (sqlToyConfig.getTranslateMap().isEmpty()) ? false : true;
HashMap<String, Translate> translateMap = sqlToyConfig.getTranslateMap();
HashMap<String, HashMap<String, Object[]>> translateCache = null;
if (hasTranslate) {
translateCache = sqlToyContext.getTranslateManager().getTranslates(translateMap);
if (translateCache == null || translateCache.isEmpty()) {
hasTranslate = false;
logger.debug("通过缓存配置未获取到缓存数据,请正确配置TranslateManager!");
}
}
// link 目前只支持单个字段运算
int columnSize = labelNames.length;
int index = 0;
// 警告阀值
int warnThresholds = SqlToyConstants.getWarnThresholds();
boolean warnLimit = false;
// 最大阀值
long maxThresholds = SqlToyConstants.getMaxThresholds();
boolean maxLimit = false;
// 是否判断全部为null的行记录
boolean ignoreAllEmpty = sqlToyConfig.isIgnoreEmpty();
// 最大值要大于等于警告阀值
if (maxThresholds > 1 && maxThresholds <= warnThresholds) {
maxThresholds = warnThresholds;
}
List rowTemp;
if (linkModel != null) {
Object identity = null;
String linkColumn = linkModel.getColumns()[0];
String linkColumnLow = linkColumn.toLowerCase();
if (!labelIndexMap.containsKey(linkColumnLow)) {
throw new DataAccessException("做link操作时,查询结果字段中没有字段:" + linkColumn + ",请检查sql或link 配置的正确性!");
}
Set<String> linkSet = new HashSet<String>();
int linkIndex = labelIndexMap.get(linkColumnLow);
StringBuilder linkBuffer = new StringBuilder();
boolean hasDecorate = (linkModel.getDecorateAppendChar() == null) ? false : true;
boolean isLeft = true;
if (hasDecorate) {
isLeft = linkModel.getDecorateAlign().equals("left") ? true : false;
}
Object preIdentity = null;
Object linkValue;
String linkStr;
boolean translateLink = hasTranslate ? translateMap.containsKey(linkColumnLow) : false;
HashMap<String, Object[]> linkTranslateMap = null;
int linkTranslateIndex = 1;
TranslateExtend extend = null;
if (translateLink) {
extend = translateMap.get(linkColumnLow).getExtend();
linkTranslateIndex = extend.index;
linkTranslateMap = translateCache.get(extend.column);
}
Object[] cacheValues;
// 判断link拼接是否重新开始
boolean isLastProcess = false;
boolean doLink = true;
while (rs.next()) {
isLastProcess = false;
linkValue = rs.getObject(linkColumn);
if (linkValue == null) {
linkStr = "";
} else {
if (translateLink) {
cacheValues = linkTranslateMap.get(linkValue.toString());
if (cacheValues == null) {
linkStr = "[" + linkValue + "]未匹配";
logger.debug("translate cache:{},cacheType:{}, 对应的key:{} 没有设置相应的value!", extend.cache, extend.cacheType, linkValue);
} else {
linkStr = (cacheValues[linkTranslateIndex] == null) ? "" : cacheValues[linkTranslateIndex].toString();
}
} else {
linkStr = linkValue.toString();
}
}
identity = (linkModel.getIdColumns() == null) ? "default" : getLinkColumnsId(rs, linkModel.getIdColumns());
// 不相等
if (!identity.equals(preIdentity)) {
if (index != 0) {
items.get(items.size() - 1).set(linkIndex, linkBuffer.toString());
linkBuffer.delete(0, linkBuffer.length());
linkSet.clear();
}
linkBuffer.append(linkStr);
linkSet.add(linkStr);
if (hasTranslate) {
rowTemp = processResultRowWithTranslate(translateMap, translateCache, labelNames, rs, columnSize, decryptHandler, ignoreAllEmpty);
} else {
rowTemp = processResultRow(rs, labelNames, columnSize, decryptHandler, ignoreAllEmpty);
}
if (rowTemp != null) {
items.add(rowTemp);
}
preIdentity = identity;
} else {
isLastProcess = true;
doLink = true;
if (linkModel.isDistinct() && linkSet.contains(linkStr)) {
doLink = false;
}
linkSet.add(linkStr);
if (doLink) {
if (linkBuffer.length() > 0) {
linkBuffer.append(linkModel.getSign());
}
linkBuffer.append(hasDecorate ? StringUtil.appendStr(linkStr, linkModel.getDecorateAppendChar(), linkModel.getDecorateSize(), isLeft) : linkStr);
}
}
index++;
// 存在超出25000条数据的查询
if (index == warnThresholds) {
warnLimit = true;
}
// 提取数据超过上限(-1表示不限制)
if (index == maxThresholds) {
maxLimit = true;
break;
}
}
// 对最后一条写入循环值
if (isLastProcess) {
items.get(items.size() - 1).set(linkIndex, linkBuffer.toString());
}
} else {
// 修改操作不支持link操作
boolean isUpdate = false;
if (updateRowHandler != null) {
isUpdate = true;
}
// 循环通过java reflection将rs中的值映射到VO中
if (hasTranslate) {
while (rs.next()) {
// 先修改后再获取最终值
if (isUpdate) {
updateRowHandler.updateRow(rs, index);
rs.updateRow();
}
rowTemp = processResultRowWithTranslate(translateMap, translateCache, labelNames, rs, columnSize, decryptHandler, ignoreAllEmpty);
if (rowTemp != null) {
items.add(rowTemp);
}
index++;
// 存在超出25000条数据的查询(具体数据规模可以通过参数进行定义)
if (index == warnThresholds) {
warnLimit = true;
}
// 超出最大提取数据阀值,直接终止数据提取
if (index == maxThresholds) {
maxLimit = true;
break;
}
}
} else {
while (rs.next()) {
if (isUpdate) {
updateRowHandler.updateRow(rs, index);
rs.updateRow();
}
rowTemp = processResultRow(rs, labelNames, columnSize, decryptHandler, ignoreAllEmpty);
if (rowTemp != null) {
items.add(rowTemp);
}
index++;
// 存在超出警告规模级的数据查询
if (index == warnThresholds) {
warnLimit = true;
}
// 提取数据超过上限(-1表示不限制)
if (index == maxThresholds) {
maxLimit = true;
break;
}
}
}
}
// 超出警告阀值
if (warnLimit) {
warnLog(sqlToyConfig, index);
}
// 超过最大提取数据阀值
if (maxLimit) {
logger.error("MaxLargeResult:执行sql提取数据超出最大阀值限制{},sqlId={},具体语句={}", index, sqlToyConfig.getId(), sqlToyConfig.getSql(null));
}
return items;
}
use of org.sagacity.sqltoy.exception.DataAccessException in project sagacity-sqltoy by chenrenfei.
the class Elastic method findPage.
/**
* @todo 分页查询
* @param pageModel
* @return
*/
public Page findPage(Page pageModel) {
QueryExecutor queryExecutor = build();
SqlToyConfig sqlToyConfig = sqlToyContext.getSqlToyConfig(sql, SqlType.search, "");
NoSqlConfigModel noSqlConfig = sqlToyConfig.getNoSqlConfigModel();
if (noSqlConfig == null) {
throw new IllegalArgumentException(ERROR_MESSAGE);
}
Page pageResult = null;
try {
if (noSqlConfig.isSqlMode()) {
ElasticEndpoint esConfig = sqlToyContext.getElasticEndpoint(noSqlConfig.getEndpoint());
if (esConfig.isNativeSql()) {
throw new UnsupportedOperationException("elastic native sql pagination is not support!");
}
pageResult = ElasticSqlPlugin.findPage(sqlToyContext, sqlToyConfig, pageModel, queryExecutor);
} else {
pageResult = ElasticSearchPlugin.findPage(sqlToyContext, sqlToyConfig, pageModel, queryExecutor);
}
if (pageResult.getRecordCount() == 0 && sqlToyContext.isPageOverToFirst()) {
pageResult.setPageNo(1L);
}
return pageResult;
} catch (Exception e) {
e.printStackTrace();
throw new DataAccessException(e);
}
}
use of org.sagacity.sqltoy.exception.DataAccessException in project sagacity-sqltoy by chenrenfei.
the class Elastic method findTop.
/**
* @todo 查询前多少条记录
* @param topSize
* @return
*/
public List<?> findTop(final int topSize) {
QueryExecutor queryExecutor = build();
SqlToyConfig sqlToyConfig = sqlToyContext.getSqlToyConfig(sql, SqlType.search, "");
if (sqlToyConfig.getNoSqlConfigModel() == null) {
throw new IllegalArgumentException(ERROR_MESSAGE);
}
try {
if (sqlToyConfig.getNoSqlConfigModel().isSqlMode()) {
return ElasticSqlPlugin.findTop(sqlToyContext, sqlToyConfig, queryExecutor, topSize);
}
return ElasticSearchPlugin.findTop(sqlToyContext, sqlToyConfig, queryExecutor, topSize);
} catch (Exception e) {
e.printStackTrace();
throw new DataAccessException(e);
}
}
use of org.sagacity.sqltoy.exception.DataAccessException in project sagacity-sqltoy by chenrenfei.
the class Elastic method find.
/**
* @todo 集合记录查询
* @return
*/
public List<?> find() {
QueryExecutor queryExecutor = build();
SqlToyConfig sqlToyConfig = sqlToyContext.getSqlToyConfig(sql, SqlType.search, "");
if (sqlToyConfig.getNoSqlConfigModel() == null) {
throw new IllegalArgumentException(ERROR_MESSAGE);
}
try {
if (sqlToyConfig.getNoSqlConfigModel().isSqlMode()) {
return ElasticSqlPlugin.findTop(sqlToyContext, sqlToyConfig, queryExecutor, null);
}
return ElasticSearchPlugin.findTop(sqlToyContext, sqlToyConfig, queryExecutor, null);
} catch (Exception e) {
e.printStackTrace();
throw new DataAccessException(e);
}
}
Aggregations