Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI build
on:
workflow_dispatch:
push:
branches: master
branches: main
jobs:
build:
runs-on: ubuntu-latest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import io.github.mmm.orm.result.DbResultValue;
import io.github.mmm.orm.statement.AbstractEntityClause;
import io.github.mmm.orm.statement.BasicDbStatementFormatter;
import io.github.mmm.orm.statement.select.SelectFrom;
import io.github.mmm.orm.statement.select.SelectFromClause;
import io.github.mmm.property.criteria.CriteriaFormatterFactory;

/**
Expand Down Expand Up @@ -63,7 +63,7 @@ protected void formatEntityName(AbstractEntityClause<?, ?, ?> entityClause) {
}

@Override
protected void formatSelectAll(SelectFrom<?, ?> selectFrom) {
protected void formatSelectAll(SelectFromClause<?, ?> selectFrom) {

EntityBean entity = selectFrom.getEntity();
DbBeanMapper<EntityBean> mapping = this.dialect.getOrm().createBeanMapper(entity);
Expand Down
98 changes: 90 additions & 8 deletions core/src/main/java/io/github/mmm/orm/naming/DbNamingStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
* http://www.apache.org/licenses/LICENSE-2.0 */
package io.github.mmm.orm.naming;

import java.util.List;

import io.github.mmm.base.text.CaseSyntax;
import io.github.mmm.bean.BeanType;
import io.github.mmm.entity.bean.EntityBean;
import io.github.mmm.orm.ddl.DbColumnSpec;
import io.github.mmm.orm.statement.AbstractEntityClause;
import io.github.mmm.orm.statement.create.CreateIndexStatement;
import io.github.mmm.property.ReadableProperty;
import io.github.mmm.property.WritableProperty;
import io.github.mmm.value.PropertyPath;
Expand All @@ -22,6 +26,29 @@
*/
public interface DbNamingStrategy {

/**
* @return the maximum length for names of DDL elements (tables, columns, constraints, indexes, etc.) supported by the
* underlying database. To avoid trouble you should name your entities and properties short but precise.
* However, if you somehow exceed the limit, your names will be truncated automatically.
*/
default int getMaximumNameLength() {

return 128;
}

/**
* @param name the suggested name of a DDL element.
* @return the given {@code name} clipped to ensure {@link #getMaximumNameLength()} is not exceeded.
*/
default String clipName(String name) {

int max = getMaximumNameLength();
if (name.length() > max) {
return name.substring(0, max);
}
return name;
}

/**
* @param property the {@link ReadableProperty} to derive the column name from.
* @return the column name for the given {@link ReadableProperty property}.
Expand Down Expand Up @@ -62,7 +89,7 @@ default String getColumnName(String columnName, PropertyPath<?> property) {
builder.add(columnName);
return builder.toString();
}
return columnName;
return clipName(columnName);
}

/**
Expand All @@ -89,7 +116,8 @@ default String getColumnName(String rawColumnName, TypeMapper<?, ?> typeMapper)
if ((suffix != null) && !suffix.isEmpty()) {
suffix = getColumnName(suffix);
}
return typeMapper.getNameMode().format(rawColumnName, suffix);
String columnName = typeMapper.getNameMode().format(rawColumnName, suffix);
return clipName(columnName);
}

/**
Expand All @@ -98,21 +126,21 @@ default String getColumnName(String rawColumnName, TypeMapper<?, ?> typeMapper)
*/
default String getColumnName(String rawColumnName) {

return rawColumnName;
return clipName(rawColumnName);
}

/**
* @param bean the {@link EntityBean} to map to a database table.
* @param entity the {@link EntityBean} to map to a database table.
* @return the physical table name.
*/
default String getTableName(EntityBean bean) {
default String getTableName(EntityBean entity) {

BeanType type = bean.getType();
BeanType type = entity.getType();
String tableName = type.getMetaInfo().get(EntityBean.META_KEY_TABLE);
if (tableName == null) {
tableName = getTableName(type.getSimpleName());
}
return tableName;
return clipName(tableName);
}

/**
Expand All @@ -135,7 +163,61 @@ default String getTableName(AbstractEntityClause<?, ?, ?> entityClause) {
*/
default String getTableName(String rawTableName) {

return rawTableName;
return clipName(rawTableName);
}

/**
* @param createIndex the {@link CreateIndexStatement}.
* @return the static prefix for an {@link #getIndexName(CreateIndexStatement) index name}.
*/
default String getIndexNamePrefix(CreateIndexStatement<?> createIndex) {

if (createIndex.getCreateIndex().isUnique()) {
return "UX";
} else {
return "IX";
}
}

/**
* @return the static infix for an {@link #getIndexName(CreateIndexStatement) index name} used to separate the
* columns.
*/
default String getIndexNameInfix() {

return "_";
}

/**
* @param createIndex the {@link CreateIndexStatement}.
* @return the auto-generated index name.
*/
default String getIndexName(CreateIndexStatement<?> createIndex) {

EntityBean entity = createIndex.getOn().getEntity();
List<DbColumnSpec> columns = createIndex.getColumn().getColumns();
String tableName = getTableName(entity);
int capacity = 3 + tableName.length() + (columns.size() * 5);
int max = getMaximumNameLength();
if (capacity > max) {
capacity = max;
}
StringBuilder sb = new StringBuilder(capacity);
String infix = getIndexNameInfix();
sb.append(getIndexNamePrefix(createIndex));
sb.append(infix);
sb.append(tableName);
for (DbColumnSpec column : columns) {
column.getName();
String columnName = getColumnName(column.getProperty());
sb.append(infix);
sb.append(columnName);
if (sb.length() > max) {
break;
}
}
String indexName = sb.toString();
return clipName(indexName);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

/**
* {@link DbClause} containing {@link #getAssignments() assignments} like a
* {@link io.github.mmm.orm.statement.insert.InsertValues}-clause.
* {@link io.github.mmm.orm.statement.insert.InsertValuesClause}-clause.
*
* @param <E> type of the {@link EntityBean} to query.
* @param <SELF> type of this class itself.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@
import io.github.mmm.orm.statement.delete.DeleteClause;
import io.github.mmm.orm.statement.impl.CriteriaJqlParametersInline;
import io.github.mmm.orm.statement.insert.InsertClause;
import io.github.mmm.orm.statement.insert.InsertValues;
import io.github.mmm.orm.statement.insert.InsertValuesClause;
import io.github.mmm.orm.statement.merge.MergeClause;
import io.github.mmm.orm.statement.select.GroupByClause;
import io.github.mmm.orm.statement.select.HavingClause;
import io.github.mmm.orm.statement.select.OrderByClause;
import io.github.mmm.orm.statement.select.SelectClause;
import io.github.mmm.orm.statement.select.SelectFrom;
import io.github.mmm.orm.statement.select.SelectFromClause;
import io.github.mmm.orm.statement.select.SelectSequenceNextValueClause;
import io.github.mmm.orm.statement.select.SelectStatement;
import io.github.mmm.orm.statement.update.UpdateClause;
Expand Down Expand Up @@ -383,7 +383,7 @@ public void formatSelectClause(SelectClause<?> select, DbContext context) {
writeIndent();
write("SELECT ");
SelectStatement<?> statement = select.getStatement();
SelectFrom<?, ?> selectFrom = null;
SelectFromClause<?, ?> selectFrom = null;
if (statement != null) {
selectFrom = statement.getFrom();
}
Expand Down Expand Up @@ -505,9 +505,9 @@ public void formatAlterTableClause(AlterTableClause<?> alterTable, DbContext con

/**
* @param select the {@link SelectClause} with the {@link SelectClause#getSelections() selections}.
* @param selectFrom the {@link SelectFrom}.
* @param selectFrom the {@link SelectFromClause}.
*/
protected void formatSelections(SelectClause<?> select, SelectFrom<?, ?> selectFrom) {
protected void formatSelections(SelectClause<?> select, SelectFromClause<?, ?> selectFrom) {

List<? extends CriteriaObject<?>> selectionCriterias = select.getSelections();
if (selectionCriterias.isEmpty()) {
Expand Down Expand Up @@ -535,35 +535,39 @@ protected void formatSelections(SelectClause<?> select, SelectFrom<?, ?> selectF
}

/**
* @return {@code true} if a {@link SelectClause} of all properties should happen via {@link SelectFrom#getAlias()
* alias}, {@code false} otherwise (to simply use {@code *}). The default is {@code false}. Override to
* change. E.g. in JPQL you would write "SELECT a FROM Entity a ..." whereas in plain SQL you would write
* "SELECT * FROM Entity ..."
* @return {@code true} if a {@link SelectClause} of all properties should happen via
* {@link SelectFromClause#getAlias() alias}, {@code false} otherwise (to simply use {@code *}). The default
* is {@code false}. Override to change. E.g. in JPQL you would write "SELECT a FROM Entity a ..." whereas in
* plain SQL you would write "SELECT * FROM Entity ..."
*/
public boolean isSelectAllByAlias() {

return true;
}

/**
* @return {@code true} to use the {@code AS} keyword before an {@link SelectFrom#getAlias() alias} (e.g. "FROM Entity
* <b>AS</b> e"), {@code false} otherwise.
* @return {@code true} to use the {@code AS} keyword before an {@link SelectFromClause#getAlias() alias} (e.g. "FROM
* Entity <b>AS</b> e"), {@code false} otherwise.
*/
public boolean isUseAsBeforeAlias() {

return false;
}

/**
* @param selectFrom the {@link SelectFrom} giving access to the {@link SelectFrom#getAlias() alias}.
* @param selectFrom the {@link SelectFromClause} giving access to the {@link SelectFromClause#getAlias() alias}.
*/
protected void formatSelectAll(SelectFrom<?, ?> selectFrom) {
protected void formatSelectAll(SelectFromClause<?, ?> selectFrom) {

if (isSelectAllByAlias()) {
write(selectFrom.getAlias());
write(" ");
if (selectFrom == null) {
write("?"); // robustness to avoid toString fails in debugger while object is created.
} else {
write("* ");
if (isSelectAllByAlias()) {
write(selectFrom.getAlias());
write(" ");
} else {
write("* ");
}
}
}

Expand Down Expand Up @@ -727,7 +731,7 @@ public void formatIntoClause(IntoClause<?, ?, ?> into, DbContext context) {
*/
public void formatValuesClause(ValuesClause<?, ?> values, DbContext context) {

boolean isInto = values instanceof InsertValues;
boolean isInto = values instanceof InsertValuesClause;
List<PropertyAssignment<?>> assignments = values.getAssignments();
List<CriteriaObject<?>> args = null;
if (isInto) {
Expand Down Expand Up @@ -1118,7 +1122,11 @@ public void formatCreateIndexClause(CreateIndexClause createIndex, DbContext con
write("UNIQUE ");
}
write("INDEX ");
formatName(createIndex.getName());
String name = createIndex.getName();
if ((name == null) || name.isEmpty()) {
name = getOrm().getNamingStrategy().getIndexName(createIndex.getStatement());
}
formatName(name);
}

/**
Expand Down
Loading