@Override public void rowWrittenEvent(RowMetaInterface rowMeta, Object[] row) throws KettleStepException { if (rowNbr >= data.length) { throw new ComparisonFailure("too many output rows", "" + data.length, "" + rowNbr + 1); } else { for (int i = 0; i < data[rowNbr].length; i++) { try { boolean eq = true; if (comparators.containsKey(i)) { Comparison<Object> comp = comparators.get(i); if (comp != null) { eq = comp.equals(data[rowNbr][i], row[i]); } } else { ValueMetaInterface valueMeta = rowMeta.getValueMeta(i); eq = valueMeta.compare(data[rowNbr][i], row[i]) == 0; } if (!eq) { throw new ComparisonFailure( String.format("Mismatch row %d, column %d", rowNbr, i), rowMeta.getString(data[rowNbr]), rowMeta.getString(row)); } } catch (Exception e) { throw new AssertionError( String.format("Value type at row %d, column %d", rowNbr, i), e); } } rowNbr++; } }
private Object[] getRowFromCache(RowMetaInterface lookupMeta, Object[] lookupRow) throws KettleException { if (data.allEquals) { // only do the hashtable lookup when all equals otherwise conditions >, <, <> will give wrong // results TimedRow timedRow = data.look.get(new RowMetaAndData(data.lookupMeta, lookupRow)); if (timedRow != null) { return timedRow.getRow(); } } else { // special handling of conditions <,>, <> etc. if (!data.hasDBCondition) { // e.g. LIKE not handled by this routine, yet // TODO: find an alternative way to look up the data based on the condition. // Not all conditions are "=" so we are going to have to evaluate row by row // A sorted list or index might be a good solution here... // Enumeration<RowMetaAndData> keys = data.look.keys(); while (keys.hasMoreElements()) { RowMetaAndData key = keys.nextElement(); // Now verify that the key is matching our conditions... // boolean match = true; int lookupIndex = 0; for (int i = 0; i < data.conditions.length && match; i++) { ValueMetaInterface cmpMeta = lookupMeta.getValueMeta(lookupIndex); Object cmpData = lookupRow[lookupIndex]; ValueMetaInterface keyMeta = key.getValueMeta(i); Object keyData = key.getData()[i]; switch (data.conditions[i]) { case DatabaseLookupMeta.CONDITION_EQ: match = (cmpMeta.compare(cmpData, keyMeta, keyData) == 0); break; case DatabaseLookupMeta.CONDITION_NE: match = (cmpMeta.compare(cmpData, keyMeta, keyData) != 0); break; case DatabaseLookupMeta.CONDITION_LT: match = (cmpMeta.compare(cmpData, keyMeta, keyData) > 0); break; case DatabaseLookupMeta.CONDITION_LE: match = (cmpMeta.compare(cmpData, keyMeta, keyData) >= 0); break; case DatabaseLookupMeta.CONDITION_GT: match = (cmpMeta.compare(cmpData, keyMeta, keyData) < 0); break; case DatabaseLookupMeta.CONDITION_GE: match = (cmpMeta.compare(cmpData, keyMeta, keyData) <= 0); break; case DatabaseLookupMeta.CONDITION_IS_NULL: match = keyMeta.isNull(keyData); break; case DatabaseLookupMeta.CONDITION_IS_NOT_NULL: match = !keyMeta.isNull(keyData); break; case DatabaseLookupMeta.CONDITION_BETWEEN: // Between key >= cmp && key <= cmp2 ValueMetaInterface cmpMeta2 = lookupMeta.getValueMeta(lookupIndex + 1); Object cmpData2 = lookupRow[lookupIndex + 1]; match = (keyMeta.compare(keyData, cmpMeta, cmpData) >= 0); if (match) { match = (keyMeta.compare(keyData, cmpMeta2, cmpData2) <= 0); } lookupIndex++; break; // TODO: add LIKE operator (think of changing the hasDBCondition logic then) default: match = false; data.hasDBCondition = true; // avoid looping in here the next time, also safety when a new condition // will be introduced break; } lookupIndex++; } if (match) { TimedRow timedRow = data.look.get(key); if (timedRow != null) { return timedRow.getRow(); } } } } } return null; }