borinquenkid commented on code in PR #16583:
URL: https://github.com/apache/grails-core/pull/16583#discussion_r4365178288
##########
grails-doc/src/en/guide/upgrading/upgrading90x.adoc:
##########
@@ -1151,3 +1151,34 @@ When upgrading an affected application:
----
See xref:theWebLayer#commandObjects[Command Objects] for a trait-based
alternative to sharing a non-domain superclass with a domain class.
+
+==== 17. A Null in a Unique Constraint's Composite Key Follows the Database
Review Comment:
Merged 9.0.x in 268003b434: the section is 20 now, after 18 (RxGORM) and 19
(RxJava 1 and 2), and the PR body says section 20.
##########
grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/config/Settings.java:
##########
@@ -54,6 +54,11 @@ public interface Settings {
* The default constraints
*/
String SETTING_DEFAULT_CONSTRAINTS = PREFIX + '.' + "default.constraints";
+ /**
+ * How the {@code unique} constraint treats a {@code null} in a composite
key: {@code wildcard}, {@code skip},
+ * {@code value} or {@code database}, which is the default. See {@link
UniqueNulls}.
+ */
+ String SETTING_UNIQUE_NULLS = PREFIX + '.' + "unique.nulls";
Review Comment:
Fixed in 268003b434: `grails.gorm.unique.nulls` is in
`additional-spring-configuration-metadata.json` next to
`grails.gorm.default.nullable`, as a `java.lang.String` defaulting to
`database`, with the four values in the description.
##########
grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/validation/constraints/builtin/UniqueConstraint.groovy:
##########
@@ -48,27 +55,72 @@ class UniqueConstraint extends AbstractConstraint {
public static final String NAME = 'unique'
+ public static final String GROUP = 'group'
+
+ public static final String NULLS = 'nulls'
+
protected List group = []
+ /** The reading the constraint asks for, or {@code null} to follow the
datastore. */
+ protected UniqueNulls nulls
+
UniqueConstraint(Class<?> constraintOwningClass, String
constraintPropertyName, Object constraintParameter, MessageSource
messageSource) {
super(constraintOwningClass, constraintPropertyName,
constraintParameter, messageSource)
- if (constraintParameter instanceof Iterable) {
- for (property in ((Iterable) constraintParameter)) {
+ Object groupParameter = constraintParameter
+ if (constraintParameter instanceof Map) {
+ groupParameter = ((Map) constraintParameter).get(GROUP)
+ nulls = UniqueNulls.of(((Map) constraintParameter).get(NULLS))
+ }
+ if (groupParameter instanceof Iterable) {
+ for (property in ((Iterable) groupParameter)) {
group.add(property.toString())
}
}
- else if (constraintParameter instanceof CharSequence) {
- group.add(constraintParameter.toString())
+ else if (groupParameter instanceof CharSequence) {
+ group.add(groupParameter.toString())
}
}
@Override
protected Object validateParameter(Object constraintParameter) {
if (constraintParameter instanceof Boolean) {
return constraintParameter
- } else {
- return constraintParameter instanceof Iterable ||
constraintParameter instanceof CharSequence
}
+ if (constraintParameter instanceof Map) {
+ Map options = (Map) constraintParameter
+ Object groupOption = options.get(GROUP)
+ boolean knownKeys = options.keySet().every { it == GROUP || it ==
NULLS }
+ boolean validGroup = groupOption == null || groupOption instanceof
Iterable || groupOption instanceof CharSequence
+ if (!knownKeys || !validGroup) {
+ throw new IllegalArgumentException("The unique constraint of
[${constraintOwningClass.name}.${constraintPropertyName}] takes a map with a
'${GROUP}' (a property name or a list of them) and a '${NULLS}' option, not
${options}")
+ }
+ UniqueNulls.of(options.get(NULLS))
+ return options
Review Comment:
Fixed in 268003b434: an empty map is rejected with the same message as the
other malformed maps, and `UniqueNullsSpec` has the row.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]