Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
101 changes: 101 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,107 @@ you can fix it by running the following command where your driver is located:
```
zip -d google-cloud-spanner-jdbc-2.6.2-single-jar-with-dependencies.jar 'META-INF/.SF' 'META-INF/.RSA' 'META-INF/*SF'
```
## Rosetta Extensions Feature
### Overview
The Extensions feature in Rosetta allows users to append custom SQL code to the Data Definition Language (DDL) operations generated during the execution of the apply command. This feature enhances the flexibility and functionality of Rosetta by enabling custom SQL commands to be executed at various stages of the DDL lifecycle.

### Supported Extensions


Currently, Rosetta supports the following extension:
- DDL_EXTENSION: This extension type allows the addition of custom SQL commands to the DDL operations.


### DDL_EXTENSION Commands


Users can specify custom SQL commands to be executed at different points in the DDL lifecycle using the following commands:
- PRE_CREATE: Execute SQL before a CREATE operation.
- PRE_ALTER: Execute SQL before an ALTER operation.
- PRE_DROP: Execute SQL before a DROP operation.
- POST_CREATE: Execute SQL after a CREATE operation.
- POST_ALTER: Execute SQL after an ALTER operation.
- POST_DROP: Execute SQL after a DROP operation.

### Example Usage

Below is an example of how to use the DDL_EXTENSION to append custom SQL code to a table creation operation in the model.yaml file.
```yaml
- name: "fullname"
typeName: "varchar"
ordinalPosition: 0
primaryKeySequenceId: 0
columnDisplaySize: 2147483647
scale: 0
precision: 2147483647
columnProperties: []
primaryKey: false
nullable: true
autoincrement: false
extensions:
- name: SQL
type: DDL_EXTENSION
actions:
POST_CREATE: UPDATE basic_library.authors SET fullname = CONCAT(name, ' ', surname) WHERE fullname IS NULL;
```
### How to Use
1. Define the Extension in model.yaml:
- Add the extensions section under the column or table definition where the custom SQL needs to be applied.
- Specify the name as SQL and the type as DDL_EXTENSION.
3. Specify Actions:
- Under actions, define the SQL commands to be executed for the desired DDL operations (e.g., POST_CREATE, PRE_ALTER).
### Example Scenarios


#### Scenario 1: Custom SQL After Table Creation

If you need to populate or update data in a newly created table immediately after its creation, you can use the POST_CREATE command:
```yaml
- name: "fullname"
typeName: "varchar"
ordinalPosition: 0
primaryKeySequenceId: 0
columnDisplaySize: 2147483647
scale: 0
precision: 2147483647
columnProperties: []
primaryKey: false
nullable: true
autoincrement: false
extensions:
- name: SQL
type: DDL_EXTENSION
actions:
POST_CREATE: UPDATE basic_library.authors SET fullname = CONCAT(name, ' ', surname) WHERE fullname IS NULL;
```
#### Scenario 2: Custom SQL Before Table Alteration
To execute custom SQL before altering a table, use the PRE_ALTER command:
```yaml
- name: "fullname"
typeName: "varchar"
ordinalPosition: 0
primaryKeySequenceId: 0
columnDisplaySize: 2147483647
scale: 0
precision: 2147483647
columnProperties: []
primaryKey: false
nullable: true
autoincrement: false
extensions:
- name: SQL
type: DDL_EXTENSION
actions:
PRE_ALTER: CREATE TEMPORARY TABLE temp_authors AS SELECT * FROM authors;
```
### Best Practices

- Validation: Ensure that the custom SQL commands are valid and tested to avoid errors during the apply command execution.
- Performance: Consider the performance implications of the custom SQL, especially for large datasets.
- Security: Validate and sanitize custom SQL to prevent SQL injection and other security vulnerabilities.
### Conclusion

The Extensions feature in Rosetta, particularly the DDL_EXTENSION, provides a powerful way to customize the DDL lifecycle with user-defined SQL commands. By leveraging this feature, users can enhance the functionality and control of their data operations, ensuring that specific actions are performed at key stages of the DDL execution process.

## Copyright and License Information
Unless otherwise specified, all content, including all source code files and documentation files in this repository are:
Expand Down
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
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
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);

}
Loading