diff --git a/TapSchemaManager/pom.xml b/TapSchemaManager/pom.xml index d1d46c06c47ededd227ff1c394bcc85f03c965bd..e1035a6db88b0ee659f3e18ebab36af8187a3f90 100644 --- a/TapSchemaManager/pom.xml +++ b/TapSchemaManager/pom.xml @@ -20,6 +20,11 @@ TapSchemaManagerDL 1.0-SNAPSHOT + + ari.ucd + ucdvalidator + 1.0beta + javax javaee-web-api @@ -53,8 +58,8 @@ maven-compiler-plugin 3.1 - 1.6 - 1.6 + 1.7 + 1.7 ${endorsed.dir} diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Column.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Column.java index 7135af0c61aeef6e34d945d4e52ae8f35f5c4927..07a9bc60dc859c8ed0175e030cdad4ea2369828a 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Column.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Column.java @@ -6,7 +6,7 @@ import java.io.Serializable; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public class Column extends EntityWrapper implements Serializable { @@ -28,10 +28,10 @@ public class Column extends EntityWrapper implements Serializable private boolean hidden; - public Column(TapSchemaHandler tapSchemaHandler, ColumnEntity columnEntity, boolean primaryKey) { + public Column(TapSchemaHandler tapSchemaHandler, ColumnEntity columnEntity) { super(columnEntity, UTYPE, UCD, UNIT, DESCRIPTION, STD, PRINCIPAL); hidden = true; - this.primaryKey = primaryKey; + this.primaryKey = columnEntity.isPrimaryKey(); this.datatype = columnEntity.getDatatype(); this.size = columnEntity.getSize(); this.indexed = columnEntity.getIndexed() == 1; @@ -51,18 +51,25 @@ public class Column extends EntityWrapper implements Serializable @Override protected void afterSetValue(String key, String value) { ColumnEntity columnEntity = getEntity(); - if (key.equals(UTYPE)) { - columnEntity.setUtype(value); - } else if (key.equals(UCD)) { - columnEntity.setUcd(value); - } else if (key.equals(UNIT)) { - columnEntity.setUnit(value); - } else if (key.equals(DESCRIPTION)) { - columnEntity.setDescription(value); - } else if (key.equals(STD)) { - columnEntity.setStd(Integer.parseInt(value)); - } else if (key.equals(PRINCIPAL)) { - columnEntity.setPrincipal(Integer.parseInt(value)); + switch (key) { + case UTYPE: + columnEntity.setUtype(value); + break; + case UCD: + columnEntity.setUcd(value); + break; + case UNIT: + columnEntity.setUnit(value); + break; + case DESCRIPTION: + columnEntity.setDescription(value); + break; + case STD: + columnEntity.setStd(Integer.parseInt(value)); + break; + case PRINCIPAL: + columnEntity.setPrincipal(Integer.parseInt(value)); + break; } } diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/CredentialsConfiguration.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/CredentialsConfiguration.java index 9fdccce0caa3f66eaea9db19a7a3648242b8ca4c..8da2b296ae37da7965a3cb6025e25a7755101c5f 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/CredentialsConfiguration.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/CredentialsConfiguration.java @@ -10,7 +10,7 @@ import javax.xml.bind.annotation.XmlRootElement; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ @XmlRootElement(name = "credentials-config") public class CredentialsConfiguration { @@ -20,7 +20,7 @@ public class CredentialsConfiguration { private List credentialsInfo; public CredentialsConfiguration() { - credentialsInfo = new ArrayList(); + credentialsInfo = new ArrayList<>(); } public void addCredentials(Credentials credentials) { diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/CredentialsConfigurationBean.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/CredentialsConfigurationBean.java deleted file mode 100644 index 85c34a6475031a31393967a03ba70582e3945cc9..0000000000000000000000000000000000000000 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/CredentialsConfigurationBean.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package it.inaf.oats.ia2.tapschemamanager.businesslayer; - -/** - * - * @author Sonia Zorba - */ -public class CredentialsConfigurationBean { - -} diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/EntityWrapper.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/EntityWrapper.java index c70b65a021deea7422e91820e7b08120d786bab3..139758ffb729e7433ce46622762e2508bc936abf 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/EntityWrapper.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/EntityWrapper.java @@ -9,7 +9,7 @@ import java.util.Map; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } * @param */ public abstract class EntityWrapper implements Serializable { @@ -23,8 +23,8 @@ public abstract class EntityWrapper implements Serial private Status status; public EntityWrapper(T entity, String... supportedKeys) { - originalValues = new HashMap(); - editedValues = new HashMap(); + originalValues = new HashMap<>(); + editedValues = new HashMap<>(); this.entity = entity; this.supportedKeys = Arrays.asList(supportedKeys); } @@ -48,7 +48,7 @@ public abstract class EntityWrapper implements Serial protected abstract void afterSetValue(String key, String value); public final void setValue(String key, String value) { - if (originalValues.get(key) == null && value.equals("")) { + if (originalValues.get(key) == null && value.isEmpty()) { value = null; } editedValues.put(key, value); diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/EntityWrapperContainer.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/EntityWrapperContainer.java index c088ee55edf95db5f20c3cb962ed24ff2b28c6c2..c191fe50d03e4c1a3c0296f6cd02b3514f9c1121 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/EntityWrapperContainer.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/EntityWrapperContainer.java @@ -5,7 +5,7 @@ import java.util.List; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } * @param */ public interface EntityWrapperContainer { diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/ParsedUCD.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/ParsedUCD.java new file mode 100644 index 0000000000000000000000000000000000000000..62dc9e40643e358eaa5fa71e322738929f958700 --- /dev/null +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/ParsedUCD.java @@ -0,0 +1,80 @@ +package it.inaf.oats.ia2.tapschemamanager.businesslayer; + +import ari.ucd.UCD; +import ari.ucd.UCDParser; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Serializable wrapper for the ari.ucd.UCD class. Contains only a subset of the + * original properties. + * + * @author Sonia Zorba {@literal } + */ +public class ParsedUCD implements Serializable { + + private static final long serialVersionUID = 527435700858258310L; + + private final boolean valid; + private final boolean recognised; + private final boolean recommended; + private final List errors; + private final List advices; + private final String suggestedUCD; + + public ParsedUCD(UCD parsedUCD) { + valid = parsedUCD.isFullyValid(); + recognised = parsedUCD.isAllRecognised(); + recommended = parsedUCD.isAllRecommended(); + + errors = new ArrayList<>(); + Iterator errorIte = parsedUCD.getErrors(); + while (errorIte.hasNext()) { + errors.add(errorIte.next()); + } + + advices = new ArrayList<>(); + Iterator adviceIte = parsedUCD.getAdvice(); + while (adviceIte.hasNext()) { + advices.add(adviceIte.next()); + } + + UCD suggested = parsedUCD.getSuggestion(); + String suggestionString = suggested == null ? null : suggested.toString(); + if (suggestionString != null && !suggestionString.isEmpty() && !suggestionString.equals(parsedUCD.toString())) { + suggestedUCD = suggestionString; + } else { + suggestedUCD = null; + } + } + + public ParsedUCD(String ucdText) { + this(UCDParser.parseUCD(ucdText)); + } + + public boolean isValid() { + return valid; + } + + public boolean isRecognised() { + return recognised; + } + + public boolean isRecommended() { + return recommended; + } + + public List getErrors() { + return errors; + } + + public List getAdvices() { + return advices; + } + + public String getSuggestedUCD() { + return suggestedUCD; + } +} diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Schema.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Schema.java index f8836ca0bdaf4f5cf103199ea091df15a2effcbc..996227fd433c3b96c427e01740c8942504b24b52 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Schema.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Schema.java @@ -13,7 +13,7 @@ import java.util.TreeMap; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public class Schema extends EntityWrapper implements EntityWrapperContainer, Serializable { @@ -22,10 +22,10 @@ public class Schema extends EntityWrapper implements EntityWrapper public static final String UTYPE = "utype"; public static final String DESCRIPTION = "description"; - private TapSchemaHandler tapSchemaHandler; + private final TapSchemaHandler tapSchemaHandler; private String selectedTable; - private Map tables; + private final Map tables; public Schema(TapSchemaHandler tapSchemaHandler, SchemaEntity schemaEntity) throws SQLException { super(schemaEntity, UTYPE, DESCRIPTION); @@ -35,7 +35,7 @@ public class Schema extends EntityWrapper implements EntityWrapper addValue(UTYPE, schemaEntity.getUtype()); addValue(DESCRIPTION, schemaEntity.getDescription()); - tables = new TreeMap(String.CASE_INSENSITIVE_ORDER); + tables = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); for (TableEntity tableEntity : schemaEntity.getTables()) { String tableName = tableEntity.getShortTableName(); @@ -48,10 +48,13 @@ public class Schema extends EntityWrapper implements EntityWrapper @Override protected void afterSetValue(String key, String value) { SchemaEntity schemaEntity = getEntity(); - if (key.equals(UTYPE)) { - schemaEntity.setUtype(value); - } else if (key.equals(DESCRIPTION)) { - schemaEntity.setDescription(value); + switch (key) { + case UTYPE: + schemaEntity.setUtype(value); + break; + case DESCRIPTION: + schemaEntity.setDescription(value); + break; } } diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/SearchUCD.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/SearchUCD.java index 16e16ae2b045e7242f3ade0b528ef5ecf5a8c933..076472e1b4f348d95cc5c7f1b059bc9ad9c858cb 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/SearchUCD.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/SearchUCD.java @@ -18,7 +18,7 @@ import javax.naming.NamingException; * Collection of static methods for accessing to the UCD REST service and * validating custom UCD. * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public class SearchUCD { @@ -113,7 +113,7 @@ public class SearchUCD { int responseCodeSuggest = connectionSuggest.getResponseCode(); if (responseCodeSuggest == 200) { - List resultList = new ArrayList(); + List resultList = new ArrayList<>(); BufferedReader br = new BufferedReader(new InputStreamReader(connectionSuggest.getInputStream())); String line; diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/SeparateCredentials.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/SeparateCredentials.java index 4b63ca2d1ded6eb55043ebcd2b642d64922b34ec..74f16c7f9fbd47964aa6942eddc36b0483269df7 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/SeparateCredentials.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/SeparateCredentials.java @@ -5,7 +5,7 @@ import javax.xml.bind.annotation.XmlElement; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public class SeparateCredentials { @@ -37,5 +37,4 @@ public class SeparateCredentials { public void setTapSchemaCredentials(Credentials tapSchemaCredentials) { this.tapSchemaCredentials = tapSchemaCredentials; } - } diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Status.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Status.java index 509a0b849a29345dad3cb4571cadc199af4e77db..e04e7a6fddc76e22ebf2e2092c7f4ce515b5a7cd 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Status.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Status.java @@ -2,7 +2,7 @@ package it.inaf.oats.ia2.tapschemamanager.businesslayer; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public enum Status { ADDED_PERSISTED, diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Table.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Table.java index 1be645281d2befa4d0bd1f5b5cfd9d2827813edd..3fcf9e68e789504d374a267889dc0877ed80c065 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Table.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Table.java @@ -1,7 +1,6 @@ package it.inaf.oats.ia2.tapschemamanager.businesslayer; import it.inaf.oats.ia2.tapschemamanager.datalayer.ColumnEntity; -import it.inaf.oats.ia2.tapschemamanager.datalayer.ColumnInfo; import it.inaf.oats.ia2.tapschemamanager.datalayer.DLUtil; import it.inaf.oats.ia2.tapschemamanager.datalayer.TableEntity; import it.inaf.oats.ia2.tapschemamanager.datalayer.TapSchemaHandler; @@ -14,7 +13,7 @@ import java.util.TreeMap; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public class Table extends EntityWrapper implements EntityWrapperContainer, Serializable { @@ -41,11 +40,10 @@ public class Table extends EntityWrapper implements EntityWrapperCo this.tableName = tableName; // Load all ColumnEntity map - columns = new TreeMap(String.CASE_INSENSITIVE_ORDER); + columns = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); List alreadyLoadedColumns = DLUtil.getEntitiesNames(tableEntity.getColumns()); - for (ColumnInfo columnInfo : tapSchemaHandler.getColumnInfo(schemaName, tableName)) { - ColumnEntity columnEntity = columnInfo.getColumnEntity(); - Column column = new Column(tapSchemaHandler, columnEntity, columnInfo.isPrimaryKey()); + for (ColumnEntity columnEntity : tapSchemaHandler.getColumnEntities(schemaName, tableName)) { + Column column = new Column(tapSchemaHandler, columnEntity); columns.put(columnEntity.getName(), column); if (alreadyLoadedColumns.contains(columnEntity.getName())) { @@ -68,16 +66,19 @@ public class Table extends EntityWrapper implements EntityWrapperCo @Override protected void afterSetValue(String key, String value) { TableEntity tableEntity = getEntity(); - if (key.equals(UTYPE)) { - tableEntity.setUtype(value); - } else if (key.equals(DESCRIPTION)) { - tableEntity.setDescription(value); + switch (key) { + case UTYPE: + tableEntity.setUtype(value); + break; + case DESCRIPTION: + tableEntity.setDescription(value); + break; } } @Override public List getAddables() { - List addables = new ArrayList(); + List addables = new ArrayList<>(); for (Column column : columns.values()) { if (column.isHidden()) { addables.add(column.getName()); @@ -148,7 +149,7 @@ public class Table extends EntityWrapper implements EntityWrapperCo @Override public List getEntitiesNames() { - List columnsNames = new ArrayList(); + List columnsNames = new ArrayList<>(); for (Column column : columns.values()) { if (!column.isHidden()) { columnsNames.add(column.getName()); @@ -181,7 +182,7 @@ public class Table extends EntityWrapper implements EntityWrapperCo @Override public List getAllEntityWrappers() { - List list = new ArrayList(); + List list = new ArrayList<>(); for (Column column : columns.values()) { if (!column.isHidden()) { list.add(column); diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/TapSchema.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/TapSchema.java index fd215a320ce73ea0b2b0443c0cd971434b594ccd..eff528ce9fb8934d1744eb3ada66cfe9d73a3814 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/TapSchema.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/TapSchema.java @@ -1,6 +1,5 @@ package it.inaf.oats.ia2.tapschemamanager.businesslayer; -import it.inaf.oats.ia2.tapschemamanager.datalayer.Credentials; import it.inaf.oats.ia2.tapschemamanager.datalayer.DBWrapper; import it.inaf.oats.ia2.tapschemamanager.datalayer.SchemaEntity; import it.inaf.oats.ia2.tapschemamanager.datalayer.TapSchemaHandler; @@ -14,7 +13,7 @@ import java.util.TreeMap; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public class TapSchema implements EntityWrapperContainer, Serializable { @@ -29,7 +28,7 @@ public class TapSchema implements EntityWrapperContainer, Serializable { public TapSchema(DBWrapper dbWrapper, String tapSchemaName, boolean exists) throws SQLException { this.name = tapSchemaName; - schemas = new TreeMap(String.CASE_INSENSITIVE_ORDER); + schemas = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); this.tapSchemaHandler = new TapSchemaHandler(dbWrapper, tapSchemaName, exists); diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/UCDInfo.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/UCDInfo.java index 62f27aa54ad22014d28fab2c19671ce29606d73c..ed6a7e221e8a9120668521009b3501f047e4c242 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/UCDInfo.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/UCDInfo.java @@ -4,7 +4,7 @@ import java.io.Serializable; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public class UCDInfo implements Serializable { diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/UCDServiceException.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/UCDServiceException.java index 51d450ee9bed499e62c80f96f8c501d614ace32c..daf9f54a501c42e44c5b4ca39908df64d72e8658 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/UCDServiceException.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/UCDServiceException.java @@ -2,7 +2,7 @@ package it.inaf.oats.ia2.tapschemamanager.businesslayer; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public class UCDServiceException extends Exception { diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Util.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Util.java index 5b43c186fbb9434fbc7f687b54d326297d75e9cd..446a9e0bccd1965e47c1c34f33f0b7e0251ad3fd 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Util.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/businesslayer/Util.java @@ -6,12 +6,12 @@ import java.util.Set; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ class Util { protected static List getAddables(List allElements, Set addedElements) { - List addables = new ArrayList(); + List addables = new ArrayList<>(); for (String elementName : allElements) { if (!addedElements.contains(elementName)) { addables.add(elementName); @@ -21,7 +21,7 @@ class Util { } protected static List setToList(Set set) { - List list = new ArrayList(); + List list = new ArrayList<>(); list.addAll(set); return list; } diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CredentialsBean.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CredentialsBean.java index 61deb73f3487f45861102f044c80adc4b42b50cb..7b674f10ee8d293402bc3cf9825d8458bda9eeb7 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CredentialsBean.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CredentialsBean.java @@ -20,7 +20,7 @@ import org.slf4j.LoggerFactory; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ @Named("credentialsInsertion") @SessionScoped diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CredentialsConfigurationBean.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CredentialsConfigurationBean.java index 2a019e6d787979450acfcd622cd84e2844facf91..8a8463272a31f85be8bb5e8277db03fff1315162 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CredentialsConfigurationBean.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CredentialsConfigurationBean.java @@ -14,7 +14,7 @@ import org.slf4j.LoggerFactory; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ @ApplicationScoped public class CredentialsConfigurationBean { diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CustomPartialResponseWriter.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CustomPartialResponseWriter.java index f691edaad4ce7685ec87e898cb7afedbea51c650..e06c3b0d0dc9b5dca3dbbad94a76c37992eaca82 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CustomPartialResponseWriter.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CustomPartialResponseWriter.java @@ -13,7 +13,7 @@ import javax.faces.context.ResponseWriter; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public class CustomPartialResponseWriter extends PartialResponseWriter { diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CustomPartialViewContextFactory.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CustomPartialViewContextFactory.java index c56032f801e0855615743cde7055fea92a00c3ed..33ff63e92fa3ddc907c8fa9e4614f9fd5a332562 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CustomPartialViewContextFactory.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CustomPartialViewContextFactory.java @@ -6,7 +6,7 @@ import javax.faces.context.PartialViewContextFactory; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public class CustomPartialViewContextFactory extends PartialViewContextFactory { diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CustomPartialViewContextWrapper.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CustomPartialViewContextWrapper.java index c0f163cbb7c62899a8cf5dc4d2d6010a765793b4..8c3ca400a695a35a30e322b6819386ba8999be4e 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CustomPartialViewContextWrapper.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/CustomPartialViewContextWrapper.java @@ -6,7 +6,7 @@ import javax.faces.context.PartialViewContextWrapper; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public class CustomPartialViewContextWrapper extends PartialViewContextWrapper { diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/JSUpdateHandler.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/JSUpdateHandler.java index c31a0e1e16fd318972811aef864bd32738876bd2..707dd6748a1fa31f422228c7e4caf6bec5d5e71d 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/JSUpdateHandler.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/JSUpdateHandler.java @@ -2,7 +2,7 @@ package it.inaf.oats.ia2.tapschemamanager.webapp; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public abstract class JSUpdateHandler { diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/SchemaSelectionBean.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/SchemaSelectionBean.java index be9efb56620f593204055433c2f3d28ab46119f0..a30e6e85331af37a2623ca612a39bdd191ed02d8 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/SchemaSelectionBean.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/SchemaSelectionBean.java @@ -2,7 +2,7 @@ package it.inaf.oats.ia2.tapschemamanager.webapp; import it.inaf.oats.ia2.tapschemamanager.businesslayer.TapSchema; import it.inaf.oats.ia2.tapschemamanager.datalayer.DBWrapper; -import it.inaf.oats.ia2.tapschemamanager.datalayer.DataProvider; +import it.inaf.oats.ia2.tapschemamanager.datalayer.Dao; import java.io.Serializable; import java.sql.SQLException; import java.util.ArrayList; @@ -21,7 +21,7 @@ import org.slf4j.LoggerFactory; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ @Named("schemaSelection") @ConversationScoped @@ -67,7 +67,7 @@ public class SchemaSelectionBean implements Serializable { // Loading all schemas of the source database try { - allSchemas = DataProvider.getAllSchemasNames(dbWrapper.getSourceDataSource(), dbWrapper.getSourceDatabaseType()); + allSchemas = Dao.getAllSchemasNames(dbWrapper.getSourceDataSource(), dbWrapper.getSourceDatabaseType()); setSelectedSchemas(new ArrayList()); } catch (SQLException e) { throw new RuntimeException(e); @@ -75,8 +75,7 @@ public class SchemaSelectionBean implements Serializable { // Loading all schemas of the TAP_SCHEMA database try { - allTAPSchemas = DataProvider.getAllTAPSchemasNames( - dbWrapper, DataProvider.getAllSchemasNames(dbWrapper.getTapSchemaDataSource(), dbWrapper.getTapSchemaDatabaseType())); + allTAPSchemas = Dao.getAllTAPSchemasNames(dbWrapper, Dao.getAllSchemasNames(dbWrapper.getTapSchemaDataSource(), dbWrapper.getTapSchemaDatabaseType())); if (!allTAPSchemas.isEmpty()) { this.selectedTAPSchema = allTAPSchemas.get(0); @@ -89,7 +88,7 @@ public class SchemaSelectionBean implements Serializable { } private void loadExposedSchemas() throws SQLException { - List schemas = DataProvider.getExposedSchemas(dbWrapper, selectedTAPSchema); + List schemas = Dao.getExposedSchemas(dbWrapper, selectedTAPSchema); exposedSchemas = ""; for (int i = 0; i < schemas.size(); i++) { exposedSchemas += schemas.get(i); diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/SearchUCDDialog.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/SearchUCDDialog.java index d53308b5c0e02d1ecead28c828308b78b29987b6..bdffb9dcbffa7281b04a161fd114230e8b69a948 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/SearchUCDDialog.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/SearchUCDDialog.java @@ -1,5 +1,6 @@ package it.inaf.oats.ia2.tapschemamanager.webapp; +import it.inaf.oats.ia2.tapschemamanager.businesslayer.ParsedUCD; import it.inaf.oats.ia2.tapschemamanager.businesslayer.SearchUCD; import it.inaf.oats.ia2.tapschemamanager.businesslayer.UCDInfo; import it.inaf.oats.ia2.tapschemamanager.businesslayer.UCDServiceException; @@ -14,7 +15,7 @@ import javax.faces.validator.ValidatorException; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ @Dependent public class SearchUCDDialog implements Serializable { @@ -32,8 +33,11 @@ public class SearchUCDDialog implements Serializable { private String suggestedUCD; private List suggestedUCDs; + private ParsedUCD parsedUCD; + private String UCDValidationMessage; + public SearchUCDDialog() { - suggestedUCDs = new ArrayList(); + suggestedUCDs = new ArrayList<>(); } public String getDescription() { @@ -60,15 +64,16 @@ public class SearchUCDDialog implements Serializable { return suggestedUCDs; } - public void setDefault() { + public void setDefault() { UCDManualText = null; - + parsedUCD = null; + description = null; UCDnotFound = false; selectedUCD = null; suggestedUCD = null; suggestedUCDs.clear(); - + UCDServiceErrorMessage = null; } @@ -95,7 +100,7 @@ public class SearchUCDDialog implements Serializable { setUCDServiceErrorMessage(e); } } - + public void selectUCD(String selectedUCD) { this.selectedUCD = selectedUCD; } @@ -133,25 +138,11 @@ public class SearchUCDDialog implements Serializable { this.UCDManualText = UCDManualText; } - public void validateManualUCD(FacesContext context, UIComponent inputComponent, Object value) { - String textValue = (String) value; - - String validatorMessage = null; - if (textValue == null || textValue.isEmpty()) { - validatorMessage = "UCD can't be null"; + public void validateManualUCD() { + if (UCDManualText == null || UCDManualText.isEmpty()) { + UCDValidationMessage = "UCD can't be null"; } else { - try { - if (!SearchUCD.validateManualUCD(textValue)) { - validatorMessage = "Invalid UCD!"; - } - } catch (UCDServiceException e) { - setUCDServiceErrorMessage(e); - FacesContext.getCurrentInstance().validationFailed(); - } - } - - if (validatorMessage != null) { - throw new ValidatorException(new FacesMessage(validatorMessage)); + parsedUCD = new ParsedUCD(UCDManualText); } } @@ -162,4 +153,12 @@ public class SearchUCDDialog implements Serializable { public String getNamespaceRegExp() { return SearchUCD.REG_EXP_START_WITH_NAMESPACE; } + + public String getUCDValidationMessage() { + return UCDValidationMessage; + } + + public ParsedUCD getParsedUCD() { + return parsedUCD; + } } diff --git a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/TapSchemaEditingBean.java b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/TapSchemaEditingBean.java index cd197e56ccd14c6b87b7c281ba4139e68a584964..3d38fd3a790a4fdb2b655d71435b259dadd3fbbd 100644 --- a/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/TapSchemaEditingBean.java +++ b/TapSchemaManager/src/main/java/it/inaf/oats/ia2/tapschemamanager/webapp/TapSchemaEditingBean.java @@ -21,7 +21,7 @@ import javax.json.JsonObjectBuilder; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ @Named("tapSchemaEditing") @ConversationScoped diff --git a/TapSchemaManager/src/main/webapp/resources/js/edit-tapschema.js b/TapSchemaManager/src/main/webapp/resources/js/edit-tapschema.js index d6f3e4a814c3be751bf49abbdd15f15f921b4574..85d52059b39825698f6c5f5785be410fdb997a08 100644 --- a/TapSchemaManager/src/main/webapp/resources/js/edit-tapschema.js +++ b/TapSchemaManager/src/main/webapp/resources/js/edit-tapschema.js @@ -43,18 +43,18 @@ initUCDValidator: function (UCDRegExpStr) { UCDRegExp = new RegExp(UCDRegExpStr); }, - validateManualUCD: function (event) { - $clientValidationMessage = $('#ucd_search_form\\:ucd_validation_result'); - - var valid = UCDRegExp.test(event.target.value); - if (valid) { - $clientValidationMessage.empty(); - } else { - $clientValidationMessage.text('Invalid UCD!'); - } - - $('#ucd_search_form\\:save_ucd').prop('disabled', !valid); - }, +// validateManualUCD: function (event) { +// $clientValidationMessage = $('#ucd_search_form\\:ucd_validation_result'); +// +// var valid = UCDRegExp.test(event.target.value); +// if (valid) { +// $clientValidationMessage.empty(); +// } else { +// $clientValidationMessage.text('Invalid UCD!'); +// } +// +// $('#ucd_search_form\\:save_ucd').prop('disabled', !valid); +// }, saveUCDCalled: eventHandlerFactory(function (srcElement, jsupdate) { if (jsupdate !== null) { $('#searchUCDModal').modal('hide'); diff --git a/TapSchemaManager/src/main/webapp/tapSchemaEditing.xhtml b/TapSchemaManager/src/main/webapp/tapSchemaEditing.xhtml index df89375e736b1516ffc2af82890e68862d2133a3..461f3f253e0ac8c231665bc46de89b0b2f467869 100644 --- a/TapSchemaManager/src/main/webapp/tapSchemaEditing.xhtml +++ b/TapSchemaManager/src/main/webapp/tapSchemaEditing.xhtml @@ -399,9 +399,70 @@
UCD: - - - + + + + +
+ + + + + + + + + + + + + + +
Valid:Recognized:Recommended:
+ + + + + + + + + + + + + + + + + + + + +
+ + + + Suggested UCD: ${UCDDialog.parsedUCD.suggestedUCD} + + +
Advices:
+
    + +
  • ${advice}
  • +
    +
+
+ + +
Errors:
+
    + +
  • ${error}
  • +
    +
+
+
@@ -470,7 +531,7 @@ - + diff --git a/TapSchemaManager/src/test/java/TapSchemaMangerTest.java b/TapSchemaManager/src/test/java/TapSchemaMangerTest.java index dcd087f3aa9a78d51321142351d2e44fceea237b..b8c29f58c14835147298cbe5d741d7a1935cd5d3 100644 --- a/TapSchemaManager/src/test/java/TapSchemaMangerTest.java +++ b/TapSchemaManager/src/test/java/TapSchemaMangerTest.java @@ -17,7 +17,7 @@ import org.junit.Ignore; /** * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public class TapSchemaMangerTest { diff --git a/TapSchemaManagerDL/pom.xml b/TapSchemaManagerDL/pom.xml index ead9297f1ba8920b795b1c0236185d0d76a475eb..e070e57707d43c542ef2f5b023b4dc73909cdac0 100644 --- a/TapSchemaManagerDL/pom.xml +++ b/TapSchemaManagerDL/pom.xml @@ -15,7 +15,7 @@ org.eclipse.persistence eclipselink 2.6.2 - + mysql mysql-connector-java @@ -41,19 +41,14 @@ - + \ No newline at end of file diff --git a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/ColumnEntity.java b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/ColumnEntity.java index 0f3cddda6f3813da8825675feb881610fead43a2..d4273b8e97a4ad16c39a61fe334e247f6a13e574 100644 --- a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/ColumnEntity.java +++ b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/ColumnEntity.java @@ -20,8 +20,9 @@ class ColumnId implements Serializable { } /** + * JPA entity for the table TAP_SCHEMA.columns. * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ @Entity @IdClass(ColumnId.class) @@ -71,10 +72,12 @@ public class ColumnEntity implements Serializable, TapSchemaEntity { @Column(name = "columnID") private BigInteger columnID; - + @Column(name = "id") private int id; + private boolean primaryKey; + protected ColumnEntity() { } @@ -83,6 +86,10 @@ public class ColumnEntity implements Serializable, TapSchemaEntity { this.name = columnName; } + /** + * The complete table name: + * <schema-name>.<table-name>. + */ public String getFullTableName() { return fullTableName; } @@ -91,6 +98,9 @@ public class ColumnEntity implements Serializable, TapSchemaEntity { this.fullTableName = fullTableName; } + /** + * The value in the column_name column. + */ @Override public String getName() { return name; @@ -100,6 +110,9 @@ public class ColumnEntity implements Serializable, TapSchemaEntity { this.name = columnName; } + /** + * The value in the utype column. + */ public String getUtype() { return utype; } @@ -108,6 +121,10 @@ public class ColumnEntity implements Serializable, TapSchemaEntity { this.utype = utype; } + /** + * The value in the ucd column: represents the Unified Content + * Descriptor of the column. + */ public String getUcd() { return ucd; } @@ -116,6 +133,9 @@ public class ColumnEntity implements Serializable, TapSchemaEntity { this.ucd = ucd; } + /** + * The value in the unit column. + */ public String getUnit() { return unit; } @@ -124,6 +144,9 @@ public class ColumnEntity implements Serializable, TapSchemaEntity { this.unit = unit; } + /** + * The value in the description column. + */ public String getDescription() { return description; } @@ -132,6 +155,9 @@ public class ColumnEntity implements Serializable, TapSchemaEntity { this.description = description; } + /** + * The value in the datatype column. + */ public String getDatatype() { return datatype; } @@ -140,6 +166,9 @@ public class ColumnEntity implements Serializable, TapSchemaEntity { this.datatype = datatype; } + /** + * The value in the size column. + */ public int getSize() { return size; } @@ -148,6 +177,11 @@ public class ColumnEntity implements Serializable, TapSchemaEntity { this.size = size; } + /** + * The value in the principal column: indicates that the column + * is considered a core part the content.
It is an integer but should be + * treated as a boolean value. + */ public int getPrincipal() { return principal; } @@ -156,6 +190,11 @@ public class ColumnEntity implements Serializable, TapSchemaEntity { this.principal = principal; } + /** + * The value in the indexed column: indicates that the column + * is indexed.
It is an integer but should be treated as a boolean + * value. + */ public int getIndexed() { return indexed; } @@ -164,6 +203,11 @@ public class ColumnEntity implements Serializable, TapSchemaEntity { this.indexed = indexed; } + /** + * The value in the std column: indicates that the column is + * defined by some standard.
It is an integer but should be treated as a + * boolean value. + */ public int getStd() { return std; } @@ -172,6 +216,9 @@ public class ColumnEntity implements Serializable, TapSchemaEntity { this.std = std; } + /** + * The value in the columnID column: it represents [TODO]... + */ protected BigInteger getColumnID() { return columnID; } @@ -180,6 +227,9 @@ public class ColumnEntity implements Serializable, TapSchemaEntity { this.columnID = columnID; } + /** + * The {@link TableEntity} that owns this ColumnEntity. + */ public TableEntity getTable() { return table; } @@ -195,4 +245,17 @@ public class ColumnEntity implements Serializable, TapSchemaEntity { public void setId(int id) { this.id = id; } + + /** + * Indicates if the column is a primary key (or a part of a primary key). + * This information is not stored into the TAP_SCHEMA, so it will be + * reloaded from the source schema each time. + */ + public boolean isPrimaryKey() { + return primaryKey; + } + + public void setPrimaryKey(boolean primaryKey) { + this.primaryKey = primaryKey; + } } diff --git a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/ColumnInfo.java b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/ColumnInfo.java deleted file mode 100644 index 6c263b1a93319b11c8eecb444e70f043267b8558..0000000000000000000000000000000000000000 --- a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/ColumnInfo.java +++ /dev/null @@ -1,31 +0,0 @@ -package it.inaf.oats.ia2.tapschemamanager.datalayer; - -import java.io.Serializable; - -/** - * - * @author Sonia Zorba - */ -public class ColumnInfo implements Serializable { - - private static final long serialVersionUID = 2139630525057375743L; - - private boolean primaryKey; - private final ColumnEntity columnEntity; - - public ColumnInfo(ColumnEntity columnEntity) { - this.columnEntity = columnEntity; - } - - public boolean isPrimaryKey() { - return primaryKey; - } - - public void setPrimaryKey(boolean primaryKey) { - this.primaryKey = primaryKey; - } - - public ColumnEntity getColumnEntity() { - return columnEntity; - } -} diff --git a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/Credentials.java b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/Credentials.java index 430d0854a7cd5493af3400de91fab28515ec9d45..8dd6fce4ca96ff33768aeecdd434e137295cb3d4 100644 --- a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/Credentials.java +++ b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/Credentials.java @@ -1,16 +1,15 @@ package it.inaf.oats.ia2.tapschemamanager.datalayer; import java.io.Serializable; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; import javax.xml.bind.annotation.XmlAttribute; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** + * Representation of credentials used to connect to a RDBMS. It can be + * serialized in XML using the JAXB standard. * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public class Credentials implements Serializable { @@ -34,6 +33,9 @@ public class Credentials implements Serializable { this.setDefaults(); } + /** + * The name of the server that hosts the RDBMS. + */ @XmlAttribute(name = "hostname", required = true) public String getHostname() { return this.hostname; @@ -43,6 +45,9 @@ public class Credentials implements Serializable { this.hostname = hostname; } + /** + * The RDBMS port number. + */ @XmlAttribute(name = "port", required = true) public int getPort() { return this.port; @@ -70,6 +75,9 @@ public class Credentials implements Serializable { this.password = password; } + /** + * The kind of RDBMS used. + */ @XmlAttribute(name = "database-type", required = true) public DatabaseType getDatabaseType() { return databaseType; @@ -80,7 +88,8 @@ public class Credentials implements Serializable { } /** - * Only for POSTGRES + * Only for POSTGRES. The database to use in the + * connection. The default value is "postgres". */ @XmlAttribute(name = "database") public String getDatabase() { @@ -88,12 +97,17 @@ public class Credentials implements Serializable { } /** - * Only for POSTGRES + * Only for POSTGRES. The database to use in the + * connection. */ public void setDatabase(String database) { this.database = database; } + /** + * Set default values for databaseType, database + * and port properties. + */ public final void setDefaults() { if (databaseType == DatabaseType.MYSQL) { this.port = 3306; @@ -104,6 +118,9 @@ public class Credentials implements Serializable { } } + /** + * The class name of the RDBMS driver. + */ public String getDatabaseDriverClass() { switch (getDatabaseType()) { case MYSQL: @@ -113,16 +130,4 @@ public class Credentials implements Serializable { } return null; } - - public Connection getConnection() throws SQLException { - try { - Class.forName(getDatabaseDriverClass()); - } catch (ClassNotFoundException e) { - e.printStackTrace(System.err); - } - - String connectionString = "jdbc:mysql://" + this.hostname + ":" + this.port + "/"; - log.debug("Connecting to {} with username '{}'", connectionString, this.username); - return DriverManager.getConnection(connectionString, this.username, this.password); - } } diff --git a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/DBWrapper.java b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/DBWrapper.java index 112cb7e9802a9edda78f5cee82ad0d2c9a0f7ba0..2bf4617ed5c37a59db358985d26bff3d11997e04 100644 --- a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/DBWrapper.java +++ b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/DBWrapper.java @@ -8,8 +8,15 @@ import javax.sql.DataSource; import org.postgresql.ds.PGPoolingDataSource; /** + * This class is used to silently manage the possibility to have separate data + * sources for the TAP_SCHEMA schema and it source schema (the schema from which + * it takes the information).
+ * An API user asks, for example, {@link getSourceDataSource()}, and the + * DBWrapper returns the correct DataSource, both if + * it is separated from the TAP_SCHEMA DataSource or if they are + * the same object. * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public class DBWrapper implements Serializable { @@ -85,6 +92,13 @@ public class DBWrapper implements Serializable { return getTapSchemaCredentials().getDatabaseType(); } + /** + * Test both the connection to the TAP_SCHEMA DataSource and + * its source DataSource. + * + * @throws SQLException if it is not possible to connect to the + * DataSource. + */ public void testConnections() throws SQLException { Connection connection; if (credentials != null) { @@ -98,6 +112,10 @@ public class DBWrapper implements Serializable { } } + /** + * @return true if the TAP_SCHEMA DataSource is different from + * its source DataSource, false otherwise. + */ public boolean isSeparatedSources() { return dataSources.isSeparatedSources(); } diff --git a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/DLUtil.java b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/DLUtil.java index 5e3e6a4e5d8f9ac46b981a3a1ae4d388ec13d961..7b10388a8f46160cd1cdb6ad15fbed60019da706 100644 --- a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/DLUtil.java +++ b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/DLUtil.java @@ -1,15 +1,21 @@ package it.inaf.oats.ia2.tapschemamanager.datalayer; import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.List; /** + * Utility class that contains some static methods to manage various operations + * with the TAP_SCHEMA entities. * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public class DLUtil { + /** + * Retrieve a TapSchemaEntity from a list searching it by name. + */ public static T getEntityByName(List entities, String name) { for (T entity : entities) { if (entity.getName().equals(name)) { @@ -19,33 +25,29 @@ public class DLUtil { return null; } + /** + * Given a list of TapSchemaEntity objects returns a list + * containing their names. + * + * @return list of entities names alphabetically and case insensitively + * ordered. + */ public static List getEntitiesNames(List entities) { - List entitiesNames = new ArrayList(); + List entitiesNames = new ArrayList<>(); for (T entity : entities) { entitiesNames.add(entity.getName()); } + Collections.sort(entitiesNames, String.CASE_INSENSITIVE_ORDER); return entitiesNames; } /** - * Lists are already ordered because the JPA relations are created specifying @OrderBy, - * so when you need to add an entity you should insert it in order. - * - * @param - * @param entities - * @param newEntity + * Remove an entity from a list of TapSchemaEntity searching it + * by name. + * + * This method is protected because this operation should be performed by + * the entity that contains the list. */ - protected static void insertEntityInOrder(List entities, T newEntity) { - int i = 0; - for (T entity : entities) { - if (entity.getName().compareTo(newEntity.getName()) > 0) { - break; - } - i++; - } - entities.add(i, newEntity); - } - protected static void removeEntity(List entities, String entityName) { Iterator iterator = entities.iterator(); while (iterator.hasNext()) { @@ -63,6 +65,11 @@ public class DLUtil { columnEntity.setStd(1); } + /** + * Fill descriptions of the TAP_SCHEMA schema entities. + * + * @param schema the TAP_SCHEMA schema SchemaEntity. + */ protected static void putInfoIntoTapSchemaSchema(SchemaEntity schema) { schema.setDescription("a special schema to describe a TAP tableset"); diff --git a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/DataProvider.java b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/Dao.java similarity index 59% rename from TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/DataProvider.java rename to TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/Dao.java index 408dd4fe74f123d6434f49a2f3289758b5501a84..1f1a74a67817f30451adb66621b5cbcf4fe8eba3 100644 --- a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/DataProvider.java +++ b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/Dao.java @@ -5,20 +5,42 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.regex.Pattern; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.sql.DataSource; +import org.postgresql.ds.PGPoolingDataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** + * Utility class that contains static methods for interacting with databases. + * All the specific SQL clauses of the application are encapsulated in this + * class. All the other datalayer operations are performed using the JPA. * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ -public class DataProvider { +public class Dao { + private static final Logger log = LoggerFactory.getLogger(Dao.class); + + private static List sortStringsList(List list) { + Collections.sort(list, String.CASE_INSENSITIVE_ORDER); + return list; + } + + /** + * Retrieve the list of the names of the all the schemas contained into the + * database specified by the DataSource parameter. + * + * @return list of schemas names alphabetically and case insensitively + * ordered. + */ public static List getAllSchemasNames(DataSource dataSource, DatabaseType dbType) throws SQLException { String query; @@ -30,6 +52,8 @@ public class DataProvider { throw new UnsupportedOperationException("Database type " + dbType + " not supported"); } + log.debug("Executing query {}", query); + List allSchemas = new ArrayList<>(); try (Connection connection = dataSource.getConnection(); @@ -40,9 +64,29 @@ public class DataProvider { } } - return allSchemas; + log.debug("{} schemas found", allSchemas.size()); + + return sortStringsList(allSchemas); + } + + public static List getAllTAPSchemasNames(DBWrapper dbs) throws SQLException { + List allSchemas = getAllSchemasNames(dbs.getTapSchemaDataSource(), dbs.getTapSchemaDatabaseType()); + return getAllTAPSchemasNames(dbs, allSchemas); } + /** + * Retrieve the list of all TAP_SCHEMA schemas names contained in the + * TAP_SCHEMA DataSource.
+ * TAP_SCHEMA schemas are selected simply checking if they contains the + * TAP_SCHEMA standard tables. Currently no check on columns is performed. + * + * @param allSchemas usually the TAP_SCHEMA schemas list is loaded together + * the list of all schemas, so this list is passed by parameter to avoid + * repeating the query twice. + * + * @return list of all TAP_SCHEMA schemas names alphabetically and case + * insensitively ordered. + */ public static List getAllTAPSchemasNames(DBWrapper dbs, List allSchemas) throws SQLException { List allTAPSchemas = new ArrayList<>(); @@ -66,6 +110,8 @@ public class DataProvider { throw new UnsupportedOperationException("Database type " + dbType + " not supported"); } + log.debug("Executing query {}", query); + try (Connection connection = dbs.getTapSchemaConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(query)) { @@ -100,9 +146,18 @@ public class DataProvider { } } - return allTAPSchemas; + log.debug("{} TAP_SCHEMA schemas found", allTAPSchemas.size()); + + return sortStringsList(allTAPSchemas); } + /** + * Retrieve the list of the name of the schemas exposed by the TAP_SCHEMA + * specified by the tapSchemaName parameter. + * + * @return list of exposed schemas names alphabetically and case + * insensitively ordered. + */ public static List getExposedSchemas(DBWrapper dbs, String tapSchemaName) throws SQLException { final List exposedSchemas = new ArrayList<>(); @@ -118,6 +173,8 @@ public class DataProvider { throw new UnsupportedOperationException("Database type " + dbType + " not supported"); } + log.debug("Executing query " + query); + try (Connection connection = dbs.getTapSchemaConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(query)) { @@ -130,9 +187,8 @@ public class DataProvider { } /** - * @param tapSchemaCredentials - * @param tapSchemaName - * @return JPA entity manager for given TAP_SCHEMA name and credentials + * Retrieve the JPA entity manager for given TAP_SCHEMA name and + * credentials. */ protected static EntityManager getEntityManager(Credentials tapSchemaCredentials, String tapSchemaName) { Map persistenceMap = new HashMap<>(); @@ -155,6 +211,11 @@ public class DataProvider { EntityManagerFactory managerFactory = Persistence.createEntityManagerFactory("pu", persistenceMap); + try { + Class.forName(tapSchemaCredentials.getDatabaseDriverClass()); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } EntityManager em = managerFactory.createEntityManager(); // if (dbType == DatabaseType.POSTGRES) { @@ -163,6 +224,9 @@ public class DataProvider { return em; } + /** + * Create the TAP_SCHEMA schema into the database. + */ protected static void createTapSchemaSchema(DBWrapper dbs, String tapSchemaName) throws SQLException { DatabaseType dbType = dbs.getTapSchemaDatabaseType(); @@ -180,7 +244,14 @@ public class DataProvider { } } - protected static ArrayList getAllTablesNames(DataSource dataSource, DatabaseType dbType, String schemaName) throws SQLException { + /** + * Retrieve the list of the names of all the tables contained in a schema, + * given their related DataSource and schema name. + * + * @return list of all tables names alphabetically and case insensitively + * ordered. + */ + protected static List getAllTablesNames(DataSource dataSource, DatabaseType dbType, String schemaName) throws SQLException { String query; if (dbType == DatabaseType.MYSQL) { @@ -191,7 +262,9 @@ public class DataProvider { throw new UnsupportedOperationException("Database type " + dbType + " not supported"); } - ArrayList allTables = new ArrayList<>(); + log.debug("Executing query {}", query); + + List allTables = new ArrayList<>(); try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(query)) { @@ -200,9 +273,17 @@ public class DataProvider { } } - return allTables; + return sortStringsList(allTables); } + /** + * Retrieve the association between the tables names and their types + * (table or view), given a + * DataSource and a schema name. + * + * @return a map which has the tables names as keys and the table types as + * values. + */ protected static Map getTablesTypes(DataSource dataSource, DatabaseType dbType, String schemaName) throws SQLException { final Map tablesTypes = new HashMap<>(); @@ -220,6 +301,8 @@ public class DataProvider { throw new UnsupportedOperationException("Database type " + dbType + " not supported"); } + log.debug("Executing query {}", query); + try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(query)) { @@ -234,82 +317,139 @@ public class DataProvider { } /** - * Generate list of KeyEntity for a given schema. This keys are without id! - * It has to be set when a table is added to a schema. - * - * @param sourceConnection - * @param schemaName - * @return - * @throws SQLException + * Generate list of KeyEntity for a given schema, specifying its + * DataSource and its name.
+ * IMPORTANT: this keys are without id. The id has to be + * set when a table is added to a schema. */ protected static List getSchemaKeys(DataSource dataSource, DatabaseType dbType, String schemaName) throws SQLException { - final Map schemaKeysMap = new HashMap<>(); + if (dbType == DatabaseType.MYSQL) { - String query; + Map schemaKeysMap = new HashMap<>(); + + String query = "SELECT\n" + + "c.`CONSTRAINT_NAME` AS constraint_name,\n" + + "k.`TABLE_SCHEMA` AS from_schema,\n" + + "k.`TABLE_NAME` AS from_table,\n" + + "k.`COLUMN_NAME` AS from_column,\n" + + "k.`REFERENCED_TABLE_SCHEMA` AS target_schema,\n" + + "k.`REFERENCED_TABLE_NAME` AS target_table,\n" + + "k.`REFERENCED_COLUMN_NAME` AS target_column\n" + + "FROM information_schema.TABLE_CONSTRAINTS c \n" + + "LEFT JOIN information_schema.KEY_COLUMN_USAGE k \n" + + "ON c.`CONSTRAINT_NAME` = k.`CONSTRAINT_NAME` AND c.`TABLE_SCHEMA` = k.`TABLE_SCHEMA`\n" + + "WHERE c.`CONSTRAINT_TYPE` = 'FOREIGN KEY' \n" + + "AND k.`TABLE_SCHEMA` = '" + schemaName + "' OR k.`REFERENCED_TABLE_SCHEMA` = '" + schemaName + "'"; + + try (Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(query)) { + + while (resultSet.next()) { + String constraintName = resultSet.getString("constraint_name"); + + KeyEntity key = schemaKeysMap.get(constraintName); + if (key == null) { + key = new KeyEntity( + resultSet.getString("from_schema"), + resultSet.getString("from_table"), + resultSet.getString("target_schema"), + resultSet.getString("target_table") + ); + schemaKeysMap.put(constraintName, key); + } + + KeyColumnEntity keyColumnEntity = new KeyColumnEntity(); + keyColumnEntity.setFromColumn(resultSet.getString("from_column")); + keyColumnEntity.setTargetColumn(resultSet.getString("target_column")); + } + } + + return new ArrayList<>(schemaKeysMap.values()); - if (dbType == DatabaseType.MYSQL) { - query = "SELECT k.TABLE_NAME, k.COLUMN_NAME, " - + "k.REFERENCED_TABLE_NAME, k.REFERENCED_COLUMN_NAME " - + "FROM information_schema.TABLE_CONSTRAINTS i " - + "LEFT JOIN information_schema.KEY_COLUMN_USAGE k " - + "ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME " - + "WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY' " - + "AND i.TABLE_SCHEMA = '" + schemaName + "' " - + "AND k.TABLE_SCHEMA = '" + schemaName + "'"; } else if (dbType == DatabaseType.POSTGRES) { - query = "SELECT \n" - + "conrelid::regclass AS from_table,\n" - + "confrelid::regclass AS target_table,\n" - + "c.column_name AS from_column,\n" - + "a.attname AS target_column\n" - + "FROM pg_catalog.pg_constraint r\n" - + "JOIN pg_catalog.pg_tables t ON r.conrelid = (t.schemaname || '.' || t.tablename)::regclass::oid\n" - + "JOIN information_schema.columns c ON c.table_schema = t.schemaname AND c.table_name = t.tablename AND c.ordinal_position = ANY(r.conkey)\n" - + "JOIN pg_catalog.pg_attribute a ON r.conindid = a.attrelid\n" - + "WHERE contype = 'f' AND t.schemaname = '" + schemaName + "'"; - } else { - throw new UnsupportedOperationException("Database type " + dbType + " not supported"); - } - try (Connection connection = dataSource.getConnection(); - Statement statement = connection.createStatement(); - ResultSet resultSet = statement.executeQuery(query)) { - while (resultSet.next()) { - String fromTable, targetTable, fromColumn, targetColumn; + String databaseName = ((PGPoolingDataSource) dataSource).getDatabaseName(); - if (dbType == DatabaseType.MYSQL) { - fromTable = schemaName + "." + resultSet.getString("k.TABLE_NAME"); - targetTable = schemaName + "." + resultSet.getString("k.REFERENCED_TABLE_NAME"); - fromColumn = resultSet.getString("k.COLUMN_NAME"); - targetColumn = resultSet.getString("k.REFERENCED_COLUMN_NAME"); - } else if (dbType == DatabaseType.POSTGRES) { - fromTable = resultSet.getString("from_table"); - targetTable = resultSet.getString("target_table"); - fromColumn = resultSet.getString("from_column").replace(schemaName + ".", ""); - targetColumn = resultSet.getString("target_column").replace(schemaName + ".", ""); - } else { - throw new UnsupportedOperationException("Database type " + dbType + " not supported"); - } + List schemaKeys = new ArrayList<>(); - String mapKey = fromTable + "_" + targetTable; + String queryKeys = "SELECT\n" + + "conname AS constraint_name,\n" + + "conrelid::regclass AS from_table, \n" + + "confrelid::regclass AS target_table\n" + + "FROM pg_catalog.pg_constraint\n" + + "WHERE contype = 'f'\n" + + "AND ((conrelid::regclass || '' LIKE '" + schemaName + ".%')\n" + + "OR (confrelid::regclass || '' LIKE '" + schemaName + ".%'))"; - KeyEntity keyEntity = schemaKeysMap.get(mapKey); - if (keyEntity == null) { - keyEntity = new KeyEntity(); - keyEntity.setFromTableFullName(fromTable); - keyEntity.setTargetTableFullName(targetTable); - schemaKeysMap.put(mapKey, keyEntity); - } + try (Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(queryKeys)) { + + log.debug("Executing query {}", queryKeys); - KeyColumnEntity keyColumnEntity = new KeyColumnEntity(); - keyColumnEntity.setFromColumn(fromColumn); - keyColumnEntity.setTargetColumn(targetColumn); - keyEntity.getKeyColumns().add(keyColumnEntity); + while (resultSet.next()) { + + String constraintName = resultSet.getString("constraint_name"); + + String[] fromTableFullNameSplitted = resultSet.getString("from_table").split(Pattern.quote(".")); + String[] targetTableFullNameSplitted = resultSet.getString("target_table").split(Pattern.quote(".")); + + KeyEntity key = new KeyEntity( + fromTableFullNameSplitted[0], + fromTableFullNameSplitted[1], + targetTableFullNameSplitted[0], + targetTableFullNameSplitted[1] + ); + schemaKeys.add(key); + + // conkey conrelid + String queryFromKC = "SELECT\n" + + "c.column_name AS key_column\n" + + "FROM information_schema.columns c\n" + + "JOIN pg_catalog.pg_constraint r ON c.ordinal_position = ANY(r.conkey)\n" + + "AND (c.table_schema || '.' || c.table_name) = (r.conrelid::regclass || '')\n" + + "WHERE r.conname = '" + constraintName + "' AND r.contype = 'f'\n" + + "AND c.table_schema = '" + schemaName + "'\n" + + "AND table_catalog = '" + databaseName + "'"; + + // as above, but with confkey and confrelid + String queryTargetKC = "SELECT\n" + + "c.column_name AS key_column\n" + + "FROM information_schema.columns c\n" + + "JOIN pg_catalog.pg_constraint r ON c.ordinal_position = ANY(r.confkey)\n" + + "AND (c.table_schema || '.' || c.table_name) = (r.confrelid::regclass || '')\n" + + "WHERE r.conname = '" + constraintName + "' AND r.contype = 'f'\n" + + "AND c.table_schema = '" + schemaName + "'\n" + + "AND table_catalog = '" + databaseName + "'"; + + try (Statement statFromKC = connection.createStatement(); + Statement statTargetKC = connection.createStatement()) { + + try (ResultSet rsFromKC = statFromKC.executeQuery(queryFromKC); + ResultSet rsTargetKC = statTargetKC.executeQuery(queryTargetKC)) { + + log.debug("Executing query {}", queryFromKC); + log.debug("Executing query {}", queryTargetKC); + + while (rsFromKC.next()) { + if (rsTargetKC.next()) { + KeyColumnEntity keyColumn = new KeyColumnEntity(); + keyColumn.setFromColumn(rsFromKC.getString("key_column")); + keyColumn.setTargetColumn(rsTargetKC.getString("key_column")); + key.getKeyColumns().add(keyColumn); + } + } + } + } + } } - } - return new ArrayList(schemaKeysMap.values()); + return schemaKeys; + } else { + throw new UnsupportedOperationException("Database type " + dbType + " not supported"); + } } private static boolean equalsOneOf(String string, String... values) { @@ -321,8 +461,19 @@ public class DataProvider { return false; } - protected static List getAllColumns(DataSource dataSource, DatabaseType dbType, TableEntity table) throws SQLException { - final List allColumns = new ArrayList<>(); + /** + * A list of ALL the possible {@link ColumnEntity} for a + * given DataSource and a given {@link TableEntity}.
+ * IMPORTANT: this list includes also the + * ColumnEntity instances that aren't exposed by the + * TAP_SCHEMA. This choice was done for performance reasons, to avoid + * repeating the query for adding new columns. A ColumnEntity + * will be persisted to the TAP_SCHEMA if it was added to its + * TableEntity using the methods + * {@link TableEntity.addColumn()}. + */ + protected static List getAllColumns(DataSource dataSource, DatabaseType dbType, TableEntity table) throws SQLException { + final List allColumns = new ArrayList<>(); String query; if (dbType == DatabaseType.MYSQL) { @@ -337,6 +488,8 @@ public class DataProvider { throw new UnsupportedOperationException("Database type " + dbType + " not supported"); } + log.debug("Executing query {}", query); + try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(query)) { @@ -362,12 +515,10 @@ public class DataProvider { columnEntity.setFullTableName(table.getName()); columnEntity.setTable(table); - ColumnInfo columnInfo = new ColumnInfo(columnEntity); - // Key type if (dbType == DatabaseType.MYSQL) { String key = resultSet.getString("Key"); - columnInfo.setPrimaryKey(key.equals("PRI")); + columnEntity.setPrimaryKey(key.equals("PRI")); columnEntity.setIndexed(equalsOneOf(key, "PRI", "UNI", "MUL") ? 1 : 0); if (!alreadyLoaded) { columnEntity.setPrincipal(key.equals("PRI") ? 1 : 0); @@ -375,7 +526,7 @@ public class DataProvider { } else if (dbType == DatabaseType.POSTGRES) { String columnType = resultSet.getString("column_type"); if (columnType != null) { - columnInfo.setPrimaryKey("p".equals(columnType)); + columnEntity.setPrimaryKey("p".equals(columnType)); columnEntity.setIndexed(equalsOneOf(columnType, "p", "f", "u") ? 1 : 0); } if (!alreadyLoaded) { @@ -448,7 +599,7 @@ public class DataProvider { columnEntity.setStd(0); } - allColumns.add(columnInfo); + allColumns.add(columnEntity); } } diff --git a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/DatabaseType.java b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/DatabaseType.java index dc0bc62812233134d1b6b59e5f44402df8bf134d..d0a39a8974ae9ad3ca107e5798ff6504c125fae0 100644 --- a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/DatabaseType.java +++ b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/DatabaseType.java @@ -1,8 +1,9 @@ package it.inaf.oats.ia2.tapschemamanager.datalayer; /** - * - * @author Sonia Zorba + * This enum lists the supported RDBMS. + * + * @author Sonia Zorba {@literal } */ public enum DatabaseType { MYSQL, diff --git a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/KeyColumnEntity.java b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/KeyColumnEntity.java index 5933f208ec2d95efe9a93b179926a7a260e3db35..a52200dbd899dbf24ea8a37c47427f232b0d950a 100644 --- a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/KeyColumnEntity.java +++ b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/KeyColumnEntity.java @@ -12,7 +12,7 @@ import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; class KeyColumn implements Serializable { - + private static final long serialVersionUID = 1244476100879775193L; String keyId; @@ -21,14 +21,15 @@ class KeyColumn implements Serializable { } /** + * JPA entity for the table TAP_SCHEMA.key_columns. * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ @Entity @IdClass(KeyColumn.class) @Table(name = "key_columns") public class KeyColumnEntity implements Serializable { - + private static final long serialVersionUID = -1841850907719547336L; @Id @@ -50,6 +51,9 @@ public class KeyColumnEntity implements Serializable { @PrimaryKeyJoinColumn(name = "key_id", referencedColumnName = "key_id") private KeyEntity key; + /** + * The value in the key_id column. + */ public String getKeyId() { return keyId; } @@ -58,6 +62,9 @@ public class KeyColumnEntity implements Serializable { this.keyId = keyId; } + /** + * The value in the from_column column. + */ public String getFromColumn() { return fromColumn; } @@ -66,6 +73,9 @@ public class KeyColumnEntity implements Serializable { this.fromColumn = fromColumn; } + /** + * The value in the target_column column. + */ public String getTargetColumn() { return targetColumn; } @@ -74,6 +84,10 @@ public class KeyColumnEntity implements Serializable { this.targetColumn = targetColumn; } + /** + * The value in the key_columnID column: it represents + * [TODO]... + */ public BigInteger getKeyColumnID() { return keyColumnID; } @@ -82,6 +96,9 @@ public class KeyColumnEntity implements Serializable { this.keyColumnID = keyColumnID; } + /** + * The KeyEntity that owns this KeyColumnEntity. + */ public KeyEntity getKey() { return key; } diff --git a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/KeyEntity.java b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/KeyEntity.java index 594b22bdef1f991123db933e8473150b223e51e3..beef34e04560e9e36cb23a90edfb9ea0654579d8 100644 --- a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/KeyEntity.java +++ b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/KeyEntity.java @@ -15,13 +15,14 @@ import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; /** + * JPA entity for the table TAP_SCHEMA.keys. * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ @Entity @Table(name = "\"keys\"") public class KeyEntity implements Serializable { - + private static final long serialVersionUID = 4321901642780866919L; @Id @@ -54,15 +55,36 @@ public class KeyEntity implements Serializable { @OneToMany(mappedBy = "key", cascade = CascadeType.ALL, orphanRemoval = true) private final List keyColumns; + private String fromSchemaName; + private String targetSchemaName; + public KeyEntity() { - keyColumns = new ArrayList(); + keyColumns = new ArrayList<>(); } + public KeyEntity(String fromSchema, String fromTable, String targetSchema, String targetTable) { + this(); + this.fromSchemaName = fromSchema; + this.fromTableFullName = fromSchema + "." + fromTable; + this.targetSchemaName = targetSchema; + this.targetTableFullName = targetSchema + "." + targetTable; + } + + /** + * The TAP standard define the key ID as a VARCHAR, but in our + * implementation we assume it represents a numeric value + * + * @param keyId - ID of the key + */ public KeyEntity(int keyId) { this(); this.keyId = keyId + ""; } + /** + * The value in the key_id column: represents the ID of the key + * (in our implementation we assume it represents a numeric value). + */ public String getKeyId() { return keyId; } @@ -71,6 +93,11 @@ public class KeyEntity implements Serializable { this.keyId = keyId; } + /** + * The value in the from_table column: it is the complete name + * of the table, as defined in the TAP standard: so it is + * <schema-name>.<table-name>. + */ public String getFromTableFullName() { return fromTableFullName; } @@ -79,6 +106,11 @@ public class KeyEntity implements Serializable { this.fromTableFullName = fromTableFullName; } + /** + * The value in the target_table column: it is the complete + * name of the table, as defined in the TAP standard: so it is + * <schema-name>.<table-name>. + */ public String getTargetTableFullName() { return targetTableFullName; } @@ -87,6 +119,9 @@ public class KeyEntity implements Serializable { this.targetTableFullName = targetTableFullName; } + /** + * The value in the utype column. + */ public String getUtype() { return utype; } @@ -95,6 +130,9 @@ public class KeyEntity implements Serializable { this.utype = utype; } + /** + * The value in the description column. + */ public String getDescription() { return description; } @@ -103,6 +141,9 @@ public class KeyEntity implements Serializable { this.description = description; } + /** + * The value in the keyID column: it represents [TODO]... + */ public BigInteger getKeyID() { return keyID; } @@ -111,6 +152,10 @@ public class KeyEntity implements Serializable { this.keyID = keyID; } + /** + * @return the {@link TableEntity} related to the from_table + * field + */ public TableEntity getFromTable() { return fromTable; } @@ -119,15 +164,39 @@ public class KeyEntity implements Serializable { this.fromTable = fromTable; } - public void setTargetTable(TableEntity targetTable) { - this.targetTable = targetTable; - } - + /** + * @return the {@link TableEntity} related to the target_table + * field + */ public TableEntity getTargetTable() { return targetTable; } + public void setTargetTable(TableEntity targetTable) { + this.targetTable = targetTable; + } + + /** + * List of the KeyColumnEntity owned by this + * KeyEntity. + */ public List getKeyColumns() { return keyColumns; } + + public String getFromSchemaName() { + return fromSchemaName; + } + + public void setFromSchemaName(String fromSchemaName) { + this.fromSchemaName = fromSchemaName; + } + + public String getTargetSchemaName() { + return targetSchemaName; + } + + public void setTargetSchemaName(String targetSchemaName) { + this.targetSchemaName = targetSchemaName; + } } diff --git a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/ResultSetReader.java b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/ResultSetReader.java deleted file mode 100644 index 47a97200461edd186f8ffd3f20ce285f1a617091..0000000000000000000000000000000000000000 --- a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/ResultSetReader.java +++ /dev/null @@ -1,47 +0,0 @@ -package it.inaf.oats.ia2.tapschemamanager.datalayer; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author Sonia Zorba - */ -public abstract class ResultSetReader { - - private static final Logger log = LoggerFactory.getLogger(ResultSetReader.class); - - private final String query; - - public ResultSetReader(String query) { - this.query = query; - } - - public abstract void manipulateItem(ResultSet resultSet) throws SQLException; - - public final void read(Connection connection) throws SQLException { - Statement statement = null; - ResultSet resultSet = null; - try { - statement = connection.createStatement(); - resultSet = statement.executeQuery(query); - while (resultSet.next()) { - manipulateItem(resultSet); - } - } catch (SQLException e) { - log.error("The following query caused SQLException: \"" + query + "\""); - throw e; - } finally { - if (resultSet != null) { - resultSet.close(); - } - if (statement != null) { - statement.close(); - } - } - } -} diff --git a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/SchemaEntity.java b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/SchemaEntity.java index e923a0f6bd210e6a1ca8c2c0f495dab0b605d652..e0727681e5f8476ae75a1e205cb37a58b2ce86c8 100644 --- a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/SchemaEntity.java +++ b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/SchemaEntity.java @@ -11,97 +11,128 @@ import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.MapKeyColumn; import javax.persistence.OneToMany; -import javax.persistence.OrderBy; import javax.persistence.Table; /** + * JPA entity for the table TAP_SCHEMA.schemas. * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ @Entity @Table(name = "\"schemas\"") public class SchemaEntity implements Serializable, TapSchemaEntity { - + private static final long serialVersionUID = -1058919664128696098L; - + @Id @Column(name = "schema_name", length = 64) private String name; - + @Column(name = "utype", length = 512) private String utype; - + @Column(name = "description", length = 512) private String description; - + @Column(name = "schemaID") private BigInteger schemaID; - + @OneToMany(mappedBy = "schema", cascade = CascadeType.ALL, orphanRemoval = true) @MapKeyColumn(name = "table_name", insertable = false, updatable = false) - @OrderBy("name ASC") private final List tables; - + protected SchemaEntity() { - this.tables = new ArrayList(); + this.tables = new ArrayList<>(); } - + protected SchemaEntity(String schemaName) { this(); this.name = schemaName; } - + + /** + * The value in the schema_name column. + */ @Override public String getName() { return name; } - + protected void setName(String schemaName) { this.name = schemaName; } - + + /** + * The value in the utype column. + */ public String getUtype() { return utype; } - + public void setUtype(String utype) { this.utype = utype; } - + + /** + * The value in the description column. + */ public String getDescription() { return description; } - + public void setDescription(String description) { this.description = description; } - + + /** + * The value in the schemaID column: it represents [TODO]... + */ protected BigInteger getSchemaID() { return schemaID; } - + protected void setSchemaID(BigInteger schemaID) { this.schemaID = schemaID; } - + + /** + * The list of TableEntity owned by this + * SchemaEntity. + * + * @return an unmodifiable list + */ public List getTables() { return Collections.unmodifiableList(tables); } - + + /** + * Find the TableEntity owned by this SchemaEntity + * using its short name (the table name without the schema name). + * + * @return the TableEntity instance if it exists, null + * otherwise. + */ public TableEntity getTableByShortName(String shortTableName) { return getTable(name + "." + shortTableName); } - + + /** + * Find the TableEntity owned by this SchemaEntity + * using its complete name (schema_name.table_name). + * + * @return the TableEntity instance if it exists, null + * otherwise. + */ public TableEntity getTable(String fullTableName) { return DLUtil.getEntityByName(tables, fullTableName); } - + protected void addTable(TableEntity table) { - DLUtil.insertEntityInOrder(tables, table); + tables.add(table); table.setSchemaName(name); table.setSchema(this); } - + protected void removeTable(String fullTableName) { DLUtil.removeEntity(tables, fullTableName); } diff --git a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/TableEntity.java b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/TableEntity.java index 23f802911d50d858a8b8b89687f3b4683a589438..6189e62a12677ef78a7fb0f71411b24ce94824d6 100644 --- a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/TableEntity.java +++ b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/TableEntity.java @@ -14,13 +14,13 @@ import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.MapKeyColumn; import javax.persistence.OneToMany; -import javax.persistence.OrderBy; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; /** + * JPA entity for the table TAP_SCHEMA.tables. * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ @Entity @Table(name = "tables") @@ -53,7 +53,6 @@ public class TableEntity implements Serializable, TapSchemaEntity { @OneToMany(mappedBy = "table", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) @MapKeyColumn(name = "column_name", insertable = false, updatable = false) - @OrderBy("name ASC") private final List columns; @OneToMany(mappedBy = "fromTable", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) @@ -63,9 +62,9 @@ public class TableEntity implements Serializable, TapSchemaEntity { private final List targetKeys; protected TableEntity() { - columns = new ArrayList(); - fromKeys = new ArrayList(); - targetKeys = new ArrayList(); + columns = new ArrayList<>(); + fromKeys = new ArrayList<>(); + targetKeys = new ArrayList<>(); } protected TableEntity(SchemaEntity schemaEntity, String shortTableName) { @@ -76,7 +75,8 @@ public class TableEntity implements Serializable, TapSchemaEntity { } /** - * @return full table name: schemaName.tableName + * The value in the table_name column: it represents the + * complete table name: schema_name.table_name. */ @Override public String getName() { @@ -84,7 +84,7 @@ public class TableEntity implements Serializable, TapSchemaEntity { } /** - * @return table name without schema name + * The table name without the schema name. */ public String getShortTableName() { return name.split(Pattern.quote("."))[1]; @@ -94,6 +94,9 @@ public class TableEntity implements Serializable, TapSchemaEntity { this.name = fullTableName; } + /** + * The value in the schema_name column. + */ public String getSchemaName() { return schemaName; } @@ -102,6 +105,10 @@ public class TableEntity implements Serializable, TapSchemaEntity { this.schemaName = schemaName; } + /** + * The value in the table_type column: it could be + * table or view. + */ public String getTableType() { return tableType; } @@ -110,6 +117,9 @@ public class TableEntity implements Serializable, TapSchemaEntity { this.tableType = tableType; } + /** + * The value in the utype column. + */ public String getUtype() { return utype; } @@ -118,6 +128,9 @@ public class TableEntity implements Serializable, TapSchemaEntity { this.utype = utype; } + /** + * The value in the description column. + */ public String getDescription() { return description; } @@ -126,6 +139,9 @@ public class TableEntity implements Serializable, TapSchemaEntity { this.description = description; } + /** + * The value in the tableID column: it represents [TODO]... + */ protected BigInteger getTableID() { return tableID; } @@ -134,6 +150,9 @@ public class TableEntity implements Serializable, TapSchemaEntity { this.tableID = tableID; } + /** + * The {@link SchemaEntity} that owns this TableEntity. + */ public SchemaEntity getSchema() { return schema; } @@ -142,20 +161,38 @@ public class TableEntity implements Serializable, TapSchemaEntity { this.schema = schemaEntity; } + /** + * The list of ColumnEntity owned by this + * TableEntity. + * + * @return an unmodifiable list + */ public List getColumns() { return Collections.unmodifiableList(columns); } + /** + * The list of KeyEntity which from_table column + * is the complete name of this TableEntity. + * + * @return an unmodifiable list + */ public List getFromKeys() { return Collections.unmodifiableList(fromKeys); } + /** + * The list of KeyEntity which target_table column + * is the complete name of this TableEntity. + * + * @return an unmodifiable list + */ public List getTargetKeys() { return Collections.unmodifiableList(targetKeys); } protected void addColumn(ColumnEntity column) { - DLUtil.insertEntityInOrder(columns, column); + columns.add(column); column.setFullTableName(name); column.setTable(this); } diff --git a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/TapSchemaEntity.java b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/TapSchemaEntity.java index addd8ae3249db19091b958fae0e26a59ea7b285a..e157ca853767239fb7aef603b2c95073289e9e45 100644 --- a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/TapSchemaEntity.java +++ b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/TapSchemaEntity.java @@ -1,10 +1,21 @@ package it.inaf.oats.ia2.tapschemamanager.datalayer; /** + * Interface that represents one of the principal entities of the TAP_SCHEMA, so + * it can be an instance of {@link SchemaEntity}, {@link TableEntity} or + * {@link ColumnEntity}. * - * @author Sonia Zorba + * {@link KeyEntity} and {@link KeyColumnEntity} aren't included because their + * management is different. + * + * @author Sonia Zorba {@literal } */ public interface TapSchemaEntity { - - String getName(); + + /** + * It can be the schema name, the table name or the column name. + * + * @return the name of the entity + */ + String getName(); } diff --git a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/TapSchemaHandler.java b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/TapSchemaHandler.java index f4eec232138ee097813194f845290d711186d63f..49300da6b35e6a18bc41e9f7fb7534f79be3a47b 100644 --- a/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/TapSchemaHandler.java +++ b/TapSchemaManagerDL/src/main/java/it/inaf/oats/ia2/tapschemamanager/datalayer/TapSchemaHandler.java @@ -27,9 +27,9 @@ class SchemaInfo implements Serializable { private final Map tablesType; SchemaInfo(DataSource dataSource, DatabaseType dbType, String schemaName) throws SQLException { - allSchemaTables = DataProvider.getAllTablesNames(dataSource, dbType, schemaName); - schemaKeys = DataProvider.getSchemaKeys(dataSource, dbType, schemaName); - tablesType = DataProvider.getTablesTypes(dataSource, dbType, schemaName); + allSchemaTables = Dao.getAllTablesNames(dataSource, dbType, schemaName); + schemaKeys = Dao.getSchemaKeys(dataSource, dbType, schemaName); + tablesType = Dao.getTablesTypes(dataSource, dbType, schemaName); } public List getAllSchemaTables() { @@ -50,7 +50,7 @@ class ColumnsInfo implements Serializable { private static final long serialVersionUID = -3407052226160044192L; private final String tapSchemaName; - private final Map>> columnsInfo; + private final Map>> columnsInfo; ColumnsInfo(String tapSchemaName) { this.tapSchemaName = tapSchemaName; @@ -59,22 +59,22 @@ class ColumnsInfo implements Serializable { void addColumnsInfo(DBWrapper dbWrapper, TableEntity tableEntity) throws SQLException { String schemaName = tableEntity.getSchemaName(); - Map> map = columnsInfo.get(schemaName); + Map> map = columnsInfo.get(schemaName); if (map == null) { map = new HashMap<>(); columnsInfo.put(schemaName, map); } - List allColumns; + List allColumns; if (schemaName.equals(tapSchemaName)) { - allColumns = DataProvider.getAllColumns(dbWrapper.getTapSchemaDataSource(), dbWrapper.getTapSchemaDatabaseType(), tableEntity); + allColumns = Dao.getAllColumns(dbWrapper.getTapSchemaDataSource(), dbWrapper.getTapSchemaDatabaseType(), tableEntity); } else { - allColumns = DataProvider.getAllColumns(dbWrapper.getSourceDataSource(), dbWrapper.getSourceDatabaseType(), tableEntity); + allColumns = Dao.getAllColumns(dbWrapper.getSourceDataSource(), dbWrapper.getSourceDatabaseType(), tableEntity); } map.put(tableEntity.getShortTableName(), allColumns); } - List getColumnsInfo(String schemaName, String shortTableName) { + List getColumnsInfo(String schemaName, String shortTableName) { return columnsInfo.get(schemaName).get(shortTableName); } } @@ -84,7 +84,7 @@ class ColumnsInfo implements Serializable { * informations. IMPORTANT: If you use this class inside another object remember * to call the close method to release the occupied resources. * - * @author Sonia Zorba + * @author Sonia Zorba {@literal } */ public class TapSchemaHandler implements Serializable, Closeable { @@ -114,7 +114,7 @@ public class TapSchemaHandler implements Serializable, Closeable { this.tapSchemaName = tapSchemaName; this.exists = exists; - this.allSchemas = DataProvider.getAllSchemasNames(dbWrapper.getSourceDataSource(), dbWrapper.getSourceDatabaseType()); + this.allSchemas = Dao.getAllSchemasNames(dbWrapper.getSourceDataSource(), dbWrapper.getSourceDatabaseType()); this.schemas = new ArrayList<>(); this.persistedSchemas = new ArrayList<>(); @@ -157,10 +157,18 @@ public class TapSchemaHandler implements Serializable, Closeable { } public final void addSchema(SchemaEntity schemaEntity) { - DLUtil.insertEntityInOrder(schemas, schemaEntity); + schemas.add(schemaEntity); + + for (TableEntity tableEntity : schemaEntity.getTables()) { + addTableKeys(schemaEntity, tableEntity); + } } public final void removeSchema(String schemaName) { + for (TableEntity tableEntity : DLUtil.getEntityByName(schemas, schemaName).getTables()) { + removeKeys(tableEntity); + } + if (persistedSchemas.contains(schemaName)) { toRemoveSchemas.add(getSchema(schemaName)); persistedSchemas.remove(schemaName); @@ -180,7 +188,7 @@ public class TapSchemaHandler implements Serializable, Closeable { return allSchemaInfos.get(schemaName).getAllSchemaTables(); } - public List getColumnInfo(String schemaName, String shortTableName) { + public List getColumnEntities(String schemaName, String shortTableName) { return columnsInfo.getColumnsInfo(schemaName, shortTableName); } @@ -217,50 +225,76 @@ public class TapSchemaHandler implements Serializable, Closeable { return table; } - public void addTable(String schemaName, TableEntity tableEntity) { - SchemaEntity schema = getSchema(schemaName); - schema.addTable(tableEntity); - - // Add table keys + private void addTableKeys(SchemaEntity schemaEntity, TableEntity tableEntity) { int currentKey = getMaxKey() + 1; - for (KeyEntity keyEntity : getAllSchemaKeys(schemaName)) { - String fromTableName = keyEntity.getFromTableFullName(); - String targetTableName = keyEntity.getTargetTableFullName(); - TableEntity fromTable = null, targetTable = null; - if (tableEntity.getName().equals(fromTableName)) { - fromTable = tableEntity; - targetTable = schema.getTable(targetTableName); - } else if (tableEntity.getName().equals(targetTableName)) { - targetTable = tableEntity; - fromTable = schema.getTable(fromTableName); + for (KeyEntity keyEntity : getAllSchemaKeys(schemaEntity.getName())) { + + String fromTableSchemaName = keyEntity.getFromSchemaName(); + String targetTableSchemaName = keyEntity.getTargetSchemaName(); + + boolean fromTableSchemaExposed = false; + boolean targetTableSchemaExposed = false; + for (SchemaEntity s : getSchemas()) { + if (fromTableSchemaExposed && targetTableSchemaExposed) { + break; + } + if (s.getName().equals(fromTableSchemaName)) { + fromTableSchemaExposed = true; + } + if (s.getName().equals(targetTableSchemaName)) { + targetTableSchemaExposed = true; + } } - if (fromTable != null && targetTable != null - && !fromTable.getFromKeys().contains(keyEntity) - && !targetTable.getTargetKeys().contains(keyEntity)) { - String key = currentKey + ""; - keyEntity.setKeyId(key); - keyEntity.setFromTable(fromTable); - keyEntity.setTargetTable(targetTable); - for (KeyColumnEntity keyColumn : keyEntity.getKeyColumns()) { - keyColumn.setKeyId(key); + + // If both schemas are exposed it is possible to add the key + if (fromTableSchemaExposed && targetTableSchemaExposed) { + String fromTableName = keyEntity.getFromTableFullName(); + String targetTableName = keyEntity.getTargetTableFullName(); + TableEntity fromTable = null, targetTable = null; + if (tableEntity.getName().equals(fromTableName)) { + fromTable = tableEntity; + targetTable = schemaEntity.getTable(targetTableName); + } else if (tableEntity.getName().equals(targetTableName)) { + targetTable = tableEntity; + fromTable = schemaEntity.getTable(fromTableName); } + if (fromTable != null && targetTable != null + && !fromTable.getFromKeys().contains(keyEntity) + && !targetTable.getTargetKeys().contains(keyEntity)) { + String key = currentKey + ""; + keyEntity.setKeyId(key); + keyEntity.setFromTable(fromTable); + keyEntity.setTargetTable(targetTable); + for (KeyColumnEntity keyColumn : keyEntity.getKeyColumns()) { + keyColumn.setKeyId(key); + } - fromTable.addFromKey(keyEntity); - targetTable.addTargetKey(keyEntity); + fromTable.addFromKey(keyEntity); + targetTable.addTargetKey(keyEntity); - currentKey++; + currentKey++; + } } } } - public void removeTable(SchemaEntity schemaEntity, TableEntity tableEntity) { + public void addTable(String schemaName, TableEntity tableEntity) { + SchemaEntity schemaEntity = getSchema(schemaName); + schemaEntity.addTable(tableEntity); + addTableKeys(schemaEntity, tableEntity); + } + + private void removeKeys(TableEntity tableEntity) { for (KeyEntity keyEntity : tableEntity.getFromKeys()) { keyEntity.getTargetTable().removeTargetKey(keyEntity); } for (KeyEntity keyEntity : tableEntity.getTargetKeys()) { keyEntity.getFromTable().removeFromKey(keyEntity); } + } + public void removeTable(SchemaEntity schemaEntity, TableEntity tableEntity) { + removeKeys(tableEntity); schemaEntity.removeTable(tableEntity.getName()); } @@ -296,6 +330,8 @@ public class TapSchemaHandler implements Serializable, Closeable { public void save() throws SQLException { if (exists) { + log.info("Saving existing TAP_SCHEMA {}", tapSchemaName); + loadEntityManager(); entityManager.getTransaction().begin(); @@ -307,7 +343,8 @@ public class TapSchemaHandler implements Serializable, Closeable { } entityManager.getTransaction().commit(); } else { - DataProvider.createTapSchemaSchema(dbWrapper, tapSchemaName); + log.info("Saving TAP_SCHEMA {} for the first time", tapSchemaName); + Dao.createTapSchemaSchema(dbWrapper, tapSchemaName); loadEntityManager(); @@ -326,8 +363,8 @@ public class TapSchemaHandler implements Serializable, Closeable { for (String shortTableName : allSchemaInfos.get(tapSchemaName).getAllSchemaTables()) { TableEntity tableEntity = getNewTable(tapSchemaName, shortTableName); addTable(tapSchemaName, tableEntity); - for (ColumnInfo ci : columnsInfo.getColumnsInfo(tapSchemaName, shortTableName)) { - addColumn(tableEntity, ci.getColumnEntity()); + for (ColumnEntity ce : columnsInfo.getColumnsInfo(tapSchemaName, shortTableName)) { + addColumn(tableEntity, ce); } } @@ -343,7 +380,7 @@ public class TapSchemaHandler implements Serializable, Closeable { private void loadEntityManager() { if (entityManager == null) { - entityManager = DataProvider.getEntityManager(dbWrapper.getTapSchemaCredentials(), tapSchemaName); + entityManager = Dao.getEntityManager(dbWrapper.getTapSchemaCredentials(), tapSchemaName); } } diff --git a/TapSchemaManagerDL/src/test/java/TestQuery.java b/TapSchemaManagerDL/src/test/java/TestQuery.java deleted file mode 100644 index 0f2abd4120264e36c12173677081e6ca7c8a65e8..0000000000000000000000000000000000000000 --- a/TapSchemaManagerDL/src/test/java/TestQuery.java +++ /dev/null @@ -1,448 +0,0 @@ - -import it.inaf.oats.ia2.tapschemamanager.datalayer.ColumnEntity; -import it.inaf.oats.ia2.tapschemamanager.datalayer.ColumnInfo; -import it.inaf.oats.ia2.tapschemamanager.datalayer.Credentials; -import it.inaf.oats.ia2.tapschemamanager.datalayer.DBWrapper; -import it.inaf.oats.ia2.tapschemamanager.datalayer.DatabaseType; -import it.inaf.oats.ia2.tapschemamanager.datalayer.KeyColumnEntity; -import it.inaf.oats.ia2.tapschemamanager.datalayer.KeyEntity; -import it.inaf.oats.ia2.tapschemamanager.datalayer.SchemaEntity; -import it.inaf.oats.ia2.tapschemamanager.datalayer.TableEntity; -import it.inaf.oats.ia2.tapschemamanager.datalayer.TapSchemaHandler; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.List; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import static org.junit.Assert.*; -import org.junit.Ignore; - -/** - * - * @author Sonia Zorba - */ -public class TestQuery { - - private static final int DATABASES_COUNT = 2; - private static final int TABLES_COUNT = 3; - - private static List dbWrappers; - - public TestQuery() { - } - - @BeforeClass - public static void setUpClass() throws SQLException { - - dbWrappers = new ArrayList<>(); - - // MYSQL - Credentials mysqlCredentials = new Credentials(DatabaseType.MYSQL); - mysqlCredentials.setHostname("localhost"); - mysqlCredentials.setUsername("root"); - mysqlCredentials.setPassword("root"); - - // POSTGRES - Credentials postgresCredentials = new Credentials(DatabaseType.POSTGRES); - postgresCredentials.setHostname("localhost"); - postgresCredentials.setUsername("postgres"); - postgresCredentials.setPassword("pippo"); - - DBWrapper dbWrapper = new DBWrapper(mysqlCredentials); - dbWrapper.testConnections(); - //dbWrappers.add(dbWrapper); - - dbWrapper = new DBWrapper(postgresCredentials); - dbWrapper.testConnections(); - //dbWrappers.add(dbWrapper); - - // Mix! - dbWrappers.add(new DBWrapper(mysqlCredentials, postgresCredentials)); - //dbWrappers.add(new DBWrapper(postgresCredentials, mysqlCredentials)); - } - - @AfterClass - public static void tearDownClass() { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } - - private void removeTestingDatabases() throws SQLException { - for (DBWrapper dbWrapper : dbWrappers) { - try (Connection sourceConnection = dbWrapper.getSourceConnection(); - Statement statement = sourceConnection.createStatement()) { - DatabaseType dbType = dbWrapper.getSourceDatabaseType(); - for (int i = 0; i < DATABASES_COUNT; i++) { - if (dbType == DatabaseType.MYSQL) { - statement.executeUpdate("DROP DATABASE IF EXISTS db" + i); - } else if (dbType == DatabaseType.POSTGRES) { - statement.executeUpdate("DROP SCHEMA IF EXISTS db" + i + " CASCADE"); - } else { - 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"); - } - } - } - } - - private void setUpTestingDatabases() throws SQLException { - removeTestingDatabases(); - - for (DBWrapper dbWrapper : dbWrappers) { - - DatabaseType dbType = dbWrapper.getSourceDatabaseType(); - - try (Connection connection = dbWrapper.getSourceConnection()) { - - try (Statement statement = connection.createStatement()) { - - if (dbType == DatabaseType.MYSQL) { - for (int i = 0; i < DATABASES_COUNT; i++) { - statement.executeUpdate("CREATE DATABASE db" + i); - for (int j = 0; j < TABLES_COUNT; j++) { - statement.executeUpdate("CREATE TABLE db" + 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 < DATABASES_COUNT; i++) { - statement.executeUpdate("CREATE SCHEMA db" + i); - for (int j = 0; j < TABLES_COUNT; j++) { - statement.executeUpdate("CREATE TABLE db" + i + ".table" + j + " (\n" - + "id BIGSERIAL PRIMARY KEY,\n" - + "value1 VARCHAR(255),\n" - + "value2 FLOAT\n" - + ");"); - } - } - } else { - throw new UnsupportedOperationException("Database type " + dbType + " not supported"); - } - } - - System.out.println("dbs created"); - - try (Statement statement = connection.createStatement()) { - for (int j = 0; j < TABLES_COUNT - 1; j++) { - String update1 = "ALTER TABLE db0.table" + (j + 1) + " ADD COLUMN table" + j + "_id INT"; - statement.executeUpdate(update1); - //System.out.println(update1); - String update2; - if (dbType == DatabaseType.MYSQL) { - update2 = "ALTER TABLE db0.table" + (j + 1) + " ADD CONSTRAINT id_constraint_" + (j + 1) + " FOREIGN KEY(table" + j + "_id) REFERENCES db0.table" + j + "(id)"; - } else if (dbType == DatabaseType.POSTGRES) { - update2 = "ALTER TABLE db0.table" + (j + 1) + " ADD CONSTRAINT id_constraint_" + (j + 1) + " FOREIGN KEY (table" + j + "_id) REFERENCES db0.table" + j + "(id)"; - } else { - throw new UnsupportedOperationException("Database type " + dbType + " not supported"); - } - - //System.out.println(update2); - statement.executeUpdate(update2); - } - } - } - } - } - - @Test - public void testTapSchemaSerialization() throws Exception { - for (DBWrapper dbWrapper : dbWrappers) { - if (dbWrapper.getTapSchemaDatabaseType() == DatabaseType.MYSQL) { // currently "tng_TAP_SCHEMA" exists in a MySQL instance - TapSchemaHandler tapSchemaHandler = new TapSchemaHandler(dbWrapper, "tng_TAP_SCHEMA", true); - - System.out.println("schemas size = " + tapSchemaHandler.getSchemas().size()); - - try (FileOutputStream fileOut = new FileOutputStream("/home/sonia/test.ser"); - ObjectOutputStream out = new ObjectOutputStream(fileOut)) { - out.writeObject(tapSchemaHandler); - } - - try (FileInputStream fileIn = new FileInputStream("/home/sonia/test.ser"); - ObjectInputStream in = new ObjectInputStream(fileIn)) { - tapSchemaHandler = (TapSchemaHandler) in.readObject(); - } - - tapSchemaHandler.save(); - System.out.println("schemas size = " + tapSchemaHandler.getSchemas().size()); - } - } - } - - //@Ignore - @Test - public void loadSchema() throws SQLException { - for (DBWrapper dbWrapper : dbWrappers) { - if (dbWrapper.getTapSchemaDatabaseType() == DatabaseType.MYSQL) { // currently "tng_TAP_SCHEMA" exists in a MySQL instance - TapSchemaHandler tapSchemaHandler = new TapSchemaHandler(dbWrapper, "tng_TAP_SCHEMA", true); - assertTrue(!tapSchemaHandler.getSchemas().isEmpty()); - - // Testing alphabetical order loading - for (SchemaEntity schemaEntity : tapSchemaHandler.getSchemas()) { - TableEntity previousTable = null; - for (TableEntity table : schemaEntity.getTables()) { - if (previousTable != null) { - //assertTrue("Table=" + table.getName() + ", Previous Table=" + previousTable.getName(), - // previousTable.getName().compareToIgnoreCase(table.getName()) < 1); - } - previousTable = table; - - ColumnEntity previousColumn = null; - for (ColumnEntity column : table.getColumns()) { - if (previousColumn != null) { - //assertTrue("Column=" + column.getName() + ", Previous Column=" + previousColumn.getName(), - // previousColumn.getName().compareToIgnoreCase(column.getName()) < 1); - } - previousColumn = column; - } - -// if(previousTable == null) { -// previousTable = table; -// } else { -// } - } - } - } - } - - } - - //@Ignore - @Test - public void createNewAndUpdate() throws SQLException { - System.out.println("TEST createNewAndUpdate STARTED"); - - try { - removeTestingDatabases(); - - setUpTestingDatabases(); - - for (DBWrapper dbWrapper : dbWrappers) { - - // TEST first TapSchema creation - TapSchemaHandler tsh = new TapSchemaHandler(dbWrapper, "test_tap_schema", false); - - SchemaEntity db0 = tsh.getNewSchema("db0"); - tsh.addSchema(db0); - - List db0Keys = tsh.getAllSchemaKeys("db0"); - assertEquals(db0Keys.size(), TABLES_COUNT - 1); - // Print keys: - for (KeyEntity schemaKey : db0Keys) { - System.out.println(schemaKey.getFromTableFullName() + " -> " + schemaKey.getTargetTableFullName()); - for (KeyColumnEntity keyColumn : schemaKey.getKeyColumns()) { - System.out.println("\t" + schemaKey.getFromTableFullName() + "." + keyColumn.getFromColumn() + " -> " + schemaKey.getTargetTableFullName() + "." + keyColumn.getTargetColumn()); - } - } - - // Test add, remove and re-add of a table - //List db0Tables = tsh.getAllTables("db0"); - TableEntity db0table0 = tsh.getNewTable("db0", "table0"); - assertEquals(db0table0.getName(), "db0.table0"); - tsh.addTable("db0", db0table0); - for (ColumnInfo ci : tsh.getColumnInfo("db0", "table0")) { - assertNotNull(ci.getColumnEntity().getTable()); - } - - TableEntity db0table1 = tsh.getNewTable("db0", "table1"); - tsh.addTable("db0", db0table1); - assertEquals(db0.getTables().size(), 2); - - // Test key adding - assertTrue(db0table0.getFromKeys().isEmpty()); - assertEquals(db0table0.getTargetKeys().size(), 1); - - assertTrue(db0table1.getTargetKeys().isEmpty()); - assertEquals(db0table1.getFromKeys().size(), 1); - - KeyEntity keyEntity = db0table1.getFromKeys().get(0); - assertEquals(keyEntity.getFromTableFullName(), "db0.table1"); - assertEquals(keyEntity.getKeyColumns().get(0).getFromColumn(), "table0_id"); - assertEquals(keyEntity.getTargetTableFullName(), "db0.table0"); - assertEquals(keyEntity.getKeyColumns().get(0).getTargetColumn(), "id"); - - TableEntity db0table2 = tsh.getNewTable("db0", "table2"); - tsh.addTable("db0", db0table2); - assertEquals(db0table1.getFromKeys().size(), 1); - assertEquals(db0table1.getTargetKeys().size(), 1); - assertEquals(db0table2.getFromKeys().size(), 1); - - // Test key removing - assertEquals(db0.getTables().size(), 3); - tsh.removeTable(db0, db0table2); - assertEquals(db0.getTables().size(), 2); - assertEquals(db0table1.getFromKeys().size(), 1); - assertTrue(db0table1.getTargetKeys().isEmpty()); - - db0table2 = tsh.getNewTable("db0", "table2"); - tsh.addTable("db0", db0table2); - assertEquals(db0table1.getFromKeys().size(), 1); - assertEquals(db0table1.getTargetKeys().size(), 1); - assertEquals(db0table2.getFromKeys().size(), 1); - - assertEquals(tsh.getForeignKeyReference("db0", "db0.table1", "table0_id"), "table0.id"); - assertNull(tsh.getForeignKeyReference("db0", "db0.table1", "id")); - - tsh.removeTable(db0, db0table1); - assertTrue(db0table0.getFromKeys().isEmpty()); - assertTrue(db0table0.getTargetKeys().isEmpty()); - assertTrue(db0table2.getFromKeys().isEmpty()); - assertTrue(db0table2.getTargetKeys().isEmpty()); - - // Test add column - ColumnInfo ci = tsh.getColumnInfo("db0", "table1").get(0); - ColumnEntity columnEntity = ci.getColumnEntity(); - tsh.addColumn(db0table1, columnEntity); - assertNotNull(columnEntity.getTable()); - - // Test save - tsh.save(); - assertNotNull(db0.getTable("db0.table0")); - - // Test load saved - tsh = new TapSchemaHandler(dbWrapper, "test_tap_schema", true); - db0 = tsh.getSchemas().iterator().next(); - tsh.removeTable(db0, db0.getTable("db0.table0")); - assertNull(db0.getTable("db0.table0")); - tsh.save(); - - tsh = new TapSchemaHandler(dbWrapper, "test_tap_schema", true); - db0 = tsh.getSchemas().iterator().next(); - assertNull(db0.getTable("db0.table0")); - - // Test key constraints - tsh.addTable("db0", db0table0); - System.out.println("db0.table0 added"); - - } -// assertEquals(db0Tables.size(), TABLES_COUNT); -// for (String tableName : db0Tables) { -// tapSchemaHandler.get -// } -// -// TableEntity db0_ -// -// List addables = tapSchema.getAddables(); -// assertTrue(addables.contains("db0")); -// assertTrue(addables.contains("db1")); -// -// tapSchema.addEntityWrapper("db0"); -// assertFalse(tapSchema.getAddables().contains("db0")); -// -// Schema schema = tapSchema.getSchema("db0"); -// -// addables = schema.getAddables(); -// for (int i = 0; i < addables.size(); i++) { -// String tableName = addables.get(i); -// assertEquals(tableName, "table" + i); -// schema.addEntityWrapper(tableName); -// } -// assertTrue(schema.getAddables().isEmpty()); -// -// Table table1 = schema.getTable("table1"); -// assertEquals(table1.getName(), "table1"); -// assertEquals(table1.getFullName(), "db0.table1"); -// table1.addEntityWrapper("id"); -// table1.addEntityWrapper("value1"); -// assertFalse(table1.getAddables().contains("id")); -// assertTrue(table1.getAddables().contains("value2")); -// -// Column column = table1.getColumn("id"); -// column.setValue(Column.DESCRIPTION, "Test description"); -// assertTrue(column.isChanged()); -// column.setValue(Column.DESCRIPTION, ""); -// assertFalse(column.isChanged()); - } catch (SQLException e) { - throw e; - } finally { - //removeTestingDatabases(credentials); - } - } - - @Ignore - @Test - public void query() throws SQLException { - -// EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu"); -// EntityManager em = emf.createEntityManager(); - //CriteriaBuilder cb = em.getCriteriaBuilder(); - //CriteriaQuery cq = cb.createQuery(SchemaEntity.class); - //List results = em.createQuery(cq).getResultList(); -// SchemaEntity schema = new SchemaEntity("test_schema"); -// -// TableEntity table = new TableEntity("table1"); -// schema.addTable(table); -// -// ColumnEntity column = new ColumnEntity("table1_column1"); -// table.addColumn(column); - //TapSchemaHandler tapSchemaHandler = new TapSchemaHandler(credentials, "TestJPA", false); - //statement = connection.createStatement(); - // String tapschemaName = tapSchema.getName(); - //creates database - //String queryString = "CREATE DATABASE IF NOT EXISTS " + tapschemaName + ";"; - //statement.executeUpdate(queryString); - //em.getTransaction().begin(); -// for (SchemaEntity schema : results) { -// System.out.println("schema = " + schema.getSchemaName()); -// for (TableEntity table : schema.getTables().values()) { -// System.out.println("table = " + table.getTableName()); -// } -// -//// if (schema.getSchemaName().equals("geo")) { -//// Map tables = schema.getTables(); -//// TableEntity table = schema.getTables().get("geo.country_block_ipv4"); -//// //em.remove(table); -////// for (ColumnEntity column : table.getColumns().values()) { -////// System.out.println("column = " + column.getColumnName()); -////// column.setDescription("testDescription"); -////// } -//// break; -//// } -// } - //em.getTransaction().commit(); - //results.get(i) -// for (SchemaEntity schema : results) { -// System.out.println("schema = " + schema.getSchemaName()); -// for (TableEntity table : schema.getTables()) { -// System.out.println("table = " + table.getTableName()); -// for (ColumnEntity column : table.getColumns()) { -// System.out.println("column = " + column.getColumnName()); -// } -// for (KeyEntity fromKey : table.getFromKeys()) { -// System.out.println("fromKey = " + fromKey.getKeyId()); -// } -// for (KeyEntity targetKey : table.getTargetKeys()) { -// System.out.println("targetKey = " + targetKey.getKeyId()); -// } -// } -// } - } -} diff --git a/TapSchemaManagerDL/src/test/java/it/inaf/oats/ia2/tapschemamanager/datalayer/test/TestQuery.java b/TapSchemaManagerDL/src/test/java/it/inaf/oats/ia2/tapschemamanager/datalayer/test/TestQuery.java new file mode 100644 index 0000000000000000000000000000000000000000..0e4bed2823b2d3b72c3cf240d5cafda02464d8c4 --- /dev/null +++ b/TapSchemaManagerDL/src/test/java/it/inaf/oats/ia2/tapschemamanager/datalayer/test/TestQuery.java @@ -0,0 +1,482 @@ +package it.inaf.oats.ia2.tapschemamanager.datalayer.test; + +import it.inaf.oats.ia2.tapschemamanager.datalayer.ColumnEntity; +import it.inaf.oats.ia2.tapschemamanager.datalayer.Credentials; +import it.inaf.oats.ia2.tapschemamanager.datalayer.DBWrapper; +import it.inaf.oats.ia2.tapschemamanager.datalayer.DLUtil; +import it.inaf.oats.ia2.tapschemamanager.datalayer.DatabaseType; +import it.inaf.oats.ia2.tapschemamanager.datalayer.KeyColumnEntity; +import it.inaf.oats.ia2.tapschemamanager.datalayer.KeyEntity; +import it.inaf.oats.ia2.tapschemamanager.datalayer.SchemaEntity; +import it.inaf.oats.ia2.tapschemamanager.datalayer.TableEntity; +import it.inaf.oats.ia2.tapschemamanager.datalayer.TapSchemaHandler; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; +import org.junit.Ignore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Sonia Zorba {@literal } + */ +public class TestQuery { + + private static final Logger log = LoggerFactory.getLogger(TestQuery.class); + + private static final int SCHEMAS_COUNT = 2; // minimum value: 2 + private static final int TABLES_COUNT = 3; + + private static List dbWrappers; + + public TestQuery() { + } + + @BeforeClass + public static void setUpClass() throws SQLException { + + dbWrappers = new ArrayList<>(); + + // MYSQL + Credentials mysqlCredentials = new Credentials(DatabaseType.MYSQL); + mysqlCredentials.setHostname("localhost"); + mysqlCredentials.setUsername("root"); + mysqlCredentials.setPassword("root"); + + // POSTGRES + Credentials postgresCredentials = new Credentials(DatabaseType.POSTGRES); + postgresCredentials.setHostname("localhost"); + postgresCredentials.setUsername("postgres"); + postgresCredentials.setPassword("pippo"); + + DBWrapper dbWrapper = new DBWrapper(mysqlCredentials); + dbWrapper.testConnections(); + //dbWrappers.add(dbWrapper); + + dbWrapper = new DBWrapper(postgresCredentials); + dbWrapper.testConnections(); + dbWrappers.add(dbWrapper); + + // Mix! + //dbWrappers.add(new DBWrapper(mysqlCredentials, postgresCredentials)); + //dbWrappers.add(new DBWrapper(postgresCredentials, mysqlCredentials)); + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + private void removeTestingDatabases() throws SQLException { + for (DBWrapper dbWrapper : dbWrappers) { + try (Connection sourceConnection = dbWrapper.getSourceConnection(); + Statement statement = sourceConnection.createStatement()) { + 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"); + } + } + } 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"); + } + } + } 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 { + 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"); + } + } + } + } + + private void setUpTestingDatabases() throws SQLException { + removeTestingDatabases(); + + for (DBWrapper dbWrapper : dbWrappers) { + + DatabaseType dbType = dbWrapper.getSourceDatabaseType(); + + try (Connection connection = dbWrapper.getSourceConnection()) { + + 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 { + throw new UnsupportedOperationException("Database type " + dbType + " not supported"); + } + } + + log.info("dbs created"); + + try (Statement statement = connection.createStatement()) { + for (int j = 0; j < TABLES_COUNT - 1; j++) { + String update1 = "ALTER TABLE sch0.table" + (j + 1) + " ADD COLUMN table" + j + "_id INT"; + statement.executeUpdate(update1); + String update2; + if (dbType == DatabaseType.MYSQL || dbType == DatabaseType.POSTGRES) { + update2 = "ALTER TABLE sch0.table" + (j + 1) + " ADD CONSTRAINT id_constraint_" + (j + 1) + " FOREIGN KEY (table" + j + "_id) REFERENCES sch0.table" + j + "(id)"; + } else { + throw new UnsupportedOperationException("Database type " + dbType + " not supported"); + } + + statement.executeUpdate(update2); + } + + // Foreign key with multiple columns + statement.executeUpdate("CREATE TABLE sch0.tableX (idx1 INT, idx2 INT)"); + statement.executeUpdate("ALTER TABLE sch0.tableX ADD CONSTRAINT pkx PRIMARY KEY (idx1, idx2)"); + statement.executeUpdate("CREATE TABLE sch0.tableY (idy1 INT, idy2 INT)"); + statement.executeUpdate("ALTER TABLE sch0.tableY ADD CONSTRAINT pky PRIMARY KEY (idy1, idy2)"); + statement.executeUpdate("ALTER TABLE sch0.tableY ADD CONSTRAINT fky FOREIGN KEY(idy1, idy2) REFERENCES sch0.tableX(idx1, idx2)"); + + // Foreign keys between different schemas + statement.executeUpdate("ALTER TABLE sch0.table0 ADD COLUMN sch1table0id INT"); + statement.executeUpdate("ALTER TABLE sch0.table0 ADD CONSTRAINT sch1table0id_constraint FOREIGN KEY(sch1table0id) REFERENCES sch1.table0(id)"); + statement.executeUpdate("ALTER TABLE sch1.table0 ADD COLUMN sch0table0id INT"); + statement.executeUpdate("ALTER TABLE sch1.table0 ADD CONSTRAINT sch0table0id_constraint FOREIGN KEY(sch0table0id) REFERENCES sch0.table0(id)"); + } + } + } + } + + @Test + public void testTapSchemaSerialization() throws Exception { + for (DBWrapper dbWrapper : dbWrappers) { + if (dbWrapper.getTapSchemaDatabaseType() == DatabaseType.MYSQL) { // currently "tng_TAP_SCHEMA" exists in a MySQL instance + TapSchemaHandler tapSchemaHandler = new TapSchemaHandler(dbWrapper, "tng_TAP_SCHEMA", true); + + log.info("schemas size = {}", tapSchemaHandler.getSchemas().size()); + + try (FileOutputStream fileOut = new FileOutputStream("/home/sonia/test.ser"); + ObjectOutputStream out = new ObjectOutputStream(fileOut)) { + out.writeObject(tapSchemaHandler); + } + + try (FileInputStream fileIn = new FileInputStream("/home/sonia/test.ser"); + ObjectInputStream in = new ObjectInputStream(fileIn)) { + tapSchemaHandler = (TapSchemaHandler) in.readObject(); + } + + tapSchemaHandler.save(); + log.info("schemas size = {}", tapSchemaHandler.getSchemas().size()); + } + } + } + + //@Ignore + @Test + public void loadSchema() throws SQLException { + for (DBWrapper dbWrapper : dbWrappers) { + if (dbWrapper.getTapSchemaDatabaseType() == DatabaseType.MYSQL) { // currently "tng_TAP_SCHEMA" exists in a MySQL instance + TapSchemaHandler tapSchemaHandler = new TapSchemaHandler(dbWrapper, "tng_TAP_SCHEMA", true); + assertTrue(!tapSchemaHandler.getSchemas().isEmpty()); + + // Testing alphabetical order loading + for (SchemaEntity schemaEntity : tapSchemaHandler.getSchemas()) { + TableEntity previousTable = null; + for (TableEntity table : schemaEntity.getTables()) { + if (previousTable != null) { + //assertTrue("Table=" + table.getName() + ", Previous Table=" + previousTable.getName(), + // previousTable.getName().compareToIgnoreCase(table.getName()) < 1); + } + previousTable = table; + + ColumnEntity previousColumn = null; + for (ColumnEntity column : table.getColumns()) { + if (previousColumn != null) { + //assertTrue("Column=" + column.getName() + ", Previous Column=" + previousColumn.getName(), + // previousColumn.getName().compareToIgnoreCase(column.getName()) < 1); + } + previousColumn = column; + } + +// if(previousTable == null) { +// previousTable = table; +// } else { +// } + } + } + } + } + + } + + private void printKeys(String message, List keys) { + log.info("{}: Found {} keys", message, keys.size()); + int index = 0; + for (KeyEntity key : keys) { + for (KeyColumnEntity keyColumn : key.getKeyColumns()) { + log.info("[{}] {}.{} -> {}.{}", index, key.getFromTableFullName(), keyColumn.getFromColumn(), key.getTargetTableFullName(), keyColumn.getTargetColumn()); + } + index++; + } + } + + //@Ignore + @Test + public void createNewAndUpdate() throws SQLException { + log.info("TEST createNewAndUpdate STARTED"); + + try { + removeTestingDatabases(); + + setUpTestingDatabases(); + + for (DBWrapper dbWrapper : dbWrappers) { + + // Initializing a not existing TAP_SCHEMA + TapSchemaHandler tsh = new TapSchemaHandler(dbWrapper, "test_tap_schema", false); + + ///////////////////////////////////// + // ADDING A SCHEMA // + ///////////////////////////////////// + // + SchemaEntity sch0 = tsh.getNewSchema("sch0"); + tsh.addSchema(sch0); + + List sch0Keys = tsh.getAllSchemaKeys("sch0"); + printKeys("ALL sch0 keys", sch0Keys); + + // 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. + // Moreover, there are also the following keys: + // - sch0.table0.sch1table0id -> sch1.table0.id + // - sch1.table0.sch0table0id -> sch0.table0.id + // - sch0.tableY.(idy1, idy2) -> sch0.tableX.(idyx, idx2) + // so we check for TABLES_COUNT + 2. + assertEquals(sch0Keys.size(), TABLES_COUNT + 2); + + // Checking that keys information has been filled. + for (KeyEntity schemaKey : sch0Keys) { + assertNotNull(schemaKey.getFromTableFullName()); + assertNotNull(schemaKey.getTargetTableFullName()); + for (KeyColumnEntity keyColumn : schemaKey.getKeyColumns()) { + assertNotNull(keyColumn.getFromColumn()); + assertNotNull(keyColumn.getTargetColumn()); + } + } + + ///////////////////////////////////// + // ADDING A TABLE // + ///////////////////////////////////// + // + TableEntity sch0table0 = tsh.getNewTable("sch0", "table0"); + assertEquals(sch0table0.getName(), "sch0.table0"); + tsh.addTable("sch0", sch0table0); + assertEquals(sch0.getTables().size(), 1); + + // Checking that columns information has been filled. + List sch0table0Columns = tsh.getColumnEntities("sch0", "table0"); + for (ColumnEntity ce : sch0table0Columns) { + assertNotNull(ce.getTable()); + } + // Primary key check + assertTrue(DLUtil.getEntityByName(sch0table0Columns, "id").isPrimaryKey()); + + ///////////////////////////////////// + // KEYS MANAGEMENT // + ///////////////////////////////////// + // + // CASE 1: Foreign key between two tables in the same schema. + // sch0.table1.t0id -> sch0.table0.id + // + // Adding sch0.table1 + TableEntity sch0table1 = tsh.getNewTable("sch0", "table1"); + tsh.addTable("sch0", sch0table1); + assertEquals(sch0.getTables().size(), 2); + + printKeys("sch0table0 fromKeys", sch0table0.getFromKeys()); + assertTrue(sch0table0.getFromKeys().isEmpty()); + assertEquals(sch0table0.getTargetKeys().size(), 1); + assertEquals(sch0table0.getTargetKeys().get(0).getFromTableFullName(), "sch0.table1"); + assertEquals(sch0table0.getTargetKeys().get(0).getTargetTableFullName(), "sch0.table0"); + assertEquals(sch0table1.getFromKeys().size(), 1); + assertEquals(sch0table1.getFromKeys().get(0).getFromTableFullName(), "sch0.table1"); + assertEquals(sch0table1.getFromKeys().get(0).getTargetTableFullName(), "sch0.table0"); + assertTrue(sch0table1.getTargetKeys().isEmpty()); + + // Removing sch0.table1 + tsh.removeTable(sch0, sch0table1); + assertEquals(sch0.getTables().size(), 1); + assertTrue(sch0table0.getFromKeys().isEmpty()); + assertTrue(sch0table0.getTargetKeys().isEmpty()); + + // + // CASE 2: Foreign key between two tables in different schemas. + // sch1.table0.sch0table0id -> sch0.table0.id + // + // Adding sch1 + SchemaEntity sch1 = tsh.getNewSchema("sch1"); + tsh.addSchema(sch1); + List sch1Keys = tsh.getAllSchemaKeys("sch1"); + assertEquals(sch1Keys.size(), 2); + for (KeyEntity keyEntity : sch1Keys) { + String fromSchemaName = keyEntity.getFromSchemaName(); + String targetSchemaName = keyEntity.getTargetSchemaName(); + assertTrue(fromSchemaName.equals("")); + // TODO <--- + } + + // Adding sch1.table0 + TableEntity sch1table0 = tsh.getNewTable("sch1", "table0"); + tsh.addTable("sch1", sch1table0); + + assertEquals(sch0table0.getTargetKeys().size(), 1); + assertEquals(sch0table0.getTargetKeys().get(0).getFromTableFullName(), "sch1.table0"); + assertEquals(sch0table0.getTargetKeys().get(0).getTargetTableFullName(), "sch0.table0"); + assertEquals(sch1table0.getFromKeys().size(), 1); + assertEquals(sch0table0.getFromKeys().get(0).getFromTableFullName(), "sch1.table0"); + assertEquals(sch0table0.getFromKeys().get(0).getTargetTableFullName(), "sch0.table0"); + + // Removing sch1 + tsh.removeSchema("sch1"); + assertTrue(sch0table0.getTargetKeys().isEmpty()); + assertTrue(sch1table0.getFromKeys().isEmpty()); + + // Case 2B: Re-adding the same instance of sch1 + // sch1.table0 has not been removed from its schema, so the keys + // should be re-added. + tsh.addSchema(sch1); + assertEquals(sch0table0.getTargetKeys().size(), 1); + assertEquals(sch1table0.getFromKeys().size(), 1); + + // Case 2C: removing sch1 and re-adding a new instance of sch1 + // In this case the sch1.table0 it isn't in sch1 instance, so + // there shouldn't be any keys to add. + tsh.removeSchema("sch1"); + sch1 = tsh.getNewSchema("sch1"); + tsh.addSchema(sch1); + assertTrue(sch0table0.getTargetKeys().isEmpty()); + assertTrue(sch1table0.getFromKeys().isEmpty()); + + // + // CASE 3: foreign key with multiple columns + // + TableEntity tableX = tsh.getNewTable("sch0", "tableX"); + tsh.addTable("sch0", tableX); + TableEntity tableY = tsh.getNewTable("sch0", "tableY"); + tsh.addTable("sch0", tableY); + + assertTrue(tableX.getFromKeys().isEmpty()); + assertEquals(tableX.getTargetKeys().size(), 1); + for (KeyColumnEntity keyColumn : tableX.getTargetKeys().get(0).getKeyColumns()) { + String fromColumn = keyColumn.getFromColumn(); + String targetColumn = keyColumn.getFromColumn(); + assertTrue(fromColumn.equals("idy1") || fromColumn.equals("idy2")); + assertTrue(targetColumn.equals("idx1") || targetColumn.equals("idx2")); + } + + assertTrue(tableY.getTargetKeys().isEmpty()); + assertEquals(tableY.getFromKeys().size(), 1); + for (KeyColumnEntity keyColumn : tableY.getFromKeys().get(0).getKeyColumns()) { + String fromColumn = keyColumn.getFromColumn(); + String targetColumn = keyColumn.getFromColumn(); + assertTrue(fromColumn.equals("idy1") || fromColumn.equals("idy2")); + assertTrue(targetColumn.equals("idx1") || targetColumn.equals("idx2")); + } + + ///////////////////////////////////// + // ADDING A COLUMN // + ///////////////////////////////////// + ColumnEntity columnEntity = tsh.getColumnEntities("sch0", "table1").get(0); + tsh.addColumn(sch0table1, columnEntity); + assertNotNull(columnEntity.getTable()); + + ///////////////////////////////////// + // SAVE // + ///////////////////////////////////// + tsh.save(); + assertNotNull(sch0.getTable("sch0.table0")); + + ///////////////////////////////////// + // LOAD SAVED // + ///////////////////////////////////// + tsh = new TapSchemaHandler(dbWrapper, "test_tap_schema", true); + sch0 = tsh.getSchemas().iterator().next(); + tsh.removeTable(sch0, sch0.getTable("sch0.table0")); + assertNull(sch0.getTable("sch0.table0")); + tsh.save(); + + tsh = new TapSchemaHandler(dbWrapper, "test_tap_schema", true); + sch0 = tsh.getSchemas().iterator().next(); + assertNull(sch0.getTable("sch0.table0")); + + tsh.addTable("sch0", sch0table0); + } + } catch (SQLException e) { + throw e; + } finally { + //removeTestingDatabases(credentials); + } + } +}