Commit fca053a6 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Improvements on XML models inheritance (in progress)

parent 62382a93
......@@ -22,6 +22,8 @@
*/
package it.inaf.ia2.tsm;
import it.inaf.ia2.tsm.model.TableModel;
import it.inaf.ia2.tsm.model.TypesMapping;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -63,6 +65,22 @@ public class Column extends ChildEntity<Table> {
setStatus(Status.LOADED);
}
private void overrideDataTypeFromModels() {
Schema parentSchema = parentTable.getParent();
String type = null;
if (tapSchema.getName().equals(parentSchema.getName())) {
TableModel tableModel = tapSchema.getTapSchemaModel().get(parentTable.getName());
type = tableModel.get(getName()).getType();
}
if (type != null) {
String compatibleType = TypesMapping.getCompatibleADQLType(type, tapSchema.getVersion());
getProperty(DATATYPE_KEY).init(compatibleType);
}
}
public Key getForeignKey() {
if (!foreignKeySearched) { // lazy loading (but the foreignKey value can be null, so we use this boolean)
......
......@@ -22,7 +22,7 @@
*/
package it.inaf.ia2.tsm;
import it.inaf.ia2.tsm.model.PropertyModel;
import it.inaf.ia2.tsm.model.ColumnModel;
import java.io.Serializable;
/**
......@@ -35,7 +35,7 @@ public class EntityProperty<T> implements Serializable {
private static final long serialVersionUID = 6735553751078589085L;
private PropertyModel propertyModel;
private ColumnModel propertyModel;
private Class<T> type;
private T originalValue;
private T value;
......@@ -44,7 +44,7 @@ public class EntityProperty<T> implements Serializable {
private EntityProperty() {
}
public EntityProperty(PropertyModel propertyModel, T defaultValue) {
public EntityProperty(ColumnModel propertyModel, T defaultValue) {
this.propertyModel = propertyModel;
this.type = propertyModel.getJavaType();
this.init(defaultValue);
......
......@@ -23,6 +23,7 @@
package it.inaf.ia2.tsm;
import it.inaf.ia2.tsm.datalayer.DBBroker;
import it.inaf.ia2.tsm.model.TableModel;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
......@@ -56,6 +57,17 @@ public class Table extends ChildEntity<Schema> implements EntitiesContainer<Colu
super();
}
private TableModel getModel() {
if (tapSchema.getName().equals(parentSchema.getName())) {
return tapSchema.getTapSchemaModel().get(simpleName);
}
if (tapSchema.isHasObscore() && parentSchema.getName().equals("ivoa")
&& simpleName.equals("obscore")) {
return tapSchema.getIvoaSchemaModel().get(simpleName);
}
return null;
}
protected Table(TapSchema tapSchema, Schema schema, String tableSimpleName) throws SQLException {
super(tapSchema, tapSchema.getTableModel(TapSchema.TABLES_TABLE), schema.getTableMetadata(tableSimpleName));
......@@ -65,7 +77,7 @@ public class Table extends ChildEntity<Schema> implements EntitiesContainer<Colu
columns = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
DBBroker broker = tapSchema.getDBBroker(schema.getName());
columnsMetadata = broker.getAllColumnsMetadata(schema.getName(), tableSimpleName);
columnsMetadata = broker.getAllColumnsMetadata(schema.getName(), tableSimpleName, getModel(), tapSchema.getVersion());
for (Map.Entry<String, Map<String, Object>> entry : columnsMetadata.entrySet()) {
// Adding table names to columns metadata
entry.getValue().put(Column.TABLE_NAME_KEY, schema.getName() + "." + tableSimpleName);
......
......@@ -25,7 +25,7 @@ package it.inaf.ia2.tsm;
import it.inaf.ia2.tsm.datalayer.DBBroker;
import it.inaf.ia2.tsm.datalayer.DBBrokerFactory;
import it.inaf.ia2.tsm.datalayer.DBWrapper;
import it.inaf.ia2.tsm.model.PropertyModel;
import it.inaf.ia2.tsm.model.ColumnModel;
import it.inaf.ia2.tsm.model.TableModel;
import it.inaf.ia2.tsm.model.SchemaModel;
import it.inaf.ia2.tsm.model.SchemaModels;
......@@ -427,7 +427,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
schemas.put(schemaName, null);
}
private SchemaModel getIvoaSchemaModel() {
public SchemaModel getIvoaSchemaModel() {
if (obscore) {
return SchemaModels.getIvoaSchemaModel(obscoreVersion);
}
......@@ -686,6 +686,10 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
return value ? 1 : 0;
}
public boolean isHasObscore() {
return obscore;
}
/**
* Fill descriptions of the TAP_SCHEMA schema entities for a given
* SchemaModel (TAP_SCHEMA or ivoa).
......@@ -700,7 +704,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
for (TableModel tableModel : schemaModel.getTables().values()) {
Table table = schema.getChild(tableModel.getName());
table.setValue(DESCRIPTION_KEY, tableModel.getDescription());
for (PropertyModel propertyModel : tableModel.getProperties().values()) {
for (ColumnModel propertyModel : tableModel.getColumns()) {
Column column = table.getChild(propertyModel.getName());
column.setValue(DESCRIPTION_KEY, propertyModel.getDescription());
column.setValue(Column.UCD_KEY, propertyModel.getUcd());
......
......@@ -22,7 +22,7 @@
*/
package it.inaf.ia2.tsm;
import it.inaf.ia2.tsm.model.PropertyModel;
import it.inaf.ia2.tsm.model.ColumnModel;
import it.inaf.ia2.tsm.model.TableModel;
import java.io.Serializable;
import java.util.ArrayList;
......@@ -64,7 +64,7 @@ public abstract class TapSchemaEntity implements Serializable {
}
private void fillProperties() {
for (PropertyModel propModel : tableModel.getProperties().values()) {
for (ColumnModel propModel : tableModel.getColumns()) {
Object defaultValue = null;
if (propModel.getLoaderKey() != null) {
defaultValue = metadata.get(propModel.getLoaderKey());
......
......@@ -52,7 +52,7 @@ public interface DBBroker {
List<String> getAllColumnsNames(String schemaName, String tableName) throws SQLException;
Map<String, Map<String, Object>> getAllColumnsMetadata(String schemaName, String tableSimpleName) throws SQLException;
Map<String, Map<String, Object>> getAllColumnsMetadata(String schemaName, String tableSimpleName, TableModel tableModel, String tapSchemaVersion) throws SQLException;
List<Key> getKeys(TapSchema tapSchema, String schemaName) throws SQLException;
......
......@@ -32,7 +32,7 @@ import it.inaf.ia2.tsm.Table;
import it.inaf.ia2.tsm.TapSchema;
import it.inaf.ia2.tsm.TapSchemaEntity;
import it.inaf.ia2.tsm.UpdateOperations;
import it.inaf.ia2.tsm.model.PropertyModel;
import it.inaf.ia2.tsm.model.ColumnModel;
import it.inaf.ia2.tsm.model.TableModel;
import it.inaf.ia2.tsm.model.SchemaModel;
import it.inaf.ia2.tsm.model.SchemaModels;
......@@ -403,12 +403,12 @@ public abstract class DBBrokerTemplate implements DBBroker {
StringBuilder querySb = new StringBuilder("SELECT ");
boolean first = true;
for (PropertyModel pm : tableModel.getProperties().values()) {
for (ColumnModel cm : tableModel.getColumns()) {
if (!first) {
querySb.append(", ");
}
first = false;
querySb.append(escape(pm.getName()));
querySb.append(escape(cm.getName()));
}
querySb.append(" FROM ");
......@@ -431,9 +431,9 @@ public abstract class DBBrokerTemplate implements DBBroker {
while (rs.next()) {
Map<String, Object> item = new HashMap<>();
for (PropertyModel pm : tableModel.getProperties().values()) {
Object value = TSMUtil.getObject(rs, pm.getName(), pm.getJavaType());
item.put(pm.getName(), value);
for (ColumnModel cm : tableModel.getColumns()) {
Object value = TSMUtil.getObject(rs, cm.getName(), cm.getJavaType());
item.put(cm.getName(), value);
}
items.add(item);
......@@ -655,10 +655,10 @@ public abstract class DBBrokerTemplate implements DBBroker {
}
private boolean match(TableModel tableModel, List<String> columns) {
if (tableModel.getProperties().size() != columns.size()) {
if (tableModel.getColumns().size() != columns.size()) {
return false;
}
for (PropertyModel propertyModel : tableModel.getProperties().values()) {
for (ColumnModel propertyModel : tableModel.getColumns()) {
String columnName = propertyModel.getName();
if (!columns.contains(columnName)) {
return false;
......@@ -767,6 +767,30 @@ public abstract class DBBrokerTemplate implements DBBroker {
return allColumns;
}
protected abstract Map<String, Map<String, Object>> getAllColumnsOriginalMetadata(String schemaName, String tableName) throws SQLException;
@Override
public Map<String, Map<String, Object>> getAllColumnsMetadata(String schemaName, String tableName, TableModel tableModel, String tapSchemaVersion) throws SQLException {
Map<String, Map<String, Object>> metadata = getAllColumnsOriginalMetadata(schemaName, tableName);
// Overriding data type from models
if (tableModel != null) {
for (Map.Entry<String, Map<String, Object>> entry : metadata.entrySet()) {
String columnName = entry.getKey();
String declaredDataType = tableModel.get(columnName).getType();
String compatibleType = TypesMapping.getCompatibleADQLType(declaredDataType, tapSchemaVersion);
Integer size = (Integer) entry.getValue().get(Column.SIZE_KEY);
if (size != null) {
compatibleType += String.format("(%s)", size);
}
entry.getValue().put(Column.DATATYPE_KEY, compatibleType);
}
}
return metadata;
}
protected String getTapSchemaVersion() {
return tapSchemaVersion;
}
......
......@@ -27,7 +27,7 @@ import it.inaf.ia2.tsm.Key;
import it.inaf.ia2.tsm.TapSchema;
import it.inaf.ia2.tsm.datalayer.ADQL;
import it.inaf.ia2.tsm.datalayer.DBBrokerTemplate;
import it.inaf.ia2.tsm.model.PropertyModel;
import it.inaf.ia2.tsm.model.ColumnModel;
import it.inaf.ia2.tsm.model.TableModel;
import it.inaf.ia2.tsm.model.TypesMapping;
import java.sql.Connection;
......@@ -85,7 +85,7 @@ public class MySQLDBBroker extends DBBrokerTemplate {
}
@Override
public Map<String, Map<String, Object>> getAllColumnsMetadata(String schemaName, String tableName) throws SQLException {
public Map<String, Map<String, Object>> getAllColumnsOriginalMetadata(String schemaName, String tableName) throws SQLException {
Map<String, Map<String, Object>> allColumnsMetadata = new HashMap<>();
......@@ -155,22 +155,22 @@ public class MySQLDBBroker extends DBBrokerTemplate {
querySb.append(" (\n");
boolean first = true;
for (PropertyModel pm : tableModel.getProperties().values()) {
for (ColumnModel cm : tableModel.getColumns()) {
if (!first) {
querySb.append(",\n");
}
first = false;
querySb.append(pm.getName());
querySb.append(cm.getName());
querySb.append(" ");
String mySQLType = TypesMapping.getMySQLTypeFromADQLType(pm.getType());
String mySQLType = TypesMapping.getMySQLTypeFromADQLType(cm.getType()).toUpperCase();
querySb.append(mySQLType);
if (pm.getType().equals(ADQL.VARCHAR.name()) || pm.getType().equals(ADQL.CHAR.name())) {
appendSize(querySb, pm.getSize());
if (mySQLType.equals("VARCHAR") || mySQLType.equals("CHAR")) {
appendSize(querySb, cm.getSize());
}
if (pm.isNullable()) {
if (cm.isNullable()) {
querySb.append(" NULL");
} else {
querySb.append(" NOT NULL");
......
......@@ -27,7 +27,7 @@ import it.inaf.ia2.tsm.Key;
import it.inaf.ia2.tsm.TapSchema;
import it.inaf.ia2.tsm.datalayer.ADQL;
import it.inaf.ia2.tsm.datalayer.DBBrokerTemplate;
import it.inaf.ia2.tsm.model.PropertyModel;
import it.inaf.ia2.tsm.model.ColumnModel;
import it.inaf.ia2.tsm.model.TableModel;
import it.inaf.ia2.tsm.model.TypesMapping;
import java.sql.Connection;
......@@ -48,66 +48,65 @@ import org.slf4j.LoggerFactory;
* @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
*/
public class PostgresDBBroker extends DBBrokerTemplate {
private final static Logger LOG = LoggerFactory.getLogger(PostgresDBBroker.class);
private final String pgDatabaseName;
public PostgresDBBroker(DataSource dataSource, String pgDatabaseName, String tapSchemaVersion) {
super(dataSource, '"', tapSchemaVersion);
this.pgDatabaseName = pgDatabaseName;
}
@Override
protected void createTable(String schemaName, TableModel tableModel, Connection conn) throws SQLException {
StringBuilder querySb = new StringBuilder();
querySb.append("CREATE TABLE IF NOT EXISTS ");
querySb.append(escape(schemaName));
querySb.append(".");
querySb.append(escape(tableModel.getName()));
querySb.append(" (\n");
boolean first = true;
for (PropertyModel pm : tableModel.getProperties().values()) {
for (ColumnModel cm : tableModel.getColumns()) {
if (!first) {
querySb.append(",\n");
}
first = false;
querySb.append(pm.getName());
querySb.append(cm.getName());
querySb.append(" ");
String pgsqlType = TypesMapping.getPostgresSQLTypeFromADQLType(pm.getType());
String pgsqlType = TypesMapping.getPostgresSQLTypeFromADQLType(cm.getType()).toLowerCase();
querySb.append(pgsqlType);
if (pm.getType().equals(ADQL.VARCHAR.name())
|| pm.getType().equals(ADQL.CHAR.name())) {
appendSize(querySb, pm.getSize());
if (pgsqlType.equals("character varying") || pgsqlType.equals("character")) {
appendSize(querySb, cm.getSize());
}
if (pm.isNullable()) {
if (cm.isNullable()) {
querySb.append(" NULL");
} else {
querySb.append(" NOT NULL");
}
}
querySb.append(")");
String query = querySb.toString();
try (Statement stat = conn.createStatement()) {
LOG.debug("Executing query: {}", query);
stat.executeUpdate(query);
}
}
@Override
protected String getAddPrimaryKeyQuery(String tapSchemaName, String tableName, String[] keyColumns) {
return String.format("ALTER TABLE ONLY %s.%s ADD CONSTRAINT %s_pkey PRIMARY KEY (%s)",
escape(tapSchemaName), escape(tableName), tableName, buildColumnsList(keyColumns));
}
@Override
protected String getAddForeignKeyQuery(String tapSchemaName, String tableName, String[] fromKeyColumns, String targetTableName, String[] toKeyColumns) {
// Building univocal constraint name
......@@ -120,12 +119,12 @@ public class PostgresDBBroker extends DBBrokerTemplate {
escape(tapSchemaName), escape(tableName), constraintNameSb.toString(), buildColumnsList(fromKeyColumns),
escape(tapSchemaName), escape(targetTableName), buildColumnsList(toKeyColumns));
}
@Override
protected String getCreateDatabaseQuery(String databaseName) {
return "CREATE SCHEMA IF NOT EXISTS " + escape(databaseName);
}
@Override
protected String getSchemaTablesQuery(String schemaName) {
return String.format("SELECT tablename FROM pg_catalog.pg_tables where schemaname = '%s'", schemaName);
......@@ -145,14 +144,14 @@ public class PostgresDBBroker extends DBBrokerTemplate {
}
return sb.toString();
}
@Override
public Map<String, Map<String, Object>> getAllColumnsMetadata(String schemaName, String tableSimpleName) throws SQLException {
public Map<String, Map<String, Object>> getAllColumnsOriginalMetadata(String schemaName, String tableSimpleName) throws SQLException {
Map<String, Map<String, Object>> allColumnsMetadata = new HashMap<>();
StringBuilder querySb = new StringBuilder();
querySb.append("SELECT c.column_name, c.data_type, pg_catalog.format_type(a.atttypid, a.atttypmod), r.contype AS column_type, c.character_maximum_length, c.numeric_precision, a.attndims AS arraydim\n");
querySb.append("FROM information_schema.columns c\n");
querySb.append("JOIN pg_catalog.pg_tables t ON c.table_schema = t.schemaname AND c.table_name = t.tablename\n");
......@@ -163,16 +162,16 @@ public class PostgresDBBroker extends DBBrokerTemplate {
querySb.append("' AND t.tablename = '");
querySb.append(tableSimpleName);
querySb.append("'");
String query = querySb.toString();
LOG.debug("Executing query {}", query);
try (Connection conn = dataSource.getConnection();
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery(query)) {
while (resultSet.next()) {
Map<String, Object> cm = new HashMap<>();
// Column name
......@@ -193,11 +192,11 @@ public class PostgresDBBroker extends DBBrokerTemplate {
}
cm.put(Column.PRIMARY_KEY, primaryKey);
cm.put(Column.INDEXED_KEY, indexed);
Integer size = null;
int arraydimension = 0;
String datatype;
String type = resultSet.getString("data_type").toUpperCase();
boolean isArray = false;
if ("ARRAY".equals(type)) {
......@@ -209,7 +208,7 @@ public class PostgresDBBroker extends DBBrokerTemplate {
// numbers inside brakets, so this case will be approximated to *x*
arraydimension = resultSet.getInt("arraydim");
}
datatype = TypesMapping.getADQLTypeFromPostgresType(type, getTapSchemaVersion());
if (!isArray && (datatype.equals(ADQL.VARCHAR.name()) || datatype.equals(ADQL.CHAR.name()))) {
size = resultSet.getInt("character_maximum_length");
......@@ -218,10 +217,10 @@ public class PostgresDBBroker extends DBBrokerTemplate {
// Adding size at the end of datatype
datatype += String.format("(%s)", size);
}
cm.put(Column.DATATYPE_KEY, datatype);
cm.put(Column.SIZE_KEY, size);
String arraySize = null;
if (isArray) {
arraySize = formatArraySize(arraydimension);
......@@ -232,21 +231,21 @@ public class PostgresDBBroker extends DBBrokerTemplate {
arraySize += "*";
}
}
cm.put(Column.ARRAYSIZE_KEY, arraySize);
allColumnsMetadata.put(columnName, cm);
}
}
return allColumnsMetadata;
}
@Override
public List<Key> getKeys(TapSchema tapSchema, String schemaName) throws SQLException {
StringBuilder queryKeysSb = new StringBuilder();
queryKeysSb.append("SELECT\n");
queryKeysSb.append("conname AS constraint_name,\n");
queryKeysSb.append("conrelid::regclass AS from_table, \n");
......@@ -259,33 +258,33 @@ public class PostgresDBBroker extends DBBrokerTemplate {
queryKeysSb.append("OR (confrelid::regclass || '' LIKE '");
queryKeysSb.append(schemaName);
queryKeysSb.append(".%'))");
String queryKeys = queryKeysSb.toString();
try (Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(queryKeys)) {
LOG.debug("Executing query {}", queryKeys);
List<Key> keys = new ArrayList<>();
while (resultSet.next()) {
String constraintName = resultSet.getString("constraint_name");
String fromTableCompleteName = resultSet.getString("from_table");
String targetTableCompleteName = resultSet.getString("target_table");
String fromSchema = fromTableCompleteName.split(Pattern.quote("."))[0];
String targetSchema = targetTableCompleteName.split(Pattern.quote("."))[0];
Map<String, Object> keyMetadata = new HashMap<>();
keyMetadata.put(Key.FROM_TABLE_KEY, fromTableCompleteName);
keyMetadata.put(Key.TARGET_TABLE_KEY, targetTableCompleteName);
Key key = new Key(tapSchema, keyMetadata);
keys.add(key);
StringBuilder queryFromKCSb = new StringBuilder();
queryFromKCSb.append("SELECT\n");
queryFromKCSb.append("c.column_name AS key_column\n");
......@@ -303,7 +302,7 @@ public class PostgresDBBroker extends DBBrokerTemplate {
// conkey conrelid
String queryFromKC = queryFromKCSb.toString();
StringBuilder queryTargetKCSb = new StringBuilder();
queryTargetKCSb.append("SELECT\n");
queryTargetKCSb.append("c.column_name AS key_column\n");
......@@ -321,16 +320,16 @@ public class PostgresDBBroker extends DBBrokerTemplate {
// as above, but with confkey and confrelid and different c.table_schema where condition
String queryTargetKC = queryTargetKCSb.toString();
try (Statement statFromKC = connection.createStatement();
Statement statTargetKC = connection.createStatement()) {
try (ResultSet rsFromKC = statFromKC.executeQuery(queryFromKC);
ResultSet rsTargetKC = statTargetKC.executeQuery(queryTargetKC)) {
LOG.debug("Executing query {}", queryFromKC);
LOG.debug("Executing query {}", queryTargetKC);
while (rsFromKC.next()) {
if (rsTargetKC.next()) {
key.addKeyColumn(
......@@ -342,11 +341,11 @@ public class PostgresDBBroker extends DBBrokerTemplate {
}
<