Skip to content

Commit

Permalink
Add AlterCluster change
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaliimak committed Jul 23, 2024
1 parent 3b12076 commit 5edc190
Show file tree
Hide file tree
Showing 12 changed files with 412 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package liquibase.ext.databricks.change.alterCluster;

import liquibase.change.AbstractChange;
import liquibase.change.DatabaseChange;
import liquibase.change.DatabaseChangeProperty;
import liquibase.database.Database;
import liquibase.exception.ValidationErrors;
import liquibase.servicelocator.PrioritizedService;
import liquibase.statement.SqlStatement;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

@DatabaseChange(name = "alterCluster", description = "Alter Cluster", priority = PrioritizedService.PRIORITY_DATABASE +500)
public class AlterClusterChangeDatabricks extends AbstractChange {

private String tableName;
private String catalogName;
private String schemaName;
private List<ColumnConfig> columns;
private List<NoneConfig> clusterBy;

@Override
public ValidationErrors validate(Database database) {
ValidationErrors validationErrors = new ValidationErrors();
validationErrors.addAll(super.validate(database));

if (columns == null && clusterBy == null) {
validationErrors.addError("Alter Cluster change require list of columns or element 'ClusterBy', please add at least one option.");
}
return validationErrors;
}

public AlterClusterChangeDatabricks() {
super();
columns = new ArrayList<>();
clusterBy = new ArrayList<>();
}

@Override
public String getConfirmationMessage() {
return MessageFormat.format("{0}.{1}.{2} successfully altered.", getCatalogName(), getSchemaName(), getTableName());
}

@Override
public SqlStatement[] generateStatements(Database database) {
AlterClusterDatabricksStatement statement = new AlterClusterDatabricksStatement(tableName, catalogName, schemaName);
if (getColumns() != null && !getColumns().isEmpty()) {
statement.setColumns(getColumns());
} else if (getClusterBy() != null && !getClusterBy().isEmpty()) {
statement.setClusterBy(getClusterBy());
}
return new SqlStatement[]{statement};
}

@DatabaseChangeProperty
public String getTableName() {
return tableName;
}

public void setTableName(String tableName) {
this.tableName = tableName;
}

@DatabaseChangeProperty
public List<ColumnConfig> getColumns() {
if (columns == null) {
return new ArrayList<>();
}
return columns;
}

public void setColumns(List<ColumnConfig> columns) {
this.columns = columns;
}

@DatabaseChangeProperty
public String getCatalogName() {
return catalogName;
}

public void setCatalogName(String catalogName) {
this.catalogName = catalogName;
}

@DatabaseChangeProperty
public String getSchemaName() {
return schemaName;
}

public void setSchemaName(String schemaName) {
this.schemaName = schemaName;
}

@DatabaseChangeProperty
public List<NoneConfig> getClusterBy() {
if (clusterBy == null) {
return new ArrayList<>();
}
return clusterBy;
}

public void setClusterBy(List<NoneConfig> clusterBy) {
this.clusterBy = clusterBy;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package liquibase.ext.databricks.change.alterCluster;

import liquibase.statement.AbstractSqlStatement;

import java.util.List;

public class AlterClusterDatabricksStatement extends AbstractSqlStatement {

private String tableName;
private String catalogName;
private String schemaName;
private List<ColumnConfig> columns;
private List<NoneConfig> clusterBy;

public AlterClusterDatabricksStatement(String tableName, String catalogName, String schemaName) {
this.tableName = tableName;
this.catalogName = catalogName;
this.schemaName = schemaName;
}

public String getTableName() {
return tableName;
}

public void setTableName(String tableName) {
this.tableName = tableName;
}

public List<ColumnConfig> getColumns() {
return columns;
}

public void setColumns(List<ColumnConfig> columns) {
this.columns = columns;
}

public String getCatalogName() {
return catalogName;
}

public void setCatalogName(String catalogName) {
this.catalogName = catalogName;
}

public String getSchemaName() {
return schemaName;
}

public void setSchemaName(String schemaName) {
this.schemaName = schemaName;
}

public List<NoneConfig> getClusterBy() {
return clusterBy;
}

public void setClusterBy(List<NoneConfig> clusterBy) {
this.clusterBy = clusterBy;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package liquibase.ext.databricks.change.alterCluster;

import liquibase.serializer.AbstractLiquibaseSerializable;

public class ColumnConfig extends AbstractLiquibaseSerializable {

private String name;

@Override
public String getSerializedObjectName() {
return "column";
}

@Override
public String getSerializedObjectNamespace() {
return "http://www.liquibase.org/xml/ns/databricks";
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package liquibase.ext.databricks.change.alterCluster;

import liquibase.serializer.AbstractLiquibaseSerializable;

public class NoneConfig extends AbstractLiquibaseSerializable {

private String none;

@Override
public String getSerializedObjectName() {
return "clusterBy";
}

@Override
public String getSerializedObjectNamespace() {
return "http://www.liquibase.org/xml/ns/databricks";
}

public String getNone() {
return none;
}

public void setNone(String none) {
this.none = none;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package liquibase.ext.databricks.sqlgenerator;

import liquibase.database.Database;
import liquibase.exception.ValidationErrors;
import liquibase.ext.databricks.change.alterCluster.AlterClusterDatabricksStatement;
import liquibase.ext.databricks.change.alterCluster.ColumnConfig;
import liquibase.sql.Sql;
import liquibase.sql.UnparsedSql;
import liquibase.sqlgenerator.SqlGeneratorChain;
import liquibase.sqlgenerator.core.AbstractSqlGenerator;

public class AlterClusterGeneratorDatabricks extends AbstractSqlGenerator<AlterClusterDatabricksStatement> {
@Override
public ValidationErrors validate(AlterClusterDatabricksStatement statement, Database database, SqlGeneratorChain<AlterClusterDatabricksStatement> sqlGeneratorChain) {
ValidationErrors validationErrors = new ValidationErrors();
if (statement.getClusterBy() == null && statement.getColumns() == null){
validationErrors.addError("WARNING! Alter Cluster change require list of columns or element 'ClusterBy', please add at least one option.");
}
if (statement.getClusterBy() != null && (statement.getClusterBy().isEmpty() || !statement.getClusterBy().get(0).getNone().equals("true"))) {
validationErrors.addError("WARNING! ClusterBy attribute require attribute 'none=\"true\"'");
}
return validationErrors;
}

@Override
public Sql[] generateSql(AlterClusterDatabricksStatement statement, Database database, SqlGeneratorChain<AlterClusterDatabricksStatement> sqlGeneratorChain) {
StringBuilder buffer = new StringBuilder();

buffer.append("ALTER TABLE ");
buffer.append(database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()));
buffer.append(" CLUSTER BY ");
if (statement.getColumns() != null && !statement.getColumns().isEmpty()) {
buffer.append("(");
for (ColumnConfig column : statement.getColumns()) {
buffer.append(column.getName());
buffer.append(",");
}
buffer.deleteCharAt(buffer.length() - 1);
buffer.append(")");
} else if (statement.getClusterBy() != null && !statement.getClusterBy().isEmpty()) {
buffer.append("NONE");
}

return new Sql[]{
new UnparsedSql(buffer.toString())
};
}

}
3 changes: 2 additions & 1 deletion src/main/resources/META-INF/services/liquibase.change.Change
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ liquibase.ext.databricks.change.analyzeTable.AnalyzeTableChange
liquibase.ext.databricks.change.vacuumTable.VacuumTableChange
liquibase.ext.databricks.change.addLookupTable.AddLookupTableChangeDatabricks
liquibase.ext.databricks.change.addCheckConstraint.AddCheckConstraintChangeDatabricks
liquibase.ext.databricks.change.dropCheckConstraint.DropCheckConstraintChangeDatabricks
liquibase.ext.databricks.change.dropCheckConstraint.DropCheckConstraintChangeDatabricks
liquibase.ext.databricks.change.alterCluster.AlterClusterChangeDatabricks
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ liquibase.ext.databricks.sqlgenerator.AddUniqueConstraintGeneratorDatabricks
liquibase.ext.databricks.sqlgenerator.InsertOrUpdateGeneratorDatabricks
liquibase.ext.databricks.sqlgenerator.UpdateGeneratorDatabricks
liquibase.ext.databricks.change.addCheckConstraint.AddCheckConstraintGeneratorDatabricks
liquibase.ext.databricks.change.dropCheckConstraint.DropCheckConstraintGeneratorDatabricks
liquibase.ext.databricks.change.dropCheckConstraint.DropCheckConstraintGeneratorDatabricks
liquibase.ext.databricks.sqlgenerator.AlterClusterGeneratorDatabricks
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,48 @@
<xsd:attribute name="tblProperties" type="xsd:string"/>
</xsd:complexType>
</xsd:element>

<xsd:element name="alterCluster">
<xsd:complexType>
<xsd:choice maxOccurs="1" minOccurs="1">
<xsd:sequence >
<xsd:element ref="column" maxOccurs="unbounded"/>
<xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element ref="clusterBy" maxOccurs="1"/>
<xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:choice>
<xsd:attribute name="tableName" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>

<xsd:element name="column">
<xsd:complexType mixed="true">
<xsd:attributeGroup ref="column"/>
<xsd:anyAttribute namespace="##other" processContents="lax"/>
</xsd:complexType>
</xsd:element>

<xsd:attributeGroup name="column">
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:attributeGroup>

<xsd:element name="clusterBy">
<xsd:complexType mixed="true">
<xsd:attributeGroup ref="clusterBy"/>
<xsd:anyAttribute namespace="##other" processContents="lax"/>
</xsd:complexType>
</xsd:element>

<xsd:attributeGroup name="clusterBy">
<xsd:attribute name="none" type="noneClusterBy" use="required"/>
</xsd:attributeGroup>

<xsd:simpleType name="noneClusterBy">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="true"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,48 @@
<xsd:attribute name="tblProperties" type="xsd:string"/>
</xsd:complexType>
</xsd:element>

<xsd:element name="alterCluster">
<xsd:complexType>
<xsd:choice maxOccurs="1" minOccurs="1">
<xsd:sequence >
<xsd:element ref="column" maxOccurs="unbounded"/>
<xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element ref="clusterBy" maxOccurs="1"/>
<xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:choice>
<xsd:attribute name="tableName" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>

<xsd:element name="column">
<xsd:complexType mixed="true">
<xsd:attributeGroup ref="column"/>
<xsd:anyAttribute namespace="##other" processContents="lax"/>
</xsd:complexType>
</xsd:element>

<xsd:attributeGroup name="column">
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:attributeGroup>

<xsd:element name="clusterBy">
<xsd:complexType mixed="true">
<xsd:attributeGroup ref="clusterBy"/>
<xsd:anyAttribute namespace="##other" processContents="lax"/>
</xsd:complexType>
</xsd:element>

<xsd:attributeGroup name="clusterBy">
<xsd:attribute name="none" type="noneClusterBy" use="required"/>
</xsd:attributeGroup>

<xsd:simpleType name="noneClusterBy">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="true"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
Loading

0 comments on commit 5edc190

Please sign in to comment.