use of io.micronaut.data.annotation.GeneratedValue.Type.SEQUENCE in project micronaut-data by micronaut-projects.
the class SqlQueryBuilder method buildCreateTableStatements.
/**
* Builds the create table statement. Designed for testing and not production usage. For production a
* SQL migration tool such as Flyway or Liquibase is recommended.
*
* @param entity The entity
* @return The tables for the give entity
*/
@Experimental
@NonNull
public String[] buildCreateTableStatements(@NonNull PersistentEntity entity) {
ArgumentUtils.requireNonNull("entity", entity);
final String unescapedTableName = getUnescapedTableName(entity);
String tableName = getTableName(entity);
boolean escape = shouldEscape(entity);
PersistentProperty identity = entity.getIdentity();
List<String> createStatements = new ArrayList<>();
String schema = entity.getAnnotationMetadata().stringValue(MappedEntity.class, SqlMembers.SCHEMA).orElse(null);
if (StringUtils.isNotEmpty(schema)) {
if (escape) {
schema = quote(schema);
}
createStatements.add("CREATE SCHEMA " + schema + ";");
}
Collection<Association> foreignKeyAssociations = getJoinTableAssociations(entity);
NamingStrategy namingStrategy = entity.getNamingStrategy();
if (CollectionUtils.isNotEmpty(foreignKeyAssociations)) {
for (Association association : foreignKeyAssociations) {
StringBuilder joinTableBuilder = new StringBuilder("CREATE TABLE ");
PersistentEntity associatedEntity = association.getAssociatedEntity();
Optional<Association> inverseSide = association.getInverseSide().map(Function.identity());
Association owningAssociation = inverseSide.orElse(association);
AnnotationMetadata annotationMetadata = owningAssociation.getAnnotationMetadata();
String joinTableName = annotationMetadata.stringValue(ANN_JOIN_TABLE, "name").orElseGet(() -> namingStrategy.mappedName(association));
if (escape) {
joinTableName = quote(joinTableName);
}
joinTableBuilder.append(joinTableName).append(" (");
List<PersistentPropertyPath> leftProperties = new ArrayList<>();
List<PersistentPropertyPath> rightProperties = new ArrayList<>();
boolean isAssociationOwner = !inverseSide.isPresent();
List<String> leftJoinTableColumns = resolveJoinTableJoinColumns(annotationMetadata, isAssociationOwner, entity, namingStrategy);
List<String> rightJoinTableColumns = resolveJoinTableJoinColumns(annotationMetadata, !isAssociationOwner, association.getAssociatedEntity(), namingStrategy);
traversePersistentProperties(entity.getIdentity(), (associations, property) -> {
leftProperties.add(PersistentPropertyPath.of(associations, property, ""));
});
traversePersistentProperties(associatedEntity.getIdentity(), (associations, property) -> {
rightProperties.add(PersistentPropertyPath.of(associations, property, ""));
});
if (leftJoinTableColumns.size() == leftProperties.size()) {
for (int i = 0; i < leftJoinTableColumns.size(); i++) {
PersistentPropertyPath pp = leftProperties.get(i);
String columnName = leftJoinTableColumns.get(i);
if (escape) {
columnName = quote(columnName);
}
joinTableBuilder.append(addTypeToColumn(pp.getProperty(), columnName, true)).append(',');
}
} else {
for (PersistentPropertyPath pp : leftProperties) {
String columnName = namingStrategy.mappedJoinTableColumn(entity, pp.getAssociations(), pp.getProperty());
if (escape) {
columnName = quote(columnName);
}
joinTableBuilder.append(addTypeToColumn(pp.getProperty(), columnName, true)).append(',');
}
}
if (rightJoinTableColumns.size() == rightProperties.size()) {
for (int i = 0; i < rightJoinTableColumns.size(); i++) {
PersistentPropertyPath pp = rightProperties.get(i);
String columnName = rightJoinTableColumns.get(i);
if (escape) {
columnName = quote(columnName);
}
joinTableBuilder.append(addTypeToColumn(pp.getProperty(), columnName, true)).append(',');
}
} else {
for (PersistentPropertyPath pp : rightProperties) {
String columnName = namingStrategy.mappedJoinTableColumn(entity, pp.getAssociations(), pp.getProperty());
if (escape) {
columnName = quote(columnName);
}
joinTableBuilder.append(addTypeToColumn(pp.getProperty(), columnName, true)).append(',');
}
}
joinTableBuilder.setLength(joinTableBuilder.length() - 1);
joinTableBuilder.append(")");
if (dialect != Dialect.ORACLE) {
joinTableBuilder.append(';');
}
createStatements.add(joinTableBuilder.toString());
}
}
boolean generatePkAfterColumns = false;
List<String> primaryColumnsName = new ArrayList<>();
List<String> columns = new ArrayList<>();
if (identity != null) {
List<PersistentPropertyPath> ids = new ArrayList<>();
traversePersistentProperties(identity, (associations, property) -> {
ids.add(PersistentPropertyPath.of(associations, property, ""));
});
if (ids.size() > 1) {
generatePkAfterColumns = true;
}
boolean finalGeneratePkAfterColumns = generatePkAfterColumns;
for (PersistentPropertyPath pp : ids) {
String column = namingStrategy.mappedName(pp.getAssociations(), pp.getProperty());
if (escape) {
column = quote(column);
}
primaryColumnsName.add(column);
column = addTypeToColumn(pp.getProperty(), column, isRequired(pp.getAssociations(), pp.getProperty()));
if (isNotForeign(pp.getAssociations())) {
column = addGeneratedStatementToColumn(pp.getProperty(), column, !finalGeneratePkAfterColumns);
}
columns.add(column);
}
}
PersistentProperty version = entity.getVersion();
if (version != null) {
String column = namingStrategy.mappedName(Collections.emptyList(), version);
if (escape) {
column = quote(column);
}
column = addTypeToColumn(version, column, true);
columns.add(column);
}
BiConsumer<List<Association>, PersistentProperty> addColumn = (associations, property) -> {
String column = namingStrategy.mappedName(associations, property);
if (escape) {
column = quote(column);
}
column = addTypeToColumn(property, column, isRequired(associations, property));
if (isNotForeign(associations)) {
column = addGeneratedStatementToColumn(property, column, false);
}
columns.add(column);
};
for (PersistentProperty prop : entity.getPersistentProperties()) {
traversePersistentProperties(prop, addColumn);
}
StringBuilder builder = new StringBuilder("CREATE TABLE ").append(tableName).append(" (");
builder.append(String.join(",", columns));
if (generatePkAfterColumns) {
builder.append(", PRIMARY KEY(").append(String.join(",", primaryColumnsName)).append(')');
}
if (dialect == Dialect.ORACLE) {
builder.append(")");
} else {
builder.append(");");
}
if (identity != null && identity.isGenerated()) {
GeneratedValue.Type idGeneratorType = identity.getAnnotationMetadata().enumValue(GeneratedValue.class, GeneratedValue.Type.class).orElseGet(() -> selectAutoStrategy(identity));
boolean isSequence = idGeneratorType == GeneratedValue.Type.SEQUENCE;
final String generatedDefinition = identity.getAnnotationMetadata().stringValue(GeneratedValue.class, "definition").orElse(null);
if (generatedDefinition != null) {
createStatements.add(generatedDefinition);
} else if (isSequence) {
final boolean isSqlServer = dialect == Dialect.SQL_SERVER;
final String sequenceName = quote(unescapedTableName + SEQ_SUFFIX);
String createSequenceStmt = "CREATE SEQUENCE " + sequenceName;
if (isSqlServer) {
createSequenceStmt += " AS BIGINT";
}
createSequenceStmt += " MINVALUE 1 START WITH 1";
if (dialect == Dialect.ORACLE) {
createSequenceStmt += " NOCACHE NOCYCLE";
} else {
if (isSqlServer) {
createSequenceStmt += " INCREMENT BY 1";
}
}
createStatements.add(createSequenceStmt);
}
}
createStatements.add(builder.toString());
addIndexes(entity, tableName, createStatements);
return createStatements.toArray(new String[0]);
}
Aggregations