Search in sources :

Example 1 with DataAccessException

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配置的实现),请检查!");
                    }
                }
            }
        }
    }
}
Also used : DataAuthFilterConfig(org.sagacity.sqltoy.model.DataAuthFilterConfig) Set(java.util.Set) HashSet(java.util.HashSet) Collection(java.util.Collection) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Example 2 with DataAccessException

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;
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) LinkModel(org.sagacity.sqltoy.config.model.LinkModel) TranslateExtend(org.sagacity.sqltoy.model.inner.TranslateExtend) ReverseList(org.sagacity.sqltoy.plugins.calculator.ReverseList) List(java.util.List) ArrayList(java.util.ArrayList) UnpivotList(org.sagacity.sqltoy.plugins.calculator.UnpivotList) Translate(org.sagacity.sqltoy.config.model.Translate) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) HashSet(java.util.HashSet)

Example 3 with DataAccessException

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);
    }
}
Also used : NoSqlConfigModel(org.sagacity.sqltoy.config.model.NoSqlConfigModel) QueryExecutor(org.sagacity.sqltoy.model.QueryExecutor) SqlToyConfig(org.sagacity.sqltoy.config.model.SqlToyConfig) Page(org.sagacity.sqltoy.model.Page) ElasticEndpoint(org.sagacity.sqltoy.config.model.ElasticEndpoint) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Example 4 with DataAccessException

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);
    }
}
Also used : QueryExecutor(org.sagacity.sqltoy.model.QueryExecutor) SqlToyConfig(org.sagacity.sqltoy.config.model.SqlToyConfig) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Example 5 with DataAccessException

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);
    }
}
Also used : QueryExecutor(org.sagacity.sqltoy.model.QueryExecutor) SqlToyConfig(org.sagacity.sqltoy.config.model.SqlToyConfig) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Aggregations

DataAccessException (org.sagacity.sqltoy.exception.DataAccessException)40 Connection (java.sql.Connection)24 DataSourceCallbackHandler (org.sagacity.sqltoy.callback.DataSourceCallbackHandler)24 ArrayList (java.util.ArrayList)19 SqlToyConfig (org.sagacity.sqltoy.config.model.SqlToyConfig)17 List (java.util.List)13 ShardingModel (org.sagacity.sqltoy.config.model.ShardingModel)13 QueryExecutorExtend (org.sagacity.sqltoy.model.inner.QueryExecutorExtend)12 QueryExecutor (org.sagacity.sqltoy.model.QueryExecutor)9 QueryResult (org.sagacity.sqltoy.model.QueryResult)9 SqlToyResult (org.sagacity.sqltoy.config.model.SqlToyResult)6 HashMap (java.util.HashMap)5 Serializable (java.io.Serializable)4 NoSqlConfigModel (org.sagacity.sqltoy.config.model.NoSqlConfigModel)4 HashSet (java.util.HashSet)3 ExecutorService (java.util.concurrent.ExecutorService)3 EntityMeta (org.sagacity.sqltoy.config.model.EntityMeta)3 FieldMeta (org.sagacity.sqltoy.config.model.FieldMeta)3 Type (java.lang.reflect.Type)2 ResultSet (java.sql.ResultSet)2