Skip to content
Snippets Groups Projects
Commit ef21098f authored by Thomas Mortagne's avatar Thomas Mortagne
Browse files

XWIKI-19121: Sub tables are not migrated to DYNAMIC RAW type

parent d2e3aed0
No related branches found
No related tags found
No related merge requests found
...@@ -23,8 +23,10 @@ ...@@ -23,8 +23,10 @@
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
...@@ -163,8 +165,8 @@ private void appendXmlAttribute(String property, String value, StringBuilder str ...@@ -163,8 +165,8 @@ private void appendXmlAttribute(String property, String value, StringBuilder str
stringBuilder.append("\" "); stringBuilder.append("\" ");
} }
private void updateColumn(Column column, DatabaseMetaData databaseMetaData, StringBuilder builder) private void updateColumn(Column column, DatabaseMetaData databaseMetaData, Set<String> dynamicTables,
throws SQLException StringBuilder builder) throws SQLException, DataMigrationException
{ {
int expectedLenght = column.getLength(); int expectedLenght = column.getLength();
...@@ -173,7 +175,7 @@ private void updateColumn(Column column, DatabaseMetaData databaseMetaData, Stri ...@@ -173,7 +175,7 @@ private void updateColumn(Column column, DatabaseMetaData databaseMetaData, Stri
// Skip the update if the column does not exist of if its size if greater or equals already // Skip the update if the column does not exist of if its size if greater or equals already
if (databaseSize != null && databaseSize.intValue() < expectedLenght) { if (databaseSize != null && databaseSize.intValue() < expectedLenght) {
update(column, builder); update(column, dynamicTables, builder);
} }
} }
} }
...@@ -198,27 +200,28 @@ private Integer getDatabaseSize(Column column, DatabaseMetaData databaseMetaData ...@@ -198,27 +200,28 @@ private Integer getDatabaseSize(Column column, DatabaseMetaData databaseMetaData
return null; return null;
} }
private void updateProperty(Property property, DatabaseMetaData databaseMetaData, StringBuilder builder) private void updateProperty(Property property, DatabaseMetaData databaseMetaData, Set<String> dynamicTables,
throws SQLException StringBuilder builder) throws SQLException, DataMigrationException
{ {
if (property != null) { if (property != null) {
updateValue(property.getValue(), databaseMetaData, builder); updateValue(property.getValue(), databaseMetaData, dynamicTables, builder);
} }
} }
private void updateValue(Value value, DatabaseMetaData databaseMetaData, StringBuilder builder) throws SQLException private void updateValue(Value value, DatabaseMetaData databaseMetaData, Set<String> dynamicTables,
StringBuilder builder) throws SQLException, DataMigrationException
{ {
if (value instanceof Collection) { if (value instanceof Collection) {
Table collectionTable = ((Collection) value).getCollectionTable(); Table collectionTable = ((Collection) value).getCollectionTable();
for (Iterator<Column> it = collectionTable.getColumnIterator(); it.hasNext();) { for (Iterator<Column> it = collectionTable.getColumnIterator(); it.hasNext();) {
updateColumn(it.next(), databaseMetaData, builder); updateColumn(it.next(), databaseMetaData, dynamicTables, builder);
} }
} else if (value != null) { } else if (value != null) {
for (Iterator<Selectable> it = value.getColumnIterator(); it.hasNext();) { for (Iterator<Selectable> it = value.getColumnIterator(); it.hasNext();) {
Selectable selectable = it.next(); Selectable selectable = it.next();
if (selectable instanceof Column) { if (selectable instanceof Column) {
updateColumn((Column) selectable, databaseMetaData, builder); updateColumn((Column) selectable, databaseMetaData, dynamicTables, builder);
} }
} }
} }
...@@ -312,31 +315,40 @@ public List<String> doInHibernate(Session session) throws HibernateException, XW ...@@ -312,31 +315,40 @@ public List<String> doInHibernate(Session session) throws HibernateException, XW
private void updateColumns(DatabaseMetaData databaseMetaData, StringBuilder builder) private void updateColumns(DatabaseMetaData databaseMetaData, StringBuilder builder)
throws SQLException, DataMigrationException throws SQLException, DataMigrationException
{ {
Set<String> dynamicTables = new HashSet<>();
for (PersistentClass entity : this.hibernateStore.getConfigurationMetadata().getEntityBindings()) { for (PersistentClass entity : this.hibernateStore.getConfigurationMetadata().getEntityBindings()) {
// Check if the table exist // Check if the table exist
if (exists(entity, databaseMetaData)) { if (exists(entity, databaseMetaData)) {
if (this.hibernateStore.getDatabaseProductName() == DatabaseProduct.MYSQL) { if (this.hibernateStore.getDatabaseProductName() == DatabaseProduct.MYSQL) {
// Make sure all MySQL/MariaDB tables use a DYNAMIC row format (required to support key prefix // Make sure all MySQL/MariaDB tables use a DYNAMIC row format (required to support key prefix
// length limit up to 3072 bytes) // length limit up to 3072 bytes)
setTableDYNAMIC(entity, builder); setTableDYNAMIC(entity, builder, dynamicTables);
} }
// Find properties to update // Find properties to update
for (Iterator<Property> it = entity.getPropertyIterator(); it.hasNext();) { for (Iterator<Property> it = entity.getPropertyIterator(); it.hasNext();) {
updateProperty(it.next(), databaseMetaData, builder); updateProperty(it.next(), databaseMetaData, dynamicTables, builder);
} }
// Check the key // Check the key
updateValue(entity.getKey(), databaseMetaData, builder); updateValue(entity.getKey(), databaseMetaData, dynamicTables, builder);
} }
} }
} }
private void setTableDYNAMIC(PersistentClass entity, StringBuilder builder) throws DataMigrationException private void setTableDYNAMIC(PersistentClass entity, StringBuilder builder, Set<String> dynamicTables)
throws DataMigrationException
{ {
String tableName = this.hibernateStore.getConfiguredTableName(entity); String tableName = this.hibernateStore.getConfiguredTableName(entity);
if (!StringUtils.equalsIgnoreCase(getRowFormat(tableName), "Dynamic")) { setTableDYNAMIC(tableName, builder, dynamicTables);
}
private void setTableDYNAMIC(String tableName, StringBuilder builder, Set<String> dynamicTables)
throws DataMigrationException
{
if (!dynamicTables.contains(tableName) && !StringUtils.equalsIgnoreCase(getRowFormat(tableName), "Dynamic")) {
builder.append("<sql>"); builder.append("<sql>");
builder.append("ALTER TABLE "); builder.append("ALTER TABLE ");
builder.append(tableName); builder.append(tableName);
...@@ -353,8 +365,8 @@ private String getRowFormat(String tableName) throws DataMigrationException ...@@ -353,8 +365,8 @@ private String getRowFormat(String tableName) throws DataMigrationException
@Override @Override
public String doInHibernate(Session session) throws HibernateException, XWikiException public String doInHibernate(Session session) throws HibernateException, XWikiException
{ {
NativeQuery<String> query = session NativeQuery<String> query =
.createNativeQuery("SELECT DISTINCT ROW_FORMAT FROM INFORMATION_SCHEMA.TABLES " session.createNativeQuery("SELECT DISTINCT ROW_FORMAT FROM INFORMATION_SCHEMA.TABLES "
+ "WHERE TABLE_SCHEMA = :schema AND TABLE_NAME = :table"); + "WHERE TABLE_SCHEMA = :schema AND TABLE_NAME = :table");
query.setParameter("schema", hibernateStore.getDatabaseFromWikiName()); query.setParameter("schema", hibernateStore.getDatabaseFromWikiName());
query.setParameter("table", tableName); query.setParameter("table", tableName);
...@@ -382,30 +394,20 @@ private boolean exists(PersistentClass entity, DatabaseMetaData databaseMetaData ...@@ -382,30 +394,20 @@ private boolean exists(PersistentClass entity, DatabaseMetaData databaseMetaData
return resultSet.next(); return resultSet.next();
} }
private ResultSet getTables(PersistentClass entity, DatabaseMetaData databaseMetaData) throws SQLException private void update(Column column, Set<String> dynamicTables, StringBuilder builder) throws DataMigrationException
{
String databaseName = this.hibernateStore.getDatabaseFromWikiName();
String tableName = this.hibernateStore.getConfiguredTableName(entity);
ResultSet resultSet;
if (this.hibernateStore.isCatalog()) {
resultSet = databaseMetaData.getTables(databaseName, null, tableName, null);
} else {
resultSet = databaseMetaData.getTables(null, databaseName, tableName, null);
}
return resultSet;
}
private void update(Column column, StringBuilder builder)
{ {
if (this.hibernateStore.getDatabaseProductName() == DatabaseProduct.MYSQL) { if (this.hibernateStore.getDatabaseProductName() == DatabaseProduct.MYSQL) {
// Not using <modifyDataType> here because Liquibase ignores attributes likes "NOT NULL"
builder.append("<sql>");
JdbcEnvironment jdbcEnvironment = JdbcEnvironment jdbcEnvironment =
this.hibernateStore.getConfigurationMetadata().getDatabase().getJdbcEnvironment(); this.hibernateStore.getConfigurationMetadata().getDatabase().getJdbcEnvironment();
String tableName = jdbcEnvironment.getQualifiedObjectNameFormatter() String tableName = jdbcEnvironment.getQualifiedObjectNameFormatter()
.format(column.getValue().getTable().getQualifiedTableName(), this.hibernateStore.getDialect()); .format(column.getValue().getTable().getQualifiedTableName(), this.hibernateStore.getDialect());
// Make sure all MySQL/MariaDB tables use a DYNAMIC row format (required to support key prefix
// length limit up to 3072 bytes)
setTableDYNAMIC(tableName, builder, dynamicTables);
// Not using <modifyDataType> here because Liquibase ignores attributes likes "NOT NULL"
builder.append("<sql>");
builder.append(this.hibernateStore.getDialect().getAlterTableString(tableName)); builder.append(this.hibernateStore.getDialect().getAlterTableString(tableName));
builder.append(" MODIFY "); builder.append(" MODIFY ");
builder.append(column.getQuotedName(this.hibernateStore.getDialect())); builder.append(column.getQuotedName(this.hibernateStore.getDialect()));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment