public boolean init(StepMetaInterface smi, StepDataInterface sdi) { meta = (DatabaseLookupMeta) smi; data = (DatabaseLookupData) sdi; if (super.init(smi, sdi)) { if (meta.getDatabaseMeta() == null) { logError( BaseMessages.getString(PKG, "DatabaseLookup.Init.ConnectionMissing", getStepname())); return false; } data.db = new Database(this, meta.getDatabaseMeta()); data.db.shareVariablesWith(this); try { if (getTransMeta().isUsingUniqueConnections()) { synchronized (getTrans()) { data.db.connect(getTrans().getTransactionId(), getPartitionID()); } } else { data.db.connect(getPartitionID()); } data.db.setCommit(100); // we never get a commit, but it just turns off auto-commit. if (log.isDetailed()) { logDetailed(BaseMessages.getString(PKG, "DatabaseLookup.Log.ConnectedToDatabase")); } // See if all the lookup conditions are "equal" // This might speed up things in the case when we load all data in the cache // data.allEquals = true; data.hasDBCondition = false; data.conditions = new int[meta.getKeyCondition().length]; for (int i = 0; i < meta.getKeyCondition().length; i++) { data.conditions[i] = Const.indexOfString(meta.getKeyCondition()[i], DatabaseLookupMeta.conditionStrings); if (!("=".equals(meta.getKeyCondition()[i]))) { data.allEquals = false; } if (data.conditions[i] == DatabaseLookupMeta.CONDITION_LIKE) { data.hasDBCondition = true; } } return true; } catch (Exception e) { logError( BaseMessages.getString(PKG, "DatabaseLookup.ERROR0004.UnexpectedErrorDuringInit") + e.toString()); if (data.db != null) { data.db.disconnect(); } } } return false; }
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; }