This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
commit dae2bede8bfdbc73199fae0b247536d4bc27db2d Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Tue Aug 24 18:18:35 2021 +0200 Move the handling of `ReferenceSystem` outside `SQLBuilder`. --- .../sis/internal/metadata/sql/SQLBuilder.java | 47 ++++++++++------------ .../apache/sis/metadata/sql/MetadataSource.java | 16 +++++++- .../apache/sis/metadata/sql/MetadataWriter.java | 6 +-- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/SQLBuilder.java b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/SQLBuilder.java index bc9990c..25f8b16 100644 --- a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/SQLBuilder.java +++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/SQLBuilder.java @@ -19,9 +19,6 @@ package org.apache.sis.internal.metadata.sql; import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.util.StringTokenizer; -import org.opengis.util.FactoryException; -import org.opengis.referencing.IdentifiedObject; -import org.apache.sis.internal.metadata.ReferencingServices; import org.apache.sis.util.CharSequences; @@ -191,9 +188,8 @@ public class SQLBuilder extends Syntax { * * @param value the value to append, or {@code null}. * @return this builder, for method call chaining. - * @throws FactoryException if an error occurred while using the geodetic database. */ - public final SQLBuilder appendCondition(final Object value) throws FactoryException { + public final SQLBuilder appendCondition(final Object value) { if (value == null) { buffer.append(" IS NULL"); return this; @@ -203,24 +199,35 @@ public class SQLBuilder extends Syntax { } /** - * Appends a value in an {@code INSERT} statement. + * Appends a value in a {@code SELECT} or {@code INSERT} statement. + * The value is written between quotes. * * @param value the value to append, or {@code null}. * @return this builder, for method call chaining. - * @throws FactoryException if an error occurred while using the geodetic database. */ - public final SQLBuilder appendValue(Object value) throws FactoryException { + public final SQLBuilder appendValue(final String value) { if (value == null) { buffer.append("NULL"); + } else { + buffer.append('\'').append(value.replace("'", "''")).append('\''); + } + return this; + } + + /** + * Appends a value in a {@code SELECT} or {@code INSERT} statement. + * If the given value is a character string, then it is written between quotes. + * + * @param value the value to append, or {@code null}. + * @return this builder, for method call chaining. + */ + public final SQLBuilder appendValue(final Object value) { + if (value instanceof Number) { + buffer.append(value); } else if (value instanceof Boolean) { buffer.append((Boolean) value ? "TRUE" : "FALSE"); - } else if (value instanceof Number) { - buffer.append(value); } else { - if (value instanceof IdentifiedObject) { - value = ReferencingServices.getInstance().getPreferredIdentifier((IdentifiedObject) value); - } - buffer.append('\'').append(doubleQuotes(value)).append('\''); + return appendValue((value != null) ? value.toString() : (String) null); } return this; } @@ -231,7 +238,7 @@ public class SQLBuilder extends Syntax { * * <p>This method does not double the simple quotes of the given string on intent, because * it may be used in a {@code PreparedStatement}. If the simple quotes need to be doubled, - * then {@link #doubleQuotes(Object)} should be invoked explicitly.</p> + * then {@link #appendValue(String)} should be invoked.</p> * * @param value the value to append. * @return this builder, for method call chaining. @@ -352,16 +359,6 @@ public class SQLBuilder extends Syntax { } /** - * Returns the string representation of the given value with simple quote doubled. - * - * @param value the object for which to double the quotes in the string representation. - * @return a string representation of the given object with simple quotes doubled. - */ - private static String doubleQuotes(final Object value) { - return value.toString().replace("'", "''"); - } - - /** * Returns the SQL statement. * * @return the SQL statement. diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java index fa623de..3326476 100644 --- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java +++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java @@ -48,6 +48,7 @@ import org.opengis.annotation.UML; import org.opengis.util.CodeList; import org.opengis.util.ControlledVocabulary; import org.opengis.util.FactoryException; +import org.opengis.referencing.IdentifiedObject; import org.apache.sis.metadata.MetadataStandard; import org.apache.sis.metadata.KeyNamePolicy; import org.apache.sis.metadata.ValueExistencePolicy; @@ -58,6 +59,7 @@ import org.apache.sis.internal.system.DelayedRunnable; import org.apache.sis.internal.metadata.sql.Initializer; import org.apache.sis.internal.metadata.sql.Reflection; import org.apache.sis.internal.metadata.sql.SQLBuilder; +import org.apache.sis.internal.metadata.ReferencingServices; import org.apache.sis.internal.system.Loggers; import org.apache.sis.internal.util.Strings; import org.apache.sis.internal.util.CollectionsExt; @@ -750,7 +752,7 @@ public class MetadataSource implements AutoCloseable { } else { helper.append(" AND "); } - helper.appendIdentifier(column).appendCondition(value); + helper.appendIdentifier(column).appendCondition(toStorableValue(value)); } /* * The SQL statement is ready, with metadata dependency (if any) resolved. We can now execute it. @@ -776,6 +778,18 @@ public class MetadataSource implements AutoCloseable { } /** + * Converts the given object to a value that can be stored in the database. + * + * @throws FactoryException if an error occurred while using the geodetic database. + */ + static Object toStorableValue(Object value) throws FactoryException { + if (value instanceof IdentifiedObject) { + value = ReferencingServices.getInstance().getPreferredIdentifier((IdentifiedObject) value); + } + return value; + } + + /** * Returns the set of all columns in a table, or an empty set if none (never {@code null}). * Because each table should have at least the {@value #ID_COLUMN} column, an empty set of * columns will be understood as meaning that the table does not exist. diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java index 62b3f50..a7c8794 100644 --- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java +++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataWriter.java @@ -112,7 +112,7 @@ import org.opengis.util.ControlledVocabulary; * </table> * * @author Martin Desruisseaux (Geomatys) - * @version 1.0 + * @version 1.1 * @since 0.8 * @module */ @@ -521,7 +521,7 @@ public class MetadataWriter extends MetadataSource { } helper.append(") VALUES (").appendValue(identifier); for (final Object value : asSingletons.values()) { - helper.append(", ").appendValue(value); + helper.append(", ").appendValue(toStorableValue(value)); } final String sql = helper.append(')').toString(); if (stmt.executeUpdate(sql) != 1) { @@ -652,7 +652,7 @@ public class MetadataWriter extends MetadataSource { * the native SQL {@code ENUM} type for making easier to add new values when a standard * is updated. */ - private String addCode(final Statement stmt, final ControlledVocabulary code) throws SQLException, FactoryException { + private String addCode(final Statement stmt, final ControlledVocabulary code) throws SQLException { assert Thread.holdsLock(this); final String table = getTableName(code.getClass()); final Set<String> columns = getExistingColumns(table);