diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Column.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Column.java index 6e309600bbd2a7b4d572114e54bf02aa4b6578c6..51b0e17eb4d405d42840a49136459c17152b26bd 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Column.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Column.java @@ -91,7 +91,14 @@ public class Column extends ChildEntity<Table> { } public boolean getIndexed() { - return getValue(INDEXED_KEY, Boolean.class); + EntityProperty indexedProp = getProperty(INDEXED_KEY); + if (indexedProp.getType() == Boolean.class) { + return getValue(INDEXED_KEY, Boolean.class); + } else if (indexedProp.getType() == Integer.class) { + return getValue(INDEXED_KEY, Integer.class) == 1; + } else { + throw new RuntimeException("Indexed property cannot be an instance of " + indexedProp.getType()); + } } /** diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ConsistencyChecks.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ConsistencyChecks.java index d1e9d2790cd5ddbcc6224a44223582a6570e41ed..439c348a835fdb13e2ec718adb7afa80b8dadf91 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ConsistencyChecks.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ConsistencyChecks.java @@ -40,6 +40,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** + * + * TODO: Move queries into data layer classes. * * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} */ @@ -48,28 +50,62 @@ public class ConsistencyChecks implements Serializable { private static final long serialVersionUID = 4412404312756740093L; private final static Logger LOG = LoggerFactory.getLogger(ConsistencyChecks.class); - private static class UnexistingKeyColumn { + public static class UnexistingKey implements Serializable { + + private static final long serialVersionUID = 7891439129072900628L; private final String keyId; - private final String fromColumn; - private final String targetColumn; + private final String fromTable; + private final String[] fromColumns; + private final String targetTable; + private final String[] targetColumns; - private UnexistingKeyColumn(String keyId, String fromColumn, String targetColumn) { + private UnexistingKey(String keyId, String fromTable, String[] fromColumns, String targetTable, String[] targetColumns) { this.keyId = keyId; - this.fromColumn = fromColumn; - this.targetColumn = targetColumn; + this.fromTable = fromTable; + this.fromColumns = fromColumns; + this.targetTable = targetTable; + this.targetColumns = targetColumns; } public String getKeyId() { return keyId; } - public String getFromColumn() { - return fromColumn; + public String getFromTable() { + return fromTable; + } + + public String[] getFromColumns() { + return fromColumns; } - public String getTargetColumn() { - return targetColumn; + public String getTargetTable() { + return targetTable; + } + + public String[] getTargetColumns() { + return targetColumns; + } + + private String getColumnsString(String[] columns) { + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (String column : columns) { + if (!first) { + sb.append(","); + } + sb.append(column); + first = false; + } + return sb.toString(); + } + + @Override + public String toString() { + return String.format("[%s] %s(%s) -> %s(%s)", keyId, + fromTable, getColumnsString(fromColumns), + targetTable, getColumnsString(targetColumns)); } } @@ -77,16 +113,14 @@ public class ConsistencyChecks implements Serializable { private final Set<String> unexisingSchemas; private final Set<String> unexisingTables; private final Map<String, String> unexisingColumns; - private final Set<String> unexistingKeys; - private final List<UnexistingKeyColumn> unexistingKeyColumns; + private final List<UnexistingKey> unexistingKeys; public ConsistencyChecks() { inconsistencies = new ArrayList<>(); unexisingSchemas = new HashSet<>(); unexisingTables = new HashSet<>(); unexisingColumns = new HashMap<>(); - unexistingKeys = new HashSet<>(); - unexistingKeyColumns = new ArrayList<>(); + unexistingKeys = new ArrayList<>(); } public void addInconsistency(InconsistentValue problemDescription) { @@ -121,21 +155,17 @@ public class ConsistencyChecks implements Serializable { unexisingColumns.put(completeTableName, columnName); } - public void addUnexistingKey(String keyId) { + public void addUnexistingKey(String keyId, String fromTable, String[] fromColumns, String targetTable, String[] targetColumns) { if (keyId == null) { throw new IllegalArgumentException("key_id can't be null"); } - unexistingKeys.add(keyId); + unexistingKeys.add(new UnexistingKey(keyId, fromTable, fromColumns, targetTable, targetColumns)); } - public Set<String> getUnexistingKeys() { + public List<UnexistingKey> getUnexistingKeys() { return unexistingKeys; } - public void addUnexistingKeyColumn(String keyId, String fromColumn, String targetColumn) { - unexistingKeyColumns.add(new UnexistingKeyColumn(keyId, fromColumn, targetColumn)); - } - private Set<String> getKeysToRemove(Connection conn, String tapSchemaNameEscaped, DatabaseType dbType, String like) throws SQLException { Set<String> ret = new HashSet<>(); String query = String.format("SELECT key_id from %s.%s WHERE from_table LIKE ? OR target_table LIKE ?", tapSchemaNameEscaped, TSMUtil.escapeName("keys", dbType)); @@ -197,7 +227,9 @@ public class ConsistencyChecks implements Serializable { } } - keysToRemoveIds.addAll(unexistingKeys); + for (UnexistingKey unexistingKey : unexistingKeys) { + keysToRemoveIds.add(unexistingKey.getKeyId()); + } conn.setAutoCommit(false); LOG.debug("Starting transaction"); diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Dao.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Dao.java deleted file mode 100644 index 42ae18d0720b346e730f60123f401776020060cb..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Dao.java +++ /dev/null @@ -1,707 +0,0 @@ -/* - * _____________________________________________________________________________ - * - * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of - * Trieste INAF - IA2 Italian Center for Astronomical Archives - * _____________________________________________________________________________ - * - * Copyright (C) 2016 Istituto Nazionale di Astrofisica - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License Version 3 as published by the - * Free Software Foundation. - * - * 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., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package it.inaf.ia2.tsm; - -import it.inaf.ia2.tsm.datalayer.Credentials; -import it.inaf.ia2.tsm.datalayer.DatabaseType; -import it.inaf.ia2.tsm.datalayer.DBWrapper; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.List; -import javax.sql.DataSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Utility class that contains static methods for interacting with databases. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public class Dao { - -// private static final Logger log = LoggerFactory.getLogger(Dao.class); -// -// /** -// * Creates the TAP_SCHEMA schema and its tables. -// */ -// private static void createTapSchemaStructure(DatabaseType dbType, Connection conn, TapSchema tapSchema) throws SQLException { -// -// String tapSchemaName = tapSchema.getName(); -// String version = tapSchema.getVersion(); -// -// if (dbType == DatabaseType.MYSQL) { -// try (Statement statement = conn.createStatement()) { -// -// ///////////////////////////////////// -// // CREATE DATABASE // -// ///////////////////////////////////// -// String queryString = String.format("CREATE DATABASE IF NOT EXISTS `%s`", tapSchemaName); -// log.debug("Executing query {}", queryString); -// statement.executeUpdate(queryString); -// -// StringBuilder querySb = new StringBuilder(); -// -// ///////////////////////////////////// -// // CREATE schemas TABLE // -// ///////////////////////////////////// -// querySb.append("CREATE TABLE IF NOT EXISTS `"); -// querySb.append(tapSchemaName); -// querySb.append("`.`schemas` (\n"); -// querySb.append("schema_name varchar(64),\n"); -// querySb.append("utype varchar(512) NULL,\n"); -// querySb.append("description varchar(512) NULL,\n"); -// if (TSMUtil.isIA2(version)) { -// querySb.append("schemaID bigint,\n"); -// } -// querySb.append("PRIMARY KEY (schema_name))"); -// -// queryString = querySb.toString(); -// log.debug("Creating \"schemas\" table"); -// log.debug("Executing query {}", queryString); -// statement.executeUpdate(queryString); -// -// ///////////////////////////////////// -// // CREATE tables TABLE // -// ///////////////////////////////////// -// querySb = new StringBuilder(); -// querySb.append("CREATE TABLE IF NOT EXISTS `"); -// querySb.append(tapSchemaName); -// querySb.append("`.tables (\n"); -// querySb.append("schema_name varchar(64),\n"); -// querySb.append("table_name varchar(128),\n"); -// querySb.append("table_type varchar(8),\n"); -// querySb.append("utype varchar(512) NULL,\n"); -// querySb.append("description varchar(512) NULL,\n"); -// if (TSMUtil.isIA2(version)) { -// querySb.append("tableID bigint,\n"); -// } -// querySb.append("PRIMARY KEY (table_name),\n"); -// querySb.append("FOREIGN KEY (schema_name) REFERENCES `"); -// querySb.append(tapSchemaName); -// querySb.append("`.`schemas` (schema_name))"); -// -// queryString = querySb.toString(); -// log.debug("Creating \"tables\" table"); -// log.debug("Executing query {}", queryString); -// statement.executeUpdate(queryString); -// -// ///////////////////////////////////// -// // CREATE columns TABLE // -// ///////////////////////////////////// -// querySb = new StringBuilder(); -// querySb.append("CREATE TABLE IF NOT EXISTS `"); -// querySb.append(tapSchemaName); -// querySb.append("`.columns (\n"); -// querySb.append("table_name varchar(128),\n"); -// querySb.append("column_name varchar(64),\n"); -// querySb.append("utype varchar(512) NULL,\n"); -// querySb.append("ucd varchar(64) NULL,\n"); -// querySb.append("unit varchar(64) NULL,\n"); -// querySb.append("description varchar(512) NULL,\n"); -// querySb.append("datatype varchar(64) NOT NULL,\n"); -// querySb.append("size integer NULL,\n"); -// querySb.append("principal integer NOT NULL,\n"); -// querySb.append("indexed integer NOT NULL,\n"); -// querySb.append("std integer NOT NULL,\n"); -// if (TSMUtil.isIA2(version)) { -// querySb.append("id integer,\n"); -// querySb.append("columnID bigint,\n"); -// } -// querySb.append("PRIMARY KEY (table_name, column_name),\n"); -// querySb.append("FOREIGN KEY (table_name) REFERENCES `"); -// querySb.append(tapSchemaName); -// querySb.append("`.tables (table_name))"); -// -// queryString = querySb.toString(); -// log.debug("Creating \"columns\" table"); -// log.debug("Executing query {}", queryString); -// statement.executeUpdate(queryString); -// -// ///////////////////////////////////// -// // CREATE keys TABLE // -// ///////////////////////////////////// -// querySb = new StringBuilder(); -// querySb.append("CREATE TABLE IF NOT EXISTS `"); -// querySb.append(tapSchemaName); -// querySb.append("`.keys (\n"); -// querySb.append("key_id varchar(64),\n"); -// querySb.append("from_table varchar(128) NOT NULL,\n"); -// querySb.append("target_table varchar(128) NOT NULL,\n"); -// querySb.append("utype varchar(512) NULL,\n"); -// querySb.append("description varchar(512) NULL,\n"); -// if (TSMUtil.isIA2(version)) { -// querySb.append("keyID bigint,\n"); -// } -// querySb.append("PRIMARY KEY (key_id),\n"); -// querySb.append("FOREIGN KEY (from_table) REFERENCES `"); -// querySb.append(tapSchemaName); -// querySb.append("`.tables (table_name),\n"); -// querySb.append("FOREIGN KEY (target_table) REFERENCES `"); -// querySb.append(tapSchemaName); -// querySb.append("`.tables (table_name))"); -// -// queryString = querySb.toString(); -// log.debug("Creating \"keys\" table"); -// log.debug("Executing query {}", queryString); -// statement.executeUpdate(queryString); -// -// ///////////////////////////////////// -// // CREATE key_columns TABLE // -// ///////////////////////////////////// -// querySb = new StringBuilder(); -// querySb.append("CREATE TABLE IF NOT EXISTS `"); -// querySb.append(tapSchemaName); -// querySb.append("`.key_columns (\n"); -// querySb.append("key_id varchar(64),\n"); -// querySb.append("from_column varchar(64) NOT NULL,\n"); -// querySb.append("target_column varchar(64) NOT NULL,\n"); -// if (TSMUtil.isIA2(version)) { -// querySb.append("key_columnID bigint,\n"); -// } -// querySb.append("FOREIGN KEY (key_id) REFERENCES `"); -// querySb.append(tapSchemaName); -// querySb.append("`.keys (key_id))"); -// -// queryString = querySb.toString(); -// log.debug("Creating \"key_columns\" table"); -// log.debug("Executing query {}", queryString); -// statement.executeUpdate(queryString); -// } -// } else if (dbType == DatabaseType.POSTGRES) { -// try (Statement statement = conn.createStatement()) { -// String tapSchemaNameEscaped = TSMUtil.escapeName(tapSchemaName, dbType); -// -// statement.executeUpdate("CREATE SCHEMA IF NOT EXISTS " + tapSchemaNameEscaped); -// -// StringBuilder querySb = new StringBuilder(); -// -// ///////////////////////////////////// -// // CREATE schemas TABLE // -// ///////////////////////////////////// -// querySb.append("CREATE TABLE IF NOT EXISTS "); -// querySb.append(tapSchemaNameEscaped); -// querySb.append(".schemas (\n"); -// querySb.append("schema_name character varying(64) NOT NULL,\n"); -// querySb.append("description character varying(512),\n"); -// if (TSMUtil.isIA2(version)) { -// querySb.append("schemaid bigint,\n"); -// } -// querySb.append("utype character varying(512))"); -// -// String queryString = querySb.toString(); -// log.debug("Creating \"schemas\" table"); -// log.debug("Executing query {}", queryString); -// int updateResult = statement.executeUpdate(queryString); -// -// if (updateResult > 0) { -// queryString = "ALTER TABLE ONLY schemas ADD CONSTRAINT schemas_pkey PRIMARY KEY (schema_name)"; -// log.debug("Adding constraints to \"schemas\" table"); -// log.debug("Executing query {}", queryString); -// statement.executeUpdate(queryString); -// } -// -// ///////////////////////////////////// -// // CREATE tables TABLE // -// ///////////////////////////////////// -// querySb = new StringBuilder(); -// -// querySb.append("CREATE TABLE IF NOT EXISTS "); -// querySb.append(tapSchemaNameEscaped); -// querySb.append(".tables (\n"); -// querySb.append("table_name character varying(128) NOT NULL,\n"); -// querySb.append("description character varying(512),\n"); -// querySb.append("schema_name character varying(64),\n"); -// if (TSMUtil.isIA2(version)) { -// querySb.append("tableid bigint,\n"); -// } -// querySb.append("table_type character varying(8),\n"); -// querySb.append("utype character varying(512))"); -// -// queryString = querySb.toString(); -// log.debug("Creating \"tables\" table"); -// log.debug("Executing query {}", queryString); -// updateResult = statement.executeUpdate(queryString); -// -// if (updateResult > 0) { -// log.debug("Adding constraints to \"tables\" table"); -// queryString = "ALTER TABLE ONLY tables ADD CONSTRAINT tables_pkey PRIMARY KEY (table_name)"; -// log.debug("Executing query {}", queryString); -// statement.executeUpdate(queryString); -// queryString = "ALTER TABLE ONLY tables ADD CONSTRAINT fk_tables_schema_name FOREIGN KEY (schema_name) REFERENCES schemas(schema_name)"; -// log.debug("Executing query {}", queryString); -// statement.executeUpdate(queryString); -// } -// -// ///////////////////////////////////// -// // CREATE columns TABLE // -// ///////////////////////////////////// -// querySb = new StringBuilder(); -// -// querySb.append("CREATE TABLE IF NOT EXISTS "); -// querySb.append(tapSchemaNameEscaped); -// querySb.append(".columns (\n"); -// querySb.append("table_name character varying(128) NOT NULL,\n"); -// querySb.append("column_name character varying(64) NOT NULL,\n"); -// if (TSMUtil.isIA2(version)) { -// querySb.append("columnid bigint,\n"); -// } -// querySb.append("datatype character varying(64),\n"); -// querySb.append("description character varying(512),\n"); -// querySb.append("id integer,\n"); -// querySb.append("indexed boolean,\n"); -// querySb.append("principal boolean,\n"); -// querySb.append("size integer,\n"); -// querySb.append("std boolean,\n"); -// querySb.append("ucd character varying(64),\n"); -// querySb.append("unit character varying(64),\n"); -// querySb.append("utype character varying(512))"); -// -// queryString = querySb.toString(); -// log.debug("Creating \"columns\" table"); -// log.debug("Executing query {}", queryString); -// updateResult = statement.executeUpdate(queryString); -// -// if (updateResult > 0) { -// log.debug("Adding constraints to \"columns\" table"); -// queryString = "ALTER TABLE ONLY columns ADD CONSTRAINT columns_pkey PRIMARY KEY (table_name, column_name)"; -// log.debug("Executing query {}", queryString); -// statement.executeUpdate(queryString); -// queryString = "ALTER TABLE ONLY columns ADD CONSTRAINT fk_columns_table_name FOREIGN KEY (table_name) REFERENCES tables(table_name)"; -// log.debug("Executing query {}", queryString); -// statement.executeUpdate(queryString); -// } -// -// ///////////////////////////////////// -// // CREATE keys TABLE // -// ///////////////////////////////////// -// querySb = new StringBuilder(); -// -// querySb.append("CREATE TABLE IF NOT EXISTS "); -// querySb.append(tapSchemaNameEscaped); -// querySb.append(".keys (\n"); -// querySb.append("key_id character varying(64) NOT NULL,\n"); -// querySb.append("description character varying(512),\n"); -// querySb.append("from_table character varying(128),\n"); -// if (TSMUtil.isIA2(version)) { -// querySb.append("keyid bigint,\n"); -// } -// querySb.append("target_table character varying(128),\n"); -// querySb.append("utype character varying(512))"); -// -// queryString = querySb.toString(); -// log.debug("Creating \"keys\" table"); -// log.debug("Executing query {}", queryString); -// updateResult = statement.executeUpdate(queryString); -// -// if (updateResult > 0) { -// log.debug("Adding constraints to \"keys\" table"); -// queryString = "ALTER TABLE ONLY keys ADD CONSTRAINT keys_pkey PRIMARY KEY (key_id)"; -// log.debug("Executing query {}", queryString); -// statement.executeUpdate(queryString); -// queryString = "ALTER TABLE ONLY keys ADD CONSTRAINT \"FK_keys_from_table\" FOREIGN KEY (from_table) REFERENCES tables(table_name)"; -// log.debug("Executing query {}", queryString); -// statement.executeUpdate(queryString); -// queryString = "ALTER TABLE ONLY keys ADD CONSTRAINT \"FK_keys_target_table\" FOREIGN KEY (target_table) REFERENCES tables(table_name)"; -// log.debug("Executing query {}", queryString); -// statement.executeUpdate(queryString); -// } -// -// ///////////////////////////////////// -// // CREATE key_columns TABLE // -// ///////////////////////////////////// -// querySb = new StringBuilder(); -// -// querySb.append("CREATE TABLE IF NOT EXISTS "); -// querySb.append(tapSchemaNameEscaped); -// querySb.append(".key_columns (\n"); -// querySb.append("from_column character varying(64) NOT NULL,\n"); -// querySb.append("target_column character varying(64) NOT NULL,\n"); -// if (TSMUtil.isIA2(version)) { -// querySb.append("key_columnid bigint,\n"); -// } -// querySb.append("key_id character varying(64) NOT NULL)"); -// -// queryString = querySb.toString(); -// log.debug("Creating \"key_columns\" table"); -// log.debug("Executing query {}", queryString); -// updateResult = statement.executeUpdate(queryString); -// -// if (updateResult > 0) { -// log.debug("Adding constraints to \"key_columns\" table"); -// queryString = "ALTER TABLE ONLY key_columns ADD CONSTRAINT key_columns_pkey PRIMARY KEY (from_column, target_column, key_id)"; -// log.debug("Executing query {}", queryString); -// statement.executeUpdate(queryString); -// queryString = "ALTER TABLE ONLY key_columns ADD CONSTRAINT fk_key_columns_key_id FOREIGN KEY (key_id) REFERENCES keys(key_id)"; -// log.debug("Executing query {}", queryString); -// statement.executeUpdate(queryString); -// } -// } -// } else { -// throw new UnsupportedOperationException("Database type " + dbType + " not supported"); -// } -// } -// -// protected static void save(DBWrapper dbWrapper, TapSchema tapSchema) throws SQLException { -// -// log.debug("Saving TAP_SCHEMA"); -// -// DatabaseType dbType = dbWrapper.getTapSchemaDatabaseType(); -// DataSource dataSource = dbWrapper.getTapSchemaDataSource(); -// -// Connection connection = null; -// PreparedStatement statement = null; -// boolean transactionStarted = false; -// -// try { -// connection = dataSource.getConnection(); -// -// UpdateOperations operations = new UpdateOperations(tapSchema); -// -// if (!tapSchema.exists()) { -// createTapSchemaStructure(dbType, connection, tapSchema); -// } -// -// // Start update -// connection.setAutoCommit(false); // start transaction -// transactionStarted = true; -// -// String tapSchemaNameEscaped = TSMUtil.escapeName(tapSchema.getName(), dbType); -// -// // REMOVE ELEMENTS -// if (tapSchema.exists()) { -// for (Key key : operations.getKeysToRemove()) { -// String keyId = key.getId(); -// -// String query = String.format("DELETE FROM %s.%s WHERE key_id = ?", tapSchemaNameEscaped, TSMUtil.escapeName("key_columns", dbType)); -// statement = connection.prepareStatement(query); -// statement.setString(1, keyId); -// log.debug("Executing query {} [key_id={}]", query, keyId); -// statement.executeUpdate(); -// -// query = String.format("DELETE FROM %s.%s WHERE key_id = ?", tapSchemaNameEscaped, TSMUtil.escapeName("keys", dbType)); -// statement = connection.prepareStatement(query); -// statement.setString(1, keyId); -// log.debug("Executing query {} [key_id={}]", query, keyId); -// statement.executeUpdate(); -// } -// -// for (Column column : operations.getColumnsToRemove()) { -// String query = String.format("DELETE FROM %s.%s WHERE table_name = ? AND column_name = ?", tapSchemaNameEscaped, TSMUtil.escapeName("columns", dbType)); -// statement = connection.prepareStatement(query); -// String tableName = column.getTableCompleteName(); -// String columnName = column.getName(); -// statement.setString(1, tableName); -// statement.setString(2, columnName); -// log.debug("Executing query {} [table_name={}, column_name={}]", query, tableName, columnName); -// statement.executeUpdate(); -// } -// -// for (Table table : operations.getTablesToRemove()) { -// String query = String.format("DELETE FROM %s.%s WHERE table_name = ?", tapSchemaNameEscaped, TSMUtil.escapeName("tables", dbType)); -// statement = connection.prepareStatement(query); -// String tableCompleteName = table.getCompleteName(); -// statement.setString(1, tableCompleteName); -// log.debug("Executing query {} [table_name={}]", query, tableCompleteName); -// statement.executeUpdate(); -// } -// -// for (Schema schema : operations.getSchemasToRemove()) { -// String query = String.format("DELETE FROM %s.%s WHERE schema_name = ?", tapSchemaNameEscaped, TSMUtil.escapeName("schemas", dbType)); -// statement = connection.prepareStatement(query); -// String schemaName = schema.getName(); -// statement.setString(1, schemaName); -// log.debug("Executing query {} [schema_name={}]", query, schemaName); -// statement.executeUpdate(); -// } -// } -// -// // INSERT ELEMENTS -// if (!operations.getSchemasToAdd().isEmpty()) { -// log.debug("Inserting {} new schemas", operations.getSchemasToAdd().size()); -// } -// for (Schema schema : operations.getSchemasToAdd()) { -// DaoSchema.insertNewSchema(dbType, connection, tapSchema, schema); -// } -// -// if (!operations.getTablesToAdd().isEmpty()) { -// log.debug("Inserting {} new tables", operations.getTablesToAdd().size()); -// } -// for (Table table : operations.getTablesToAdd()) { -// DaoTable.insertNewTable(dbType, connection, tapSchema, table); -// } -// -// if (!operations.getColumnsToAdd().isEmpty()) { -// log.debug("Inserting {} new columns", operations.getColumnsToAdd().size()); -// } -// for (Column column : operations.getColumnsToAdd()) { -// DaoColumn.insertNewColumn(dbType, connection, tapSchema, column); -// } -// -// if (!operations.getKeysToAdd().isEmpty()) { -// log.debug("Inserting {} new keys", operations.getKeysToAdd().size()); -// } -// for (Key key : operations.getKeysToAdd()) { -// // insert new keys and their key columns -// DaoKey.insertNewKey(dbType, connection, tapSchema, key); -// } -// -// //UPDATE ELEMENTS -// if (tapSchema.exists()) { -// for (Key key : operations.getKeysToUpdate()) { -// // update keys and their key columns -// DaoKey.updateKey(dbType, connection, tapSchema, key); -// } -// -// for (Schema schema : operations.getSchemasToUpdate()) { -// DaoSchema.updateSchema(dbType, connection, tapSchema, schema); -// } -// -// for (Table table : operations.getTablesToUpdate()) { -// DaoTable.updateTable(dbType, connection, tapSchema, table); -// } -// -// for (Column column : operations.getColumnsToUpdate()) { -// DaoColumn.updateColumn(dbType, connection, tapSchema, column); -// } -// } -// -// connection.commit(); -// -// // Status cleanup after commit -// // added -// for (Key key : operations.getKeysToAdd()) { -// key.save(); -// } -// for (Schema schema : operations.getSchemasToAdd()) { -// schema.save(); -// } -// for (Table table : operations.getTablesToAdd()) { -// table.save(); -// } -// for (Column column : operations.getColumnsToAdd()) { -// column.save(); -// } -// -// // removed -// for (Key key : operations.getKeysToRemove()) { -// key.initProperty(Key.ID_KEY, null); -// for (KeyColumn keyColumn : key.getKeyColumns()) { -// keyColumn.initProperty(KeyColumn.KEY_ID_KEY, null); -// } -// } -// for (Column column : operations.getColumnsToRemove()) { -// column.setStatus(Status.LOADED); -// } -// for (Column column : operations.getColumnsToClean()) { -// column.setStatus(Status.LOADED); -// } -// for (Table table : operations.getTablesToRemove()) { -// Schema schema = tapSchema.getChild(table.getSchemaName()); -// if (schema != null) { -// ((Schema) schema).cleanTable(table.getName()); -// } -// } -// for (Table table : operations.getTablesToClean()) { -// Schema schema = tapSchema.getChild(table.getSchemaName()); -// if (schema != null) { -// ((Schema) schema).cleanTable(table.getName()); -// } -// } -// for (Schema schema : operations.getSchemasToRemove()) { -// ((TapSchema) tapSchema).cleanSchema(schema.getName()); -// } -// for (Schema schema : operations.getSchemasToClean()) { -// ((TapSchema) tapSchema).cleanSchema(schema.getName()); -// } -// -// // updated -// for (Key key : operations.getKeysToUpdate()) { -// key.save(); -// } -// for (Schema schema : operations.getSchemasToUpdate()) { -// schema.save(); -// } -// for (Table table : operations.getTablesToUpdate()) { -// table.save(); -// } -// for (Column column : operations.getColumnsToUpdate()) { -// column.save(); -// } -// } catch (SQLException e) { -// log.error("Exception caught", e); -// try { -// if (connection != null && transactionStarted) { -// log.debug("Executing rollback"); -// connection.rollback(); -// } -// } catch (SQLException e2) { -// log.error("Exception caught", e2); -// } -// throw e; -// } finally { -// if (connection != null) { -// try { -// if (statement != null) { -// statement.close(); -// } -// connection.close(); -// } catch (SQLException e2) { -// log.error("Exception caught", e2); -// } -// } -// } -// } -// -// public static List<String> getAllTAPSchemasNames(Credentials credentials) throws SQLException { -// DatabaseType dbType = credentials.getDatabaseType(); -// DataSource ds = TSMUtil.createDataSource(credentials); -// List<String> allSchemas = DaoSchema.getAllSchemasNames(ds, dbType); -// return getAllTAPSchemasNames(ds, dbType, allSchemas); -// } -// -// public static List<String> getAllTAPSchemasNames(DBWrapper dbs) throws SQLException { -// List<String> allSchemas = DaoSchema.getAllSchemasNames(dbs.getTapSchemaDataSource(), dbs.getTapSchemaDatabaseType()); -// return getAllTAPSchemasNames(dbs, allSchemas); -// } -// -// public static List<String> getAllTAPSchemasNames(DBWrapper dbs, List<String> allSchemas) throws SQLException { -// return getAllTAPSchemasNames(dbs.getTapSchemaDataSource(), dbs.getTapSchemaDatabaseType(), allSchemas); -// } -// -// /** -// * Retrieve the list of all TAP_SCHEMA schemas names contained in the -// * TAP_SCHEMA <code>DataSource</code>.<br> -// * TAP_SCHEMA schemas are selected simply checking if they contains the -// * TAP_SCHEMA standard tables. Currently no check on columns is performed. -// * -// * @param allSchemas usually the TAP_SCHEMA schemas list is loaded together -// * the list of all schemas, so this list is passed by parameter to avoid -// * repeating the query twice. -// * -// * @return list of all TAP_SCHEMA schemas names alphabetically and case -// * insensitively ordered. -// */ -// public static List<String> getAllTAPSchemasNames(DataSource dataSource, DatabaseType dbType, List<String> allSchemas) throws SQLException { -// -// List<String> allTAPSchemas = new ArrayList<>(); -// -// for (String schemaName : allSchemas) { -// -// boolean schemas = false, -// tables = false, -// columns = false, -// keys = false, -// keyColumns = false; -// -// String query; -// switch (dbType) { -// case MYSQL: -// query = "SHOW TABLES FROM `" + schemaName + "`"; -// break; -// case POSTGRES: -// query = "SELECT tablename FROM pg_catalog.pg_tables where schemaname = '" + schemaName + "'"; -// break; -// default: -// throw new UnsupportedOperationException("Database type " + dbType + " not supported"); -// } -// -// log.debug("Executing query {}", query); -// -// try (Connection connection = dataSource.getConnection(); -// Statement statement = connection.createStatement(); -// ResultSet resultSet = statement.executeQuery(query)) { -// while (resultSet.next()) { -// String shortTableName = resultSet.getString(1); -// -// if (null != shortTableName) { -// switch (shortTableName) { -// case "schemas": -// schemas = true; -// break; -// case "tables": -// tables = true; -// break; -// case "columns": -// columns = true; -// break; -// case "keys": -// keys = true; -// break; -// case "key_columns": -// keyColumns = true; -// break; -// } -// } -// } -// } -// -// if (schemas && tables && columns && keys && keyColumns) { -// // the schema is a TAP_SCHEMA -// allTAPSchemas.add(schemaName); -// } -// } -// -// log.debug("{} TAP_SCHEMA schemas found", allTAPSchemas.size()); -// -// return TSMUtil.sortStringsList(allTAPSchemas); -// } -// -// /** -// * Retrieve the list of the name of the schemas exposed by the TAP_SCHEMA -// * specified by the <code>tapSchemaName</code> parameter. -// * -// * @return list of exposed schemas names alphabetically and case -// * insensitively ordered. -// */ -// public static List<String> getExposedSchemas(DBWrapper dbs, String tapSchemaName) throws SQLException { -// -// final List<String> exposedSchemas = new ArrayList<>(); -// -// DatabaseType dbType = dbs.getTapSchemaDatabaseType(); -// -// String query; -// if (dbType == DatabaseType.MYSQL) { -// query = "SELECT schema_name FROM `" + tapSchemaName + "`.`schemas`"; -// } else if (dbType == DatabaseType.POSTGRES) { -// query = "SELECT schema_name FROM \"" + tapSchemaName + "\".\"schemas\""; -// } else { -// throw new UnsupportedOperationException("Database type " + dbType + " not supported"); -// } -// -// log.debug("Executing query " + query); -// -// try (Connection connection = dbs.getTapSchemaConnection(); -// Statement statement = connection.createStatement(); -// ResultSet resultSet = statement.executeQuery(query)) { -// while (resultSet.next()) { -// exposedSchemas.add(resultSet.getString(1)); -// } -// } -// -// return exposedSchemas; -// } -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoColumn.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoColumn.java deleted file mode 100644 index 6aafd03a20393456d8ef0bfadcbe0f2c712b222a..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoColumn.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * _____________________________________________________________________________ - * - * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of - * Trieste INAF - IA2 Italian Center for Astronomical Archives - * _____________________________________________________________________________ - * - * Copyright (C) 2016 Istituto Nazionale di Astrofisica - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License Version 3 as published by the - * Free Software Foundation. - * - * 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., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package it.inaf.ia2.tsm; - -import it.inaf.ia2.tsm.datalayer.DatabaseType; -import it.inaf.ia2.tsm.datalayer.DBWrapper; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; -import javax.sql.DataSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Utility class that contains static methods for managing {@link Column}s into - * the database. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public class DaoColumn { -// -// private static final Logger log = LoggerFactory.getLogger(DaoColumn.class); -// -// private static boolean equalsOneOf(String string, String... values) { -// for (String value : values) { -// if (string.equals(value)) { -// return true; -// } -// } -// return false; -// } -// -// /** -// * Returns the list of all the columns names given a schema name and a table -// * name, also if these objects have never been added into the TAP_SCHEMA. -// * This can be useful to retrieve the source database structure. -// */ -// public static List<String> getAllColumnsNames(DBWrapper dbWrapper, TapSchema tapSchema, String schemaName, String tableSimpleName) throws SQLException { -// final List<String> allColumns = new ArrayList<>(); -// -// DataSource dataSource = TSMUtil.getSchemaDataSource(dbWrapper, tapSchema, schemaName); -// DatabaseType dbType = TSMUtil.getSchemaDatabaseType(dbWrapper, tapSchema, schemaName); -// -// String query; -// if (dbType == DatabaseType.MYSQL) { -// query = String.format("SHOW COLUMNS FROM `%s`.`%s`", schemaName, tableSimpleName); -// } else if (dbType == DatabaseType.POSTGRES) { -// query = "SELECT column_name FROM information_schema.columns WHERE table_schema = '" + schemaName + "' AND table_name = '" + tableSimpleName + "'"; -// } else { -// throw new UnsupportedOperationException("Database type " + dbType + " not supported"); -// } -// -// log.debug("Executing query {}", query); -// -// try (Connection connection = dataSource.getConnection(); -// Statement statement = connection.createStatement(); -// ResultSet resultSet = statement.executeQuery(query)) { -// -// while (resultSet.next()) { -// -// String columnName; -// if (dbType == DatabaseType.MYSQL) { -// columnName = resultSet.getString("Field"); -// } else if (dbType == DatabaseType.POSTGRES) { -// columnName = resultSet.getString("column_name"); -// } else { -// throw new UnsupportedOperationException("Database type " + dbType + " not supported"); -// } -// -// allColumns.add(columnName); -// } -// } -// -// return allColumns; -// } -// -// /** -// * For performance reasons all columns of a {@link Table} are loaded -// * together using this method. Columns {@link Status} is at first set as -// * {@code LOADED}. -// */ -// protected static List<Column> loadAllTableColumns(DBWrapper dbWrapper, TapSchema tapSchema, String schemaName, Table table) throws SQLException { -// String tableSimpleName = table.getName(); -// final List<Column> allColumns = new ArrayList<>(); -// -// DataSource dataSource = TSMUtil.getSchemaDataSource(dbWrapper, tapSchema, schemaName); -// DatabaseType dbType = TSMUtil.getSchemaDatabaseType(dbWrapper, tapSchema, schemaName); -// -// String query; -// if (dbType == DatabaseType.MYSQL) { -// query = String.format("SHOW COLUMNS FROM `%s`.`%s`", schemaName, tableSimpleName); -// } else if (dbType == DatabaseType.POSTGRES) { -// query = "SELECT c.column_name, c.data_type, r.contype AS column_type, c.character_maximum_length, c.numeric_precision\n" //, c.numeric_precision_radix -// + "FROM information_schema.columns c\n" -// + "JOIN pg_catalog.pg_tables t ON c.table_schema = t.schemaname AND c.table_name = t.tablename\n" -// + "LEFT JOIN pg_catalog.pg_constraint r ON c.ordinal_position = ANY(r.conkey) AND r.conrelid = (t.schemaname || '.' || t.tablename)::regclass::oid\n" -// + "WHERE t.schemaname = '" + schemaName + "' AND t.tablename = '" + tableSimpleName + "'"; -// } else { -// throw new UnsupportedOperationException("Database type " + dbType + " not supported"); -// } -// -// log.debug("Executing query {}", query); -// -// try (Connection connection = dataSource.getConnection(); -// Statement statement = connection.createStatement(); -// ResultSet resultSet = statement.executeQuery(query)) { -// -// while (resultSet.next()) { -// -// String columnName; -// if (dbType == DatabaseType.MYSQL) { -// columnName = resultSet.getString("Field"); -// } else if (dbType == DatabaseType.POSTGRES) { -// columnName = resultSet.getString("column_name"); -// } else { -// throw new UnsupportedOperationException("Database type " + dbType + " not supported"); -// } -// -// boolean indexed = false, primaryKey = false; -// -// // Key type -// if (dbType == DatabaseType.MYSQL) { -// String key = resultSet.getString("Key"); -// primaryKey = key.equals("PRI"); -// indexed = equalsOneOf(key, "PRI", "UNI", "MUL"); -// } else if (dbType == DatabaseType.POSTGRES) { -// String columnType = resultSet.getString("column_type"); -// if (columnType != null) { -// primaryKey = "p".equals(columnType); -// indexed = equalsOneOf(columnType, "p", "f", "u"); -// } -// } else { -// throw new UnsupportedOperationException("Database type " + dbType + " not supported"); -// } -// -// // Datatype and Size -// int size = 0; -// String datatype; -// -// if (dbType == DatabaseType.MYSQL) { -// String type = resultSet.getString("Type").toLowerCase(); -// -// if (type.startsWith("int")) { -// datatype = "adql:INTEGER"; -// } else if (type.startsWith("smallint")) { -// datatype = "adql:SMALLINT"; -// } else if (type.startsWith("bigint")) { -// datatype = "adql:BIGINT"; -// } else if (type.startsWith("float")) { -// datatype = "adql:REAL"; -// } else if (type.startsWith("char")) { -// int beginIndex = type.indexOf('('); -// int endIndex = type.indexOf(')'); -// size = Integer.parseInt(type.substring(beginIndex + 1, endIndex)); -// datatype = "adql:CHAR"; -// } else if (type.startsWith("varchar")) { -// int beginIndex = type.indexOf('('); -// int endIndex = type.indexOf(')'); -// size = Integer.parseInt(type.substring(beginIndex + 1, endIndex)); -// datatype = "adql:VARCHAR"; -// } else if (type.contains("timestamp")) { -// datatype = "adql:TIMESTAMP"; -// } else { -// datatype = "adql:" + type.toUpperCase(); -// } -// } else if (dbType == DatabaseType.POSTGRES) { -// String type = resultSet.getString("data_type"); -// -// if (type.startsWith("int")) { -// datatype = "adql:INTEGER"; -// } else if (type.startsWith("smallint")) { -// datatype = "adql:SMALLINT"; -// } else if (type.startsWith("bigint")) { -// datatype = "adql:BIGINT"; -// } else if (type.startsWith("double") || type.startsWith("real")) { -// datatype = "adql:REAL"; -// } else if (type.startsWith("character varying")) { -// datatype = "adql:VARCHAR"; -// size = resultSet.getInt("character_maximum_length"); -// } else if (type.startsWith("char")) { -// datatype = "adql:CHAR"; -// size = resultSet.getInt("character_maximum_length"); -// } else if (type.contains("timestamp")) { -// datatype = "adql:TIMESTAMP"; -// } else { -// datatype = "adql:" + type.toUpperCase(); -// } -// } else { -// throw new UnsupportedOperationException("Database type " + dbType + " not supported"); -// } -// -// Integer arraySize = null; // TODO (v 1.1) -// -// Column column = new Column(dbWrapper, tapSchema, table, columnName, indexed, primaryKey, datatype, size, arraySize); -// -// allColumns.add(column); -// } -// } -// -// return allColumns; -// } -// -// /** -// * Retrieves saved {@code Column}s from the database and add them into the -// * specified {@code TapSchema}. -// */ -// protected static void fillSavedColumns(DBWrapper dbWrapper, final TapSchema tapSchema) throws SQLException { -// -// log.debug("fillSavedColumns"); -// -// SelectQueryBuilder selectQueryBuilder = new SelectQueryBuilder(dbWrapper.getTapSchemaDatabaseType(), tapSchema, TapSchema.COLUMNS_TABLE) { -// -// @Override -// protected TapSchemaEntity getEntity(ResultSet rs) throws SQLException { -// String tableCompleteName = rs.getString("table_name"); -// String columnName = rs.getString("column_name"); -// -// String[] tableNameSplit = tableCompleteName.split(Pattern.quote(".")); -// String schemaName = tableNameSplit[0]; -// String tableSimpleName = tableNameSplit[1]; -// -// Schema schema = tapSchema.getChild(schemaName); -// if (schema == null) { -// return null; -// } -// Table table = schema.getChild(tableSimpleName); -// if (table == null) { -// return null; -// } -// Column column = table.addChild(columnName); -// if (column == null) { -// return null; -// } -// column.setStatus(Status.ADDED_PERSISTED); -// return column; -// } -// }; -// -// selectQueryBuilder.executeQuery(dbWrapper.getTapSchemaConnection()); -// } -// -// /** -// * Save a new {@code Column} into the TAP_SCHEMA schema. -// */ -// protected static void insertNewColumn(DatabaseType dbType, Connection connection, TapSchema tapSchema, Column column) throws SQLException { -// -// log.debug("insertNewColumn"); -// -// InsertQueryBuilder insertQueryBuilder = new InsertQueryBuilder(dbType, tapSchema, column, TapSchema.COLUMNS_TABLE); -// insertQueryBuilder.executeQuery(connection); -// } -// -// /** -// * Updates an existing {@code Column}. -// */ -// protected static void updateColumn(DatabaseType dbType, Connection connection, TapSchema tapSchema, Column column) throws SQLException { -// -// UpdateQueryBuilder updateQueryBuilder = new UpdateQueryBuilder(dbType, tapSchema, column, TapSchema.COLUMNS_TABLE, "column_name = ? AND table_name = ?"); -// -// String query = updateQueryBuilder.getQuery(); -// -// try (PreparedStatement statement = connection.prepareStatement(query)) { -// -// log.debug("Executing query {}", query); -// -// int i = updateQueryBuilder.addStatementValues(statement); -// statement.setString(i, column.getName()); -// statement.setString(i + 1, column.getTableCompleteName()); -// -// statement.executeUpdate(); -// } -// } -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoKey.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoKey.java deleted file mode 100644 index 28599ae3cecbd2d812ef46d43fedd9f8133ccec4..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoKey.java +++ /dev/null @@ -1,489 +0,0 @@ -/* - * _____________________________________________________________________________ - * - * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of - * Trieste INAF - IA2 Italian Center for Astronomical Archives - * _____________________________________________________________________________ - * - * Copyright (C) 2016 Istituto Nazionale di Astrofisica - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License Version 3 as published by the - * Free Software Foundation. - * - * 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., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package it.inaf.ia2.tsm; - -import it.inaf.ia2.tsm.datalayer.DatabaseType; -import it.inaf.ia2.tsm.datalayer.DBWrapper; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; -import javax.sql.DataSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Utility class that contains static methods for managing {@link Key}s and - * {@link KeyColumn}s into the database. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public class DaoKey { -// -// private static final Logger log = LoggerFactory.getLogger(DaoKey.class); -// -// /** -// * Generate list of KeyEntity for a given schema, specifying its -// * <code>DataSource</code> and its name.<br> -// * <strong>IMPORTANT</strong>: this keys are without id. The id has to be -// * set when a table is added to a schema. -// */ -// protected static List<Key> getSchemaKeys(DBWrapper dbWrapper, TapSchema tapSchema, String schemaName) throws SQLException { -// -// log.debug("getSchemaKeys"); -// -// DataSource dataSource = TSMUtil.getSchemaDataSource(dbWrapper, tapSchema, schemaName); -// DatabaseType dbType = TSMUtil.getSchemaDatabaseType(dbWrapper, tapSchema, schemaName); -// -// if (dbType == DatabaseType.MYSQL) { -// -// Map<String, Key> schemaKeys = new HashMap<>(); -// -// String query = "SELECT\n" -// + "c.`CONSTRAINT_NAME` AS constraint_name,\n" -// + "k.`TABLE_SCHEMA` AS from_schema,\n" -// + "k.`TABLE_NAME` AS from_table,\n" -// + "k.`COLUMN_NAME` AS from_column,\n" -// + "k.`REFERENCED_TABLE_SCHEMA` AS target_schema,\n" -// + "k.`REFERENCED_TABLE_NAME` AS target_table,\n" -// + "k.`REFERENCED_COLUMN_NAME` AS target_column\n" -// + "FROM information_schema.TABLE_CONSTRAINTS c \n" -// + "LEFT JOIN information_schema.KEY_COLUMN_USAGE k \n" -// + "ON c.`CONSTRAINT_NAME` = k.`CONSTRAINT_NAME` AND c.`TABLE_SCHEMA` = k.`TABLE_SCHEMA`\n" -// + "WHERE c.`CONSTRAINT_TYPE` = 'FOREIGN KEY' \n" -// + "AND k.`TABLE_SCHEMA` = '" + schemaName + "' OR k.`REFERENCED_TABLE_SCHEMA` = '" + schemaName + "'"; -// -// try (Connection connection = dataSource.getConnection(); -// Statement statement = connection.createStatement(); -// ResultSet resultSet = statement.executeQuery(query)) { -// -// while (resultSet.next()) { -// String constraintName = resultSet.getString("constraint_name"); -// -// Key key = schemaKeys.get(constraintName); -// if (key == null) { -// key = new Key( -// dbWrapper, -// tapSchema, -// resultSet.getString("from_schema"), -// resultSet.getString("from_table"), -// resultSet.getString("target_schema"), -// resultSet.getString("target_table") -// ); -// schemaKeys.put(constraintName, key); -// } -// -// ((Key) key).addKeyColumn(resultSet.getString("from_column"), resultSet.getString("target_column")); -// } -// } -// -// return new ArrayList<>(schemaKeys.values()); -// -// } else if (dbType == DatabaseType.POSTGRES) { -// -// String databaseName -// = schemaName.equals(tapSchema.getName()) -// ? dbWrapper.getTapSchemaCredentials().getDatabase() -// : dbWrapper.getSourceCredentials().getDatabase(); -// -// List<Key> schemaKeys = new ArrayList<>(); -// -// String queryKeys = "SELECT\n" -// + "conname AS constraint_name,\n" -// + "conrelid::regclass AS from_table, \n" -// + "confrelid::regclass AS target_table\n" -// + "FROM pg_catalog.pg_constraint\n" -// + "WHERE contype = 'f'\n" -// + "AND ((conrelid::regclass || '' LIKE '" + schemaName + ".%')\n" -// + "OR (confrelid::regclass || '' LIKE '" + schemaName + ".%'))"; -// -// try (Connection connection = dataSource.getConnection(); -// Statement statement = connection.createStatement(); -// ResultSet resultSet = statement.executeQuery(queryKeys)) { -// -// log.debug("Executing query {}", queryKeys); -// -// while (resultSet.next()) { -// -// String constraintName = resultSet.getString("constraint_name"); -// -// String[] fromTableFullNameSplit = resultSet.getString("from_table").split(Pattern.quote(".")); -// String fromSchema = fromTableFullNameSplit[0]; -// String fromTable = fromTableFullNameSplit[1]; -// -// String[] targetTableFullNameSplit = resultSet.getString("target_table").split(Pattern.quote(".")); -// String targetSchema = targetTableFullNameSplit[0]; -// String targetTable = targetTableFullNameSplit[1]; -// -// Key key = new Key(dbWrapper, tapSchema, fromSchema, fromTable, targetSchema, targetTable); -// schemaKeys.add(key); -// -// // conkey conrelid -// String queryFromKC = "SELECT\n" -// + "c.column_name AS key_column\n" -// + "FROM information_schema.columns c\n" -// + "JOIN pg_catalog.pg_constraint r ON c.ordinal_position = ANY(r.conkey)\n" -// + "AND (c.table_schema || '.' || c.table_name) = (r.conrelid::regclass || '')\n" -// + "WHERE r.conname = '" + constraintName + "' AND r.contype = 'f'\n" -// + "AND c.table_schema = '" + fromSchema + "'\n" -// + "AND table_catalog = '" + databaseName + "'"; -// -// // as above, but with confkey and confrelid and different c.table_schema where condition -// String queryTargetKC = "SELECT\n" -// + "c.column_name AS key_column\n" -// + "FROM information_schema.columns c\n" -// + "JOIN pg_catalog.pg_constraint r ON c.ordinal_position = ANY(r.confkey)\n" -// + "AND (c.table_schema || '.' || c.table_name) = (r.confrelid::regclass || '')\n" -// + "WHERE r.conname = '" + constraintName + "' AND r.contype = 'f'\n" -// + "AND c.table_schema = '" + targetSchema + "'\n" -// + "AND table_catalog = '" + databaseName + "'"; -// -// try (Statement statFromKC = connection.createStatement(); -// Statement statTargetKC = connection.createStatement()) { -// -// try (ResultSet rsFromKC = statFromKC.executeQuery(queryFromKC); -// ResultSet rsTargetKC = statTargetKC.executeQuery(queryTargetKC)) { -// -// log.debug("Executing query {}", queryFromKC); -// log.debug("Executing query {}", queryTargetKC); -// -// while (rsFromKC.next()) { -// if (rsTargetKC.next()) { -// ((Key) key).addKeyColumn( -// rsFromKC.getString("key_column"), -// rsTargetKC.getString("key_column") -// ); -// } -// } -// } -// } -// } -// } -// -// return schemaKeys; -// } else { -// throw new UnsupportedOperationException("Database type " + dbType + " not supported"); -// } -// } -// -// /** -// * Retrieves saved {@code Key}s from the database and add them into the -// * specified {@code TapSchema}. -// */ -// protected static void fillSavedKeys(DBWrapper dbWrapper, TapSchema tapSchema) throws SQLException { -// -// log.debug("fillSavedKeys"); -// -// // We can decide to work only on from tables or target tables, because -// // the same key is contained on both. -// // Schemas and tables have to be already added to the TAP_SCHEMA. -// List<Key> allVisibleKeys = new ArrayList<>(); -// -// // Reset to null all generated keyId. -// for (Key key : ((TapSchema) tapSchema).getAllKeys()) { -// key.initProperty(Key.ID_KEY, null); -// -// // Meanwhile we add all the visible keys to this list for -// // further checks -// if (key.isVisible()) { -// allVisibleKeys.add(key); -// } -// } -// -// // Building query for the keys table -// SelectQueryBuilder keysSelect = new SelectQueryBuilder(dbWrapper.getTapSchemaDatabaseType(), tapSchema, TapSchema.KEYS_TABLE) { -// @Override -// protected TapSchemaEntity getEntity(ResultSet rs) throws SQLException { -// throw new UnsupportedOperationException(); -// } -// }; -// String queryKeys = keysSelect.getQuery(); -// -// // Building query for the key_columns table -// SelectQueryBuilder keyColumnsSelect = new SelectQueryBuilder(dbWrapper.getTapSchemaDatabaseType(), tapSchema, TapSchema.KEY_COLUMNS_TABLE) { -// @Override -// protected TapSchemaEntity getEntity(ResultSet rs) throws SQLException { -// throw new UnsupportedOperationException(); -// } -// }; -// String queryKeyColumns = String.format("%s WHERE %s = ?", -// keyColumnsSelect.getQuery(), -// TSMUtil.escapeName(KeyColumn.KEY_ID_KEY, dbWrapper.getTapSchemaDatabaseType())); -// -// boolean supportKeyID = EntityPropertyInfo.getEntityPropertyInfo(TapSchema.KEYS_TABLE, Key.KEY_ID_KEY).acceptVersion(tapSchema.getVersion()); -// boolean supportKeyColumnID = EntityPropertyInfo.getEntityPropertyInfo(TapSchema.KEY_COLUMNS_TABLE, KeyColumn.KEY_COLUMN_ID_KEY).acceptVersion(tapSchema.getVersion()); -// -// try (Connection conn = dbWrapper.getTapSchemaConnection()) { -// -// log.debug("Executing query {}", queryKeys); -// -// // ResultSet type and concurrency are necessary for PostgreSQL -// try (Statement statementKeys = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); -// ResultSet rsKeys = statementKeys.executeQuery(queryKeys)) { -// -// while (rsKeys.next()) { -// // Searching the keys. -// -// String keyId = rsKeys.getString(Key.ID_KEY); -// String fromTableCompleteNameSplit[] = rsKeys.getString(Key.FROM_TABLE_KEY).split(Pattern.quote(".")); -// String fromSchemaName = fromTableCompleteNameSplit[0]; -// String fromTableName = fromTableCompleteNameSplit[1]; -// -// Schema fromSchema = tapSchema.getChild(fromSchemaName); -// -// if (fromSchema == null) { -// tapSchema.getConsistencyChecks().addUnexistingKey(keyId); -// } else { -// Table fromTable = fromSchema.getChild(fromTableName); -// if (fromTable == null) { -// tapSchema.getConsistencyChecks().addUnexistingKey(keyId); -// } else { -// // ResultSet type and concurrency are necessary for PostgreSQL -// try (PreparedStatement statementKeyColumns = conn.prepareStatement(queryKeyColumns, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)) { -// -// statementKeyColumns.setString(1, keyId); -// log.debug("Executing query {} [key_id={}]", queryKeyColumns, keyId); -// -// try (ResultSet rsKeyColumns = statementKeyColumns.executeQuery()) { -// for (Key fromKey : fromTable.getAllFromKeys()) { -// -// boolean columnsFound = false; -// -// for (KeyColumn keyColumn : fromKey.getKeyColumns()) { -// columnsFound = false; -// -// rsKeyColumns.beforeFirst(); -// while (rsKeyColumns.next()) { -// String fromColumn = rsKeyColumns.getString(KeyColumn.FROM_COLUMN_KEY); -// String targetColumn = rsKeyColumns.getString(KeyColumn.TARGET_COLUMN_KEY); -// if (keyColumn.getFromColumn().equals(fromColumn) -// && keyColumn.getTargetColumn().equals(targetColumn)) { -// columnsFound = true; -// break; -// } -// } -// if (!columnsFound) { -// break; -// } -// } -// -// if (columnsFound) { -// // all columns found --> key found! -// -// // Updating key -// String keyDescription = rsKeys.getString(Key.DESCRIPTION_KEY); -// String keyUtype = rsKeys.getString(Key.UTYPE_KEY); -// -// fromKey.initProperty(Key.ID_KEY, keyId); -// fromKey.initProperty(Key.DESCRIPTION_KEY, keyDescription); -// fromKey.initProperty(Key.UTYPE_KEY, keyUtype); -// if (supportKeyID) { -// fromKey.initProperty(Key.KEY_ID_KEY, TSMUtil.getObject(rsKeys, Key.KEY_ID_KEY, Long.class)); -// } -// ((Key) fromKey).setVisible(true); -// -// // Updating key columns -// for (KeyColumn keyColumn : fromKey.getKeyColumns()) { -// rsKeyColumns.beforeFirst(); -// while (rsKeyColumns.next()) { -// String fromColumn = rsKeyColumns.getString(KeyColumn.FROM_COLUMN_KEY); -// String targetColumn = rsKeyColumns.getString(KeyColumn.TARGET_COLUMN_KEY); -// if (keyColumn.getFromColumn().equals(fromColumn) -// && keyColumn.getTargetColumn().equals(targetColumn)) { -// keyColumn.initProperty(KeyColumn.KEY_ID_KEY, keyId); -// if (supportKeyColumnID) { -// keyColumn.initProperty(KeyColumn.KEY_COLUMN_ID_KEY, TSMUtil.getObject(rsKeyColumns, KeyColumn.KEY_COLUMN_ID_KEY, Long.class)); -// } -// break; -// } -// } -// } -// -// break; -// } -// } -// } -// } -// } -// } -// } -// -// // Check if the saved TAP_SCHEMA contains keys that aren't loaded (fictitious keys). -// List<Key> fictitiousKeys = new ArrayList<>(); -// -// rsKeys.beforeFirst(); -// while (rsKeys.next()) { -// String keyId = rsKeys.getString(Key.ID_KEY); -// boolean keyIdFound = false; -// for (Key key : allVisibleKeys) { -// if (keyId.equals(key.getId())) { -// keyIdFound = true; -// break; -// } -// } -// if (!keyIdFound && !tapSchema.getConsistencyChecks().getUnexistingKeys().contains(keyId)) { -// String fromTableCompleteName = rsKeys.getString(Key.FROM_TABLE_KEY); -// String targetTableCompleteName = rsKeys.getString(Key.TARGET_TABLE_KEY); -// Key key = new Key(dbWrapper, tapSchema, fromTableCompleteName, targetTableCompleteName); -// key.initProperty(Key.ID_KEY, keyId); -// if (supportKeyID) { -// key.initProperty(Key.KEY_ID_KEY, TSMUtil.getObject(rsKeys, Key.KEY_ID_KEY, Long.class)); -// } -// key.setVisible(true); -// fictitiousKeys.add(key); -// -// tapSchema.getChild(key.getFromSchemaName()).getChild(key.getFromTableSimpleName()).addFromKey(key); -// tapSchema.getChild(key.getTargetSchemaName()).getChild(key.getTargetTableSimpleName()).addTargetKey(key); -// } -// } -// -// // filling fictitious keys columns -// for (Key key : fictitiousKeys) { -// try (PreparedStatement statementKeyColumns = conn.prepareStatement(queryKeyColumns)) { -// -// String keyId = key.getId(); -// statementKeyColumns.setString(1, keyId); -// log.debug("Executing query {} [key_id={}]", queryKeyColumns, keyId); -// -// try (ResultSet rsKeyColumns = statementKeyColumns.executeQuery()) { -// -// while (rsKeyColumns.next()) { -// String fromColumn = rsKeyColumns.getString(KeyColumn.FROM_COLUMN_KEY); -// String targetColumn = rsKeyColumns.getString(KeyColumn.TARGET_COLUMN_KEY); -// -// KeyColumn keyColumn = ((Key) key).addKeyColumn(fromColumn, targetColumn); -// if (supportKeyColumnID) { -// keyColumn.initProperty(KeyColumn.KEY_COLUMN_ID_KEY, TSMUtil.getObject(rsKeyColumns, KeyColumn.KEY_COLUMN_ID_KEY, Long.class)); -// } -// } -// } -// } -// -// // adding fictitious key to key set -// ((TapSchema) tapSchema).getAllKeys().add(key); -// } -// -// if (!fictitiousKeys.isEmpty()) { -// log.debug("{} fictitious keys found", fictitiousKeys.size()); -// for (Key key : fictitiousKeys) { -// log.debug(" {}", key); -// } -// } -// -// // Check if there are remaining keys with keyId = null (valid keys -// // that weren't saved into the TAP_SCHEMA). -// int keyId = ((TapSchema) tapSchema).getMaxKeyId() + 1; -// for (Key key : allVisibleKeys) { -// if (key.getId() == null) { -// key.setId(keyId + ""); -// keyId++; -// } -// } -// } -// } -// } -// -// /** -// * Save a new {@code Key} into the TAP_SCHEMA schema. -// */ -// protected static void insertNewKey(DatabaseType dbType, Connection connection, TapSchema tapSchema, Key key) throws SQLException { -// log.debug("insertNewKey"); -// -// InsertQueryBuilder insertQueryBuilder = new InsertQueryBuilder(dbType, tapSchema, key, TapSchema.KEYS_TABLE); -// insertQueryBuilder.executeQuery(connection); -// -// for (KeyColumn keyColumn : key.getKeyColumns()) { -// insertQueryBuilder = new InsertQueryBuilder(dbType, tapSchema, keyColumn, TapSchema.KEY_COLUMNS_TABLE); -// insertQueryBuilder.executeQuery(connection); -// } -// } -// -// /** -// * Updates an existing {@code Key}. -// */ -// protected static void updateKey(DatabaseType dbType, Connection connection, TapSchema tapSchema, Key key) throws SQLException { -// log.debug("updateKey"); -// -// if (key.getId() == null) { -// throw new IllegalStateException("Unable to update key: key_id is null"); -// } -// -// boolean keyIdChanged = key.isChanged(Key.ID_KEY); -// -// if (keyIdChanged) { -// // Deleting key columns to avoid problem with foreign key constraint failures -// -// String tapSchemaNameEscaped = TSMUtil.escapeName(tapSchema.getName(), dbType); -// String keyColumnsNameEscaped = TSMUtil.escapeName("key_columns", dbType); -// -// String query = String.format("DELETE FROM %s.%s WHERE key_id = ?", tapSchemaNameEscaped, keyColumnsNameEscaped); -// -// try (PreparedStatement statement = connection.prepareStatement(query)) { -// String originalKey = key.getOriginalValue(Key.ID_KEY, String.class); -// statement.setString(1, originalKey); -// log.debug("Executing query {} [key_id={}]", query, originalKey); -// statement.executeUpdate(); -// } -// } -// -// // Updating keys -// UpdateQueryBuilder updateQueryBuilder = new UpdateQueryBuilder(dbType, tapSchema, key, TapSchema.KEYS_TABLE, "key_id = ?"); -// String query = updateQueryBuilder.getQuery(); -// try (PreparedStatement statement = connection.prepareStatement(query)) { -// int i = updateQueryBuilder.addStatementValues(statement); -// String keyId = key.getId(); -// statement.setString(i, keyId); -// log.debug("Executing query {} [key_id={}]", query, keyId); -// statement.executeUpdate(); -// } -// -// if (keyIdChanged) { -// // Re-insert deleted key columns -// for (KeyColumn keyColumn : key.getKeyColumns()) { -// InsertQueryBuilder insertQueryBuilder = new InsertQueryBuilder(dbType, tapSchema, keyColumn, TapSchema.KEY_COLUMNS_TABLE); -// insertQueryBuilder.executeQuery(connection); -// } -// } else { -// // Update key columns -// for (KeyColumn keyColumn : key.getKeyColumns()) { -// if (keyColumn.isChanged()) { -// updateQueryBuilder = new UpdateQueryBuilder(dbType, tapSchema, keyColumn, TapSchema.KEY_COLUMNS_TABLE, "key_id = ?"); -// query = updateQueryBuilder.getQuery(); -// try (PreparedStatement statement = connection.prepareStatement(query)) { -// int i = updateQueryBuilder.addStatementValues(statement); -// String keyId = key.getId(); -// statement.setString(i, keyId); -// log.debug("Executing query {} [key_id={}]", query, keyId); -// statement.executeUpdate(); -// } -// } -// } -// } -// } -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoSchema.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoSchema.java deleted file mode 100644 index 74429dde4750563440530033e207bdcbc9229511..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoSchema.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * _____________________________________________________________________________ - * - * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of - * Trieste INAF - IA2 Italian Center for Astronomical Archives - * _____________________________________________________________________________ - * - * Copyright (C) 2016 Istituto Nazionale di Astrofisica - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License Version 3 as published by the - * Free Software Foundation. - * - * 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., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package it.inaf.ia2.tsm; - -import it.inaf.ia2.tsm.datalayer.Credentials; -import it.inaf.ia2.tsm.datalayer.DatabaseType; -import it.inaf.ia2.tsm.datalayer.DBWrapper; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.List; -import javax.sql.DataSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Utility class that contains static methods for managing {@link Schema}s into - * the database. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public class DaoSchema { -// -// private static final Logger log = LoggerFactory.getLogger(DaoSchema.class); -// -// public static List<String> getAllSchemasNames(Credentials credentials) throws SQLException { -// DataSource ds = TSMUtil.createDataSource(credentials); -// return getAllSchemasNames(ds, credentials.getDatabaseType()); -// } -// -// /** -// * Retrieve the list of the names of the all the schemas contained into the -// * database specified by the <code>DataSource</code> parameter. -// * -// * @return list of schemas names alphabetically and case insensitively -// * ordered. -// */ -// public static List<String> getAllSchemasNames(DataSource dataSource, DatabaseType dbType) throws SQLException { -// -// log.debug("getAllSchemasNames"); -// -// String query; -// if (dbType == DatabaseType.MYSQL) { -// query = "SHOW DATABASES"; -// } else if (dbType == DatabaseType.POSTGRES) { -// query = "SELECT schema_name FROM information_schema.schemata"; -// } else { -// throw new UnsupportedOperationException("Database type " + dbType + " not supported"); -// } -// -// log.debug("Executing query {}", query); -// -// List<String> allSchemas = new ArrayList<>(); -// -// try (Connection connection = dataSource.getConnection(); -// Statement statement = connection.createStatement(); -// ResultSet resultSet = statement.executeQuery(query)) { -// while (resultSet.next()) { -// allSchemas.add(resultSet.getString(1)); -// } -// } -// -// log.debug("{} schemas found", allSchemas.size()); -// -// return TSMUtil.sortStringsList(allSchemas); -// } -// -// /** -// * Retrieves saved {@code Schema}s from the database and add them into the -// * specified {@code TapSchema}. -// */ -// protected static void fillSavedSchemas(DBWrapper dbWrapper, final TapSchema tapSchema) throws SQLException { -// -// log.debug("fillSavedSchemas"); -// -// SelectQueryBuilder selectQueryBuilder = new SelectQueryBuilder(dbWrapper.getTapSchemaDatabaseType(), tapSchema, TapSchema.SCHEMAS_TABLE) { -// -// @Override -// protected TapSchemaEntity getEntity(ResultSet rs) throws SQLException { -// String schemaName = rs.getString("schema_name"); -// Schema schema = tapSchema.addChild(schemaName); -// if (schema == null) { -// return null; -// } -// schema.setStatus(Status.ADDED_PERSISTED); -// return schema; -// } -// }; -// -// selectQueryBuilder.executeQuery(dbWrapper.getTapSchemaConnection()); -// } -// -// /** -// * Save a new {@code Schema} into the TAP_SCHEMA schema. -// */ -// protected static void insertNewSchema(DatabaseType dbType, Connection connection, TapSchema tapSchema, Schema schema) throws SQLException { -// -// log.debug("insertNewSchema"); -// -// InsertQueryBuilder insertQueryBuilder = new InsertQueryBuilder(dbType, tapSchema, schema, TapSchema.SCHEMAS_TABLE); -// insertQueryBuilder.executeQuery(connection); -// } -// -// /** -// * Updates an existing {@code Schema}. -// */ -// protected static void updateSchema(DatabaseType dbType, Connection connection, TapSchema tapSchema, Schema schema) throws SQLException { -// -// UpdateQueryBuilder updateQueryBuilder = new UpdateQueryBuilder(dbType, tapSchema, schema, TapSchema.SCHEMAS_TABLE, "schema_name = ?"); -// -// String query = updateQueryBuilder.getQuery(); -// -// try (PreparedStatement statement = connection.prepareStatement(query)) { -// -// log.debug("Executing query {}", query); -// -// int i = updateQueryBuilder.addStatementValues(statement); -// statement.setString(i, schema.getName()); -// -// statement.executeUpdate(); -// } -// } -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoTable.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoTable.java deleted file mode 100644 index 4a42d7f247a8de15b0d00b581bf58d6855363a53..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoTable.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * _____________________________________________________________________________ - * - * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of - * Trieste INAF - IA2 Italian Center for Astronomical Archives - * _____________________________________________________________________________ - * - * Copyright (C) 2016 Istituto Nazionale di Astrofisica - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License Version 3 as published by the - * Free Software Foundation. - * - * 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., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package it.inaf.ia2.tsm; - -import it.inaf.ia2.tsm.datalayer.DatabaseType; -import it.inaf.ia2.tsm.datalayer.DBWrapper; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; -import javax.sql.DataSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Utility class that contains static methods for managing {@link Table}s into - * the database. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public class DaoTable { - -// private static final Logger log = LoggerFactory.getLogger(DaoTable.class); -// -// /** -// * Retrieve the list of the names of all the tables contained in a schema, -// * given its name, also if the schema has never been added into the -// * TAP_SCHEMA. -// * -// * @return list of all tables names alphabetically and case insensitively -// * ordered. -// */ -// public static List<String> getAllTablesNames(DBWrapper dbWrapper, TapSchema tapSchema, String schemaName) throws SQLException { -// -// DataSource dataSource = TSMUtil.getSchemaDataSource(dbWrapper, tapSchema, schemaName); -// DatabaseType dbType = TSMUtil.getSchemaDatabaseType(dbWrapper, tapSchema, schemaName); -// -// String query; -// switch (dbType) { -// case MYSQL: -// query = "SHOW TABLES FROM `" + schemaName + "`"; -// break; -// case POSTGRES: -// query = "SELECT tablename FROM pg_catalog.pg_tables where schemaname = '" + schemaName + "'"; -// break; -// default: -// throw new UnsupportedOperationException("Database type " + dbType + " not supported"); -// } -// -// log.debug("Executing query {}", query); -// -// List<String> allTables = new ArrayList<>(); -// try (Connection connection = dataSource.getConnection(); -// Statement statement = connection.createStatement(); -// ResultSet resultSet = statement.executeQuery(query)) { -// while (resultSet.next()) { -// allTables.add(resultSet.getString(1)); -// } -// } -// -// return TSMUtil.sortStringsList(allTables); -// } -// -// /** -// * Retrieve the association between the tables names and their types -// * (<code>table</code> or <code>view</code>), given a -// * <code>DataSource</code> and a schema name. -// * -// * @return a map which has the tables names as keys and the table types as -// * values. -// */ -// protected static Map<String, String> getTablesTypes(DBWrapper dbWrapper, TapSchema tapSchema, String schemaName) throws SQLException { -// -// log.debug("getTablesTypes"); -// -// final Map<String, String> tablesTypes = new HashMap<>(); -// -// DataSource dataSource = TSMUtil.getSchemaDataSource(dbWrapper, tapSchema, schemaName); -// DatabaseType dbType = TSMUtil.getSchemaDatabaseType(dbWrapper, tapSchema, schemaName); -// -// String query; -// switch (dbType) { -// case MYSQL: -// query = "SELECT table_name, table_type FROM information_schema.tables WHERE table_schema = '" + schemaName + "'"; -// break; -// case POSTGRES: -// query = "SELECT tablename AS table_name, 'table' AS table_type\n" -// + "FROM pg_catalog.pg_tables WHERE schemaname = '" + schemaName + "'\n" -// + "UNION\n" -// + "SELECT table_name AS table_name, 'view' AS table_type\n" -// + "FROM INFORMATION_SCHEMA.views\n" -// + "WHERE table_schema = '" + schemaName + "'"; -// break; -// default: -// throw new UnsupportedOperationException("Database type " + dbType + " not supported"); -// } -// -// log.debug("Executing query {}", query); -// -// try (Connection connection = dataSource.getConnection(); -// Statement statement = connection.createStatement(); -// ResultSet resultSet = statement.executeQuery(query)) { -// while (resultSet.next()) { -// String tableName = resultSet.getString("table_name"); -// String tableType = resultSet.getString("table_type").equalsIgnoreCase("VIEW") ? "view" : "table"; -// tablesTypes.put(tableName, tableType); -// } -// } -// -// return tablesTypes; -// } -// -// /** -// * Retrieves saved {@code Table}s from the database and add them into the -// * specified {@code TapSchema}. -// */ -// protected static void fillSavedTables(DBWrapper dbWrapper, final TapSchema tapSchema) throws SQLException { -// -// log.debug("fillSavedTables"); -// -// SelectQueryBuilder selectQueryBuilder = new SelectQueryBuilder(dbWrapper.getTapSchemaDatabaseType(), tapSchema, TapSchema.TABLES_TABLE) { -// -// @Override -// protected TapSchemaEntity getEntity(ResultSet rs) throws SQLException { -// String schemaName = rs.getString("schema_name"); -// String completeTableName = rs.getString("table_name"); -// -// Schema schema = tapSchema.getChild(schemaName); -// -// if (schema != null) { -// Table table = schema.addChild(completeTableName.split(Pattern.quote("."))[1]); -// if (table == null) { -// return null; -// } -// table.setStatus(Status.ADDED_PERSISTED); -// return table; -// } -// // Schema was marked for removal in the ConsistencyChecks -// return null; -// } -// }; -// -// selectQueryBuilder.executeQuery(dbWrapper.getTapSchemaConnection()); -// } -// -// /** -// * Save a new {@code Table} into the TAP_SCHEMA schema. -// */ -// protected static void insertNewTable(DatabaseType dbType, Connection connection, TapSchema tapSchema, Table table) throws SQLException { -// -// log.debug("insertNewTable"); -// -// InsertQueryBuilder insertQueryBuilder = new InsertQueryBuilder(dbType, tapSchema, table, TapSchema.TABLES_TABLE); -// insertQueryBuilder.executeQuery(connection); -// } -// -// /** -// * Updates an existing {@code Table}. -// */ -// protected static void updateTable(DatabaseType dbType, Connection connection, TapSchema tapSchema, Table table) throws SQLException { -// -// UpdateQueryBuilder updateQueryBuilder = new UpdateQueryBuilder(dbType, tapSchema, table, TapSchema.TABLES_TABLE, "table_name = ?"); -// -// String query = updateQueryBuilder.getQuery(); -// -// try (PreparedStatement statement = connection.prepareStatement(query)) { -// -// log.debug("Executing query {}", query); -// -// int i = updateQueryBuilder.addStatementValues(statement); -// statement.setString(i, table.getCompleteName()); -// -// statement.executeUpdate(); -// } -// } -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntityProperty.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntityProperty.java index 50744201b5ec1128ea859ac28b10396ed11ef5b7..f009cec488d19dbea0a0e6ddc813c0fb82c94eee 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntityProperty.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntityProperty.java @@ -77,6 +77,7 @@ public class EntityProperty<T> implements Serializable { } private <X> void setValue(X value, boolean checkUpdatable) { + assert value == null || value.getClass() == type; if (checkUpdatable && !propertyModel.isUpdatable()) { throw new UnsupportedOperationException("This EntityProperty instance (" + propertyModel.getName() + ") is not updatable"); } @@ -104,6 +105,9 @@ public class EntityProperty<T> implements Serializable { * Initialize the value. */ public final <X> void init(X initialValue) { + if (!propertyModel.isNullable() && initialValue == null) { + initialValue = (X) propertyModel.getDefaultValue(); + } setValue(initialValue, false); this.originalValue = (T) initialValue; } @@ -115,4 +119,12 @@ public class EntityProperty<T> implements Serializable { public Class getType() { return type; } + + public boolean isUpdatable() { + return propertyModel.isUpdatable(); + } + + public boolean isNullable() { + return propertyModel.isNullable(); + } } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/InsertQueryBuilder.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/InsertQueryBuilder.java deleted file mode 100644 index 712c16c38652354efe6ecb50dbfccdcc0eb1e0a2..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/InsertQueryBuilder.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * _____________________________________________________________________________ - * - * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of - * Trieste INAF - IA2 Italian Center for Astronomical Archives - * _____________________________________________________________________________ - * - * Copyright (C) 2016 Istituto Nazionale di Astrofisica - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License Version 3 as published by the - * Free Software Foundation. - * - * 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., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package it.inaf.ia2.tsm; - -import it.inaf.ia2.tsm.datalayer.DatabaseType; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Prepares an {@code INSERT} SQL query for a given {@link TapSchemaEntity} and - * a given {@link TapSchema}. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public class InsertQueryBuilder { -// -// private static final Logger log = LoggerFactory.getLogger(InsertQueryBuilder.class); -// -// private final String query; -// private final List<EntityPropertyInfo> addedProperties; -// private final TapSchemaEntity tapSchemaEntity; -// -// protected InsertQueryBuilder(DatabaseType dbType, TapSchema tapSchema, TapSchemaEntity tapSchemaEntity, String tapSchemaTableName) { -// -// StringBuilder querySb = new StringBuilder("INSERT INTO "); -// querySb.append(TSMUtil.escapeName(tapSchema.getName(), dbType)); -// querySb.append("."); -// querySb.append(TSMUtil.escapeName(tapSchemaTableName, dbType)); -// querySb.append(" ("); -// -// addedProperties = new ArrayList<>(); -// this.tapSchemaEntity = tapSchemaEntity; -// -// boolean first = true; -// for (EntityPropertyInfo propertyInfo : EntityPropertyInfo.getEntityPropertiesInfo(tapSchemaTableName)) { -// if (propertyInfo.acceptVersion(tapSchema.getVersion())) { -// -// if (!first) { -// querySb.append(", "); -// } -// querySb.append(propertyInfo.getPropertyKey()); -// addedProperties.add(propertyInfo); -// first = false; -// } -// } -// querySb.append(") VALUES ("); -// for (int i = 0; i < addedProperties.size(); i++) { -// if (i > 0) { -// querySb.append(","); -// } -// querySb.append("?"); -// } -// querySb.append(")"); -// -// query = querySb.toString(); -// } -// -// protected void executeQuery(Connection connection) throws SQLException { -// -// try (PreparedStatement statement = connection.prepareStatement(query)) { -// log.debug("Executing query {}", query); -// int i = 1; -// for (EntityPropertyInfo property : addedProperties) { -// Object value = tapSchemaEntity.getValue(property.getPropertyKey(), property.getPropertyType()); -// //log.debug(" [{}] {} ({})", i, value, property.getSqlType()); -// statement.setObject(i, value, property.getSqlType()); -// i++; -// } -// statement.executeUpdate(); -// } -// } -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/SelectQueryBuilder.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/SelectQueryBuilder.java deleted file mode 100644 index b3db4d2cebb5cf2087ed62a08c090172640e1480..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/SelectQueryBuilder.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * _____________________________________________________________________________ - * - * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of - * Trieste INAF - IA2 Italian Center for Astronomical Archives - * _____________________________________________________________________________ - * - * Copyright (C) 2016 Istituto Nazionale di Astrofisica - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License Version 3 as published by the - * Free Software Foundation. - * - * 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., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package it.inaf.ia2.tsm; - -import it.inaf.ia2.tsm.datalayer.DatabaseType; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Prepares a {@code SELECT} SQL query for a given {@link TapSchemaEntity} and a - * given {@link TapSchema}. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public abstract class SelectQueryBuilder { -// -// private static final Logger log = LoggerFactory.getLogger(SelectQueryBuilder.class); -// -// private final TapSchema tapSchema; -// private final String query; -// private final List<EntityPropertyInfo> addedProperties; -// -// protected SelectQueryBuilder(DatabaseType dbType, TapSchema tapSchema, String tapSchemaTableName) { -// -// this.tapSchema = tapSchema; -// -// StringBuilder querySb = new StringBuilder("SELECT "); -// -// addedProperties = new ArrayList<>(); -// -// boolean first = true; -// for (EntityPropertyInfo propertyInfo : EntityPropertyInfo.getEntityPropertiesInfo(tapSchemaTableName)) { -// if (propertyInfo.acceptVersion(tapSchema.getVersion())) { -// if (!first) { -// querySb.append(", "); -// } -// querySb.append(propertyInfo.getPropertyKey()); -// addedProperties.add(propertyInfo); -// first = false; -// } -// } -// -// querySb.append(" FROM "); -// -// querySb.append(TSMUtil.escapeName(tapSchema.getName(), dbType)); -// querySb.append("."); -// querySb.append(TSMUtil.escapeName(tapSchemaTableName, dbType)); -// -// query = querySb.toString(); -// } -// -// protected abstract TapSchemaEntity getEntity(ResultSet rs) throws SQLException; -// -// protected void executeQuery(Connection connection) throws SQLException { -// -// log.debug("Executing query {}", query); -// -// try (Statement statement = connection.createStatement(); -// ResultSet rs = statement.executeQuery(query)) { -// -// while (rs.next()) { -// -// TapSchemaEntity entity = getEntity(rs); -// -// if (entity != null) { -// for (EntityPropertyInfo property : addedProperties) { -// String key = property.getPropertyKey(); -// Class type = property.getPropertyType(); -// Object value = TSMUtil.getObject(rs, key, type); -// if (property.isUpdatable()) { -// entity.initProperty(key, value); -// } else { -// Object correctValue = entity.getValue(key, type); -// boolean changed = (correctValue == null && value != null) || (correctValue != null && !correctValue.equals(value)); -// if (changed) { -// -// entity.amendProperty(key, correctValue); -// -// InconsistentValue inconsistentValue = new InconsistentValue( -// TSMUtil.getNaturalLangueName(entity), -// TSMUtil.getName(entity), -// key, -// value, -// correctValue -// ); -// -// tapSchema.getConsistencyChecks().addInconsistency(inconsistentValue); -// -// //throw new InconsistentTapSchemaException(debugInfo); -// } -// } -// } -// } -// } -// } -// } -// -// public String getQuery() { -// return query; -// } -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TSMUtil.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TSMUtil.java index 418914b57c3e8d93a3f7603c1f89a5ba908ebb3f..f0639af4d5ea161f0929455f38a59871ca7c1e19 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TSMUtil.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TSMUtil.java @@ -145,7 +145,7 @@ public class TSMUtil { * </li> * </ul> */ - protected static <T> T getObject(ResultSet rs, String key, Class<T> type) throws SQLException { + public static <T> T getObject(ResultSet rs, String key, Class<T> type) throws SQLException { T ret; if (type == String.class) { ret = (T) rs.getString(key); @@ -168,7 +168,7 @@ public class TSMUtil { /** * Same as {@link DLUtil.getObject(ResultSet, String, Class<T>)}. */ - protected static <T> T getObject(ResultSet rs, int i, Class<T> type) throws SQLException { + public static <T> T getObject(ResultSet rs, int i, Class<T> type) throws SQLException { T ret; if (type == String.class) { ret = (T) rs.getString(i); diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Table.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Table.java index 64461019ce77ef89e3b2b1ed85af22af9f2be2e7..83f24761313c1fee582211a371b5976226a8a703 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Table.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Table.java @@ -206,10 +206,7 @@ public class Table extends ChildEntity<Schema> implements EntitiesContainer<Colu return false; } final Table other = (Table) obj; - if (!Objects.equals(this.getCompleteName(), other.getCompleteName())) { - return false; - } - return true; + return Objects.equals(this.getCompleteName(), other.getCompleteName()); } protected void afterUpdate() { diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchema.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchema.java index e1c285ce1563b4e143230fb0c09e7f1deb7ae449..d8752dbc883ca9ba22f932fe36d03ace86ae1b32 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchema.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchema.java @@ -29,6 +29,7 @@ import it.inaf.ia2.tsm.model.PropertyModel; import it.inaf.ia2.tsm.model.TableModel; import it.inaf.ia2.tsm.model.TapSchemaModel; import it.inaf.ia2.tsm.model.TapSchemaModels; +import it.inaf.ia2.tsm.model.Tasman; import java.io.Serializable; import java.sql.SQLException; import java.util.ArrayList; @@ -36,6 +37,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.TreeMap; import java.util.regex.Pattern; @@ -55,7 +57,9 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { public static final String COLUMNS_TABLE = "columns"; public static final String KEYS_TABLE = "keys"; public static final String KEY_COLUMNS_TABLE = "key_columns"; + public static final String DESCRIPTION_KEY = "description"; + public static final String STD_KEY = "std"; private static final long serialVersionUID = 1678083091602571256L; @@ -118,6 +122,30 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { checkKeys(); } + private void loadSavedProperties(TapSchemaEntity tapSchemaEntity, Map<String, Object> savedProperties) { + for (Map.Entry<String, Object> entry : savedProperties.entrySet()) { + String key = entry.getKey(); + Object savedValue = entry.getValue(); + Object currentValue = entry.getValue(); + EntityProperty ep = tapSchemaEntity.getProperty(key); + + if (!ep.isUpdatable() && !Objects.equals(savedValue, currentValue)) { + + InconsistentValue inconsistentValue = new InconsistentValue( + TSMUtil.getNaturalLangueName(tapSchemaEntity), + TSMUtil.getName(tapSchemaEntity), + key, + savedValue, + savedValue + ); + + consistencyChecks.addInconsistency(inconsistentValue); + } + + tapSchemaEntity.initProperty(key, savedValue); + } + } + /** * Loads saved TAP_SCHEMA data and performs consistency checking. * @@ -133,7 +161,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { if (schema == null) { consistencyChecks.addUnexistingSchema(schemaName); } else { - schema.init(schemaProps); + loadSavedProperties(schema, schemaProps); schema.setStatus(Status.ADDED_PERSISTED); } } @@ -152,7 +180,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { if (table == null) { consistencyChecks.addUnexistingTable(schemaName, tableName); } else { - table.init(tableProps); + loadSavedProperties(table, tableProps); table.setStatus(Status.ADDED_PERSISTED); } } @@ -177,7 +205,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { if (column == null) { consistencyChecks.addUnexistingColumn(tableCompleteName, columnName); } else { - column.init(columnProps); + loadSavedProperties(column, columnProps); column.setStatus(Status.ADDED_PERSISTED); } } @@ -188,19 +216,26 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { List<Map<String, Object>> keysProps = broker.getSavedItems(getName(), getTableModel(KEYS_TABLE)); List<Map<String, Object>> keysColumnsProps = broker.getSavedItems(getName(), getTableModel(KEY_COLUMNS_TABLE)); for (Map<String, Object> keyProp : keysProps) { + + String fromTable = (String) keyProp.get(Key.FROM_TABLE_KEY); + String targetTable = (String) keyProp.get(Key.TARGET_TABLE_KEY); + String keyId = (String) keyProp.get(Key.ID_KEY); + assert keyId != null; + + List<Map<String, Object>> kcPropsById = new ArrayList<>(); + for (Map<String, Object> kcp : keysColumnsProps) { + String keyColumnId = (String) kcp.get(KeyColumn.KEY_ID_KEY); + assert keyColumnId != null; + if (keyColumnId.equals(keyId)) { + kcPropsById.add(kcp); + } + } + // Searching the key boolean keyFound = false; for (Key key : allKeys) { - String fromTable = (String) keyProp.get(Key.FROM_TABLE_KEY); - String targetTable = (String) keyProp.get(Key.TARGET_TABLE_KEY); if (key.getFromTableCompleteName().equals(fromTable) && key.getTargetTableCompleteName().equals(targetTable)) { // Search the key columns having proper key id - List<Map<String, Object>> kcPropsById = new ArrayList<>(); - for (Map<String, Object> kcp : keysColumnsProps) { - if (kcp.get(KeyColumn.KEY_ID_KEY).equals(key.getId())) { - kcPropsById.add(kcp); - } - } // Verifying the matching List<KeyColumn> matchedKeyColumns = new ArrayList<>(); @@ -219,21 +254,40 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { if (kcPropsById.size() == matchedKeyColumns.size()) { keyFound = true; int index = 0; - key.init(keyProp); + loadSavedProperties(key, keyProp); for (Map<String, Object> kcp : kcPropsById) { KeyColumn kc = matchedKeyColumns.get(index); - kc.init(kcp); + loadSavedProperties(kc, kcp); index++; } } } } + if (!keyFound) { - // TODO + boolean setKeyToRemove = true; + if (Tasman.ALLOWS_FICTITIOUS_KEYS) { + // TODO + } + if (setKeyToRemove) { + String[] fromColumns = new String[kcPropsById.size()]; + String[] targetColumns = new String[kcPropsById.size()]; + int i = 0; + for (Map<String, Object> kcp : kcPropsById) { + fromColumns[i] = (String) kcp.get(KeyColumn.FROM_COLUMN_KEY); + targetColumns[i] = (String) kcp.get(KeyColumn.TARGET_COLUMN_KEY); + i++; + } + consistencyChecks.addUnexistingKey(keyId, fromTable, fromColumns, targetTable, targetColumns); + } } } } + public void addFictitiousKey(String fromTable, String[] fromColumns, String targetTable, String[] targetColumns) { + // TODO + } + public DBBroker getDBBroker(String schemaName) { if (schemaName.equals(tapSchemaName)) { return getTapSchemaDBBroker(); @@ -627,14 +681,18 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { */ private void fillTapSchemaDescriptions() { TapSchemaModel tapSchemaModel = getTapSchemaModel(); + boolean hasStd = tapSchemaModel.get(TapSchema.COLUMNS_TABLE).get(STD_KEY) != null; Schema tapSchema = getChild(tapSchemaName); tapSchema.setValue(DESCRIPTION_KEY, tapSchemaModel.getDescription()); for (TableModel tableModel : getTapSchemaModel().getTables().values()) { Table table = tapSchema.getChild(tableModel.getName()); - table.setValue(DESCRIPTION_KEY, tableModel.getDescription()); + tapSchema.setValue(DESCRIPTION_KEY, tableModel.getDescription()); for (PropertyModel propertyModel : tableModel.getProperties().values()) { Column column = table.getChild(propertyModel.getName()); - column.setValue(DESCRIPTION_KEY, propertyModel.getDescription()); + tapSchema.setValue(DESCRIPTION_KEY, propertyModel.getDescription()); + if (hasStd) { + column.setValue(STD_KEY, 1); + } } } } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchemaEntity.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchemaEntity.java index a7705dfeeb01e44934e7e8a0cb500bb5384efab4..5cb250fadbdeb54ecbd81419715808151da9e16a 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchemaEntity.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchemaEntity.java @@ -68,6 +68,14 @@ public abstract class TapSchemaEntity implements Serializable { Object defaultValue = null; if (propModel.getLoaderKey() != null) { defaultValue = metadata.get(propModel.getLoaderKey()); + if (defaultValue != null && propModel.getType() != defaultValue.getClass()) { + // Special case for boolean to integer conversion + if (defaultValue.getClass() == Boolean.class && propModel.getType() == Integer.class) { + defaultValue = ((Boolean) defaultValue) ? 1 : 0; + } else { + throw new UnsupportedOperationException("Unable to convert " + defaultValue.getClass().getCanonicalName() + " into " + propModel.getType()); + } + } } EntityProperty ep = new EntityProperty(propModel, defaultValue); this.properties.put(propModel.getName(), ep); @@ -85,15 +93,6 @@ public abstract class TapSchemaEntity implements Serializable { properties.get(key).init(value); } - /** - * Fill saved properties. - */ - public void init(Map<String, Object> props) { - for (Map.Entry<String, Object> entry : props.entrySet()) { - initProperty(entry.getKey(), entry.getValue()); - } - } - protected String getVersion() { return tapSchema.getVersion(); } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/UpdateQueryBuilder.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/UpdateQueryBuilder.java deleted file mode 100644 index 4f8bbb60373a8f2e28f82dd9313a9b5c632c04ba..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/UpdateQueryBuilder.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * _____________________________________________________________________________ - * - * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of - * Trieste INAF - IA2 Italian Center for Astronomical Archives - * _____________________________________________________________________________ - * - * Copyright (C) 2016 Istituto Nazionale di Astrofisica - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License Version 3 as published by the - * Free Software Foundation. - * - * 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., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package it.inaf.ia2.tsm; - -import it.inaf.ia2.tsm.datalayer.DatabaseType; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Prepares an {@code UPDATE } SQL query for a given {@link TapSchemaEntity} and - * a given {@link TapSchema}. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public class UpdateQueryBuilder { -// -// private static final Logger log = LoggerFactory.getLogger(UpdateQueryBuilder.class); -// -// private final String query; -// private final List<EntityPropertyInfo> addedProperties; -// private final TapSchemaEntity tapSchemaEntity; -// -// protected UpdateQueryBuilder(DatabaseType dbType, TapSchema tapSchema, TapSchemaEntity tapSchemaEntity, String tapSchemaTableName, String whereCondition) { -// -// StringBuilder querySb = new StringBuilder("UPDATE "); -// querySb.append(TSMUtil.escapeName(tapSchema.getName(), dbType)); -// querySb.append("."); -// querySb.append(TSMUtil.escapeName(tapSchemaTableName, dbType)); -// querySb.append("\nSET"); -// -// addedProperties = new ArrayList<>(); -// this.tapSchemaEntity = tapSchemaEntity; -// -// boolean first = true; -// for (EntityPropertyInfo propertyInfo : EntityPropertyInfo.getEntityPropertiesInfo(tapSchemaTableName)) { -// if (propertyInfo.acceptVersion(tapSchema.getVersion()) -// && tapSchemaEntity.isChanged(propertyInfo.getPropertyKey())) { -// -// if (!first) { -// querySb.append(","); -// } -// querySb.append(" "); -// querySb.append(propertyInfo.getPropertyKey()); -// querySb.append(" = ?"); -// addedProperties.add(propertyInfo); -// first = false; -// } -// } -// -// querySb.append("\nWHERE "); -// querySb.append(whereCondition); -// -// query = querySb.toString(); -// } -// -// public String getQuery() { -// return query; -// } -// -// protected int addStatementValues(PreparedStatement statement) throws SQLException { -// int i = 1; -// for (EntityPropertyInfo property : addedProperties) { -// Object value = tapSchemaEntity.getValue(property.getPropertyKey(), property.getPropertyType()); -// statement.setObject(i, value, property.getSqlType()); -// log.debug("\t[{}] {}", property.getPropertyKey(), value); -// i++; -// } -// return i; -// } -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBroker.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBroker.java index d1870434c140f38f3549ef73cfdd92e13a06da0e..768fcaff1e6be4da7ab709ae1d9c1b05e8039c5e 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBroker.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBroker.java @@ -38,12 +38,12 @@ import java.util.Map; */ public interface DBBroker { - Map<String, Map<String, Object>> getColumnsInfo(String schemaName, String tableName) throws SQLException; - List<String> getAllSchemaNames() throws SQLException; List<String> getAllTAPSchemaNames(List<String> allSchemas) throws SQLException; + String detectVersion(String tapSchemaName) throws SQLException; + List<String> getExposedSchemas(String tapSchemaName) throws SQLException; List<String> getAllTablesNames(String schemaName) throws SQLException; diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerFactory.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerFactory.java index 7213c5632bc38be70cf680c92a1a3514bfd1805e..27a947007edc64577ce3488762628566e168d4a5 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerFactory.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerFactory.java @@ -23,6 +23,7 @@ package it.inaf.ia2.tsm.datalayer; import it.inaf.ia2.tsm.datalayer.mysql.MySQLDBBroker; +import it.inaf.ia2.tsm.datalayer.pgsql.PostgresDBBroker; /** * @@ -35,7 +36,8 @@ public class DBBrokerFactory { case MYSQL: return new MySQLDBBroker(dataSourceWrapper.getDataSource()); default: - throw new UnsupportedOperationException(dataSourceWrapper.getDatabaseType() + " not supported yet"); + String pgDatabase = dataSourceWrapper.getCredentials().getDatabase(); + return new PostgresDBBroker(dataSourceWrapper.getDataSource(), pgDatabase); } } } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerTemplate.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerTemplate.java index 5e42f12292c95bb53fe80a7fdd75b3aa459b31bf..685b04e05f546b5ad64f42041481ff9eac42a005 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerTemplate.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerTemplate.java @@ -35,6 +35,7 @@ import it.inaf.ia2.tsm.UpdateOperations; import it.inaf.ia2.tsm.model.PropertyModel; import it.inaf.ia2.tsm.model.TableModel; import it.inaf.ia2.tsm.model.TapSchemaModel; +import it.inaf.ia2.tsm.model.TapSchemaModels; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -44,6 +45,7 @@ import java.sql.Types; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import javax.sql.DataSource; @@ -106,50 +108,57 @@ public abstract class DBBrokerTemplate implements DBBroker { protected abstract void createTable(String tapSchemaName, TableModel tableModel, Connection conn) throws SQLException; - protected abstract void addPrimaryKey(String tapSchemaName, String tableName, String[] keyColumns, Connection conn) throws SQLException; + protected abstract String getAddPrimaryKeyQuery(String tapSchemaName, String tableName, String[] keyColumns); - protected abstract void addForeignKey(String tapSchemaName, String tableName, String[] fromKeyColumns, String targetTableName, String[] toKeyColumns, Connection conn) throws SQLException; + protected abstract String getAddForeignKeyQuery(String tapSchemaName, String tableName, String[] fromKeyColumns, String targetTableName, String[] toKeyColumns); - private void addPrimaryKey(String tapSchemaName, String tableName, String keyColumn, Connection conn) throws SQLException { - addPrimaryKey(tapSchemaName, tableName, new String[]{keyColumn}, conn); + private String getAddPrimaryKeyQuery(String tapSchemaName, String tableName, String keyColumn) { + return getAddPrimaryKeyQuery(tapSchemaName, tableName, new String[]{keyColumn}); } - private void addForeignKey(String tapSchemaName, String tableName, String fromKeyColumn, String targetTableName, String toKeyColumn, Connection conn) throws SQLException { - addForeignKey(tapSchemaName, tableName, new String[]{fromKeyColumn}, targetTableName, new String[]{toKeyColumn}, conn); + private String getAddForeignKeyQuery(String tapSchemaName, String tableName, String fromKeyColumn, String targetTableName, String toKeyColumn) { + return getAddForeignKeyQuery(tapSchemaName, tableName, new String[]{fromKeyColumn}, targetTableName, new String[]{toKeyColumn}); } - protected abstract void createDatabase(String databaseName, Connection conn) throws SQLException; + protected abstract String getCreateDatabaseQuery(String databaseName); + + private void execute(String query, Connection conn) throws SQLException { + try (Statement stat = conn.createStatement()) { + LOG.debug("Executing query: {}", query); + stat.execute(query); + } + } @Override public void createTapSchemaStructure(String tapSchemaName, TapSchemaModel tapSchemaModel) throws SQLException { try (Connection conn = dataSource.getConnection()) { - createDatabase(tapSchemaName, conn); + execute(getCreateDatabaseQuery(tapSchemaName), conn); for (TableModel tableModel : tapSchemaModel.getTables().values()) { createTable(tapSchemaName, tableModel, conn); } // schemas keys - addPrimaryKey(tapSchemaName, TapSchema.SCHEMAS_TABLE, Schema.SCHEMA_NAME_KEY, conn); + execute(getAddPrimaryKeyQuery(tapSchemaName, TapSchema.SCHEMAS_TABLE, Schema.SCHEMA_NAME_KEY), conn); // tables keys - addPrimaryKey(tapSchemaName, TapSchema.TABLES_TABLE, Table.TABLE_NAME_KEY, conn); - addForeignKey(tapSchemaName, TapSchema.TABLES_TABLE, Table.SCHEMA_NAME_KEY, TapSchema.SCHEMAS_TABLE, Schema.SCHEMA_NAME_KEY, conn); + execute(getAddPrimaryKeyQuery(tapSchemaName, TapSchema.TABLES_TABLE, Table.TABLE_NAME_KEY), conn); + execute(getAddForeignKeyQuery(tapSchemaName, TapSchema.TABLES_TABLE, Table.SCHEMA_NAME_KEY, TapSchema.SCHEMAS_TABLE, Schema.SCHEMA_NAME_KEY), conn); // columns keys - addPrimaryKey(tapSchemaName, TapSchema.COLUMNS_TABLE, new String[]{Column.TABLE_NAME_KEY, Column.COLUMN_NAME_KEY}, conn); - addForeignKey(tapSchemaName, TapSchema.COLUMNS_TABLE, Column.TABLE_NAME_KEY, TapSchema.TABLES_TABLE, Table.TABLE_NAME_KEY, conn); + execute(getAddPrimaryKeyQuery(tapSchemaName, TapSchema.COLUMNS_TABLE, new String[]{Column.TABLE_NAME_KEY, Column.COLUMN_NAME_KEY}), conn); + execute(getAddForeignKeyQuery(tapSchemaName, TapSchema.COLUMNS_TABLE, Column.TABLE_NAME_KEY, TapSchema.TABLES_TABLE, Table.TABLE_NAME_KEY), conn); // keys keys - addPrimaryKey(tapSchemaName, TapSchema.KEYS_TABLE, Key.ID_KEY, conn); - addForeignKey(tapSchemaName, TapSchema.KEYS_TABLE, Key.FROM_TABLE_KEY, TapSchema.TABLES_TABLE, Table.TABLE_NAME_KEY, conn); - addForeignKey(tapSchemaName, TapSchema.KEYS_TABLE, Key.TARGET_TABLE_KEY, TapSchema.TABLES_TABLE, Table.TABLE_NAME_KEY, conn); + execute(getAddPrimaryKeyQuery(tapSchemaName, TapSchema.KEYS_TABLE, Key.ID_KEY), conn); + execute(getAddForeignKeyQuery(tapSchemaName, TapSchema.KEYS_TABLE, Key.FROM_TABLE_KEY, TapSchema.TABLES_TABLE, Table.TABLE_NAME_KEY), conn); + execute(getAddForeignKeyQuery(tapSchemaName, TapSchema.KEYS_TABLE, Key.TARGET_TABLE_KEY, TapSchema.TABLES_TABLE, Table.TABLE_NAME_KEY), conn); // key columns key //addPrimaryKey(tapSchemaName, TapSchema.KEY_COLUMNS_TABLE, new String[]{KeyColumn.KEY_ID_KEY, KeyColumn.FROM_COLUMN_KEY, KeyColumn.TARGET_COLUMN_KEY}, conn); - addForeignKey(tapSchemaName, TapSchema.KEY_COLUMNS_TABLE, Key.ID_KEY, TapSchema.KEYS_TABLE, Key.ID_KEY, conn); + execute(getAddForeignKeyQuery(tapSchemaName, TapSchema.KEY_COLUMNS_TABLE, Key.ID_KEY, TapSchema.KEYS_TABLE, Key.ID_KEY), conn); //addForeignKey(tapSchemaName, TapSchema.KEY_COLUMNS_TABLE, KeyColumn.FROM_COLUMN_KEY, TapSchema.COLUMNS_TABLE, Column.COLUMN_NAME_KEY, conn); //addForeignKey(tapSchemaName, TapSchema.KEY_COLUMNS_TABLE, KeyColumn.TARGET_COLUMN_KEY, TapSchema.COLUMNS_TABLE, Column.COLUMN_NAME_KEY, conn); } @@ -407,7 +416,7 @@ public abstract class DBBrokerTemplate implements DBBroker { Map<String, Object> item = new HashMap<>(); for (PropertyModel pm : tableModel.getProperties().values()) { - Object value = rs.getObject(pm.getName(), pm.getType()); + Object value = TSMUtil.getObject(rs, pm.getName(), pm.getType()); item.put(pm.getName(), value); } @@ -608,6 +617,68 @@ public abstract class DBBrokerTemplate implements DBBroker { return allTAPSchemas; } + protected abstract String getColumnNamesQuery(String tapSchemaName, String tableName); + + private List<String> getColumns(String tapSchemaName, String tableName, Connection connection) throws SQLException { + + List<String> columns = new ArrayList<>(); + + String query = getColumnNamesQuery(tapSchemaName, tableName); + LOG.debug("Executing query {}", query); + + try (Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(query)) { + while (resultSet.next()) { + String columnName = resultSet.getString(1); + columns.add(columnName); + } + } + + return columns; + } + + private boolean match(TableModel tableModel, List<String> columns) { + if (tableModel.getProperties().size() != columns.size()) { + return false; + } + for (PropertyModel propertyModel : tableModel.getProperties().values()) { + String columnName = propertyModel.getName(); + if (!columns.contains(columnName)) { + return false; + } + } + return true; + } + + @Override + public String detectVersion(String tapSchemaName) throws SQLException { + + List<String> schemasColumns, tablesColumns, columnsColumns, keyColumns, keyColumnsColumns; + + try (Connection connection = dataSource.getConnection()) { + schemasColumns = getColumns(tapSchemaName, TapSchema.SCHEMAS_TABLE, connection); + tablesColumns = getColumns(tapSchemaName, TapSchema.TABLES_TABLE, connection); + columnsColumns = getColumns(tapSchemaName, TapSchema.COLUMNS_TABLE, connection); + keyColumns = getColumns(tapSchemaName, TapSchema.KEYS_TABLE, connection); + keyColumnsColumns = getColumns(tapSchemaName, TapSchema.KEY_COLUMNS_TABLE, connection); + } + + Iterator<TapSchemaModel> ite = TapSchemaModels.getIterator(); + while (ite.hasNext()) { + TapSchemaModel tapSchemaModel = ite.next(); + + if (match(tapSchemaModel.get(TapSchema.SCHEMAS_TABLE), schemasColumns) + && match(tapSchemaModel.get(TapSchema.TABLES_TABLE), tablesColumns) + && match(tapSchemaModel.get(TapSchema.COLUMNS_TABLE), columnsColumns) + && match(tapSchemaModel.get(TapSchema.KEYS_TABLE), keyColumns) + && match(tapSchemaModel.get(TapSchema.KEY_COLUMNS_TABLE), keyColumnsColumns)) { + return tapSchemaModel.getVersion(); + } + } + + throw new RuntimeException("Unable to detect TAP_SCHEMA version for " + tapSchemaName); + } + protected abstract String getTableTypesQuery(String schemaName); @Override @@ -632,6 +703,7 @@ public abstract class DBBrokerTemplate implements DBBroker { return tablesTypes; } + @Override public List<String> getExposedSchemas(String tapSchemaName) throws SQLException { final List<String> exposedSchemas = new ArrayList<>(); @@ -650,4 +722,34 @@ public abstract class DBBrokerTemplate implements DBBroker { return exposedSchemas; } + + protected abstract String getAllSchemaNamesQuery(); + + @Override + public List<String> getAllSchemaNames() throws SQLException { + String query = getAllSchemaNamesQuery(); + LOG.debug("Executing query: {}", query); + List<String> allSchemas = getAllItemsNames(query); + LOG.debug("{} schemas found", allSchemas.size()); + return allSchemas; + } + + protected abstract String getAllTablesNamesQuery(String schemaName); + + @Override + public List<String> getAllTablesNames(String schemaName) throws SQLException { + String query = getAllTablesNamesQuery(schemaName); + LOG.debug("Executing query: {}", query); + List<String> allTables = getAllItemsNames(query); + LOG.debug("{} tables found", allTables.size()); + return allTables; + } + + @Override + public List<String> getAllColumnsNames(String schemaName, String tableName) throws SQLException { + String query = getColumnNamesQuery(schemaName, tableName); + List<String> allColumns = getAllItemsNames(query); + LOG.debug("{} columns found", allColumns.size()); + return allColumns; + } } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/mysql/MySQLDBBroker.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/mysql/MySQLDBBroker.java index 9998aba85e14e10d372efe3408753a6b6adad830..4acabe5937d7a3065f19fbde14f921f1f3fa7bf2 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/mysql/MySQLDBBroker.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/mysql/MySQLDBBroker.java @@ -54,30 +54,18 @@ public class MySQLDBBroker extends DBBrokerTemplate { } @Override - public Map<String, Map<String, Object>> getColumnsInfo(String schemaName, String tableName) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + protected String getAllSchemaNamesQuery() { + return "SHOW DATABASES"; } @Override - public List<String> getAllSchemaNames() throws SQLException { - List<String> allSchemas = super.getAllItemsNames("SHOW DATABASES"); - LOG.debug("{} schemas found", allSchemas.size()); - return allSchemas; - } - - @Override - public List<String> getAllTablesNames(String schemaName) throws SQLException { - List<String> allTables = super.getAllItemsNames("SHOW TABLES FROM " + escape(schemaName)); - LOG.debug("{} tables found", allTables.size()); - return allTables; + protected String getAllTablesNamesQuery(String schemaName) { + return "SHOW TABLES FROM " + escape(schemaName); } @Override - public List<String> getAllColumnsNames(String schemaName, String tableName) throws SQLException { - String query = String.format("SHOW COLUMNS FROM %s.%s", escape(schemaName), escape(tableName)); - List<String> allColumns = super.getAllItemsNames(query); - LOG.debug("{} columns found", allColumns.size()); - return allColumns; + protected String getColumnNamesQuery(String schemaName, String tableName) { + return String.format("SHOW COLUMNS FROM %s.%s", escape(schemaName), escape(tableName)); } @Override @@ -203,22 +191,14 @@ public class MySQLDBBroker extends DBBrokerTemplate { } @Override - protected void addPrimaryKey(String tapSchemaName, String tableName, String[] keyColumns, Connection conn) throws SQLException { - String query = String.format("ALTER TABLE %s.%s ADD PRIMARY KEY(%s)", escape(tapSchemaName), escape(tableName), buildColumnsList(keyColumns)); - try (Statement stat = conn.createStatement()) { - LOG.debug("Executing query: {}", query); - stat.executeUpdate(query); - } + protected String getAddPrimaryKeyQuery(String tapSchemaName, String tableName, String[] keyColumns) { + return String.format("ALTER TABLE %s.%s ADD PRIMARY KEY(%s)", escape(tapSchemaName), escape(tableName), buildColumnsList(keyColumns)); } @Override - protected void addForeignKey(String tapSchemaName, String tableName, String[] fromKeyColumns, String targetTableName, String[] toKeyColumns, Connection conn) throws SQLException { - String query = String.format("ALTER TABLE %s.%s ADD FOREIGN KEY (%s) REFERENCES %s.%s(%s)", escape(tapSchemaName), escape(tableName), + protected String getAddForeignKeyQuery(String tapSchemaName, String tableName, String[] fromKeyColumns, String targetTableName, String[] toKeyColumns) { + return String.format("ALTER TABLE %s.%s ADD FOREIGN KEY (%s) REFERENCES %s.%s(%s)", escape(tapSchemaName), escape(tableName), buildColumnsList(fromKeyColumns), escape(tapSchemaName), escape(targetTableName), buildColumnsList(toKeyColumns)); - try (Statement stat = conn.createStatement()) { - LOG.debug("Executing query: {}", query); - stat.executeUpdate(query); - } } @Override @@ -292,12 +272,8 @@ public class MySQLDBBroker extends DBBrokerTemplate { } @Override - protected void createDatabase(String databaseName, Connection conn) throws SQLException { - String queryString = "CREATE DATABASE IF NOT EXISTS " + escape(databaseName); - LOG.debug("Executing query: {}", queryString); - try (Statement stat = conn.createStatement()) { - stat.execute(queryString); - } + protected String getCreateDatabaseQuery(String databaseName) { + return "CREATE DATABASE IF NOT EXISTS " + escape(databaseName); } @Override diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/pgsql/PostgresDBBroker.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/pgsql/PostgresDBBroker.java index b27016a043611eada712230b00a385fd6b33aa57..c114cd4e8caab84b57130b6152c7169b3610e7cb 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/pgsql/PostgresDBBroker.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/pgsql/PostgresDBBroker.java @@ -22,15 +22,25 @@ */ package it.inaf.ia2.tsm.datalayer.pgsql; +import it.inaf.ia2.tsm.Column; import it.inaf.ia2.tsm.Key; import it.inaf.ia2.tsm.TapSchema; +import it.inaf.ia2.tsm.datalayer.ADQL; import it.inaf.ia2.tsm.datalayer.DBBrokerTemplate; +import it.inaf.ia2.tsm.model.PropertyModel; import it.inaf.ia2.tsm.model.TableModel; import java.sql.Connection; +import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.regex.Pattern; import javax.sql.DataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @@ -38,68 +48,283 @@ import javax.sql.DataSource; */ public class PostgresDBBroker extends DBBrokerTemplate { - public PostgresDBBroker(DataSource dataSource) { - super(dataSource, '\''); + private final static Logger LOG = LoggerFactory.getLogger(PostgresDBBroker.class); + + private final String pgDatabaseName; + + public PostgresDBBroker(DataSource dataSource, String pgDatabaseName) { + super(dataSource, '"'); + this.pgDatabaseName = pgDatabaseName; } @Override protected void createTable(String tapSchemaName, TableModel tableModel, Connection conn) throws SQLException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } + StringBuilder querySb = new StringBuilder(); - @Override - protected void addPrimaryKey(String tapSchemaName, String tableName, String[] keyColumns, Connection conn) throws SQLException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } + querySb.append("CREATE TABLE IF NOT EXISTS "); + querySb.append(escape(tapSchemaName)); + querySb.append("."); + querySb.append(escape(tableModel.getName())); + querySb.append(" (\n"); - @Override - protected void addForeignKey(String tapSchemaName, String tableName, String[] fromKeyColumns, String targetTableName, String[] toKeyColumns, Connection conn) throws SQLException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } + boolean first = true; + for (PropertyModel pm : tableModel.getProperties().values()) { + if (!first) { + querySb.append(",\n"); + } + first = false; - @Override - protected void createDatabase(String databaseName, Connection conn) throws SQLException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } + querySb.append(pm.getName()); + querySb.append(" "); - @Override - protected String getSchemaTablesQuery(String schemaName) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } + Class type = pm.getType(); + if (type == String.class) { + querySb.append("character varying("); + querySb.append(pm.getSize()); + querySb.append(")"); + } else if (type == Integer.class) { + querySb.append("integer"); + } else if (type == Boolean.class) { + querySb.append("boolean"); + } else if (type == Long.class) { + querySb.append("bigint"); + } else { + throw new UnsupportedOperationException("Column type " + type.getCanonicalName() + " not supported yet!"); + } - @Override - public Map<String, Map<String, Object>> getColumnsInfo(String schemaName, String tableName) throws SQLException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + if (pm.isNullable()) { + querySb.append(" NULL"); + } else { + querySb.append(" NOT NULL"); + } + } + + querySb.append(")"); + + String query = querySb.toString(); + + try (Statement stat = conn.createStatement()) { + LOG.debug("Executing query: {}", query); + stat.executeUpdate(query); + } } @Override - public List<String> getAllSchemaNames() throws SQLException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + protected String getAddPrimaryKeyQuery(String tapSchemaName, String tableName, String[] keyColumns) { + return String.format("ALTER TABLE ONLY %s.%s ADD CONSTRAINT %s_pkey PRIMARY KEY (%s)", + escape(tapSchemaName), escape(tableName), tableName, buildColumnsList(keyColumns)); } @Override - public List<String> getAllTablesNames(String schemaName) throws SQLException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + protected String getAddForeignKeyQuery(String tapSchemaName, String tableName, String[] fromKeyColumns, String targetTableName, String[] toKeyColumns) { + // Building univocal constraint name + StringBuilder constraintNameSb = new StringBuilder(tableName); + for (String fromKeyColumn : fromKeyColumns) { + constraintNameSb.append("_"); + constraintNameSb.append(fromKeyColumn); + } + return String.format("ALTER TABLE ONLY %s.%s ADD CONSTRAINT fk_%s FOREIGN KEY (%s) REFERENCES %s.%s(%s)", + escape(tapSchemaName), escape(tableName), constraintNameSb.toString(), buildColumnsList(fromKeyColumns), + escape(tapSchemaName), escape(targetTableName), buildColumnsList(toKeyColumns)); } @Override - public Map<String, String> getAllTableTypes(String schemaName) throws SQLException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + protected String getCreateDatabaseQuery(String databaseName) { + return "CREATE SCHEMA IF NOT EXISTS " + escape(databaseName); } @Override - public List<String> getAllColumnsNames(String schemaName, String tableName) throws SQLException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + protected String getSchemaTablesQuery(String schemaName) { + return String.format("SELECT tablename FROM pg_catalog.pg_tables where schemaname = '%s'", schemaName); } @Override public Map<String, Map<String, Object>> getAllColumnsMetadata(String schemaName, String tableSimpleName) throws SQLException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + + Map<String, Map<String, Object>> allColumnsMetadata = new HashMap<>(); + + StringBuilder querySb = new StringBuilder(); + + querySb.append("SELECT c.column_name, c.data_type, r.contype AS column_type, c.character_maximum_length, c.numeric_precision\n"); //, c.numeric_precision_radix + querySb.append("FROM information_schema.columns c\n"); + querySb.append("JOIN pg_catalog.pg_tables t ON c.table_schema = t.schemaname AND c.table_name = t.tablename\n"); + querySb.append("LEFT JOIN pg_catalog.pg_constraint r ON c.ordinal_position = ANY(r.conkey) AND r.conrelid = (t.schemaname || '.' || t.tablename)::regclass::oid\n"); + querySb.append("WHERE t.schemaname = '"); + querySb.append(schemaName); + querySb.append("' AND t.tablename = '"); + querySb.append(tableSimpleName); + querySb.append("'"); + + String query = querySb.toString(); + LOG.debug("Executing query {}", query); + + try (Connection conn = dataSource.getConnection(); + Statement statement = conn.createStatement(); + ResultSet resultSet = statement.executeQuery(query)) { + + while (resultSet.next()) { + + Map<String, Object> cm = new HashMap<>(); + + // Column name + String columnName = resultSet.getString("column_name"); + cm.put(Column.COLUMN_NAME_KEY, columnName); + + // Key info + String columnType = resultSet.getString("column_type"); + boolean primaryKey = false; + boolean indexed = false; + if (columnType != null) { + primaryKey = "p".equals(columnType); + if ("p".equals(columnType) + || "f".equals(columnType) + || "u".equals(columnType)) { + indexed = true; + } + } + cm.put(Column.PRIMARY_KEY, primaryKey); + cm.put(Column.INDEXED_KEY, indexed); + + int size = 0; + String datatype; + + String type = resultSet.getString("data_type"); + + if (type.startsWith("int")) { + datatype = ADQL.INTEGER; + } else if (type.startsWith("smallint")) { + datatype = ADQL.SMALLINT; + } else if (type.startsWith("bigint")) { + datatype = ADQL.BIGINT; + } else if (type.startsWith("double") || type.startsWith("real")) { + datatype = ADQL.REAL; + } else if (type.startsWith("character varying")) { + datatype = ADQL.VARCHAR; + size = resultSet.getInt("character_maximum_length"); + } else if (type.startsWith("char")) { + datatype = ADQL.CHAR; + size = resultSet.getInt("character_maximum_length"); + } else if (type.contains("timestamp")) { + datatype = ADQL.TIMESTAMP; + } else { + datatype = ADQL.getDataType(type); + } + + cm.put(Column.DATATYPE_KEY, datatype); + cm.put(Column.SIZE_KEY, size); + + Integer arraySize = null; // TODO (v 1.1) + + allColumnsMetadata.put(columnName, cm); + } + } + + return allColumnsMetadata; } @Override public List<Key> getKeys(TapSchema tapSchema, String schemaName) throws SQLException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + + StringBuilder queryKeysSb = new StringBuilder(); + + queryKeysSb.append("SELECT\n"); + queryKeysSb.append("conname AS constraint_name,\n"); + queryKeysSb.append("conrelid::regclass AS from_table, \n"); + queryKeysSb.append("confrelid::regclass AS target_table\n"); + queryKeysSb.append("FROM pg_catalog.pg_constraint\n"); + queryKeysSb.append("WHERE contype = 'f'\n"); + queryKeysSb.append("AND ((conrelid::regclass || '' LIKE '"); + queryKeysSb.append(schemaName); + queryKeysSb.append(".%')\n"); + queryKeysSb.append("OR (confrelid::regclass || '' LIKE '"); + queryKeysSb.append(schemaName); + queryKeysSb.append(".%'))"); + + String queryKeys = queryKeysSb.toString(); + + try (Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(queryKeys)) { + + LOG.debug("Executing query {}", queryKeys); + + List<Key> keys = new ArrayList<>(); + while (resultSet.next()) { + + String constraintName = resultSet.getString("constraint_name"); + + String fromTableCompleteName = resultSet.getString("from_table"); + String targetTableCompleteName = resultSet.getString("target_table"); + + String fromSchema = fromTableCompleteName.split(Pattern.quote("."))[0]; + String targetSchema = targetTableCompleteName.split(Pattern.quote("."))[0]; + + Map<String, Object> keyMetadata = new HashMap<>(); + keyMetadata.put(Key.FROM_TABLE_KEY, fromTableCompleteName); + keyMetadata.put(Key.TARGET_TABLE_KEY, targetTableCompleteName); + + Key key = new Key(tapSchema, keyMetadata); + keys.add(key); + + StringBuilder queryFromKCSb = new StringBuilder(); + queryFromKCSb.append("SELECT\n"); + queryFromKCSb.append("c.column_name AS key_column\n"); + queryFromKCSb.append("FROM information_schema.columns c\n"); + queryFromKCSb.append("JOIN pg_catalog.pg_constraint r ON c.ordinal_position = ANY(r.conkey)\n"); + queryFromKCSb.append("AND (c.table_schema || '.' || c.table_name) = (r.conrelid::regclass || '')\n"); + queryFromKCSb.append("WHERE r.conname = '"); + queryFromKCSb.append(constraintName); + queryFromKCSb.append("' AND r.contype = 'f'\n"); + queryFromKCSb.append("AND c.table_schema = '"); + queryFromKCSb.append(fromSchema); + queryFromKCSb.append("'\nAND table_catalog = '"); + queryFromKCSb.append(pgDatabaseName); + queryFromKCSb.append("'"); + + // conkey conrelid + String queryFromKC = queryFromKCSb.toString(); + + StringBuilder queryTargetKCSb = new StringBuilder(); + queryTargetKCSb.append("SELECT\n"); + queryTargetKCSb.append("c.column_name AS key_column\n"); + queryTargetKCSb.append("FROM information_schema.columns c\n"); + queryTargetKCSb.append("JOIN pg_catalog.pg_constraint r ON c.ordinal_position = ANY(r.confkey)\n"); + queryTargetKCSb.append("AND (c.table_schema || '.' || c.table_name) = (r.confrelid::regclass || '')\n"); + queryTargetKCSb.append("WHERE r.conname = '"); + queryTargetKCSb.append(constraintName); + queryTargetKCSb.append("' AND r.contype = 'f'\n"); + queryTargetKCSb.append("AND c.table_schema = '"); + queryTargetKCSb.append(targetSchema); + queryTargetKCSb.append("'\nAND table_catalog = '"); + queryTargetKCSb.append(pgDatabaseName); + queryTargetKCSb.append("'"); + + // as above, but with confkey and confrelid and different c.table_schema where condition + String queryTargetKC = queryTargetKCSb.toString(); + + try (Statement statFromKC = connection.createStatement(); + Statement statTargetKC = connection.createStatement()) { + + try (ResultSet rsFromKC = statFromKC.executeQuery(queryFromKC); + ResultSet rsTargetKC = statTargetKC.executeQuery(queryTargetKC)) { + + LOG.debug("Executing query {}", queryFromKC); + LOG.debug("Executing query {}", queryTargetKC); + + while (rsFromKC.next()) { + if (rsTargetKC.next()) { + key.addKeyColumn( + rsFromKC.getString("key_column"), + rsTargetKC.getString("key_column") + ); + } + } + } + } + } + + return keys; + } } @Override @@ -117,4 +342,20 @@ public class PostgresDBBroker extends DBBrokerTemplate { sb.append("'"); return sb.toString(); } + + @Override + protected String getColumnNamesQuery(String tapSchemaName, String tableName) { + return String.format("SELECT column_name FROM information_schema.columns WHERE table_schema = '%s' AND table_name = '%s'", + tapSchemaName, tableName); + } + + @Override + protected String getAllSchemaNamesQuery() { + return "SELECT schema_name FROM information_schema.schemata"; + } + + @Override + protected String getAllTablesNamesQuery(String schemaName) { + return String.format("SELECT tablename FROM pg_catalog.pg_tables where schemaname = '%s'", schemaName); + } } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyModel.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyModel.java index 3be665214e7e35ed400e93b4c12d8a09276c3a90..77f4ab5c90d58a3298cfefdd2bdccecf63921ea7 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyModel.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyModel.java @@ -39,6 +39,7 @@ public class PropertyModel implements Serializable { private boolean updatable; private boolean nullable; private String loaderKey; + private Object defaultValue; private PropertyModel() { } @@ -52,6 +53,22 @@ public class PropertyModel implements Serializable { updatable = propertyXMLModel.isUpdatable(); nullable = propertyXMLModel.isNullable(); loaderKey = propertyXMLModel.getLoaderKey(); + if (propertyXMLModel.getDefaultValue() != null) { + String strDefVal = propertyXMLModel.getDefaultValue(); + if (type == String.class) { + defaultValue = strDefVal; + } else if (type == Integer.class) { + defaultValue = Integer.parseInt(strDefVal); + } else if (type == Double.class) { + defaultValue = Double.parseDouble(strDefVal); + } else if (type == Long.class) { + defaultValue = Long.parseLong(strDefVal); + } else if (type == Float.class) { + defaultValue = Float.parseFloat(strDefVal); + } else { + throw new UnsupportedOperationException("Default value for type " + type.getCanonicalName() + " not supported yet."); + } + } } catch (ClassNotFoundException e) { throw new ExceptionInInitializerError( "Invalid property type for property " + propertyXMLModel.getName() @@ -86,4 +103,8 @@ public class PropertyModel implements Serializable { public String getLoaderKey() { return loaderKey; } + + public Object getDefaultValue() { + return defaultValue; + } } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyXMLModel.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyXMLModel.java index 2746abfe46e238a7afa74467e15f095f132ed952..878c761efaa8bd651f44980bee799ba6cadd30d7 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyXMLModel.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyXMLModel.java @@ -35,6 +35,7 @@ public class PropertyXMLModel { private Integer size; private boolean updatable; private boolean nullable; + private String defaultValue; private String loaderKey; private String description; @@ -89,6 +90,15 @@ public class PropertyXMLModel { this.nullable = nullable; } + @XmlElement(name = "default-value") + public String getDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + @XmlElement(name = "key") public String getLoaderKey() { return loaderKey; diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TapSchemaModels.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TapSchemaModels.java index 25fc5be080fb4a2b4bed7f298c35638121a3914d..1721f6152041a229ebccb3787456a346e8f518fc 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TapSchemaModels.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TapSchemaModels.java @@ -22,10 +22,8 @@ */ package it.inaf.ia2.tsm.model; -import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.net.URISyntaxException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; diff --git a/TASMAN-core/src/main/resources/tap_schema/tap_schema-1-IA2.xml b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1-IA2.xml index 70e1638b275326fccd1aaa7afdd392dd0d2ae4a2..40f909f1f3b2e9b69d90e2532bc8f97bc00fd72e 100644 --- a/TASMAN-core/src/main/resources/tap_schema/tap_schema-1-IA2.xml +++ b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1-IA2.xml @@ -47,6 +47,11 @@ Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. <type>java.lang.Long</type> <updatable>true</updatable> </property> + <property> + <name>id</name> + <type>java.lang.Integer</type> + <updatable>true</updatable> + </property> </add> </table> <table name="keys"> diff --git a/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml index 26c5446c8da15b60198b0cbe55f402a39191ef67..8dbc01479ecab0a4d92c15856375888552623432 100644 --- a/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml +++ b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml @@ -160,22 +160,27 @@ Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. </property> <property> <name>indexed</name> - <type>java.lang.Boolean</type> + <type>java.lang.Integer</type> <updatable>false</updatable> + <nullable>false</nullable> <key>indexed</key> - <description>an indexed column; 1 means 1, 0 means 0</description> + <description>an indexed column; 1 means true, 0 means false</description> </property> <property> <name>principal</name> - <type>java.lang.Boolean</type> + <type>java.lang.Integer</type> <updatable>true</updatable> - <description>a principal column; 1 means 1, 0 means 0</description> + <nullable>false</nullable> + <default-value>0</default-value> + <description>a principal column; 1 means true, 0 means false</description> </property> <property> <name>std</name> - <type>java.lang.Boolean</type> - <updatable>true</updatable> - <description>a standard column; 1 means 1, 0 means 0</description> + <type>java.lang.Integer</type> + <updatable>true</updatable> + <nullable>false</nullable> + <default-value>0</default-value> + <description>a standard column; 1 means true, 0 means false</description> </property> </add> </table> diff --git a/TASMAN-core/src/test/java/it/inaf/ia2/tsm/api/TestAll.java b/TASMAN-core/src/test/java/it/inaf/ia2/tsm/TestAll.java similarity index 98% rename from TASMAN-core/src/test/java/it/inaf/ia2/tsm/api/TestAll.java rename to TASMAN-core/src/test/java/it/inaf/ia2/tsm/TestAll.java index 6b67e26b778037e8b595184cf2b8cc2313946e4b..e68aa982c6a2d2b65ebb23cd67f7a6a800461f79 100644 --- a/TASMAN-core/src/test/java/it/inaf/ia2/tsm/api/TestAll.java +++ b/TASMAN-core/src/test/java/it/inaf/ia2/tsm/TestAll.java @@ -20,19 +20,11 @@ * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package it.inaf.ia2.tsm.api; +package it.inaf.ia2.tsm; -import it.inaf.ia2.tsm.UpdateOperations; import it.inaf.ia2.tsm.datalayer.DBWrapper; -import it.inaf.ia2.tsm.Table; -import it.inaf.ia2.tsm.KeyColumn; -import it.inaf.ia2.tsm.TapSchema; -import it.inaf.ia2.tsm.Schema; -import it.inaf.ia2.tsm.Column; import it.inaf.ia2.tsm.datalayer.DatabaseType; import it.inaf.ia2.tsm.datalayer.Credentials; -import it.inaf.ia2.tsm.Status; -import it.inaf.ia2.tsm.Key; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -95,7 +87,7 @@ public class TestAll { dbWrapper = new DBWrapper(postgresCredentials); dbWrapper.testConnections(); - //dbWrappers.add(dbWrapper); + dbWrappers.add(dbWrapper); // Mix! //dbWrappers.add(new DBWrapper(mysqlCredentials, postgresCredentials)); @@ -461,6 +453,7 @@ public class TestAll { // reloading LOG.debug("----- Reloading saved TAP_SCHEMA -----"); tapSchema = new TapSchema("1.0", dbWrapper, "test_tap_schema", true); + assertEquals("1.0", tapSchema.getTapSchemaDBBroker().detectVersion(tapSchema.getName())); LOG.debug(tapSchema.toString()); assertNotNull(sch0 = tapSchema.getChild("sch0", Status.ADDED_PERSISTED)); diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SchemaSelectionBean.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SchemaSelectionBean.java index 1a2f6556e8122e07714368bccc2da4c9d7975e81..337614c8bb5bb068e0cb1faeb5a159192c9757c2 100644 --- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SchemaSelectionBean.java +++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SchemaSelectionBean.java @@ -26,9 +26,13 @@ import it.inaf.ia2.tsm.TapSchema; import it.inaf.ia2.tsm.datalayer.DBBroker; import it.inaf.ia2.tsm.datalayer.DBBrokerFactory; import it.inaf.ia2.tsm.datalayer.DBWrapper; +import it.inaf.ia2.tsm.model.TapSchemaModel; +import it.inaf.ia2.tsm.model.TapSchemaModels; import java.io.Serializable; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; import java.util.List; import javax.annotation.PostConstruct; import javax.faces.application.FacesMessage; @@ -48,18 +52,18 @@ import org.slf4j.LoggerFactory; @Named("schemaSelection") @WindowScoped public class SchemaSelectionBean implements Serializable { - + private static final long serialVersionUID = -5745720427701334323L; private static final Logger LOG = LoggerFactory.getLogger(SchemaSelectionBean.class); - + @Inject TapSchemaEditingBean tapSchemaEditingBean; - + @Inject ConsistencyChecksBean consistencyChecksBean; - + private DBWrapper dbWrapper; - + private String selectedRadioOption; // For editing @@ -69,28 +73,37 @@ public class SchemaSelectionBean implements Serializable { // For creation private String tapSchemaName; + private List<String> versions; + private String version; private List<String> allSchemas; private List<String> selectedSchemas; private boolean loading; private TapSchema loadedTapSchema; private String loadingError; - + @PostConstruct public void init() { selectedRadioOption = "edit"; exposedSchemas = ""; + versions = new ArrayList<>(); + Iterator<TapSchemaModel> ite = TapSchemaModels.getIterator(); + while (ite.hasNext()) { + TapSchemaModel model = ite.next(); + versions.add(model.getVersion()); + } + Collections.sort(versions); } - + public void onPageLoad() { FacesContext fc = FacesContext.getCurrentInstance(); final boolean ajaxRequest = fc.getPartialViewContext().isAjaxRequest(); final boolean validationFailed = fc.isValidationFailed(); - + if (!ajaxRequest && !validationFailed) { // Loading all schemas of the source database try { - DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getSourceDataSourceWrapper()); + DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getSourceDataSourceWrapper()); allSchemas = broker.getAllSchemaNames(); setSelectedSchemas(new ArrayList<String>()); } catch (SQLException e) { @@ -99,9 +112,9 @@ public class SchemaSelectionBean implements Serializable { // Loading all schemas of the TAP_SCHEMA database try { - DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getTapSchemaDataSourceWrapper()); + DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getTapSchemaDataSourceWrapper()); allTAPSchemas = broker.getAllTAPSchemaNames(allSchemas); - + if (!allTAPSchemas.isEmpty()) { this.selectedTAPSchema = allTAPSchemas.get(0); loadExposedSchemas(); @@ -111,7 +124,7 @@ public class SchemaSelectionBean implements Serializable { } } } - + private void loadExposedSchemas() throws SQLException { DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getTapSchemaDataSourceWrapper()); List<String> schemas = broker.getExposedSchemas(selectedTAPSchema); @@ -123,35 +136,35 @@ public class SchemaSelectionBean implements Serializable { } } } - + public List<String> getAllTAPSchemas() { return allTAPSchemas; } - + public List<String> getAllSchemas() { return allSchemas; } - + public String getExposedSchemas() { return exposedSchemas; } - + public String getSelectedRadioOption() { return selectedRadioOption; } - + public void setSelectedRadioOption(String selectedRadioOption) { this.selectedRadioOption = selectedRadioOption; } - + public String getSelectedTAPSchema() { return selectedTAPSchema; } - + public void setSelectedTAPSchema(String selectedTAPSchema) { this.selectedTAPSchema = selectedTAPSchema; } - + public void selectedTAPSchemaChanged() { try { loadExposedSchemas(); @@ -159,15 +172,15 @@ public class SchemaSelectionBean implements Serializable { throw new RuntimeException(e); } } - + public List<String> getSelectedSchemas() { return selectedSchemas; } - + public void setSelectedSchemas(List<String> selectedSchemas) { this.selectedSchemas = selectedSchemas; } - + public String openLoaded() { if (loadedTapSchema.getConsistencyChecks().isInconsistent()) { consistencyChecksBean.setDbWrapper(dbWrapper); @@ -178,18 +191,20 @@ public class SchemaSelectionBean implements Serializable { return "tapSchemaEditing.xhtml?faces-redirect=true"; } } - + public void edit() { - + loadedTapSchema = null; loading = true; loadingError = null; - + new Thread(new Runnable() { @Override public void run() { try { - loadedTapSchema = new TapSchema("1.0-IA2", dbWrapper, selectedTAPSchema, true); + DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getTapSchemaDataSourceWrapper()); + String version = broker.detectVersion(selectedTAPSchema); + loadedTapSchema = new TapSchema(version, dbWrapper, selectedTAPSchema, true); } catch (Throwable e) { LOG.error("Exception caught", e); loadingError = e.getMessage(); @@ -201,48 +216,54 @@ public class SchemaSelectionBean implements Serializable { } }).start(); } - + public void create() { - + loadedTapSchema = null; loading = true; loadingError = null; - + new Thread(new Runnable() { @Override public void run() { try { - loadedTapSchema = new TapSchema("1.0-IA2", dbWrapper, tapSchemaName, false); + loadedTapSchema = new TapSchema(version, dbWrapper, tapSchemaName, false); for (String schemaName : selectedSchemas) { loadedTapSchema.addChild(schemaName); } } catch (Throwable e) { - loadingError = e.getMessage(); + LOG.error("Exception caught", e); + if (e.getMessage() != null) { + loadingError = e.getMessage(); + } else { + loadingError = e.getClass().getCanonicalName(); + loadedTapSchema = null; + } } loading = false; } }).start(); } - + public String getTapSchemaName() { return tapSchemaName; } - + public void setTapSchemaName(String tapSchemaName) { this.tapSchemaName = tapSchemaName; } - + public DBWrapper getDbWrapper() { return dbWrapper; } - + public void setDbWrapper(DBWrapper dbWrapper) { this.dbWrapper = dbWrapper; } - + public void validateTapSchemaName(FacesContext context, UIComponent inputComponent, Object value) { String textValue = (String) value; - + String validatorMessage = null; if (textValue == null || textValue.isEmpty()) { validatorMessage = "TAP_SCHEMA name is required"; @@ -251,7 +272,7 @@ public class SchemaSelectionBean implements Serializable { } else if (allSchemas.contains(textValue)) { validatorMessage = "Database already contains a schema with this name. Please choose another name"; } - + if (validatorMessage != null) { throw new ValidatorException(new FacesMessage(validatorMessage)); } @@ -271,8 +292,20 @@ public class SchemaSelectionBean implements Serializable { public String getLoadingError() { return loadingError; } - + public TapSchema getLoadedTapSchema() { return loadedTapSchema; } + + public List<String> getVersions() { + return versions; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } } diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaEditingBean.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaEditingBean.java index 5faedbe6e54d5c481e3458a830f830db2bc12ff7..66fd74860ae5cfa7acd20a0ddb565f273f88af4b 100644 --- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaEditingBean.java +++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaEditingBean.java @@ -137,6 +137,7 @@ public class TapSchemaEditingBean implements Serializable { sb.append(", "); } sb.append(key); + first = false; } } return sb.toString(); @@ -415,4 +416,42 @@ public class TapSchemaEditingBean implements Serializable { } } } + + /** + * In TAP_SCHEMA 1.0 std column has an integer data type and use 1 for true + * and 0 for false, but we want to edit it using a JSF booleanCheckbox, so + * we need this workaround pairs of getter and setter. + */ + public Boolean getStd() { + Column column = getSelectedColumn(); + if (column != null && column.getProperty("std") != null) { + return column.getValue("std", Integer.class) == 1; + } + return null; + } + + public void setStd(Boolean value) { + Column column = getSelectedColumn(); + if (column != null) { + column.setValue("std", value ? 1 : 0); + } + } + + /** + * Same of getStd(). + */ + public Boolean getPrincipal() { + Column column = getSelectedColumn(); + if (column != null && column.getProperty("principal") != null) { + return column.getValue("principal", Integer.class) == 1; + } + return null; + } + + public void setPrincipal(Boolean value) { + Column column = getSelectedColumn(); + if (column != null) { + column.setValue("principal", value ? 1 : 0); + } + } } diff --git a/TASMAN-webapp/src/main/webapp/resources/js/async-loader.js b/TASMAN-webapp/src/main/webapp/resources/js/async-loader.js index 5409768d0148f5342ba2c6d2e5ba6c143a5ebee8..0f2e31d7a68f8ee793daa7da8947fb15b3742c50 100644 --- a/TASMAN-webapp/src/main/webapp/resources/js/async-loader.js +++ b/TASMAN-webapp/src/main/webapp/resources/js/async-loader.js @@ -28,7 +28,7 @@ loading = l; }, startChecking: function (event) { - if (event.status === 'success') { + if (event.status === 'success' && $('.validation-message').length === 0) { periodicCheck(); } } diff --git a/TASMAN-webapp/src/main/webapp/schemaSelection.xhtml b/TASMAN-webapp/src/main/webapp/schemaSelection.xhtml index be96e137fe0769269b665230697d3b1087d36c5a..c547e56dc7e172ecbe4f738a1d04b93f4e1ce881 100644 --- a/TASMAN-webapp/src/main/webapp/schemaSelection.xhtml +++ b/TASMAN-webapp/src/main/webapp/schemaSelection.xhtml @@ -73,7 +73,16 @@ <div class="form-group"> <h:outputLabel for="tapschemaName">Name:</h:outputLabel> <h:inputText id="tapschemaName" value="#{schemaSelection.tapSchemaName}" class="form-control" validator="#{schemaSelection.validateTapSchemaName}" /> - <h:message for="tapschemaName" class="text-danger"></h:message> + <h:message for="tapschemaName" class="text-danger validation-message"></h:message> + </div> + + <div class="form-group"> + <h:outputLabel for="tapschemaVersion">Version:</h:outputLabel> + <h:selectOneMenu id="tapschemaVersion" value="#{schemaSelection.version}" class="form-control" required="true" requiredMessage="Select version"> + <f:selectItem itemValue="#{null}" itemLabel="Select..." noSelectionOption="true" /> + <f:selectItems value="#{schemaSelection.versions}" var="v" itemLabel="TAP_SCHEMA #{v}" itemValue="#{v}" /> + </h:selectOneMenu> + <h:message for="tapschemaVersion" class="text-danger validation-message"></h:message> </div> <div class="form-group"> @@ -82,7 +91,7 @@ <f:selectItems value="#{schemaSelection.allSchemas}"></f:selectItems> <f:validateRequired></f:validateRequired> </h:selectManyListbox> - <h:message for="selectedSchemas" class="text-danger"></h:message> + <h:message for="selectedSchemas" class="text-danger validation-message"></h:message> </div> <div class="form-group"> diff --git a/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml b/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml index cb7d6c04d09d4afc1dd99d56cee3e24bfedfb362..aa37b0f285d2795a6becf8cd841ffe5b7a8a1b6f 100644 --- a/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml +++ b/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml @@ -276,7 +276,7 @@ <div class="checkbox"> <label> <h:selectBooleanCheckbox - value="#{tapSchemaEditing.selectedColumn.getProperty('std').value}" + value="#{tapSchemaEditing.std}" class="#{tapSchemaEditing.selectedColumn.isChanged('std') ? 'changed' : ''}"> <f:ajax execute="@form" render="@this" /> </h:selectBooleanCheckbox> @@ -288,7 +288,7 @@ <div class="checkbox"> <label> <h:selectBooleanCheckbox - value="#{tapSchemaEditing.selectedColumn.getProperty('principal').value}" + value="#{tapSchemaEditing.principal}" class="#{tapSchemaEditing.selectedColumn.isChanged('principal') ? 'changed' : ''}"> <f:ajax execute="@form" render="@this" /> </h:selectBooleanCheckbox>