/**
* Licensed to JumpMind Inc under one or more contributor
* license agreements. See the NOTICE file distributed
* with this work for additional information regarding
* copyright ownership. JumpMind Inc licenses this file
* to you under the GNU General Public License, version 3.0 (GPLv3)
* (the "License"); you may not use this file except in compliance
* with the License.
*
* You should have received a copy of the GNU General Public License,
* version 3.0 (GPLv3) along with this library; if not, see
* <http://www.gnu.org/licenses/>.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jumpmind.symmetric.io.data.transform;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.jumpmind.db.model.Column;
import org.jumpmind.db.model.Table;
import org.jumpmind.db.platform.IDatabasePlatform;
import org.jumpmind.db.sql.ISqlTransaction;
import org.jumpmind.extension.IBuiltInExtensionPoint;
import org.jumpmind.symmetric.io.data.DataContext;
import org.jumpmind.symmetric.io.data.DataEventType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AdditiveColumnTransform implements ISingleValueColumnTransform, IBuiltInExtensionPoint {
static final Logger log = LoggerFactory.getLogger(AdditiveColumnTransform.class);
public static final String NAME = "additive";
public String getName() {
return NAME;
}
public boolean isExtractColumnTransform() {
return false;
}
public boolean isLoadColumnTransform() {
return true;
}
public String getFullyQualifiedTableName(IDatabasePlatform platform, String schema, String catalog, String tableName) {
String quote = platform.getDdlBuilder().isDelimitedIdentifierModeOn() ? platform
.getDatabaseInfo().getDelimiterToken() : "";
tableName = quote + tableName + quote;
if (!StringUtils.isBlank(schema)) {
tableName = schema + "." + tableName;
}
if (!StringUtils.isBlank(catalog)) {
tableName = catalog + "." + tableName;
}
return tableName;
}
public String transform(IDatabasePlatform platform, DataContext context,
TransformColumn column, TransformedData data, Map<String, String> sourceValues, String newValue, String oldValue) throws IgnoreColumnException,
IgnoreRowException {
BigDecimal multiplier = new BigDecimal(1.00);
if (StringUtils.isNotBlank(column.getTransformExpression())) {
multiplier = new BigDecimal(column.getTransformExpression());
}
Table table = platform.getTableFromCache(data.getCatalogName(), data.getSchemaName(),
data.getTableName(), false);
if (table == null) {
if (log.isDebugEnabled()) {
log.debug("Could not find the target table {}" , data.getFullyQualifiedTableName());
}
throw new IgnoreColumnException();
} else if (table.getColumnWithName(column.getTargetColumnName()) == null) {
if (log.isDebugEnabled()) {
log.debug("Could not find the target column {}" , column.getTargetColumnName());
}
throw new IgnoreColumnException();
} else {
if (log.isDebugEnabled()) {
log.debug("Old, new, transform expression as received: "+oldValue+", "+newValue+", "+column.getTransformExpression());
}
if (!StringUtils.isNotBlank(newValue) ||
data.getSourceDmlType() == DataEventType.DELETE) {
newValue="0";
}
if (!StringUtils.isNotBlank(oldValue)) {
oldValue="0";
}
BigDecimal delta = new BigDecimal(newValue);
delta = delta.subtract(new BigDecimal(oldValue));
delta = delta.multiply(multiplier);
newValue = delta.toString();
String quote = platform.getDdlBuilder().isDelimitedIdentifierModeOn() ? platform
.getDatabaseInfo().getDelimiterToken() : "";
StringBuilder sql = new StringBuilder(String.format("update %s set %s=%s+(%s) where ",
getFullyQualifiedTableName(platform, data.getSchemaName(), data.getCatalogName(), data.getTableName()),
quote + column.getTargetColumnName() + quote,
quote + column.getTargetColumnName() + quote,
newValue));
String[] keyNames = data.getKeyNames();
List<Column> columns = new ArrayList<Column>();
List<String> keyValuesList = new ArrayList<String>();
boolean addedFirstKey = false;
for (int i = 0; i < keyNames.length; i++) {
Column targetCol = table.getColumnWithName(keyNames[i]);
if (targetCol != null) {
columns.add(targetCol);
keyValuesList.add(sourceValues.get(keyNames[i]));
if (addedFirstKey) {
sql.append("and ");
} else {
addedFirstKey = true;
}
sql.append(quote);
sql.append(keyNames[i]);
sql.append(quote);
sql.append("=? ");
}
}
if (log.isDebugEnabled()) {
log.debug("SQL: "+sql);
}
ISqlTransaction transaction = context.findTransaction();
if (0 < transaction.prepareAndExecute(
sql.toString(),
platform.getObjectValues(context.getBatch().getBinaryEncoding(),
keyValuesList.toArray(new String[keyValuesList.size()]),
columns.toArray(new Column[columns.size()])))) {
throw new IgnoreColumnException();
}
}
return newValue;
}
}