提交 4d8dd6e7 authored 作者: Max Englander's avatar Max Englander

enum-support: add support for math operations

上级 fbce5a3f
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
22018=Data conversion error converting {0} 22018=Data conversion error converting {0}
22025=Error in LIKE ESCAPE: {0} 22025=Error in LIKE ESCAPE: {0}
22030=Value not permitted for column {0}: {1} 22030=Value not permitted for column {0}: {1}
22031=Value not a member of enumerators {0}: {1}
22032=Empty enums are not allowed
22033=Duplicate enumerators are not allowed for enum types: {0}
23502=NULL not allowed for column {0} 23502=NULL not allowed for column {0}
23503=Referential integrity constraint violation: {0} 23503=Referential integrity constraint violation: {0}
23505=Unique index or primary key violation: {0} 23505=Unique index or primary key violation: {0}
......
...@@ -161,16 +161,62 @@ public class ErrorCode { ...@@ -161,16 +161,62 @@ public class ErrorCode {
/** /**
* The error with code <code>22030</code> is thrown when * The error with code <code>22030</code> is thrown when
* an attempt is made to insert or update an ENUM value, * an attempt is made to INSERT or UPDATE an ENUM-typed cell,
* but the target value is not one of the values permitted * but the value is not one of the values enumerated by the
* by the column. * type.
*
* This error is best thrown in a context when the column name
* and it's enumerated values are known.
*
* Example: * Example:
* <pre> * <pre>
* CREATE TABLE TEST(ID INT, CASE ENUM('sensitive','insensitive')); * CREATE TABLE TEST(CASE ENUM('sensitive','insensitive'));
* INSERT INTO TEST VALUES(1, 'Hello'); * INSERT INTO TEST VALUES('snake');
* </pre>
*/
public static final int ENUM_VALUE_NOT_PERMITTED_1 = 22030;
/**
* The error with code <code>22031</code> is typically thrown
* when a math operation is attempted on an ENUM-typed cell,
* but the value resulting from the operation is not one of
* values enumerated by the type.
*
* This error is best thrown in a context when the column name
* is not known, but the enumerated values of the type are known.
*
* Example:
* <pre>
* CREATE TABLE TEST(CASE ENUM('sensitive','insensitive'));
* INSERT INTO TEST VALUES('sensitive');
* UPDATE TEST SET CASE = CASE + 100;
* </pre>
*/
public static final int ENUM_VALUE_NOT_PERMITTED_2 = 22031;
/**
* The error with code <code>22032</code> is thrown when an
* attempt is made to add or modify an ENUM-typed column so
* that it would not have any enumerated values.
*
* Example:
* <pre>
* CREATE TABLE TEST(CASE ENUM());
* </pre>
*/
public static final int ENUM_EMPTY = 22032;
/**
* The error with code <code>22033</code> is thrown when an
* attempt is made to add or modify an ENUM-typed column so
* that it would have duplicate values.
*
* Example:
* <pre>
* CREATE TABLE TEST(CASE ENUM('sensitive', 'sensitive'));
* </pre> * </pre>
*/ */
public static final int VALUE_NOT_PERMITTED = 22030; public static final int ENUM_DUPLICATE = 22033;
// 23: constraint violation // 23: constraint violation
......
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
22018=Data conversion error converting {0} 22018=Data conversion error converting {0}
22025=Error in LIKE ESCAPE: {0} 22025=Error in LIKE ESCAPE: {0}
22030=Value not permitted for column {0}: {1} 22030=Value not permitted for column {0}: {1}
22031=Value not a member of enumerators {0}: {1}
22032=Empty enums are not allowed
22033=Duplicate enumerators are not allowed for enum types: {0}
23502=NULL not allowed for column {0} 23502=NULL not allowed for column {0}
23503=Referential integrity constraint violation: {0} 23503=Referential integrity constraint violation: {0}
23505=Unique index or primary key violation: {0} 23505=Unique index or primary key violation: {0}
......
...@@ -376,8 +376,8 @@ public class Column { ...@@ -376,8 +376,8 @@ public class Column {
if (s.length() > 127) { if (s.length() > 127) {
s = s.substring(0, 128) + "..."; s = s.substring(0, 128) + "...";
} }
throw DbException.get(ErrorCode.VALUE_NOT_PERMITTED, throw DbException.get(ErrorCode.ENUM_VALUE_NOT_PERMITTED_1,
getCreateSQL(), s + " (" + value.getString() + ")"); getCreateSQL(), s + " (" + value.getInt() + ")");
} }
value = ValueEnum.get(enumerators, value); value = ValueEnum.get(enumerators, value);
......
...@@ -622,6 +622,8 @@ public abstract class Value { ...@@ -622,6 +622,8 @@ public abstract class Value {
return ValueInt.get(getBoolean().booleanValue() ? 1 : 0); return ValueInt.get(getBoolean().booleanValue() ? 1 : 0);
case BYTE: case BYTE:
return ValueInt.get(getByte()); return ValueInt.get(getByte());
case ENUM:
return ValueInt.get(getInt());
case SHORT: case SHORT:
return ValueInt.get(getShort()); return ValueInt.get(getShort());
case LONG: case LONG:
......
...@@ -29,19 +29,24 @@ public class ValueEnum extends Value { ...@@ -29,19 +29,24 @@ public class ValueEnum extends Value {
this.ordinal = ordinal; this.ordinal = ordinal;
} }
@Override
public Value add(final Value v) {
final Value iv = v.convertTo(Value.INT);
return convertTo(Value.INT).add(iv);
}
private static final void check(final String[] enumerators) { private static final void check(final String[] enumerators) {
switch (validate(enumerators)) { switch (validate(enumerators)) {
case VALID: case VALID:
return; return;
case EMPTY: case EMPTY:
throw DbException.get(ErrorCode.INVALID_VALUE_2, throw DbException.get(ErrorCode.ENUM_EMPTY);
"Empty enum is not allowed");
case DUPLICATE: case DUPLICATE:
throw DbException.get(ErrorCode.INVALID_VALUE_2, throw DbException.get(ErrorCode.ENUM_DUPLICATE,
"Enum with duplicate enumerator is not allowed"); toString(enumerators));
default: default:
throw DbException.get(ErrorCode.INVALID_VALUE_2, throw DbException.get(ErrorCode.INVALID_VALUE_2,
"Invalid enumerator list for enum"); toString(enumerators));
} }
} }
...@@ -51,12 +56,9 @@ public class ValueEnum extends Value { ...@@ -51,12 +56,9 @@ public class ValueEnum extends Value {
switch (validate(enumerators, label)) { switch (validate(enumerators, label)) {
case VALID: case VALID:
return; return;
case EMPTY:
throw DbException.get(ErrorCode.VALUE_NOT_PERMITTED,
"Enumerator label may not be empty");
default: default:
throw DbException.get(ErrorCode.VALUE_NOT_PERMITTED, throw DbException.get(ErrorCode.ENUM_VALUE_NOT_PERMITTED_2,
"Enumerator label is invalid"); toString(enumerators), "'" + label + "'");
} }
} }
...@@ -67,8 +69,8 @@ public class ValueEnum extends Value { ...@@ -67,8 +69,8 @@ public class ValueEnum extends Value {
case VALID: case VALID:
return; return;
default: default:
throw DbException.get(ErrorCode.VALUE_NOT_PERMITTED, throw DbException.get(ErrorCode.ENUM_VALUE_NOT_PERMITTED_2,
"Provided enumerator label does not match any member of enum"); toString(enumerators), Integer.toString(ordinal));
} }
} }
...@@ -79,15 +81,21 @@ public class ValueEnum extends Value { ...@@ -79,15 +81,21 @@ public class ValueEnum extends Value {
case VALID: case VALID:
return; return;
default: default:
throw DbException.get(ErrorCode.VALUE_NOT_PERMITTED, throw DbException.get(ErrorCode.ENUM_VALUE_NOT_PERMITTED_2,
"Provided value does not match any enumerators " + toString(enumerators), value.toString()); toString(enumerators), value.toString());
}
} }
@Override
protected int compareSecure(final Value v, final CompareMode mode) {
final ValueEnum ev = ValueEnum.get(enumerators, v);
return MathUtils.compareInt(ordinal(), ev.ordinal());
} }
@Override @Override
protected int compareSecure(final Value o, final CompareMode mode) { public Value divide(final Value v) {
final ValueEnum v = ValueEnum.get(enumerators, o); final Value iv = v.convertTo(Value.INT);
return MathUtils.compareInt(ordinal(), v.ordinal()); return convertTo(Value.INT).divide(iv);
} }
@Override @Override
...@@ -166,6 +174,11 @@ public class ValueEnum extends Value { ...@@ -166,6 +174,11 @@ public class ValueEnum extends Value {
return label; return label;
} }
@Override
public int getType() {
return Value.ENUM;
}
@Override @Override
public int hashCode() { public int hashCode() {
return enumerators.hashCode() + ordinal; return enumerators.hashCode() + ordinal;
...@@ -183,13 +196,20 @@ public class ValueEnum extends Value { ...@@ -183,13 +196,20 @@ public class ValueEnum extends Value {
return validate(enumerators, value).equals(Validation.VALID); return validate(enumerators, value).equals(Validation.VALID);
} }
protected int ordinal() {
return ordinal;
}
@Override @Override
public int getType() { public Value modulus(final Value v) {
return Value.ENUM; final Value iv = v.convertTo(Value.INT);
return convertTo(Value.INT).modulus(iv);
} }
protected int ordinal() { @Override
return ordinal; public Value multiply(final Value v) {
final Value iv = v.convertTo(Value.INT);
return convertTo(Value.INT).multiply(iv);
} }
@Override @Override
...@@ -198,6 +218,12 @@ public class ValueEnum extends Value { ...@@ -198,6 +218,12 @@ public class ValueEnum extends Value {
prep.setInt(parameterIndex, ordinal); prep.setInt(parameterIndex, ordinal);
} }
@Override
public Value subtract(final Value v) {
final Value iv = v.convertTo(Value.INT);
return convertTo(Value.INT).subtract(iv);
}
private static String toString(final String[] enumerators) { private static String toString(final String[] enumerators) {
String result = "("; String result = "(";
for (int i = 0; i < enumerators.length; i++) { for (int i = 0; i < enumerators.length; i++) {
...@@ -213,12 +239,10 @@ public class ValueEnum extends Value { ...@@ -213,12 +239,10 @@ public class ValueEnum extends Value {
private static Validation validate(final String[] enumerators, final String label) { private static Validation validate(final String[] enumerators, final String label) {
check(enumerators); check(enumerators);
if (label == null || label.trim().length() == 0) { final String cleanLabel = label.trim().toLowerCase();
return Validation.EMPTY;
}
for (int i = 0; i < enumerators.length; i++) { for (int i = 0; i < enumerators.length; i++) {
if (label.equals(enumerators[i])) { if (cleanLabel.equals(enumerators[i])) {
return Validation.VALID; return Validation.VALID;
} }
} }
...@@ -228,7 +252,7 @@ public class ValueEnum extends Value { ...@@ -228,7 +252,7 @@ public class ValueEnum extends Value {
private static Validation validate(final String[] enumerators) { private static Validation validate(final String[] enumerators) {
for (int i = 0; i < enumerators.length; i++) { for (int i = 0; i < enumerators.length; i++) {
if (enumerators[i] == null || enumerators[i].equals("")) { if (enumerators[i] == null || enumerators[i].trim().equals("")) {
return Validation.EMPTY; return Validation.EMPTY;
} }
......
...@@ -453,7 +453,7 @@ public class TestPreparedStatement extends TestBase { ...@@ -453,7 +453,7 @@ public class TestPreparedStatement extends TestBase {
PreparedStatement prep = conn.prepareStatement( PreparedStatement prep = conn.prepareStatement(
"INSERT INTO test_enum VALUES(?)"); "INSERT INTO test_enum VALUES(?)");
prep.setObject(1, badSizes[i]); prep.setObject(1, badSizes[i]);
assertThrows(ErrorCode.VALUE_NOT_PERMITTED, prep).execute(); assertThrows(ErrorCode.ENUM_VALUE_NOT_PERMITTED_1, prep).execute();
} }
String[] goodSizes = new String[]{"small", "medium", "large"}; String[] goodSizes = new String[]{"small", "medium", "large"};
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论