public void writeLine(RowMetaInterface mi, Object[] row) throws KettleException { if (first) { first = false; enclosure = meta.getEnclosure(); // Setup up the fields we need to take for each of the rows // as this speeds up processing. fieldNumbers = new int[meta.getFieldStream().length]; for (int i = 0; i < fieldNumbers.length; i++) { fieldNumbers[i] = mi.indexOfValue(meta.getFieldStream()[i]); if (fieldNumbers[i] < 0) { throw new KettleException( "Could not find field " + meta.getFieldStream()[i] + " in stream"); } } sdfDate = new SimpleDateFormat("yyyy-MM-dd"); sdfDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); outbuf = new StringBuilder(); } outbuf.setLength(0); // Write the data to the output ValueMetaInterface v = null; int number = 0; for (int i = 0; i < fieldNumbers.length; i++) { if (i != 0) { outbuf.append(","); } v = mi.getValueMeta(i); number = fieldNumbers[i]; if (row[number] == null) { // TODO (SB): special check for null in case of Strings. outbuf.append(enclosure); outbuf.append(enclosure); } else { switch (v.getType()) { case ValueMetaInterface.TYPE_STRING: String s = mi.getString(row, number); if (s.indexOf(enclosure) >= 0) { s = createEscapedString(s, enclosure); } outbuf.append(enclosure); outbuf.append(s); outbuf.append(enclosure); break; case ValueMetaInterface.TYPE_INTEGER: Long l = mi.getInteger(row, number); outbuf.append(enclosure); outbuf.append(l); outbuf.append(enclosure); break; case ValueMetaInterface.TYPE_NUMBER: Double d = mi.getNumber(row, number); outbuf.append(enclosure); outbuf.append(d); outbuf.append(enclosure); break; case ValueMetaInterface.TYPE_BIGNUMBER: BigDecimal bd = mi.getBigNumber(row, number); outbuf.append(enclosure); outbuf.append(bd); outbuf.append(enclosure); break; case ValueMetaInterface.TYPE_DATE: Date dt = mi.getDate(row, number); outbuf.append(enclosure); String mask = meta.getDateMask()[i]; if (OraBulkLoaderMeta.DATE_MASK_DATETIME.equals(mask)) { outbuf.append(sdfDateTime.format(dt)); } else { // Default is date format outbuf.append(sdfDate.format(dt)); } outbuf.append(enclosure); break; case ValueMetaInterface.TYPE_BOOLEAN: Boolean b = mi.getBoolean(row, number); outbuf.append(enclosure); if (b.booleanValue()) { outbuf.append("Y"); } else { outbuf.append("N"); } outbuf.append(enclosure); break; case ValueMetaInterface.TYPE_BINARY: byte[] byt = mi.getBinary(row, number); outbuf.append("<startlob>"); outbuf.append(byt); outbuf.append("<endlob>"); break; default: throw new KettleException("Unsupported type"); } } } outbuf.append(recTerm); try { output.append(outbuf); } catch (IOException e) { throw new KettleException("IO exception occured: " + e.getMessage(), e); } }
/** * Get the contents of the control file as specified in the meta object * * @param meta the meta object to model the control file after * @return a string containing the control file contents */ public String getControlFileContents(OraBulkLoaderMeta meta, RowMetaInterface rm, Object[] r) throws KettleException { DatabaseMeta dm = meta.getDatabaseMeta(); String inputName = "'" + environmentSubstitute(meta.getDataFile()) + "'"; String loadAction = meta.getLoadAction(); StringBuilder contents = new StringBuilder(500); contents.append("OPTIONS(").append(Const.CR); contents.append(" ERRORS=\'").append(meta.getMaxErrors()).append("\'").append(Const.CR); if (meta.getCommitSizeAsInt(this) != 0 && !(meta.isDirectPath() && getStepMeta().getCopies() > 1)) { // For the second part of the above expressions: ROWS is not supported // in parallel mode (by sqlldr). contents.append(" , ROWS=\'").append(meta.getCommitSize()).append("\'").append(Const.CR); } if (meta.getBindSizeAsInt(this) != 0) { contents.append(" , BINDSIZE=\'").append(meta.getBindSize()).append("\'").append(Const.CR); } if (meta.getReadSizeAsInt(this) != 0) { contents.append(" , READSIZE=\'").append(meta.getReadSize()).append("\'").append(Const.CR); } contents.append(")").append(Const.CR); contents.append("LOAD DATA").append(Const.CR); if (!Utils.isEmpty(meta.getCharacterSetName())) { contents.append("CHARACTERSET ").append(meta.getCharacterSetName()).append(Const.CR); } if (!OraBulkLoaderMeta.METHOD_AUTO_CONCURRENT.equals(meta.getLoadMethod()) || !Utils.isEmpty(meta.getAltRecordTerm())) { String infile = inputName; if (OraBulkLoaderMeta.METHOD_AUTO_CONCURRENT.equals(meta.getLoadMethod())) { infile = "''"; } // For concurrent input, data command line argument must be specified contents.append("INFILE ").append(infile); if (!Utils.isEmpty(meta.getAltRecordTerm())) { contents .append(" \"STR x'") .append(encodeRecordTerminator(meta.getAltRecordTerm(), meta.getEncoding())) .append("'\""); } contents.append(Const.CR); } contents .append("INTO TABLE ") .append( dm.getQuotedSchemaTableCombination( environmentSubstitute(meta.getSchemaName()), environmentSubstitute(meta.getTableName()))) .append(Const.CR) .append(loadAction) .append(Const.CR) .append("FIELDS TERMINATED BY ',' ENCLOSED BY '\"'") .append(Const.CR) .append("("); String[] streamFields = meta.getFieldStream(); String[] tableFields = meta.getFieldTable(); String[] dateMask = meta.getDateMask(); if (streamFields == null || streamFields.length == 0) { throw new KettleException("No fields defined to load to database"); } for (int i = 0; i < streamFields.length; i++) { if (i != 0) { contents.append(", ").append(Const.CR); } contents.append(dm.quoteField(tableFields[i])); int pos = rm.indexOfValue(streamFields[i]); if (pos < 0) { throw new KettleException("Could not find field " + streamFields[i] + " in stream"); } ValueMetaInterface v = rm.getValueMeta(pos); switch (v.getType()) { case ValueMetaInterface.TYPE_STRING: if (v.getLength() > 255) { contents.append(" CHAR(").append(v.getLength()).append(")"); } else { contents.append(" CHAR"); } break; case ValueMetaInterface.TYPE_INTEGER: case ValueMetaInterface.TYPE_NUMBER: case ValueMetaInterface.TYPE_BIGNUMBER: break; case ValueMetaInterface.TYPE_DATE: if (OraBulkLoaderMeta.DATE_MASK_DATE.equals(dateMask[i])) { contents.append(" DATE 'yyyy-mm-dd'"); } else if (OraBulkLoaderMeta.DATE_MASK_DATETIME.equals(dateMask[i])) { contents.append(" TIMESTAMP 'yyyy-mm-dd hh24:mi:ss.ff'"); } else { // If not specified the default is date. contents.append(" DATE 'yyyy-mm-dd'"); } break; case ValueMetaInterface.TYPE_BINARY: contents.append(" ENCLOSED BY '<startlob>' AND '<endlob>'"); break; case ValueMetaInterface.TYPE_TIMESTAMP: contents.append(" TIMESTAMP 'yyyy-mm-dd hh24:mi:ss.ff'"); break; default: break; } } contents.append(")"); return contents.toString(); }