/** * Copyright 2017 StreamSets Inc. * * Licensed under the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ package com.streamsets.pipeline.lib.jdbc; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Joiner; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.streamsets.pipeline.api.StageException; import com.streamsets.pipeline.api.base.OnRecordErrorException; import com.streamsets.pipeline.lib.operation.OperationType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.sql.Connection; import java.sql.PreparedStatement; import java.util.SortedMap; import java.util.Map; import java.util.HashMap; import java.util.List; import java.util.concurrent.ExecutionException; final class PreparedStatementMap { /** * Map of opCode and PreparedStatementCache. */ private final Map<Integer, PreparedStatementCache> cache = new HashMap<>(); public PreparedStatementMap( Connection connection, String tableName, List<JdbcFieldColumnMapping> generatedColumnMappings, List<String> primaryKeyColumns, int maxPrepStmtCache, boolean caseSensitive) { for (JDBCOperationType type: JDBCOperationType.values()) { cache.put(type.code, new PreparedStatementCache( connection, tableName, generatedColumnMappings, primaryKeyColumns, type.code, maxPrepStmtCache, caseSensitive) ); } } /** * Receive operation code and columnName-param map per each record. * Return a PreparedStatement if cache already has one for the same operation code * and same number of columns. Otherwise load one. * @param opCode Operation Code * @param columns Column to param mapping. * @return PreparedStatement * @throws StageException */ @VisibleForTesting PreparedStatement getPreparedStatement(int opCode, SortedMap<String, String> columns) throws StageException { //Cache already has PreparedStatementCache for all opCode. if (!cache.containsKey(opCode)){ // This check has been done earlier, so shouldn't come here. throw new StageException(JdbcErrors.JDBC_70, opCode); } return cache.get(opCode).get(columns); } void destroy(){ for (Map.Entry<Integer, PreparedStatementCache> pcache: cache.entrySet()){ pcache.getValue().destroy(); } } }