/* * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software;Designed and Developed mainly by many Chinese * opensource volunteers. you can redistribute it and/or modify it under the * terms of the GNU General Public License version 2 only, as published by the * Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Any questions about this component can be directed to it's project Web address * https://code.google.com/p/opencloudb/. * */ package org.opencloudb.route; import java.sql.SQLNonTransientException; import org.opencloudb.cache.CachePool; import org.opencloudb.cache.CacheService; import org.opencloudb.cache.LayerCachePool; import org.opencloudb.config.model.SchemaConfig; import org.opencloudb.config.model.SystemConfig; import org.opencloudb.server.parser.ServerParse; public class RouteService { private final CachePool sqlRouteCache; private final LayerCachePool tableId2DataNodeCache; public RouteService(CacheService cachService) { sqlRouteCache = cachService.getCachePool("SQLRouteCache"); tableId2DataNodeCache = (LayerCachePool) cachService .getCachePool("TableID2DataNodeCache"); } public LayerCachePool getTableId2DataNodeCache() { return tableId2DataNodeCache; } public RouteResultset route(SystemConfig sysconf, SchemaConfig schema, int sqlType, String stmt, String charset, Object info) throws SQLNonTransientException { RouteResultset rrs = null; String cacheKey = null; if (sqlType == ServerParse.SELECT) { cacheKey = schema.getName() + stmt; rrs = (RouteResultset) sqlRouteCache.get(cacheKey); if (rrs != null) { return rrs; } } // 处理自定义分片注释 String mycatHint = "/*!mycat"; /* !mycat: select name from aa */ if (stmt.startsWith(mycatHint)) { int endPos = stmt.indexOf("*/"); if (endPos > 0) { // 用!mycat内部的SQL来做路由分析 String hintSQl = stmt.substring(mycatHint.length(), endPos) .trim(); rrs = ServerRouterUtil.route(sysconf, schema, sqlType, hintSQl, charset, info, tableId2DataNodeCache); // 替换RRS中的SQL执行 String realSQL = stmt.substring(endPos + "*/".length()).trim(); RouteResultsetNode[] oldRsNodes = rrs.getNodes(); RouteResultsetNode[] newRrsNodes = new RouteResultsetNode[oldRsNodes.length]; for (int i = 0; i < newRrsNodes.length; i++) { newRrsNodes[i] = new RouteResultsetNode( oldRsNodes[i].getName(), oldRsNodes[i].getSqlType(), realSQL); } rrs.setNodes(newRrsNodes); } } else { stmt = stmt.trim(); rrs = ServerRouterUtil.route(sysconf, schema, sqlType, stmt, charset, info, tableId2DataNodeCache); } if (sqlType == ServerParse.SELECT && rrs.isCacheAble()) { sqlRouteCache.putIfAbsent(cacheKey, rrs); } return rrs; } }