@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++;
   }
 }
Example #2
0
  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;
  }