mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#513 - Column Constraint for Enum types should cover all Enum values in an inheritance hierachy
This commit is contained in:
+25
-4
@@ -11,12 +11,13 @@ import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyCompound;
|
||||
import com.avaje.ebeaninternal.server.deploy.CompoundUniqueConstraint;
|
||||
import com.avaje.ebeaninternal.server.deploy.InheritInfo;
|
||||
import com.avaje.ebeaninternal.server.deploy.TableJoinColumn;
|
||||
import com.avaje.ebeaninternal.server.deploy.id.ImportedId;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Used as part of ModelBuildBeanVisitor and generally adds the MColumn to the associated
|
||||
@@ -249,9 +250,13 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
|
||||
col.setUnique(determineUniqueConstraintName(col.getName()));
|
||||
indexSetAdd(col.getName());
|
||||
}
|
||||
String checkConstraint = p.getDbConstraintExpression();
|
||||
if (checkConstraint != null) {
|
||||
col.setCheckConstraint(checkConstraint);
|
||||
Set<String> checkConstraintValues = p.getDbCheckConstraintValues();
|
||||
if (checkConstraintValues != null) {
|
||||
if (beanDescriptor.hasInheritance()) {
|
||||
InheritInfo inheritInfo = beanDescriptor.getInheritInfo();
|
||||
inheritInfo.appendCheckConstraintValues(p.getName(), checkConstraintValues);
|
||||
}
|
||||
col.setCheckConstraint(buildCheckConstraint(p.getDbColumn(), checkConstraintValues));
|
||||
col.setCheckConstraintName(determineCheckConstraintName(col.getName()));
|
||||
}
|
||||
|
||||
@@ -268,6 +273,22 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
|
||||
table.addColumn(col);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the check constraint clause given the db column and values.
|
||||
*/
|
||||
private String buildCheckConstraint(String dbColumn, Set<String> checkConstraintValues) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("check ( ").append(dbColumn).append(" in (");
|
||||
int count = 0;
|
||||
for (String value : checkConstraintValues) {
|
||||
if (count++ > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(value);
|
||||
}
|
||||
sb.append("))");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void indexSetAdd(String column) {
|
||||
indexSet.add(column);
|
||||
|
||||
@@ -6,11 +6,9 @@ import com.avaje.ebean.bean.PersistenceContext;
|
||||
import com.avaje.ebean.config.EncryptKey;
|
||||
import com.avaje.ebean.config.dbplatform.DbEncryptFunction;
|
||||
import com.avaje.ebean.config.dbplatform.DbType;
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeanservice.docstore.api.mapping.DocMappingBuilder;
|
||||
import com.avaje.ebeanservice.docstore.api.mapping.DocPropertyMapping;
|
||||
import com.avaje.ebean.plugin.Property;
|
||||
import com.avaje.ebean.text.StringParser;
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.core.InternString;
|
||||
import com.avaje.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.generatedproperty.GeneratedWhenCreated;
|
||||
@@ -28,7 +26,10 @@ import com.avaje.ebeaninternal.server.text.json.WriteJson;
|
||||
import com.avaje.ebeaninternal.server.type.DataBind;
|
||||
import com.avaje.ebeaninternal.server.type.ScalarType;
|
||||
import com.avaje.ebeaninternal.server.type.ScalarTypeBoolean;
|
||||
import com.avaje.ebeaninternal.server.type.ScalarTypeEnum;
|
||||
import com.avaje.ebeaninternal.util.ValueUtil;
|
||||
import com.avaje.ebeanservice.docstore.api.mapping.DocMappingBuilder;
|
||||
import com.avaje.ebeanservice.docstore.api.mapping.DocPropertyMapping;
|
||||
import com.avaje.ebeanservice.docstore.api.mapping.DocPropertyOptions;
|
||||
import com.avaje.ebeanservice.docstore.api.mapping.DocPropertyType;
|
||||
import com.avaje.ebeanservice.docstore.api.support.DocStructure;
|
||||
@@ -45,6 +46,7 @@ import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Description of a property of a bean. Includes its deployment information such
|
||||
@@ -231,11 +233,6 @@ public class BeanProperty implements ElPropertyValue, Property {
|
||||
*/
|
||||
final String dbComment;
|
||||
|
||||
/**
|
||||
* DB Constraint (typically check constraint on enum)
|
||||
*/
|
||||
final String dbConstraintExpression;
|
||||
|
||||
final DbEncryptFunction dbEncryptFunction;
|
||||
|
||||
int deployOrder;
|
||||
@@ -304,7 +301,6 @@ public class BeanProperty implements ElPropertyValue, Property {
|
||||
this.dbLength = deploy.getDbLength();
|
||||
this.dbScale = deploy.getDbScale();
|
||||
this.dbColumnDefn = InternString.intern(deploy.getDbColumnDefn());
|
||||
this.dbConstraintExpression = InternString.intern(deploy.getDbConstraintExpression());
|
||||
this.dbColumnDefault = deploy.getDbColumnDefault();
|
||||
|
||||
this.inherited = false;// deploy.isInherited();
|
||||
@@ -414,7 +410,6 @@ public class BeanProperty implements ElPropertyValue, Property {
|
||||
this.dbLength = source.getDbLength();
|
||||
this.dbScale = source.getDbScale();
|
||||
this.dbColumnDefn = InternString.intern(source.getDbColumnDefn());
|
||||
this.dbConstraintExpression = InternString.intern(source.getDbConstraintExpression());
|
||||
this.dbColumnDefault = source.dbColumnDefault;
|
||||
|
||||
this.inherited = source.isInherited();
|
||||
@@ -977,8 +972,11 @@ public class BeanProperty implements ElPropertyValue, Property {
|
||||
* For an Enum returns IN expression for the set of Enum values.
|
||||
* </p>
|
||||
*/
|
||||
public String getDbConstraintExpression() {
|
||||
return dbConstraintExpression;
|
||||
public Set<String> getDbCheckConstraintValues() {
|
||||
if (scalarType instanceof ScalarTypeEnum) {
|
||||
return ((ScalarTypeEnum) scalarType).getDbCheckConstraintValues();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.avaje.ebeaninternal.server.deploy;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
@@ -88,6 +89,25 @@ public class InheritInfo {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append check constraint values for the entire inheritance hierarchy.
|
||||
*/
|
||||
public void appendCheckConstraintValues(final String propertyName, final Set<String> checkConstraintValues) {
|
||||
|
||||
visitChildren(new InheritInfoVisitor() {
|
||||
@Override
|
||||
public void visit(InheritInfo inheritInfo) {
|
||||
BeanProperty prop = inheritInfo.desc().getBeanProperty(propertyName);
|
||||
if (prop != null) {
|
||||
Set<String> values = prop.getDbCheckConstraintValues();
|
||||
if (values != null) {
|
||||
checkConstraintValues.addAll(values);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* return true if anything in the inheritance hierarchy has a relationship with a save cascade on
|
||||
* it.
|
||||
|
||||
@@ -393,17 +393,6 @@ public class DeployBeanProperty {
|
||||
}
|
||||
}
|
||||
|
||||
public String getDbConstraintExpression() {
|
||||
if (scalarType instanceof ScalarTypeEnum) {
|
||||
// create a check constraint for the enum
|
||||
ScalarTypeEnum etype = (ScalarTypeEnum) scalarType;
|
||||
|
||||
// check dbColName IN ('A', 'I', 'D')
|
||||
return "check (" + dbColumn + " in " + etype.getConstraintInValues() + ")";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the scalarType. This returns null for native JDBC types, otherwise
|
||||
* it is used to convert between logical types and jdbc types.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Marker interface for the Enum scalar types.
|
||||
*/
|
||||
@@ -8,6 +10,6 @@ public interface ScalarTypeEnum {
|
||||
/**
|
||||
* Return the IN values for DB constraint construction.
|
||||
*/
|
||||
String getConstraintInValues();
|
||||
Set<String> getDbCheckConstraintValues();
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* JPA standard based Enum scalar type.
|
||||
@@ -41,22 +43,17 @@ public class ScalarTypeEnumStandard {
|
||||
/**
|
||||
* Return the IN values for DB constraint construction.
|
||||
*/
|
||||
public String getConstraintInValues() {
|
||||
@Override
|
||||
public Set<String> getDbCheckConstraintValues() {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
LinkedHashSet<String> values = new LinkedHashSet<String>();
|
||||
|
||||
sb.append("(");
|
||||
Object[] ea = enumType.getEnumConstants();
|
||||
for (int i = 0; i < ea.length; i++) {
|
||||
Enum<?> e = (Enum<?>) ea[i];
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append("'").append(e.name()).append("'");
|
||||
values.add("'" + e.name() + "'");
|
||||
}
|
||||
sb.append(")");
|
||||
|
||||
return sb.toString();
|
||||
return values;
|
||||
}
|
||||
|
||||
private int maxValueLength(Class<?> enumType) {
|
||||
@@ -129,21 +126,15 @@ public class ScalarTypeEnumStandard {
|
||||
/**
|
||||
* Return the IN values for DB constraint construction.
|
||||
*/
|
||||
public String getConstraintInValues() {
|
||||
@Override
|
||||
public Set<String> getDbCheckConstraintValues() {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("(");
|
||||
LinkedHashSet<String> values = new LinkedHashSet<String>();
|
||||
for (int i = 0; i < enumArray.length; i++) {
|
||||
Enum<?> e = (Enum<?>) enumArray[i];
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(e.ordinal());
|
||||
values.add(Integer.toString(e.ordinal()));
|
||||
}
|
||||
sb.append(")");
|
||||
|
||||
return sb.toString();
|
||||
return values;
|
||||
}
|
||||
|
||||
public void bind(DataBind b, Object value) throws SQLException {
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Additional control over mapping to DB values.
|
||||
@@ -35,32 +37,21 @@ public class ScalarTypeEnumWithMapping extends ScalarTypeEnumStandard.EnumBase i
|
||||
/**
|
||||
* Return the IN values for DB constraint construction.
|
||||
*/
|
||||
public String getConstraintInValues() {
|
||||
@Override
|
||||
public Set<String> getDbCheckConstraintValues() {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int i = 0;
|
||||
|
||||
sb.append("(");
|
||||
LinkedHashSet values = new LinkedHashSet();
|
||||
|
||||
Iterator<?> it = beanDbMap.dbValues();
|
||||
while (it.hasNext()) {
|
||||
Object dbValue = it.next();
|
||||
if (i++ > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
if (!beanDbMap.isIntegerType()) {
|
||||
sb.append("'");
|
||||
}
|
||||
sb.append(dbValue.toString());
|
||||
if (!beanDbMap.isIntegerType()) {
|
||||
sb.append("'");
|
||||
if (beanDbMap.isIntegerType()) {
|
||||
values.add(dbValue.toString());
|
||||
} else {
|
||||
values.add("'" + dbValue.toString() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
sb.append(")");
|
||||
|
||||
return sb.toString();
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user