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

enum-support: add support for math operations

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