public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException { if (data.linesWritten >= meta.getDataLines().size()) // no more rows to be written { setOutputDone(); return false; } if (first) { // The output meta is the original input meta + the // additional constant fields. first = false; data.linesWritten = 0; data.outputRowMeta = new RowMeta(); meta.getFields(data.outputRowMeta, getStepname(), null, null, this); // Use these metadata values to convert data... // data.convertMeta = data.outputRowMeta.clone(); for (ValueMetaInterface valueMeta : data.convertMeta.getValueMetaList()) { valueMeta.setType(ValueMetaInterface.TYPE_STRING); } } Object[] outputRowData = RowDataUtil.allocateRowData(data.outputRowMeta.size()); List<String> outputLine = meta.getDataLines().get(data.linesWritten); for (int i = 0; i < data.outputRowMeta.size(); i++) { ValueMetaInterface valueMeta = data.outputRowMeta.getValueMeta(i); ValueMetaInterface convertMeta = data.convertMeta.getValueMeta(i); String valueData = outputLine.get(i); outputRowData[i] = valueMeta.convertDataFromString(valueData, convertMeta, null, null, 0); } putRow(data.outputRowMeta, outputRowData); data.linesWritten++; if (log.isRowLevel()) { log.logRowlevel( toString(), BaseMessages.getString( PKG, "DataGrid.Log.Wrote.Row", Long.toString(getLinesWritten()), data.outputRowMeta.getString(outputRowData))); } if (checkFeedback(getLinesWritten())) { if (log.isBasic()) logBasic( BaseMessages.getString(PKG, "DataGrid.Log.LineNr", Long.toString(getLinesWritten()))); } return true; }
public static final RowMetaAndData buildRow( RowGeneratorMeta meta, List<CheckResultInterface> remarks, String origin) { RowMetaInterface rowMeta = new RowMeta(); Object[] rowData = RowDataUtil.allocateRowData(meta.getFieldName().length); for (int i = 0; i < meta.getFieldName().length; i++) { int valtype = ValueMeta.getType(meta.getFieldType()[i]); if (meta.getFieldName()[i] != null) { ValueMetaInterface valueMeta = new ValueMeta(meta.getFieldName()[i], valtype); // build a value! valueMeta.setLength(meta.getFieldLength()[i]); valueMeta.setPrecision(meta.getFieldPrecision()[i]); valueMeta.setConversionMask(meta.getFieldFormat()[i]); valueMeta.setGroupingSymbol(meta.getGroup()[i]); valueMeta.setDecimalSymbol(meta.getDecimal()[i]); valueMeta.setOrigin(origin); ValueMetaInterface stringMeta = valueMeta.clone(); stringMeta.setType(ValueMetaInterface.TYPE_STRING); String stringValue = meta.getValue()[i]; // If the value is empty: consider it to be NULL. if (Const.isEmpty(stringValue)) { rowData[i] = null; if (valueMeta.getType() == ValueMetaInterface.TYPE_NONE) { String message = BaseMessages.getString( PKG, "RowGenerator.CheckResult.SpecifyTypeError", valueMeta.getName(), stringValue); remarks.add(new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, message, null)); } } else { // Convert the data from String to the specified type ... // try { rowData[i] = valueMeta.convertData(stringMeta, stringValue); } catch (KettleValueException e) { switch (valueMeta.getType()) { case ValueMetaInterface.TYPE_NUMBER: { String message = BaseMessages.getString( PKG, "RowGenerator.BuildRow.Error.Parsing.Number", valueMeta.getName(), stringValue, e.toString()); remarks.add( new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, message, null)); } break; case ValueMetaInterface.TYPE_DATE: { String message = BaseMessages.getString( PKG, "RowGenerator.BuildRow.Error.Parsing.Date", valueMeta.getName(), stringValue, e.toString()); remarks.add( new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, message, null)); } break; case ValueMetaInterface.TYPE_INTEGER: { String message = BaseMessages.getString( PKG, "RowGenerator.BuildRow.Error.Parsing.Integer", valueMeta.getName(), stringValue, e.toString()); remarks.add( new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, message, null)); } break; case ValueMetaInterface.TYPE_BIGNUMBER: { String message = BaseMessages.getString( PKG, "RowGenerator.BuildRow.Error.Parsing.BigNumber", valueMeta.getName(), stringValue, e.toString()); remarks.add( new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, message, null)); } break; default: // Boolean and binary don't throw errors normally, so it's probably an unspecified // error problem... { String message = BaseMessages.getString( PKG, "RowGenerator.CheckResult.SpecifyTypeError", valueMeta.getName(), stringValue); remarks.add( new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, message, null)); } break; } } } // Now add value to the row! // This is in fact a copy from the fields row, but now with data. rowMeta.addValueMeta(valueMeta); } } return new RowMetaAndData(rowMeta, rowData); }
public void getFields( RowMetaInterface rowMeta, String origin, RowMetaInterface[] info, StepMeta nextStep, VariableSpace space) throws KettleStepException { rowMeta.clear(); // Start with a clean slate, eats the input for (int i = 0; i < inputFields.length; i++) { TextFileInputField field = inputFields[i]; ValueMetaInterface valueMeta = new ValueMeta(field.getName(), field.getType()); valueMeta.setConversionMask(field.getFormat()); valueMeta.setLength(field.getLength()); valueMeta.setPrecision(field.getPrecision()); valueMeta.setConversionMask(field.getFormat()); valueMeta.setDecimalSymbol(field.getDecimalSymbol()); valueMeta.setGroupingSymbol(field.getGroupSymbol()); valueMeta.setCurrencySymbol(field.getCurrencySymbol()); valueMeta.setTrimType(field.getTrimType()); if (lazyConversionActive) valueMeta.setStorageType(ValueMetaInterface.STORAGE_TYPE_BINARY_STRING); valueMeta.setStringEncoding(space.environmentSubstitute(encoding)); // In case we want to convert Strings... // Using a copy of the valueMeta object means that the inner and outer representation format // is the same. // Preview will show the data the same way as we read it. // This layout is then taken further down the road by the metadata through the transformation. // ValueMetaInterface storageMetadata = valueMeta.clone(); storageMetadata.setType(ValueMetaInterface.TYPE_STRING); storageMetadata.setStorageType(ValueMetaInterface.STORAGE_TYPE_NORMAL); storageMetadata.setLength( -1, -1); // we don't really know the lengths of the strings read in advance. valueMeta.setStorageMetadata(storageMetadata); valueMeta.setOrigin(origin); rowMeta.addValueMeta(valueMeta); } if (!Const.isEmpty(filenameField) && includingFilename) { ValueMetaInterface filenameMeta = new ValueMeta(filenameField, ValueMetaInterface.TYPE_STRING); filenameMeta.setOrigin(origin); if (lazyConversionActive) { filenameMeta.setStorageType(ValueMetaInterface.STORAGE_TYPE_BINARY_STRING); filenameMeta.setStorageMetadata( new ValueMeta(filenameField, ValueMetaInterface.TYPE_STRING)); } rowMeta.addValueMeta(filenameMeta); } if (!Const.isEmpty(rowNumField)) { ValueMetaInterface rowNumMeta = new ValueMeta(rowNumField, ValueMetaInterface.TYPE_INTEGER); rowNumMeta.setLength(10); rowNumMeta.setOrigin(origin); rowMeta.addValueMeta(rowNumMeta); } }
public void getFields( RowMetaInterface row, String origin, RowMetaInterface[] info, StepMeta nextStep, VariableSpace space) throws KettleStepException { // Row should normally be empty when we get here. // That is because there is no previous step to this mapping input step from the viewpoint of // this single sub-transformation. // From the viewpoint of the transformation that executes the mapping, it's important to know // what comes out at the exit points. // For that reason we need to re-order etc, based on the input specification... // if (inputRowMeta != null && !inputRowMeta.isEmpty()) { // this gets set only in the parent transformation... // It includes all the renames that needed to be done // if (selectingAndSortingUnspecifiedFields) { // First rename any fields... if (valueRenames != null) { for (MappingValueRename valueRename : valueRenames) { ValueMetaInterface valueMeta = inputRowMeta.searchValueMeta(valueRename.getSourceValueName()); if (valueMeta == null) { throw new KettleStepException( BaseMessages.getString( PKG, "MappingInput.Exception.UnableToFindMappedValue", valueRename.getSourceValueName())); } valueMeta.setName(valueRename.getTargetValueName()); } } // Select the specified fields from the input, re-order everything and put the other fields // at the back, sorted... // RowMetaInterface newRow = new RowMeta(); for (int i = 0; i < fieldName.length; i++) { int index = inputRowMeta.indexOfValue(fieldName[i]); if (index < 0) { throw new KettleStepException( BaseMessages.getString( PKG, "MappingInputMeta.Exception.UnknownField", fieldName[i])); } newRow.addValueMeta(inputRowMeta.getValueMeta(index)); } // Now get the unspecified fields. // Sort the fields // Add them after the specified fields... // List<String> extra = new ArrayList<String>(); for (int i = 0; i < inputRowMeta.size(); i++) { String fieldName = inputRowMeta.getValueMeta(i).getName(); if (newRow.indexOfValue(fieldName) < 0) { extra.add(fieldName); } } Collections.sort(extra); for (String fieldName : extra) { ValueMetaInterface extraValue = inputRowMeta.searchValueMeta(fieldName); newRow.addValueMeta(extraValue); } // now merge the new row... // This is basically the input row meta data with the fields re-ordered. // row.mergeRowMeta(newRow); } else { row.mergeRowMeta(inputRowMeta); // Validate the existence of all the specified fields... // if (!row.isEmpty()) { for (int i = 0; i < fieldName.length; i++) { if (row.indexOfValue(fieldName[i]) < 0) { throw new KettleStepException( BaseMessages.getString( PKG, "MappingInputMeta.Exception.UnknownField", fieldName[i])); } } } } } else { // We'll have to work with the statically provided information for (int i = 0; i < fieldName.length; i++) { if (!Const.isEmpty(fieldName[i])) { ValueMetaInterface v = new ValueMeta(fieldName[i], fieldType[i]); if (v.getType() == ValueMetaInterface.TYPE_NONE) v.setType(ValueMetaInterface.TYPE_STRING); v.setLength(fieldLength[i]); v.setPrecision(fieldPrecision[i]); v.setOrigin(origin); row.addValueMeta(v); } } } }
private ValueMetaInterface getValueMeta(CalculatorMetaFunction fn, String origin) { ValueMetaInterface v = new ValueMeta(fn.getFieldName(), fn.getValueType()); v.setLength(fn.getValueLength()); v.setPrecision(fn.getValuePrecision()); v.setOrigin(origin); v.setComments(fn.getCalcTypeDesc()); v.setConversionMask(fn.getConversionMask()); v.setDecimalSymbol(fn.getDecimalSymbol()); v.setGroupingSymbol(fn.getGroupingSymbol()); v.setCurrencySymbol(fn.getCurrencySymbol()); // What if the user didn't specify a data type? // In that case we look for the default data type // if (fn.getValueType() == ValueMetaInterface.TYPE_NONE) { int defaultResultType = ValueMetaInterface.TYPE_NONE; switch (fn.getCalcType()) { case CalculatorMetaFunction.CALC_NONE: break; case CalculatorMetaFunction.CALC_ADD: // A + B defaultResultType = ValueMetaInterface.TYPE_NUMBER; break; case CalculatorMetaFunction.CALC_SUBTRACT: // A - B defaultResultType = ValueMetaInterface.TYPE_NUMBER; break; case CalculatorMetaFunction.CALC_MULTIPLY: // A * B defaultResultType = ValueMetaInterface.TYPE_NUMBER; break; case CalculatorMetaFunction.CALC_DIVIDE: // A / B defaultResultType = ValueMetaInterface.TYPE_NUMBER; break; case CalculatorMetaFunction.CALC_SQUARE: // A * A defaultResultType = ValueMetaInterface.TYPE_NUMBER; break; case CalculatorMetaFunction.CALC_SQUARE_ROOT: // SQRT( A ) defaultResultType = ValueMetaInterface.TYPE_NUMBER; break; case CalculatorMetaFunction.CALC_PERCENT_1: // 100 * A / B defaultResultType = ValueMetaInterface.TYPE_NUMBER; break; case CalculatorMetaFunction.CALC_PERCENT_2: // A - ( A * B / 100 ) defaultResultType = ValueMetaInterface.TYPE_NUMBER; break; case CalculatorMetaFunction.CALC_PERCENT_3: // A + ( A * B / 100 ) defaultResultType = ValueMetaInterface.TYPE_NUMBER; break; case CalculatorMetaFunction.CALC_COMBINATION_1: // A + B * C defaultResultType = ValueMetaInterface.TYPE_NUMBER; break; case CalculatorMetaFunction.CALC_COMBINATION_2: // SQRT( A*A + B*B ) defaultResultType = ValueMetaInterface.TYPE_NUMBER; break; case CalculatorMetaFunction.CALC_ROUND_1: // ROUND( A ) defaultResultType = ValueMetaInterface.TYPE_INTEGER; break; case CalculatorMetaFunction.CALC_ROUND_2: // ROUND( A , B ) defaultResultType = ValueMetaInterface.TYPE_NUMBER; break; case CalculatorMetaFunction.CALC_CONSTANT: // Set field to constant value... defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_NVL: // Replace null values with another value break; case CalculatorMetaFunction.CALC_ADD_DAYS: // Add B days to date field A defaultResultType = ValueMetaInterface.TYPE_DATE; break; case CalculatorMetaFunction.CALC_YEAR_OF_DATE: // What is the year (Integer) of a date? defaultResultType = ValueMetaInterface.TYPE_INTEGER; break; case CalculatorMetaFunction.CALC_MONTH_OF_DATE: // What is the month (Integer) of a date? defaultResultType = ValueMetaInterface.TYPE_INTEGER; break; case CalculatorMetaFunction .CALC_DAY_OF_YEAR: // What is the day of year (Integer) of a date? defaultResultType = ValueMetaInterface.TYPE_INTEGER; break; case CalculatorMetaFunction .CALC_DAY_OF_MONTH: // What is the day of month (Integer) of a date? defaultResultType = ValueMetaInterface.TYPE_INTEGER; break; case CalculatorMetaFunction .CALC_DAY_OF_WEEK: // What is the day of week (Integer) of a date? defaultResultType = ValueMetaInterface.TYPE_INTEGER; break; case CalculatorMetaFunction .CALC_WEEK_OF_YEAR: // What is the week of year (Integer) of a date? defaultResultType = ValueMetaInterface.TYPE_INTEGER; break; case CalculatorMetaFunction .CALC_WEEK_OF_YEAR_ISO8601: // What is the week of year (Integer) of a date ISO8601 // style? defaultResultType = ValueMetaInterface.TYPE_INTEGER; break; case CalculatorMetaFunction .CALC_YEAR_OF_DATE_ISO8601: // What is the year (Integer) of a date ISO8601 style? defaultResultType = ValueMetaInterface.TYPE_INTEGER; break; case CalculatorMetaFunction.CALC_BYTE_TO_HEX_ENCODE: // Byte to Hex encode string field A defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_HEX_TO_BYTE_DECODE: // Hex to Byte decode string field A defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_CHAR_TO_HEX_ENCODE: // Char to Hex encode string field A defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_HEX_TO_CHAR_DECODE: // Hex to Char decode string field A defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_CRC32: // CRC32 of a file A defaultResultType = ValueMetaInterface.TYPE_INTEGER; break; case CalculatorMetaFunction.CALC_ADLER32: // ADLER32 of a file A defaultResultType = ValueMetaInterface.TYPE_INTEGER; break; case CalculatorMetaFunction.CALC_MD5: // MD5 of a file A defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_SHA1: // SHA1 of a file Al defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction .CALC_LEVENSHTEIN_DISTANCE: // LEVENSHTEIN_DISTANCE of string A and string B defaultResultType = ValueMetaInterface.TYPE_INTEGER; break; case CalculatorMetaFunction.CALC_METAPHONE: // METAPHONE of string A defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_DOUBLE_METAPHONE: // Double METAPHONE of string A defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_ABS: // ABS( A ) defaultResultType = ValueMetaInterface.TYPE_INTEGER; break; case CalculatorMetaFunction.CALC_REMOVE_TIME_FROM_DATE: // Remove time from field A defaultResultType = ValueMetaInterface.TYPE_DATE; break; case CalculatorMetaFunction.CALC_DATE_DIFF: // DateA - DateB defaultResultType = ValueMetaInterface.TYPE_INTEGER; break; case CalculatorMetaFunction.CALC_ADD3: // A + B +C defaultResultType = ValueMetaInterface.TYPE_NUMBER; break; case CalculatorMetaFunction.CALC_INITCAP: // InitCap(A) defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_UPPER_CASE: // UpperCase(A) defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_LOWER_CASE: // LowerCase(A) defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_MASK_XML: // MaskXML(A) defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_USE_CDATA: // CDATA(A) defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_REMOVE_CR: // REMOVE CR FROM string A defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_REMOVE_LF: // REMOVE LF FROM string A defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_REMOVE_CRLF: // REMOVE CRLF FROM string A defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_REMOVE_TAB: // REMOVE TAB FROM string A defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_GET_ONLY_DIGITS: // GET ONLY DIGITS FROM string A defaultResultType = ValueMetaInterface.TYPE_INTEGER; break; case CalculatorMetaFunction.CALC_REMOVE_DIGITS: // REMOVE DIGITS FROM string A defaultResultType = ValueMetaInterface.TYPE_STRING; break; case CalculatorMetaFunction.CALC_STRING_LEN: // LENGTH OF string A defaultResultType = ValueMetaInterface.TYPE_INTEGER; break; case CalculatorMetaFunction.CALC_LOAD_FILE_CONTENT_BINARY: // LOAD FILE CONTENT IN BLOB defaultResultType = ValueMetaInterface.TYPE_BINARY; break; case CalculatorMetaFunction.CALC_ADD_TIME_TO_DATE: // ADD TIME TO A DATE defaultResultType = ValueMetaInterface.TYPE_DATE; break; case CalculatorMetaFunction.CALC_GEOM_UNION: // Calculate geometry union defaultResultType = ValueMetaInterface.TYPE_GEOMETRY; break; case CalculatorMetaFunction.CALC_GEOM_INTERSECTION: // Calculate geometry intersection defaultResultType = ValueMetaInterface.TYPE_GEOMETRY; break; case CalculatorMetaFunction.CALC_GEOM_DIFFERENCE: // Calculate geometry difference defaultResultType = ValueMetaInterface.TYPE_GEOMETRY; break; case CalculatorMetaFunction .CALC_GEOM_SYMETRIC_DIFFERENCE: // Calculate geometry symetric difference defaultResultType = ValueMetaInterface.TYPE_GEOMETRY; break; case CalculatorMetaFunction.CALC_GEOM_AREA: // Calculate area defaultResultType = ValueMetaInterface.TYPE_NUMBER; break; case CalculatorMetaFunction.CALC_GEOM_LENGTH: // Calculate length defaultResultType = ValueMetaInterface.TYPE_NUMBER; break; case CalculatorMetaFunction.CALC_GEOM_CENTROID: // Calculate centroid defaultResultType = ValueMetaInterface.TYPE_GEOMETRY; break; case CalculatorMetaFunction.CALC_GEOM_POINT_ON_SURFACE: // Calculate random point on surface defaultResultType = ValueMetaInterface.TYPE_GEOMETRY; break; case CalculatorMetaFunction.CALC_GEOM_REVERSE: // Reverse geometry defaultResultType = ValueMetaInterface.TYPE_GEOMETRY; break; case CalculatorMetaFunction.CALC_GEOM_BOUNDARY: // Calculate geometry boundary defaultResultType = ValueMetaInterface.TYPE_GEOMETRY; break; case CalculatorMetaFunction.CALC_GEOM_ENVELOPE: // Calculate geometry envelope defaultResultType = ValueMetaInterface.TYPE_GEOMETRY; break; case CalculatorMetaFunction.CALC_GEOM_CONVEX_HULL: // Calculate geometry convex hull defaultResultType = ValueMetaInterface.TYPE_GEOMETRY; break; case CalculatorMetaFunction.CALC_GEOM_BUFFER: // Calculate geometry buffer defaultResultType = ValueMetaInterface.TYPE_GEOMETRY; break; case CalculatorMetaFunction.CALC_GEOM_DISTANCE: // Calculate distance between geometries defaultResultType = ValueMetaInterface.TYPE_NUMBER; break; default: break; } v.setType(defaultResultType); } return v; }
public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException { meta = (DatabaseLookupMeta) smi; data = (DatabaseLookupData) sdi; boolean sendToErrorRow = false; String errorMessage = null; Object[] r = getRow(); // Get row from input rowset & set row busy! if (r == null) // no more input to be expected... { setOutputDone(); return false; } if (first) { first = false; // create the output metadata data.outputRowMeta = getInputRowMeta().clone(); meta.getFields(data.outputRowMeta, getStepname(), null, null, this); if (meta.isCached()) { if (meta.getCacheSize() > 0) { data.look = new Hashtable<RowMetaAndData, TimedRow>((int) (meta.getCacheSize() * 1.5)); } else { data.look = new Hashtable<RowMetaAndData, TimedRow>(); } } data.db.setLookup( environmentSubstitute(meta.getSchemaName()), environmentSubstitute(meta.getTablename()), meta.getTableKeyField(), meta.getKeyCondition(), meta.getReturnValueField(), meta.getReturnValueNewName(), meta.getOrderByClause(), meta.isFailingOnMultipleResults()); // lookup the values! if (log.isDetailed()) logDetailed( BaseMessages.getString(PKG, "DatabaseLookup.Log.CheckingRow") + getInputRowMeta().getString(r)); // $NON-NLS-1$ data.keynrs = new int[meta.getStreamKeyField1().length]; data.keynrs2 = new int[meta.getStreamKeyField1().length]; for (int i = 0; i < meta.getStreamKeyField1().length; i++) { data.keynrs[i] = getInputRowMeta().indexOfValue(meta.getStreamKeyField1()[i]); if (data.keynrs[i] < 0 && // couldn't find field! !"IS NULL".equalsIgnoreCase(meta.getKeyCondition()[i]) && // No field needed! //$NON-NLS-1$ !"IS NOT NULL" .equalsIgnoreCase(meta.getKeyCondition()[i]) // No field needed! //$NON-NLS-1$ ) { throw new KettleStepException( BaseMessages.getString(PKG, "DatabaseLookup.ERROR0001.FieldRequired1.Exception") + meta.getStreamKeyField1()[i] + BaseMessages.getString( PKG, "DatabaseLookup.ERROR0001.FieldRequired2.Exception")); //$NON-NLS-1$ // //$NON-NLS-2$ } data.keynrs2[i] = getInputRowMeta().indexOfValue(meta.getStreamKeyField2()[i]); if (data.keynrs2[i] < 0 && // couldn't find field! "BETWEEN".equalsIgnoreCase(meta.getKeyCondition()[i]) // 2 fields needed! //$NON-NLS-1$ ) { throw new KettleStepException( BaseMessages.getString(PKG, "DatabaseLookup.ERROR0001.FieldRequired3.Exception") + meta.getStreamKeyField2()[i] + BaseMessages.getString( PKG, "DatabaseLookup.ERROR0001.FieldRequired4.Exception")); //$NON-NLS-1$ // //$NON-NLS-2$ } if (log.isDebug()) logDebug( BaseMessages.getString(PKG, "DatabaseLookup.Log.FieldHasIndex1") + meta.getStreamKeyField1()[i] + BaseMessages.getString(PKG, "DatabaseLookup.Log.FieldHasIndex2") + data.keynrs[i]); // $NON-NLS-1$ //$NON-NLS-2$ } data.nullif = new Object[meta.getReturnValueField().length]; for (int i = 0; i < meta.getReturnValueField().length; i++) { ValueMetaInterface stringMeta = new ValueMeta("string", ValueMetaInterface.TYPE_STRING); ValueMetaInterface returnMeta = data.outputRowMeta.getValueMeta(i + getInputRowMeta().size()); if (!Const.isEmpty(meta.getReturnValueDefault()[i])) { data.nullif[i] = returnMeta.convertData(stringMeta, meta.getReturnValueDefault()[i]); } else { data.nullif[i] = null; ; } } // Determine the types... data.keytypes = new int[meta.getTableKeyField().length]; String schemaTable = meta.getDatabaseMeta() .getQuotedSchemaTableCombination( environmentSubstitute(meta.getSchemaName()), environmentSubstitute(meta.getTablename())); RowMetaInterface fields = data.db.getTableFields(schemaTable); if (fields != null) { // Fill in the types... for (int i = 0; i < meta.getTableKeyField().length; i++) { ValueMetaInterface key = fields.searchValueMeta(meta.getTableKeyField()[i]); if (key != null) { data.keytypes[i] = key.getType(); } else { throw new KettleStepException( BaseMessages.getString(PKG, "DatabaseLookup.ERROR0001.FieldRequired5.Exception") + meta.getTableKeyField()[i] + BaseMessages.getString( PKG, "DatabaseLookup.ERROR0001.FieldRequired6.Exception")); //$NON-NLS-1$ // //$NON-NLS-2$ } } } else { throw new KettleStepException( BaseMessages.getString(PKG, "DatabaseLookup.ERROR0002.UnableToDetermineFieldsOfTable") + schemaTable + "]"); //$NON-NLS-1$ //$NON-NLS-2$ } // Count the number of values in the lookup as well as the metadata to send along with it. // data.lookupMeta = new RowMeta(); for (int i = 0; i < meta.getStreamKeyField1().length; i++) { if (data.keynrs[i] >= 0) { ValueMetaInterface value = getInputRowMeta().getValueMeta(data.keynrs[i]).clone(); // Try to convert type if needed in a clone, we don't want to // change the type in the original row value.setType(data.keytypes[i]); data.lookupMeta.addValueMeta(value); } if (data.keynrs2[i] >= 0) { ValueMetaInterface value = getInputRowMeta().getValueMeta(data.keynrs2[i]).clone(); // Try to convert type if needed in a clone, we don't want to // change the type in the original row value.setType(data.keytypes[i]); data.lookupMeta.addValueMeta(value); } } // We also want to know the metadata of the return values beforehand (null handling) data.returnMeta = new RowMeta(); for (int i = 0; i < meta.getReturnValueField().length; i++) { ValueMetaInterface v = data.outputRowMeta.getValueMeta(getInputRowMeta().size() + i).clone(); data.returnMeta.addValueMeta(v); } // If the user selected to load all data into the cache at startup, that's what we do now... // if (meta.isCached() && meta.isLoadingAllDataInCache()) { loadAllTableDataIntoTheCache(); } } if (log.isRowLevel()) logRowlevel( BaseMessages.getString(PKG, "DatabaseLookup.Log.GotRowFromPreviousStep") + getInputRowMeta().getString(r)); // $NON-NLS-1$ try { // add new lookup values to the row Object[] outputRow = lookupValues(getInputRowMeta(), r); if (outputRow != null) { // copy row to output rowset(s); putRow(data.outputRowMeta, outputRow); if (log.isRowLevel()) logRowlevel( BaseMessages.getString(PKG, "DatabaseLookup.Log.WroteRowToNextStep") + getInputRowMeta().getString(r)); // $NON-NLS-1$ if (checkFeedback(getLinesRead())) logBasic("linenr " + getLinesRead()); // $NON-NLS-1$ } } catch (KettleException e) { if (getStepMeta().isDoingErrorHandling()) { sendToErrorRow = true; errorMessage = e.toString(); } else { logError( BaseMessages.getString(PKG, "DatabaseLookup.ERROR003.UnexpectedErrorDuringProcessing") + e.getMessage()); // $NON-NLS-1$ setErrors(1); stopAll(); setOutputDone(); // signal end to receiver(s) return false; } if (sendToErrorRow) { // Simply add this row to the error row putError(getInputRowMeta(), r, 1, errorMessage, null, "DBLOOKUPD001"); } } return true; }