/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2005-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.coverage.sql; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.geotoolkit.internal.sql.table.Database; import org.geotoolkit.internal.sql.table.LocalCache; import org.geotoolkit.internal.sql.table.QueryType; import org.geotoolkit.internal.sql.table.SingletonTable; import static org.apache.sis.util.ArgumentChecks.ensureNonNull; /** * Connection to a table of {@linkplain Layer layers}. * * @author Martin Desruisseaux (IRD, Geomatys) * @version 3.15 * * @since 3.10 (derived from Seagis) * @module */ final class LayerTable extends SingletonTable<LayerEntry> { /** * Creates a layer table. * * @param database Connection to the database. */ public LayerTable(final Database database) { this(new LayerQuery(database)); } /** * Constructs a new {@code LayerTable} from the specified query. */ private LayerTable(final LayerQuery query) { super(query, query.byName); } /** * Creates a new instance having the same configuration than the given table. * This is a copy constructor used for obtaining a new instance to be used * concurrently with the original instance. * * @param table The table to use as a template. */ private LayerTable(final LayerTable table) { super(table); } /** * Returns a copy of this table. This is a copy constructor used for obtaining * a new instance to be used concurrently with the original instance. */ @Override protected LayerTable clone() { return new LayerTable(this); } /** * Creates a layer from the current row in the specified result set. * * @param results The result set to read. * @param identifier The identifier of the layer to create. * @return The entry for current row in the specified result set. * @throws SQLException if an error occurred while reading the database. */ @Override protected LayerEntry createEntry(final LocalCache lc, final ResultSet results, final Comparable<?> identifier) throws SQLException { final LayerQuery query = (LayerQuery) super.query; double period = results.getDouble(indexOf(query.period)); if (results.wasNull()) { period = Double.NaN; } final String fallback = results.getString(indexOf(query.fallback)); final String comments = results.getString(indexOf(query.comments)); return new LayerEntry(identifier, period, fallback, comments, (TableFactory) getDatabase()); } /** * Creates a new layer if none exist for the given name. * * @param name The name of the layer. * @return {@code true} if a new layer has been created, or {@code false} if it already exists. * @throws SQLException if an error occurred while reading or writing the database. */ final boolean createIfAbsent(final String name) throws SQLException { ensureNonNull("name", name); if (exists(name)) { return false; } final LayerQuery query = (LayerQuery) super.query; final LocalCache lc = getLocalCache(); synchronized (lc) { boolean success = false; transactionBegin(lc); try { final LocalCache.Stmt ce = getStatement(lc, QueryType.INSERT); final PreparedStatement statement = ce.statement; statement.setString(indexOf(query.name), name); success = updateSingleton(statement); release(lc, ce); } finally { transactionEnd(lc, success); } } return true; } /** * Searches for a layer name not already in use. If the given string is not in use, then * it is returned as-is. Otherwise this method appends a unused decimal number to the * specified name. * * @since 3.11 */ public String searchFreeIdentifier(final String base) throws SQLException { final LocalCache lc = getLocalCache(); synchronized (lc) { return searchFreeIdentifier(lc, base); } } }