From 8c18e736e95d2b5976ce42fc56889bbb701a428e Mon Sep 17 00:00:00 2001 From: Sonia Zorba <zorba@oats.inaf.it> Date: Fri, 21 Apr 2017 16:07:17 +0200 Subject: [PATCH] Big refactoring in order to allow multiple TAP versions (2) --- TASMAN-core/pom.xml | 2 +- .../java/it/inaf/ia2/tsm/ChildEntity.java | 2 +- .../src/main/java/it/inaf/ia2/tsm/Column.java | 21 +- .../it/inaf/ia2/tsm/ConsistencyChecks.java | 18 +- .../java/it/inaf/ia2/tsm/EntityProperty.java | 6 +- .../src/main/java/it/inaf/ia2/tsm/Key.java | 41 +- .../main/java/it/inaf/ia2/tsm/KeyColumn.java | 5 +- .../java/it/inaf/ia2/tsm/KeyMetadata.java | 162 ------ .../src/main/java/it/inaf/ia2/tsm/Schema.java | 2 - .../main/java/it/inaf/ia2/tsm/TSMUtil.java | 63 --- .../src/main/java/it/inaf/ia2/tsm/Table.java | 1 - .../main/java/it/inaf/ia2/tsm/TapSchema.java | 374 +++++++------- .../java/it/inaf/ia2/tsm/TapSchemaEntity.java | 23 +- .../it/inaf/ia2/tsm/UpdateOperations.java | 25 +- .../it/inaf/ia2/tsm/datalayer/DBBroker.java | 11 +- .../ia2/tsm/datalayer/DBBrokerTemplate.java | 48 +- .../tsm/datalayer/mysql/MySQLDBBroker.java | 49 +- .../tsm/datalayer/pgsql/PostgresDBBroker.java | 7 +- .../{xmlmodel => model}/PropertyModel.java | 8 +- .../{xmlmodel => model}/PropertyXMLModel.java | 2 +- .../tsm/{xmlmodel => model}/TableModel.java | 10 +- .../{xmlmodel => model}/TableXMLModel.java | 2 +- .../{xmlmodel => model}/TapSchemaModel.java | 10 +- .../{xmlmodel => model}/TapSchemaModels.java | 23 +- .../TapSchemaXMLModel.java | 2 +- .../java/it/inaf/ia2/tsm/model/Tasman.java | 55 +++ .../src/main/resources/core.properties | 9 + .../resources/tap_schema/tap_schema-1.xml | 4 - .../java/it/inaf/ia2/tsm/api/TestAll.java | 463 +++++++----------- TASMAN-webapp/pom.xml | 4 +- .../ia2/tsm/webapp/ConsistencyChecksBean.java | 2 +- .../ia2/tsm/webapp/SchemaSelectionBean.java | 29 +- .../ia2/tsm/webapp/TapSchemaEditingBean.java | 22 +- .../src/main/webapp/tapSchemaEditing.xhtml | 24 +- 34 files changed, 701 insertions(+), 828 deletions(-) delete mode 100644 TASMAN-core/src/main/java/it/inaf/ia2/tsm/KeyMetadata.java rename TASMAN-core/src/main/java/it/inaf/ia2/tsm/{xmlmodel => model}/PropertyModel.java (92%) rename TASMAN-core/src/main/java/it/inaf/ia2/tsm/{xmlmodel => model}/PropertyXMLModel.java (98%) rename TASMAN-core/src/main/java/it/inaf/ia2/tsm/{xmlmodel => model}/TableModel.java (88%) rename TASMAN-core/src/main/java/it/inaf/ia2/tsm/{xmlmodel => model}/TableXMLModel.java (98%) rename TASMAN-core/src/main/java/it/inaf/ia2/tsm/{xmlmodel => model}/TapSchemaModel.java (87%) rename TASMAN-core/src/main/java/it/inaf/ia2/tsm/{xmlmodel => model}/TapSchemaModels.java (84%) rename TASMAN-core/src/main/java/it/inaf/ia2/tsm/{xmlmodel => model}/TapSchemaXMLModel.java (98%) create mode 100644 TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/Tasman.java create mode 100644 TASMAN-core/src/main/resources/core.properties diff --git a/TASMAN-core/pom.xml b/TASMAN-core/pom.xml index 9e6f3fa..cec38d2 100644 --- a/TASMAN-core/pom.xml +++ b/TASMAN-core/pom.xml @@ -3,7 +3,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>it.inaf.ia2.tap</groupId> <artifactId>tasman-core</artifactId> - <version>1.1.0</version> + <version>1.2.0</version> <packaging>jar</packaging> <name>tasman-core</name> <properties> diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ChildEntity.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ChildEntity.java index e6e9e5d..7ff7479 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ChildEntity.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ChildEntity.java @@ -22,7 +22,7 @@ */ package it.inaf.ia2.tsm; -import it.inaf.ia2.tsm.xmlmodel.TableModel; +import it.inaf.ia2.tsm.model.TableModel; import java.util.Map; /** diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Column.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Column.java index aae711c..6e30960 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Column.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Column.java @@ -43,7 +43,7 @@ public class Column extends ChildEntity<Table> { private static final Logger LOG = LoggerFactory.getLogger(Column.class); private boolean foreignKeySearched; - private KeyMetadata foreignKey; + private Key foreignKey; private Table parentTable; @@ -58,9 +58,24 @@ public class Column extends ChildEntity<Table> { setStatus(Status.LOADED); } - public KeyMetadata getForeignKey() { + public Key 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()); + + String fromSchemaName = parentTable.getParent().getName(); + String fromTableName = parentTable.getName(); + String fromColumnName = getName(); + + ext: + for (Key key : tapSchema.getAllKeys()) { + if (key.getFromSchemaName().equals(fromSchemaName) && key.getFromTableSimpleName().equals(fromTableName)) { + for (KeyColumn keyColumn : key.getKeyColumns()) { + if (keyColumn.getFromColumn().equals(fromColumnName)) { + foreignKey = key; + break ext; + } + } + } + } } return foreignKey; diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ConsistencyChecks.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ConsistencyChecks.java index 1b9f6d6..d1e9d27 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ConsistencyChecks.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ConsistencyChecks.java @@ -74,18 +74,18 @@ public class ConsistencyChecks implements Serializable { } private final List<InconsistentValue> inconsistencies; - private final List<String> unexisingSchemas; - private final List<String> unexisingTables; + private final Set<String> unexisingSchemas; + private final Set<String> unexisingTables; private final Map<String, String> unexisingColumns; - private final List<String> unexistingKeys; + private final Set<String> unexistingKeys; private final List<UnexistingKeyColumn> unexistingKeyColumns; public ConsistencyChecks() { inconsistencies = new ArrayList<>(); - unexisingSchemas = new ArrayList<>(); - unexisingTables = new ArrayList<>(); + unexisingSchemas = new HashSet<>(); + unexisingTables = new HashSet<>(); unexisingColumns = new HashMap<>(); - unexistingKeys = new ArrayList<>(); + unexistingKeys = new HashSet<>(); unexistingKeyColumns = new ArrayList<>(); } @@ -97,7 +97,7 @@ public class ConsistencyChecks implements Serializable { return inconsistencies; } - public List<String> getUnexisingSchemas() { + public Set<String> getUnexisingSchemas() { return unexisingSchemas; } @@ -105,7 +105,7 @@ public class ConsistencyChecks implements Serializable { unexisingSchemas.add(schemaName); } - public List<String> getUnexisingTables() { + public Set<String> getUnexisingTables() { return unexisingTables; } @@ -128,7 +128,7 @@ public class ConsistencyChecks implements Serializable { unexistingKeys.add(keyId); } - public List<String> getUnexistingKeys() { + public Set<String> getUnexistingKeys() { return unexistingKeys; } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntityProperty.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntityProperty.java index ec37b22..5074420 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntityProperty.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntityProperty.java @@ -22,7 +22,7 @@ */ package it.inaf.ia2.tsm; -import it.inaf.ia2.tsm.xmlmodel.PropertyModel; +import it.inaf.ia2.tsm.model.PropertyModel; import java.io.Serializable; /** @@ -111,4 +111,8 @@ public class EntityProperty<T> implements Serializable { public void save() { this.originalValue = value; } + + public Class getType() { + return type; + } } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Key.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Key.java index dfbe3a1..b16933c 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Key.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Key.java @@ -25,8 +25,11 @@ package it.inaf.ia2.tsm; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.regex.Pattern; /** * The main implementation of {@link Key}. @@ -41,25 +44,31 @@ public class Key extends TapSchemaEntity implements Serializable { private static final long serialVersionUID = -8783695875831579336L; - private KeyMetadata keyMetadata; private List<KeyColumn> keyColumns; - private boolean visible; + private String fromSchema; + private String fromTable; + private String targetSchema; + private String targetTable; + private Key() { super(); } - public Key(TapSchema tapSchema, KeyMetadata keyMetadata) { - super(tapSchema, tapSchema.getTableModel(TapSchema.KEYS_TABLE), keyMetadata.getKeyMetadata()); + public Key(TapSchema tapSchema, Map<String, Object> metadata) { + super(tapSchema, tapSchema.getTableModel(TapSchema.KEYS_TABLE), metadata); - this.keyMetadata = keyMetadata; keyColumns = new ArrayList<>(); visible = false; - } - public KeyMetadata getKeyMetadata() { - return keyMetadata; + String[] fromSplit = ((String) metadata.get(FROM_TABLE_KEY)).split(Pattern.quote(".")); + String[] targetSplit = ((String) metadata.get(TARGET_TABLE_KEY)).split(Pattern.quote(".")); + + fromSchema = fromSplit[0]; + fromTable = fromSplit[1]; + targetSchema = targetSplit[0]; + targetTable = targetSplit[1]; } public boolean isVisible() { @@ -86,11 +95,11 @@ public class Key extends TapSchemaEntity implements Serializable { } public String getFromSchemaName() { - return keyMetadata.getFromSchema(); + return fromSchema; } public String getFromTableSimpleName() { - return keyMetadata.getFromTable(); + return fromTable; } public String getFromTableCompleteName() { @@ -98,11 +107,11 @@ public class Key extends TapSchemaEntity implements Serializable { } public String getTargetSchemaName() { - return keyMetadata.getTargetSchema(); + return targetSchema; } public String getTargetTableSimpleName() { - return keyMetadata.getTargetTable(); + return targetTable; } public String getTargetTableCompleteName() { @@ -110,13 +119,19 @@ public class Key extends TapSchemaEntity implements Serializable { } public KeyColumn addKeyColumn(String fromColumn, String targetColumn) { - KeyColumn keyColumn = new KeyColumn(tapSchema, this, fromColumn, targetColumn); + Map<String, Object> keyColumnMetadata = new HashMap<>(); + keyColumnMetadata.put(KeyColumn.FROM_COLUMN_KEY, fromColumn); + keyColumnMetadata.put(KeyColumn.TARGET_COLUMN_KEY, targetColumn); + KeyColumn keyColumn = new KeyColumn(tapSchema, this, keyColumnMetadata); keyColumns.add(keyColumn); return keyColumn; } @Override public void save() { + if (!isVisible()) { + initProperty(ID_KEY, null); + } super.save(); for (KeyColumn keyColumn : keyColumns) { keyColumn.save(); diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/KeyColumn.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/KeyColumn.java index b7aeb11..af97007 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/KeyColumn.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/KeyColumn.java @@ -22,6 +22,7 @@ */ package it.inaf.ia2.tsm; +import java.util.Map; import java.util.Objects; /** @@ -44,8 +45,8 @@ public class KeyColumn extends TapSchemaEntity { super(); } - protected KeyColumn(TapSchema tapSchema, Key key, String fromColumn, String targetColumn) { - super(tapSchema, tapSchema.getTableModel(TapSchema.KEY_COLUMNS_TABLE), key.getKeyMetadata().getKeyColumnMetadata(fromColumn, targetColumn)); + protected KeyColumn(TapSchema tapSchema, Key key, Map<String, Object> keyColumnMetadata) { + super(tapSchema, tapSchema.getTableModel(TapSchema.KEY_COLUMNS_TABLE), keyColumnMetadata); this.key = key; } 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 deleted file mode 100644 index 02b9371..0000000 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/KeyMetadata.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * _____________________________________________________________________________ - * - * 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/Schema.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Schema.java index fe02380..ad3df64 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Schema.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Schema.java @@ -88,8 +88,6 @@ public class Schema extends ChildEntity<TapSchema> implements EntitiesContainer< 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?"); - tapSchema.getConsistencyChecks().addUnexistingTable(schemaName, tableSimpleName); return null; } else { diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TSMUtil.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TSMUtil.java index a584a6e..418914b 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TSMUtil.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TSMUtil.java @@ -241,7 +241,6 @@ public class TSMUtil { // column.setDescription(description); // column.setStd(true); // } - public static String getNaturalLangueName(TapSchemaEntity entity) { if (entity instanceof Schema) { return "schema"; @@ -307,66 +306,4 @@ public class TSMUtil { return sb.toString(); } - - /** - * Fill descriptions of the TAP_SCHEMA schema entities. - * - * @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"); - } } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Table.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Table.java index 4ad2590..6446101 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Table.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Table.java @@ -101,7 +101,6 @@ public class Table extends ChildEntity<Schema> implements EntitiesContainer<Colu 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); diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchema.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchema.java index 4b008b7..e1c285c 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchema.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchema.java @@ -25,9 +25,10 @@ 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 it.inaf.ia2.tsm.model.PropertyModel; +import it.inaf.ia2.tsm.model.TableModel; +import it.inaf.ia2.tsm.model.TapSchemaModel; +import it.inaf.ia2.tsm.model.TapSchemaModels; import java.io.Serializable; import java.sql.SQLException; import java.util.ArrayList; @@ -37,6 +38,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; +import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,13 +55,13 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { public static final String COLUMNS_TABLE = "columns"; public static final String KEYS_TABLE = "keys"; public static final String KEY_COLUMNS_TABLE = "key_columns"; + public static final String DESCRIPTION_KEY = "description"; 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; @@ -90,7 +92,6 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { // for serialization schemas = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); allKeys = new HashSet<>(); - keysMetadata = new ArrayList<>(); consistencyChecks = new ConsistencyChecks(); } @@ -109,16 +110,130 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { } 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)); -// } + if (exists) { + loadSavedTapSchema(); + } + loading = false; checkKeys(); } + /** + * Loads saved TAP_SCHEMA data and performs consistency checking. + * + * @throws SQLException + */ + private void loadSavedTapSchema() throws SQLException { + DBBroker broker = getTapSchemaDBBroker(); + + // Schemata + for (Map<String, Object> schemaProps : broker.getSavedItems(getName(), getTableModel(SCHEMAS_TABLE))) { + String schemaName = (String) schemaProps.get(Schema.SCHEMA_NAME_KEY); + Schema schema = addChild(schemaName); + if (schema == null) { + consistencyChecks.addUnexistingSchema(schemaName); + } else { + schema.init(schemaProps); + schema.setStatus(Status.ADDED_PERSISTED); + } + } + + // Tables + for (Map<String, Object> tableProps : broker.getSavedItems(getName(), getTableModel(TABLES_TABLE))) { + String tableCompleteName = (String) tableProps.get(Table.TABLE_NAME_KEY); + String[] tableNameSplit = tableCompleteName.split(Pattern.quote(".")); + String schemaName = tableNameSplit[0]; + String tableName = tableNameSplit[1]; + Schema schema = getChild(schemaName, Status.ADDED_PERSISTED); + if (schema == null) { + consistencyChecks.addUnexistingSchema(schemaName); + } else { + Table table = schema.addChild(tableName); + if (table == null) { + consistencyChecks.addUnexistingTable(schemaName, tableName); + } else { + table.init(tableProps); + table.setStatus(Status.ADDED_PERSISTED); + } + } + } + + // Columns + for (Map<String, Object> columnProps : broker.getSavedItems(getName(), getTableModel(COLUMNS_TABLE))) { + String tableCompleteName = (String) columnProps.get(Column.TABLE_NAME_KEY); + String[] tableNameSplit = tableCompleteName.split(Pattern.quote(".")); + String schemaName = tableNameSplit[0]; + String tableName = tableNameSplit[1]; + String columnName = (String) columnProps.get(Column.COLUMN_NAME_KEY); + Schema schema = getChild(schemaName, Status.ADDED_PERSISTED); + if (schema == null) { + consistencyChecks.addUnexistingSchema(schemaName); + } else { + Table table = schema.getChild(tableName, Status.ADDED_PERSISTED); + if (table == null) { + consistencyChecks.addUnexistingTable(schemaName, tableName); + } else { + Column column = table.addChild(columnName); + if (column == null) { + consistencyChecks.addUnexistingColumn(tableCompleteName, columnName); + } else { + column.init(columnProps); + column.setStatus(Status.ADDED_PERSISTED); + } + } + } + } + + // Keys + List<Map<String, Object>> keysProps = broker.getSavedItems(getName(), getTableModel(KEYS_TABLE)); + List<Map<String, Object>> keysColumnsProps = broker.getSavedItems(getName(), getTableModel(KEY_COLUMNS_TABLE)); + for (Map<String, Object> keyProp : keysProps) { + // Searching the key + boolean keyFound = false; + for (Key key : allKeys) { + String fromTable = (String) keyProp.get(Key.FROM_TABLE_KEY); + String targetTable = (String) keyProp.get(Key.TARGET_TABLE_KEY); + if (key.getFromTableCompleteName().equals(fromTable) && key.getTargetTableCompleteName().equals(targetTable)) { + // Search the key columns having proper key id + List<Map<String, Object>> kcPropsById = new ArrayList<>(); + for (Map<String, Object> kcp : keysColumnsProps) { + if (kcp.get(KeyColumn.KEY_ID_KEY).equals(key.getId())) { + kcPropsById.add(kcp); + } + } + + // Verifying the matching + List<KeyColumn> matchedKeyColumns = new ArrayList<>(); + if (kcPropsById.size() == key.getKeyColumns().size()) { + for (Map<String, Object> kcp : kcPropsById) { + String fromColumn = (String) kcp.get(KeyColumn.FROM_COLUMN_KEY); + String targetColumn = (String) kcp.get(KeyColumn.TARGET_COLUMN_KEY); + for (KeyColumn keyColumn : key.getKeyColumns()) { + if (keyColumn.getFromColumn().equals(fromColumn) + && keyColumn.getTargetColumn().equals(targetColumn)) { + matchedKeyColumns.add(keyColumn); + } + } + } + } + if (kcPropsById.size() == matchedKeyColumns.size()) { + keyFound = true; + int index = 0; + key.init(keyProp); + for (Map<String, Object> kcp : kcPropsById) { + KeyColumn kc = matchedKeyColumns.get(index); + kc.init(kcp); + index++; + } + } + } + } + if (!keyFound) { + // TODO + } + } + } + public DBBroker getDBBroker(String schemaName) { if (schemaName.equals(tapSchemaName)) { return getTapSchemaDBBroker(); @@ -130,7 +245,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { /** * The name of the TAP_SCHEMA schema. */ - public String getName() { + public final String getName() { return tapSchemaName; } @@ -142,10 +257,10 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { } private void loadSchemaKeysMetadata(String schemaName) throws SQLException { - keysMetadata.addAll(getDBBroker(schemaName).getKeysMetadata(schemaName)); + allKeys.addAll(getDBBroker(schemaName).getKeys(this, schemaName)); } - protected Set<Key> getAllKeys() { + public Set<Key> getAllKeys() { return allKeys; } @@ -153,14 +268,12 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { * {@inheritDoc} */ @Override - public Schema addChild(String schemaName) throws SQLException { + public final Schema addChild(String schemaName) throws SQLException { LOG.debug("Adding schema {}", schemaName); Schema schema; if (!schemas.containsKey(schemaName)) { - - consistencyChecks.addUnexistingSchema(schemaName); schema = null; } else { @@ -183,9 +296,9 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { throw new IllegalArgumentException("Cannot add the schema " + schemaName + ". Invalid status. Schema status is " + schema.getStatus()); } } - } - checkKeys(); + checkKeys(); + } return schema; } @@ -219,7 +332,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { * {@inheritDoc} */ @Override - public Schema getChild(String childName, Status... statuses) { + public final Schema getChild(String childName, Status... statuses) { return TSMUtil.getChild(schemas, childName, statuses); } @@ -272,13 +385,11 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { */ public void save() throws SQLException { - fillKeyIds(); - DBBroker broker = getTapSchemaDBBroker(); - broker.save(this); - if (!exists) { + broker.createTapSchemaStructure(getName(), getTapSchemaModel()); + // Adding TAP_SCHEMA into TAP_SCHEMA Schema tapSchemaSchema = addChild(tapSchemaName); for (String tableName : tapSchemaSchema.getAddableChildrenNames()) { @@ -287,14 +398,13 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { table.addChild(columnName); } } - LOG.debug(this.toString()); - TSMUtil.putInfoIntoTapSchemaSchema(tapSchemaSchema); - - exists = true; // important! - //broker.save(this); // save again + fillTapSchemaDescriptions(); } + fillKeyIds(); + + broker.save(this); exists = true; consistencyChecks.getInconsistencies().clear(); @@ -309,7 +419,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { private int getMaxKeyId() { int maxKeyId = 0; for (Key key : allKeys) { - if (key.getId() != null && !KeyMetadata.NEW_KEY.equals(key.getId())) { + if (key.getId() != null) { int keyId = Integer.parseInt(key.getId()); if (keyId > maxKeyId) { maxKeyId = keyId; @@ -323,7 +433,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { List<Key> newKeys = new ArrayList<>(); for (Key key : allKeys) { - if (key.isVisible() && KeyMetadata.NEW_KEY.equals(key.getId())) { + if (key.isVisible()) { newKeys.add(key); } } @@ -335,56 +445,6 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { } } -// /** -// * 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) + ""); @@ -400,49 +460,38 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { // checkKeys(); // } /** - * Automatically add and remove keys that should be visible. + * 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}). */ public final void checkKeys() { if (!loading) { - for (KeyMetadata keyMetadata : keysMetadata) { + for (Key key : allKeys) { // Check if key should be exposed in TAP_SCHEMA boolean keyVisible = true; - for (String fromColumn : keyMetadata.getFromColumns()) { - if (!isColumnVisible(keyMetadata.getFromSchema(), keyMetadata.getFromTable(), fromColumn)) { + for (KeyColumn keyColumn : key.getKeyColumns()) { + String schemaName = keyColumn.getParent().getFromSchemaName(); + String tableName = keyColumn.getParent().getFromTableSimpleName(); + String columnName = keyColumn.getFromColumn(); + if (!isColumnVisible(schemaName, tableName, columnName)) { 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; + schemaName = keyColumn.getParent().getTargetSchemaName(); + tableName = keyColumn.getParent().getTargetTableSimpleName(); + columnName = keyColumn.getTargetColumn(); + if (!isColumnVisible(schemaName, tableName, columnName)) { + keyVisible = false; 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); - } + key.setVisible(keyVisible); } } } @@ -457,55 +506,39 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { 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"); -// } -// } + 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"); + } + + sb.append("\n"); + } + } + + sb.append("** Keys **\n"); + for (Key key : getVisibileKeys()) { + sb.append(key); + sb.append("\n"); + } + return sb.toString(); } @@ -569,20 +602,10 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { return TapSchemaModels.getTapSchemaModel(version); } - public TableModel getTableModel(String tableName) { + public final 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); @@ -598,4 +621,21 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable { } return visibleKeys; } + + /** + * Fill descriptions of the TAP_SCHEMA schema entities. + */ + private void fillTapSchemaDescriptions() { + TapSchemaModel tapSchemaModel = getTapSchemaModel(); + Schema tapSchema = getChild(tapSchemaName); + tapSchema.setValue(DESCRIPTION_KEY, tapSchemaModel.getDescription()); + for (TableModel tableModel : getTapSchemaModel().getTables().values()) { + Table table = tapSchema.getChild(tableModel.getName()); + table.setValue(DESCRIPTION_KEY, tableModel.getDescription()); + for (PropertyModel propertyModel : tableModel.getProperties().values()) { + Column column = table.getChild(propertyModel.getName()); + column.setValue(DESCRIPTION_KEY, propertyModel.getDescription()); + } + } + } } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchemaEntity.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchemaEntity.java index 86aa23d..a7705df 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchemaEntity.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchemaEntity.java @@ -22,8 +22,8 @@ */ package it.inaf.ia2.tsm; -import it.inaf.ia2.tsm.xmlmodel.PropertyModel; -import it.inaf.ia2.tsm.xmlmodel.TableModel; +import it.inaf.ia2.tsm.model.PropertyModel; +import it.inaf.ia2.tsm.model.TableModel; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; @@ -85,6 +85,15 @@ public abstract class TapSchemaEntity implements Serializable { properties.get(key).init(value); } + /** + * Fill saved properties. + */ + public void init(Map<String, Object> props) { + for (Map.Entry<String, Object> entry : props.entrySet()) { + initProperty(entry.getKey(), entry.getValue()); + } + } + protected String getVersion() { return tapSchema.getVersion(); } @@ -103,6 +112,14 @@ public abstract class TapSchemaEntity implements Serializable { } public Object getValue(String key) { + return properties.get(key).getValue(); + } + + public Class getPropertyType(String key) { + return properties.get(key).getType(); + } + + public EntityProperty getProperty(String key) { return properties.get(key); } @@ -125,7 +142,7 @@ public abstract class TapSchemaEntity implements Serializable { * @return */ public <T> T getOriginalValue(String key, Class<T> type) { - return (T) properties.get(key).getValue(); + return (T) properties.get(key).getOriginalValue(type); } /** diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/UpdateOperations.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/UpdateOperations.java index ff8357c..235a079 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/UpdateOperations.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/UpdateOperations.java @@ -22,10 +22,6 @@ */ 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; @@ -94,20 +90,17 @@ public class UpdateOperations { keysToAdd = new ArrayList<>(); keysToUpdate = new ArrayList<>(); - for (Key key : ((TapSchema) tapSchema).getAllKeys()) { + for (Key key : tapSchema.getAllKeys()) { - if (key.getId() != null) { - - if (key.isVisible()) { - String originalKeyId = key.getOriginalValue(Key.ID_KEY, String.class); - if (originalKeyId == null || KeyMetadata.NEW_KEY.equals(originalKeyId)) { - keysToAdd.add(key); - } else if (key.isChanged()) { - keysToUpdate.add(key); - } - } else { - keysToRemove.add(key); + if (key.isVisible()) { + String originalKeyId = key.getOriginalValue(Key.ID_KEY, String.class); + if (originalKeyId == null) { + keysToAdd.add(key); + } else if (key.isChanged()) { + keysToUpdate.add(key); } + } else if (key.getId() != null) { + keysToRemove.add(key); } } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBroker.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBroker.java index 48acab3..d187043 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBroker.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBroker.java @@ -22,10 +22,11 @@ */ package it.inaf.ia2.tsm.datalayer; -import it.inaf.ia2.tsm.KeyMetadata; +import it.inaf.ia2.tsm.Key; import it.inaf.ia2.tsm.TapSchema; import it.inaf.ia2.tsm.TapSchemaEntity; -import it.inaf.ia2.tsm.xmlmodel.TableModel; +import it.inaf.ia2.tsm.model.TableModel; +import it.inaf.ia2.tsm.model.TapSchemaModel; import java.sql.Connection; import java.sql.SQLException; import java.util.List; @@ -42,6 +43,8 @@ public interface DBBroker { List<String> getAllSchemaNames() throws SQLException; List<String> getAllTAPSchemaNames(List<String> allSchemas) throws SQLException; + + List<String> getExposedSchemas(String tapSchemaName) throws SQLException; List<String> getAllTablesNames(String schemaName) throws SQLException; @@ -51,7 +54,7 @@ public interface DBBroker { Map<String, Map<String, Object>> getAllColumnsMetadata(String schemaName, String tableSimpleName) throws SQLException; - List<KeyMetadata> getKeysMetadata(String schemaName) throws SQLException; + List<Key> getKeys(TapSchema tapSchema, String schemaName) throws SQLException; List<Map<String, Object>> getSavedItems(String tapSchemaName, TableModel tableModel, String whereCondition, Object[] whereParams) throws SQLException; @@ -61,5 +64,7 @@ public interface DBBroker { void updateItem(String tapSchemaName, TapSchemaEntity entity, Connection conn, String whereCondition, Object... whereParams) throws SQLException; + void createTapSchemaStructure(String tapSchemaName, TapSchemaModel tapSchemaModel) throws SQLException; + void save(TapSchema tapSchema) throws SQLException; } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerTemplate.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerTemplate.java index c283b39..5e42f12 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerTemplate.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerTemplate.java @@ -32,9 +32,9 @@ 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 it.inaf.ia2.tsm.model.PropertyModel; +import it.inaf.ia2.tsm.model.TableModel; +import it.inaf.ia2.tsm.model.TapSchemaModel; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -120,7 +120,8 @@ public abstract class DBBrokerTemplate implements DBBroker { protected abstract void createDatabase(String databaseName, Connection conn) throws SQLException; - private void createTapSchemaStructure(String tapSchemaName, TapSchemaModel tapSchemaModel) throws SQLException { + @Override + public void createTapSchemaStructure(String tapSchemaName, TapSchemaModel tapSchemaModel) throws SQLException { try (Connection conn = dataSource.getConnection()) { @@ -165,10 +166,6 @@ public abstract class DBBrokerTemplate implements DBBroker { try { - if (!tapSchema.exists()) { - createTapSchemaStructure(tapSchema.getName(), tapSchema.getTapSchemaModel()); - } - connection = dataSource.getConnection(); UpdateOperations operations = new UpdateOperations(tapSchema); @@ -255,7 +252,9 @@ public abstract class DBBrokerTemplate implements DBBroker { for (Key key : operations.getKeysToAdd()) { // insert new keys and their key columns insertItem(tapSchema.getName(), key, connection); - // TODO: INSERT COLUMNS!!! + for (KeyColumn keyColumn : key.getKeyColumns()) { + insertItem(tapSchema.getName(), keyColumn, connection); + } } //UPDATE ELEMENTS @@ -264,6 +263,10 @@ public abstract class DBBrokerTemplate implements DBBroker { // update keys and their key columns String whereCond = String.format("%s = ?", escape(Key.ID_KEY)); updateItem(tapSchema.getName(), key, connection, whereCond, key.getId()); + for (KeyColumn keyColumn : key.getKeyColumns()) { + whereCond = String.format("%s = ?", escape(KeyColumn.KEY_ID_KEY)); + updateItem(tapSchema.getName(), keyColumn, connection, whereCond, keyColumn.getKeyId()); + } } for (Schema schema : operations.getSchemasToUpdate()) { @@ -485,7 +488,7 @@ public abstract class DBBrokerTemplate implements DBBroker { } } - LOG.debug("Executing query {} [{}]", query, values); + LOG.debug("Executing query {} {}", query, values); statement.executeUpdate(); } } @@ -517,7 +520,7 @@ public abstract class DBBrokerTemplate implements DBBroker { try (PreparedStatement ps = conn.prepareStatement(query)) { - int i = 0; + int i = 1; List<Object> statParams = null; if (LOG.isDebugEnabled()) { @@ -525,7 +528,7 @@ public abstract class DBBrokerTemplate implements DBBroker { } for (String key : tapSchemaItem.getPropertiesKeys()) { Object value = tapSchemaItem.getValue(key); - ps.setObject(i, value, getSQLType(value.getClass())); + ps.setObject(i, value, getSQLType(tapSchemaItem.getPropertyType(key))); i++; if (statParams != null) { statParams.add(value); @@ -539,7 +542,7 @@ public abstract class DBBrokerTemplate implements DBBroker { } } - LOG.debug("Executing query: {} [{}]", query, statParams); + LOG.debug("Executing query: {} {}", query, statParams); ps.executeUpdate(); } @@ -628,4 +631,23 @@ public abstract class DBBrokerTemplate implements DBBroker { return tablesTypes; } + + public List<String> getExposedSchemas(String tapSchemaName) throws SQLException { + + final List<String> exposedSchemas = new ArrayList<>(); + + String query = String.format("SELECT %s FROM %s.%s", Schema.SCHEMA_NAME_KEY, escape(tapSchemaName), escape(TapSchema.SCHEMAS_TABLE)); + + LOG.debug("Executing query " + query); + + try (Connection connection = dataSource.getConnection(); + 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/datalayer/mysql/MySQLDBBroker.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/mysql/MySQLDBBroker.java index 99a26ad..9998aba 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/mysql/MySQLDBBroker.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/mysql/MySQLDBBroker.java @@ -23,11 +23,12 @@ package it.inaf.ia2.tsm.datalayer.mysql; import it.inaf.ia2.tsm.Column; -import it.inaf.ia2.tsm.KeyMetadata; +import it.inaf.ia2.tsm.Key; +import it.inaf.ia2.tsm.TapSchema; import it.inaf.ia2.tsm.datalayer.ADQL; import it.inaf.ia2.tsm.datalayer.DBBrokerTemplate; -import it.inaf.ia2.tsm.xmlmodel.PropertyModel; -import it.inaf.ia2.tsm.xmlmodel.TableModel; +import it.inaf.ia2.tsm.model.PropertyModel; +import it.inaf.ia2.tsm.model.TableModel; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; @@ -102,12 +103,12 @@ public class MySQLDBBroker extends DBBrokerTemplate { // 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); - } + + boolean primaryKey = "PRI".equals(keyType); + cm.put(Column.PRIMARY_KEY, primaryKey); + + boolean indexed = "PRI".equals(keyType) || "UNI".equals(keyType) || "MUL".equals(keyType); + cm.put(Column.INDEXED_KEY, indexed); // Datatype and Size String type = resultSet.getString("Type").toLowerCase(); @@ -221,7 +222,7 @@ public class MySQLDBBroker extends DBBrokerTemplate { } @Override - public List<KeyMetadata> getKeysMetadata(String schemaName) throws SQLException { + public List<Key> getKeys(TapSchema tapSchema, String schemaName) throws SQLException { StringBuilder sb = new StringBuilder(); sb.append("SELECT\n"); @@ -246,7 +247,7 @@ public class MySQLDBBroker extends DBBrokerTemplate { LOG.debug("Executing query: {}", query); - List<KeyMetadata> keysMetadata = new ArrayList<>(); + List<Key> keys = new ArrayList<>(); try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(query)) { @@ -259,14 +260,30 @@ public class MySQLDBBroker extends DBBrokerTemplate { 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); + Map<String, Object> keyMetadata = new HashMap<>(); + keyMetadata.put(Key.FROM_TABLE_KEY, fromSchemaName + "." + fromTableName); + keyMetadata.put(Key.TARGET_TABLE_KEY, targetSchemaName + "." + targetTableName); + + Key key = null; + // Searching for a partial built key + for (Key k : keys) { + if (k.getFromSchemaName().equals(fromSchemaName) + && k.getFromTableSimpleName().equals(fromTableName) + && k.getTargetSchemaName().equals(targetSchemaName) + && k.getTargetTableSimpleName().equals(targetTableName)) { + key = k; + break; + } + } + if (key == null) { + key = new Key(tapSchema, keyMetadata); + keys.add(key); + } + key.addKeyColumn(resultSet.getString("from_column"), resultSet.getString("target_column")); } } - return keysMetadata; + return keys; } @Override diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/pgsql/PostgresDBBroker.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/pgsql/PostgresDBBroker.java index 94a41df..b27016a 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/pgsql/PostgresDBBroker.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/pgsql/PostgresDBBroker.java @@ -22,9 +22,10 @@ */ package it.inaf.ia2.tsm.datalayer.pgsql; -import it.inaf.ia2.tsm.KeyMetadata; +import it.inaf.ia2.tsm.Key; +import it.inaf.ia2.tsm.TapSchema; import it.inaf.ia2.tsm.datalayer.DBBrokerTemplate; -import it.inaf.ia2.tsm.xmlmodel.TableModel; +import it.inaf.ia2.tsm.model.TableModel; import java.sql.Connection; import java.sql.SQLException; import java.util.List; @@ -97,7 +98,7 @@ public class PostgresDBBroker extends DBBrokerTemplate { } @Override - public List<KeyMetadata> getKeysMetadata(String schemaName) throws SQLException { + public List<Key> getKeys(TapSchema tapSchema, String schemaName) throws SQLException { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } 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/model/PropertyModel.java similarity index 92% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/PropertyModel.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyModel.java index ca02f53..3be6652 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/PropertyModel.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyModel.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.xmlmodel; +package it.inaf.ia2.tsm.model; import java.io.Serializable; @@ -33,6 +33,7 @@ public class PropertyModel implements Serializable { private static final long serialVersionUID = -3081516272534689428L; private String name; + private String description; private Class type; private Integer size; private boolean updatable; @@ -45,6 +46,7 @@ public class PropertyModel implements Serializable { public PropertyModel(PropertyXMLModel propertyXMLModel) { try { name = propertyXMLModel.getName(); + description = propertyXMLModel.getDescription(); type = Class.forName(propertyXMLModel.getType()); size = propertyXMLModel.getSize(); updatable = propertyXMLModel.isUpdatable(); @@ -61,6 +63,10 @@ public class PropertyModel implements Serializable { return name; } + public String getDescription() { + return description; + } + public Class getType() { return type; } 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/model/PropertyXMLModel.java similarity index 98% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/PropertyXMLModel.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyXMLModel.java index 8558bf7..2746abf 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/PropertyXMLModel.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyXMLModel.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.xmlmodel; +package it.inaf.ia2.tsm.model; import javax.xml.bind.annotation.XmlElement; 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/model/TableModel.java similarity index 88% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TableModel.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TableModel.java index a058342..892972a 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TableModel.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TableModel.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.xmlmodel; +package it.inaf.ia2.tsm.model; import java.io.Serializable; import java.util.HashMap; @@ -36,14 +36,16 @@ public class TableModel implements Serializable { private final Map<String, PropertyModel> properties; private String name; + private String description; private TableModel() { this.properties = new HashMap<>(); } - public TableModel(String name) { + public TableModel(String name, String description) { this(); this.name = name; + this.description = description; } public String getName() { @@ -57,4 +59,8 @@ public class TableModel implements Serializable { public PropertyModel get(String columnName) { return properties.get(columnName); } + + public String getDescription() { + return description; + } } diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TableXMLModel.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TableXMLModel.java similarity index 98% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TableXMLModel.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TableXMLModel.java index b0118b4..17848aa 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TableXMLModel.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TableXMLModel.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.xmlmodel; +package it.inaf.ia2.tsm.model; import java.util.List; import javax.xml.bind.annotation.XmlAttribute; diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TapSchemaModel.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TapSchemaModel.java similarity index 87% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TapSchemaModel.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TapSchemaModel.java index 7c8ae31..9760e1b 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TapSchemaModel.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TapSchemaModel.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.xmlmodel; +package it.inaf.ia2.tsm.model; import java.io.Serializable; import java.util.HashMap; @@ -36,20 +36,26 @@ public class TapSchemaModel implements Serializable { private final Map<String, TableModel> tables; private String version; + private String description; private TapSchemaModel() { tables = new HashMap<>(); } - public TapSchemaModel(String version) { + public TapSchemaModel(String version, String description) { this(); this.version = version; + this.description = description; } public String getVersion() { return version; } + public String getDescription() { + return description; + } + public Map<String, TableModel> getTables() { return tables; } 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/model/TapSchemaModels.java similarity index 84% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TapSchemaModels.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TapSchemaModels.java index 7ab8dc4..25fc5be 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TapSchemaModels.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TapSchemaModels.java @@ -20,9 +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.xmlmodel; +package it.inaf.ia2.tsm.model; import java.io.File; +import java.io.IOException; +import java.io.InputStream; import java.net.URISyntaxException; import java.util.HashMap; import java.util.Iterator; @@ -49,22 +51,25 @@ public class TapSchemaModels { MODELS = new HashMap<>(); for (TapSchemaXMLModel xmlModel : xmlModels.values()) { - TapSchemaModel model = new TapSchemaModel(xmlModel.getVersion()); + TapSchemaModel model = new TapSchemaModel(xmlModel.getVersion(), xmlModel.getDescription()); loadTapSchemaModel(model, xmlModel, xmlModels); MODELS.put(model.getVersion(), model); } - } catch (URISyntaxException e) { + } catch (IOException e) { throw new ExceptionInInitializerError(e); } } - private static Map<String, TapSchemaXMLModel> getXmlModels() throws URISyntaxException { + private static Map<String, TapSchemaXMLModel> getXmlModels() throws IOException { 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); + + for (String modelFile : Tasman.XML_MODEL_FILES) { + try (InputStream in = TapSchemaModels.class.getClassLoader().getResourceAsStream(modelFile)) { + TapSchemaXMLModel model = JAXB.unmarshal(in, TapSchemaXMLModel.class); + xmlModels.put(model.getVersion(), model); + } } + return xmlModels; } @@ -74,7 +79,7 @@ public class TapSchemaModels { String tableName = tableXmlModel.getName(); TableModel tableModel = model.get(tableName); if (tableModel == null) { - tableModel = new TableModel(tableName); + tableModel = new TableModel(tableName, tableXmlModel.getDescription()); } for (PropertyXMLModel property : tableXmlModel.getAdd()) { tableModel.getProperties().put(property.getName(), new PropertyModel(property)); 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/model/TapSchemaXMLModel.java similarity index 98% rename from TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TapSchemaXMLModel.java rename to TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TapSchemaXMLModel.java index e320d16..dc561f8 100644 --- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/xmlmodel/TapSchemaXMLModel.java +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TapSchemaXMLModel.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.xmlmodel; +package it.inaf.ia2.tsm.model; import java.util.List; import javax.xml.bind.annotation.XmlAttribute; diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/Tasman.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/Tasman.java new file mode 100644 index 0000000..11fc66e --- /dev/null +++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/Tasman.java @@ -0,0 +1,55 @@ +/* + * _____________________________________________________________________________ + * + * 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.model; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +/** + * + * @author Sonia Zorba {@literal <zorba at oats.inaf.it>} + */ +public class Tasman { + + public static final String[] XML_MODEL_FILES; + public static final boolean ALLOWS_FICTITIOUS_KEYS; + + static { + try (InputStream in = Tasman.class.getClassLoader().getResourceAsStream("core.properties")) { + Properties props = new Properties(); + props.load(in); + String[] models = props.getProperty("models").split(","); + XML_MODEL_FILES = new String[models.length]; + for (int i = 0; i < models.length; i++) { + String suffix = models[i]; + XML_MODEL_FILES[i] = "tap_schema" + File.separator + "tap_schema-" + suffix + ".xml"; + } + + ALLOWS_FICTITIOUS_KEYS = Boolean.parseBoolean(props.getProperty("allow_fictitious_keys")); + } catch (IOException e) { + throw new ExceptionInInitializerError(e); + } + } +} diff --git a/TASMAN-core/src/main/resources/core.properties b/TASMAN-core/src/main/resources/core.properties new file mode 100644 index 0000000..d7dd188 --- /dev/null +++ b/TASMAN-core/src/main/resources/core.properties @@ -0,0 +1,9 @@ +## Configuration properties ## + +# List of supported TAP_SCHEMA models. These comma separated values are XML file +# suffixes for model configurations. +# (It is necessary to put this list here because, unfortunately, there is no +# easy way to read an entire resource folder using the ClassLoader). +models = 1,1-IA2,1_1 + +allow_fictitious_keys = false diff --git a/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml index 89adc9c..26c5446 100644 --- a/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml +++ b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml @@ -186,8 +186,6 @@ Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. <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> @@ -229,8 +227,6 @@ Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. <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> 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 c85aaf4..6b67e26 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 @@ -43,9 +43,8 @@ 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.Objects; import java.util.Set; import org.junit.After; import org.junit.AfterClass; @@ -63,7 +62,7 @@ import org.slf4j.LoggerFactory; */ public class TestAll { - private static final Logger log = LoggerFactory.getLogger(TestAll.class); + private static final Logger LOG = LoggerFactory.getLogger(TestAll.class); private static final int SCHEMAS_COUNT = 2; // minimum value: 2 private static final int TABLES_COUNT = 3; @@ -122,45 +121,62 @@ public class TestAll { DatabaseType dbType = dbWrapper.getSourceDatabaseType(); // Removing keys between schema1 and schema0 - if (dbType == DatabaseType.MYSQL) { - try (ResultSet rs = statement.executeQuery("SHOW DATABASES WHERE `Database` = 'sch1'")) { - // The constraint can be removed only if sch1 exists - if (rs.next()) { - statement.executeUpdate("ALTER TABLE sch1.table0 DROP FOREIGN KEY sch0table0id_constraint"); - } + if (null == dbType) { + throw new UnsupportedOperationException("Database type " + dbType + " not supported"); + } else { + switch (dbType) { + case MYSQL: + try (ResultSet rs = statement.executeQuery("SHOW DATABASES WHERE `Database` = 'sch1'")) { + // The constraint can be removed only if sch1 exists + if (rs.next()) { + statement.executeUpdate("ALTER TABLE sch1.table0 DROP FOREIGN KEY sch0table0id_constraint"); + } + } + break; + case POSTGRES: + try (ResultSet rs = statement.executeQuery("SELECT schema_name FROM information_schema.schemata WHERE schema_name = 'sch1'")) { + // The constraint can be removed only if sch1 exists + if (rs.next()) { + statement.executeUpdate("ALTER TABLE sch1.table0 DROP CONSTRAINT sch0table0id_constraint"); + } + } + break; + default: + throw new UnsupportedOperationException("Database type " + dbType + " not supported"); } - } else if (dbType == DatabaseType.POSTGRES) { - try (ResultSet rs = statement.executeQuery("SELECT schema_name FROM information_schema.schemata WHERE schema_name = 'sch1'")) { - // The constraint can be removed only if sch1 exists - if (rs.next()) { - statement.executeUpdate("ALTER TABLE sch1.table0 DROP CONSTRAINT sch0table0id_constraint"); + + for (int i = 0; i < SCHEMAS_COUNT; i++) { + switch (dbType) { + case MYSQL: + statement.executeUpdate("DROP DATABASE IF EXISTS sch" + i); + break; + case POSTGRES: + statement.executeUpdate("DROP SCHEMA IF EXISTS sch" + i + " CASCADE"); + break; + default: + throw new UnsupportedOperationException("Database type " + dbType + " not supported"); } } - } else { - throw new UnsupportedOperationException("Database type " + dbType + " not supported"); } - - for (int i = 0; i < SCHEMAS_COUNT; i++) { - if (dbType == DatabaseType.MYSQL) { - statement.executeUpdate("DROP DATABASE IF EXISTS sch" + i); - } else if (dbType == DatabaseType.POSTGRES) { - statement.executeUpdate("DROP SCHEMA IF EXISTS sch" + i + " CASCADE"); - } else { + try (Connection tapSchemaConnection = dbWrapper.getTapSchemaConnection(); + Statement stat = tapSchemaConnection.createStatement()) { + dbType = dbWrapper.getTapSchemaDatabaseType(); + if (null == dbType) { throw new UnsupportedOperationException("Database type " + dbType + " not supported"); + } else { + switch (dbType) { + case MYSQL: + stat.executeUpdate("DROP DATABASE IF EXISTS test_tap_schema"); + break; + case POSTGRES: + stat.executeUpdate("DROP SCHEMA IF EXISTS test_tap_schema CASCADE"); + break; + default: + throw new UnsupportedOperationException("Database type " + dbType + " not supported"); + } } } } - try (Connection tapSchemaConnection = dbWrapper.getTapSchemaConnection(); - Statement statement = tapSchemaConnection.createStatement()) { - DatabaseType dbType = dbWrapper.getTapSchemaDatabaseType(); - if (dbType == DatabaseType.MYSQL) { - statement.executeUpdate("DROP DATABASE IF EXISTS test_tap_schema"); - } else if (dbType == DatabaseType.POSTGRES) { - statement.executeUpdate("DROP SCHEMA IF EXISTS test_tap_schema CASCADE"); - } else { - throw new UnsupportedOperationException("Database type " + dbType + " not supported"); - } - } } } @@ -175,34 +191,41 @@ public class TestAll { try (Statement statement = connection.createStatement()) { - if (dbType == DatabaseType.MYSQL) { - for (int i = 0; i < SCHEMAS_COUNT; i++) { - statement.executeUpdate("CREATE DATABASE sch" + i); - for (int j = 0; j < TABLES_COUNT; j++) { - statement.executeUpdate("CREATE TABLE sch" + i + ".table" + j + " (\n" - + "id INT PRIMARY KEY AUTO_INCREMENT,\n" - + "value1 VARCHAR(255),\n" - + "value2 FLOAT\n" - + ");"); - } - } - } else if (dbType == DatabaseType.POSTGRES) { - for (int i = 0; i < SCHEMAS_COUNT; i++) { - statement.executeUpdate("CREATE SCHEMA sch" + i); - for (int j = 0; j < TABLES_COUNT; j++) { - statement.executeUpdate("CREATE TABLE sch" + i + ".table" + j + " (\n" - + "id BIGSERIAL PRIMARY KEY,\n" - + "value1 VARCHAR(255),\n" - + "value2 FLOAT\n" - + ");"); - } - } - } else { + if (null == dbType) { throw new UnsupportedOperationException("Database type " + dbType + " not supported"); + } else { + switch (dbType) { + case MYSQL: + for (int i = 0; i < SCHEMAS_COUNT; i++) { + statement.executeUpdate("CREATE DATABASE sch" + i); + for (int j = 0; j < TABLES_COUNT; j++) { + statement.executeUpdate("CREATE TABLE sch" + i + ".table" + j + " (\n" + + "id INT PRIMARY KEY AUTO_INCREMENT,\n" + + "value1 VARCHAR(255),\n" + + "value2 FLOAT\n" + + ");"); + } + } + break; + case POSTGRES: + for (int i = 0; i < SCHEMAS_COUNT; i++) { + statement.executeUpdate("CREATE SCHEMA sch" + i); + for (int j = 0; j < TABLES_COUNT; j++) { + statement.executeUpdate("CREATE TABLE sch" + i + ".table" + j + " (\n" + + "id BIGSERIAL PRIMARY KEY,\n" + + "value1 VARCHAR(255),\n" + + "value2 FLOAT\n" + + ");"); + } + } + break; + default: + throw new UnsupportedOperationException("Database type " + dbType + " not supported"); + } } } - log.info("dbs created"); + LOG.info("dbs created"); try (Statement statement = connection.createStatement()) { for (int j = 0; j < TABLES_COUNT - 1; j++) { @@ -235,62 +258,40 @@ public class TestAll { } } - @Test - public void test1() throws Exception { - - setUpTestingDatabases(); - - for (DBWrapper dbWrapper : dbWrappers) { - TapSchema tapSchema = new TapSchema("1.0", dbWrapper, "test_tap_schema", false); - tapSchema.save(); + private boolean checkKey(Key key, String fromTableCompleteName, String[] fromColumns, String targetTableCompleteName, String[] targetColumns, boolean isVisible) { + if (!fromTableCompleteName.equals(key.getFromTableCompleteName())) { + return false; + } + if (!targetTableCompleteName.equals(key.getTargetTableCompleteName())) { + return false; } - } - -// -// 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()); for (int i = 0; i < key.getKeyColumns().size(); i++) { KeyColumn keyColumn = key.getKeyColumns().get(i); - assertEquals(fromColumns[i], keyColumn.getFromColumn()); - assertEquals(targetColumns[i], keyColumn.getTargetColumn()); + if (!fromColumns[i].equals(keyColumn.getFromColumn())) { + return false; + } + if (!targetColumns[i].equals(keyColumn.getTargetColumn())) { + return false; + } + } + if (isVisible != key.isVisible()) { + return false; } - assertEquals(isVisible, key.isVisible()); for (KeyColumn keyColumn : key.getKeyColumns()) { - assertEquals(key.getId(), keyColumn.getKeyId()); + if (!Objects.equals(key.getId(), keyColumn.getKeyId())) { + return false; + } } + return true; } - private void checkKey(Key key, String fromTableCompleteName, String fromColumn, String targetTableCompleteName, String targetColumn, boolean isVisible) { - checkKey(key, fromTableCompleteName, new String[]{fromColumn}, targetTableCompleteName, new String[]{targetColumn}, isVisible); + private boolean checkKey(Key key, String fromTableCompleteName, String fromColumn, String targetTableCompleteName, String targetColumn, boolean isVisible) { + return checkKey(key, fromTableCompleteName, new String[]{fromColumn}, targetTableCompleteName, new String[]{targetColumn}, isVisible); } @Test public void createNewAndUpdate() throws SQLException { - log.info("TEST createNewAndUpdate STARTED"); + LOG.info("TEST createNewAndUpdate STARTED"); try { removeTestingDatabases(); @@ -309,11 +310,12 @@ public class TestAll { Schema sch0 = tapSchema.addChild("sch0"); assertEquals(Status.ADDED_NOT_PERSISTED, sch0.getStatus()); -// Set<Key> allKeys = 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. @@ -322,20 +324,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 // ///////////////////////////////////// @@ -366,11 +368,11 @@ public class TestAll { assertTrue(tapSchema.getVisibileKeys().isEmpty()); sch0table1.addChild("table0_id"); - assertEquals(1, tapSchema.getVisibileKeys()); + assertEquals(1, tapSchema.getVisibileKeys().size()); // Check if key and its columns have been properly initialized Key k1 = tapSchema.getVisibileKeys().get(0); - checkKey(k1, "sch0.table1", "table0_id", "sch0.table0", "id", true); + assertTrue(checkKey(k1, "sch0.table1", "table0_id", "sch0.table0", "id", true)); // Removing sch0.table1 sch0.removeChild("table1"); @@ -383,8 +385,7 @@ public class TestAll { // // Adding sch1 Schema sch1 = tapSchema.addChild("sch1"); -// allKeys = ((TapSchema) tapSchema).getAllKeys(); -// assertEquals(5, allKeys.size()); + assertEquals(5, allKeys.size()); // Adding sch1.table0 Table sch1table0 = sch1.addChild("table0"); @@ -393,105 +394,52 @@ 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(2, tapSchema.getVisibileKeys().size()); + + for (Key key : tapSchema.getVisibileKeys()) { + assertTrue( + checkKey(key, "sch0.table1", "table0_id", "sch0.table0", "id", false) + || checkKey(key, "sch1.table0", "sch0table0id", "sch0.table0", "id", true) + || checkKey(key, "sch0.table0", "sch1table0id", "sch1.table0", "id", true) + ); + } + // Removing sch1 tapSchema.removeChild("sch1"); assertEquals(Status.REMOVED_NOT_PERSISTED, sch1.getStatus()); -// assertTrue(sch0table0.getVisibleTargetKeys().isEmpty()); + assertEquals(0, tapSchema.getVisibileKeys().size()); // 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()); + assertEquals(2, tapSchema.getVisibileKeys().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"); + assertEquals(2, tapSchema.getVisibileKeys().size()); -// 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"); + assertEquals(2, tapSchema.getVisibileKeys().size()); -// 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(3, tapSchema.getVisibileKeys().size()); + + for (Key key : tapSchema.getVisibileKeys()) { + assertTrue( + checkKey(key, "sch0.table1", "table0_id", "sch0.table0", "id", false) + || checkKey(key, "sch1.table0", "sch0table0id", "sch0.table0", "id", true) + || checkKey(key, "sch0.table0", "sch1table0id", "sch1.table0", "id", true) + || checkKey(key, "sch0.table_y", new String[]{"idy1", "idy2"}, "sch0.table_x", new String[]{"idx1", "idx2"}, true) + ); + } -// 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 // ///////////////////////////////////// @@ -500,30 +448,6 @@ 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)); UpdateOperations operations = new UpdateOperations(tapSchema); assertEquals(2, operations.getSchemasToAdd().size()); assertEquals(6, operations.getTablesToAdd().size()); @@ -531,15 +455,13 @@ public class TestAll { assertEquals(5, operations.getKeysToAdd().size()); tapSchema.save(); - assertFalse(new UpdateOperations(tapSchema).getHasOperations()); -// assertTrue(allKeysHaveDifferentId(tapSchema)); + operations = new UpdateOperations(tapSchema); + assertFalse(operations.getHasOperations()); // reloading - log.debug("----- Reloading saved TAP_SCHEMA -----"); -// tapSchema = TapSchemaFactory.getTapSchema(TapSchemaVersion.TAP_SCHEMA_1_IA2, dbWrapper, "test_tap_schema", true); -// allKeys = ((TapSchema) tapSchema).getAllKeys(); -// assertTrue(allKeysHaveDifferentId(tapSchema)); - log.debug(tapSchema.toString()); + LOG.debug("----- Reloading saved TAP_SCHEMA -----"); + tapSchema = new TapSchema("1.0", dbWrapper, "test_tap_schema", true); + LOG.debug(tapSchema.toString()); assertNotNull(sch0 = tapSchema.getChild("sch0", Status.ADDED_PERSISTED)); assertNotNull(sch1 = tapSchema.getChild("sch1", Status.ADDED_PERSISTED)); @@ -565,43 +487,16 @@ public class TestAll { // 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( +// checkKey(key, "sch0.table1", "table0_id", "sch0.table0", "id", true) +// || checkKey(key, "sch1.table0", "sch0table0id", "sch0.table0", "id", true) +// || checkKey(key, "sch0.table0", "sch1table0id", "sch1.table0", "id", true) +// || checkKey(key, "sch0.table_y", new String[]{"idy1", "idy2"}, "sch0.table_x", new String[]{"idx1", "idx2"}, true) +// || checkKey(key, "sch0.table2", "table1_id", "sch0.table1", "id", true) +// ); // } // } -// 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; -// } -// } -// } operations = new UpdateOperations(tapSchema); assertFalse(operations.getHasEntitiesToUpdate()); @@ -612,14 +507,14 @@ public class TestAll { assertEquals(2, operations.getKeysToRemove().size()); tapSchema.save(); - log.debug(tapSchema.toString()); - assertFalse(new UpdateOperations(tapSchema).getHasOperations()); + LOG.debug(tapSchema.toString()); + operations = new UpdateOperations(tapSchema); + assertFalse(operations.getHasOperations()); // reloading - log.debug("----- Reloading saved TAP_SCHEMA -----"); - tapSchema = new TapSchema("1.0", dbWrapper, "test_tap_schema", false); -// allKeys = ((TapSchema) tapSchema).getAllKeys(); - log.debug(tapSchema.toString()); + LOG.debug("----- Reloading saved TAP_SCHEMA -----"); + tapSchema = new TapSchema("1.0", dbWrapper, "test_tap_schema", true); + LOG.debug(tapSchema.toString()); assertNotNull(sch0 = tapSchema.getChild("sch0", Status.ADDED_PERSISTED)); assertNotNull(sch1 = tapSchema.getChild("sch1", Status.ADDED_PERSISTED)); @@ -643,20 +538,12 @@ public class TestAll { // 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; -// } +// assertTrue( +// checkKey(key, "sch1.table0", "sch0table0id", "sch0.table0", "id", true) +// || checkKey(key, "sch0.table0", "sch1table0id", "sch1.table0", "id", true) +// || checkKey(key, "sch0.table_y", new String[]{"idy1", "idy2"}, "sch0.table_x", new String[]{"idx1", "idx2"}, true) +// || checkKey(key, "sch0.table2", "table1_id", "sch0.table1", "id", true) +// ); // } // } // Test adding ficitious key @@ -706,7 +593,7 @@ public class TestAll { tapSchema = (TapSchema) in.readObject(); } - log.debug(tapSchema.toString()); + LOG.debug(tapSchema.toString()); } } } diff --git a/TASMAN-webapp/pom.xml b/TASMAN-webapp/pom.xml index 2afaa32..9038a68 100644 --- a/TASMAN-webapp/pom.xml +++ b/TASMAN-webapp/pom.xml @@ -4,7 +4,7 @@ <groupId>it.inaf.ia2.tap</groupId> <artifactId>tasman-webapp</artifactId> - <version>1.1.0</version> + <version>1.2.0</version> <packaging>war</packaging> <name>tasman-webapp</name> @@ -88,7 +88,7 @@ <dependency> <groupId>it.inaf.ia2.tap</groupId> <artifactId>tasman-core</artifactId> - <version>1.1.0</version> + <version>1.2.0</version> </dependency> <dependency> <groupId>ari.ucidy</groupId> 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 abf6235..81b1423 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,8 +22,8 @@ */ package it.inaf.ia2.tsm.webapp; +import it.inaf.ia2.tsm.TapSchema; import it.inaf.ia2.tsm.datalayer.DBWrapper; -import it.inaf.ia2.tsm.api.contract.TapSchema; import java.io.Serializable; import java.sql.SQLException; import javax.inject.Inject; 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 75d0987..1a2f655 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 @@ -22,12 +22,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.TapSchema; +import it.inaf.ia2.tsm.datalayer.DBBroker; +import it.inaf.ia2.tsm.datalayer.DBBrokerFactory; import it.inaf.ia2.tsm.datalayer.DBWrapper; -import it.inaf.ia2.tsm.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; @@ -92,7 +90,8 @@ public class SchemaSelectionBean implements Serializable { // Loading all schemas of the source database try { - allSchemas = DaoSchema.getAllSchemasNames(dbWrapper.getSourceDataSource(), dbWrapper.getSourceDatabaseType()); + DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getSourceDataSourceWrapper()); + allSchemas = broker.getAllSchemaNames(); setSelectedSchemas(new ArrayList<String>()); } catch (SQLException e) { throw new RuntimeException(e); @@ -100,7 +99,8 @@ public class SchemaSelectionBean implements Serializable { // Loading all schemas of the TAP_SCHEMA database try { - allTAPSchemas = Dao.getAllTAPSchemasNames(dbWrapper, DaoSchema.getAllSchemasNames(dbWrapper.getTapSchemaDataSource(), dbWrapper.getTapSchemaDatabaseType())); + DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getTapSchemaDataSourceWrapper()); + allTAPSchemas = broker.getAllTAPSchemaNames(allSchemas); if (!allTAPSchemas.isEmpty()) { this.selectedTAPSchema = allTAPSchemas.get(0); @@ -113,7 +113,8 @@ public class SchemaSelectionBean implements Serializable { } private void loadExposedSchemas() throws SQLException { - List<String> schemas = Dao.getExposedSchemas(dbWrapper, selectedTAPSchema); + DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getTapSchemaDataSourceWrapper()); + List<String> schemas = broker.getExposedSchemas(selectedTAPSchema); exposedSchemas = ""; for (int i = 0; i < schemas.size(); i++) { exposedSchemas += schemas.get(i); @@ -148,9 +149,9 @@ public class SchemaSelectionBean implements Serializable { } public void setSelectedTAPSchema(String selectedTAPSchema) { - this.selectedTAPSchema = selectedTAPSchema; + this.selectedTAPSchema = selectedTAPSchema; } - + public void selectedTAPSchemaChanged() { try { loadExposedSchemas(); @@ -188,11 +189,11 @@ public class SchemaSelectionBean implements Serializable { @Override public void run() { try { - loadedTapSchema = TapSchemaFactory.getTapSchema(TapSchemaVersion.TAP_SCHEMA_1_IA2, dbWrapper, selectedTAPSchema, true); + loadedTapSchema = new TapSchema("1.0-IA2", dbWrapper, selectedTAPSchema, true); } catch (Throwable e) { LOG.error("Exception caught", e); loadingError = e.getMessage(); - if(loadingError == null) { + if (loadingError == null) { loadingError = e.getClass().getCanonicalName(); } } @@ -211,7 +212,7 @@ public class SchemaSelectionBean implements Serializable { @Override public void run() { try { - loadedTapSchema = TapSchemaFactory.getTapSchema(TapSchemaVersion.TAP_SCHEMA_1_IA2, dbWrapper, tapSchemaName, false); + loadedTapSchema = new TapSchema("1.0-IA2", dbWrapper, tapSchemaName, false); for (String schemaName : selectedSchemas) { loadedTapSchema.addChild(schemaName); } @@ -270,7 +271,7 @@ public class SchemaSelectionBean implements Serializable { public String getLoadingError() { return loadingError; } - + public TapSchema getLoadedTapSchema() { return loadedTapSchema; } 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 5a8c784..5faedbe 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 @@ -22,17 +22,17 @@ */ package it.inaf.ia2.tsm.webapp; +import it.inaf.ia2.tsm.ChildEntity; +import it.inaf.ia2.tsm.Column; 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.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.Key; +import it.inaf.ia2.tsm.KeyColumn; +import it.inaf.ia2.tsm.Schema; 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.Table; +import it.inaf.ia2.tsm.TapSchema; import it.inaf.ia2.tsm.TapSchemaEntity; import it.inaf.ia2.tsm.UpdateOperations; import java.io.Serializable; @@ -229,7 +229,7 @@ public class TapSchemaEditingBean implements Serializable { if (selectedColumn == null) { voUnitValidator = new VOUnitValidator(null); } else { - voUnitValidator = new VOUnitValidator(selectedColumn.getUnit()); + voUnitValidator = new VOUnitValidator(selectedColumn.getValue("unit", String.class)); } } @@ -305,9 +305,9 @@ public class TapSchemaEditingBean implements Serializable { if (!FacesContext.getCurrentInstance().isValidationFailed()) { if (searchUCDDialog.isManualInsertion()) { - selectedColumn.setUCD(searchUCDDialog.getUCDManualText()); + selectedColumn.setValue("ucd", searchUCDDialog.getUCDManualText()); } else { - selectedColumn.setUCD(searchUCDDialog.getSelectedUCD()); + selectedColumn.setValue("ucd", searchUCDDialog.getSelectedUCD()); } // New UCD is set and we can notify the client to close the UCD Search modal dialog. @@ -327,7 +327,7 @@ public class TapSchemaEditingBean implements Serializable { public void openUCDDialog() throws Exception { searchUCDDialog.setDefault(); - String description = selectedColumn.getDescription(); + String description = selectedColumn.getValue("description", String.class); if (description != null && !description.isEmpty()) { searchUCDDialog.setDescription(description); searchUCDDialog.search(); diff --git a/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml b/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml index 501fec0..cb7d6c0 100644 --- a/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml +++ b/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml @@ -106,7 +106,7 @@ <h:inputText id="schema_utype" class="form-control #{tapSchemaEditing.selectedSchema.isChanged('utype') ? 'changed' : ''}" - value="#{tapSchemaEditing.selectedSchema.utype}"> + value="#{tapSchemaEditing.selectedSchema.getProperty('utype').value}"> <f:converter converterId="it.inaf.ia2.NullOrEmptyConverter" /> <f:ajax event="keyup" execute="@form" listener="#{tapSchemaEditing.textInputChanged(tapSchemaEditing.selectedSchema, 'utype')}" onevent="TSM.textInputChanged" /> </h:inputText> @@ -118,7 +118,7 @@ <h:inputText id="schema_description" class="form-control #{tapSchemaEditing.selectedSchema.isChanged('description') ? 'changed' : ''}" - value="#{tapSchemaEditing.selectedSchema.description}"> + value="#{tapSchemaEditing.selectedSchema.getProperty('description').value}"> <f:converter converterId="it.inaf.ia2.NullOrEmptyConverter" /> <f:ajax event="keyup" execute="@form" listener="#{tapSchemaEditing.textInputChanged(tapSchemaEditing.selectedSchema, 'description')}" onevent="TSM.textInputChanged" /> </h:inputText> @@ -174,7 +174,7 @@ <h:inputText id="table_utype" class="form-control #{tapSchemaEditing.selectedTable.isChanged('utype') ? 'changed' : ''}" - value="#{tapSchemaEditing.selectedTable.utype}"> + value="#{tapSchemaEditing.selectedTable.getProperty('utype').value}"> <f:converter converterId="it.inaf.ia2.NullOrEmptyConverter" /> <f:ajax event="keyup" execute="@form" listener="#{tapSchemaEditing.textInputChanged(tapSchemaEditing.selectedTable, 'utype')}" onevent="TSM.textInputChanged" /> </h:inputText> @@ -186,7 +186,7 @@ <h:inputText id="table_description" class="form-control #{tapSchemaEditing.selectedTable.isChanged('description') ? 'changed' : ''}" - value="#{tapSchemaEditing.selectedTable.description}"> + value="#{tapSchemaEditing.selectedTable.getProperty('description').value}"> <f:converter converterId="it.inaf.ia2.NullOrEmptyConverter" /> <f:ajax event="keyup" execute="@form" listener="#{tapSchemaEditing.textInputChanged(tapSchemaEditing.selectedTable, 'description')}" onevent="TSM.textInputChanged" /> </h:inputText> @@ -261,13 +261,13 @@ <div class="col-xs-6"> <div class="form-group"> <label for="datatype" class="control-label">Datatype:</label> - <span>#{tapSchemaEditing.selectedColumn.datatype}</span> + <span>#{tapSchemaEditing.selectedColumn.getProperty('datatype').value}</span> </div> </div> <div class="col-xs-6"> <div class="form-group"> <label for="size" class="control-label">Size:</label> - <span>#{tapSchemaEditing.selectedColumn.size}</span> + <span>#{tapSchemaEditing.selectedColumn.getProperty('size').value}</span> </div> </div> </div> @@ -276,7 +276,7 @@ <div class="checkbox"> <label> <h:selectBooleanCheckbox - value="#{tapSchemaEditing.selectedColumn.std}" + value="#{tapSchemaEditing.selectedColumn.getProperty('std').value}" class="#{tapSchemaEditing.selectedColumn.isChanged('std') ? 'changed' : ''}"> <f:ajax execute="@form" render="@this" /> </h:selectBooleanCheckbox> @@ -288,7 +288,7 @@ <div class="checkbox"> <label> <h:selectBooleanCheckbox - value="#{tapSchemaEditing.selectedColumn.principal}" + value="#{tapSchemaEditing.selectedColumn.getProperty('principal').value}" class="#{tapSchemaEditing.selectedColumn.isChanged('principal') ? 'changed' : ''}"> <f:ajax execute="@form" render="@this" /> </h:selectBooleanCheckbox> @@ -302,7 +302,7 @@ <h:inputText id="column_utype" class="form-control #{tapSchemaEditing.selectedColumn.isChanged('utype') ? 'changed' : ''}" - value="#{tapSchemaEditing.selectedColumn.utype}"> + value="#{tapSchemaEditing.selectedColumn.getProperty('utype').value}"> <f:converter converterId="it.inaf.ia2.NullOrEmptyConverter" /> <f:ajax event="keyup" execute="@form" listener="#{tapSchemaEditing.textInputChanged(tapSchemaEditing.selectedColumn, 'utype')}" onevent="TSM.textInputChanged" /> </h:inputText> @@ -310,7 +310,7 @@ <div class="form-group"> <label for=":main:column_ucd" class="control-label">UCD:</label> <h:commandLink action="#{tapSchemaEditing.openUCDDialog()}" class="form-control #{tapSchemaEditing.selectedColumn.isChanged('ucd') ? 'changed' : ''}" id="column_ucd"> - #{tapSchemaEditing.selectedColumn.UCD} + #{tapSchemaEditing.selectedColumn.getProperty('UCD').value} <f:ajax execute="@form" render=":ucd_search_form:search_UCD_modal_content" onevent="TSM.openSearchUCDModal"/> </h:commandLink> </div> @@ -319,7 +319,7 @@ <h:inputText id="column_unit" class="form-control #{tapSchemaEditing.selectedColumn.isChanged('unit') ? 'changed' : ''}" - value="#{tapSchemaEditing.selectedColumn.unit}" + value="#{tapSchemaEditing.selectedColumn.getProperty('unit').value}" autocomplete="off"> <f:converter converterId="it.inaf.ia2.NullOrEmptyConverter" /> <f:ajax event="keyup" execute="@form" listener="#{tapSchemaEditing.textInputChanged(tapSchemaEditing.selectedColumn, 'unit')}" onevent="TSM.textInputChanged" render="vounit-validator" /> @@ -363,7 +363,7 @@ <h:inputText id="column_description" class="form-control #{tapSchemaEditing.selectedColumn.isChanged('description') ? 'changed' : ''}" - value="#{tapSchemaEditing.selectedColumn.description}"> + value="#{tapSchemaEditing.selectedColumn.getProperty('description').value}"> <f:converter converterId="it.inaf.ia2.NullOrEmptyConverter" /> <f:ajax event="keyup" execute="@form" listener="#{tapSchemaEditing.textInputChanged(tapSchemaEditing.selectedColumn, 'description')}" onevent="TSM.textInputChanged" /> </h:inputText> -- GitLab