Skip to content

Commit

Permalink
Merge pull request #142 from AdaptiveScale/release-1.9.1
Browse files Browse the repository at this point in the history
Release 1.9.1
  • Loading branch information
nbesimi authored Mar 3, 2023
2 parents 92e7fba + 889bad8 commit 32111ca
Show file tree
Hide file tree
Showing 12 changed files with 607 additions and 78 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repositories {

allprojects {
group = 'com.adaptivescale'
version = '1.9.0'
version = '1.9.1'
sourceCompatibility = 11
targetCompatibility = 11
}
Expand Down
2 changes: 1 addition & 1 deletion cli/src/main/java/com/adaptivescale/rosetta/cli/Cli.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
@Slf4j
@CommandLine.Command(name = "cli",
mixinStandardHelpOptions = true,
version = "1.9.0",
version = "1.9.1",
description = "Declarative Database Management - DDL Transpiler"
)
class Cli implements Callable<Void> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.adaptivescale.rosetta.common.models;

import java.util.Objects;

public class Interleave {

private String tableName;

private String parentName;

private String onDeleteAction;

public String getTableName() {
return tableName;
}

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

public String getParentName() {
return parentName;
}

public void setParentName(String parentName) {
this.parentName = parentName;
}

public String getOnDeleteAction() {
return onDeleteAction;
}

public void setOnDeleteAction(String onDeleteAction) {
this.onDeleteAction = onDeleteAction;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Interleave that = (Interleave) o;
return Objects.equals(tableName, that.tableName) && Objects.equals(parentName, that.parentName) && Objects.equals(onDeleteAction, that.onDeleteAction);
}

@Override
public int hashCode() {
return Objects.hash(tableName, parentName, onDeleteAction);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@

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

public class Table {

private String name;
private String description;
private String type;
private String schema;

private Interleave interleave;

private List<Index> indices;

private Collection<Column> columns;
Expand Down Expand Up @@ -54,11 +58,32 @@ public void setDescription(String description) {
this.description = description;
}

public Interleave getInterleave() {
return interleave;
}

public void setInterleave(Interleave interleave) {
this.interleave = interleave;
}

public List<Index> getIndices() {
return indices;
}

public void setIndices(List<Index> indices) {
this.indices = indices;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Table table = (Table) o;
return Objects.equals(name, table.name) && Objects.equals(description, table.description) && Objects.equals(type, table.type) && Objects.equals(schema, table.schema) && Objects.equals(interleave, table.interleave) && Objects.equals(indices, table.indices) && Objects.equals(columns, table.columns);
}

@Override
public int hashCode() {
return Objects.hash(name, description, type, schema, interleave, indices, columns);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ public List<Change<?>> findChanges(Database expected, Database actual) {
List<Change<?>> changesFromIndices = findChangesInIndicesForTable(expectedTable, table);
changes.addAll(changesFromTables);
changes.addAll(changesFromIndices);

if (checkInterleaveChanges(table, expectedTable)) {
Change<Table> tableChangeDrop = ChangeFactory.tableChange(null, table, Change.Status.DROP);
Change<Table> tableChangeAdd = ChangeFactory.tableChange(expectedTable, null, Change.Status.ADD);
changes.add(tableChangeDrop);
changes.add(tableChangeAdd);
}
} else {
throw new RuntimeException(String.format("Found %d table with name '%s' and schema '%s'",
foundedTables.size(), expectedTable.getName(), expectedTable.getSchema()));
Expand All @@ -77,6 +84,15 @@ public List<Change<?>> findChanges(Database expected, Database actual) {
return result;
}

private boolean checkInterleaveChanges(Table table, Table expectedTable) {
if ((table.getInterleave() == null && expectedTable.getInterleave() != null) ||
(table.getInterleave() != null && expectedTable.getInterleave() == null) ||
(table.getInterleave() != null && expectedTable.getInterleave() != null && !table.getInterleave().equals(expectedTable.getInterleave()))) {
return true;
}
return false;
}

private void viewChanges(Database expected, Database actual, List<Change<?>> changes) {
// Backwards compatibility
if (actual.getViews() == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.util.stream.Collectors;

import static com.adaptivescale.rosetta.ddl.targets.spanner.Constants.DEFAULT_WRAPPER;
import static java.util.Comparator.*;

@Slf4j
@RosettaModule(
Expand Down Expand Up @@ -55,7 +56,7 @@ public String createTable(Table table, boolean dropTableIfExists) {

if (table.getSchema() != null && !table.getSchema().isBlank()) {
stringBuilder.append(DEFAULT_WRAPPER)
.append(table.getSchema()).append(DEFAULT_WRAPPER).append(".");
.append(table.getSchema()).append(DEFAULT_WRAPPER).append(".");
}

stringBuilder.append(DEFAULT_WRAPPER).append(table.getName()).append(DEFAULT_WRAPPER)
Expand All @@ -65,6 +66,16 @@ public String createTable(Table table, boolean dropTableIfExists) {
stringBuilder.append(primaryKeysForTable.get());
}

if (table.getInterleave() != null) {
stringBuilder.append(",\r");
stringBuilder.append("INTERLEAVE IN PARENT ")
.append(table.getInterleave().getParentName());

final String onDeleteAction = table.getInterleave().getOnDeleteAction();
if (onDeleteAction != null && !onDeleteAction.isEmpty()) {
stringBuilder.append(" ON DELETE ").append(table.getInterleave().getOnDeleteAction());
}
}
stringBuilder.append(";");
return stringBuilder.toString();
}
Expand All @@ -85,21 +96,29 @@ public String createDatabase(Database database, boolean dropTableIfExists) {
});
if(!missingPrimaryKeys.isEmpty()){
throw new RuntimeException(
String.format("Tables %s are missing primary key. Spanner does not allow table without primary key.",
missingPrimaryKeys.stream().collect(Collectors.joining(","))));
String.format("Tables %s are missing primary key. Spanner does not allow table without primary key.",
missingPrimaryKeys.stream().collect(Collectors.joining(","))));
}
stringBuilder.append(database.getTables()
.stream()
.map(table -> createTable(table, dropTableIfExists))
.collect(Collectors.joining("\r\r")));
List<Table> tablesToCreate = database.getTables().stream().collect(Collectors.toList());

//Make sure you create interleaved tables at the end
tablesToCreate.sort(nullsFirst(
comparing(it -> Optional.ofNullable(it.getInterleave())
.map(Interleave::getTableName)
.orElse(null), nullsFirst(naturalOrder()))));

stringBuilder.append(tablesToCreate
.stream()
.map(table -> createTable(table, dropTableIfExists))
.collect(Collectors.joining("\r\r")));

String foreignKeys = database
.getTables()
.stream()
.map(this::foreignKeys)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.joining());
.getTables()
.stream()
.map(this::foreignKeys)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.joining());

if (!foreignKeys.isEmpty()) {
stringBuilder.append("\r").append(foreignKeys).append("\r");
Expand Down Expand Up @@ -129,6 +148,11 @@ public String createDatabase(Database database, boolean dropTableIfExists) {

@Override
public String createForeignKey(ForeignKey foreignKey) {
//For foreign keys returned as result of interleave table, JDBC returns no name.
// Those are created automatically by JDBC once we specify that the table is interleaved.
if (foreignKey.getName() == null) {
return "";
}
return "ALTER TABLE" + handleNullSchema(foreignKey.getSchema(), foreignKey.getTableName()) + " ADD CONSTRAINT "
+ foreignKey.getName() + " FOREIGN KEY ("+ DEFAULT_WRAPPER + foreignKey.getColumnName() + DEFAULT_WRAPPER +") REFERENCES "
+ foreignKey.getPrimaryTableName()
Expand Down Expand Up @@ -246,12 +270,23 @@ private Optional<String> createPrimaryKeysForTable(Table table) {

private Optional<String> foreignKeys(Table table) {
String result = table.getColumns().stream()
.filter(column -> column.getForeignKeys() != null && !column.getForeignKeys().isEmpty())
.map(this::createForeignKeys).collect(Collectors.joining());
.filter(column -> column.getForeignKeys() != null && !column.getForeignKeys().isEmpty())
.filter(column -> !checkColumnIsInterleaved(table, column))
.map(this::createForeignKeys).collect(Collectors.joining());

return result.isEmpty() ? Optional.empty() : Optional.of(result);
}

private boolean checkColumnIsInterleaved(Table table, Column column) {
if (table.getInterleave() != null &&
column.isPrimaryKey() &&
table.getInterleave().getParentName().equals(column.getForeignKeys().get(0).getPrimaryTableName())) {
return true;
}

return false;
}

//ALTER TABLE rosetta.contacts ADD CONSTRAINT contacts_fk FOREIGN KEY (contact_id) REFERENCES rosetta."user"(user_id);
private String createForeignKeys(Column column) {
return column.getForeignKeys().stream().map(this::createForeignKey).collect(Collectors.joining());
Expand Down
Loading

0 comments on commit 32111ca

Please sign in to comment.