diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/ChildEntity.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ChildEntity.java similarity index 65% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/ChildEntity.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/ChildEntity.java index 4f55929696ffb7115371793703f15d609d99193a..e6e9e5ddff14a1e9795271d3f4cdcb05df1f1106 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/ChildEntity.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ChildEntity.java @@ -20,7 +20,10 @@ * 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.contract; +package it.inaf.ia2.tsm; + +import it.inaf.ia2.tsm.xmlmodel.TableModel; +import java.util.Map; /** * A {@link TapSchemaEntity} that can be a child of an @@ -28,23 +31,44 @@ package it.inaf.ia2.tsm.api.contract; * * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} */ -public interface ChildEntity<T extends EntitiesContainer> extends TapSchemaEntity { +public abstract class ChildEntity<T extends EntitiesContainer> extends TapSchemaEntity { + + private static final long serialVersionUID = -8941059435527998685L; + + private Status status; + + protected ChildEntity() { + } + + public ChildEntity(TapSchema tapSchema, TableModel tableModel, Map<String, Object> metadata) { + super(tapSchema, tableModel, metadata); + } /** - * Each child has a name that is univocal for a given parent, in this way - * the parent can search a child by name. + * The persistence status of the {@link ChildEntity}. */ - String getName(); + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + + @Override + public void save() { + setStatus(Status.ADDED_PERSISTED); + super.save(); + } /** - * The {@link EntitiesContainer} that owns the {@link ChildEntity}. + * Each child has a name that is univocal for a given parent, in this way + * the parent can search a child by name. */ - T getParent(); + public abstract String getName(); /** - * The persistence status of the {@link ChildEntity}. + * The {@link EntitiesContainer} that owns the {@link ChildEntity}. */ - Status getStatus(); - - void setStatus(Status status); + public abstract T getParent(); } 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 new file mode 100644 index 0000000000000000000000000000000000000000..aae711c003939e1cd2bcc0202731e34badb55ff0 --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Column.java @@ -0,0 +1,120 @@ +/* + * _____________________________________________________________________________ + * + * 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 java.util.Objects; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} + */ +public class Column extends ChildEntity<Table> { + + public final static String TABLE_NAME_KEY = "table_name"; + public final static String COLUMN_NAME_KEY = "column_name"; + public final static String DATATYPE_KEY = "datatype"; + public final static String SIZE_KEY = "size"; + public final static String ARRAYSIZE_KEY = "arraysize"; + public final static String INDEXED_KEY = "indexed"; + public final static String PRIMARY_KEY = "primary_key"; + + private static final long serialVersionUID = 9175956487892235521L; + private static final Logger LOG = LoggerFactory.getLogger(Column.class); + + private boolean foreignKeySearched; + private KeyMetadata foreignKey; + + private Table parentTable; + + private Column() { + // for serialization + super(); + } + + protected Column(TapSchema tapSchema, Table table, String columnName) { + super(tapSchema, tapSchema.getTableModel(TapSchema.COLUMNS_TABLE), table.getColumnMetadata(columnName)); + parentTable = table; + setStatus(Status.LOADED); + } + + public KeyMetadata getForeignKey() { + if (!foreignKeySearched) { // lazy loading (but the foreignKey value can be null, so we use this boolean) + foreignKey = tapSchema.searchKeyMetadata(parentTable.getParent().getName(), parentTable.getName(), getName()); + } + + return foreignKey; + } + + public String getTableCompleteName() { + return getValue(TABLE_NAME_KEY, String.class); + } + + @Override + public String getName() { + return getValue(COLUMN_NAME_KEY, String.class); + } + + public boolean getIndexed() { + return getValue(INDEXED_KEY, Boolean.class); + } + + /** + * This information is not stored into the TAP_SCHEMA, so it will be + * reloaded from the source schema each time. + */ + public boolean isPrimaryKey() { + return (boolean) getMetadata(PRIMARY_KEY); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 29 * hash + Objects.hashCode(getTableCompleteName()); + hash = 29 * hash + Objects.hashCode(getName()); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Column other = (Column) obj; + if (!Objects.equals(this.getTableCompleteName(), other.getTableCompleteName())) { + return false; + } + return Objects.equals(this.getName(), other.getName()); + } + + /** + * {@inheritDoc} + */ + @Override + public Table getParent() { + return parentTable; + } +} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/ConsistencyChecks.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ConsistencyChecks.java similarity index 98% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/ConsistencyChecks.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/ConsistencyChecks.java index 13c5d690c3f357b46f751d8d7fe037dc128e9773..1b9f6d6fa85578fc9742474497198a97aea69541 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/ConsistencyChecks.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ConsistencyChecks.java @@ -20,10 +20,10 @@ * 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.api.contract.DatabaseType; -import it.inaf.ia2.tsm.api.contract.TapSchema; +import it.inaf.ia2.tsm.datalayer.DatabaseType; +import it.inaf.ia2.tsm.datalayer.DBWrapper; import java.io.Serializable; import java.sql.Connection; import java.sql.PreparedStatement; 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 new file mode 100644 index 0000000000000000000000000000000000000000..42ae18d0720b346e730f60123f401776020060cb --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Dao.java @@ -0,0 +1,707 @@ +/* + * _____________________________________________________________________________ + * + * 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 new file mode 100644 index 0000000000000000000000000000000000000000..6aafd03a20393456d8ef0bfadcbe0f2c712b222a --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoColumn.java @@ -0,0 +1,298 @@ +/* + * _____________________________________________________________________________ + * + * 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 new file mode 100644 index 0000000000000000000000000000000000000000..28599ae3cecbd2d812ef46d43fedd9f8133ccec4 --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoKey.java @@ -0,0 +1,489 @@ +/* + * _____________________________________________________________________________ + * + * 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 new file mode 100644 index 0000000000000000000000000000000000000000..74429dde4750563440530033e207bdcbc9229511 --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoSchema.java @@ -0,0 +1,146 @@ +/* + * _____________________________________________________________________________ + * + * 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 new file mode 100644 index 0000000000000000000000000000000000000000..4a42d7f247a8de15b0d00b581bf58d6855363a53 --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoTable.java @@ -0,0 +1,202 @@ +/* + * _____________________________________________________________________________ + * + * 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/api/contract/EntitiesContainer.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntitiesContainer.java similarity index 98% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/EntitiesContainer.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntitiesContainer.java index 13febd04d9b4578ff8e1f928cf9dfbb7578e7829..8c10dd114d4c03ed822234ae597203bdb4b6dba2 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/EntitiesContainer.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntitiesContainer.java @@ -20,7 +20,7 @@ * 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.contract; +package it.inaf.ia2.tsm; import java.sql.SQLException; import java.util.List; diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/EditableProperty.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntityProperty.java similarity index 54% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/EditableProperty.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntityProperty.java index 89c20cce13437a829cb03cbecf46f9e36e3b0844..ec37b228cef30774bbb69be1dc43c811d3b5831a 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/EditableProperty.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntityProperty.java @@ -20,66 +20,91 @@ * 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.xmlmodel.PropertyModel; import java.io.Serializable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * Represent an {@code EntityProperty} which value can be modified by the user. + * Store the value of an entity property (that corresponds to a column of the + * mapped table). * * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} */ -public class EditableProperty<T> implements EntityProperty, Serializable { +public class EntityProperty<T> implements Serializable { - private static final long serialVersionUID = 4896192667771442640L; - private static final Logger log = LoggerFactory.getLogger(EditableProperty.class); + private static final long serialVersionUID = 6735553751078589085L; - private final T defaultValue; - private final boolean allowsNull; + private PropertyModel propertyModel; + private Class<T> type; private T originalValue; private T value; + private boolean changed; - public EditableProperty() { - this.defaultValue = null; - this.allowsNull = true; - this.init(defaultValue); + private EntityProperty() { } - public EditableProperty(T defaultValue, boolean allowsNull) { - this.defaultValue = defaultValue; - this.allowsNull = allowsNull; + public EntityProperty(PropertyModel propertyModel, T defaultValue) { + this.propertyModel = propertyModel; + this.type = propertyModel.getType(); this.init(defaultValue); } - @Override + /** + * Retrieve the current value. + */ + public T getValue() { + return value; + } + + /** + * Retrieve the current value. + */ public <X> X getValue(Class<X> type) { return (X) value; } + public T getOriginalValue() { + return originalValue; + } + public <X> X getOriginalValue(Class<X> type) { return (X) originalValue; } public <X> void setValue(X value) { - if (value == null && !allowsNull) { - throw new IllegalArgumentException("This EditableProperty instance doesn't allow null values"); + this.setValue(value, true); + } + + private <X> void setValue(X value, boolean checkUpdatable) { + if (checkUpdatable && !propertyModel.isUpdatable()) { + throw new UnsupportedOperationException("This EntityProperty instance (" + propertyModel.getName() + ") is not updatable"); + } + if (value == null && !propertyModel.isNullable()) { + throw new IllegalArgumentException("This EntityProperty instance (" + propertyModel.getName() + ") doesn't allow null values"); } this.value = (T) value; } - @Override public boolean isChanged() { + if (changed) { + return true; + } if (originalValue == null) { return value != null; } return !originalValue.equals(value); } - @Override + public void setChanged(boolean changed) { + this.changed = changed; + } + + /** + * Initialize the value. + */ public final <X> void init(X initialValue) { - setValue(initialValue); + setValue(initialValue, false); this.originalValue = (T) initialValue; } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/InconsistentValue.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/InconsistentValue.java similarity index 98% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/InconsistentValue.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/InconsistentValue.java index 6f6892328f60d2a9de6d3c60f27d9150b3b24871..d7e6c11597feaeedceb7d8868f6c051ec3040f7e 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/InconsistentValue.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/InconsistentValue.java @@ -20,7 +20,7 @@ * 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; /** * 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 new file mode 100644 index 0000000000000000000000000000000000000000..712c16c38652354efe6ecb50dbfccdcc0eb1e0a2 --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/InsertQueryBuilder.java @@ -0,0 +1,97 @@ +/* + * _____________________________________________________________________________ + * + * 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/api/KeyImpl.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Key.java similarity index 55% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/KeyImpl.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/Key.java index db2277ad8476c5c6d36dc0609fe7f96e8311d3df..dfbe3a140470222468bbbd5153b9833451ffb6a5 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/KeyImpl.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Key.java @@ -20,67 +20,48 @@ * 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.api.contract.Key; -import it.inaf.ia2.tsm.api.contract.KeyColumn; -import it.inaf.ia2.tsm.api.contract.TapSchema; +import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.regex.Pattern; /** * The main implementation of {@link Key}. * * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} */ -public class KeyImpl extends TapSchemaEntityImpl implements Key { +public class Key extends TapSchemaEntity implements Serializable { + + public static final String ID_KEY = "key_id"; + public static final String FROM_TABLE_KEY = "from_table"; + public static final String TARGET_TABLE_KEY = "target_table"; private static final long serialVersionUID = -8783695875831579336L; - private final List<KeyColumn> keyColumns; + private KeyMetadata keyMetadata; + private List<KeyColumn> keyColumns; - private String fromSchema; - private String fromTable; - private String targetSchema; - private String targetTable; private boolean visible; - private KeyImpl() { - // for serialization + private Key() { super(); - keyColumns = new ArrayList<>(); } - public KeyImpl(DBWrapper dbWrapper, TapSchema tapSchema, String fromSchema, String fromTable, String targetSchema, String targetTable) { - this(dbWrapper, tapSchema, fromSchema + "." + fromTable, targetSchema + "." + targetTable); - } - - public KeyImpl(DBWrapper dbWrapper, TapSchema tapSchema, String fromTableCompleteName, String targetTableCompleteName) { - super(dbWrapper, tapSchema); - - addProperty(FROM_TABLE_KEY, new FixedEntityProperty<>(fromTableCompleteName)); - addProperty(TARGET_TABLE_KEY, new FixedEntityProperty<>(targetTableCompleteName)); - - addProperty(ID_KEY, new EditableProperty<String>()); - addProperty(UTYPE_KEY, new EditableProperty<String>()); - addProperty(DESCRIPTION_KEY, new EditableProperty<String>()); - addProperty(KEY_ID_KEY, new EditableProperty<Long>()); + public Key(TapSchema tapSchema, KeyMetadata keyMetadata) { + super(tapSchema, tapSchema.getTableModel(TapSchema.KEYS_TABLE), keyMetadata.getKeyMetadata()); + this.keyMetadata = keyMetadata; keyColumns = new ArrayList<>(); - - String fromTableCompleteNameSplit[] = fromTableCompleteName.split(Pattern.quote(".")); - String targetTableCompleteNameSplit[] = targetTableCompleteName.split(Pattern.quote(".")); - this.fromSchema = fromTableCompleteNameSplit[0]; - this.fromTable = fromTableCompleteNameSplit[1]; - this.targetSchema = targetTableCompleteNameSplit[0]; - this.targetTable = targetTableCompleteNameSplit[1]; visible = false; } - @Override + public KeyMetadata getKeyMetadata() { + return keyMetadata; + } + public boolean isVisible() { return visible; } @@ -89,12 +70,10 @@ public class KeyImpl extends TapSchemaEntityImpl implements Key { this.visible = visible; } - @Override public String getId() { return getValue(ID_KEY, String.class); } - @Override public void setId(String id) { setValue(ID_KEY, id); for (KeyColumn keyColumn : keyColumns) { @@ -102,73 +81,36 @@ public class KeyImpl extends TapSchemaEntityImpl implements Key { } } - @Override public List<KeyColumn> getKeyColumns() { return Collections.unmodifiableList(keyColumns); } - @Override public String getFromSchemaName() { - return fromSchema; + return keyMetadata.getFromSchema(); } - @Override public String getFromTableSimpleName() { - return fromTable; + return keyMetadata.getFromTable(); } - @Override public String getFromTableCompleteName() { return getValue(FROM_TABLE_KEY, String.class); } - @Override public String getTargetSchemaName() { - return targetSchema; + return keyMetadata.getTargetSchema(); } - @Override public String getTargetTableSimpleName() { - return targetTable; + return keyMetadata.getTargetTable(); } - @Override public String getTargetTableCompleteName() { return getValue(TARGET_TABLE_KEY, String.class); } - @Override - public String getUtype() { - return getValue(UTYPE_KEY, String.class); - } - - @Override - public void setUtype(String utype) { - setValue(UTYPE_KEY, utype); - } - - @Override - public String getDescription() { - return getValue(DESCRIPTION_KEY, String.class); - } - - @Override - public void setDescription(String description) { - setValue(DESCRIPTION_KEY, description); - } - - @Override - public Long getKeyID() { - return getValue(KEY_ID_KEY, Long.class); - } - - @Override - public void setKeyID(Long keyID) { - setValue(KEY_ID_KEY, keyID); - } - public KeyColumn addKeyColumn(String fromColumn, String targetColumn) { - KeyColumn keyColumn = new KeyColumnImpl(dbWrapper, tapSchema, this, fromColumn, targetColumn); + KeyColumn keyColumn = new KeyColumn(tapSchema, this, fromColumn, targetColumn); keyColumns.add(keyColumn); return keyColumn; } @@ -200,11 +142,11 @@ public class KeyImpl extends TapSchemaEntityImpl implements Key { if (obj == null) { return false; } - if (getClass() != obj.getClass()) { + if (Key.class != obj.getClass()) { return false; } - final KeyImpl other = (KeyImpl) obj; + final Key other = (Key) obj; List<KeyColumn> otherKeyColumns = other.getKeyColumns(); // Comparing each key column diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/KeyColumnImpl.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/KeyColumn.java similarity index 72% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/KeyColumnImpl.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/KeyColumn.java index 8294c918fbf68615d37563c0e662be81226af674..b7aeb1159b1cbbcf99936502afb4021b83c635b9 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/KeyColumnImpl.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/KeyColumn.java @@ -20,75 +20,55 @@ * 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.api.contract.Key; -import it.inaf.ia2.tsm.api.contract.KeyColumn; -import it.inaf.ia2.tsm.api.contract.TapSchema; import java.util.Objects; /** * The main implementation of {@link KeyColumn}. - * + * * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} */ -public class KeyColumnImpl extends TapSchemaEntityImpl implements KeyColumn { +public class KeyColumn extends TapSchemaEntity { + + public static final String KEY_ID_KEY = "key_id"; + public static final String FROM_COLUMN_KEY = "from_column"; + public static final String TARGET_COLUMN_KEY = "target_column"; private static final long serialVersionUID = -3681677723432728327L; private Key key; - private KeyColumnImpl() { + private KeyColumn() { // for serialization super(); } - protected KeyColumnImpl(DBWrapper dbWrapper, TapSchema tapSchema, Key key, String fromColumn, String targetColumn) { - super(dbWrapper, tapSchema); + protected KeyColumn(TapSchema tapSchema, Key key, String fromColumn, String targetColumn) { + super(tapSchema, tapSchema.getTableModel(TapSchema.KEY_COLUMNS_TABLE), key.getKeyMetadata().getKeyColumnMetadata(fromColumn, targetColumn)); this.key = key; - - addProperty(FROM_COLUMN_KEY, new FixedEntityProperty<>(fromColumn)); - addProperty(TARGET_COLUMN_KEY, new FixedEntityProperty<>(targetColumn)); - - addProperty(KEY_ID_KEY, new EditableProperty<>(key.getId(), true)); - addProperty(KEY_COLUMN_ID_KEY, new EditableProperty<Long>()); } - @Override public Key getParent() { return key; } - @Override public String getKeyId() { return getValue(KEY_ID_KEY, String.class); } - @Override public void setKeyId(String keyId) { setValue(KEY_ID_KEY, keyId); } - @Override public String getFromColumn() { return getValue(FROM_COLUMN_KEY, String.class); } - @Override public String getTargetColumn() { return getValue(TARGET_COLUMN_KEY, String.class); } - @Override - public Long getKeyColumnID() { - return getValue(KEY_COLUMN_ID_KEY, Long.class); - } - - @Override - public void setKeyColumnID(Long keyColumnID) { - setValue(KEY_COLUMN_ID_KEY, keyColumnID); - } - @Override public int hashCode() { int hash = 3; @@ -107,7 +87,7 @@ public class KeyColumnImpl extends TapSchemaEntityImpl implements KeyColumn { if (getClass() != obj.getClass()) { return false; } - final KeyColumnImpl other = (KeyColumnImpl) obj; + final KeyColumn other = (KeyColumn) obj; if (!Objects.equals(this.key.getFromTableCompleteName(), other.key.getFromTableCompleteName())) { return false; } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/KeyMetadata.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/KeyMetadata.java new file mode 100644 index 0000000000000000000000000000000000000000..02b93715d3fa8fe63928322f85f70fea5121e951 --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/KeyMetadata.java @@ -0,0 +1,162 @@ +/* + * _____________________________________________________________________________ + * + * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of + * Trieste INAF - IA2 Italian Center for Astronomical Archives + * _____________________________________________________________________________ + * + * Copyright (C) 2017 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 java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * + * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} + */ +public class KeyMetadata implements Serializable { + + public static final String NEW_KEY = "#NEW#"; + private static final long serialVersionUID = -30688540834789724L; + + private final String fromSchema; + private final String fromTable; + private final List<String> fromColumns; + private final String targetSchema; + private final String targetTable; + private final List<String> targetColumns; + + public KeyMetadata(String fromSchema, String fromTable, String targetSchema, String targetTable) { + this.fromSchema = fromSchema; + this.fromTable = fromTable; + this.fromColumns = new ArrayList<>(); + this.targetSchema = targetSchema; + this.targetTable = targetTable; + this.targetColumns = new ArrayList<>(); + } + + public String getFromSchema() { + return fromSchema; + } + + public String getFromTable() { + return fromTable; + } + + public List<String> getFromColumns() { + return fromColumns; + } + + public String getTargetSchema() { + return targetSchema; + } + + public String getTargetTable() { + return targetTable; + } + + public List<String> getTargetColumns() { + return targetColumns; + } + + public void addKeyColumn(String fromColumn, String targetColumn) { + fromColumns.add(fromColumn); + targetColumns.add(targetColumn); + } + + public Map<String, Object> getKeyMetadata() { + Map<String, Object> metadata = new HashMap<>(); + metadata.put(Key.ID_KEY, NEW_KEY); + metadata.put(Key.FROM_TABLE_KEY, fromSchema + "." + fromTable); + metadata.put(Key.TARGET_TABLE_KEY, targetSchema + "." + targetTable); + return metadata; + } + + public Map<String, Object> getKeyColumnMetadata(String fromColumn, String targetColumn) { + Map<String, Object> metadata = new HashMap<>(); + metadata.put(KeyColumn.KEY_ID_KEY, NEW_KEY); + metadata.put(KeyColumn.FROM_COLUMN_KEY, fromColumn); + metadata.put(KeyColumn.TARGET_COLUMN_KEY, targetColumn); + return metadata; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 17 * hash + Objects.hashCode(this.fromSchema); + hash = 17 * hash + Objects.hashCode(this.fromTable); + for (String fromColumn : fromColumns) { + hash = 17 * hash + Objects.hashCode(fromColumn); + } + hash = 17 * hash + Objects.hashCode(this.targetSchema); + hash = 17 * hash + Objects.hashCode(this.targetTable); + for (String targetColumn : targetColumns) { + hash = 17 * hash + Objects.hashCode(targetColumn); + } + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final KeyMetadata other = (KeyMetadata) obj; + if (!Objects.equals(this.fromSchema, other.fromSchema)) { + return false; + } + if (!Objects.equals(this.fromTable, other.fromTable)) { + return false; + } + if (!Objects.equals(this.targetSchema, other.targetSchema)) { + return false; + } + if (!Objects.equals(this.targetTable, other.targetTable)) { + return false; + } + if (this.fromColumns.size() != other.fromColumns.size()) { + return false; + } + for (int i = 0; i < fromColumns.size(); i++) { + String fromColumn = fromColumns.get(i); + if (!Objects.equals(fromColumn, other.fromColumns.get(i))) { + return false; + } + } + if (this.targetColumns.size() != other.targetColumns.size()) { + return false; + } + for (int i = 0; i < targetColumns.size(); i++) { + String targetColumn = targetColumns.get(i); + if (!Objects.equals(targetColumn, other.targetColumns.get(i))) { + return false; + } + } + return true; + } +} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/SchemaImpl.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Schema.java similarity index 67% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/SchemaImpl.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/Schema.java index 22bc9e822a3b6f302d60c765e184329b65d1d945..fe02380623dcbe95df899ca9bc622426214ad625 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/SchemaImpl.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Schema.java @@ -20,14 +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.api.contract.Key; -import it.inaf.ia2.tsm.api.contract.Schema; -import it.inaf.ia2.tsm.api.contract.Status; -import it.inaf.ia2.tsm.api.contract.Table; -import it.inaf.ia2.tsm.api.contract.TapSchema; +import it.inaf.ia2.tsm.datalayer.DBBroker; import java.sql.SQLException; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -40,35 +37,34 @@ import org.slf4j.LoggerFactory; * * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} */ -public class SchemaImpl extends ChildEntityImpl<TapSchema> implements Schema { +public class Schema extends ChildEntity<TapSchema> implements EntitiesContainer<Table> { + + public final static String SCHEMA_NAME_KEY = "schema_name"; private static final long serialVersionUID = 8828583158332877855L; - private static final Logger log = LoggerFactory.getLogger(SchemaImpl.class); + private static final Logger LOG = LoggerFactory.getLogger(Schema.class); private final Map<String, Table> tables; private Map<String, String> tablesTypes; - private SchemaImpl() { + private Schema() { // for serialization super(); tables = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); } - public SchemaImpl(DBWrapper dbWrapper, TapSchema tapSchema, String name) throws SQLException { - super(dbWrapper, tapSchema); + public Schema(TapSchema tapSchema, String name) throws SQLException { + super(tapSchema, tapSchema.getTableModel(TapSchema.SCHEMAS_TABLE), tapSchema.getSchemaMetadata(name)); + + DBBroker broker = tapSchema.getDBBroker(name); tables = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - tablesTypes = DaoTable.getTablesTypes(dbWrapper, tapSchema, name); + tablesTypes = broker.getAllTableTypes(name); - for (String tableName : DaoTable.getAllTablesNames(dbWrapper, tapSchema, name)) { + for (String tableName : broker.getAllTablesNames(name)) { tables.put(tableName, null); } - log.debug("Schema {} contains {} tables", name, tables.size()); - - addProperty(SCHEMA_NAME_KEY, new FixedEntityProperty<>(name)); - addProperty(UTYPE_KEY, new EditableProperty<String>()); - addProperty(DESCRIPTION_KEY, new EditableProperty<String>()); - addProperty(SCHEMA_ID, new EditableProperty<Long>()); + LOG.debug("Schema {} contains {} tables", name, tables.size()); setStatus(Status.LOADED); } @@ -89,7 +85,7 @@ public class SchemaImpl extends ChildEntityImpl<TapSchema> implements Schema { public Table addChild(String tableSimpleName) throws SQLException { String schemaName = getName(); - log.debug("Adding table {} into schema {}", tableSimpleName, schemaName); + LOG.debug("Adding table {} into schema {}", tableSimpleName, schemaName); if (!tables.containsKey(tableSimpleName)) { //throw new IllegalArgumentException("The table " + tableSimpleName + " doesn't exist into the schema " + schemaName + ". Are you sure you are using the simple table name?"); @@ -100,21 +96,9 @@ public class SchemaImpl extends ChildEntityImpl<TapSchema> implements Schema { Table table = tables.get(tableSimpleName); if (table == null) { - table = new TableImpl(dbWrapper, tapSchema, this, tableSimpleName, tablesTypes.get(tableSimpleName)); - - // Adding fromKeys and targetKeys to the table. The keys could be hidden, - // their status is not important here. We are adding all tables keys. - // It is the method {@link #TableImpl.checkKeys()} that set their visibility. - // We have to loop on all keys of all schemas to retrieve also the - // target keys. - for (Key key : ((TapSchemaImpl) tapSchema).getAllKeys()) { - if (key.getFromTableCompleteName().equals(table.getCompleteName())) { - ((TableImpl) table).addFromKey(key); - } - if (key.getTargetTableCompleteName().equals(table.getCompleteName())) { - ((TableImpl) table).addTargetKey(key); - } - } + table = new Table(tapSchema, this, tableSimpleName); + + tapSchema.checkKeys(); tables.put(tableSimpleName, table); table.setStatus(Status.ADDED_NOT_PERSISTED); @@ -131,7 +115,7 @@ public class SchemaImpl extends ChildEntityImpl<TapSchema> implements Schema { } } - ((TapSchemaImpl) tapSchema).checkKeys(); + tapSchema.checkKeys(); return table; } @@ -144,7 +128,7 @@ public class SchemaImpl extends ChildEntityImpl<TapSchema> implements Schema { public void removeChild(String tableSimpleName) { String schemaName = getName(); - log.debug("Removing table {} from schema {}", tableSimpleName, schemaName); + LOG.debug("Removing table {} from schema {}", tableSimpleName, schemaName); if (!tables.containsKey(tableSimpleName)) { throw new IllegalArgumentException("The table " + tableSimpleName + " doesn't exist into the schema " + schemaName + ". Are you sure you are using the simple table name?"); @@ -166,7 +150,7 @@ public class SchemaImpl extends ChildEntityImpl<TapSchema> implements Schema { table.setStatus(Status.TO_REMOVE); } - ((TapSchemaImpl) tapSchema).checkKeys(); + tapSchema.checkKeys(); } /** @@ -209,45 +193,6 @@ public class SchemaImpl extends ChildEntityImpl<TapSchema> implements Schema { return getChildren(Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED, Status.TO_REMOVE, Status.REMOVED_NOT_PERSISTED); } - /** - * {@inheritDoc} - */ - @Override - public String getUtype() { - return getValue(UTYPE_KEY, String.class); - } - - @Override - public void setUtype(String utype) { - setValue(UTYPE_KEY, utype); - } - - /** - * {@inheritDoc} - */ - @Override - public String getDescription() { - return getValue(DESCRIPTION_KEY, String.class); - } - - @Override - public void setDescription(String description) { - setValue(DESCRIPTION_KEY, description); - } - - /** - * {@inheritDoc} - */ - @Override - public Long getSchemaID() { - return getValue(SCHEMA_ID, Long.class); - } - - @Override - public void setSchemaID(Long schemaID) { - setValue(SCHEMA_ID, schemaID); - } - @Override public int hashCode() { int hash = 5; @@ -263,11 +208,8 @@ public class SchemaImpl extends ChildEntityImpl<TapSchema> implements Schema { if (getClass() != obj.getClass()) { return false; } - final SchemaImpl other = (SchemaImpl) obj; - if (!Objects.equals(this.getName(), other.getName())) { - return false; - } - return true; + final Schema other = (Schema) obj; + return Objects.equals(this.getName(), other.getName()); } /** @@ -275,7 +217,7 @@ public class SchemaImpl extends ChildEntityImpl<TapSchema> implements Schema { * to the database, in order to remove from the memory the tables with * status {@code Status.TO_REMOVE} or {@code Status.REMOVED_NOT_PERSISTED}. */ - protected void cleanTable(String tableSimpleName) { + public void cleanTable(String tableSimpleName) { if (!tables.containsKey(tableSimpleName)) { throw new IllegalArgumentException("Schema " + getName() + "doesn't contain the table " + tableSimpleName); } @@ -289,4 +231,12 @@ public class SchemaImpl extends ChildEntityImpl<TapSchema> implements Schema { public TapSchema getParent() { return tapSchema; } + + public Map<String, Object> getTableMetadata(String tableSimpleName) { + Map<String, Object> metadata = new HashMap<>(); + metadata.put(Table.SCHEMA_NAME_KEY, getName()); + metadata.put(Table.TABLE_NAME_KEY, getName() + "." + tableSimpleName); + metadata.put(Table.TABLE_TYPE_KEY, tablesTypes.get(tableSimpleName)); + return metadata; + } } 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 new file mode 100644 index 0000000000000000000000000000000000000000..b3db4d2cebb5cf2087ed62a08c090172640e1480 --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/SelectQueryBuilder.java @@ -0,0 +1,127 @@ +/* + * _____________________________________________________________________________ + * + * 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/api/contract/Status.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Status.java similarity index 98% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/Status.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/Status.java index 7081f27e39cc74135104f3baef312299238f2020..59f2a6204059973ad033ed59491fcef6d11aacca 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/Status.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Status.java @@ -20,7 +20,7 @@ * 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.contract; +package it.inaf.ia2.tsm; /** * Define the persistence status of a {@link ChildEntity}. diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/TSMUtil.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TSMUtil.java similarity index 69% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/TSMUtil.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/TSMUtil.java index 8548bdf7c8adc56f34fca053a09f490b80b75896..a584a6e276348d94c21f58ed4807daf8445259c5 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/TSMUtil.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TSMUtil.java @@ -20,20 +20,12 @@ * 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.datalayer.Credentials; +import it.inaf.ia2.tsm.datalayer.DatabaseType; +import it.inaf.ia2.tsm.datalayer.DBWrapper; import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; -import it.inaf.ia2.tsm.api.contract.DatabaseType; -import it.inaf.ia2.tsm.api.contract.ChildEntity; -import it.inaf.ia2.tsm.api.contract.Column; -import it.inaf.ia2.tsm.api.contract.Key; -import it.inaf.ia2.tsm.api.contract.KeyColumn; -import it.inaf.ia2.tsm.api.contract.Schema; -import it.inaf.ia2.tsm.api.contract.Status; -import it.inaf.ia2.tsm.api.contract.Table; -import it.inaf.ia2.tsm.api.contract.TapSchema; -import it.inaf.ia2.tsm.api.contract.TapSchemaEntity; -import it.inaf.ia2.tsm.api.contract.TapSchemaVersion; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; @@ -53,7 +45,7 @@ import org.slf4j.LoggerFactory; */ public class TSMUtil { - private static final Logger log = LoggerFactory.getLogger(TSMUtil.class); + private static final Logger LOG = LoggerFactory.getLogger(TSMUtil.class); public static DataSource createDataSource(Credentials credentials) { @@ -208,16 +200,8 @@ public class TSMUtil { return schemaName.equals(tapSchema.getName()); } - protected static UnsupportedOperationException getUnsupportedOperationException(TapSchemaVersion version, String unsupportedFeature) { - return new UnsupportedOperationException("Version \"" + version.name() + "\" doesn't support " + unsupportedFeature); - } - - protected static boolean is1_1(TapSchemaVersion version) { - return version == TapSchemaVersion.TAP_SCHEMA_1_1 || version == TapSchemaVersion.TAP_SCHEMA_1_1_IA2; - } - - protected static boolean isIA2(TapSchemaVersion version) { - return version == TapSchemaVersion.TAP_SCHEMA_1_IA2 || version == TapSchemaVersion.TAP_SCHEMA_1_1_IA2; + protected static UnsupportedOperationException getUnsupportedOperationException(String version, String unsupportedFeature) { + return new UnsupportedOperationException("Version \"" + version + "\" doesn't support " + unsupportedFeature); } protected static String escapeName(String name, DatabaseType dbType) { @@ -248,15 +232,15 @@ public class TSMUtil { } else if (entity instanceof KeyColumn) { return TapSchema.KEY_COLUMNS_TABLE; } - log.warn("getTapSchemaTableNameFromEntity returns null for {}" + entity.getClass().getCanonicalName()); + LOG.warn("getTapSchemaTableNameFromEntity returns null for {}" + entity.getClass().getCanonicalName()); return null; } - private static void setTSColumnDescription(Table table, String columnName, String description) { - Column column = table.getChild(columnName); - column.setDescription(description); - column.setStd(true); - } +// private static void setTSColumnDescription(Table table, String columnName, String description) { +// Column column = table.getChild(columnName); +// column.setDescription(description); +// column.setStd(true); +// } public static String getNaturalLangueName(TapSchemaEntity entity) { if (entity instanceof Schema) { @@ -330,59 +314,59 @@ public class TSMUtil { * @param schema the TAP_SCHEMA schema <code>SchemaEntity</code>. */ protected static void putInfoIntoTapSchemaSchema(Schema schema) { - - schema.setDescription("a special schema to describe a TAP tableset"); - - // SCHEMAS - Table schemasTable = schema.getChild("schemas"); - schemasTable.setDescription("description of schemas in this tableset"); - - setTSColumnDescription(schemasTable, "schema_name", "schema name for reference to TAP_SCHEMA.schemas"); - setTSColumnDescription(schemasTable, "utype", "lists the utypes of schemas in the tableset"); - setTSColumnDescription(schemasTable, "description", "describes schemas in the tableset"); - - // TABLES - Table tablesTable = schema.getChild("tables"); - tablesTable.setDescription("description of tables in this tableset"); - - setTSColumnDescription(tablesTable, "schema_name", "the schema this table belongs to"); - setTSColumnDescription(tablesTable, "table_name", "the fully qualified table name"); - setTSColumnDescription(tablesTable, "table_type", "one of: table view"); - setTSColumnDescription(tablesTable, "utype", "lists the utype of tables in the tableset"); - setTSColumnDescription(tablesTable, "description", "describes tables in the tableset"); - - // COLUMNS - Table columnsTable = schema.getChild("columns"); - columnsTable.setDescription("description of columns in this tableset"); - - setTSColumnDescription(columnsTable, "table_name", "the table this column belongs to"); - setTSColumnDescription(columnsTable, "column_name", "the column name"); - setTSColumnDescription(columnsTable, "utype", "lists the utypes of columns in the tableset"); - setTSColumnDescription(columnsTable, "ucd", "lists the UCDs of columns in the tableset"); - setTSColumnDescription(columnsTable, "unit", "lists the unit used for column values in the tableset"); - setTSColumnDescription(columnsTable, "description", "describes the columns in the tableset"); - setTSColumnDescription(columnsTable, "datatype", "lists the ADQL datatype of columns in the tableset"); - setTSColumnDescription(columnsTable, "size", "lists the size of variable-length columns in the tableset"); - setTSColumnDescription(columnsTable, "principal", "a principal column; 1 means 1, 0 means 0"); - setTSColumnDescription(columnsTable, "indexed", "an indexed column; 1 means 1, 0 means 0"); - setTSColumnDescription(columnsTable, "std", "a standard column; 1 means 1, 0 means 0"); - - // KEYS - Table keysTable = schema.getChild("keys"); - keysTable.setDescription("description of foreign keys in this tableset"); - - setTSColumnDescription(keysTable, "key_id", "unique key to join to TAP_SCHEMA.key_columns"); - setTSColumnDescription(keysTable, "from_table", "the table with the foreign key"); - setTSColumnDescription(keysTable, "target_table", "the table with the primary key"); - setTSColumnDescription(keysTable, "utype", "lists the utype of keys in the tableset"); - setTSColumnDescription(keysTable, "description", "describes keys in the tableset"); - - // KEY COLUMNS - Table keyColumnsTable = schema.getChild("key_columns"); - keyColumnsTable.setDescription("description of foreign key columns in this tableset"); - - setTSColumnDescription(keyColumnsTable, "key_id", "key to join to TAP_SCHEMA.keys"); - setTSColumnDescription(keyColumnsTable, "from_column", "column in the from_table"); - setTSColumnDescription(keyColumnsTable, "target_column", "column in the target_table"); +// +// schema.setDescription("a special schema to describe a TAP tableset"); +// +// // SCHEMAS +// Table schemasTable = schema.getChild("schemas"); +// schemasTable.setDescription("description of schemas in this tableset"); +// +// setTSColumnDescription(schemasTable, "schema_name", "schema name for reference to TAP_SCHEMA.schemas"); +// setTSColumnDescription(schemasTable, "utype", "lists the utypes of schemas in the tableset"); +// setTSColumnDescription(schemasTable, "description", "describes schemas in the tableset"); +// +// // TABLES +// Table tablesTable = schema.getChild("tables"); +// tablesTable.setDescription("description of tables in this tableset"); +// +// setTSColumnDescription(tablesTable, "schema_name", "the schema this table belongs to"); +// setTSColumnDescription(tablesTable, "table_name", "the fully qualified table name"); +// setTSColumnDescription(tablesTable, "table_type", "one of: table view"); +// setTSColumnDescription(tablesTable, "utype", "lists the utype of tables in the tableset"); +// setTSColumnDescription(tablesTable, "description", "describes tables in the tableset"); +// +// // COLUMNS +// Table columnsTable = schema.getChild("columns"); +// columnsTable.setDescription("description of columns in this tableset"); +// +// setTSColumnDescription(columnsTable, "table_name", "the table this column belongs to"); +// setTSColumnDescription(columnsTable, "column_name", "the column name"); +// setTSColumnDescription(columnsTable, "utype", "lists the utypes of columns in the tableset"); +// setTSColumnDescription(columnsTable, "ucd", "lists the UCDs of columns in the tableset"); +// setTSColumnDescription(columnsTable, "unit", "lists the unit used for column values in the tableset"); +// setTSColumnDescription(columnsTable, "description", "describes the columns in the tableset"); +// setTSColumnDescription(columnsTable, "datatype", "lists the ADQL datatype of columns in the tableset"); +// setTSColumnDescription(columnsTable, "size", "lists the size of variable-length columns in the tableset"); +// setTSColumnDescription(columnsTable, "principal", "a principal column; 1 means 1, 0 means 0"); +// setTSColumnDescription(columnsTable, "indexed", "an indexed column; 1 means 1, 0 means 0"); +// setTSColumnDescription(columnsTable, "std", "a standard column; 1 means 1, 0 means 0"); +// +// // KEYS +// Table keysTable = schema.getChild("keys"); +// keysTable.setDescription("description of foreign keys in this tableset"); +// +// setTSColumnDescription(keysTable, "key_id", "unique key to join to TAP_SCHEMA.key_columns"); +// setTSColumnDescription(keysTable, "from_table", "the table with the foreign key"); +// setTSColumnDescription(keysTable, "target_table", "the table with the primary key"); +// setTSColumnDescription(keysTable, "utype", "lists the utype of keys in the tableset"); +// setTSColumnDescription(keysTable, "description", "describes keys in the tableset"); +// +// // KEY COLUMNS +// Table keyColumnsTable = schema.getChild("key_columns"); +// keyColumnsTable.setDescription("description of foreign key columns in this tableset"); +// +// setTSColumnDescription(keyColumnsTable, "key_id", "key to join to TAP_SCHEMA.keys"); +// setTSColumnDescription(keyColumnsTable, "from_column", "column in the from_table"); +// setTSColumnDescription(keyColumnsTable, "target_column", "column in the target_table"); } } 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 new file mode 100644 index 0000000000000000000000000000000000000000..4ad2590fe03cc421824ed827d9e59d32e3b4a5e0 --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Table.java @@ -0,0 +1,234 @@ +/* + * _____________________________________________________________________________ + * + * 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.DBBroker; +import java.sql.SQLException; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.TreeMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The main implementation of {@link Table}. + * + * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} + */ +public class Table extends ChildEntity<Schema> implements EntitiesContainer<Column> { + + public final static String SCHEMA_NAME_KEY = "schema_name"; + public final static String TABLE_NAME_KEY = "table_name"; + public final static String TABLE_TYPE_KEY = "table_type"; + + private static final long serialVersionUID = 8265331530960896871L; + private static final Logger LOG = LoggerFactory.getLogger(Table.class); + + private Map<String, Map<String, Object>> columnsMetadata; + private Map<String, Column> columns; + + private String simpleName; + private Schema parentSchema; + + private Table() { + // for serialization + super(); + } + + protected Table(TapSchema tapSchema, Schema schema, String tableSimpleName) throws SQLException { + super(tapSchema, tapSchema.getTableModel(TapSchema.TABLES_TABLE), schema.getTableMetadata(tableSimpleName)); + + parentSchema = schema; + this.simpleName = tableSimpleName; + + columns = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + + DBBroker broker = tapSchema.getDBBroker(schema.getName()); + columnsMetadata = broker.getAllColumnsMetadata(schema.getName(), tableSimpleName); + for (Map.Entry<String, Map<String, Object>> entry : columnsMetadata.entrySet()) { + // Adding table names to columns metadata + entry.getValue().put(Column.TABLE_NAME_KEY, schema.getName() + "." + tableSimpleName); + // Initializing columns map + columns.put(entry.getKey(), null); + } + + setStatus(Status.LOADED); + } + + /** + * Only the table name. + */ + @Override + public String getName() { + return simpleName; + } + + /** + * {@code schema_name.table_name}. + */ + public String getCompleteName() { + return getValue(TABLE_NAME_KEY, String.class); + } + + /** + * {@inheritDoc } + */ + @Override + public Column addChild(String columnName) { + String tableCompleteName = getCompleteName(); + + LOG.debug("Adding column {} into table {}", columnName, tableCompleteName); + + if (!columns.containsKey(columnName)) { + tapSchema.getConsistencyChecks().addUnexistingColumn(getCompleteName(), columnName); + return null; + } else { + Column column = columns.get(columnName); + if (column == null) { + column = new Column(tapSchema, this, columnName); + columns.put(columnName, column); + column.setStatus(Status.ADDED_NOT_PERSISTED); + } else { + switch (column.getStatus()) { + case REMOVED_NOT_PERSISTED: // undo removal + column.setStatus(Status.ADDED_NOT_PERSISTED); + break; + case TO_REMOVE: // undo removal + column.setStatus(Status.ADDED_PERSISTED); + break; + default: + throw new IllegalArgumentException("Cannot add column " + columnName + " in table " + tableCompleteName + ". Invalid column status: " + column.getStatus()); + } + } + + tapSchema.checkKeys(); + + return column; + } + } + + /** + * {@inheritDoc } + */ + @Override + public void removeChild(String columnName) { + String tableCompleteName = getCompleteName(); + + LOG.debug("Removing column {} from table {}", columnName, tableCompleteName); + + if (!columns.containsKey(columnName)) { + throw new IllegalArgumentException("Column " + columnName + " doesn't exists in table " + tableCompleteName); + } + + Column column = columns.get(columnName); + + switch (column.getStatus()) { + case ADDED_NOT_PERSISTED: + column.setStatus(Status.REMOVED_NOT_PERSISTED); + break; + case ADDED_PERSISTED: + column.setStatus(Status.TO_REMOVE); + break; + default: + throw new IllegalArgumentException("Cannot remove column " + columnName + " in table " + tableCompleteName + ". Invalid column status: " + column.getStatus()); + } + + tapSchema.checkKeys(); + } + + /** + * {@inheritDoc } + */ + @Override + public Column getChild(String childName, Status... statuses) { + return TSMUtil.getChild(columns, childName, statuses); + } + + /** + * {@inheritDoc } + */ + @Override + public List<Column> getChildren(Status... statuses) { + return TSMUtil.getChildrenByStatus(columns.values(), statuses); + } + + /** + * {@inheritDoc } + */ + @Override + public List<String> getAddableChildrenNames() { + return TSMUtil.getAddableChildrenNames(columns); + } + + @Override + public List<Column> getAddedChildren() { + return getChildren(Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); + } + + @Override + public List<Column> getAddedOrRemovedChildren() { + return getChildren(Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED, Status.TO_REMOVE, Status.REMOVED_NOT_PERSISTED); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 29 * hash + Objects.hashCode(this.getCompleteName()); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Table other = (Table) obj; + if (!Objects.equals(this.getCompleteName(), other.getCompleteName())) { + return false; + } + return true; + } + + protected void afterUpdate() { + for (Column column : columns.values()) { + if (column.getStatus() == Status.ADDED_NOT_PERSISTED) { + column.setStatus(Status.ADDED_PERSISTED); + } else if (column.getStatus() != Status.ADDED_PERSISTED) { + column.setStatus(Status.LOADED); + } + } + } + + @Override + public Schema getParent() { + return parentSchema; + } + + public Map<String, Object> getColumnMetadata(String columnName) { + return columnsMetadata.get(columnName); + } +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..4b008b7047f6842b855200a734b5ff063ce1f265 --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchema.java @@ -0,0 +1,601 @@ +/* + * _____________________________________________________________________________ + * + * 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.DBBroker; +import it.inaf.ia2.tsm.datalayer.DBBrokerFactory; +import it.inaf.ia2.tsm.datalayer.DBWrapper; +import it.inaf.ia2.tsm.xmlmodel.TableModel; +import it.inaf.ia2.tsm.xmlmodel.TapSchemaModel; +import it.inaf.ia2.tsm.xmlmodel.TapSchemaModels; +import java.io.Serializable; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The main implementation of {@link TapSchema}. + * + * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} + */ +public class TapSchema implements EntitiesContainer<Schema>, Serializable { + + // Mandatory tables constants + public static final String TABLES_TABLE = "tables"; + public static final String SCHEMAS_TABLE = "schemas"; + public static final String COLUMNS_TABLE = "columns"; + public static final String KEYS_TABLE = "keys"; + public static final String KEY_COLUMNS_TABLE = "key_columns"; + + private static final long serialVersionUID = 1678083091602571256L; + + private static final Logger LOG = LoggerFactory.getLogger(TapSchema.class); + + private final Map<String, Schema> schemas; + private final List<KeyMetadata> keysMetadata; + private final Set<Key> allKeys; + private final ConsistencyChecks consistencyChecks; + + private boolean loading; + private String version; + private DBWrapper dbWrapper; + private String tapSchemaName; + private boolean exists; + + private transient DBBroker sourceDBBroker; + private transient DBBroker tapSchemaDBBroker; + + public final DBBroker getSourceDBBroker() { + if (sourceDBBroker == null) { + sourceDBBroker = DBBrokerFactory.getDBBroker(dbWrapper.getSourceDataSourceWrapper()); + } + return sourceDBBroker; + } + + public final DBBroker getTapSchemaDBBroker() { + if (tapSchemaDBBroker == null) { + tapSchemaDBBroker = DBBrokerFactory.getDBBroker(dbWrapper.getTapSchemaDataSourceWrapper()); + } + return tapSchemaDBBroker; + } + + private TapSchema() { + // for serialization + schemas = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + allKeys = new HashSet<>(); + keysMetadata = new ArrayList<>(); + consistencyChecks = new ConsistencyChecks(); + } + + public TapSchema(String version, DBWrapper dbWrapper, String tapSchemaName, boolean exists) throws SQLException { + this(); + + loading = true; + this.version = version; + this.dbWrapper = dbWrapper; + this.tapSchemaName = tapSchemaName; + this.exists = exists; + + // Initializing schemas map + for (String schemaName : getSourceDBBroker().getAllSchemaNames()) { + schemas.put(schemaName, null); + } + schemas.put(tapSchemaName, null); // the TAP_SCHEMA contains itself + +// if (exists) { +// DaoSchema.fillSavedSchemas(dbWrapper, (this)); +// DaoTable.fillSavedTables(dbWrapper, (this)); +// DaoColumn.fillSavedColumns(dbWrapper, (this)); +// DaoKey.fillSavedKeys(dbWrapper, (this)); +// } + loading = false; + checkKeys(); + } + + public DBBroker getDBBroker(String schemaName) { + if (schemaName.equals(tapSchemaName)) { + return getTapSchemaDBBroker(); + } else { + return getSourceDBBroker(); + } + } + + /** + * The name of the TAP_SCHEMA schema. + */ + public String getName() { + return tapSchemaName; + } + + /** + * The version selected for this TAP_SCHEMA. + */ + public String getVersion() { + return version; + } + + private void loadSchemaKeysMetadata(String schemaName) throws SQLException { + keysMetadata.addAll(getDBBroker(schemaName).getKeysMetadata(schemaName)); + } + + protected Set<Key> getAllKeys() { + return allKeys; + } + + /** + * {@inheritDoc} + */ + @Override + public Schema addChild(String schemaName) throws SQLException { + LOG.debug("Adding schema {}", schemaName); + + Schema schema; + + if (!schemas.containsKey(schemaName)) { + + consistencyChecks.addUnexistingSchema(schemaName); + schema = null; + } else { + + schema = schemas.get(schemaName); + + if (schema == null) { + schema = new Schema(this, schemaName); + schema.setStatus(Status.ADDED_NOT_PERSISTED); + schemas.put(schemaName, schema); + loadSchemaKeysMetadata(schemaName); + } else { + switch (schema.getStatus()) { + case TO_REMOVE: + schema.setStatus(Status.ADDED_PERSISTED); + break; + case REMOVED_NOT_PERSISTED: + schema.setStatus(Status.ADDED_NOT_PERSISTED); + break; + default: + throw new IllegalArgumentException("Cannot add the schema " + schemaName + ". Invalid status. Schema status is " + schema.getStatus()); + } + } + } + + checkKeys(); + + return schema; + } + + /** + * {@inheritDoc} + */ + @Override + public void removeChild(String schemaName) { + LOG.debug("Removing schema {}", schemaName); + + if (!schemas.containsKey(schemaName)) { + throw new IllegalArgumentException("The database doesn't contains a schema named " + schemaName); + } + + Schema schema = schemas.get(schemaName); + if (schema == null || schema.getStatus() == Status.LOADED) { + throw new IllegalArgumentException("Cannot remove the schema " + schemaName + ". It has never been added."); + } + + if (schema.getStatus() == Status.ADDED_NOT_PERSISTED) { + schema.setStatus(Status.REMOVED_NOT_PERSISTED); + } else if (schema.getStatus() == Status.ADDED_PERSISTED) { + schema.setStatus(Status.TO_REMOVE); + } + + checkKeys(); + } + + /** + * {@inheritDoc} + */ + @Override + public Schema getChild(String childName, Status... statuses) { + return TSMUtil.getChild(schemas, childName, statuses); + } + + /** + * {@inheritDoc} + */ + @Override + public List<Schema> getChildren(Status... statuses) { + return TSMUtil.getChildrenByStatus(schemas.values(), statuses); + } + + /** + * {@inheritDoc} + */ + @Override + public List<String> getAddableChildrenNames() { + return TSMUtil.getAddableChildrenNames(schemas); + } + + /** + * {@inheritDoc} + */ + @Override + public List<Schema> getAddedChildren() { + return getChildren(Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); + } + + /** + * {@inheritDoc} + */ + @Override + public List<Schema> getAddedOrRemovedChildren() { + return getChildren(Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED, Status.TO_REMOVE, Status.REMOVED_NOT_PERSISTED); + } + + /** + * This method has to be used after TAP_SCHEMA modifications are committed + * to the database, in order to remove from the memory the schemas with + * status {@code Status.TO_REMOVE} or {@code Status.REMOVED_NOT_PERSISTED}. + */ + public void cleanSchema(String schemaName) { + if (!schemas.containsKey(schemaName)) { + throw new IllegalArgumentException("The TAP_SCHEMA doesn't contain the schema " + schemaName); + } + schemas.put(schemaName, null); + } + + /** + * Save or update the TAP_SCHEMA changes into the database. + */ + public void save() throws SQLException { + + fillKeyIds(); + + DBBroker broker = getTapSchemaDBBroker(); + + broker.save(this); + + if (!exists) { + // Adding TAP_SCHEMA into TAP_SCHEMA + Schema tapSchemaSchema = addChild(tapSchemaName); + for (String tableName : tapSchemaSchema.getAddableChildrenNames()) { + Table table = tapSchemaSchema.addChild(tableName); + for (String columnName : table.getAddableChildrenNames()) { + table.addChild(columnName); + } + } + LOG.debug(this.toString()); + TSMUtil.putInfoIntoTapSchemaSchema(tapSchemaSchema); + + exists = true; // important! + + //broker.save(this); // save again + } + + exists = true; + + consistencyChecks.getInconsistencies().clear(); + } + + /** + * Retrieve the maximum key id from all the schemas that are added into the + * TAP_SCHEMA. + * + * @return the maximum key, if it exists, zero otherwise. + */ + private int getMaxKeyId() { + int maxKeyId = 0; + for (Key key : allKeys) { + if (key.getId() != null && !KeyMetadata.NEW_KEY.equals(key.getId())) { + int keyId = Integer.parseInt(key.getId()); + if (keyId > maxKeyId) { + maxKeyId = keyId; + } + } + } + return maxKeyId; + } + + private void fillKeyIds() { + + List<Key> newKeys = new ArrayList<>(); + for (Key key : allKeys) { + if (key.isVisible() && KeyMetadata.NEW_KEY.equals(key.getId())) { + newKeys.add(key); + } + } + + int maxKeyId = getMaxKeyId(); + for (Key newKey : newKeys) { + maxKeyId++; + newKey.setId(maxKeyId + ""); + } + } + +// /** +// * Set keys visibility based on other entities visibility (a key is visible +// * if all schemas, tables and columns involved have +// * {@link Status} {@code ADDED_PERSISTED} or {@code ADDED_NOT_PERSISTED}). +// */ +// protected void checkKeys() { +// +// int currentKey = getMaxKeyId() + 1; +// +// for (Key key : allKeys) { +// +// ((Key) key).setVisible(false); +// +// Schema fromSchema = getChild(key.getFromSchemaName(), Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); +// Schema targetSchema = getChild(key.getTargetSchemaName(), Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); +// if (fromSchema != null && targetSchema != null) { +// +// Table fromTable = fromSchema.getChild(key.getFromTableSimpleName(), Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); +// Table targetTable = targetSchema.getChild(key.getTargetTableSimpleName(), Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); +// +// if (fromTable != null && targetTable != null) { +// +// boolean allColumnsVisible = true; +// +// for (KeyColumn keyColumn : key.getKeyColumns()) { +// +// Column fromColumn = fromTable.getChild(keyColumn.getFromColumn(), Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); +// Column targetColumn = targetTable.getChild(keyColumn.getTargetColumn(), Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); +// +// if (fromColumn == null || targetColumn == null) { +// allColumnsVisible = false; +// break; +// } +// } +// +// if (allColumnsVisible) { +// ((Key) key).setVisible(true); +// if (key.getId() == null) { +// key.setId(currentKey + ""); +// currentKey++; +// } +// } +// } +// } +// } +// for (Key key : allKeys) { +// log.debug("{} [{}]", key, key.getStatus()); +// } +// } +// +// public void addFictitiousKey(Table fromTable, String[] fromColumns, Table targetTable, String[] targetColumns) { +// Key key = new Key(dbWrapper, this, fromTable.getCompleteName(), targetTable.getCompleteName()); +// key.setId((getMaxKeyId() + 1) + ""); +// +// for (int i = 0; i < fromColumns.length; i++) { +// key.addKeyColumn(fromColumns[i], targetColumns[i]); +// } +// +// fromTable.addFromKey(key); +// targetTable.addTargetKey(key); +// +// allKeys.add(key); +// checkKeys(); +// } + /** + * Automatically add and remove keys that should be visible. + */ + public final void checkKeys() { + if (!loading) { + + for (KeyMetadata keyMetadata : keysMetadata) { + + // Check if key should be exposed in TAP_SCHEMA + boolean keyVisible = true; + + for (String fromColumn : keyMetadata.getFromColumns()) { + if (!isColumnVisible(keyMetadata.getFromSchema(), keyMetadata.getFromTable(), fromColumn)) { + keyVisible = false; + break; + } + } + if (keyVisible) { + for (String targetColumn : keyMetadata.getTargetColumns()) { + if (!isColumnVisible(keyMetadata.getTargetSchema(), keyMetadata.getTargetTable(), targetColumn)) { + keyVisible = false; + break; + } + } + } + + Key key = null; + for (Key k : allKeys) { + if (k.getKeyMetadata().equals(keyMetadata)) { + key = k; + break; + } + } + + // TODO: use status instead of set visibile [?] + if (keyVisible) { + if (key == null) { + key = new Key(this, keyMetadata); + allKeys.add(key); + } + key.setVisible(true); + } else if (key != null) { + key.setVisible(false); + } + } + } + } + + /** + * Print all TAP_SCHEMA tree (useful for debugging). + */ + @Override + public String toString() { + + StringBuilder sb = new StringBuilder("\n"); + + sb.append(String.format(">> TAP_SCHEMA %s <<\n", tapSchemaName)); + +// for (Schema schema : getChildren()) { +// sb.append("--"); +// sb.append(schema.getName()); +// sb.append(String.format(" [%s]", schema.getStatus())); +// sb.append("\n"); +// List<Table> tables = schema.getChildren(); +// for (int i = 0; i < tables.size(); i++) { +// Table table = tables.get(i); +// sb.append(" |--"); +// sb.append(table.getName()); +// sb.append(String.format(" [%s]", table.getStatus())); +// sb.append("\n"); +// +// String padder = i < tables.size() - 1 ? " | " : " "; +// +// for (Column column : table.getChildren()) { +// sb.append(padder); +// sb.append("|--"); +// sb.append(column.getName()); +// sb.append(String.format(" [%s]", column.getStatus())); +// sb.append("\n"); +// } +// +// if (table.getAllFromKeys().size() > 0) { +// sb.append(padder); +// sb.append("** From keys **\n"); +// for (Key fromKey : table.getAllFromKeys()) { +// sb.append(padder); +// sb.append("* "); +// sb.append(fromKey.toString()); +// sb.append(String.format(" [visible=%s]", fromKey.isVisible())); +// sb.append("\n"); +// } +// } +// if (table.getAllTargetKeys().size() > 0) { +// sb.append(padder); +// sb.append("** Target keys **\n"); +// for (Key targetKey : table.getAllTargetKeys()) { +// sb.append(padder); +// sb.append("* "); +// sb.append(targetKey.toString()); +// sb.append(String.format(" [visible=%s]", targetKey.isVisible())); +// sb.append("\n"); +// } +// } +// +// sb.append("\n"); +// } +// } + return sb.toString(); + } + + public boolean isSchemaVisible(String schemaName) { + Schema schema = schemas.get(schemaName); + if (schema == null) { + return false; + } + return schema.getStatus() == Status.ADDED_PERSISTED + || schema.getStatus() == Status.ADDED_NOT_PERSISTED; + } + + public boolean isTableVisible(String schemaName, String tableName) { + if (!isSchemaVisible(schemaName)) { + return false; + } + + Table table = schemas.get(schemaName).getChild(tableName); + if (table == null) { + return false; + } + + if (table.getStatus() == Status.ADDED_PERSISTED + || table.getStatus() == Status.ADDED_NOT_PERSISTED) { + return isSchemaVisible(schemaName); + } + + return false; + } + + public boolean isColumnVisible(String schemaName, String tableName, String columnName) { + if (!isTableVisible(schemaName, tableName)) { + return false; + } + + Column column = schemas.get(schemaName).getChild(tableName).getChild(columnName); + if (column == null) { + return false; + } + + if (column.getStatus() == Status.ADDED_PERSISTED + || column.getStatus() == Status.ADDED_NOT_PERSISTED) { + return isTableVisible(schemaName, tableName); + } + + return false; + } + + /** + * Define if the TAP_SCHEMA schema was already written into the database. + */ + public boolean exists() { + return exists; + } + + public ConsistencyChecks getConsistencyChecks() { + return consistencyChecks; + } + + public TapSchemaModel getTapSchemaModel() { + return TapSchemaModels.getTapSchemaModel(version); + } + + public TableModel getTableModel(String tableName) { + return getTapSchemaModel().getTables().get(tableName); + } + + public KeyMetadata searchKeyMetadata(String fromSchemaName, String fromTableName, String fromColumnName) { + for (KeyMetadata km : keysMetadata) { + if (km.getFromSchema().equals(fromSchemaName) && km.getFromTable().equals(fromTableName) + && km.getFromColumns().contains(fromColumnName)) { + return km; + } + } + return null; + } + + public Map<String, Object> getSchemaMetadata(String schemaName) { + Map<String, Object> metadata = new HashMap<>(); + metadata.put(Schema.SCHEMA_NAME_KEY, schemaName); + return metadata; + } + + public List<Key> getVisibileKeys() { + List<Key> visibleKeys = new ArrayList<>(); + for (Key key : allKeys) { + if (key.isVisible()) { + visibleKeys.add(key); + } + } + return visibleKeys; + } +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..86aa23db791b02542b046251fecb1d50aa76357c --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchemaEntity.java @@ -0,0 +1,169 @@ +/* + * _____________________________________________________________________________ + * + * 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.xmlmodel.PropertyModel; +import it.inaf.ia2.tsm.xmlmodel.TableModel; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Represents an object that is mapped on a table of the TAP_SCHEMA. + * + * A TapSchemaEntity has some properties that correspond to columns of the table + * represented by the TapSchemaEntity.<br> + * Property value can be changed but the original value has to be maintained + * until the {@link #save()} method is called. + * + * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} + */ +public abstract class TapSchemaEntity implements Serializable { + + private static final long serialVersionUID = 5515596028279668709L; + private static final Logger LOG = LoggerFactory.getLogger(TapSchemaEntity.class); + + private Map<String, Object> metadata; + private Map<String, EntityProperty> properties; + protected TapSchema tapSchema; + private TableModel tableModel; + + protected TapSchemaEntity() { + } + + public TapSchemaEntity(TapSchema tapSchema, TableModel tableModel, Map<String, Object> metadata) { + this.tapSchema = tapSchema; + this.tableModel = tableModel; + this.metadata = metadata; + this.properties = new HashMap<>(); + fillProperties(); + } + + private void fillProperties() { + for (PropertyModel propModel : tableModel.getProperties().values()) { + Object defaultValue = null; + if (propModel.getLoaderKey() != null) { + defaultValue = metadata.get(propModel.getLoaderKey()); + } + EntityProperty ep = new EntityProperty(propModel, defaultValue); + this.properties.put(propModel.getName(), ep); + } + } + + public Object getMetadata(String key) { + return metadata.get(key); + } + + /** + * Initializes the value of a property (store the original value). + */ + public <T> void initProperty(String key, T value) { + properties.get(key).init(value); + } + + protected String getVersion() { + return tapSchema.getVersion(); + } + + /** + * Returns true if one or more property values is changed (the current value + * is different from the original value). + */ + public boolean isChanged() { + for (EntityProperty property : properties.values()) { + if (property.isChanged()) { + return true; + } + } + return false; + } + + public Object getValue(String key) { + return properties.get(key); + } + + /** + * Retrieve the current value of the property (the last value set). + */ + public <T> T getValue(String key, Class<T> type) { + return (T) properties.get(key).getValue(type); + } + + public void setValue(String key, Object value) { + properties.get(key).setValue(value); + } + + /** + * Retrieve the original value of the property. + * + * @param key the name of the property (the name of the table column). + * @param type the class of the property value. + * @return + */ + public <T> T getOriginalValue(String key, Class<T> type) { + return (T) properties.get(key).getValue(); + } + + /** + * Returns true the value of property which key is passed as parameter is + * changed (the current value is different from the original value). + */ + public boolean isChanged(String key) { + return properties.get(key).isChanged(); + } + + /** + * Retrieve a list of all properties names (the names of the table columns). + */ + public List<String> getPropertiesKeys() { + return new ArrayList<>(properties.keySet()); + } + + /** + * Marks the TapSchemaEntity as saved (all original values are set equals to + * current values). + */ + public void save() { + for (EntityProperty p : properties.values()) { + p.save(); + } + } + + /** + * Set the correct value for a fixed property that has inconsistent value in + * the TAP_SCHEMA. + */ + public <T> void amendProperty(String key, T value) { + EntityProperty prop = properties.get(key); + prop.init(value); + prop.setChanged(true); + } + + public TableModel getTableModel() { + return tableModel; + } +} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/UpdateOperations.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/UpdateOperations.java similarity index 93% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/UpdateOperations.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/UpdateOperations.java index bf82d260533910fcc2e5b9b569a50b9326a0260b..ff8357c4971e91922c765f6255c638d4b90d5301 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/UpdateOperations.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/UpdateOperations.java @@ -20,14 +20,12 @@ * 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; - -import it.inaf.ia2.tsm.api.contract.Column; -import it.inaf.ia2.tsm.api.contract.Key; -import it.inaf.ia2.tsm.api.contract.Schema; -import it.inaf.ia2.tsm.api.contract.Status; -import it.inaf.ia2.tsm.api.contract.Table; -import it.inaf.ia2.tsm.api.contract.TapSchema; +package it.inaf.ia2.tsm; + +import it.inaf.ia2.tsm.datalayer.DBBroker; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; @@ -37,15 +35,17 @@ import org.slf4j.LoggerFactory; * List of operations that have to be performed by the * {@link it.inaf.oats.ia2.tapschemamanager.contract.TapSchema#save()} method, * in terms of adding, updating or removing - * {@link it.inaf.ia2.tsm.api.contract.TapSchemaEntity} - * entities. Could be used stand-alone to obtain a preview of the operations - * that will be performed on the database. + * {@link it.inaf.ia2.tsm.api.TapSchemaEntity} entities. Could be used + * stand-alone to obtain a preview of the operations that will be performed on + * the database. * * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} */ public class UpdateOperations { - private static final Logger log = LoggerFactory.getLogger(UpdateOperations.class); + private static final Logger LOG = LoggerFactory.getLogger(UpdateOperations.class); + + private final TapSchema tapSchema; private final List<Schema> schemasToRemove; private final List<Schema> schemasToAdd; @@ -75,6 +75,9 @@ public class UpdateOperations { } public UpdateOperations(TapSchema tapSchema) { + + this.tapSchema = tapSchema; + schemasToRemove = new ArrayList<>(); schemasToAdd = new ArrayList<>(); schemasToUpdate = new ArrayList<>(); @@ -91,13 +94,13 @@ public class UpdateOperations { keysToAdd = new ArrayList<>(); keysToUpdate = new ArrayList<>(); - for (Key key : ((TapSchemaImpl) tapSchema).getAllKeys()) { + for (Key key : ((TapSchema) tapSchema).getAllKeys()) { if (key.getId() != null) { if (key.isVisible()) { String originalKeyId = key.getOriginalValue(Key.ID_KEY, String.class); - if (originalKeyId == null) { + if (originalKeyId == null || KeyMetadata.NEW_KEY.equals(originalKeyId)) { keysToAdd.add(key); } else if (key.isChanged()) { keysToUpdate.add(key); 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 new file mode 100644 index 0000000000000000000000000000000000000000..4f8bbb60373a8f2e28f82dd9313a9b5c632c04ba --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/UpdateQueryBuilder.java @@ -0,0 +1,94 @@ +/* + * _____________________________________________________________________________ + * + * 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/api/ChildEntityImpl.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/ChildEntityImpl.java deleted file mode 100644 index 366c3274fc3c4ff87803e4ed052bc9ceacc4d739..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/ChildEntityImpl.java +++ /dev/null @@ -1,65 +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.api; - -import it.inaf.ia2.tsm.api.contract.ChildEntity; -import it.inaf.ia2.tsm.api.contract.EntitiesContainer; -import it.inaf.ia2.tsm.api.contract.Status; -import it.inaf.ia2.tsm.api.contract.TapSchema; - -/** - * The main implementation of {@link ChildEntity}. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public abstract class ChildEntityImpl<T extends EntitiesContainer> extends TapSchemaEntityImpl implements ChildEntity<T> { - - private static final long serialVersionUID = -8941059435527998685L; - - private Status status; - - protected ChildEntityImpl() { - // for serialization - super(); - } - - public ChildEntityImpl(DBWrapper dbWrapper, TapSchema tapSchema) { - super(dbWrapper, tapSchema); - } - - @Override - public Status getStatus() { - return status; - } - - @Override - public void setStatus(Status status) { - this.status = status; - } - - @Override - public void save() { - setStatus(Status.ADDED_PERSISTED); - super.save(); - } -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/ColumnImpl.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/ColumnImpl.java deleted file mode 100644 index 62040864902bb76d5e8b75ee2aff5c9d65c7d877..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/ColumnImpl.java +++ /dev/null @@ -1,306 +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.api; - -import it.inaf.ia2.tsm.api.contract.Column; -import it.inaf.ia2.tsm.api.contract.Key; -import it.inaf.ia2.tsm.api.contract.KeyColumn; -import it.inaf.ia2.tsm.api.contract.Status; -import it.inaf.ia2.tsm.api.contract.Table; -import it.inaf.ia2.tsm.api.contract.TapSchema; -import java.util.Objects; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The main implementation of {@link Column}. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public class ColumnImpl extends ChildEntityImpl<Table> implements Column { - - private static final long serialVersionUID = 9175956487892235521L; - private static final Logger log = LoggerFactory.getLogger(ColumnImpl.class); - - private boolean isPrimaryKey; - - private boolean foreignKeySearched; - private Key foreignKey; - - private Table parentTable; - - private ColumnImpl() { - // for serialization - super(); - } - - protected ColumnImpl(DBWrapper dbWrapper, TapSchema tapSchema, Table table, String columnName, boolean indexed, boolean isPrimaryKey, String datatype, Integer size, Integer arraySize) { - super(dbWrapper, tapSchema); - - this.isPrimaryKey = isPrimaryKey; - - parentTable = table; - - addProperty(TABLE_NAME_KEY, new FixedEntityProperty<>(table.getCompleteName())); - addProperty(COLUMN_NAME_KEY, new FixedEntityProperty<>(columnName)); - addProperty(DATATYPE_KEY, new FixedEntityProperty<>(datatype)); - addProperty(SIZE_KEY, new FixedEntityProperty<>(size)); - addProperty(ARRAYSIZE_KEY, new FixedEntityProperty<>(arraySize)); - addProperty(INDEXED_KEY, new FixedEntityProperty<>(indexed)); - - // Updatables - addProperty(DESCRIPTION_KEY, new EditableProperty<String>()); - addProperty(UTYPE_KEY, new EditableProperty<String>()); - addProperty(UNIT_KEY, new EditableProperty<String>()); - addProperty(UCD_KEY, new EditableProperty<String>()); - addProperty(PRINCIPAL_KEY, new EditableProperty<>(isPrimaryKey, false)); - addProperty(STD_KEY, new EditableProperty<>(false, false)); - addProperty(COLUMN_INDEX_KEY, new EditableProperty<Integer>()); - addProperty(ID_KEY, new EditableProperty<Integer>()); - addProperty(COLUMN_ID_KEY, new EditableProperty<Long>()); - - setStatus(Status.LOADED); - } - - /** - * {@inheritDoc} - */ - @Override - public Key getForeignKey() { - if (!foreignKeySearched) { // lazy loading (but the foreignKey value can be null, so we use this boolean) - - String tableCompleteName = getParent().getCompleteName(); - String columnName = getValue(COLUMN_NAME_KEY, String.class); - - keysloop: // we want to loop on all schema keys, also hidden ones. - for (Key key : ((TapSchemaImpl) tapSchema).getAllKeys()) { - if (key.getFromTableCompleteName().equals(tableCompleteName)) { - for (KeyColumn keyColumn : key.getKeyColumns()) { - if (keyColumn.getFromColumn().equals(columnName)) { - foreignKey = key; - break keysloop; - } - } - } - } - - foreignKeySearched = true; - } - - return foreignKey; - } - - /** - * {@inheritDoc} - */ - @Override - public String getTableCompleteName() { - return getValue(TABLE_NAME_KEY, String.class); - } - - /** - * {@inheritDoc} - */ - @Override - public String getName() { - return getValue(COLUMN_NAME_KEY, String.class); - } - - @Override - public boolean getIndexed() { - return getValue(INDEXED_KEY, Boolean.class); - } - - /** - * {@inheritDoc} - * - * This information is not stored into the TAP_SCHEMA, so it will be - * reloaded from the source schema each time. - */ - @Override - public boolean isPrimaryKey() { - return isPrimaryKey; - } - - /** - * {@inheritDoc} - */ - @Override - public String getDatatype() { - return getValue(DATATYPE_KEY, String.class); - } - - /** - * {@inheritDoc} - */ - @Override - public Integer getArraySize() { - return getValue(ARRAYSIZE_KEY, Integer.class); - } - - /** - * {@inheritDoc} - */ - @Override - public Integer getSize() { - return getValue(SIZE_KEY, Integer.class); - } - - /** - * {@inheritDoc} - */ - @Override - public String getDescription() { - return getValue(DESCRIPTION_KEY, String.class); - } - - @Override - public void setDescription(String description) { - setValue(DESCRIPTION_KEY, description); - } - - /** - * {@inheritDoc} - */ - @Override - public String getUtype() { - return getValue(UTYPE_KEY, String.class); - } - - @Override - public void setUtype(String utype) { - setValue(UTYPE_KEY, utype); - } - - /** - * {@inheritDoc} - */ - @Override - public String getUnit() { - return getValue(UNIT_KEY, String.class); - } - - @Override - public void setUnit(String unit) { - setValue(UNIT_KEY, unit); - } - - /** - * {@inheritDoc} - */ - @Override - public String getUCD() { - return getValue(UCD_KEY, String.class); - } - - @Override - public void setUCD(String ucd) { - setValue(UCD_KEY, ucd); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean getPrincipal() { - return getValue(PRINCIPAL_KEY, Boolean.class); - } - - @Override - public void setPrincipal(boolean principal) { - setValue(PRINCIPAL_KEY, principal); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean getStd() { - return getValue(STD_KEY, Boolean.class); - } - - @Override - public void setStd(boolean std) { - setValue(STD_KEY, std); - } - - /** - * {@inheritDoc} - */ - @Override - public Integer getColumnIndex() { - return getValue(COLUMN_INDEX_KEY, Integer.class); - } - - @Override - public void setColumnIndex(Integer columnIndex) { - setValue(COLUMN_INDEX_KEY, columnIndex); - } - - /** - * {@inheritDoc} - */ - @Override - public Long getColumnID() { - return getValue(COLUMN_ID_KEY, Long.class); - } - - @Override - public void setColumnID(Long columnID) { - setValue(COLUMN_ID_KEY, columnID); - } - - @Override - public int hashCode() { - int hash = 7; - hash = 29 * hash + Objects.hashCode(getTableCompleteName()); - hash = 29 * hash + Objects.hashCode(getName()); - return hash; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final ColumnImpl other = (ColumnImpl) obj; - if (!Objects.equals(this.getTableCompleteName(), other.getTableCompleteName())) { - return false; - } - if (!Objects.equals(this.getName(), other.getName())) { - return false; - } - return true; - } - - /** - * {@inheritDoc} - */ - @Override - public Table getParent() { - return parentTable; - } -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/Dao.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/Dao.java deleted file mode 100644 index 28d4c61780c10fbac7bccadfc049f7b3b2c4976b..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/Dao.java +++ /dev/null @@ -1,713 +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.api; - -import it.inaf.ia2.tsm.api.contract.DatabaseType; -import it.inaf.ia2.tsm.api.contract.Column; -import it.inaf.ia2.tsm.api.contract.Key; -import it.inaf.ia2.tsm.api.contract.KeyColumn; -import it.inaf.ia2.tsm.api.contract.Schema; -import it.inaf.ia2.tsm.api.contract.Status; -import it.inaf.ia2.tsm.api.contract.Table; -import it.inaf.ia2.tsm.api.contract.TapSchema; -import it.inaf.ia2.tsm.api.contract.TapSchemaVersion; -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(); - TapSchemaVersion 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) { - ((SchemaImpl) schema).cleanTable(table.getName()); - } - } - for (Table table : operations.getTablesToClean()) { - Schema schema = tapSchema.getChild(table.getSchemaName()); - if (schema != null) { - ((SchemaImpl) schema).cleanTable(table.getName()); - } - } - for (Schema schema : operations.getSchemasToRemove()) { - ((TapSchemaImpl) tapSchema).cleanSchema(schema.getName()); - } - for (Schema schema : operations.getSchemasToClean()) { - ((TapSchemaImpl) 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/api/DaoColumn.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/DaoColumn.java deleted file mode 100644 index eb93b08a4c1b010c49a65758ba2d53717028a67a..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/DaoColumn.java +++ /dev/null @@ -1,303 +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.api; - -import it.inaf.ia2.tsm.api.contract.DatabaseType; -import it.inaf.ia2.tsm.api.contract.Column; -import it.inaf.ia2.tsm.api.contract.Schema; -import it.inaf.ia2.tsm.api.contract.Status; -import it.inaf.ia2.tsm.api.contract.Table; -import it.inaf.ia2.tsm.api.contract.TapSchema; -import it.inaf.ia2.tsm.api.contract.TapSchemaEntity; -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 ColumnImpl(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/api/DaoKey.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/DaoKey.java deleted file mode 100644 index 1824ce02de05d7a6cb18bdfce90ae3ac4ab50b78..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/DaoKey.java +++ /dev/null @@ -1,494 +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.api; - -import it.inaf.ia2.tsm.api.contract.DatabaseType; -import it.inaf.ia2.tsm.api.contract.Key; -import it.inaf.ia2.tsm.api.contract.KeyColumn; -import it.inaf.ia2.tsm.api.contract.Schema; -import it.inaf.ia2.tsm.api.contract.Table; -import it.inaf.ia2.tsm.api.contract.TapSchema; -import it.inaf.ia2.tsm.api.contract.TapSchemaEntity; -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 KeyImpl( - dbWrapper, - tapSchema, - resultSet.getString("from_schema"), - resultSet.getString("from_table"), - resultSet.getString("target_schema"), - resultSet.getString("target_table") - ); - schemaKeys.put(constraintName, key); - } - - ((KeyImpl) 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 KeyImpl(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()) { - ((KeyImpl) 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 : ((TapSchemaImpl) 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)); - } - ((KeyImpl) 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); - KeyImpl key = new KeyImpl(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 = ((KeyImpl) 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 - ((TapSchemaImpl) 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 = ((TapSchemaImpl) 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/api/DaoSchema.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/DaoSchema.java deleted file mode 100644 index 32257b6ec90fafaef6f2dfec7357072053182168..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/DaoSchema.java +++ /dev/null @@ -1,148 +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.api; - -import it.inaf.ia2.tsm.api.contract.DatabaseType; -import it.inaf.ia2.tsm.api.contract.Schema; -import it.inaf.ia2.tsm.api.contract.Status; -import it.inaf.ia2.tsm.api.contract.TapSchema; -import it.inaf.ia2.tsm.api.contract.TapSchemaEntity; -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/api/DaoTable.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/DaoTable.java deleted file mode 100644 index 90c21f245c13ed36e978c76c0222aa9eca5c033f..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/DaoTable.java +++ /dev/null @@ -1,206 +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.api; - -import it.inaf.ia2.tsm.api.contract.DatabaseType; -import it.inaf.ia2.tsm.api.contract.Schema; -import it.inaf.ia2.tsm.api.contract.Status; -import it.inaf.ia2.tsm.api.contract.Table; -import it.inaf.ia2.tsm.api.contract.TapSchema; -import it.inaf.ia2.tsm.api.contract.TapSchemaEntity; -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/api/EntityPropertyInfo.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/EntityPropertyInfo.java deleted file mode 100644 index 37a590508ac6f156f3b231eaebea8b6c0ab5239c..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/EntityPropertyInfo.java +++ /dev/null @@ -1,206 +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.api; - -import it.inaf.ia2.tsm.api.contract.Column; -import it.inaf.ia2.tsm.api.contract.Key; -import it.inaf.ia2.tsm.api.contract.KeyColumn; -import it.inaf.ia2.tsm.api.contract.Schema; -import it.inaf.ia2.tsm.api.contract.Table; -import it.inaf.ia2.tsm.api.contract.TapSchema; -import it.inaf.ia2.tsm.api.contract.TapSchemaVersion; -import java.sql.Types; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Describes the mapping between the - * {@link it.inaf.ia2.tsm.api.contract.TapSchemaEntity} instances - * and their related table columns. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public class EntityPropertyInfo { - - private static final Logger log = LoggerFactory.getLogger(EntityPropertyInfo.class); - - private static final Map<String, List<EntityPropertyInfo>> propertiesMap = new HashMap<>(); - - static { - List<EntityPropertyInfo> schemaProperties = new ArrayList<>(); - propertiesMap.put(TapSchema.SCHEMAS_TABLE, schemaProperties); - schemaProperties.add(new EntityPropertyInfo(Schema.SCHEMA_NAME_KEY, String.class, false)); - schemaProperties.add(new EntityPropertyInfo(Schema.UTYPE_KEY, String.class, true)); - schemaProperties.add(new EntityPropertyInfo(Schema.DESCRIPTION_KEY, String.class, true)); - schemaProperties.add(new EntityPropertyInfo(Schema.SCHEMA_ID, Long.class, true, TapSchemaVersion.TAP_SCHEMA_1_IA2, TapSchemaVersion.TAP_SCHEMA_1_1_IA2)); - - List<EntityPropertyInfo> tableProperties = new ArrayList<>(); - propertiesMap.put(TapSchema.TABLES_TABLE, tableProperties); - tableProperties.add(new EntityPropertyInfo(Table.SCHEMA_NAME_KEY, String.class, false)); - tableProperties.add(new EntityPropertyInfo(Table.TABLE_NAME_KEY, String.class, false)); - tableProperties.add(new EntityPropertyInfo(Table.TABLE_TYPE_KEY, String.class, false)); - tableProperties.add(new EntityPropertyInfo(Table.UTYPE_KEY, String.class, true)); - tableProperties.add(new EntityPropertyInfo(Table.DESCRIPTION_KEY, String.class, true)); - tableProperties.add(new EntityPropertyInfo(Table.TABLE_INDEX, Integer.class, true, TapSchemaVersion.TAP_SCHEMA_1_1, TapSchemaVersion.TAP_SCHEMA_1_1_IA2)); - tableProperties.add(new EntityPropertyInfo(Table.TABLE_ID, Long.class, true, TapSchemaVersion.TAP_SCHEMA_1_IA2, TapSchemaVersion.TAP_SCHEMA_1_1_IA2)); - - List<EntityPropertyInfo> columnProperties = new ArrayList<>(); - propertiesMap.put(TapSchema.COLUMNS_TABLE, columnProperties); - columnProperties.add(new EntityPropertyInfo(Column.TABLE_NAME_KEY, String.class, false)); - columnProperties.add(new EntityPropertyInfo(Column.COLUMN_NAME_KEY, String.class, false)); - columnProperties.add(new EntityPropertyInfo(Column.DATATYPE_KEY, String.class, false)); - columnProperties.add(new EntityPropertyInfo(Column.ARRAYSIZE_KEY, Integer.class, false, TapSchemaVersion.TAP_SCHEMA_1_1, TapSchemaVersion.TAP_SCHEMA_1_1_IA2)); - columnProperties.add(new EntityPropertyInfo(Column.SIZE_KEY, Integer.class, false)); - columnProperties.add(new EntityPropertyInfo(Column.DESCRIPTION_KEY, String.class, true)); - columnProperties.add(new EntityPropertyInfo(Column.UTYPE_KEY, String.class, true)); - columnProperties.add(new EntityPropertyInfo(Column.UNIT_KEY, String.class, true)); - columnProperties.add(new EntityPropertyInfo(Column.UCD_KEY, String.class, true)); - columnProperties.add(new EntityPropertyInfo(Column.INDEXED_KEY, Boolean.class, false)); - columnProperties.add(new EntityPropertyInfo(Column.PRINCIPAL_KEY, Boolean.class, true)); - columnProperties.add(new EntityPropertyInfo(Column.STD_KEY, Boolean.class, true)); - columnProperties.add(new EntityPropertyInfo(Column.COLUMN_INDEX_KEY, Integer.class, true, TapSchemaVersion.TAP_SCHEMA_1_1, TapSchemaVersion.TAP_SCHEMA_1_1_IA2)); - columnProperties.add(new EntityPropertyInfo(Column.ID_KEY, Integer.class, true, TapSchemaVersion.TAP_SCHEMA_1_IA2, TapSchemaVersion.TAP_SCHEMA_1_1_IA2)); - columnProperties.add(new EntityPropertyInfo(Column.COLUMN_ID_KEY, Long.class, true, TapSchemaVersion.TAP_SCHEMA_1_IA2, TapSchemaVersion.TAP_SCHEMA_1_1_IA2)); - - List<EntityPropertyInfo> keyProperties = new ArrayList<>(); - propertiesMap.put(TapSchema.KEYS_TABLE, keyProperties); - keyProperties.add(new EntityPropertyInfo(Key.ID_KEY, String.class, true)); - keyProperties.add(new EntityPropertyInfo(Key.FROM_TABLE_KEY, String.class, false)); - keyProperties.add(new EntityPropertyInfo(Key.TARGET_TABLE_KEY, String.class, false)); - keyProperties.add(new EntityPropertyInfo(Key.DESCRIPTION_KEY, String.class, true)); - keyProperties.add(new EntityPropertyInfo(Key.UTYPE_KEY, String.class, true)); - keyProperties.add(new EntityPropertyInfo(Key.KEY_ID_KEY, Long.class, true, TapSchemaVersion.TAP_SCHEMA_1_IA2, TapSchemaVersion.TAP_SCHEMA_1_1_IA2)); - - List<EntityPropertyInfo> keyColumnProperties = new ArrayList<>(); - propertiesMap.put(TapSchema.KEY_COLUMNS_TABLE, keyColumnProperties); - keyColumnProperties.add(new EntityPropertyInfo(KeyColumn.KEY_ID_KEY, String.class, true)); - keyColumnProperties.add(new EntityPropertyInfo(KeyColumn.FROM_COLUMN_KEY, String.class, false)); - keyColumnProperties.add(new EntityPropertyInfo(KeyColumn.TARGET_COLUMN_KEY, String.class, false)); - keyColumnProperties.add(new EntityPropertyInfo(KeyColumn.KEY_COLUMN_ID_KEY, Long.class, true, TapSchemaVersion.TAP_SCHEMA_1_IA2, TapSchemaVersion.TAP_SCHEMA_1_1_IA2)); - } - - /** - * Obtains all the {@link EntityPropertyInfo} for a given TAP_SCHEMA table - * name. - */ - public static List<EntityPropertyInfo> getEntityPropertiesInfo(String tapSchemaTable) { - return propertiesMap.get(tapSchemaTable); - } - - /** - * Obtains the {@link EntityPropertyInfo} for a given TAP_SCHEMA table name - * and a given column name. - */ - public static EntityPropertyInfo getEntityPropertyInfo(String tapSchemaTable, String key) { - for (EntityPropertyInfo propertyInfo : getEntityPropertiesInfo(tapSchemaTable)) { - if (propertyInfo.getPropertyKey().equals(key)) { - return propertyInfo; - } - } - log.debug("property {} not found for {} table", key, tapSchemaTable); - return null; - } - - private final String propertyKey; - private final Class type; - private final int sqlType; - private final boolean updatable; - private final TapSchemaVersion[] versions; - - protected EntityPropertyInfo(String propertyKey, Class type, boolean updatable, TapSchemaVersion... versions) { - this.propertyKey = propertyKey; - this.type = type; - - if (type == String.class) { - sqlType = Types.VARCHAR; - } else if (type == Integer.class) { - sqlType = Types.INTEGER; - } else if (type == Long.class) { - sqlType = Types.BIGINT; - } else if (type == Boolean.class) { - sqlType = Types.BIT; - } else { - throw new IllegalArgumentException("EntityPropertyInfo doesn't support class type " + type.getCanonicalName()); - } - - this.updatable = updatable; - this.versions = versions; - } - - /** - * The name of the property (the column name). - */ - public String getPropertyKey() { - return propertyKey; - } - - /** - * The class type of the property value (the value stored in a - * {@link EntityProperty}). - */ - public Class getPropertyType() { - return type; - } - - /** - * The {@link java.sql.Types} integer related to the class type of the - * property value. - */ - public int getSqlType() { - return sqlType; - } - - /** - * Returns true if the user can update the value of this property. - */ - public boolean isUpdatable() { - return updatable; - } - - /** - * Returns all the TAP_SCHEMA versions that uses this property. - */ - public TapSchemaVersion[] getVersions() { - return versions; - } - - /** - * Returns true if the specified {@link TapSchemaVersion} uses this - * property. - */ - public boolean acceptVersion(TapSchemaVersion version) { - if (versions == null || versions.length == 0) { - return true; - } - for (TapSchemaVersion v : versions) { - if (v == version) { - return true; - } - } - return false; - } -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/InsertQueryBuilder.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/InsertQueryBuilder.java deleted file mode 100644 index f62a1d5c8b9f53ca8a72b06087e9ecbc71b19f83..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/InsertQueryBuilder.java +++ /dev/null @@ -1,99 +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.api; - -import it.inaf.ia2.tsm.api.contract.DatabaseType; -import it.inaf.ia2.tsm.api.contract.TapSchema; -import it.inaf.ia2.tsm.api.contract.TapSchemaEntity; -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/api/SelectQueryBuilder.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/SelectQueryBuilder.java deleted file mode 100644 index e17277dd3f970186d92c7f5892edc92c0bb2a4a4..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/SelectQueryBuilder.java +++ /dev/null @@ -1,129 +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.api; - -import it.inaf.ia2.tsm.api.contract.DatabaseType; -import it.inaf.ia2.tsm.api.contract.TapSchema; -import it.inaf.ia2.tsm.api.contract.TapSchemaEntity; -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/api/TableImpl.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/TableImpl.java deleted file mode 100644 index 629fb0de94db31ce927a993c931eb5ec974e2af3..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/TableImpl.java +++ /dev/null @@ -1,339 +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.api; - -import it.inaf.ia2.tsm.api.contract.Column; -import it.inaf.ia2.tsm.api.contract.Key; -import it.inaf.ia2.tsm.api.contract.Schema; -import it.inaf.ia2.tsm.api.contract.Status; -import it.inaf.ia2.tsm.api.contract.Table; -import it.inaf.ia2.tsm.api.contract.TapSchema; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.TreeMap; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The main implementation of {@link Table}. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public class TableImpl extends ChildEntityImpl<Schema> implements Table { - - private static final long serialVersionUID = 8265331530960896871L; - private static final Logger log = LoggerFactory.getLogger(TableImpl.class); - - private final Map<String, Column> columns; - private final List<Key> fromKeys; - private final List<Key> targetKeys; - - private String simpleName; - private Schema parentSchema; - - private TableImpl() { - // for serialization - super(); - columns = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - fromKeys = new ArrayList<>(); - targetKeys = new ArrayList<>(); - } - - protected TableImpl(DBWrapper dbWrapper, TapSchema tapSchema, Schema schema, String tableSimpleName, String tableType) throws SQLException { - super(dbWrapper, tapSchema); - parentSchema = schema; - String schemaName = schema.getName(); - this.simpleName = tableSimpleName; - columns = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - - addProperty(SCHEMA_NAME_KEY, new FixedEntityProperty<>(schemaName)); - addProperty(TABLE_NAME_KEY, new FixedEntityProperty<>(schemaName + "." + tableSimpleName)); - addProperty(TABLE_TYPE_KEY, new FixedEntityProperty<>(tableType)); - - addProperty(UTYPE_KEY, new EditableProperty<String>()); - addProperty(DESCRIPTION_KEY, new EditableProperty<String>()); - addProperty(TABLE_INDEX, new EditableProperty<Integer>()); - addProperty(TABLE_ID, new EditableProperty<Long>()); - - fromKeys = new ArrayList<>(); - targetKeys = new ArrayList<>(); - - for (Column column : DaoColumn.loadAllTableColumns(dbWrapper, tapSchema, schemaName, (this))) { - columns.put(column.getName(), column); - } - - setStatus(Status.LOADED); - } - - /** - * Only the table name. - */ - @Override - public String getName() { - return simpleName; - } - - /** - * {@code schema_name.table_name}. - */ - @Override - public String getCompleteName() { - return getValue(TABLE_NAME_KEY, String.class); - } - - /** - * {@inheritDoc } - */ - @Override - public Column addChild(String columnName) { - String tableCompleteName = getCompleteName(); - - log.debug("Adding column {} into table {}", columnName, tableCompleteName); - - if (!columns.containsKey(columnName)) { - //throw new IllegalArgumentException("Column " + columnName + " doesn't exists in table " + tableCompleteName); - tapSchema.getConsistencyChecks().addUnexistingColumn(getCompleteName(), columnName); - return null; - } else { - Column column = columns.get(columnName); - - switch (column.getStatus()) { - case LOADED: - column.setStatus(Status.ADDED_NOT_PERSISTED); - break; - case REMOVED_NOT_PERSISTED: // undo removal - column.setStatus(Status.ADDED_NOT_PERSISTED); - break; - case TO_REMOVE: // undo removal - column.setStatus(Status.ADDED_PERSISTED); - break; - default: - throw new IllegalArgumentException("Cannot add column " + columnName + " in table " + tableCompleteName + ". Invalid column status: " + column.getStatus()); - } - - ((TapSchemaImpl) tapSchema).checkKeys(); - - return column; - } - } - - /** - * {@inheritDoc } - */ - @Override - public void removeChild(String columnName) { - String tableCompleteName = getCompleteName(); - - log.debug("Removing column {} from table {}", columnName, tableCompleteName); - - if (!columns.containsKey(columnName)) { - throw new IllegalArgumentException("Column " + columnName + " doesn't exists in table " + tableCompleteName); - } - - Column column = columns.get(columnName); - - switch (column.getStatus()) { - case ADDED_NOT_PERSISTED: - column.setStatus(Status.REMOVED_NOT_PERSISTED); - break; - case ADDED_PERSISTED: - column.setStatus(Status.TO_REMOVE); - break; - default: - throw new IllegalArgumentException("Cannot remove column " + columnName + " in table " + tableCompleteName + ". Invalid column status: " + column.getStatus()); - } - - ((TapSchemaImpl) tapSchema).checkKeys(); - } - - /** - * {@inheritDoc } - */ - @Override - public Column getChild(String childName, Status... statuses) { - return TSMUtil.getChild(columns, childName, statuses); - } - - /** - * {@inheritDoc } - */ - @Override - public List<Column> getChildren(Status... statuses) { - return TSMUtil.getChildrenByStatus(columns.values(), statuses); - } - - /** - * {@inheritDoc } - */ - @Override - public List<String> getAddableChildrenNames() { - return TSMUtil.getAddableChildrenNames(columns); - } - - @Override - public List<Column> getAddedChildren() { - return getChildren(Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); - } - - @Override - public List<Column> getAddedOrRemovedChildren() { - return getChildren(Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED, Status.TO_REMOVE, Status.REMOVED_NOT_PERSISTED); - } - - @Override - public String getTableType() { - return getValue(TABLE_TYPE_KEY, String.class); - } - - @Override - public Integer getTableIndex() { - return getValue(TABLE_INDEX, Integer.class); - } - - @Override - public void setTableIndex(Integer tableIndex) { - setValue(TABLE_INDEX, tableIndex); - } - - @Override - public Long getTableID() { - return getValue(TABLE_ID, Long.class); - } - - @Override - public void setTableID(Long tableID) { - setValue(TABLE_ID, tableID); - } - - @Override - public List<Key> getVisibleFromKeys() { - List<Key> ret = new ArrayList<>(); - for (Key key : fromKeys) { - if (key.isVisible()) { - ret.add(key); - } - } - return Collections.unmodifiableList(ret); - } - - @Override - public List<Key> getAllFromKeys() { - return Collections.unmodifiableList(fromKeys); - } - - @Override - public List<Key> getVisibleTargetKeys() { - List<Key> ret = new ArrayList<>(); - for (Key key : targetKeys) { - if (key.isVisible()) { - ret.add(key); - } - } - return Collections.unmodifiableList(ret); - } - - @Override - public List<Key> getAllTargetKeys() { - return Collections.unmodifiableList(targetKeys); - } - - @Override - public void addFromKey(Key key) { - if (!fromKeys.contains(key)) { - fromKeys.add(key); - } - } - - @Override - public void addTargetKey(Key key) { - if (!targetKeys.contains(key)) { - targetKeys.add(key); - } - } - - @Override - public int hashCode() { - int hash = 7; - hash = 29 * hash + Objects.hashCode(this.getCompleteName()); - return hash; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final TableImpl other = (TableImpl) obj; - if (!Objects.equals(this.getCompleteName(), other.getCompleteName())) { - return false; - } - return true; - } - - @Override - public String getSchemaName() { - return getValue(SCHEMA_NAME_KEY, String.class); - } - - @Override - public String getUtype() { - return getValue(UTYPE_KEY, String.class); - } - - @Override - public void setUtype(String utype) { - setValue(UTYPE_KEY, utype); - } - - @Override - public String getDescription() { - return getValue(DESCRIPTION_KEY, String.class); - } - - @Override - public void setDescription(String description) { - setValue(DESCRIPTION_KEY, description); - } - - protected void afterUpdate() { - for (Column column : columns.values()) { - if (column.getStatus() == Status.ADDED_NOT_PERSISTED) { - column.setStatus(Status.ADDED_PERSISTED); - } else if (column.getStatus() != Status.ADDED_PERSISTED) { - column.setStatus(Status.LOADED); - } - } - } - - @Override - public Schema getParent() { - return parentSchema; - } -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/TapSchemaEntityImpl.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/TapSchemaEntityImpl.java deleted file mode 100644 index 4696fee20de3d0dc22f03df5d8f18c72e04f5a3a..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/TapSchemaEntityImpl.java +++ /dev/null @@ -1,150 +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.api; - -import it.inaf.ia2.tsm.api.contract.TapSchema; -import it.inaf.ia2.tsm.api.contract.TapSchemaEntity; -import it.inaf.ia2.tsm.api.contract.TapSchemaVersion; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The main implementation of {@link TapSchemaEntity}. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public abstract class TapSchemaEntityImpl implements TapSchemaEntity, Serializable { - - private static final long serialVersionUID = 5515596028279668709L; - private static final Logger log = LoggerFactory.getLogger(TapSchemaEntityImpl.class); - - private final Map<String, EntityProperty> properties; - private final String tapSchemaEntityTable; - protected DBWrapper dbWrapper; - protected TapSchema tapSchema; - - protected TapSchemaEntityImpl() { - // for serialization - properties = new HashMap<>(); - tapSchemaEntityTable = TSMUtil.getTapSchemaTableNameFromEntity((this)); - } - - public TapSchemaEntityImpl(DBWrapper dbWrapper, TapSchema tapSchema) { - this(); - this.dbWrapper = dbWrapper; - this.tapSchema = tapSchema; - } - - protected void addProperty(String key, EntityProperty property) { - if (EntityPropertyInfo.getEntityPropertyInfo(tapSchemaEntityTable, key).acceptVersion(tapSchema.getVersion())) { - properties.put(key, property); - } - } - - protected DBWrapper getDBWrapper() { - return dbWrapper; - } - - @Override - public <T> void initProperty(String key, T value) { - properties.get(key).init(value); - } - - protected TapSchemaVersion getVersion() { - return tapSchema.getVersion(); - } - - @Override - public boolean isChanged() { - for (EntityProperty property : properties.values()) { - if (property.isChanged()) { - return true; - } - } - return false; - } - - @Override - public <T> T getValue(String key, Class<T> type) { - if (!EntityPropertyInfo.getEntityPropertyInfo(tapSchemaEntityTable, key).acceptVersion(tapSchema.getVersion())) { - throw TSMUtil.getUnsupportedOperationException(getVersion(), key + " property"); - } - return properties.get(key).getValue(type); - } - - public <T> void setValue(String key, T value) { - EntityProperty property = properties.get(key); - if (property instanceof EditableProperty) { - if (!EntityPropertyInfo.getEntityPropertyInfo(tapSchemaEntityTable, key).acceptVersion(tapSchema.getVersion())) { - throw TSMUtil.getUnsupportedOperationException(getVersion(), key + " property"); - } - ((EditableProperty) property).setValue(value); - } else { - throw new IllegalArgumentException("Property " + key + " isn't editable"); - } - } - - @Override - public <T> T getOriginalValue(String key, Class<T> type) { - EntityProperty property = properties.get(key); - if (property instanceof EditableProperty) { - return ((EditableProperty<T>) property).getOriginalValue(type); - } - throw new IllegalArgumentException("Property " + key + " hasn't original value"); - } - - @Override - public boolean isChanged(String key) { - return properties.get(key).isChanged(); - } - - @Override - public List<String> getPropertiesKeys() { - return new ArrayList<>(properties.keySet()); - } - - @Override - public void save() { - for (EntityProperty p : properties.values()) { - if (p instanceof EditableProperty) { - EditableProperty property = (EditableProperty) p; - property.save(); - } else { - FixedEntityProperty property = (FixedEntityProperty) p; - property.setChanged(false); - } - } - } - - @Override - public <T> void amendProperty(String key, T value) { - FixedEntityProperty prop = (FixedEntityProperty) properties.get(key); - prop.init(value); - prop.setChanged(true); - } -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/TapSchemaImpl.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/TapSchemaImpl.java deleted file mode 100644 index 5823d61322db9c585bb0f5e61dae4395c5a666b9..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/TapSchemaImpl.java +++ /dev/null @@ -1,425 +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.api; - -import it.inaf.ia2.tsm.api.contract.Column; -import it.inaf.ia2.tsm.api.contract.Key; -import it.inaf.ia2.tsm.api.contract.KeyColumn; -import it.inaf.ia2.tsm.api.contract.Schema; -import it.inaf.ia2.tsm.api.contract.Status; -import it.inaf.ia2.tsm.api.contract.Table; -import it.inaf.ia2.tsm.api.contract.TapSchema; -import it.inaf.ia2.tsm.api.contract.TapSchemaVersion; -import java.io.Serializable; -import java.sql.SQLException; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The main implementation of {@link TapSchema}. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public class TapSchemaImpl implements TapSchema, Serializable { - - private static final long serialVersionUID = 1678083091602571256L; - private static final Logger log = LoggerFactory.getLogger(TapSchemaImpl.class); - - private final Map<String, Schema> schemas; - private final Set<Key> allKeys; - private final ConsistencyChecks consistencyChecks; - - private TapSchemaVersion version; - private DBWrapper dbWrapper; - private String tapSchemaName; - private boolean exists; - - private TapSchemaImpl() { - // for serialization - schemas = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - allKeys = new HashSet<>(); - consistencyChecks = new ConsistencyChecks(); - } - - protected TapSchemaImpl(TapSchemaVersion version, DBWrapper dbWrapper, String tapSchemaName, boolean exists) throws SQLException { - this.version = version; - this.dbWrapper = dbWrapper; - this.tapSchemaName = tapSchemaName; - this.exists = exists; - - schemas = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - allKeys = new HashSet<>(); - consistencyChecks = new ConsistencyChecks(); - - // Initializing schemas map - for (String schemaName : DaoSchema.getAllSchemasNames(dbWrapper.getSourceDataSource(), dbWrapper.getSourceDatabaseType())) { - schemas.put(schemaName, null); - } - schemas.put(tapSchemaName, null); // the TAP_SCHEMA contains itself - - if (exists) { - DaoSchema.fillSavedSchemas(dbWrapper, (this)); - DaoTable.fillSavedTables(dbWrapper, (this)); - DaoColumn.fillSavedColumns(dbWrapper, (this)); - DaoKey.fillSavedKeys(dbWrapper, (this)); - } - } - - /** - * {@inheritDoc} - */ - @Override - public String getName() { - return tapSchemaName; - } - - /** - * {@inheritDoc} - */ - @Override - public TapSchemaVersion getVersion() { - return version; - } - - private void loadSchemaKeys(String schemaName) throws SQLException { - for (Key key : DaoKey.getSchemaKeys(dbWrapper, this, schemaName)) { - if (!allKeys.contains(key)) { - allKeys.add(key); - } - } - } - - protected Set<Key> getAllKeys() { - return allKeys; - } - - /** - * {@inheritDoc} - */ - @Override - public Schema addChild(String schemaName) throws SQLException { - log.debug("Adding schema {}", schemaName); - - Schema schema; - - if (!schemas.containsKey(schemaName)) { - - consistencyChecks.addUnexistingSchema(schemaName); - schema = null; - } else { - - schema = schemas.get(schemaName); - - if (schema == null) { - schema = new SchemaImpl(dbWrapper, this, schemaName); - schema.setStatus(Status.ADDED_NOT_PERSISTED); - schemas.put(schemaName, schema); - loadSchemaKeys(schemaName); - } else { - switch (schema.getStatus()) { - case TO_REMOVE: - schema.setStatus(Status.ADDED_PERSISTED); - break; - case REMOVED_NOT_PERSISTED: - schema.setStatus(Status.ADDED_NOT_PERSISTED); - break; - default: - throw new IllegalArgumentException("Cannot add the schema " + schemaName + ". Invalid status. Schema status is " + schema.getStatus()); - } - } - } - - checkKeys(); - - return schema; - } - - /** - * {@inheritDoc} - */ - @Override - public void removeChild(String schemaName) { - log.debug("Removing schema {}", schemaName); - - if (!schemas.containsKey(schemaName)) { - throw new IllegalArgumentException("The database doesn't contains a schema named " + schemaName); - } - - Schema schema = schemas.get(schemaName); - if (schema == null || schema.getStatus() == Status.LOADED) { - throw new IllegalArgumentException("Cannot remove the schema " + schemaName + ". It has never been added."); - } - - if (schema.getStatus() == Status.ADDED_NOT_PERSISTED) { - schema.setStatus(Status.REMOVED_NOT_PERSISTED); - } else if (schema.getStatus() == Status.ADDED_PERSISTED) { - schema.setStatus(Status.TO_REMOVE); - } - - checkKeys(); - } - - /** - * {@inheritDoc} - */ - @Override - public Schema getChild(String childName, Status... statuses) { - return TSMUtil.getChild(schemas, childName, statuses); - } - - /** - * {@inheritDoc} - */ - @Override - public List<Schema> getChildren(Status... statuses) { - return TSMUtil.getChildrenByStatus(schemas.values(), statuses); - } - - /** - * {@inheritDoc} - */ - @Override - public List<String> getAddableChildrenNames() { - return TSMUtil.getAddableChildrenNames(schemas); - } - - /** - * {@inheritDoc} - */ - @Override - public List<Schema> getAddedChildren() { - return getChildren(Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); - } - - /** - * {@inheritDoc} - */ - @Override - public List<Schema> getAddedOrRemovedChildren() { - return getChildren(Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED, Status.TO_REMOVE, Status.REMOVED_NOT_PERSISTED); - } - - /** - * This method has to be used after TAP_SCHEMA modifications are committed - * to the database, in order to remove from the memory the schemas with - * status {@code Status.TO_REMOVE} or {@code Status.REMOVED_NOT_PERSISTED}. - */ - protected void cleanSchema(String schemaName) { - if (!schemas.containsKey(schemaName)) { - throw new IllegalArgumentException("The TAP_SCHEMA doesn't contain the schema " + schemaName); - } - schemas.put(schemaName, null); - } - - /** - * {@inheritDoc} - */ - @Override - public void save() throws SQLException { - - Dao.save(dbWrapper, this); - - if (!exists) { - // Adding TAP_SCHEMA into TAP_SCHEMA - Schema tapSchemaSchema = addChild(tapSchemaName); - for (String tableName : tapSchemaSchema.getAddableChildrenNames()) { - Table table = tapSchemaSchema.addChild(tableName); - for (String columnName : table.getAddableChildrenNames()) { - table.addChild(columnName); - } - } - log.debug(this.toString()); - TSMUtil.putInfoIntoTapSchemaSchema(tapSchemaSchema); - - exists = true; // important! - - Dao.save(dbWrapper, this); // save again - } - - exists = true; - - consistencyChecks.getInconsistencies().clear(); - } - - /** - * Retrieve the maximum key id from all the schemas that are added into the - * TAP_SCHEMA. - * - * @return the maximum key, if it exists, zero otherwise. - */ - public int getMaxKeyId() { - int maxKeyId = 0; - for (Key key : allKeys) { - if (key.getId() != null) { - int keyId = Integer.parseInt(key.getId()); - if (keyId > maxKeyId) { - maxKeyId = keyId; - } - } - } - return maxKeyId; - } - - /** - * Set keys visibility based on other entities visibility (a key is visible - * if all schemas, tables and columns involved have - * {@link Status} {@code ADDED_PERSISTED} or {@code ADDED_NOT_PERSISTED}). - */ - protected void checkKeys() { - - int currentKey = getMaxKeyId() + 1; - - for (Key key : allKeys) { - - ((KeyImpl) key).setVisible(false); - - Schema fromSchema = getChild(key.getFromSchemaName(), Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); - Schema targetSchema = getChild(key.getTargetSchemaName(), Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); - if (fromSchema != null && targetSchema != null) { - - Table fromTable = fromSchema.getChild(key.getFromTableSimpleName(), Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); - Table targetTable = targetSchema.getChild(key.getTargetTableSimpleName(), Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); - - if (fromTable != null && targetTable != null) { - - boolean allColumnsVisible = true; - - for (KeyColumn keyColumn : key.getKeyColumns()) { - - Column fromColumn = fromTable.getChild(keyColumn.getFromColumn(), Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); - Column targetColumn = targetTable.getChild(keyColumn.getTargetColumn(), Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); - - if (fromColumn == null || targetColumn == null) { - allColumnsVisible = false; - break; - } - } - - if (allColumnsVisible) { - ((KeyImpl) key).setVisible(true); - if (key.getId() == null) { - key.setId(currentKey + ""); - currentKey++; - } - } - } - } - } -// for (Key key : allKeys) { -// log.debug("{} [{}]", key, key.getStatus()); -// } - } - - public void addFictitiousKey(Table fromTable, String[] fromColumns, Table targetTable, String[] targetColumns) { - KeyImpl key = new KeyImpl(dbWrapper, this, fromTable.getCompleteName(), targetTable.getCompleteName()); - key.setId((getMaxKeyId() + 1) + ""); - - for (int i = 0; i < fromColumns.length; i++) { - key.addKeyColumn(fromColumns[i], targetColumns[i]); - } - - fromTable.addFromKey(key); - targetTable.addTargetKey(key); - - allKeys.add(key); - checkKeys(); - } - - /** - * Print all TAP_SCHEMA tree (useful for debugging). - */ - @Override - public String toString() { - - StringBuilder sb = new StringBuilder("\n"); - - sb.append(String.format(">> TAP_SCHEMA %s <<\n", tapSchemaName)); - - for (Schema schema : getChildren()) { - sb.append("--"); - sb.append(schema.getName()); - sb.append(String.format(" [%s]", schema.getStatus())); - sb.append("\n"); - List<Table> tables = schema.getChildren(); - for (int i = 0; i < tables.size(); i++) { - Table table = tables.get(i); - sb.append(" |--"); - sb.append(table.getName()); - sb.append(String.format(" [%s]", table.getStatus())); - sb.append("\n"); - - String padder = i < tables.size() - 1 ? " | " : " "; - - for (Column column : table.getChildren()) { - sb.append(padder); - sb.append("|--"); - sb.append(column.getName()); - sb.append(String.format(" [%s]", column.getStatus())); - sb.append("\n"); - } - - if (table.getAllFromKeys().size() > 0) { - sb.append(padder); - sb.append("** From keys **\n"); - for (Key fromKey : table.getAllFromKeys()) { - sb.append(padder); - sb.append("* "); - sb.append(fromKey.toString()); - sb.append(String.format(" [visible=%s]", fromKey.isVisible())); - sb.append("\n"); - } - } - if (table.getAllTargetKeys().size() > 0) { - sb.append(padder); - sb.append("** Target keys **\n"); - for (Key targetKey : table.getAllTargetKeys()) { - sb.append(padder); - sb.append("* "); - sb.append(targetKey.toString()); - sb.append(String.format(" [visible=%s]", targetKey.isVisible())); - sb.append("\n"); - } - } - - sb.append("\n"); - } - } - - return sb.toString(); - } - - @Override - public boolean exists() { - return exists; - } - - @Override - public ConsistencyChecks getConsistencyChecks() { - return consistencyChecks; - } -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/UpdateQueryBuilder.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/UpdateQueryBuilder.java deleted file mode 100644 index 62d2cf0cf1e17f872a25d2f8992fd0790f046946..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/UpdateQueryBuilder.java +++ /dev/null @@ -1,96 +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.api; - -import it.inaf.ia2.tsm.api.contract.DatabaseType; -import it.inaf.ia2.tsm.api.contract.TapSchema; -import it.inaf.ia2.tsm.api.contract.TapSchemaEntity; -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/api/contract/Column.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/Column.java deleted file mode 100644 index 00b8441519684c84d492c01db5a084a111a10800..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/Column.java +++ /dev/null @@ -1,138 +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.api.contract; - -/** - * {@link TapSchemaEntity} that represents the table {@code TAP_SCHEMA.columns}. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public interface Column extends ChildEntity<Table> { - - final static String TABLE_NAME_KEY = "table_name"; - final static String COLUMN_NAME_KEY = "column_name"; - final static String DATATYPE_KEY = "datatype"; - final static String SIZE_KEY = "size"; - final static String ARRAYSIZE_KEY = "arraysize"; - final static String DESCRIPTION_KEY = "description"; - final static String UTYPE_KEY = "utype"; - final static String UNIT_KEY = "unit"; - final static String UCD_KEY = "ucd"; - final static String INDEXED_KEY = "indexed"; - final static String PRINCIPAL_KEY = "principal"; - final static String STD_KEY = "std"; - final static String COLUMN_INDEX_KEY = "column_index"; - final static String ID_KEY = "id"; // IA2? - final static String COLUMN_ID_KEY = "columnID"; - - /** - * The complete table name: {@code <schema-name>.<table-name>}. - */ - String getTableCompleteName(); - - /** - * Indicates if the column is a primary key (or a part of a primary key). - */ - boolean isPrimaryKey(); - - /** - * Retrieve (if it exists) the key of which this column is a "from column". - */ - Key getForeignKey(); - - /** - * The value in the {@code datatype} column. - */ - String getDatatype(); - - Integer getArraySize(); - - /** - * The value in the {@code size} column. - */ - Integer getSize(); - - /** - * The value in the {@code description} column. - */ - String getDescription(); - - void setDescription(String description); - - /** - * The value in the {@code utype} column. - */ - String getUtype(); - - void setUtype(String utype); - - /** - * The value in the {@code unit} column. - */ - String getUnit(); - - void setUnit(String unit); - - /** - * The value in the {@code ucd} column: represents the Unified Content - * Descriptor of the column. - */ - String getUCD(); - - void setUCD(String ucd); - - /** - * The value in the {@code indexed} column: indicates that the column is - * indexed.<br> It is an integer but should be treated as a boolean value. - */ - boolean getIndexed(); - - /** - * The value in the {@code principal} column: indicates that the column is - * considered a core part the content.<br> It is an integer but should be - * treated as a boolean value. - */ - boolean getPrincipal(); - - void setPrincipal(boolean principal); - - /** - * The value in the {@code std} column: indicates that the column is defined - * by some standard.<br> It is an integer but should be treated as a boolean - * value. - */ - boolean getStd(); - - void setStd(boolean std); - - Integer getColumnIndex(); - - void setColumnIndex(Integer columnIndex); - - /** - * The value in the {@code columnID} column: it represents [TODO]... - */ - Long getColumnID(); - - void setColumnID(Long columnID); -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/Key.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/Key.java deleted file mode 100644 index 40965887fb8367645806e31448803493edaf62b0..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/Key.java +++ /dev/null @@ -1,103 +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.api.contract; - -import java.util.List; - -/** - * {@link TapSchemaEntity} that represents the table {@code TAP_SCHEMA.keys}. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public interface Key extends TapSchemaEntity { - - static final String ID_KEY = "key_id"; - static final String FROM_TABLE_KEY = "from_table"; - static final String TARGET_TABLE_KEY = "target_table"; - static final String DESCRIPTION_KEY = "description"; - static final String UTYPE_KEY = "utype"; - static final String KEY_ID_KEY = "keyID"; - - /** - * The value in the {@code key_id} column: represents the ID of the key (The - * TAP standard define the {@code key_id} as a {@code VARCHAR}, but in our - * implementation we assume it represents a numeric value). - */ - String getId(); - - void setId(String keyId); - - /** - * List of the {@code KeyColumnEntity} owned by this {@code KeyEntity}. - */ - List<KeyColumn> getKeyColumns(); - - String getFromSchemaName(); - - String getFromTableSimpleName(); - - /** - * The value in the {@code from_table} column: it is the complete name of - * the table, as defined in the TAP standard: so it is - * {@code <schema-name>.<table-name>}. - */ - String getFromTableCompleteName(); - - String getTargetSchemaName(); - - String getTargetTableSimpleName(); - - /** - * The value in the {@code target_table} column: it is the complete name of - * the table, as defined in the TAP standard: so it is - * {@code <schema-name>.<table-name>}. - */ - String getTargetTableCompleteName(); - - /** - * The value in the {@code utype} column. - */ - String getUtype(); - - void setUtype(String utype); - - /** - * The value in the {@code description} column. - */ - String getDescription(); - - void setDescription(String description); - - /** - * The value in the {@code keyID} column: it represents [TODO]... - */ - Long getKeyID(); - - void setKeyID(Long keyID); - - /** - * A key is visible if all schemas, tables and columns involved with it have - * {@link Status} {@code ADDED_PERSISTED} or {@code ADDED_NOT_PERSISTED}. - */ - boolean isVisible(); -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/KeyColumn.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/KeyColumn.java deleted file mode 100644 index c6f9c3870f3d134b72bcbed0e3eb2b21424e55bb..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/KeyColumn.java +++ /dev/null @@ -1,63 +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.api.contract; - -/** - * {@link TapSchemaEntity} that represents the table - * {@code TAP_SCHEMA.key_columns}. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public interface KeyColumn extends TapSchemaEntity { - - static final String KEY_ID_KEY = "key_id"; - static final String FROM_COLUMN_KEY = "from_column"; - static final String TARGET_COLUMN_KEY = "target_column"; - static final String KEY_COLUMN_ID_KEY = "key_columnID"; - - Key getParent(); - - /** - * The value in the {@code key_id} column. - */ - String getKeyId(); - - void setKeyId(String keyId); - - /** - * The value in the {@code from_column} column. - */ - String getFromColumn(); - - /** - * The value in the {@code target_column} column. - */ - String getTargetColumn(); - - /** - * The value in the {@code key_columnID} column: it represents [TODO]... - */ - Long getKeyColumnID(); - - void setKeyColumnID(Long keyColumnID); -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/Schema.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/Schema.java deleted file mode 100644 index af7c875d4da67b3875f52402c6cd500532f0ba59..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/Schema.java +++ /dev/null @@ -1,57 +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.api.contract; - -/** - * {@link TapSchemaEntity} that represents the table {@code TAP_SCHEMA.schemas}. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public interface Schema extends EntitiesContainer<Table>, ChildEntity<TapSchema> { - - final static String SCHEMA_NAME_KEY = "schema_name"; - final static String UTYPE_KEY = "utype"; - final static String DESCRIPTION_KEY = "description"; - final static String SCHEMA_ID = "schemaID"; - - /** - * The value in the {@code utype} column. - */ - String getUtype(); - - void setUtype(String utype); - - /** - * The value in the {@code description} column. - */ - String getDescription(); - - void setDescription(String description); - - /** - * The value in the {@code schemaID} column: it represents [TODO]... - */ - Long getSchemaID(); - - void setSchemaID(Long schemaID); -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/Table.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/Table.java deleted file mode 100644 index 1d8abf66a04b18941f9e1466a8cc9c2100d7e0d5..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/Table.java +++ /dev/null @@ -1,115 +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.api.contract; - -import java.util.List; - -/** - * {@link TapSchemaEntity} that represents the table {@code TAP_SCHEMA.tables}. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public interface Table extends EntitiesContainer<Column>, ChildEntity<Schema> { - - final static String SCHEMA_NAME_KEY = "schema_name"; - final static String TABLE_NAME_KEY = "table_name"; - final static String TABLE_TYPE_KEY = "table_type"; - final static String UTYPE_KEY = "utype"; - final static String DESCRIPTION_KEY = "description"; - final static String TABLE_INDEX = "table_index"; - final static String TABLE_ID = "tableID"; - - /** - * The value in the {@code schema_name} column. - */ - String getSchemaName(); - - /** - * The value in the {@code table_name} column: it represents the complete - * table name: {@code schema_name.table_name}. - */ - String getCompleteName(); - - /** - * The value in the {@code table_type} column: it could be {@code table} or - * {@code view}. - */ - String getTableType(); - - Integer getTableIndex(); - - void setTableIndex(Integer tableIndex); - - /** - * The value in the {@code tableID} column: it represents [TODO]... - */ - Long getTableID(); - - void setTableID(Long tableID); - - /** - * Retrieve the list of all the visible keys whose - * {@link Key#getFromTableCompleteName()} method returns the complete name - * of this table. - */ - List<Key> getVisibleFromKeys(); - - /** - * Retrieve the list of all the keys (both visible and not visible) whose - * {@link Key#getFromTableCompleteName()} method returns the complete name - * of this table. - */ - List<Key> getAllFromKeys(); - - /** - * Retrieve the list of all the visible keys whose - * {@link Key#getTargetTableCompleteName()} method returns the complete name - * of this table. - */ - List<Key> getVisibleTargetKeys(); - - /** - * Retrieve the list of all the keys (both visible and not visible) whose - * {@link Key#getTargetTableCompleteName()} method returns the complete name - * of this table. - */ - List<Key> getAllTargetKeys(); - - void addFromKey(Key key); - - void addTargetKey(Key key); - - /** - * The value in the {@code utype} column. - */ - String getUtype(); - - void setUtype(String utype); - - /** - * The value in the {@code description} column. - */ - String getDescription(); - - void setDescription(String description); -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/TapSchema.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/TapSchema.java deleted file mode 100644 index 2b658803264bda3d6785f3edd87fc6a6782f8294..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/TapSchema.java +++ /dev/null @@ -1,62 +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.api.contract; - -import it.inaf.ia2.tsm.api.ConsistencyChecks; -import java.sql.SQLException; - -/** - * Represents a TAP_SCHEMA. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public interface TapSchema extends EntitiesContainer<Schema> { - - public static final String TABLES_TABLE = "tables"; - public static final String SCHEMAS_TABLE = "schemas"; - public static final String COLUMNS_TABLE = "columns"; - public static final String KEYS_TABLE = "keys"; - public static final String KEY_COLUMNS_TABLE = "key_columns"; - - ConsistencyChecks getConsistencyChecks(); - - /** - * The name of the TAP_SCHEMA schema. - */ - String getName(); - - /** - * The version selected for this TAP_SCHEMA. - */ - TapSchemaVersion getVersion(); - - /** - * Save or update the TAP_SCHEMA changes into the database. - */ - void save() throws SQLException; - - /** - * Define if the TAP_SCHEMA schema was already written into the database. - */ - boolean exists(); -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/TapSchemaEntity.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/TapSchemaEntity.java deleted file mode 100644 index 35895847f1eed32f698dff589c10bdc12e5d8cb2..0000000000000000000000000000000000000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/TapSchemaEntity.java +++ /dev/null @@ -1,86 +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.api.contract; - -import java.util.List; - -/** - * Represents an object that is mapped on a table of the TAP_SCHEMA. - * - * A TapSchemaEntity has some properties that correspond to columns of the table - * represented by the TapSchemaEntity.<br> - * Property value can be changed but the original value has to be maintained - * until the {@link #save()} method is called. - * - * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} - */ -public interface TapSchemaEntity { - - /** - * Initializes the value of a property (store the original value). - */ - <T> void initProperty(String key, T value); - - /** - * Set the correct value for a fixed property that has inconsistent value in - * the TAP_SCHEMA. - */ - <T> void amendProperty(String key, T value); - - /** - * Returns true if one or more property values is changed (the current value - * is different from the original value). - */ - boolean isChanged(); - - /** - * Returns true the value of property which key is passed as parameter is - * changed (the current value is different from the original value). - */ - boolean isChanged(String key); - - /** - * Retrieve the current value of the property (the last value set). - */ - <T> T getValue(String key, Class<T> type); - - /** - * Retrieve the original value of the property. - * - * @param key the name of the property (the name of the table column). - * @param type the class of the property value. - * @return - */ - <T> T getOriginalValue(String key, Class<T> type); - - /** - * Retrieve a list of all properties names (the names of the table columns). - */ - List<String> getPropertiesKeys(); - - /** - * Marks the TapSchemaEntity as saved (all original values are set equals to - * current values). - */ - void save(); -} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/EntityProperty.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/ADQL.java similarity index 57% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/EntityProperty.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/ADQL.java index 29afe97c5caef614aa1727cdd9924d2b0695e5e9..830e6f7d2f84523a6818532f24467d07795b7466 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/EntityProperty.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/ADQL.java @@ -1,11 +1,11 @@ -/* +/* * _____________________________________________________________________________ * * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of * Trieste INAF - IA2 Italian Center for Astronomical Archives * _____________________________________________________________________________ * - * Copyright (C) 2016 Istituto Nazionale di Astrofisica + * Copyright (C) 2017 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 @@ -20,25 +20,26 @@ * 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.datalayer; /** - * Store the value of an entity property (that corresponds to a column of the - * mapped table). - * + * ADQL data type constants. + * * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} */ -public interface EntityProperty { - - /** - * Retrieve the current value. - */ - <T> T getValue(Class<T> type); +public class ADQL { - /** - * Initialize the value. - */ - <T> void init(T initialValue); + private static final String ADQL_PREFIX = "adql:"; - boolean isChanged(); + public static final String INTEGER = ADQL_PREFIX + "INTEGER"; + public static final String SMALLINT = ADQL_PREFIX + "SMALLINT"; + public static final String BIGINT = ADQL_PREFIX + "BIGINT"; + public static final String REAL = ADQL_PREFIX + "REAL"; + public static final String CHAR = ADQL_PREFIX + "CHAR"; + public static final String VARCHAR = ADQL_PREFIX + "VARCHAR"; + public static final String TIMESTAMP = ADQL_PREFIX + "TIMESTAMP"; + + public static String getDataType(String dataType) { + return ADQL_PREFIX + dataType.toUpperCase(); + } } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/Credentials.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/Credentials.java similarity index 98% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/Credentials.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/Credentials.java index c3ad13438e3ad3bfafb188233c927820bf4383a8..7f8e342c4f33c37765fa423e5c07729e6ab65274 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/Credentials.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/Credentials.java @@ -20,9 +20,9 @@ * 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.datalayer; -import it.inaf.ia2.tsm.api.contract.DatabaseType; +import it.inaf.ia2.tsm.datalayer.DatabaseType; import java.io.Serializable; import javax.xml.bind.annotation.XmlAttribute; import org.slf4j.Logger; 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 new file mode 100644 index 0000000000000000000000000000000000000000..48acab3be4aaa4f52775561e1de48c114ee7063e --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBroker.java @@ -0,0 +1,65 @@ +/* + * _____________________________________________________________________________ + * + * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of + * Trieste INAF - IA2 Italian Center for Astronomical Archives + * _____________________________________________________________________________ + * + * Copyright (C) 2017 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.datalayer; + +import it.inaf.ia2.tsm.KeyMetadata; +import it.inaf.ia2.tsm.TapSchema; +import it.inaf.ia2.tsm.TapSchemaEntity; +import it.inaf.ia2.tsm.xmlmodel.TableModel; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.List; +import java.util.Map; + +/** + * + * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} + */ +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; + + List<String> getAllTablesNames(String schemaName) throws SQLException; + + Map<String, String> getAllTableTypes(String schemaName) throws SQLException; + + List<String> getAllColumnsNames(String schemaName, String tableName) throws SQLException; + + Map<String, Map<String, Object>> getAllColumnsMetadata(String schemaName, String tableSimpleName) throws SQLException; + + List<KeyMetadata> getKeysMetadata(String schemaName) throws SQLException; + + List<Map<String, Object>> getSavedItems(String tapSchemaName, TableModel tableModel, String whereCondition, Object[] whereParams) throws SQLException; + + List<Map<String, Object>> getSavedItems(String tapSchemaName, TableModel tableModel) throws SQLException; + + void insertItem(String tapSchemaName, TapSchemaEntity entity, Connection conn) throws SQLException; + + void updateItem(String tapSchemaName, TapSchemaEntity entity, Connection conn, String whereCondition, Object... whereParams) throws SQLException; + + void save(TapSchema tapSchema) throws SQLException; +} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/TapSchemaVersion.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerFactory.java similarity index 65% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/TapSchemaVersion.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerFactory.java index c91e790b202919cc39865246e41dbfc2e0d81560..7213c5632bc38be70cf680c92a1a3514bfd1805e 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/TapSchemaVersion.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerFactory.java @@ -1,11 +1,11 @@ -/* +/* * _____________________________________________________________________________ * * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of * Trieste INAF - IA2 Italian Center for Astronomical Archives * _____________________________________________________________________________ * - * Copyright (C) 2016 Istituto Nazionale di Astrofisica + * Copyright (C) 2017 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 @@ -20,24 +20,22 @@ * 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.contract; +package it.inaf.ia2.tsm.datalayer; + +import it.inaf.ia2.tsm.datalayer.mysql.MySQLDBBroker; /** - * Version of a TAP_SCHEMA schema. TAP_SCHEMA schemas with different versions - * can use different columns in the database. * * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} */ -public enum TapSchemaVersion { - - TAP_SCHEMA_1("TAP_SCHEMA 1.0"), - TAP_SCHEMA_1_1("TAP_SCHEMA 1.1"), - TAP_SCHEMA_1_IA2("IA2 TAP_SCHEMA 1.0"), - TAP_SCHEMA_1_1_IA2("IA2 TAP_SCHEMA 1.1"); - - private final String name; +public class DBBrokerFactory { - private TapSchemaVersion(String name) { - this.name = name; + public static DBBroker getDBBroker(DataSourceWrapper dataSourceWrapper) { + switch (dataSourceWrapper.getDatabaseType()) { + case MYSQL: + return new MySQLDBBroker(dataSourceWrapper.getDataSource()); + default: + throw new UnsupportedOperationException(dataSourceWrapper.getDatabaseType() + " not supported yet"); + } } } 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 new file mode 100644 index 0000000000000000000000000000000000000000..c283b39d59fcc53c80168dfeef12a793f051c25e --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerTemplate.java @@ -0,0 +1,631 @@ +/* + * _____________________________________________________________________________ + * + * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of + * Trieste INAF - IA2 Italian Center for Astronomical Archives + * _____________________________________________________________________________ + * + * Copyright (C) 2017 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.datalayer; + +import it.inaf.ia2.tsm.Column; +import it.inaf.ia2.tsm.Key; +import it.inaf.ia2.tsm.KeyColumn; +import it.inaf.ia2.tsm.Schema; +import it.inaf.ia2.tsm.Status; +import it.inaf.ia2.tsm.TSMUtil; +import it.inaf.ia2.tsm.Table; +import it.inaf.ia2.tsm.TapSchema; +import it.inaf.ia2.tsm.TapSchemaEntity; +import it.inaf.ia2.tsm.UpdateOperations; +import it.inaf.ia2.tsm.xmlmodel.PropertyModel; +import it.inaf.ia2.tsm.xmlmodel.TableModel; +import it.inaf.ia2.tsm.xmlmodel.TapSchemaModel; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Types; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.sql.DataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} + */ +public abstract class DBBrokerTemplate implements DBBroker { + + private static final Logger LOG = LoggerFactory.getLogger(DBBrokerTemplate.class); + + protected final DataSource dataSource; + private final char escapeCharacter; + + public DBBrokerTemplate(DataSource dataSource, char escapeCharacter) { + this.dataSource = dataSource; + this.escapeCharacter = escapeCharacter; + } + + protected List<String> getAllItemsNames(String query) throws SQLException { + + List<String> allSchemas = new ArrayList<>(); + + LOG.debug("Executing query: {}", query); + + try (Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(query)) { + while (resultSet.next()) { + allSchemas.add(resultSet.getString(1)); + } + } + + Collections.sort(allSchemas, String.CASE_INSENSITIVE_ORDER); + return allSchemas; + } + + protected String buildColumnsList(String[] columns) { + + StringBuilder sb = new StringBuilder(); + + boolean first = true; + for (String keyColumn : columns) { + if (!first) { + sb.append(","); + } + first = false; + sb.append(escape(keyColumn)); + } + + return sb.toString(); + } + + protected String escape(String name) { + return String.format("%s%s%s", escapeCharacter, name, escapeCharacter); + } + + 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 void addForeignKey(String tapSchemaName, String tableName, String[] fromKeyColumns, String targetTableName, String[] toKeyColumns, Connection conn) throws SQLException; + + private void addPrimaryKey(String tapSchemaName, String tableName, String keyColumn, Connection conn) throws SQLException { + addPrimaryKey(tapSchemaName, tableName, new String[]{keyColumn}, conn); + } + + 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); + } + + protected abstract void createDatabase(String databaseName, Connection conn) throws SQLException; + + private void createTapSchemaStructure(String tapSchemaName, TapSchemaModel tapSchemaModel) throws SQLException { + + try (Connection conn = dataSource.getConnection()) { + + createDatabase(tapSchemaName, conn); + + for (TableModel tableModel : tapSchemaModel.getTables().values()) { + createTable(tapSchemaName, tableModel, conn); + } + + // schemas keys + addPrimaryKey(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); + + // 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); + + // 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); + + // 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); + //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); + } + } + + @Override + public void save(TapSchema tapSchema) throws SQLException { + + LOG.debug("Saving TAP_SCHEMA"); + + Connection connection = null; + PreparedStatement statement = null; + boolean transactionStarted = false; + + try { + + if (!tapSchema.exists()) { + createTapSchemaStructure(tapSchema.getName(), tapSchema.getTapSchemaModel()); + } + + connection = dataSource.getConnection(); + + UpdateOperations operations = new UpdateOperations(tapSchema); + + // Start update + connection.setAutoCommit(false); // start transaction + transactionStarted = true; + + String tapSchemaNameEscaped = escape(tapSchema.getName()); + + // 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, escape("key_columns")); + 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, escape("keys")); + 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, escape("columns")); + 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, escape("tables")); + 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, escape("schemas")); + 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()) { + insertItem(tapSchema.getName(), schema, connection); + } + + if (!operations.getTablesToAdd().isEmpty()) { + LOG.debug("Inserting {} new tables", operations.getTablesToAdd().size()); + } + for (Table table : operations.getTablesToAdd()) { + insertItem(tapSchema.getName(), table, connection); + } + + if (!operations.getColumnsToAdd().isEmpty()) { + LOG.debug("Inserting {} new columns", operations.getColumnsToAdd().size()); + } + for (Column column : operations.getColumnsToAdd()) { + insertItem(tapSchema.getName(), column, connection); + } + + if (!operations.getKeysToAdd().isEmpty()) { + LOG.debug("Inserting {} new keys", operations.getKeysToAdd().size()); + } + for (Key key : operations.getKeysToAdd()) { + // insert new keys and their key columns + insertItem(tapSchema.getName(), key, connection); + // TODO: INSERT COLUMNS!!! + } + + //UPDATE ELEMENTS + if (tapSchema.exists()) { + for (Key key : operations.getKeysToUpdate()) { + // update keys and their key columns + String whereCond = String.format("%s = ?", escape(Key.ID_KEY)); + updateItem(tapSchema.getName(), key, connection, whereCond, key.getId()); + } + + for (Schema schema : operations.getSchemasToUpdate()) { + String whereCond = String.format("%s = ?", escape(Schema.SCHEMA_NAME_KEY)); + updateItem(tapSchema.getName(), schema, connection, whereCond, schema.getName()); + } + + for (Table table : operations.getTablesToUpdate()) { + String whereCond = String.format("%s = ?", escape(Table.TABLE_NAME_KEY)); + updateItem(tapSchema.getName(), table, connection, whereCond, table.getCompleteName()); + } + + for (Column column : operations.getColumnsToUpdate()) { + String whereCond = String.format("%s = ? AND %s = ?", escape(Column.TABLE_NAME_KEY), escape(Column.COLUMN_NAME_KEY)); + updateItem(tapSchema.getName(), column, connection, whereCond, column.getTableCompleteName(), column.getName()); + } + } + + 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.getParent().getName()); + if (schema != null) { + schema.cleanTable(table.getName()); + } + } + for (Table table : operations.getTablesToClean()) { + Schema schema = tapSchema.getChild(table.getParent().getName()); + if (schema != null) { + schema.cleanTable(table.getName()); + } + } + for (Schema schema : operations.getSchemasToRemove()) { + tapSchema.cleanSchema(schema.getName()); + } + for (Schema schema : operations.getSchemasToClean()) { + 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); + } + } + } + } + + @Override + public List<Map<String, Object>> getSavedItems(String tapSchemaName, TableModel tableModel, String whereCondition, Object[] whereParams) throws SQLException { + + StringBuilder querySb = new StringBuilder("SELECT "); + + boolean first = true; + for (PropertyModel pm : tableModel.getProperties().values()) { + if (!first) { + querySb.append(", "); + } + first = false; + querySb.append(escape(pm.getName())); + } + + querySb.append(" FROM "); + + querySb.append(escape(tapSchemaName)); + querySb.append("."); + querySb.append(escape(tableModel.getName())); + + // TODO: Manage where condition + String query = querySb.toString(); + + LOG.debug("Executing query {}", query); + + try (Connection conn = dataSource.getConnection()) { + try (Statement statement = conn.createStatement(); + ResultSet rs = statement.executeQuery(query)) { + + List<Map<String, Object>> items = new ArrayList<>(); + + while (rs.next()) { + Map<String, Object> item = new HashMap<>(); + + for (PropertyModel pm : tableModel.getProperties().values()) { + Object value = rs.getObject(pm.getName(), pm.getType()); + item.put(pm.getName(), value); + } + + items.add(item); + } + + return items; + } + } + } + + @Override + public List<Map<String, Object>> getSavedItems(String tapSchemaName, TableModel tableModel) throws SQLException { + return getSavedItems(tapSchemaName, tableModel, null, null); + } + + private int getSQLType(Class type) { + if (type == String.class) { + return Types.VARCHAR; + } else if (type == Integer.class) { + return Types.INTEGER; + } else if (type == Long.class) { + return Types.BIGINT; + } else if (type == Boolean.class) { + return Types.BIT; + } else { + throw new UnsupportedOperationException("Class type " + type.getCanonicalName() + " not supported yet!"); + } + } + + @Override + public void insertItem(String tapSchemaName, TapSchemaEntity tapSchemaItem, Connection conn) throws SQLException { + + StringBuilder querySb = new StringBuilder("INSERT INTO "); + querySb.append(escape(tapSchemaName)); + querySb.append("."); + querySb.append(escape(tapSchemaItem.getTableModel().getName())); + querySb.append(" ("); + + boolean first = true; + for (String key : tapSchemaItem.getPropertiesKeys()) { + if (!first) { + querySb.append(", "); + } + first = false; + querySb.append(escape(key)); + } + + querySb.append(") VALUES ("); + first = true; + for (String key : tapSchemaItem.getPropertiesKeys()) { + if (!first) { + querySb.append(","); + } + first = false; + querySb.append("?"); + } + querySb.append(")"); + + String query = querySb.toString(); + + try (PreparedStatement statement = conn.prepareStatement(query)) { + + List<Object> values = null; + if (LOG.isDebugEnabled()) { + values = new ArrayList<>(); + } + + int i = 1; + for (String key : tapSchemaItem.getPropertiesKeys()) { + Class type = tapSchemaItem.getTableModel().get(key).getType(); + Object value = tapSchemaItem.getValue(key, type); + statement.setObject(i, value, getSQLType(type)); + i++; + + if (values != null) { + values.add(value); + } + } + + LOG.debug("Executing query {} [{}]", query, values); + statement.executeUpdate(); + } + } + + @Override + public void updateItem(String tapSchemaName, TapSchemaEntity tapSchemaItem, Connection conn, String whereCondition, Object... whereParams) throws SQLException { + + StringBuilder querySb = new StringBuilder("UPDATE "); + querySb.append(escape(tapSchemaName)); + querySb.append("."); + querySb.append(escape(tapSchemaItem.getTableModel().getName())); + querySb.append("\nSET"); + + boolean first = true; + for (String key : tapSchemaItem.getPropertiesKeys()) { + if (!first) { + querySb.append(","); + } + first = false; + querySb.append(" "); + querySb.append(escape(key)); + querySb.append(" = ?"); + } + + querySb.append("\nWHERE "); + querySb.append(whereCondition); + + String query = querySb.toString(); + + try (PreparedStatement ps = conn.prepareStatement(query)) { + + int i = 0; + + List<Object> statParams = null; + if (LOG.isDebugEnabled()) { + statParams = new ArrayList<>(); + } + for (String key : tapSchemaItem.getPropertiesKeys()) { + Object value = tapSchemaItem.getValue(key); + ps.setObject(i, value, getSQLType(value.getClass())); + i++; + if (statParams != null) { + statParams.add(value); + } + } + for (Object wp : whereParams) { + ps.setObject(i, wp, getSQLType(wp.getClass())); + i++; + if (statParams != null) { + statParams.add(wp); + } + } + + LOG.debug("Executing query: {} [{}]", query, statParams); + + ps.executeUpdate(); + } + } + + protected abstract String getSchemaTablesQuery(String schemaName); + + @Override + public List<String> getAllTAPSchemaNames(List<String> allSchemata) throws SQLException { + + List<String> allTAPSchemas = new ArrayList<>(); + + for (String schemaName : allSchemata) { + + boolean schemas = false, + tables = false, + columns = false, + keys = false, + keyColumns = false; + + String query = getSchemaTablesQuery(schemaName); + + 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()); + + Collections.sort(allTAPSchemas, String.CASE_INSENSITIVE_ORDER); + + return allTAPSchemas; + } + + protected abstract String getTableTypesQuery(String schemaName); + + @Override + public Map<String, String> getAllTableTypes(String schemaName) throws SQLException { + LOG.debug("getTablesTypes"); + + final Map<String, String> tablesTypes = new HashMap<>(); + + String query = getTableTypesQuery(schemaName); + 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; + } +} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/DBWrapper.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBWrapper.java similarity index 58% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/DBWrapper.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBWrapper.java index 4a81333ad7e358ea7a404ab06c6e34870f0e2d9c..bddca27e8cc149820dcca2bf7dcdfc0f108e90ea 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/DBWrapper.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBWrapper.java @@ -20,9 +20,8 @@ * 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.datalayer; -import it.inaf.ia2.tsm.api.contract.DatabaseType; import java.io.Serializable; import java.sql.Connection; import java.sql.SQLException; @@ -44,19 +43,16 @@ import org.slf4j.LoggerFactory; public class DBWrapper implements Serializable { private static final long serialVersionUID = 1721030677924066695L; - private final static Logger log = LoggerFactory.getLogger(DBWrapper.class); + private final static Logger LOG = LoggerFactory.getLogger(DBWrapper.class); // Same credentials - private Credentials credentials; + private DataSourceWrapper dataSourceWrapper; // Separated credentials - private Credentials sourceCredentials; - private Credentials tapSchemaCredentials; - - private final DataSourcesWrapper dataSources; + private DataSourceWrapper sourceDataSourceWrapper; + private DataSourceWrapper tapSchemaDataSourceWrapper; private DBWrapper() { - dataSources = new DataSourcesWrapper(); } /** @@ -65,7 +61,7 @@ public class DBWrapper implements Serializable { */ public DBWrapper(Credentials credentials) { this(); - this.credentials = credentials; + dataSourceWrapper = new DataSourceWrapper(credentials); } /** @@ -74,16 +70,30 @@ public class DBWrapper implements Serializable { */ public DBWrapper(Credentials sourceCredentials, Credentials tapSchemaCredentials) { this(); - this.sourceCredentials = sourceCredentials; - this.tapSchemaCredentials = tapSchemaCredentials; + sourceDataSourceWrapper = new DataSourceWrapper(sourceCredentials); + tapSchemaDataSourceWrapper = new DataSourceWrapper(tapSchemaCredentials); + } + + public DataSourceWrapper getSourceDataSourceWrapper() { + if (dataSourceWrapper != null) { + return dataSourceWrapper; + } + return sourceDataSourceWrapper; } public DataSource getSourceDataSource() { - return dataSources.getSourceDataSource(); + return getSourceDataSourceWrapper().getDataSource(); + } + + public DataSourceWrapper getTapSchemaDataSourceWrapper() { + if (dataSourceWrapper != null) { + return dataSourceWrapper; + } + return tapSchemaDataSourceWrapper; } public DataSource getTapSchemaDataSource() { - return dataSources.getTapSchemaDataSource(); + return getTapSchemaDataSourceWrapper().getDataSource(); } public Connection getSourceConnection() throws SQLException { @@ -95,25 +105,27 @@ public class DBWrapper implements Serializable { } public Credentials getSourceCredentials() { - if (credentials != null) { - return credentials; - } - return sourceCredentials; + return getSourceDataSourceWrapper().getCredentials(); } public Credentials getTapSchemaCredentials() { - if (credentials != null) { - return credentials; - } - return tapSchemaCredentials; + return getTapSchemaDataSourceWrapper().getCredentials(); } public DatabaseType getSourceDatabaseType() { - return getSourceCredentials().getDatabaseType(); + return getSourceDataSourceWrapper().getDatabaseType(); } public DatabaseType getTapSchemaDatabaseType() { - return getTapSchemaCredentials().getDatabaseType(); + return getTapSchemaDataSourceWrapper().getDatabaseType(); + } + + /** + * @return true if the TAP_SCHEMA <code>DataSource</code> is different from + * its source <code>DataSource</code>, false otherwise. + */ + public boolean isSeparatedSources() { + return dataSourceWrapper == null; } /** @@ -125,61 +137,15 @@ public class DBWrapper implements Serializable { */ public void testConnections() throws SQLException { Connection connection; - if (credentials != null) { - connection = dataSources.getSourceDataSource().getConnection(); + + if (isSeparatedSources()) { + connection = getSourceDataSource().getConnection(); connection.close(); - } else { - connection = dataSources.getSourceDataSource().getConnection(); + connection = getTapSchemaDataSource().getConnection(); connection.close(); - connection = dataSources.getTapSchemaDataSource().getConnection(); + } else { + connection = getSourceDataSource().getConnection(); connection.close(); } } - - /** - * @return true if the TAP_SCHEMA <code>DataSource</code> is different from - * its source <code>DataSource</code>, false otherwise. - */ - public boolean isSeparatedSources() { - return dataSources.isSeparatedSources(); - } - - private class DataSourcesWrapper implements Serializable { - - private static final long serialVersionUID = -7025255003212206748L; - - private transient DataSource dataSource; - private transient DataSource sourceDataSource; - private transient DataSource tapSchemaDataSource; - - public boolean isSeparatedSources() { - return dataSource == null; - } - - public DataSource getTapSchemaDataSource() { - if (credentials != null) { - if (dataSource == null) { - dataSource = TSMUtil.createDataSource(credentials); - } - return dataSource; - } - if (tapSchemaDataSource == null) { - tapSchemaDataSource = TSMUtil.createDataSource(tapSchemaCredentials); - } - return tapSchemaDataSource; - } - - public DataSource getSourceDataSource() { - if (credentials != null) { - if (dataSource == null) { - dataSource = TSMUtil.createDataSource(credentials); - } - return dataSource; - } - if (sourceDataSource == null) { - sourceDataSource = TSMUtil.createDataSource(sourceCredentials); - } - return sourceDataSource; - } - } } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DataSourceWrapper.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DataSourceWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..266794a7083e3031673bc478aaf29bee85168de1 --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DataSourceWrapper.java @@ -0,0 +1,88 @@ +/* + * _____________________________________________________________________________ + * + * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of + * Trieste INAF - IA2 Italian Center for Astronomical Archives + * _____________________________________________________________________________ + * + * Copyright (C) 2017 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.datalayer; + +import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; +import java.io.Serializable; +import javax.sql.DataSource; +import org.postgresql.ds.PGPoolingDataSource; + +/** + * Serializable wrapper for a DataSource. + * + * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} + */ +public class DataSourceWrapper implements Serializable { + + private static final long serialVersionUID = -7658342136473761826L; + + private Credentials credentials; + private transient DataSource dataSource; + + private DataSourceWrapper() { + } + + public DataSourceWrapper(Credentials credentials) { + this.credentials = credentials; + } + + public DataSource getDataSource() { + if (dataSource == null) { + switch (credentials.getDatabaseType()) { + + case MYSQL: + MysqlDataSource myds = new MysqlDataSource(); + + myds.setServerName(credentials.getHostname()); + myds.setPortNumber(credentials.getPort()); + myds.setUser(credentials.getUsername()); + myds.setPassword(credentials.getPassword()); + + return myds; + + case POSTGRES: + PGPoolingDataSource pgds = new PGPoolingDataSource(); + + pgds.setServerName(credentials.getHostname()); + pgds.setPortNumber(credentials.getPort()); + pgds.setUser(credentials.getUsername()); + pgds.setPassword(credentials.getPassword()); + pgds.setDatabaseName(credentials.getDatabase()); + + return pgds; + + default: + throw new UnsupportedOperationException(credentials.getDatabaseType() + " not supported yet."); + } + } + return dataSource; + } + + public DatabaseType getDatabaseType() { + return credentials.getDatabaseType(); + } + + public Credentials getCredentials() { + return credentials; + } +} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/DatabaseType.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DatabaseType.java similarity index 96% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/DatabaseType.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DatabaseType.java index cbf2cc51659e20e7e5545a14cebe1a41901a8c5b..9a21e6941f7b1458144287a58295cedfbf4f60a5 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/contract/DatabaseType.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DatabaseType.java @@ -20,7 +20,7 @@ * 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.contract; +package it.inaf.ia2.tsm.datalayer; /** * This enum lists the supported RDBMS. 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 new file mode 100644 index 0000000000000000000000000000000000000000..99a26ad7cf6191ad56c72b0626d3fdc1ec8d2f14 --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/mysql/MySQLDBBroker.java @@ -0,0 +1,290 @@ +/* + * _____________________________________________________________________________ + * + * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of + * Trieste INAF - IA2 Italian Center for Astronomical Archives + * _____________________________________________________________________________ + * + * Copyright (C) 2017 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.datalayer.mysql; + +import it.inaf.ia2.tsm.Column; +import it.inaf.ia2.tsm.KeyMetadata; +import it.inaf.ia2.tsm.datalayer.ADQL; +import it.inaf.ia2.tsm.datalayer.DBBrokerTemplate; +import it.inaf.ia2.tsm.xmlmodel.PropertyModel; +import it.inaf.ia2.tsm.xmlmodel.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 javax.sql.DataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} + */ +public class MySQLDBBroker extends DBBrokerTemplate { + + private static final Logger LOG = LoggerFactory.getLogger(MySQLDBBroker.class); + + public MySQLDBBroker(DataSource dataSource) { + super(dataSource, '`'); + } + + @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. + } + + @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; + } + + @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; + } + + @Override + public Map<String, Map<String, Object>> getAllColumnsMetadata(String schemaName, String tableName) throws SQLException { + + Map<String, Map<String, Object>> allColumnsMetadata = new HashMap<>(); + + String query = String.format("SHOW COLUMNS FROM %s.%s", escape(schemaName), escape(tableName)); + + LOG.debug("Executing query {}", query); + + try (Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(query)) { + + while (resultSet.next()) { + + Map<String, Object> cm = new HashMap<>(); + + // Column name + String columnName = resultSet.getString("Field"); + cm.put(Column.COLUMN_NAME_KEY, columnName); + + // Key info + String keyType = resultSet.getString("Key"); + if ("PRI".equals(keyType)) { + cm.put(Column.PRIMARY_KEY, true); + } + if ("PRI".equals(keyType) || "UNI".equals(keyType) || "MUL".equals(keyType)) { + cm.put(Column.INDEXED_KEY, true); + } + + // Datatype and Size + String type = resultSet.getString("Type").toLowerCase(); + String datatype; + Integer size = null; + + 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.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 + protected void createTable(String tapSchemaName, TableModel tableModel, Connection conn) throws SQLException { + + StringBuilder querySb = new StringBuilder(); + + querySb.append("CREATE TABLE IF NOT EXISTS "); + querySb.append(escape(tapSchemaName)); + querySb.append("."); + querySb.append(escape(tableModel.getName())); + querySb.append(" (\n"); + + boolean first = true; + for (PropertyModel pm : tableModel.getProperties().values()) { + if (!first) { + querySb.append(",\n"); + } + first = false; + + querySb.append(pm.getName()); + querySb.append(" "); + + Class type = pm.getType(); + if (type == String.class) { + querySb.append("VARCHAR("); + querySb.append(pm.getSize()); + querySb.append(")"); + } else if (type == Integer.class || type == Boolean.class) { + querySb.append("INTEGER"); + } else if (type == Long.class) { + querySb.append("BIGINT"); + } else { + throw new UnsupportedOperationException("Column type " + type.getCanonicalName() + " not supported yet!"); + } + + 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 + 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); + } + } + + @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), + buildColumnsList(fromKeyColumns), escape(tapSchemaName), escape(targetTableName), buildColumnsList(toKeyColumns)); + try (Statement stat = conn.createStatement()) { + LOG.debug("Executing query: {}", query); + stat.executeUpdate(query); + } + } + + @Override + public List<KeyMetadata> getKeysMetadata(String schemaName) throws SQLException { + StringBuilder sb = new StringBuilder(); + + sb.append("SELECT\n"); + sb.append("c.CONSTRAINT_NAME AS constraint_name,\n"); + sb.append("k.TABLE_SCHEMA AS from_schema,\n"); + sb.append("k.TABLE_NAME AS from_table,\n"); + sb.append("k.COLUMN_NAME AS from_column,\n"); + sb.append("k.REFERENCED_TABLE_SCHEMA AS target_schema,\n"); + sb.append("k.REFERENCED_TABLE_NAME AS target_table,\n"); + sb.append("k.REFERENCED_COLUMN_NAME AS target_column\n"); + sb.append("FROM information_schema.TABLE_CONSTRAINTS c \n"); + sb.append("LEFT JOIN information_schema.KEY_COLUMN_USAGE k \n"); + sb.append("ON c.CONSTRAINT_NAME = k.CONSTRAINT_NAME AND c.TABLE_SCHEMA = k.TABLE_SCHEMA\n"); + sb.append("WHERE c.CONSTRAINT_TYPE = 'FOREIGN KEY' \n"); + sb.append("AND k.TABLE_SCHEMA = '"); + sb.append(schemaName); + sb.append("' OR k.REFERENCED_TABLE_SCHEMA = '"); + sb.append(schemaName); + sb.append("'"); + + String query = sb.toString(); + + LOG.debug("Executing query: {}", query); + + List<KeyMetadata> keysMetadata = new ArrayList<>(); + try (Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(query)) { + + while (resultSet.next()) { + //String constraintName = resultSet.getString("constraint_name"); + + String fromSchemaName = resultSet.getString("from_schema"); + String fromTableName = resultSet.getString("from_table"); + String targetSchemaName = resultSet.getString("target_schema"); + String targetTableName = resultSet.getString("target_table"); + + KeyMetadata km = new KeyMetadata(fromSchemaName, fromTableName, targetSchemaName, targetTableName); + km.addKeyColumn(resultSet.getString("from_column"), resultSet.getString("target_column")); + + keysMetadata.add(km); + } + } + + return keysMetadata; + } + + @Override + protected String getSchemaTablesQuery(String schemaName) { + return "SHOW TABLES FROM " + escape(schemaName); + } + + @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); + } + } + + @Override + protected String getTableTypesQuery(String schemaName) { + return "SELECT table_name, table_type FROM information_schema.tables WHERE table_schema = '" + schemaName + "'"; + } +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..94a41dfcfd58a039b6b85cd9e6110f837bcbbe25 --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/pgsql/PostgresDBBroker.java @@ -0,0 +1,119 @@ +/* + * _____________________________________________________________________________ + * + * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of + * Trieste INAF - IA2 Italian Center for Astronomical Archives + * _____________________________________________________________________________ + * + * Copyright (C) 2017 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.datalayer.pgsql; + +import it.inaf.ia2.tsm.KeyMetadata; +import it.inaf.ia2.tsm.datalayer.DBBrokerTemplate; +import it.inaf.ia2.tsm.xmlmodel.TableModel; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.List; +import java.util.Map; +import javax.sql.DataSource; + +/** + * + * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} + */ +public class PostgresDBBroker extends DBBrokerTemplate { + + public PostgresDBBroker(DataSource dataSource) { + super(dataSource, '\''); + } + + @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. + } + + @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. + } + + @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. + } + + @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. + } + + @Override + protected String getSchemaTablesQuery(String schemaName) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @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. + } + + @Override + public List<String> getAllSchemaNames() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public List<String> getAllTablesNames(String schemaName) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @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. + } + + @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. + } + + @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. + } + + @Override + public List<KeyMetadata> getKeysMetadata(String schemaName) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + protected String getTableTypesQuery(String schemaName) { + StringBuilder sb = new StringBuilder(); + sb.append("SELECT tablename AS table_name, 'table' AS table_type\n"); + sb.append("FROM pg_catalog.pg_tables WHERE schemaname = '"); + sb.append(schemaName); + sb.append("'\n"); + sb.append("UNION\n"); + sb.append("SELECT table_name AS table_name, 'view' AS table_type\n"); + sb.append("FROM INFORMATION_SCHEMA.views\n"); + sb.append("WHERE table_schema = '"); + sb.append(schemaName); + sb.append("'"); + return sb.toString(); + } +} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/PropertyModel.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/PropertyModel.java new file mode 100644 index 0000000000000000000000000000000000000000..ca02f53b51a753093f7b44af9f0c7099dd848c21 --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/PropertyModel.java @@ -0,0 +1,83 @@ +/* + * _____________________________________________________________________________ + * + * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of + * Trieste INAF - IA2 Italian Center for Astronomical Archives + * _____________________________________________________________________________ + * + * Copyright (C) 2017 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.xmlmodel; + +import java.io.Serializable; + +/** + * + * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} + */ +public class PropertyModel implements Serializable { + + private static final long serialVersionUID = -3081516272534689428L; + + private String name; + private Class type; + private Integer size; + private boolean updatable; + private boolean nullable; + private String loaderKey; + + private PropertyModel() { + } + + public PropertyModel(PropertyXMLModel propertyXMLModel) { + try { + name = propertyXMLModel.getName(); + type = Class.forName(propertyXMLModel.getType()); + size = propertyXMLModel.getSize(); + updatable = propertyXMLModel.isUpdatable(); + nullable = propertyXMLModel.isNullable(); + loaderKey = propertyXMLModel.getLoaderKey(); + } catch (ClassNotFoundException e) { + throw new ExceptionInInitializerError( + "Invalid property type for property " + propertyXMLModel.getName() + + ". ClassNotFoundException: " + propertyXMLModel.getType()); + } + } + + public String getName() { + return name; + } + + public Class getType() { + return type; + } + + public Integer getSize() { + return size; + } + + public boolean isUpdatable() { + return updatable; + } + + public boolean isNullable() { + return nullable; + } + + public String getLoaderKey() { + return loaderKey; + } +} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/PropertyXMLModel.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/PropertyXMLModel.java new file mode 100644 index 0000000000000000000000000000000000000000..8558bf706c33d8fead8c498f7285428ab7626e9f --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/PropertyXMLModel.java @@ -0,0 +1,109 @@ +/* + * _____________________________________________________________________________ + * + * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of + * Trieste INAF - IA2 Italian Center for Astronomical Archives + * _____________________________________________________________________________ + * + * Copyright (C) 2017 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.xmlmodel; + +import javax.xml.bind.annotation.XmlElement; + +/** + * + * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} + */ +public class PropertyXMLModel { + + private String name; + private String type; + private Integer size; + private boolean updatable; + private boolean nullable; + private String loaderKey; + private String description; + + public PropertyXMLModel() { + // default values + updatable = true; + nullable = true; + } + + @XmlElement(name = "name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @XmlElement(name = "type") + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + @XmlElement(name = "size") + public Integer getSize() { + return size; + } + + public void setSize(Integer size) { + this.size = size; + } + + @XmlElement(name = "updatable", defaultValue = "true") + public boolean isUpdatable() { + return updatable; + } + + public void setUpdatable(boolean updatable) { + this.updatable = updatable; + } + + @XmlElement(name = "nullable", defaultValue = "true") + public boolean isNullable() { + return nullable; + } + + public void setNullable(boolean nullable) { + this.nullable = nullable; + } + + @XmlElement(name = "key") + public String getLoaderKey() { + return loaderKey; + } + + public void setLoaderKey(String loaderMethod) { + this.loaderKey = loaderMethod; + } + + @XmlElement(name = "description") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TableModel.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TableModel.java new file mode 100644 index 0000000000000000000000000000000000000000..a0583421b47114ff14121ffd6b34a3d5962774e4 --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TableModel.java @@ -0,0 +1,60 @@ +/* + * _____________________________________________________________________________ + * + * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of + * Trieste INAF - IA2 Italian Center for Astronomical Archives + * _____________________________________________________________________________ + * + * Copyright (C) 2017 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.xmlmodel; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * + * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} + */ +public class TableModel implements Serializable { + + private static final long serialVersionUID = 5142593924738484037L; + + private final Map<String, PropertyModel> properties; + private String name; + + private TableModel() { + this.properties = new HashMap<>(); + } + + public TableModel(String name) { + this(); + this.name = name; + } + + public String getName() { + return name; + } + + public Map<String, PropertyModel> getProperties() { + return properties; + } + + public PropertyModel get(String columnName) { + return properties.get(columnName); + } +} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/FixedEntityProperty.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TableXMLModel.java similarity index 53% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/FixedEntityProperty.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TableXMLModel.java index b84bd9203f1b134ccfb6632e74c9d7fe689d1b86..b0118b4d1948cb41a3697dc805a2447b094d4588 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/FixedEntityProperty.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TableXMLModel.java @@ -1,11 +1,11 @@ -/* +/* * _____________________________________________________________________________ * * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of * Trieste INAF - IA2 Italian Center for Astronomical Archives * _____________________________________________________________________________ * - * Copyright (C) 2016 Istituto Nazionale di Astrofisica + * Copyright (C) 2017 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 @@ -20,46 +20,48 @@ * 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.xmlmodel; -import java.io.Serializable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import java.util.List; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; /** - * Represent an {@code EntityProperty} which value can't be modified by the - * user. * * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} */ -public class FixedEntityProperty<T> implements EntityProperty, Serializable { +public class TableXMLModel { - private static final long serialVersionUID = -7009289405382798659L; - private static final Logger log = LoggerFactory.getLogger(EntityPropertyInfo.class); + private String name; + private String description; + private List<PropertyXMLModel> add; - private T value; - private boolean changed; + @XmlAttribute(name = "name") + public String getName() { + return name; + } - public FixedEntityProperty(T value) { - init(value); + public void setName(String name) { + this.name = name; } - @Override - public final <X> void init(X initialValue) { - this.value = (T) initialValue; + @XmlAttribute(name = "description") + public String getDescription() { + return description; } - @Override - public <X> X getValue(Class<X> type) { - return (X) value; + public void setDescription(String description) { + this.description = description; } - @Override - public boolean isChanged() { - return changed; + @XmlElementWrapper(name = "add") + @XmlElement(name = "property") + public List<PropertyXMLModel> getAdd() { + return add; } - public void setChanged(boolean changed) { - this.changed = changed; + public void setAdd(List<PropertyXMLModel> add) { + this.add = add; } } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/TapSchemaFactory.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TapSchemaModel.java similarity index 57% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/TapSchemaFactory.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TapSchemaModel.java index d926b92be473fe3ee05219160cefbe1b15ad6607..7c8ae31aa1c0fc5deb0ca4bc14f0d6f21383f3eb 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/api/TapSchemaFactory.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TapSchemaModel.java @@ -1,11 +1,11 @@ -/* +/* * _____________________________________________________________________________ * * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of * Trieste INAF - IA2 Italian Center for Astronomical Archives * _____________________________________________________________________________ * - * Copyright (C) 2016 Istituto Nazionale di Astrofisica + * Copyright (C) 2017 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 @@ -20,24 +20,41 @@ * 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.xmlmodel; -import it.inaf.ia2.tsm.api.contract.TapSchema; -import it.inaf.ia2.tsm.api.contract.TapSchemaVersion; -import java.sql.SQLException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; /** - * Factory for {@link TapSchema} instances. * * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} */ -public class TapSchemaFactory { +public class TapSchemaModel implements Serializable { - private final static Logger log = LoggerFactory.getLogger(TapSchemaFactory.class); + private static final long serialVersionUID = 1087876778125446000L; - public static TapSchema getTapSchema(TapSchemaVersion version, DBWrapper dbWrapper, String tapSchemaName, boolean exists) throws SQLException { - return new TapSchemaImpl(version, dbWrapper, tapSchemaName, exists); + private final Map<String, TableModel> tables; + private String version; + + private TapSchemaModel() { + tables = new HashMap<>(); + } + + public TapSchemaModel(String version) { + this(); + this.version = version; + } + + public String getVersion() { + return version; + } + + public Map<String, TableModel> getTables() { + return tables; + } + + public TableModel get(String tableName) { + return tables.get(tableName); } } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TapSchemaModels.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TapSchemaModels.java new file mode 100644 index 0000000000000000000000000000000000000000..7ab8dc4315013fdc85b766b4ec8e5e4e06a15f96 --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TapSchemaModels.java @@ -0,0 +1,102 @@ +/* + * _____________________________________________________________________________ + * + * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of + * Trieste INAF - IA2 Italian Center for Astronomical Archives + * _____________________________________________________________________________ + * + * Copyright (C) 2017 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.xmlmodel; + +import java.io.File; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import javax.xml.bind.JAXB; + +/** + * + * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} + */ +public class TapSchemaModels { + + // Map keys are TS versions + private final static Map<String, TapSchemaModel> MODELS; + + private TapSchemaModels() { + } + + static { + + try { + Map<String, TapSchemaXMLModel> xmlModels = getXmlModels(); + + MODELS = new HashMap<>(); + + for (TapSchemaXMLModel xmlModel : xmlModels.values()) { + TapSchemaModel model = new TapSchemaModel(xmlModel.getVersion()); + loadTapSchemaModel(model, xmlModel, xmlModels); + MODELS.put(model.getVersion(), model); + } + } catch (URISyntaxException e) { + throw new ExceptionInInitializerError(e); + } + } + + private static Map<String, TapSchemaXMLModel> getXmlModels() throws URISyntaxException { + Map<String, TapSchemaXMLModel> xmlModels = new HashMap<>(); + File modelsDirectory = new File(TapSchemaModels.class.getClassLoader().getResource("tap_schema").toURI()); + for (File modelFile : modelsDirectory.listFiles()) { + TapSchemaXMLModel model = JAXB.unmarshal(modelFile, TapSchemaXMLModel.class); + xmlModels.put(model.getVersion(), model); + } + return xmlModels; + } + + private static void loadTapSchemaModel(TapSchemaModel model, TapSchemaXMLModel xmlModel, Map<String, TapSchemaXMLModel> xmlModels) { + + for (TableXMLModel tableXmlModel : xmlModel.getTables()) { + String tableName = tableXmlModel.getName(); + TableModel tableModel = model.get(tableName); + if (tableModel == null) { + tableModel = new TableModel(tableName); + } + for (PropertyXMLModel property : tableXmlModel.getAdd()) { + tableModel.getProperties().put(property.getName(), new PropertyModel(property)); + } + model.getTables().put(tableName, tableModel); + } + + if (xmlModel.getExtendsFrom() != null) { + TapSchemaXMLModel parentModel = xmlModels.get(xmlModel.getExtendsFrom()); + loadTapSchemaModel(model, parentModel, xmlModels); + } + } + + public static TapSchemaModel getTapSchemaModel(String version) { + return MODELS.get(version); + } + + public static Iterator<TapSchemaModel> getIterator() { + return MODELS.values().iterator(); + } + + public static TableModel getTableModel(String tableName, String version) { + return getTapSchemaModel(version).getTables().get(tableName); + } +} diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TapSchemaXMLModel.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TapSchemaXMLModel.java new file mode 100644 index 0000000000000000000000000000000000000000..e320d16cb6fad1d1a361535eb975924c92f8d580 --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TapSchemaXMLModel.java @@ -0,0 +1,80 @@ +/* + * _____________________________________________________________________________ + * + * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of + * Trieste INAF - IA2 Italian Center for Astronomical Archives + * _____________________________________________________________________________ + * + * Copyright (C) 2017 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.xmlmodel; + +import java.util.List; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * + * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} + */ +@XmlRootElement(name = "tap_schema") +public class TapSchemaXMLModel { + + private String version; + private String description; + private String extendsFrom; + private List<TableXMLModel> tables; + + @XmlAttribute(name = "version") + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + @XmlAttribute(name = "description") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @XmlAttribute(name = "extends") + public String getExtendsFrom() { + return extendsFrom; + } + + public void setExtendsFrom(String extendsFrom) { + this.extendsFrom = extendsFrom; + } + + @XmlElements({ + @XmlElement(name = "table") + }) + public List<TableXMLModel> getTables() { + return tables; + } + + public void setTables(List<TableXMLModel> tables) { + this.tables = tables; + } +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..70e1638b275326fccd1aaa7afdd392dd0d2ae4a2 --- /dev/null +++ b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1-IA2.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +_____________________________________________________________________________ + +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. +--> +<tap_schema version="1.0-IA2" extends="1.0"> + <table name="schemas"> + <add> + <property> + <name>schemaID</name> + <type>java.lang.Long</type> + <updatable>true</updatable> + </property> + </add> + </table> + <table name="tables"> + <add> + <property> + <name>tableID</name> + <type>java.lang.Long</type> + <updatable>true</updatable> + </property> + </add> + </table> + <table name="columns"> + <add> + <property> + <name>columnID</name> + <type>java.lang.Long</type> + <updatable>true</updatable> + </property> + </add> + </table> + <table name="keys"> + <add> + <property> + <name>keyID</name> + <type>java.lang.Long</type> + <updatable>true</updatable> + </property> + </add> + </table> + <table name="key_columns"> + <add> + <property> + <name>key_columnID</name> + <type>java.lang.Long</type> + <updatable>true</updatable> + </property> + </add> + </table> +</tap_schema> 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 new file mode 100644 index 0000000000000000000000000000000000000000..89adc9c0b7585530e77a2dd0324d0a6702a4d95f --- /dev/null +++ b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml @@ -0,0 +1,254 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +_____________________________________________________________________________ + +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. +--> +<tap_schema version="1.0" description="a special schema to describe a TAP tableset"> + <table name="schemas" description="description of schemas in this tableset"> + <add> + <property> + <name>schema_name</name> + <type>java.lang.String</type> + <size>64</size> + <updatable>false</updatable> + <nullable>false</nullable> + <key>schema_name</key> + <description>schema name for reference to TAP_SCHEMA.schemas</description> + </property> + <property> + <name>utype</name> + <type>java.lang.String</type> + <size>255</size> + <updatable>true</updatable> + <description>lists the utypes of schemas in the tableset</description> + </property> + <property> + <name>description</name> + <type>java.lang.String</type> + <size>255</size> + <updatable>true</updatable> + <description>describes schemas in the tableset</description> + </property> + </add> + </table> + <table name="tables" description="description of tables in this tableset"> + <add> + <property> + <name>schema_name</name> + <type>java.lang.String</type> + <size>64</size> + <updatable>false</updatable> + <nullable>false</nullable> + <key>schema_name</key> + <description>the schema this table belongs to</description> + </property> + <property> + <name>table_name</name> + <type>java.lang.String</type> + <size>128</size> + <updatable>false</updatable> + <nullable>false</nullable> + <key>table_name</key> + <description>the fully qualified table name</description> + </property> + <property> + <name>table_type</name> + <size>8</size> + <type>java.lang.String</type> + <updatable>false</updatable> + <key>table_type</key> + <description>one of: table view</description> + </property> + <property> + <name>utype</name> + <type>java.lang.String</type> + <size>255</size> + <updatable>true</updatable> + <description>lists the utype of tables in the tableset</description> + </property> + <property> + <name>description</name> + <type>java.lang.String</type> + <size>255</size> + <updatable>true</updatable> + <description>describes tables in the tableset</description> + </property> + </add> + </table> + <table name="columns" description="description of columns in this tableset"> + <add> + <property> + <name>table_name</name> + <required>true</required> + <type>java.lang.String</type> + <size>128</size> + <updatable>false</updatable> + <nullable>false</nullable> + <key>table_name</key> + <description>the table this column belongs to</description> + </property> + <property> + <name>column_name</name> + <required>true</required> + <type>java.lang.String</type> + <size>64</size> + <updatable>false</updatable> + <nullable>false</nullable> + <key>column_name</key> + <description>the column name</description> + </property> + <property> + <name>datatype</name> + <type>java.lang.String</type> + <size>64</size> + <updatable>false</updatable> + <key>datatype</key> + <description>lists the ADQL datatype of columns in the tableset</description> + </property> + <property> + <name>size</name> + <type>java.lang.Integer</type> + <updatable>false</updatable> + <key>size</key> + <description>lists the size of variable-length columns in the tableset</description> + </property> + <property> + <name>description</name> + <type>java.lang.String</type> + <size>255</size> + <updatable>true</updatable> + <description>describes the columns in the tableset</description> + </property> + <property> + <name>utype</name> + <type>java.lang.String</type> + <size>255</size> + <updatable>true</updatable> + <description>lists the utypes of columns in the tableset</description> + </property> + <property> + <name>unit</name> + <type>java.lang.String</type> + <size>64</size> + <updatable>true</updatable> + <description>lists the unit used for column values in the tableset</description> + </property> + <property> + <name>ucd</name> + <type>java.lang.String</type> + <size>64</size> + <updatable>true</updatable> + <description>lists the UCDs of columns in the tableset</description> + </property> + <property> + <name>indexed</name> + <type>java.lang.Boolean</type> + <updatable>false</updatable> + <key>indexed</key> + <description>an indexed column; 1 means 1, 0 means 0</description> + </property> + <property> + <name>principal</name> + <type>java.lang.Boolean</type> + <updatable>true</updatable> + <description>a principal column; 1 means 1, 0 means 0</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> + </property> + </add> + </table> + <table name="keys" description="description of foreign keys in this tableset"> + <add> + <property> + <name>key_id</name> + <type>java.lang.String</type> + <size>64</size> + <updatable>true</updatable> + <key>key_id</key> + <nullable>false</nullable> + <description>unique key to join to TAP_SCHEMA.key_columns</description> + </property> + <property> + <name>from_table</name> + <type>java.lang.String</type> + <size>128</size> + <updatable>false</updatable> + <key>from_table</key> + <description>the table with the foreign key</description> + </property> + <property> + <name>target_table</name> + <type>java.lang.String</type> + <size>128</size> + <updatable>false</updatable> + <key>target_table</key> + <description>the table with the primary key</description> + </property> + <property> + <name>description</name> + <type>java.lang.String</type> + <size>255</size> + <updatable>true</updatable> + <description>describes keys in the tableset</description> + </property> + <property> + <name>utype</name> + <type>java.lang.String</type> + <size>255</size> + <updatable>true</updatable> + <description>lists the utype of keys in the tableset</description> + </property> + </add> + </table> + <table name="key_columns" description="description of foreign key columns in this tableset"> + <add> + <property> + <name>key_id</name> + <type>java.lang.String</type> + <size>64</size> + <updatable>true</updatable> + <key>key_id</key> + <nullable>false</nullable> + <description>key to join to TAP_SCHEMA.keys</description> + </property> + <property> + <name>from_column</name> + <type>java.lang.String</type> + <size>64</size> + <updatable>false</updatable> + <key>from_column</key> + <description>column in the from_table</description> + </property> + <property> + <name>target_column</name> + <type>java.lang.String</type> + <size>64</size> + <updatable>false</updatable> + <key>target_column</key> + <description>column in the target_table</description> + </property> + </add> + </table> +</tap_schema> diff --git a/TASMAN-core/src/main/resources/tap_schema/tap_schema-1_1.xml b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..74ae692d6a05b6f14149e2999d11dae029dccb2a --- /dev/null +++ b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1_1.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +_____________________________________________________________________________ + +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. +--> +<tap_schema version="1.1" extends="1.0"> + <table name="tables"> + <add> + <property> + <name>table_index</name> + <type>java.lang.Integer</type> + <updatable>true</updatable> + </property> + </add> + </table> + <table name="columns"> + <add> + <property> + <name>arraysize</name> + <type>java.lang.Integer</type> + <updatable>false</updatable> + <key>arraysize</key> + </property> + <property> + <name>column_index</name> + <type>java.lang.Integer</type> + <updatable>true</updatable> + </property> + </add> + </table> +</tap_schema> 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/api/TestAll.java index 3295f4c08cf36c92aad4289f6618bd1805e8ab29..c85aaf4edf238ebab79b05201de091a55e38fbe2 100644 --- a/TASMAN-core/src/test/java/it/inaf/ia2/tsm/api/TestAll.java +++ b/TASMAN-core/src/test/java/it/inaf/ia2/tsm/api/TestAll.java @@ -22,15 +22,17 @@ */ package it.inaf.ia2.tsm.api; -import it.inaf.ia2.tsm.api.contract.DatabaseType; -import it.inaf.ia2.tsm.api.contract.Column; -import it.inaf.ia2.tsm.api.contract.Key; -import it.inaf.ia2.tsm.api.contract.KeyColumn; -import it.inaf.ia2.tsm.api.contract.Schema; -import it.inaf.ia2.tsm.api.contract.Status; -import it.inaf.ia2.tsm.api.contract.Table; -import it.inaf.ia2.tsm.api.contract.TapSchema; -import it.inaf.ia2.tsm.api.contract.TapSchemaVersion; +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; @@ -233,29 +235,41 @@ public class TestAll { } } - private boolean allKeysHaveDifferentId(TapSchema tapSchema) { - boolean differentKeySameId = false; - Map<String, Key> keys = new HashMap<>(); + @Test + public void test1() throws Exception { - for (Key key : ((TapSchemaImpl) tapSchema).getAllKeys()) { - if (key.getId() != null) { - if (keys.get(key.getId()) != null && !key.equals(keys.get(key.getId()))) { - differentKeySameId = true; - } - keys.put(key.getId(), key); - } - } + setUpTestingDatabases(); - if (differentKeySameId) { - log.debug("Found different keys with the same key_id!"); - for (Key key : ((TapSchemaImpl) tapSchema).getAllKeys()) { - log.debug(key.toString()); - } + for (DBWrapper dbWrapper : dbWrappers) { + TapSchema tapSchema = new TapSchema("1.0", dbWrapper, "test_tap_schema", false); + tapSchema.save(); } - - return !differentKeySameId; } +// +// private boolean allKeysHaveDifferentId(TapSchema tapSchema) { +// boolean differentKeySameId = false; +// Map<String, Key> keys = new HashMap<>(); +// +// for (Key key : ((TapSchema) tapSchema).getAllKeys()) { +// if (key.getId() != null) { +// if (keys.get(key.getId()) != null && !key.equals(keys.get(key.getId()))) { +// differentKeySameId = true; +// } +// keys.put(key.getId(), key); +// } +// } +// +// if (differentKeySameId) { +// log.debug("Found different keys with the same key_id!"); +// for (Key key : ((TapSchema) tapSchema).getAllKeys()) { +// log.debug(key.toString()); +// } +// } +// +// return !differentKeySameId; +// } +// private void checkKey(Key key, String fromTableCompleteName, String[] fromColumns, String targetTableCompleteName, String[] targetColumns, boolean isVisible) { assertEquals(fromTableCompleteName, key.getFromTableCompleteName()); assertEquals(targetTableCompleteName, key.getTargetTableCompleteName()); @@ -284,9 +298,9 @@ public class TestAll { setUpTestingDatabases(); for (DBWrapper dbWrapper : dbWrappers) { - + // Initializing a not existing TAP_SCHEMA - TapSchema tapSchema = TapSchemaFactory.getTapSchema(TapSchemaVersion.TAP_SCHEMA_1_IA2, dbWrapper, "test_tap_schema", false); + TapSchema tapSchema = new TapSchema("1.0", dbWrapper, "test_tap_schema", false); ///////////////////////////////////// // ADDING A SCHEMA // @@ -295,12 +309,11 @@ public class TestAll { Schema sch0 = tapSchema.addChild("sch0"); assertEquals(Status.ADDED_NOT_PERSISTED, sch0.getStatus()); - Set<Key> allKeys = ((TapSchemaImpl) tapSchema).getAllKeys(); - log.debug("ALL keys:"); - for (Key key : allKeys) { - log.debug(key.toString()); - } - +// Set<Key> allKeys = tapSchema.getAllKeys(); +// log.debug("ALL keys:"); +// for (Key key : allKeys) { +// log.debug(key.toString()); +// } // In the testing schemas each numbered table references the id // of the previous table, except for the first table, so there // should be "TABLES_COUNT - 1" keys for the numbered tables. @@ -309,21 +322,20 @@ public class TestAll { // - sch1.table0.sch0table0id -> sch0.table0.id // - sch0.table_y.(idy1, idy2) -> sch0.table_x.(idyx, idx2) // so we check for TABLES_COUNT + 2. - assertEquals(TABLES_COUNT + 2, allKeys.size()); - - // Checking that keys information has been filled correctly. - for (Key schemaKey : allKeys) { - assertFalse(schemaKey.isVisible()); - assertNull(schemaKey.getId()); - assertEquals(schemaKey.getFromTableCompleteName(), schemaKey.getFromSchemaName() + "." + schemaKey.getFromTableSimpleName()); - assertEquals(schemaKey.getTargetTableCompleteName(), schemaKey.getTargetSchemaName() + "." + schemaKey.getTargetTableSimpleName()); - assertTrue(schemaKey.getKeyColumns().size() >= 1); - for (KeyColumn keyColumn : schemaKey.getKeyColumns()) { - assertNotNull(keyColumn.getFromColumn()); - assertNotNull(keyColumn.getTargetColumn()); - } - } - +// assertEquals(TABLES_COUNT + 2, allKeys.size()); +// +// // Checking that keys information has been filled correctly. +// for (Key schemaKey : allKeys) { +// assertFalse(schemaKey.isVisible()); +// assertNull(schemaKey.getId()); +// assertEquals(schemaKey.getFromTableCompleteName(), schemaKey.getFromSchemaName() + "." + schemaKey.getFromTableSimpleName()); +// assertEquals(schemaKey.getTargetTableCompleteName(), schemaKey.getTargetSchemaName() + "." + schemaKey.getTargetTableSimpleName()); +// assertTrue(schemaKey.getKeyColumns().size() >= 1); +// for (KeyColumn keyColumn : schemaKey.getKeyColumns()) { +// assertNotNull(keyColumn.getFromColumn()); +// assertNotNull(keyColumn.getTargetColumn()); +// } +// } ///////////////////////////////////// // ADDING A TABLE // ///////////////////////////////////// @@ -352,34 +364,18 @@ public class TestAll { Table sch0table1 = sch0.addChild("table1"); assertEquals(2, sch0.getChildren().size()); - assertTrue(sch0table0.getVisibleFromKeys().isEmpty()); - assertTrue(sch0table0.getVisibleTargetKeys().isEmpty()); - assertTrue(sch0table1.getVisibleFromKeys().isEmpty()); - assertTrue(sch0table1.getVisibleTargetKeys().isEmpty()); - + assertTrue(tapSchema.getVisibileKeys().isEmpty()); sch0table1.addChild("table0_id"); - // Now sch0table0.getVisibleTargetKeys() and sch0table1.getVisibleFromKeys() - // have to return the same Key object with id = 1 - - assertTrue(sch0table0.getVisibleFromKeys().isEmpty()); - assertEquals(1, sch0table0.getVisibleTargetKeys().size()); - assertEquals(1, sch0table1.getVisibleFromKeys().size()); - assertTrue(sch0table1.getVisibleTargetKeys().isEmpty()); + assertEquals(1, tapSchema.getVisibileKeys()); // Check if key and its columns have been properly initialized - Key sch0table0TargetKey = sch0table0.getVisibleTargetKeys().get(0); - Key sch0table1TargetKey = sch0table1.getVisibleFromKeys().get(0); - checkKey(sch0table0TargetKey, "sch0.table1", "table0_id", "sch0.table0", "id", true); - assertEquals("1", sch0table0TargetKey.getId()); - assertEquals(sch0table0TargetKey, sch0table1TargetKey); + Key k1 = tapSchema.getVisibileKeys().get(0); + checkKey(k1, "sch0.table1", "table0_id", "sch0.table0", "id", true); // Removing sch0.table1 - assertEquals(1, sch0table0.getVisibleTargetKeys().size()); // sch0.table1.table0_id -> sch0.table0.id sch0.removeChild("table1"); assertEquals(1, sch0.getAddedChildren().size()); - assertTrue(sch0table0.getVisibleFromKeys().isEmpty()); - assertTrue(sch0table0.getVisibleTargetKeys().isEmpty()); - assertFalse(sch0table0TargetKey.isVisible()); + assertTrue(tapSchema.getVisibileKeys().isEmpty()); // // CASE 2: Foreign key between two tables in different schemas. @@ -387,8 +383,8 @@ public class TestAll { // // Adding sch1 Schema sch1 = tapSchema.addChild("sch1"); - allKeys = ((TapSchemaImpl) tapSchema).getAllKeys(); - assertEquals(5, allKeys.size()); +// allKeys = ((TapSchema) tapSchema).getAllKeys(); +// assertEquals(5, allKeys.size()); // Adding sch1.table0 Table sch1table0 = sch1.addChild("table0"); @@ -397,113 +393,105 @@ public class TestAll { sch1table0.addChild("sch0table0id"); // sch1.table0.sch0table0id -> sch0.table0.it obtains keyId = "1" sch0table0.addChild("sch1table0id");// sch0.table0.sch1table0id -> sch1.table0.it obtains keyId = "2" - assertEquals(0, sch0table1.getVisibleFromKeys().size()); - assertEquals(1, sch0table0.getVisibleFromKeys().size()); - assertEquals(1, sch0table0.getVisibleTargetKeys().size()); - assertEquals(1, sch1table0.getVisibleFromKeys().size()); - assertEquals(1, sch1table0.getVisibleTargetKeys().size()); - - for (Key key : allKeys) { - if (key.getId() == null) { - assertFalse(key.isVisible()); - } else { - switch (key.getId()) { - case "1": - checkKey(key, "sch0.table1", "table0_id", "sch0.table0", "id", false); - break; - case "2": - checkKey(key, "sch1.table0", "sch0table0id", "sch0.table0", "id", true); - break; - case "3": - checkKey(key, "sch0.table0", "sch1table0id", "sch1.table0", "id", true); - break; - } - } - } - - assertTrue(allKeysHaveDifferentId(tapSchema)); - +// assertEquals(0, sch0table1.getVisibleFromKeys().size()); +// assertEquals(1, sch0table0.getVisibleFromKeys().size()); +// assertEquals(1, sch0table0.getVisibleTargetKeys().size()); +// assertEquals(1, sch1table0.getVisibleFromKeys().size()); +// assertEquals(1, sch1table0.getVisibleTargetKeys().size()); +// for (Key key : allKeys) { +// if (key.getId() == null) { +// assertFalse(key.isVisible()); +// } else { +// switch (key.getId()) { +// case "1": +// checkKey(key, "sch0.table1", "table0_id", "sch0.table0", "id", false); +// break; +// case "2": +// checkKey(key, "sch1.table0", "sch0table0id", "sch0.table0", "id", true); +// break; +// case "3": +// checkKey(key, "sch0.table0", "sch1table0id", "sch1.table0", "id", true); +// break; +// } +// } +// } +// assertTrue(allKeysHaveDifferentId(tapSchema)); // Removing sch1 tapSchema.removeChild("sch1"); assertEquals(Status.REMOVED_NOT_PERSISTED, sch1.getStatus()); - assertTrue(sch0table0.getVisibleTargetKeys().isEmpty()); +// assertTrue(sch0table0.getVisibleTargetKeys().isEmpty()); // Case 2B: Re-adding sch1 // sch1.table0 has not been removed from its schema, so the keys // should be re-added. tapSchema.addChild("sch1"); assertEquals(Status.ADDED_NOT_PERSISTED, sch1.getStatus()); - assertEquals(1, sch0table0.getVisibleTargetKeys().size()); - assertEquals(1, sch1table0.getVisibleFromKeys().size()); - - for (Key key : allKeys) { - if (key.getId() == null) { - assertFalse(key.isVisible()); - } else { - switch (key.getId()) { - case "1": - checkKey(key, "sch0.table1", "table0_id", "sch0.table0", "id", false); - break; - case "2": - checkKey(key, "sch1.table0", "sch0table0id", "sch0.table0", "id", true); - break; - case "3": - checkKey(key, "sch0.table0", "sch1table0id", "sch1.table0", "id", true); - break; - } - } - } - +// assertEquals(1, sch0table0.getVisibleTargetKeys().size()); +// assertEquals(1, sch1table0.getVisibleFromKeys().size()); + +// for (Key key : allKeys) { +// if (key.getId() == null) { +// assertFalse(key.isVisible()); +// } else { +// switch (key.getId()) { +// case "1": +// checkKey(key, "sch0.table1", "table0_id", "sch0.table0", "id", false); +// break; +// case "2": +// checkKey(key, "sch1.table0", "sch0table0id", "sch0.table0", "id", true); +// break; +// case "3": +// checkKey(key, "sch0.table0", "sch1table0id", "sch1.table0", "id", true); +// break; +// } +// } +// } // // CASE 3: foreign key with multiple columns // Table table_x = sch0.addChild("table_x"); Table table_y = sch0.addChild("table_y"); - assertTrue(table_x.getVisibleFromKeys().isEmpty()); - assertTrue(table_x.getVisibleTargetKeys().isEmpty()); - assertTrue(table_y.getVisibleFromKeys().isEmpty()); - assertTrue(table_y.getVisibleTargetKeys().isEmpty()); - +// assertTrue(table_x.getVisibleFromKeys().isEmpty()); +// assertTrue(table_x.getVisibleTargetKeys().isEmpty()); +// assertTrue(table_y.getVisibleFromKeys().isEmpty()); +// assertTrue(table_y.getVisibleTargetKeys().isEmpty()); table_x.addChild("idx1"); table_x.addChild("idx2"); table_y.addChild("idy1"); - assertTrue(table_x.getVisibleFromKeys().isEmpty()); - assertTrue(table_x.getVisibleTargetKeys().isEmpty()); - assertTrue(table_y.getVisibleFromKeys().isEmpty()); - assertTrue(table_y.getVisibleTargetKeys().isEmpty()); - +// assertTrue(table_x.getVisibleFromKeys().isEmpty()); +// assertTrue(table_x.getVisibleTargetKeys().isEmpty()); +// assertTrue(table_y.getVisibleFromKeys().isEmpty()); +// assertTrue(table_y.getVisibleTargetKeys().isEmpty()); table_y.addChild("idy2"); - assertEquals(1, table_y.getVisibleFromKeys().size()); - assertEquals(1, table_x.getVisibleTargetKeys().size()); - assertTrue(table_x.getVisibleFromKeys().isEmpty()); - assertTrue(table_y.getVisibleTargetKeys().isEmpty()); - - for (Key key : allKeys) { - if (key.getId() == null) { - assertFalse(key.isVisible()); - } else { - switch (key.getId()) { - case "1": - checkKey(key, "sch0.table1", "table0_id", "sch0.table0", "id", false); - break; - case "2": - checkKey(key, "sch1.table0", "sch0table0id", "sch0.table0", "id", true); - break; - case "3": - checkKey(key, "sch0.table0", "sch1table0id", "sch1.table0", "id", true); - break; - case "4": - checkKey(key, "sch0.table_y", new String[]{"idy1", "idy2"}, "sch0.table_x", new String[]{"idx1", "idx2"}, true); - break; - } - } - } - - assertTrue(allKeysHaveDifferentId(tapSchema)); - +// assertEquals(1, table_y.getVisibleFromKeys().size()); +// assertEquals(1, table_x.getVisibleTargetKeys().size()); +// assertTrue(table_x.getVisibleFromKeys().isEmpty()); +// assertTrue(table_y.getVisibleTargetKeys().isEmpty()); +// for (Key key : allKeys) { +// if (key.getId() == null) { +// assertFalse(key.isVisible()); +// } else { +// switch (key.getId()) { +// case "1": +// checkKey(key, "sch0.table1", "table0_id", "sch0.table0", "id", false); +// break; +// case "2": +// checkKey(key, "sch1.table0", "sch0table0id", "sch0.table0", "id", true); +// break; +// case "3": +// checkKey(key, "sch0.table0", "sch1table0id", "sch1.table0", "id", true); +// break; +// case "4": +// checkKey(key, "sch0.table_y", new String[]{"idy1", "idy2"}, "sch0.table_x", new String[]{"idx1", "idx2"}, true); +// break; +// } +// } +// } +// +// assertTrue(allKeysHaveDifferentId(tapSchema)); ///////////////////////////////////// // SAVE // ///////////////////////////////////// @@ -512,31 +500,30 @@ public class TestAll { Table sch0table2 = sch0.addChild("table2"); sch0table2.addChild("table1_id"); - for (Key key : allKeys) { - if (key.getId() == null) { - assertFalse(key.isVisible()); - } else { - switch (key.getId()) { - case "1": - checkKey(key, "sch0.table1", "table0_id", "sch0.table0", "id", true); - break; - case "2": - checkKey(key, "sch1.table0", "sch0table0id", "sch0.table0", "id", true); - break; - case "3": - checkKey(key, "sch0.table0", "sch1table0id", "sch1.table0", "id", true); - break; - case "4": - checkKey(key, "sch0.table_y", new String[]{"idy1", "idy2"}, "sch0.table_x", new String[]{"idx1", "idx2"}, true); - break; - case "5": - checkKey(key, "sch0.table2", "table1_id", "sch0.table1", "id", true); - break; - } - } - } - assertTrue(allKeysHaveDifferentId(tapSchema)); - +// for (Key key : allKeys) { +// if (key.getId() == null) { +// assertFalse(key.isVisible()); +// } else { +// switch (key.getId()) { +// case "1": +// checkKey(key, "sch0.table1", "table0_id", "sch0.table0", "id", true); +// break; +// case "2": +// checkKey(key, "sch1.table0", "sch0table0id", "sch0.table0", "id", true); +// break; +// case "3": +// checkKey(key, "sch0.table0", "sch1table0id", "sch1.table0", "id", true); +// break; +// case "4": +// checkKey(key, "sch0.table_y", new String[]{"idy1", "idy2"}, "sch0.table_x", new String[]{"idx1", "idx2"}, true); +// break; +// case "5": +// checkKey(key, "sch0.table2", "table1_id", "sch0.table1", "id", true); +// break; +// } +// } +// } +// assertTrue(allKeysHaveDifferentId(tapSchema)); UpdateOperations operations = new UpdateOperations(tapSchema); assertEquals(2, operations.getSchemasToAdd().size()); assertEquals(6, operations.getTablesToAdd().size()); @@ -545,13 +532,13 @@ public class TestAll { tapSchema.save(); assertFalse(new UpdateOperations(tapSchema).getHasOperations()); - assertTrue(allKeysHaveDifferentId(tapSchema)); +// assertTrue(allKeysHaveDifferentId(tapSchema)); // reloading log.debug("----- Reloading saved TAP_SCHEMA -----"); - tapSchema = TapSchemaFactory.getTapSchema(TapSchemaVersion.TAP_SCHEMA_1_IA2, dbWrapper, "test_tap_schema", true); - allKeys = ((TapSchemaImpl) tapSchema).getAllKeys(); - assertTrue(allKeysHaveDifferentId(tapSchema)); +// tapSchema = TapSchemaFactory.getTapSchema(TapSchemaVersion.TAP_SCHEMA_1_IA2, dbWrapper, "test_tap_schema", true); +// allKeys = ((TapSchema) tapSchema).getAllKeys(); +// assertTrue(allKeysHaveDifferentId(tapSchema)); log.debug(tapSchema.toString()); assertNotNull(sch0 = tapSchema.getChild("sch0", Status.ADDED_PERSISTED)); @@ -574,48 +561,47 @@ public class TestAll { assertNotNull(sch1table0.getChild("id", Status.ADDED_PERSISTED)); assertNotNull(sch1table0.getChild("sch0table0id", Status.ADDED_PERSISTED)); - for (Key key : allKeys) { - if (key.getId() == null) { - assertFalse(key.isVisible()); - } else { - switch (key.getId()) { - case "1": - checkKey(key, "sch0.table1", "table0_id", "sch0.table0", "id", true); - break; - case "2": - checkKey(key, "sch1.table0", "sch0table0id", "sch0.table0", "id", true); - break; - case "3": - checkKey(key, "sch0.table0", "sch1table0id", "sch1.table0", "id", true); - break; - case "4": - checkKey(key, "sch0.table_y", new String[]{"idy1", "idy2"}, "sch0.table_x", new String[]{"idx1", "idx2"}, true); - break; - case "5": - checkKey(key, "sch0.table2", "table1_id", "sch0.table1", "id", true); - break; - } - } - } - - List<Key> sch0table1FromKeys = sch0table1.getVisibleFromKeys(); - assertEquals(1, sch0table1FromKeys.size()); - assertEquals(1, sch0table1.getVisibleTargetKeys().size()); - +// for (Key key : allKeys) { +// if (key.getId() == null) { +// assertFalse(key.isVisible()); +// } else { +// switch (key.getId()) { +// case "1": +// checkKey(key, "sch0.table1", "table0_id", "sch0.table0", "id", true); +// break; +// case "2": +// checkKey(key, "sch1.table0", "sch0table0id", "sch0.table0", "id", true); +// break; +// case "3": +// checkKey(key, "sch0.table0", "sch1table0id", "sch1.table0", "id", true); +// break; +// case "4": +// checkKey(key, "sch0.table_y", new String[]{"idy1", "idy2"}, "sch0.table_x", new String[]{"idx1", "idx2"}, true); +// break; +// case "5": +// checkKey(key, "sch0.table2", "table1_id", "sch0.table1", "id", true); +// break; +// } +// } +// } +// List<Key> sch0table1FromKeys = sch0table1.getVisibleFromKeys(); +// assertEquals(1, sch0table1FromKeys.size()); +// assertEquals(1, sch0table1.getVisibleTargetKeys().size()); +// sch0.removeChild("table1"); - assertEquals(0, sch0table1.getVisibleFromKeys().size()); - - for (Key key : allKeys) { - if (key.getId() == null) { - assertFalse(key.isVisible()); - } else { - switch (key.getId()) { - case "1": - checkKey(key, "sch0.table1", "table0_id", "sch0.table0", "id", false); - break; - } - } - } +// assertEquals(0, sch0table1.getVisibleFromKeys().size()); +// +// for (Key key : allKeys) { +// if (key.getId() == null) { +// assertFalse(key.isVisible()); +// } else { +// switch (key.getId()) { +// case "1": +// checkKey(key, "sch0.table1", "table0_id", "sch0.table0", "id", false); +// break; +// } +// } +// } operations = new UpdateOperations(tapSchema); assertFalse(operations.getHasEntitiesToUpdate()); @@ -631,8 +617,8 @@ public class TestAll { // reloading log.debug("----- Reloading saved TAP_SCHEMA -----"); - tapSchema = TapSchemaFactory.getTapSchema(TapSchemaVersion.TAP_SCHEMA_1_IA2, dbWrapper, "test_tap_schema", true); - allKeys = ((TapSchemaImpl) tapSchema).getAllKeys(); + tapSchema = new TapSchema("1.0", dbWrapper, "test_tap_schema", false); +// allKeys = ((TapSchema) tapSchema).getAllKeys(); log.debug(tapSchema.toString()); assertNotNull(sch0 = tapSchema.getChild("sch0", Status.ADDED_PERSISTED)); @@ -652,51 +638,48 @@ public class TestAll { assertNotNull(sch1table0.getChild("id", Status.ADDED_PERSISTED)); assertNotNull(sch1table0.getChild("sch0table0id", Status.ADDED_PERSISTED)); - for (Key key : allKeys) { - if (key.getId() == null) { - assertFalse(key.isVisible()); - } else { - assertNotNull(key.getOriginalValue(Key.ID_KEY, String.class)); // for reloaded keys - switch (key.getId()) { - case "2": - checkKey(key, "sch1.table0", "sch0table0id", "sch0.table0", "id", true); - break; - case "3": - checkKey(key, "sch0.table0", "sch1table0id", "sch1.table0", "id", true); - break; - case "4": - checkKey(key, "sch0.table_y", new String[]{"idy1", "idy2"}, "sch0.table_x", new String[]{"idx1", "idx2"}, true); - break; - case "5": - checkKey(key, "sch0.table2", "table1_id", "sch0.table1", "id", true); - break; - } - } - } - +// for (Key key : allKeys) { +// if (key.getId() == null) { +// assertFalse(key.isVisible()); +// } else { +// assertNotNull(key.getOriginalValue(Key.ID_KEY, String.class)); // for reloaded keys +// switch (key.getId()) { +// case "2": +// checkKey(key, "sch1.table0", "sch0table0id", "sch0.table0", "id", true); +// break; +// case "3": +// checkKey(key, "sch0.table0", "sch1table0id", "sch1.table0", "id", true); +// break; +// case "4": +// checkKey(key, "sch0.table_y", new String[]{"idy1", "idy2"}, "sch0.table_x", new String[]{"idx1", "idx2"}, true); +// break; +// case "5": +// checkKey(key, "sch0.table2", "table1_id", "sch0.table1", "id", true); +// break; +// } +// } +// } // Test adding ficitious key - sch0table0.addChild("value1"); - sch0table2.addChild("value1"); - ((TapSchemaImpl) tapSchema).addFictitiousKey(sch0table2, new String[]{"value1"}, sch0table0, new String[]{"value1"}); - operations = new UpdateOperations(tapSchema); - assertEquals(1, operations.getKeysToAdd().size()); - tapSchema.save(); - - tapSchema = TapSchemaFactory.getTapSchema(TapSchemaVersion.TAP_SCHEMA_1_IA2, dbWrapper, "test_tap_schema", true); - - sch0table2 = tapSchema.getChild("sch0").getChild("table2"); - assertEquals(1, sch0table2.getVisibleFromKeys().size()); - checkKey(sch0table2.getVisibleFromKeys().get(0), "sch0.table2", "value1", "sch0.table0", "value1", true); - - tapSchema.removeChild("sch1"); - assertEquals(1, tapSchema.getChildren(Status.TO_REMOVE).size()); - tapSchema.save(); - assertEquals(0, tapSchema.getChildren(Status.TO_REMOVE).size()); - +// sch0table0.addChild("value1"); +// sch0table2.addChild("value1"); +// ((TapSchema) tapSchema).addFictitiousKey(sch0table2, new String[]{"value1"}, sch0table0, new String[]{"value1"}); +// operations = new UpdateOperations(tapSchema); +// assertEquals(1, operations.getKeysToAdd().size()); +// tapSchema.save(); +// +// tapSchema = TapSchemaFactory.getTapSchema(TapSchemaVersion.TAP_SCHEMA_1_IA2, dbWrapper, "test_tap_schema", true); +// +// sch0table2 = tapSchema.getChild("sch0").getChild("table2"); +// assertEquals(1, sch0table2.getVisibleFromKeys().size()); +// checkKey(sch0table2.getVisibleFromKeys().get(0), "sch0.table2", "value1", "sch0.table0", "value1", true); +// +// tapSchema.removeChild("sch1"); +// assertEquals(1, tapSchema.getChildren(Status.TO_REMOVE).size()); +// tapSchema.save(); +// assertEquals(0, tapSchema.getChildren(Status.TO_REMOVE).size()); ///////////////////////////////////// // CONSISTENCY CHECKS // ///////////////////////////////////// - } } catch (SQLException e) { throw e; @@ -709,7 +692,7 @@ public class TestAll { public void testTapSchemaSerialization() throws Exception { for (DBWrapper dbWrapper : dbWrappers) { if (dbWrapper.getTapSchemaDatabaseType() == DatabaseType.MYSQL) { // currently "tng_TAP_SCHEMA" exists in a MySQL instance - TapSchema tapSchema = TapSchemaFactory.getTapSchema(TapSchemaVersion.TAP_SCHEMA_1_IA2, dbWrapper, "test_tap_schema", true); + TapSchema tapSchema = new TapSchema("1.0", dbWrapper, "test_tap_schema", true); File temp = File.createTempFile("test_tap_schema", ".ser"); diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/ConsistencyChecksBean.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/ConsistencyChecksBean.java index da1d551dfa6297b57c4e93ffcbf0ad9eb3536139..abf6235ed6b462e347aee700dc6821ee6e8157ea 100644 --- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/ConsistencyChecksBean.java +++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/ConsistencyChecksBean.java @@ -22,7 +22,7 @@ */ package it.inaf.ia2.tsm.webapp; -import it.inaf.ia2.tsm.api.DBWrapper; +import it.inaf.ia2.tsm.datalayer.DBWrapper; import it.inaf.ia2.tsm.api.contract.TapSchema; import java.io.Serializable; import java.sql.SQLException; diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/CredentialsEditing.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/CredentialsEditing.java index 96f374ff9501fb0839f3001e75f1abb82e27e7d4..282015300807286f5213d187078afa5db9d2a661 100644 --- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/CredentialsEditing.java +++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/CredentialsEditing.java @@ -22,8 +22,8 @@ */ package it.inaf.ia2.tsm.webapp; -import it.inaf.ia2.tsm.api.Credentials; -import it.inaf.ia2.tsm.api.DBWrapper; +import it.inaf.ia2.tsm.datalayer.Credentials; +import it.inaf.ia2.tsm.datalayer.DBWrapper; import java.io.IOException; import java.io.Serializable; import java.sql.SQLException; 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 aa6b84174e7234478e9e7386ab8b4a76f6d65ce4..75d09874d10c4e313c9715bbb58e0ef639bd5a63 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 @@ -24,10 +24,10 @@ package it.inaf.ia2.tsm.webapp; import it.inaf.ia2.tsm.api.contract.TapSchema; import it.inaf.ia2.tsm.api.contract.TapSchemaVersion; -import it.inaf.ia2.tsm.api.DBWrapper; -import it.inaf.ia2.tsm.api.Dao; -import it.inaf.ia2.tsm.api.DaoSchema; -import it.inaf.ia2.tsm.api.TapSchemaFactory; +import it.inaf.ia2.tsm.datalayer.DBWrapper; +import it.inaf.ia2.tsm.Dao; +import it.inaf.ia2.tsm.DaoSchema; +import it.inaf.ia2.tsm.TapSchemaFactory; import java.io.Serializable; import java.sql.SQLException; import java.util.ArrayList; diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SeparateCredentials.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SeparateCredentials.java index 16675f476af21caf89772aebb0875dd38e6b3150..f3c072c55822c9217052a05e33b2429b1c13468e 100644 --- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SeparateCredentials.java +++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SeparateCredentials.java @@ -22,7 +22,7 @@ */ package it.inaf.ia2.tsm.webapp; -import it.inaf.ia2.tsm.api.Credentials; +import it.inaf.ia2.tsm.datalayer.Credentials; import java.io.Serializable; import javax.xml.bind.annotation.XmlElement; 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 a61ddc719d55994b95654be69424ce88480a0b0e..5a8c7844e45748e7e9f5af6ad07e5afdc4f5aaeb 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 @@ -26,15 +26,15 @@ import it.inaf.ia2.tsm.webapp.env.CustomPartialResponseWriter; import it.inaf.ia2.tsm.webapp.env.JSUpdateHandler; import it.inaf.ia2.tsm.api.contract.ChildEntity; import it.inaf.ia2.tsm.api.contract.Column; -import it.inaf.ia2.tsm.api.contract.EntitiesContainer; +import it.inaf.ia2.tsm.EntitiesContainer; import it.inaf.ia2.tsm.api.contract.Key; import it.inaf.ia2.tsm.api.contract.KeyColumn; import it.inaf.ia2.tsm.api.contract.Schema; -import it.inaf.ia2.tsm.api.contract.Status; +import it.inaf.ia2.tsm.Status; import it.inaf.ia2.tsm.api.contract.Table; import it.inaf.ia2.tsm.api.contract.TapSchema; -import it.inaf.ia2.tsm.api.contract.TapSchemaEntity; -import it.inaf.ia2.tsm.api.UpdateOperations; +import it.inaf.ia2.tsm.TapSchemaEntity; +import it.inaf.ia2.tsm.UpdateOperations; import java.io.Serializable; import java.sql.SQLException; import java.util.ArrayList; diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/xmlconfig/UserConfiguration.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/xmlconfig/UserConfiguration.java index 6300479c59789894624cb8208d95a38297ac9d7c..b7e7592c317fad11e9d63772b2e3c44a50162ca2 100644 --- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/xmlconfig/UserConfiguration.java +++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/xmlconfig/UserConfiguration.java @@ -22,7 +22,7 @@ */ package it.inaf.ia2.tsm.webapp.xmlconfig; -import it.inaf.ia2.tsm.api.Credentials; +import it.inaf.ia2.tsm.datalayer.Credentials; import it.inaf.ia2.tsm.webapp.SeparateCredentials; import java.io.Serializable; import java.util.ArrayList; diff --git a/TASMAN-webapp/src/test/java/TapSchemaMangerTest.java b/TASMAN-webapp/src/test/java/TapSchemaMangerTest.java index 3b754d72be2668b4eb633543100c996c8092bea1..a96059736392611cda45ee53160cdf13e37ff429 100644 --- a/TASMAN-webapp/src/test/java/TapSchemaMangerTest.java +++ b/TASMAN-webapp/src/test/java/TapSchemaMangerTest.java @@ -21,7 +21,7 @@ * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import it.inaf.ia2.tsm.webapp.SeparateCredentials; -import it.inaf.ia2.tsm.api.Credentials; +import it.inaf.ia2.tsm.datalayer.Credentials; import it.inaf.ia2.tsm.webapp.xmlconfig.UserConfiguration; import java.io.StringReader; import java.io.StringWriter;