Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;

public class Column {

Expand All @@ -24,6 +25,7 @@ public class Column {
private List<ColumnProperties> columnProperties = new ArrayList<>();
private Tests tests;
private List<ForeignKey> foreignKeys;
private Set<Extension> extensions;

public Column() {
}
Expand Down Expand Up @@ -162,4 +164,12 @@ public Tests getTests() {
public void setTests(Tests tests) {
this.tests = tests;
}

public Set<Extension> getExtensions() {
return extensions;
}

public void setExtensions(Set<Extension> extensions) {
this.extensions = extensions;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.adaptivescale.rosetta.common.models;


import com.adaptivescale.rosetta.common.models.enums.ExtensionTypesEnum;

import java.util.Map;

public class Extension {
private String name;
private ExtensionTypesEnum type;
private Map<String,Object> actions;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public ExtensionTypesEnum getType() {
return type;
}

public void setType(ExtensionTypesEnum type) {
this.type = type;
}

public Map<String, Object> getActions() {
return actions;
}

public void setActions(Map<String, Object> actions) {
this.actions = actions;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.adaptivescale.rosetta.common.models;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.*;

public class Table {

Expand All @@ -17,6 +15,8 @@ public class Table {

private Collection<Column> columns;

private Set<Extension> extensions;

public String getName() {
return name;
}
Expand Down Expand Up @@ -74,7 +74,15 @@ public void setIndices(List<Index> indices) {
this.indices = indices;
}

@Override
public Set<Extension> getExtensions() {
return extensions;
}

public void setExtensions(Set<Extension> extensions) {
this.extensions = extensions;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.adaptivescale.rosetta.common.models.enums;

public enum ExtensionTypesEnum {
DDL_EXTENSION,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.adaptivescale.rosetta.common.models.enums;

public enum OperationTypeEnum {
PRE_CREATE,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everywhere in YAML we use camelCase, this part uses all UPPERCASE and _. This part does not make uniform the model.yaml structure.

Any opinion on this?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went through with uppercase because of it being an Enum Class, but i am open to changing if needed

PRE_ALTER,
PRE_DROP,
POST_CREATE,
POST_ALTER,
POST_DROP
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ public enum RosettaModuleTypes {
TABLE_EXTRACTOR,
VIEW_EXTRACTOR,
DIFF_TESTER,
DDL_EXTENSION_TABLE,
DDL_EXTENSION_COLUMN,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.adaptivescale.rosetta.ddl;

import com.adaptivescale.rosetta.common.models.Column;


public interface DDLExtensionColumn {

String preCreateColumn(Column column, Object action);
String postCreateColumn(Column column, Object action);

String preDropColumn(Column column, Object action);
String postDropColumn(Column column, Object action);

String preAlterColumn(Column column, Object action);
String postAlterColumn(Column column, Object action);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.adaptivescale.rosetta.ddl;

import com.adaptivescale.rosetta.common.models.*;
import com.adaptivescale.rosetta.ddl.change.model.ColumnChange;
import com.adaptivescale.rosetta.ddl.change.model.ForeignKeyChange;


public interface DDLExtensionTable {

String preCreateTable(Table table, Object action);
String postCreateTable(Table table, Object action);

String preDropTable(Table actual, Object action);
String postDropTable(Table actual, Object action);

String preAlterTable(Table expected, Object action);
String postAlterTable(Table expected, Object action);

}
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package com.adaptivescale.rosetta.ddl.change;

import com.adaptivescale.rosetta.common.helpers.ModuleLoader;
import com.adaptivescale.rosetta.common.models.Column;
import com.adaptivescale.rosetta.common.models.Extension;
import com.adaptivescale.rosetta.common.models.Table;
import com.adaptivescale.rosetta.common.models.enums.OperationTypeEnum;
import com.adaptivescale.rosetta.common.types.RosettaModuleTypes;
import com.adaptivescale.rosetta.ddl.DDL;
import com.adaptivescale.rosetta.ddl.DDLExtensionColumn;
import com.adaptivescale.rosetta.ddl.DDLExtensionTable;
import com.adaptivescale.rosetta.ddl.change.model.*;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

import static com.adaptivescale.rosetta.common.models.enums.OperationTypeEnum.*;

@Slf4j
public class ChangeHandlerImplementation implements ChangeHandler {
Expand All @@ -21,7 +30,7 @@ public ChangeHandlerImplementation(DDL ddl, Comparator<Change<?>> changeComparat

@Override
public String createDDLForChanges(List<Change<?>> changes) {
if(changeComparator != null){
if (changeComparator != null) {
changes.sort(changeComparator);
}

Expand Down Expand Up @@ -69,11 +78,53 @@ public String onDatabaseChange(DatabaseChange databaseChange) {
public String onTableChange(TableChange change) {
switch (change.getStatus()) {
case DROP:
return ddl.dropTable(change.getActual());
StringBuilder dropQueryBuilder = new StringBuilder();
if (change.getExpected() != null && change.getExpected().getExtensions() != null) {
Optional<Extension> first = change.getExpected().getExtensions().stream()
.filter(extension -> extension.getActions().containsKey(PRE_DROP.name())).findFirst();
first.ifPresent(extension -> dropQueryBuilder.append(executeTableExtensions(change.getExpected(), PRE_DROP, extension.getActions().get(PRE_DROP.name()))));
}

dropQueryBuilder.append(ddl.dropTable(change.getActual()));

if (change.getExpected() != null && change.getExpected().getExtensions() != null) {
Optional<Extension> first = change.getExpected().getExtensions().stream()
.filter(extension -> extension.getActions().containsKey(POST_DROP.name())).findFirst();
first.ifPresent(extension -> dropQueryBuilder.append(executeTableExtensions(change.getExpected(), POST_DROP, extension.getActions().get(POST_DROP.name()))));
}
return dropQueryBuilder.toString();
case ADD:
return ddl.createTable(change.getExpected(), false);
StringBuilder addQueryBuilder = new StringBuilder();
if (change.getExpected() != null && change.getExpected().getExtensions() != null) {
Optional<Extension> first = change.getExpected().getExtensions().stream()
.filter(extension -> extension.getActions().containsKey(PRE_CREATE.name())).findFirst();
first.ifPresent(extension -> addQueryBuilder.append(executeTableExtensions(change.getExpected(), PRE_CREATE, extension.getActions().get(PRE_CREATE.name()))));
}

addQueryBuilder.append(ddl.createTable(change.getExpected(), false));

if (change.getExpected() != null && change.getExpected().getExtensions() != null) {
Optional<Extension> first = change.getExpected().getExtensions().stream()
.filter(extension -> extension.getActions().containsKey(POST_CREATE.name())).findFirst();
first.ifPresent(extension -> addQueryBuilder.append(executeTableExtensions(change.getExpected(), POST_CREATE, extension.getActions().get(POST_CREATE.name()))));
}
return addQueryBuilder.toString();
case ALTER:
return ddl.alterTable(change.getExpected(), change.getActual());
StringBuilder alterQueryBuilder = new StringBuilder();
if (change.getExpected() != null && change.getExpected().getExtensions() != null) {
Optional<Extension> first = change.getExpected().getExtensions().stream()
.filter(extension -> extension.getActions().containsKey(PRE_ALTER.name())).findFirst();
first.ifPresent(extension -> alterQueryBuilder.append(executeTableExtensions(change.getExpected(), PRE_ALTER, extension.getActions().get(PRE_ALTER.name()))));
}

alterQueryBuilder.append(ddl.alterTable(change.getExpected(), change.getActual()));

if (change.getExpected() != null && change.getExpected().getExtensions() != null) {
Optional<Extension> first = change.getExpected().getExtensions().stream()
.filter(extension -> extension.getActions().containsKey(POST_ALTER.name())).findFirst();
first.ifPresent(extension -> alterQueryBuilder.append(executeTableExtensions(change.getExpected(), POST_ALTER, extension.getActions().get(POST_ALTER.name()))));
}
return alterQueryBuilder.toString();
default:
throw new RuntimeException("Operation " + change.getStatus() + " for table not supported");
}
Expand All @@ -93,16 +144,123 @@ public String onTableSchemaChange(TableSchemaChange change) {
public String onColumnChange(ColumnChange change) {
switch (change.getStatus()) {
case ALTER:
return ddl.alterColumn(change);
StringBuilder alterQueryBuilder = new StringBuilder();
if (change.getExpected() != null && change.getExpected().getExtensions() != null) {
Optional<Extension> first = change.getExpected().getExtensions().stream()
.filter(extension -> extension.getActions().containsKey(PRE_ALTER.name())).findFirst();
first.ifPresent(extension -> alterQueryBuilder.append(executeColumnExtensions(change.getExpected(), PRE_ALTER, extension.getActions().get(PRE_ALTER.name()))));
}

alterQueryBuilder.append(ddl.alterColumn(change));

if (change.getExpected() != null && change.getExpected().getExtensions() != null) {
Optional<Extension> first = change.getExpected().getExtensions().stream()
.filter(extension -> extension.getActions().containsKey(POST_ALTER.name())).findFirst();
first.ifPresent(extension -> alterQueryBuilder.append(executeColumnExtensions(change.getExpected(), POST_ALTER, extension.getActions().get(POST_ALTER.name()))));
}
return alterQueryBuilder.toString();
case DROP:
return ddl.dropColumn(change);
StringBuilder dropQueryBuilder = new StringBuilder();
if (change.getActual() != null && change.getActual().getExtensions() != null) {
Optional<Extension> first = change.getActual().getExtensions().stream()
.filter(extension -> extension.getActions().containsKey(PRE_DROP.name())).findFirst();
first.ifPresent(extension -> dropQueryBuilder.append(executeColumnExtensions(change.getActual(), PRE_DROP, extension.getActions().get(PRE_DROP.name()))));
}
dropQueryBuilder.append(ddl.dropColumn(change));
if (change.getActual() != null && change.getActual().getExtensions() != null) {
Optional<Extension> first = change.getActual().getExtensions().stream()
.filter(extension -> extension.getActions().containsKey(POST_DROP.name())).findFirst();
first.ifPresent(extension -> dropQueryBuilder.append(executeColumnExtensions(change.getActual(), POST_DROP, extension.getActions().get(POST_DROP.name()))));
}
return dropQueryBuilder.toString();
case ADD:
return ddl.addColumn(change);
StringBuilder addQueryBuilder = new StringBuilder();
if (change.getExpected() != null && change.getExpected().getExtensions() != null) {
Optional<Extension> first = change.getExpected().getExtensions().stream()
.filter(extension -> extension.getActions().containsKey(PRE_CREATE.name())).findFirst();
first.ifPresent(extension -> addQueryBuilder.append(executeColumnExtensions(change.getExpected(), PRE_CREATE, extension.getActions().get(PRE_CREATE.name()))));
}
addQueryBuilder.append(ddl.addColumn(change));

if (change.getExpected() != null && change.getExpected().getExtensions() != null) {
Optional<Extension> first = change.getExpected().getExtensions().stream()
.filter(extension -> extension.getActions().containsKey(POST_CREATE.name())).findFirst();
first.ifPresent(extension -> addQueryBuilder.append(executeColumnExtensions(change.getExpected(), POST_CREATE, extension.getActions().get(POST_CREATE.name()))));
}
return addQueryBuilder.toString();
default:
throw new RuntimeException("Operation " + change.getStatus() + " for column not supported");
}
}

public String executeTableExtensions(Table table, OperationTypeEnum status, Object action) {
Optional<Class<?>> tableExtension = ModuleLoader.loadModuleByAnnotationClassValues(String.format("%s.%s",DDLExtensionTable.class.getPackageName(),"extensions.table") , RosettaModuleTypes.DDL_EXTENSION_TABLE, "SQL");
DDLExtensionTable ddlExtensionTable = null;
if (tableExtension.isPresent()) {
try {
ddlExtensionTable = (DDLExtensionTable) tableExtension.get().getDeclaredConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |
NoSuchMethodException e) {
log.warn("Failed to load table ddl extension %s - skipping", tableExtension.get().getName());
}
} else {
log.warn("No table ddl extension found - skipping", tableExtension.get().getName());
}
if (ddlExtensionTable == null) {
return "";
}
switch (status) {
case PRE_CREATE:
return ddlExtensionTable.preCreateTable(table, action);
case PRE_ALTER:
return ddlExtensionTable.preAlterTable(table, action);
case PRE_DROP:
return ddlExtensionTable.preDropTable(table, action);
case POST_CREATE:
return ddlExtensionTable.postCreateTable(table, action);
case POST_ALTER:
return ddlExtensionTable.postAlterTable(table, action);
case POST_DROP:
return ddlExtensionTable.postDropTable(table, action);
default:
return "";
}
}

public String executeColumnExtensions(Column column, OperationTypeEnum status, Object action) {
Optional<Class<?>> columnExtension = ModuleLoader.loadModuleByAnnotationClassValues(String.format("%s.%s",DDLExtensionColumn.class.getPackageName(),"extensions.column"), RosettaModuleTypes.DDL_EXTENSION_COLUMN, "SQL");
DDLExtensionColumn ddlExtensionColumn = null;
if (columnExtension.isPresent()) {
try {
ddlExtensionColumn = (DDLExtensionColumn) columnExtension.get().getDeclaredConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |
NoSuchMethodException e) {
log.warn("Failed to load column ddl extension %s - skipping", columnExtension.get().getName());
}
} else {
log.warn("No column ddl extension found - skipping", columnExtension.get().getName());
}
if (ddlExtensionColumn == null) {
return "";
}
switch (status) {
case PRE_CREATE:
return ddlExtensionColumn.preCreateColumn(column, action);
case PRE_ALTER:
return ddlExtensionColumn.preAlterColumn(column, action);
case PRE_DROP:
return ddlExtensionColumn.preDropColumn(column, action);
case POST_CREATE:
return ddlExtensionColumn.postCreateColumn(column, action);
case POST_ALTER:
return ddlExtensionColumn.postAlterColumn(column, action);
case POST_DROP:
return ddlExtensionColumn.postDropColumn(column, action);
default:
return "";
}
}

@Override
public String onForeignKeyChange(ForeignKeyChange change) {
switch (change.getStatus()) {
Expand Down Expand Up @@ -142,4 +300,4 @@ public String onViewChange(ViewChange change) {
throw new RuntimeException("Operation " + change.getStatus() + " for view not supported");
}
}
}
}
Loading