Package jp.co.ntt.oss

Source Code of jp.co.ntt.oss.IncrementalReader

package jp.co.ntt.oss;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Hashtable;

import jp.co.ntt.oss.mapper.MappingData;

import org.apache.log4j.Logger;

public class IncrementalReader implements Reader {
  private static Logger log = Logger.getLogger(IncrementalReader.class);

  // the number of rows to fetch
  private static final int FETCH_SIZE = 100;

  // flag column count (delete flag, insert flag and update flag)
  private static final int TYPE_COUNT = 3;

  private Statement stmt = null;
  private ResultSet rset = null;
  private int pkCount;
  private MappingData columnMapping = null;

  public IncrementalReader(final Connection conn, final String query,
      final int setPkCount) throws SQLException, SyncDatabaseException {
    if (conn == null || query == null || setPkCount < 1) {
      throw new SyncDatabaseException("error.argument");
    }

    try {
      this.pkCount = setPkCount;

      stmt = conn.createStatement();
      stmt.setFetchSize(FETCH_SIZE);
      rset = stmt.executeQuery(query);

      final ResultSetMetaData rmd = rset.getMetaData();

      final int columnCount = rmd.getColumnCount() - TYPE_COUNT;
      columnMapping = new MappingData(columnCount);
      for (int i = 0; i < columnCount; i++) {
        columnMapping.setColumnType(i, rmd.getColumnType(i + TYPE_COUNT
            + 1));
        columnMapping.setColumnTypeName(i, rmd.getColumnTypeName(i
            + TYPE_COUNT + 1));
      }
    } catch (final SQLException e) {
      if (rset != null) {
        rset.close();
      }
      if (stmt != null) {
        stmt.close();
      }

      throw e;
    }
  }

  public final void close() throws SQLException {
    if (rset != null) {
      rset.close();
    }
    if (stmt != null) {
      stmt.close();
    }
  }

  public final Object[] getNextColumns() throws SQLException,
      SyncDatabaseException {
    if (!rset.next()) {
      return null;
    }

    final Object[] columns = new Object[columnMapping.getColumnCount()
        + TYPE_COUNT];

    int i;
    // get D, I ,U count
    for (i = 0; i < TYPE_COUNT; i++) {
      columns[i] = rset.getLong(i + 1);
    }

    // get PK data and select list data
    for (; i < columnMapping.getColumnCount() + TYPE_COUNT; i++) {
      columns[i] = columnMapping.getDataMapper(i - TYPE_COUNT).getObject(
          rset, i + 1);
    }

    return columns;
  }

  public final int getColumnCount() {
    return columnMapping.getColumnCount();
  }

  public final MappingData getColumnMapping() {
    return columnMapping;
  }

  public final int getPKCount() {
    return pkCount;
  }

  public static String getIncrementalQuery(final String mlogName,
      final String query, final Hashtable<Short, String> pkNames,
      final long lastMlogID) throws SQLException, SyncDatabaseException {
    if (mlogName == null || query == null || pkNames == null
        || pkNames.size() < 1 || lastMlogID < 0) {
      throw new SyncDatabaseException("error.argument");
    }

    // get PK count
    final int pkCount = pkNames.size();

    /*
     * generate get incremental data query
     */
    final StringBuilder incrementalQuery = new StringBuilder();

    // delete, insert, update flag data
    incrementalQuery.append("SELECT m.d_cnt, m.i_cnt, m.u_cnt");

    // PK list
    for (short i = 1; i <= pkCount; i++) {
      incrementalQuery.append(", m.");
      incrementalQuery.append(pkNames.get(Short.valueOf(i)));
    }

    // refresh query list and flag count
    incrementalQuery.append(", d.* FROM ( SELECT ");
    incrementalQuery
        .append("SUM(CASE WHEN m.dmltype = 'D' THEN 1 ELSE 0 END) d_cnt, ");
    incrementalQuery
        .append("SUM(CASE WHEN m.dmltype = 'I' THEN 1 ELSE 0 END) i_cnt, ");
    incrementalQuery
        .append("SUM(CASE WHEN m.dmltype = 'U' THEN 1 ELSE 0 END) u_cnt");

    // PK list
    for (short i = 1; i <= pkCount; i++) {
      incrementalQuery.append(", m.");
      incrementalQuery.append(pkNames.get(Short.valueOf(i)));
    }
    // select from mlog table and mlog search condition
    incrementalQuery.append(" FROM ");
    incrementalQuery.append(mlogName);
    incrementalQuery.append(" m WHERE m.mlogid > ");
    incrementalQuery.append(lastMlogID);
    incrementalQuery.append(" GROUP BY ");

    // PK list
    for (short i = 1; i <= pkCount; i++) {
      if (i > 1) {
        incrementalQuery.append(", ");
      }

      incrementalQuery.append(pkNames.get(Short.valueOf(i)));
    }

    // joined refresh query
    incrementalQuery.append(") m LEFT OUTER JOIN ( ");
    incrementalQuery.append(query);
    incrementalQuery.append(") d ON ( ");

    // join condition
    for (short i = 1; i <= pkCount; i++) {
      if (i > 1) {
        incrementalQuery.append(" AND ");
      }
      incrementalQuery.append("m.");
      incrementalQuery.append(pkNames.get(Short.valueOf((short) i)));
      incrementalQuery.append(" = d.");
      incrementalQuery.append(pkNames.get(i));
    }

    incrementalQuery.append(")");
    log.debug("INCREMENTAL REFRESH reader query : "
        + incrementalQuery.toString());

    return incrementalQuery.toString();
  }
}
TOP

Related Classes of jp.co.ntt.oss.IncrementalReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.