/* * Copyright 2012-2015 org.opencloudb. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * (created at 2012-6-13) */ package org.opencloudb.config.model; import java.util.ArrayList; import java.util.Random; import org.opencloudb.config.model.rule.RuleConfig; import org.opencloudb.util.SplitUtil; /** * @author mycat */ public class TableConfig { public static final int TYPE_GLOBAL_TABLE = 1; public static final int TYPE_GLOBAL_DEFAULT = 0; private final String name; private final int tableType; private final ArrayList<String> dataNodes; private final RuleConfig rule; private final String partitionColumn; private final boolean ruleRequired; private final TableConfig parentTC; private final boolean childTable; private final String joinKey; private final String parentKey; private final String locateRTableKeySql; private final Random rand=new Random(); public TableConfig(String name, int tableType, String dataNode, RuleConfig rule, boolean ruleRequired, TableConfig parentTC, boolean isChildTable, String joinKey, String parentKey) { if (name == null) { throw new IllegalArgumentException("table name is null"); } else if (dataNode == null) { throw new IllegalArgumentException("dataNode name is null"); } this.tableType = tableType; if (ruleRequired && rule == null) { throw new IllegalArgumentException("ruleRequired but rule is null"); } this.name = name.toUpperCase(); String theDataNodes[] = SplitUtil.split(dataNode, ',', '$', '-', '[', ']'); if (theDataNodes == null || theDataNodes.length <= 0) { throw new IllegalArgumentException("invalid table dataNodes: " + dataNode); } dataNodes = new ArrayList<String>(theDataNodes.length); for (String dn : theDataNodes) { dataNodes.add(dn); } this.rule = rule; this.partitionColumn = (rule == null) ? null : rule.getColumn(); this.ruleRequired = ruleRequired; this.childTable = isChildTable; this.parentTC = parentTC; this.joinKey = joinKey; this.parentKey = parentKey; if (parentTC != null) { locateRTableKeySql = genLocateRootParentSQL(); } else { locateRTableKeySql = null; } } public String getLocateRTableKeySql() { return locateRTableKeySql; } public String genLocateRootParentSQL() { TableConfig tb = this; StringBuilder tableSb = new StringBuilder(); StringBuilder condition = new StringBuilder(); TableConfig prevTC = null; int level=0; String latestCond=null; while (tb.parentTC != null) { tableSb.append(tb.parentTC.name).append(','); String relation=null; if(level==0) { latestCond = " "+tb.parentTC.getName() + '.' + tb.parentKey +"="; }else { relation = tb.parentTC.getName() + '.' + tb.parentKey +'='+tb.name+'.'+tb.joinKey; condition.append(relation).append(" AND "); } level++; prevTC = tb; tb = tb.parentTC; } String sql = "SELECT " + prevTC.parentTC.name + '.' + prevTC.parentKey + " FROM " + tableSb.substring(0, tableSb.length() - 1) + " WHERE " + ((level<2)?latestCond:condition.toString()+latestCond); //System.out.println(this.name+" sql " + sql); return sql; } public String getPartitionColumn() { return partitionColumn; } public int getTableType() { return tableType; } /** * get root parent * * @return */ public TableConfig getRootParent() { if (parentTC == null) { return null; } TableConfig preParent = parentTC; TableConfig parent = preParent.getParentTC(); while (parent != null) { preParent = parent; parent = parent.getParentTC(); } return preParent; } public TableConfig getParentTC() { return parentTC; } public boolean isChildTable() { return childTable; } public String getJoinKey() { return joinKey; } public String getParentKey() { return parentKey; } /** * @return upper-case */ public String getName() { return name; } public ArrayList<String> getDataNodes() { return dataNodes; } public String getRandomDataNode() { int index=Math.abs(rand.nextInt())%dataNodes.size(); return dataNodes.get(index); } public boolean isRuleRequired() { return ruleRequired; } public RuleConfig getRule() { return rule; } }