/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2007-2012, Open Source Geospatial Foundation (OSGeo) * (C) 2007-2012, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ package org.geotoolkit.internal.sql.table; /** * A parameter in a SQL {@linkplain Query query}. A collection of {@code Parameter} instances * allows the creation of SQL fragment like below (this example assumes 3 {@code Parameter} * instances associated to columns named {@code c1}, {@code c2} and {@code c3}): * * {@preformat sql * WHERE c1=? AND c2=? AND c3=?; * } * * The {@code =} operator can be replaced by {@code LIKE} or any other comparison operation * using the {@link #setComparator(String)} method. The default comparator is {@code =}. * * @author Martin Desruisseaux (IRD, Geomatys) * @version 3.09 * * @since 3.09 (derived from Seagis) * @module */ public final class Parameter extends ColumnOrParameter { /** * Binary operators to be processed in a special way if present in the comparator. */ private static final String[] BINARY_OP = {" AND ", " OR "}; /** * The column on which this parameter applies. */ final Column column; /** * The comparison operator to put in the prepared statement. */ private String comparator = "="; /** * Creates a new parameter for the specified query. * This constructor is not public on intend: instances of {@code Parameter} * can be created only by {@link Query#addParameter addParameter(...)}. * <p> * Instances of this class can be created only by the {@link Query#addParameter addParameter(...)} * method. This class is not designed for subclassing. * * @param query The query for which the parameter is created. * @param column The column on which the parameter is applied. * @param types Types of the queries where the parameter shall appears. */ Parameter(final Query query, final Column column, final QueryType... types) { super(query, types); this.column = column; } /** * Sets the function for this parameter when used in a query of the given type. The function * shall contain exactly one question mark for the parameter value. For example instead of * searching the record for which the column value is equals to {@code ?}, the caller way * want to search for record for which the parameter value is equals to * {@code GeometryFromText(?,4326)}. * <p> * If this method is never invoked, the default value is {@code ?}. * * @param function The function to use with this column for the given types. * @param types The type of the queries for which to use the given function. */ public void setSearchValue(final String function, final QueryType... types) { setFunction(1, function, types); } /** * Sets the comparison operator to put in the prepared statement. This method * is typically invoked for setting the comparison operator to {@code "LIKE"}. * If this method is never invoked, then the default value is {@code "="}. * <p> * This method accepts {@code AND} and {@code OR} operations provided that the question * mark apply only to the very last condition. For example the {@code "IS NULL OR >="} * comparator is legal and will be translated in SQL as: * * {@preformat sql * SELECT column WHERE column IS NULL OR column >= ? * } * * @param comparator The new comparison operator to use. */ public void setComparator(final String comparator) { this.comparator = comparator.trim(); } /** * Appends a {@code c1=?} condition where {@code c1} is the column name, and {@code =} may * be replaced by a more elaborated comparator if {@link #setComparator(String)} has been * invoked. * * @param buffer The buffer in which to write the condition. * @param quote The database-dependent identifier quote. * @param type The type of the SQL query being built. */ final void appendCondition(final StringBuilder buffer, final String quote, final QueryType type) { final String variable = column.name; String condition = comparator; String binaryOp; do { binaryOp = null; int split = 0; String fragment = condition; for (final String op : BINARY_OP) { final int i = fragment.indexOf(op); if (i >= 0) { fragment = fragment.substring(0, split=i); binaryOp = op; } } // Reminder: aggregate functions are not allowed in a WHERE clause. buffer.append(quote).append(variable).append(quote).append(' ').append(fragment); if (binaryOp != null) { buffer.append(binaryOp); condition = condition.substring(split + binaryOp.length()); } } while (binaryOp != null); buffer.append(' '); final String function = getFunction(type); if (function != null) { buffer.append(function); } else { buffer.append('?'); } } /** * Returns a string representation of this parameter. */ @Override public String toString() { return "Parameter[" + column.name + ']'; } }