/* * Constellation - An open source and standard compliant SDI * http://www.constellation-sdi.org * * Copyright 2014 Geomatys. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.constellation.om2; import org.apache.sis.util.logging.Logging; import org.constellation.util.Util; import org.geotoolkit.internal.sql.PostgisInstaller; import org.geotoolkit.internal.sql.ScriptRunner; import javax.sql.DataSource; import java.io.File; import java.io.IOException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.logging.Level; import java.util.logging.Logger; import org.geotoolkit.util.FileUtilities; /** * * @author Guilhem Legal (Geomatys) * @since 0.9 */ public class OM2DatabaseCreator { private static final Logger LOGGER = Logging.getLogger("org.mdweb.sql"); /** * Fill a new PostgreSQL database with the O&M model. * * @param dataSource A postgreSQL dataSource. * * @throws SQLException if an error occurs while filling the database. * @throws IllegalArgumentException if the dataSource is null. */ public static void createObservationDatabase(final DataSource dataSource, final boolean isPostgres, final File postgisInstall, String schemaPrefix) throws SQLException, IOException { if (dataSource == null) { throw new IllegalArgumentException("The DataSource is null"); } if (schemaPrefix == null) { schemaPrefix = ""; } try(final Connection con = dataSource.getConnection()) { if (isPostgres && postgisInstall != null) { final PostgisInstaller pgInstaller = new PostgisInstaller(con); // not needed in pg 9.1 try { pgInstaller.run("CREATE TRUSTED PROCEDURAL LANGUAGE 'plpgsql' HANDLER plpgsql_call_handler VALIDATOR plpgsql_validator;"); } catch (SQLException ex) { LOGGER.log(Level.FINER, "unable to create plpgsql lanquage", ex); } pgInstaller.run("CREATE SCHEMA postgis;"); pgInstaller.run(postgisInstall); } if (!versionTablePresent(con, schemaPrefix)) { try (Statement stmt = con.createStatement()) { stmt.executeUpdate("CREATE TABLE \"public\".\"version\" (\"number\" character varying(10) NOT NULL);"); stmt.executeUpdate("INSERT INTO \"public\".\"version\" VALUES ('1.0.3');"); stmt.executeUpdate("ALTER TABLE \"version\" ADD CONSTRAINT version_pk PRIMARY KEY (\"number\");"); } } final ScriptRunner sr = new ScriptRunner(con); if (isPostgres) { execute("org/constellation/om2/structure_observations_pg.sql", sr, schemaPrefix); } else { execute("org/constellation/om2/structure_observations.sql", sr, schemaPrefix); } LOGGER.info("O&M 2 database created"); sr.close(false); } } public static boolean structurePresent(final DataSource source, final String schemaPrefix) { if (source != null) { try (final Connection con = source.getConnection(); final Statement stmt = con.createStatement()) { boolean exist = versionTablePresent(con, schemaPrefix); if (!exist) { return false; } try(final ResultSet resultObs = stmt.executeQuery("SELECT * FROM \"" + schemaPrefix + "om\".\"observed_properties\"")) { resultObs.next(); } return true; } catch(SQLException ex) { LOGGER.log(Level.FINER, "missing table in OM database", ex); } } return false; } public static boolean versionTablePresent(final Connection con, final String schemaPrefix) { if (con != null) { try (final Statement stmt = con.createStatement(); final ResultSet result = stmt.executeQuery("SELECT * FROM \"version\"")) { result.next(); return true; } catch(SQLException ex) { LOGGER.log(Level.FINER, "missing table in OM database", ex); } } return false; } public static boolean validConnection(final DataSource source) { try (final Connection con = source.getConnection()) { return true; } catch (SQLException ex) { LOGGER.log(Level.FINER, "unable to connect", ex); } return false; } /** * Execute the SQL script pointed by the specified path. * * @param path A path in the resource files to a SQL script. * @param runner A SQL script runner connected to a database. */ private static void execute(final String path, final ScriptRunner runner, final String schemaPrefix) { try { String sql = FileUtilities.getStringFromStream(Util.getResourceAsStream(path)); sql = sql.replace("$SCHEMA", schemaPrefix); runner.run(sql); } catch (IOException ex) { LOGGER.log(Level.SEVERE, "IO exception while executing SQL script", ex); } catch (SQLException ex) { LOGGER.severe("SQLException creating statement: " + runner.getCurrentPosition() + " in " + path + " file.\n" + ex.getMessage()); } } }