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

com.tacitknowledge.util.migration.jdbc.SqlLoadMigrationTask Maven / Gradle / Ivy

There is a newer version: 1.4.2
Show newest version
/* Copyright 2004 Tacit Knowledge
 *  
 * 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.
 */

package com.tacitknowledge.util.migration.jdbc;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.tacitknowledge.util.migration.MigrationContext;
import com.tacitknowledge.util.migration.MigrationException;
import com.tacitknowledge.util.migration.MigrationTaskSupport;
import com.tacitknowledge.util.migration.jdbc.util.SqlUtil;

/**
 * Base class used for creating bulk data loading MigrationTasks.
 *  
 * @author  Scott Askew ([email protected])
 */
public abstract class SqlLoadMigrationTask extends MigrationTaskSupport
{
    /** Class logger */
    private static Log log = LogFactory.getLog(SqlLoadMigrationTask.class);
    
    /** Creates a new SqlScriptMigrationTask. */
    public SqlLoadMigrationTask()
    {
        // Nothing to do
    }
    
    /** {@inheritDoc} */
    public void migrate(MigrationContext ctx) throws MigrationException
    {
        DataSourceMigrationContext context = (DataSourceMigrationContext) ctx;
        
        Connection conn = null;
        PreparedStatement stmt = null;
        try
        {
            conn = context.getConnection();
            stmt = conn.prepareStatement(getStatmentSql());
            List rows = getData(getResourceAsStream());
            int rowCount = rows.size();
            for (int i = 0; i < rowCount; i++)
            {
                String data = (String) rows.get(i);
                boolean loadRowFlag = insert(data, stmt);
                if (loadRowFlag)
                {
                    stmt.addBatch();
                    if (i % 50 == 0)
                    {
                        stmt.executeBatch();
                    }
                }
            }
            stmt.executeBatch();
            context.commit();
        }
        catch (Exception e)
        {
            String message = getName() + ": Error running SQL \"" + getStatmentSql() + "\"";
            log.error(message, e);
            if (e instanceof SQLException)
            {
                if (((SQLException) e).getNextException() != null)
                {
                    log.error("Chained SQL Exception", ((SQLException) e).getNextException());
                }
            }
            
            context.rollback();
            
            throw new MigrationException(message, e);
        }
        finally
        {
            SqlUtil.close(conn, stmt, null);
        }
    }
    
    /**
     * Returns an input stream representing the data to load.
     *  
     * @return an input stream representing the data to load
     */
    protected abstract InputStream getResourceAsStream();

    /**
     * Inserts the given row of data into the database using the given
     * prepared statement.  Subclasses should parse the row and call the
     * appropriate set methods on the prepared statement.
     * 
     * @param  data the current row of data to load
     * @param  stmt the statement used for inserting data into the DB
     * 
     * @return false if you do not want this row loaded, true otherwise
     * @throws Exception if an unexpected error occurs
     */    
    protected abstract boolean insert(String data, PreparedStatement stmt) throws Exception;
    
    /**
     * Returns the PreparedStatement SQL used for inserting rows
     * into the table.
     * 
     * @return the PreparedStatement SQL used for inserting rows
     *         into the table
     */
    protected abstract String getStatmentSql();

    /** {@inheritDoc} */
    public String toString()
    {
        return getName();
    }

    /**
     * Returns the data to load as a list of rows.
     * 
     * @param  is the input stream containing the data to load
     * @return the data to load as a list of rows
     * @throws IOException if the input stream could not be read
     */
    protected List getData(InputStream is) throws IOException
    {
        List data = new ArrayList();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        String line = null;
        while ((line = reader.readLine()) != null)
        {
            data.add(line);
        }
        return data;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy