Commit 942178f3 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Added (a lots of) comments to code; unused methods cleanup

parent 103d837b
Pipeline #105 passed with stage
in 22 seconds
......@@ -49,7 +49,13 @@ public class Column extends ChildEntity<Table> {
public final static String COLUMN_INDEX = "column_index"; // TAP version >= 1.1
public final static String DBNAME = "dbname";
// Original datatype (computed from information_schema data), used for consistency checking
/**
* Original datatype (computed from information_schema data), used for
* consistency checking inside the method
* {@link #it.inaf.ia2.tsm.datalayer.DBBroker.getAllColumnsMetadata()}
*
* @see it.inaf.ia2.tsm.ConsistencyChecks
*/
public final static String ORIGINAL_DATATYPE_KEY = "original_datatype";
private static final long serialVersionUID = 9175956487892235521L;
......
......@@ -206,7 +206,33 @@ public class Key extends TapSchemaEntity implements Serializable {
@Override
public String toString() {
return TSMUtil.printKeyInfo(this);
StringBuilder sb = new StringBuilder();
sb.append(String.format("[%s] %s(", getId(), getFromTableCompleteName()));
boolean first = true;
for (KeyColumn keyColumn : keyColumns) {
if (!first) {
sb.append(",");
}
first = false;
sb.append(keyColumn.getFromColumn());
}
sb.append(String.format(") -> %s(", getTargetTableCompleteName()));
first = true;
for (KeyColumn keyColumn : keyColumns) {
if (!first) {
sb.append(",");
}
first = false;
sb.append(keyColumn.getTargetColumn());
}
sb.append(")");
return sb.toString();
}
@Override
......
......@@ -25,9 +25,11 @@ package it.inaf.ia2.tsm;
import java.io.Serializable;
/**
* Model used during consistency checking phase to represents a
*
*
* Model used during consistency checking phase to represents a key that has
* been stored into the TAP_SCHEMA but is not currently existing according to
* the information read from the database metadata.
*
* @see it.inaf.ia2.tsm.ConsistencyChecks
* @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
*/
public class KeyHolder implements Serializable {
......@@ -52,18 +54,32 @@ public class KeyHolder implements Serializable {
return keyId;
}
/**
* Returns the complete name of table (schema name plus table name) owning
* the foreign key.
*/
public String getFromTable() {
return fromTable;
}
/**
* Returns the columns composing the foreign key.
*/
public String[] getFromColumns() {
return fromColumns;
}
/**
* Returns the complete name of table (schema name plus table name) owning
* the primary key.
*/
public String getTargetTable() {
return targetTable;
}
/**
* Returns the columns composing the primary key.
*/
public String[] getTargetColumns() {
return targetColumns;
}
......
......@@ -33,7 +33,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The main implementation of {@link Schema}.
* Represents a Schema entity belonging to a {@link TapSchema}.
*
* @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
*/
......@@ -48,12 +48,22 @@ public class Schema extends ChildEntity<TapSchema> implements EntitiesContainer<
private final Map<String, Table> tables;
private Map<String, String> tablesTypes;
/**
* Only for serialization.
*/
private Schema() {
// for serialization
super();
tables = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
}
/**
* Default constructor.
*
* @param tapSchema the {@code TapSchema} owning this schema.
* @param name the name of this schema.
* @throws SQLException if there a problem while retrieving information
* about schema tables.
*/
public Schema(TapSchema tapSchema, String name) throws SQLException {
super(tapSchema, tapSchema.getTableModel(TapSchema.SCHEMAS_TABLE), tapSchema.getSchemaMetadata(name));
......@@ -70,6 +80,14 @@ public class Schema extends ChildEntity<TapSchema> implements EntitiesContainer<
setStatus(Status.LOADED);
}
/**
* Returns the name of the schema as seen by the database. The real schema
* name can be different from the exposed schema name if the schema renaming
* feature has been set. Schema renaming is supported by taplib adding an
* additional column {@code dbname} to the TAP_SCHEMA {@code schema},
* {@code tables} and {@code columns} tables. Not all the TASMAN schema
* definitions includes the {@code dbname} column.
*/
public final String getRealSchemaName() {
if (tapSchema.getDBName() != null && this.getName().equals(tapSchema.getName())) {
return tapSchema.getDBName();
......@@ -89,6 +107,8 @@ public class Schema extends ChildEntity<TapSchema> implements EntitiesContainer<
}
/**
* {@inheritDoc}
*
* @param tableSimpleName the name of the table, without the schema name.
*/
@Override
......@@ -185,7 +205,6 @@ public class Schema extends ChildEntity<TapSchema> implements EntitiesContainer<
return TSMUtil.getAddableChildrenNames(tables);
}
/**
* {@inheritDoc}
*/
......@@ -249,6 +268,14 @@ public class Schema extends ChildEntity<TapSchema> implements EntitiesContainer<
return tapSchema;
}
/**
* Returns the metadata {@code Map} for a {@link Table} having this schema
* as parent.
*
* @param tableSimpleName the name of the table without its schema name.
* @return a {@code Map} having table property names as keys and table
* property values as values.
*/
public Map<String, Object> getTableMetadata(String tableSimpleName) {
Map<String, Object> metadata = new HashMap<>();
metadata.put(Table.SCHEMA_NAME_KEY, getName());
......
......@@ -22,20 +22,17 @@
*/
package it.inaf.ia2.tsm;
import it.inaf.ia2.tsm.datalayer.DatabaseType;
import it.inaf.ia2.tsm.datalayer.DBWrapper;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Utility class that contains some static methods to manage various operations
* Utility class containing some static methods to manage various operations
* with the TAP_SCHEMA entities.
*
* @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
......@@ -132,143 +129,6 @@ public class TSMUtil {
return ret;
}
/**
* Same as {@link DLUtil.getObject(ResultSet, String, Class<T>)}.
*/
public static <T> T getObject(ResultSet rs, int i, Class<T> type) throws SQLException {
T ret;
if (type == String.class) {
ret = (T) rs.getString(i);
} else if (type == Integer.class) {
ret = (T) (Integer) rs.getInt(i);
} else if (type == Long.class) {
ret = (T) (Long) rs.getLong(i);
} else if (type == Boolean.class) {
ret = (T) (Boolean) rs.getBoolean(i);
} else {
throw new UnsupportedOperationException("Type " + type.getCanonicalName() + " not supported by " + TSMUtil.class.getCanonicalName() + " getObject() method");
}
if (rs.wasNull()) {
return null;
}
return ret;
}
protected static DataSource getSchemaDataSource(DBWrapper dbWrapper, TapSchema tapSchema, String schemaName) {
return schemaName.equals(tapSchema.getName()) ? dbWrapper.getTapSchemaDataSource() : dbWrapper.getSourceDataSource();
}
protected static DatabaseType getSchemaDatabaseType(DBWrapper dbWrapper, TapSchema tapSchema, String schemaName) {
return schemaName.equals(tapSchema.getName()) ? dbWrapper.getTapSchemaDatabaseType() : dbWrapper.getSourceDatabaseType();
}
protected static boolean isTapSchema(TapSchema tapSchema, String schemaName) {
return schemaName.equals(tapSchema.getName());
}
protected static UnsupportedOperationException getUnsupportedOperationException(String version, String unsupportedFeature) {
return new UnsupportedOperationException("Version \"" + version + "\" doesn't support " + unsupportedFeature);
}
protected static String escapeName(String name, DatabaseType dbType) {
char escapeChar;
switch (dbType) {
case MYSQL:
escapeChar = '`';
break;
case POSTGRES:
escapeChar = '"';
break;
default:
throw new UnsupportedOperationException("Database type " + dbType + " not supported");
}
return String.format("%s%s%s", escapeChar, name, escapeChar);
}
protected static String getTapSchemaTableNameFromEntity(TapSchemaEntity entity) {
if (entity instanceof Schema) {
return TapSchema.SCHEMAS_TABLE;
} else if (entity instanceof Table) {
return TapSchema.TABLES_TABLE;
} else if (entity instanceof Column) {
return TapSchema.COLUMNS_TABLE;
} else if (entity instanceof Key) {
return TapSchema.KEYS_TABLE;
} else if (entity instanceof KeyColumn) {
return TapSchema.KEY_COLUMNS_TABLE;
}
LOG.warn("getTapSchemaTableNameFromEntity returns null for {}" + entity.getClass().getCanonicalName());
return null;
}
public static String getNaturalLanguageName(TapSchemaEntity entity) {
if (entity instanceof Schema) {
return "schema";
} else if (entity instanceof Table) {
return "table";
} else if (entity instanceof Column) {
return "column";
} else if (entity instanceof Key) {
return "key";
} else if (entity instanceof KeyColumn) {
return "key_column";
} else {
throw new UnsupportedOperationException("entity class " + entity.getClass().getCanonicalName() + " not supported yet");
}
}
public static String getName(TapSchemaEntity entity) {
if (entity instanceof Schema) {
return ((Schema) entity).getName();
} else if (entity instanceof Table) {
return ((Table) entity).getCompleteName();
} else if (entity instanceof Column) {
Column column = (Column) entity;
return column.getParent().getCompleteName() + "." + column.getName();
} else if (entity instanceof Key) {
return printKeyInfo((Key) entity);
} else if (entity instanceof KeyColumn) {
KeyColumn keyColumn = (KeyColumn) entity;
return String.format("%s -> %s [key: %s]",
keyColumn.getFromColumn(), keyColumn.getTargetColumn(),
printKeyInfo(keyColumn.getParent()));
} else {
throw new UnsupportedOperationException("entity class " + entity.getClass().getCanonicalName() + " not supported yet");
}
}
public static String printKeyInfo(Key key) {
StringBuilder sb = new StringBuilder();
sb.append(String.format("[%s] %s(", key.getId(), key.getFromTableCompleteName()));
boolean first = true;
for (KeyColumn keyColumn : key.getKeyColumns()) {
if (!first) {
sb.append(",");
}
first = false;
sb.append(keyColumn.getFromColumn());
}
sb.append(String.format(") -> %s(", key.getTargetTableCompleteName()));
first = true;
for (KeyColumn keyColumn : key.getKeyColumns()) {
if (!first) {
sb.append(",");
}
first = false;
sb.append(keyColumn.getTargetColumn());
}
sb.append(")");
return sb.toString();
}
/**
* Utility class for joining a collection of object properties.
*/
......
......@@ -304,9 +304,9 @@ public class Table extends ChildEntity<Schema> implements EntitiesContainer<Colu
}
/**
* Returns the metadata about a column children of this table. Metadata are
* column properties the value of which can be retrieved from the database
* metadata (or information_schema).
* Returns the metadata about a column having this table as parent. Metadata
* are column properties the value of which can be retrieved from the
* database metadata (or information_schema).
*
* @param columnName the name of the column of which retrieve the metadata.
* @return a {@code Map} the keys of which are property names and the values
......
......@@ -43,10 +43,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Contains both data models of the entities exposed by the TAP_SCHEMA and
* method for managing them and edit the TAP_SCHEMA content.
*
* @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
*/
public class TapSchema implements EntitiesContainer<Schema>, Serializable {
public static final String STANDARD_TAP_SCHEMA_NAME = "TAP_SCHEMA";
public static final String STANDARD_IVOA_SCHEMA_NAME = "ivoa";
......@@ -56,16 +59,16 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
public static final String COLUMNS_TABLE = "columns";
public static final String KEYS_TABLE = "keys";
public static final String KEY_COLUMNS_TABLE = "key_columns";
public static final String DESCRIPTION_KEY = "description";
private static final long serialVersionUID = 1678083091602571256L;
private static final Logger LOG = LoggerFactory.getLogger(TapSchema.class);
private final Map<String, Schema> schemas;
private final Set<Key> allKeys;
private boolean loading;
private DBWrapper dbWrapper;
private String dbName;
......@@ -75,47 +78,67 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
private boolean exists;
private TapSchemaSettings settings;
private DataTypeMode dataTypeMode;
private transient DBBroker sourceDBBroker;
private transient DBBroker tapSchemaDBBroker;
private ConsistencyChecks consistencyChecks;
/**
* Returns the {@link DBBroker} for the database containing the astronomical
* data and the ObsCore (called the <em>source</em> in TASMAN jargon).
*
* @see it.inaf.ia2.tsm.datalayer.DBWrapper
*/
public final DBBroker getSourceDBBroker() {
if (sourceDBBroker == null) {
sourceDBBroker = DBBrokerFactory.getDBBroker(dbWrapper.getSourceDataSourceWrapper(), dataTypeMode);
}
return sourceDBBroker;
}
/**
* Returns the {@link DBBroker} for the database containing the TAP_SCHEMA
* schema.
*
* @see it.inaf.ia2.tsm.datalayer.DBWrapper
*/
public final DBBroker getTapSchemaDBBroker() {
if (tapSchemaDBBroker == null) {
tapSchemaDBBroker = DBBrokerFactory.getDBBroker(dbWrapper.getTapSchemaDataSourceWrapper(), dataTypeMode);
}
return tapSchemaDBBroker;
}
/**
* Only for serialization.
*/
private TapSchema() {
// for serialization
schemas = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
allKeys = new HashSet<>();
}
/**
* Default constructor.
*
* @param exists true if the TAP_SCHEMA has already been created, false if
* must be created when the {@link #save() method is called}.
*/
public TapSchema(DBWrapper dbWrapper, TapSchemaSettings settings, boolean exists) throws SQLException {
this();
this.dbWrapper = dbWrapper;
this.exists = exists;
this.settings = settings;
// Don't change the instructions order!
loadDBName();
loadName();
dataTypeMode = getTapSchemaModel().getDataTypeMode();
load();
}
private void loadDBName() {
// Detect if the TAP_SCHEMA version supports dbmodel
SchemaModel tapSchemaModel = SchemaModels.getTapSchemaModel(settings.getTapSchemaVersion());
......@@ -129,7 +152,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
}
}
}
private void loadName() {
if (dbName != null) {
name = STANDARD_TAP_SCHEMA_NAME;
......@@ -142,9 +165,15 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
ivoaSchemaName = settings.getIvoaSchemaName();
}
}
/**
* Loads the TAP_SCHEMA information from the database. This method is called
* in the constructor, but it can be called in every moment for reloading
* database metadata (this is useful if some modifications have been
* performed to the source schemata structure).
*/
public final void load() throws SQLException {
loading = true;
// Initializing schemas map
schemas.clear();
......@@ -155,16 +184,19 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
if (settings.isHasObscore() && ivoaSchemaDBName != null) {
schemas.put(getIvoaSchemaName(), null);
}
if (exists) {
consistencyChecks = TapSchemaLoader.loadExistingTapSchema((this));
}
loading = false;
checkKeys();
}
/**
* Returns the {@link DBBroker} related to a given schema.
*/
public DBBroker getDBBroker(String schemaName) {
if (schemaName.equals(getName())) {
return getTapSchemaDBBroker();
......@@ -174,28 +206,36 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
}
/**
* The name of the TAP_SCHEMA schema.
* Returns the name of the TAP_SCHEMA schema, as exposed by itself.
*/
public final String getName() {
return name;
}
/**
* The version selected for this TAP_SCHEMA.
* Return the versions selected for this TAP_SCHEMA.
*/
public String getVersion() {
return settings.getTapSchemaVersion();
}
/**
* Returns the {@link DataTypeMode} used by this TAP_SCHEMA.
*/
public DataTypeMode getDataTypeMode() {
return dataTypeMode;
}
private void loadSchemaKeysMetadata(String schemaName) throws SQLException {
allKeys.addAll(getDBBroker(schemaName)
.getKeys(this, schemaName, getRealSchemaName(schemaName)));
}
/**
* Returns all {@link Key} entities loaded by this instance; this include
* both visible and hidden keys (that are keys that must be exposed by the
* TAP_SCHEMA and keys that mustn't).
*/
public Set<Key> getAllKeys() {
return allKeys;
}
......@@ -206,15 +246,15 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
@Override
public final Schema addChild(String schemaName) throws SQLException {
LOG.debug("Adding schema {}", schemaName);
Schema schema;
if (!schemas.containsKey(schemaName)) {
schema = null;
} else {
schema = schemas.get(schemaName);
if (schema == null) {
schema = new Schema(this, schemaName);
schema.setStatus(Status.ADDED_NOT_PERSISTED);
......@@ -232,10 +272,10 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
throw new IllegalArgumentException("Cannot add the schema " + schemaName + ". Invalid status. Schema status is " + schema.getStatus());
}
}
checkKeys();
}
return schema;
}
......@@ -245,22 +285,22 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
@Override