Index: topia/src/java/org/codelutin/topia/persistence/topia/TopiaJDBCQueryHelper.java diff -u /dev/null topia/src/java/org/codelutin/topia/persistence/topia/TopiaJDBCQueryHelper.java:1.1 --- /dev/null Mon Aug 1 12:39:58 2005 +++ topia/src/java/org/codelutin/topia/persistence/topia/TopiaJDBCQueryHelper.java Mon Aug 1 12:39:53 2005 @@ -0,0 +1,351 @@ +/* *##% + * Copyright (C) 2002, 2003 Code Lutin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ + +/* * + * TopiaJDBCQueryHelper.java + * + * Created: 28 juil. 2005 + * + * @author Arnaud Thimel + * Copyright Code Lutin + * @version $Revision: 1.1 $ + * + * Mise a jour: $Date: 2005/08/01 12:39:53 $ + * par : $Author: thimel $ + */ +package org.codelutin.topia.persistence.topia; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +import org.codelutin.queryparser.Constraint; +import org.codelutin.queryparser.DefaultQueryVisitorUnsupportedOperation; +import org.codelutin.queryparser.FieldPath; +import org.codelutin.queryparser.From; +import org.codelutin.queryparser.OrderBy; +import org.codelutin.queryparser.QMark; +import org.codelutin.queryparser.Query; +import org.codelutin.queryparser.QueryHelper; +import org.codelutin.queryparser.QueryHelperException; +import org.codelutin.queryparser.Select; +import org.codelutin.queryparser.Where; +import org.codelutin.topia.TopiaEntity; +import org.codelutin.topia.persistence.TopiaTransaction; + +public class TopiaJDBCQueryHelper extends QueryHelper { + + public static final String LEAD_SELECT = "SELECT DISTINCT id FROM data WHERE "; +// public static final String LEAD_SELECT = "SELECT * FROM data WHERE "; + public static final String IN_START = " AND (id,longdate) IN ("; + public static final String IN_AND_SELECT = "SELECT id, longdate FROM data WHERE "; +// public static final String END_BEFORE_TYPE = "SELECT id, min(longdate) FROM management WHERE (id,longdate) IN (SELECT id, max(longdate) FROM management WHERE class='"; +// public static final String END_MIDDLE_TYPE = "' AND (longdate=-900 OR (longdate>0 AND longdate<=900)) AND id NOT IN (SELECT id FROM management WHERE (longdate=-900 OR (longdate>0 AND longdate<=900)) AND isDeleted=true) GROUP BY id UNION SELECT id, longdate FROM management WHERE class='"; +// public static final String END_AFTER_TYPE = "' AND longdate=-900 AND isDeleted=false) GROUP BY id)"; + public static final String END_BEFORE_TYPE = "SELECT id, min(longdate) FROM management WHERE (id,longdate) IN (SELECT id, max(longdate) FROM management WHERE class='"; + public static final String END_MIDDLE_TYPE = "' AND (longdate=? OR (longdate>0 AND longdate<=?)) AND id NOT IN (SELECT id FROM management WHERE (longdate=? OR (longdate>0 AND longdate<=?)) AND isDeleted=true) GROUP BY id UNION SELECT id, longdate FROM management WHERE class='"; + public static final String END_AFTER_TYPE = "' AND longdate=? AND isDeleted=false) GROUP BY id)"; + + protected TopiaJDBCQueryBuilder queryBuilder; + protected TopiaTransaction transaction; + protected long thetime; + + public void setQuery(Query query) { + super.setQuery(query); + queryBuilder = null; + } + + public void setTransaction(TopiaTransaction transaction) { + thetime = transaction.getId(); + } + + @Override + public Collection execute() throws QueryHelperException { + if (getQuery() == null) { + throw new QueryHelperException("Please use setQuery(...) " + + "before execute()"); + } + if (transaction == null) { +// throw new QueryHelperException("Please use setTransaction(...) " + +// "before execute()"); + thetime = System.currentTimeMillis(); + } + + // Préparation de la requete SQL + if (queryBuilder == null) { + queryBuilder = new TopiaJDBCQueryBuilder(); + getQuery().visit(queryBuilder); + + String request = LEAD_SELECT; + for (String s : queryBuilder.getANDs()) { + request += s + IN_START + IN_AND_SELECT; + } + request += queryBuilder.getFilter() + IN_START; + request += END_BEFORE_TYPE + queryBuilder.getFrom() + END_MIDDLE_TYPE + queryBuilder.getFrom() + END_AFTER_TYPE; + for (int i = 0; i < queryBuilder.getANDs().size(); i++) { + request += ")"; + } + request += ";"; + } + + // TODO + // utiliser la transaction pour ajouter les valeurs des 5 "?". Il faut : + // -transaction.getId(), transaction.getId(), -transaction.getId(), transaction.getId(), -transaction.getId() + // soit : -, +, -, +, - + args.add(-thetime); + args.add(thetime); + args.add(-thetime); + args.add(thetime); + args.add(-thetime); + + Collection result = null; + + //TODO Execution de la requete + + return result; + } + + public class TopiaJDBCQueryBuilder extends DefaultQueryVisitorUnsupportedOperation { + + private String filter = ""; + private Query query; + private List ANDs; + private String from; + + public String getFrom() { + return from; + } + + public String getFilter() { + return filter; + } + + public List getANDs() { + return ANDs; + } + + public void visitQuery(Query query) { + this.query = query; + ANDs = new LinkedList(); + } + + public void visitFrom(From from) { + } + public void visitFromSource(From from, String field, String alias) { + this.from = field; + } + + public void visitOrderBy(OrderBy orderBy) { + } + public void visitOrderByField(OrderBy orderBy, FieldPath field, + boolean asc) { +// String adaptedField = field.getField(); +// int pos = query.getFrom().startsWithSourceOrAlias(adaptedField); +// if (pos != -1) +// adaptedField = adaptedField.substring(pos + 1); +// this.orderBy.put(adaptedField, Boolean.valueOf(asc)); + } + + public void visitSelect(Select select) { + } + public void visitSelectAvg(Select select) { + } + public void visitSelectCount(Select select) { + } + public void visitSelectDistinct(Select select) { + } + public void visitSelectField(Select select, FieldPath field, String alias) { + } + public void visitSelectLimit(Select select, int first, int last) { + } + public void visitSelectMax(Select select) { + } + public void visitSelectMin(Select select) { + } + public void visitSelectSum(Select select) { + } + + //Visite récursivement l'opérande spécifiée + protected void visitOperand(Object op){ + if (op instanceof Constraint) { + ((Constraint)op).visit(this); + } else if(op == null) { + filter += " null"; + } else if(op instanceof String) { + filter += " \""+op.toString()+"\""; + } else if(op instanceof QMark) { + filter += " ?"; //TODO à vérif + } else if(op instanceof FieldPath) { + FieldPath field = (FieldPath)op; + String path = field.getField(); + String source = query.getFrom().getSource(field); + if (source.equals("")) { + source = from; + } + if (from.equals(source)) { + path = query.getFrom().getField(field); + } else { + // Sans doute faire plusieurs requetes pour pouvoir supporter + // plusieurs sources et faire des jointure entre elle. + throw new UnsupportedOperationException("Only one source can be used"); + } + if(path.length() > 0){ + filter += path; + } else { + filter += null; + } + } else if(op instanceof Number) { + filter += op.toString(); + } else if(op instanceof Boolean) { + filter += op.toString(); + } else if(op instanceof Collection) { +// filter += "argCollection" + argCollection.size(); +// argCollection.add(op); + } else { + throw new UnsupportedOperationException("This operand is not supported: "+op.getClass().getName()); + } + + } + + public void visitWhere(Where where) { + //Voir les visitWhere spécifiques... + } + public void visitWhereAnd(Constraint constraint, Object op1, Object op2) { + visitOperand(op1); + ANDs.add(filter); + filter = "("; + visitOperand(op2); + filter += ")"; + } + public void visitWhereOr(Constraint constraint, Object op1, Object op2) { + filter += "("; + visitOperand(op1); + filter += " OR "; + visitOperand(op2); + filter += ")"; + } + public void visitWhereNot(Constraint constraint, Object op2) { + filter += "(NOT "; + visitOperand(op2); + filter += ")"; + } + + public void visitWhereEqual(Constraint constraint, Object op1, + Object op2) { + filter += "(field='"; + visitOperand(op1); + filter += "' AND value='"; + visitOperand(op2); + filter += "')"; + } + public void visitWhereNotEqual(Constraint constraint, Object op1, + Object op2) { + filter += "(field='"; + visitOperand(op1); + filter += "' AND value!='"; + visitOperand(op2); + filter += "')"; + } + + public void visitWhereGreater(Constraint constraint, Object op1, + Object op2) { + filter += "(field='"; + visitOperand(op1); + filter += "' AND value>'"; + visitOperand(op2); + filter += "')"; + } + public void visitWhereGreaterOrEqual(Constraint constraint, Object op1, + Object op2) { + filter += "(field='"; + visitOperand(op1); + filter += "' AND value>='"; + visitOperand(op2); + filter += "')"; + } + public void visitWhereSmaller(Constraint constraint, Object op1, + Object op2) { + filter += "(field='"; + visitOperand(op1); + filter += "' AND value<'"; + visitOperand(op2); + filter += "')"; + } + public void visitWhereSmallerOrEqual(Constraint constraint, Object op1, + Object op2) { + filter += "(field='"; + visitOperand(op1); + filter += "' AND value<='"; + visitOperand(op2); + filter += "')"; + } + + public void visitWhereIn(Constraint constraint, Object op1, Object op2) { + //TODO :S +// filter += "("; +// visitOperand(op2); +// filter += ".contains(toObject("; +// visitOperand(op1); +// filter += ")))"; + } + public void visitWhereNotIn(Constraint constraint, Object op1, + Object op2) { + //TODO :S +// filter += "(!"; +// visitOperand(op2); +// filter += ".contains(toObject("; +// visitOperand(op1); +// filter += ")))"; + } + + public void visitWhereLike(Constraint constraint, Object op1, + Object op2) { +// if(op2 instanceof String) { +// String likeValue = (String)op2; +// int index; +// while ((index = likeValue.indexOf("%")) != -1) +// likeValue = likeValue.substring(0, index) + ".*?" + +// likeValue.substring(index + 1); +// op2 = likeValue; +// } + filter += "(field='"; + visitOperand(op1); + filter += "' AND value LIKE '"; + visitOperand(op2); + filter += "')"; + } + public void visitWhereNotLike(Constraint constraint, Object op1, + Object op2) { +// if(op2 instanceof String) { +// String likeValue = (String)op2; +// int index; +// while ((index = likeValue.indexOf("%")) != -1) +// likeValue = likeValue.substring(0, index) + ".*?" + +// likeValue.substring(index + 1); +// op2 = likeValue; +// } + filter += "(field='"; + visitOperand(op1); + filter += "' AND value NOT LIKE '"; + visitOperand(op2); + filter += "')"; + } + + } + +}