/*****************************************************************************
* Copyright 2013 celum Slovakia s r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 com.celum.dbtool.resource;
import com.celum.dbtool.installer.DbVars;
import com.celum.dbtool.installer.VelocityInterceptor;
import com.celum.dbtool.step.DbStep;
import javax.sql.DataSource;
import java.sql.Connection;
import java.util.*;
import static com.celum.nyx.Sql.*;
/**
* Decorator for {@link DbStepResource resource} which filter
* and returns only these patches, which was not applied yet.
*
* The mechanism is based on version table where is not only one
* value that indicates current version but it's based on
* table where is list of all applied patches. This filter then
* returns only patches they're missing in this table.
*
*/
public class AppliedPatchesFiter extends DbStepResource
{
/** referring to real resource */
private final DbStepResource decoratedResource;
/** DB connection */
private final DataSource dataSource;
/** precondition SQL which checking whether patch was applied */
private final String preconditionSql;
/** holds additional variables you could use in preconditionSql */
private final Map<String, Object> variables;
/**
* Constructor
*/
public AppliedPatchesFiter(DbStepResource decoratedResource, DataSource dataSource, String preconditionSql)
{
this(decoratedResource, dataSource, preconditionSql, new HashMap<String, Object>());
}
/**
* Constructor
*/
public AppliedPatchesFiter(DbStepResource decoratedResource, DataSource dataSource, String preconditionSql, Map<String, Object> variables)
{
this.variables = variables;
this.decoratedResource = decoratedResource;
this.dataSource = dataSource;
this.preconditionSql = preconditionSql;
}
/**
* {@inheritDoc}
* @return
*/
@Override
public List<DbStep> getSteps()
{
List<DbStep> res = decoratedResource.getSteps();
List<DbStep> output = new LinkedList<DbStep>();
for (DbStep step : res) {
if (stepIsNotApplied(step)) {
output.add(step);
}
}
return output;
}
/**
* Method executes the precondition select and check whether step has
* been applied or not.
*
* @param step
* @return true if step is missing, false if step has been applied
*/
private boolean stepIsNotApplied(DbStep step)
{
Map<String, Object> args = new HashMap<String, Object>();
args.put(DbVars.PATCH_VERSION, step.getVersion());
args.put(DbVars.PATCH_NAME, step.getName());
args.putAll(variables);
long existence =
sql(preconditionSql)
.interceptWith(new VelocityInterceptor(args))
.on(dataSource)
.runQuery().andReturnLong(-1);
return existence <= 0;
}
}