/**
 * Copyright 1999-2015 dangdang.com.
 * <p>
 * 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.
 * </p>
 */

package com.dangdang.ddframe.rdb.sharding.api.strategy.common;

import java.util.Arrays;
import java.util.Collection;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;

/**
 * 分片策略.
 * 
 * @author zhangliang
 */
@RequiredArgsConstructor
public class ShardingStrategy {
    
    @Getter
    private final Collection<String> shardingColumns;
    
    private final ShardingAlgorithm shardingAlgorithm;
    
    public ShardingStrategy(final String shardingColumn, final ShardingAlgorithm shardingAlgorithm) {
        this(Arrays.asList(shardingColumn), shardingAlgorithm);
    }
    
    /**
     * 根据分片值计算数据源名称集合.
     * 
     * @param availableTargetNames 所有的可用数据源名称集合
     * @param shardingValues 分库片值集合
     * @return 分库后指向的数据源名称集合
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public Collection<String> doSharding(final Collection<String> availableTargetNames, final Collection<ShardingValue<? extends Comparable<?>>> shardingValues) {
        if (shardingValues.isEmpty()) {
            return availableTargetNames;
        }
        if (shardingAlgorithm instanceof SingleKeyShardingAlgorithm) {
            SingleKeyShardingAlgorithm<?> singleKeyShardingAlgorithm = (SingleKeyShardingAlgorithm<?>) shardingAlgorithm;
            ShardingValue shardingValue = shardingValues.iterator().next();
            switch (shardingValue.getType()) {
                case SINGLE: // 根据hash 值分片
                    return Arrays.asList(singleKeyShardingAlgorithm.doEqualSharding(availableTargetNames, shardingValue));
                case LIST: // 根据列表分片
                    return singleKeyShardingAlgorithm.doInSharding(availableTargetNames, shardingValue);
                case RANGE: //根据范围分片
                    return singleKeyShardingAlgorithm.doBetweenSharding(availableTargetNames, shardingValue);
                default: 
                    throw new UnsupportedOperationException(shardingValue.getType().getClass().getName());
            }
        }
        if (shardingAlgorithm instanceof MultipleKeysShardingAlgorithm) {
            return ((MultipleKeysShardingAlgorithm) shardingAlgorithm).doSharding(availableTargetNames, shardingValues);
        }
        throw new UnsupportedOperationException(shardingAlgorithm.getClass().getName());
    }
}

@@ -1,741 +1,338 @@
-/**%0A * Copyright 1999-2015 dangdang.com.%0A * %3Cp%3E%0A * Licensed under the Apache License, Version 2.0 (the %22License%22);%0A * you may not use this file except in compliance with the License.%0A * You may obtain a copy of the License at%0A * %0A *      http://www.apache.org/licenses/LICENSE-2.0%0A * %0A * Unless required by applicable law or agreed to in writing, software%0A * distributed under the License is distributed on an %22AS IS%22 BASIS,%0A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.%0A * See the License for the specific language governing permissions and%0A * limitations under the License.%0A * %3C/p%3E%0A */%0A%0Apackage com.dangdang.ddframe.rdb.sharding.api.strategy.common;%0A%0Aimport java.util.Arrays;%0Aimport java.util.Collection;%0A
+%0A%0Apackage com.dangdang.ddframe.rdb.sharding.api.strategy.common;%0A%0Aimport java.util.Arrays;%0Aimport java.util.Collection;%0A%0Aimport com.dangdang.ddframe.rdb.sharding.api.ShardingValue;%0Aimport com.dangdang.ddframe.rdb.sharding.exception.ShardingJdbcException;%0Aimport com.dangdang.ddframe.rdb.sharding.parser.result.router.SQLStatementType;
 %0Aimp
@@ -394,69 +394,8 @@
 r;%0A%0A
-import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;%0A%0A
 /**%0A
@@ -840,17 +840,63 @@
 .%0A     *
- 
+%0A     *%0A     * @param sqlStatementType SQL%E8%AF%AD%E5%8F%A5%E7%9A%84%E7%B1%BB%E5%9E%8B
 %0A     * 
@@ -1111,48 +1111,131 @@
 nal 
-Collection%3CString%3E availableTargetNames,
+SQLStatementType sqlStatementType, final Collection%3CString%3E availableTargetNames, %0A                                        
  fin
@@ -1342,24 +1342,250 @@
 sEmpty()) %7B%0A
+            if (SQLStatementType.INSERT.equals(sqlStatementType) && availableTargetNames.size() %3E 1) %7B%0A                throw new ShardingJdbcException(%22INSERT statement must contains sharding value%22);%0A            %7D else %7B%0A    
             
@@ -1613,16 +1613,30 @@
 tNames;%0A
+            %7D%0A
         
@@ -1986,21 +1986,8 @@
 LE: 
-// %E6%A0%B9%E6%8D%AEhash %E5%80%BC%E5%88%86%E7%89%87
 %0A   
@@ -2137,17 +2137,8 @@
 ST: 
-// %E6%A0%B9%E6%8D%AE%E5%88%97%E8%A1%A8%E5%88%86%E7%89%87
 %0A   
@@ -2271,16 +2271,8 @@
 GE: 
-//%E6%A0%B9%E6%8D%AE%E8%8C%83%E5%9B%B4%E5%88%86%E7%89%87
 %0A   

Update ShardingStrategy.java