All Downloads are FREE. Search and download functionalities are using the official Maven repository.

metridoc.camel.component.sqlplus.SqlPlusUpdateProcessor Maven / Gradle / Ivy

There is a newer version: 0.12
Show newest version
/*
 * Copyright 2010 Trustees of the University of Pennsylvania Licensed under the
 * Educational Community 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.osedu.org/licenses/ECL-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 metridoc.camel.component.sqlplus;

import metridoc.camel.component.sqlplus.dao.SqlPlusDao;
import metridoc.camel.component.sqlplus.impl.dao.SpringSqlPlusDao;
import metridoc.utils.Assert;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Processor;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.jdbc.support.rowset.SqlRowSetMetaData;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * helps with batch updates.  The camel-sql processor only does single statements, this should help camel with speeding
 * up etl batch processing.  Using a database's loading tools is generally the fastest way to insert into a table
 * (by around 8 to 10 times faster), but this should be good enough for most scenarios.  Certain database loading utils
 * have pretty terrible feedback, so depending on the driver using this should provide better feedback when something
 * goes wrong.
 *
 * @author Tommy Barker
 */
public class SqlPlusUpdateProcessor implements Processor {
    private String sql;
    private int batchSize;
    private boolean detailedOutput;
    SqlPlusDao sqlPlusDao;

    public SqlPlusUpdateProcessor(DataSource dataSource, String sql, int batchSize, boolean detailedOutput) {
        this(dataSource, sql, batchSize);
        this.detailedOutput = detailedOutput;
    }

    public SqlPlusUpdateProcessor(DataSource dataSource, String sql, int batchSize) {
        Assert.notNull(dataSource, "The dataSource cannot be null or empty");
        Assert.notEmpty(sql, "sql cannot be null or empty");
        this.sqlPlusDao = new SpringSqlPlusDao(dataSource);
        this.sql = convertHashSql(sql);
        this.batchSize = batchSize;
    }

    @Override
    public void process(Exchange exchange) throws Exception {
        Object updates = null;
        Message in = exchange.getIn();
        SqlRowSet sqlRowSet = in.getBody(SqlRowSet.class);
        if (sqlRowSet == null) {
            List body = in.getBody(List.class);
            if (body == null) {
                Object object = in.getBody(Object.class);
                if (object != null) {
                    body = new ArrayList();
                    body.add(object);
                }
            }
            Assert.notNull(body, "the body is either null or is not of expected type");
            String sqlToExec = isSqlGenerationRequired() ? generateInsertQuery(sql, body.get(0)) : sql;

            updates = sqlPlusDao.batchUpdate(body, sqlToExec, detailedOutput);
        } else {
            Assert.isTrue(batchSize > 0, "The batchSize should be positive number");
            String sqlToExec = sql;
            if(isSqlGenerationRequired()){
            	SqlRowSetMetaData metadata = sqlRowSet.getMetaData();
            	sqlToExec = generateInsertQuery(sql, metadata.getColumnNames());
            }
            updates = sqlPlusDao.batchUpdate(sqlRowSet, sqlToExec, batchSize, detailedOutput);
        }
        exchange.getOut().setHeader(SqlPlusConstants.UPDATES, updates);
    }

    private boolean isSqlGenerationRequired() {
        return !sql.startsWith("select") && !sql.startsWith("insert") &&
                !sql.startsWith("update") && !sql.startsWith("delete");
    }

    private static String generateInsertQuery(String tableName, Object object) {
        Assert.isTrue(object instanceof Map, "Map is required to generate Insert statement");
        Set keys = ((Map) object).keySet();
        Assert.isTrue(keys.size() > 0, "Map should contain at least one element");
        return generateInsertQuery(tableName, keys.toArray(new String[keys.size()]));
    }

    private static String generateInsertQuery(String tableName, String[] columns){
    	String sqlColumns = "";
        String sqlParams = "";
        for (String column : columns) {
            sqlColumns += column + ",";
            sqlParams += ":" + column + ",";
        }
        String query = "insert into " + tableName + "(" + sqlColumns.substring(0, sqlColumns.length() - 1)
                + ") values (" + sqlParams.substring(0, sqlParams.length() - 1) + ")";
        return query;
    }
    
    static String convertHashSql(String sql) {
    	return sql.replaceAll("#", ":");
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy