Commit 894886d6 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Supported renaming of ivoa schema name, fixed various bugs

parent e258024b
......@@ -33,6 +33,7 @@ public class Column extends ChildEntity<Table> {
public final static String TABLE_NAME_KEY = "table_name";
public final static String COLUMN_NAME_KEY = "column_name";
public final static String DESCRIPTION_KEY = "description";
public final static String DATATYPE_KEY = "datatype";
public final static String SIZE_KEY = "size";
public final static String ARRAYSIZE_KEY = "arraysize";
......
......@@ -60,7 +60,7 @@ public class Schema extends ChildEntity<TapSchema> implements EntitiesContainer<
DBBroker broker = tapSchema.getDBBroker(name);
tables = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
tablesTypes = broker.getAllTableTypes(name);
tablesTypes = broker.getAllTableTypes(getRealSchemaName());
for (String tableName : broker.getAllTablesNames(getRealSchemaName())) {
tables.put(tableName, null);
......@@ -70,10 +70,13 @@ public class Schema extends ChildEntity<TapSchema> implements EntitiesContainer<
setStatus(Status.LOADED);
}
public String getRealSchemaName() {
public final String getRealSchemaName() {
if (tapSchema.getDBName() != null && this.getName().equals(tapSchema.getName())) {
return tapSchema.getDBName();
}
if (tapSchema.getIvoaSchemaDBName() != null && this.getName().equals(tapSchema.getIvoaSchemaName())) {
return tapSchema.getIvoaSchemaDBName();
}
return getName();
}
......
......@@ -65,7 +65,7 @@ public class Table extends ChildEntity<Schema> implements EntitiesContainer<Colu
if (tapSchema.getName().equals(parentSchema.getName())) {
return tapSchema.getTapSchemaModel().getTable(simpleName);
}
if (tapSchema.isHasObscore() && parentSchema.getName().equals("ivoa")
if (tapSchema.isHasObscore() && parentSchema.getName().equals(TapSchema.STANDARD_IVOA_SCHEMA_NAME)
&& simpleName.equals("obscore")) {
return tapSchema.getIvoaSchemaModel().getTable(simpleName);
}
......
......@@ -46,8 +46,9 @@ import org.slf4j.LoggerFactory;
* @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
*/
public class TapSchema implements EntitiesContainer<Schema>, Serializable {
public static final String STANDARD_NAME = "TAP_SCHEMA";
public static final String STANDARD_TAP_SCHEMA_NAME = "TAP_SCHEMA";
public static final String STANDARD_IVOA_SCHEMA_NAME = "ivoa";
// Mandatory tables constants
public static final String TABLES_TABLE = "tables";
......@@ -55,84 +56,95 @@ 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;
private String name;
private String ivoaSchemaDBName;
private String ivoaSchemaName;
private boolean exists;
private TapSchemaSettings settings;
private DataTypeMode dataTypeMode;
private transient DBBroker sourceDBBroker;
private transient DBBroker tapSchemaDBBroker;
private ConsistencyChecks consistencyChecks;
public final DBBroker getSourceDBBroker() {
if (sourceDBBroker == null) {
sourceDBBroker = DBBrokerFactory.getDBBroker(dbWrapper.getSourceDataSourceWrapper(), dataTypeMode);
}
return sourceDBBroker;
}
public final DBBroker getTapSchemaDBBroker() {
if (tapSchemaDBBroker == null) {
tapSchemaDBBroker = DBBrokerFactory.getDBBroker(dbWrapper.getTapSchemaDataSourceWrapper(), dataTypeMode);
}
return tapSchemaDBBroker;
}
private TapSchema() {
// for serialization
schemas = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
allKeys = new HashSet<>();
//consistencyChecks = new ConsistencyChecks();
}
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());
boolean hasDBName = tapSchemaModel.getTable(SCHEMAS_TABLE).get("dbname") != null;
if (hasDBName && !STANDARD_NAME.equals(settings.getTapSchemaName())) {
dbName = settings.getTapSchemaName();
if (hasDBName) {
if (!STANDARD_TAP_SCHEMA_NAME.equals(settings.getTapSchemaName())) {
dbName = settings.getTapSchemaName();
}
if (!STANDARD_IVOA_SCHEMA_NAME.equals(settings.getIvoaSchemaName())) {
ivoaSchemaDBName = settings.getIvoaSchemaName();
}
}
}
private void loadName() {
if (dbName != null) {
name = STANDARD_NAME;
name = STANDARD_TAP_SCHEMA_NAME;
} else {
name = settings.getTapSchemaName();
}
if (ivoaSchemaDBName != null) {
ivoaSchemaName = STANDARD_IVOA_SCHEMA_NAME;
} else {
ivoaSchemaName = settings.getIvoaSchemaName();
}
}
public final void load() throws SQLException {
loading = true;
// Initializing schemas map
schemas.clear();
......@@ -140,16 +152,19 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
schemas.put(schemaName, null);
}
schemas.put(getName(), null); // the TAP_SCHEMA contains itself
if (settings.isHasObscore() && ivoaSchemaDBName != null) {
schemas.put(getIvoaSchemaName(), null);
}
if (exists) {
consistencyChecks = TapSchemaLoader.loadExistingTapSchema((this));
}
loading = false;
checkKeys();
}
public DBBroker getDBBroker(String schemaName) {
if (schemaName.equals(getName())) {
return getTapSchemaDBBroker();
......@@ -171,16 +186,16 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
public String getVersion() {
return settings.getTapSchemaVersion();
}
public DataTypeMode getDataTypeMode() {
return dataTypeMode;
}
private void loadSchemaKeysMetadata(String schemaName) throws SQLException {
allKeys.addAll(getDBBroker(schemaName)
.getKeys(this, schemaName, getRealSchemaName(schemaName)));
}
public Set<Key> getAllKeys() {
return allKeys;
}
......@@ -191,15 +206,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);
......@@ -217,10 +232,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;
}
......@@ -230,22 +245,22 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
@Override
public void removeChild(String schemaName) {
LOG.debug("Removing schema {}", schemaName);
if (!schemas.containsKey(schemaName)) {
throw new IllegalArgumentException("The database doesn't contains a schema named " + schemaName);
}
Schema schema = schemas.get(schemaName);
if (schema == null || schema.getStatus() == Status.LOADED) {
throw new IllegalArgumentException("Cannot remove the schema " + schemaName + ". It has never been added.");
}
if (schema.getStatus() == Status.ADDED_NOT_PERSISTED) {
schema.setStatus(Status.REMOVED_NOT_PERSISTED);
} else if (schema.getStatus() == Status.ADDED_PERSISTED) {
schema.setStatus(Status.TO_REMOVE);
}
checkKeys();
}
......@@ -272,7 +287,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
public List<String> getAddableChildrenNames() {
return TSMUtil.getAddableChildrenNames(schemas);
}
@Override
public boolean isAddable(String childName) {
return schemas.containsKey(childName);
......@@ -305,14 +320,14 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
}
schemas.put(schemaName, null);
}
public SchemaModel getIvoaSchemaModel() {
if (settings.isHasObscore()) {
return SchemaModels.getIvoaSchemaModel(settings.getObscoreVersion());
}
return null;
}
public void addEntireSchema(String schemaName) throws SQLException {
Schema schema = addChild(schemaName);
for (String tableName : schema.getAddableChildrenNames()) {
......@@ -327,9 +342,9 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
* Save or update the TAP_SCHEMA changes into the database.
*/
public void save() throws SQLException {
DBBroker broker = getTapSchemaDBBroker();
if (!exists) {
SchemaModel tapSchemaModel = getTapSchemaModel();
broker.createTapSchemaStructure(getRealName(), tapSchemaModel);
......@@ -337,26 +352,26 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
// Adding TAP_SCHEMA into TAP_SCHEMA
addEntireSchema(getName());
fillColumnProperties(tapSchemaModel, getName());
if (settings.isHasObscore()) {
createAndAddIvoaSchema();
}
}
fillKeyIds();
broker.save(this);
exists = true;
// Clean inconsistency
consistencyChecks = null;
}
public void createAndAddIvoaSchema() throws SQLException {
SchemaModel ivoaSchemaModel = getIvoaSchemaModel();
// ivoa schema has to be created into source database
getSourceDBBroker().createIvoaSchemaStructure(ivoaSchemaModel);
getSourceDBBroker().createIvoaSchemaStructure(ivoaSchemaModel, getRealSchemaName(ivoaSchemaModel.getName()));
// Initializing ivoa schema slot in schemata maps
schemas.put(ivoaSchemaModel.getName(), null);
......@@ -383,20 +398,20 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
}
return maxKeyId;
}
private void fillKeyIds() {
List<Key> newKeys = new ArrayList<>();
for (Key key : allKeys) {
if (key.isVisible()) {
if (key.isVisible() && key.getId() == null) {
newKeys.add(key);
}
}
int maxKeyId = getMaxKeyId();
for (Key newKey : newKeys) {
maxKeyId++;
newKey.setId(maxKeyId + "");
newKey.setId(String.valueOf(maxKeyId));
}
}
......@@ -407,12 +422,12 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
*/
public final void checkKeys() {
if (!loading) {
for (Key key : allKeys) {
// Check if key should be exposed in TAP_SCHEMA
boolean keyVisible = true;
for (KeyColumn keyColumn : key.getKeyColumns()) {
String schemaName = keyColumn.getParent().getFromSchemaName();
String tableName = keyColumn.getParent().getFromTableSimpleName();
......@@ -421,7 +436,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
keyVisible = false;
break;
}
schemaName = keyColumn.getParent().getTargetSchemaName();
tableName = keyColumn.getParent().getTargetTableSimpleName();
columnName = keyColumn.getTargetColumn();
......@@ -442,11 +457,11 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder("\n");
sb.append(String.format(">> TAP_SCHEMA %s <<\n", getName()));
for (Schema schema : getChildren()) {
sb.append("--");
sb.append(schema.getName());
......@@ -459,9 +474,9 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
sb.append(table.getName());
sb.append(String.format(" [%s]", table.getStatus()));
sb.append("\n");
String padder = i < tables.size() - 1 ? " | " : " ";
for (Column column : table.getChildren()) {
sb.append(padder);
sb.append("|--");
......@@ -469,20 +484,20 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
sb.append(String.format(" [%s]", column.getStatus()));
sb.append("\n");
}
sb.append("\n");
}
}
sb.append("** Keys **\n");
for (Key key : getVisibileKeys()) {
sb.append(key);
sb.append("\n");
}
return sb.toString();
}
public boolean isSchemaVisible(String schemaName) {
Schema schema = schemas.get(schemaName);
if (schema == null) {
......@@ -491,40 +506,40 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
return schema.getStatus() == Status.ADDED_PERSISTED
|| schema.getStatus() == Status.ADDED_NOT_PERSISTED;
}
public boolean isTableVisible(String schemaName, String tableName) {
if (!isSchemaVisible(schemaName)) {
return false;
}
Table table = schemas.get(schemaName).getChild(tableName);
if (table == null) {
return false;
}
if (table.getStatus() == Status.ADDED_PERSISTED
|| table.getStatus() == Status.ADDED_NOT_PERSISTED) {
return isSchemaVisible(schemaName);
}
return false;
}
public boolean isColumnVisible(String schemaName, String tableName, String columnName) {
if (!isTableVisible(schemaName, tableName)) {
return false;
}
Column column = schemas.get(schemaName).getChild(tableName).getChild(columnName);
if (column == null) {
return false;
}
if (column.getStatus() == Status.ADDED_PERSISTED
|| column.getStatus() == Status.ADDED_NOT_PERSISTED) {
return isTableVisible(schemaName, tableName);
}
return false;
}
......@@ -534,30 +549,30 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
public boolean exists() {
return exists;
}
public ConsistencyChecks getConsistencyChecks() {
return consistencyChecks;
}
public final SchemaModel getTapSchemaModel() {
return SchemaModels.getTapSchemaModel(getVersion());
}
public final TableModel getTableModel(String tableName) {
return getTapSchemaModel().getTable(tableName);
}
public Map<String, Object> getSchemaMetadata(String schemaName) {
Map<String, Object> metadata = new HashMap<>();
metadata.put(Schema.SCHEMA_NAME_KEY, schemaName);
String dbNameMetadata = null;
if (dbName != null && schemaName.equals(STANDARD_NAME)) {
if (dbName != null && schemaName.equals(STANDARD_TAP_SCHEMA_NAME)) {
dbNameMetadata = dbName;
}
metadata.put(Schema.DBNAME, dbNameMetadata);
return metadata;
}
public List<Key> getVisibileKeys() {
List<Key> visibleKeys = new ArrayList<>();
for (Key key : allKeys) {
......@@ -567,14 +582,14 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
}
return visibleKeys;
}
private Integer getIntAsBool(Boolean value) {
if (value == null) {
return null;
}
return value ? 1 : 0;
}
public boolean isHasObscore() {
return settings.isHasObscore();
}
......@@ -587,7 +602,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
// check only on std, but valid also for principal (it depends on TS version)
boolean useIntegerAsBool = getTapSchemaModel().getTable(COLUMNS_TABLE).get(Column.STD_KEY).getJavaType() == Integer.class;
Schema schema = getChild(schemaName);
schema.setValue(DESCRIPTION_KEY, schemaModel.getDescription());
for (TableModel tableModel : schemaModel.getTables()) {
......@@ -603,7 +618,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
column.setValue(Column.UCD_KEY, columnModel.getUcd());
column.setValue(Column.UNIT_KEY, columnModel.getUnit());
column.setValue(Column.UTYPE_KEY, columnModel.getUtype());
Object compatibleStd = useIntegerAsBool ? getIntAsBool(columnModel.isStandard()) : columnModel.isStandard();
Object compatiblePrincipal = useIntegerAsBool ? getIntAsBool(columnModel.isPrincipal()) : columnModel.isPrincipal();
column.setValue(Column.STD_KEY, compatibleStd);
......@@ -611,7 +626,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
}
}
}
public void fillColumnsProperties(SchemaModel schemaModel) {
fillColumnProperties(schemaModel, schemaModel.getName());
}
......@@ -625,15 +640,26 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
public String getDBName() {
return dbName;
}
public String getIvoaSchemaDBName() {
return ivoaSchemaDBName;
}
public String getIvoaSchemaName() {
return ivoaSchemaName;
}
public String getRealName() {
return getRealSchemaName(getName());
}
public String getRealSchemaName(String schemaName) {
if (dbName != null && STANDARD_NAME.equals(schemaName)) {
if (dbName != null && STANDARD_TAP_SCHEMA_NAME.equals(schemaName)) {
return dbName;
}
if (ivoaSchemaDBName != null && STANDARD_IVOA_SCHEMA_NAME.equals(schemaName)) {
return ivoaSchemaDBName;
}
return schemaName;
}