/**
* Copyright (C) 2001-2006 France Telecom R&D
*/
package org.objectweb.speedo.query.jdo;
import org.objectweb.jorm.metainfo.api.Manager;
import org.objectweb.medor.api.EvaluationException;
import org.objectweb.medor.api.MedorException;
import org.objectweb.medor.eval.api.ConnectionResources;
import org.objectweb.medor.eval.api.QueryEvaluator;
import org.objectweb.medor.eval.lib.DeleteEvaluator;
import org.objectweb.medor.expression.api.ExpressionException;
import org.objectweb.medor.expression.api.ParameterOperand;
import org.objectweb.medor.query.api.QueryLeaf;
import org.objectweb.medor.query.api.QueryTree;
import org.objectweb.medor.query.jorm.lib.QueryBuilder;
import org.objectweb.medor.query.lib.QueryTreePrinter;
import org.objectweb.medor.query.lib.SelectProject;
import org.objectweb.medor.tuple.api.TupleCollection;
import org.objectweb.speedo.api.ExceptionHelper;
import org.objectweb.speedo.api.SpeedoException;
import org.objectweb.speedo.pm.jdo.api.JDOPOManagerItf;
import org.objectweb.speedo.query.api.QueryDefinition;
import org.objectweb.speedo.query.jdo.parser.ASTSpeedoQL;
import org.objectweb.speedo.query.jdo.parser.ParseException;
import org.objectweb.speedo.query.jdo.parser.SelectGroupByVisitor;
import org.objectweb.speedo.query.jdo.parser.SimpleNode;
import org.objectweb.speedo.query.jdo.parser.SpeedoQL;
import org.objectweb.speedo.query.jdo.parser.SpeedoQLQueryFilterVisitor;
import org.objectweb.speedo.query.jdo.parser.SpeedoQLVariableVisitor;
import org.objectweb.speedo.workingset.api.TransactionItf;
import org.objectweb.util.monolog.api.BasicLevel;
import java.io.CharArrayReader;
import java.util.Map;
import javax.jdo.JDOFatalException;
public class JDOCompiledDeleteQuery extends JDOAbstractCompiledQuery {
QueryTree optimizedQT;
QueryEvaluator evaluator;
public synchronized void compile() throws SpeedoException, MedorException, ExpressionException {
if (status == UNDEFINED)
throw new SpeedoException("Impossible to compile an undefined query");
if (status == COMPILED)
return;
long timeToCompile = System.currentTimeMillis();
boolean debug = logger.isLoggable(BasicLevel.DEBUG);
// create a speedoQL object with a filter string
String filter = qd.filter;
filter = '(' + filter + ')';
// create representations of the parameters list and the variable
// list
toHashtableParams(qd.parameters, ";,");
toHashtableVars(qd.variables, ";,");
Manager miManager = mapper.getMetaInfoManager();
if (miManager == null)
throw new SpeedoException(
"A non null Meta information manager is needed");
try {
jf.getPClassMapping(
qd.candidateClass.getName(),
classLoader);
} catch (Exception e) {
throw new SpeedoException(e);
}
SimpleNode node = null;
try {
node = new SpeedoQL(new CharArrayReader(filter.toCharArray())).SpeedoQL();
} catch (ParseException e) {
throw new SpeedoException(
"Impossible to parse the filter and to create AST", e);
}
SpeedoQLVariableVisitor sqvv = new SpeedoQLVariableVisitor(
node, miManager, varParserlogger, hparams, hvars, qd.order,
qd.candidateClass.getName(), qd.includeSubClasses);
// start the variable visitor to catch all variables and build a
// first tree of them without collection navigation
Map fields = sqvv.getFields();
QueryBuilder qb = sqvv.getQueryBuilder();
QueryTree qt = sqvv.getQueryTree();
SelectProject sp = new SelectProject("");
if (!filter.equals("(true)") && !filter.equals("true")) {
//Ther is a filter and potentialy collection navigation
if (debug) {
logger.log(BasicLevel.DEBUG, "filter = " + qd.filter);
}
// start the query filter visitor, to build and expression tree of
// the filter expression
SpeedoQLQueryFilterVisitor sqfv = new SpeedoQLQueryFilterVisitor(
fields, sp, (ASTSpeedoQL) node,
filterParserLogger, hparams, hvars,
qd.candidateClass,
qb, jf);
sp.setQueryFilter(sqfv.getQueryFilter());
}
assignMapper(sp);
assignMapper(qt);
SelectGroupByVisitor sgv = new SelectGroupByVisitor(sp, qt, sqvv, classLoader);
sgv.visit(qd);
assignMapper(sp);
logger.log(BasicLevel.INFO, "QueryTree built");
if (debug) {
QueryTreePrinter.printQueryTree(sp, logger);
}
// Optimize the queryTree
optimizedQT = optimize(sp, debug);
// Creates an evaluator associated to the QueryTree
evaluator = new DeleteEvaluator(optimizedQT);
timeToCompile = System.currentTimeMillis() - timeToCompile;
status = COMPILED;
logger.log(BasicLevel.INFO, "Query compiled in " + timeToCompile + "ms");
}
/**
* executes a the current delete query, and returns a Long object
* corresponding to the number of delete instances
*/
protected Object executeQT(JDOPOManagerItf pm, ParameterOperand[] pos, QueryDefinition userqd)
throws EvaluationException, MedorException, SpeedoException {
flushCache(pm);
Object connection = ((TransactionItf) pm.currentTransaction())
.getConnectionHolder();
ConnectionResources connRess =
evaluator.getRequiredConnectionResources();
// Gets the QueryLeafs that require connections
QueryLeaf[] leafs = connRess.getRequiredQueryLeafConnection();
// Setting QueryLeaf's appropriated connection Object
for (int cpt = 0; (cpt < leafs.length); cpt++) {
connRess.setConnection(leafs[cpt], connection);
}
TupleCollection queryResult = null;
try {
queryResult = evaluator.evaluate(pos, connRess, null);
} catch (EvaluationException e) {
throw new JDOFatalException(
"Impossible to evaluate the query: ",
ExceptionHelper.getNested(e)
);
}
return new JDOQueryResultUnique(
queryResult,
pm,
new Object[]{connection},
null,
new Class[]{Long.class},
true,
false,
logger).getResult();
}
}