|
20 | 20 | */
|
21 | 21 | package oracle.r2dbc;
|
22 | 22 |
|
| 23 | +import io.r2dbc.spi.Parameter; |
| 24 | +import io.r2dbc.spi.R2dbcType; |
23 | 25 | import io.r2dbc.spi.Result;
|
| 26 | +import io.r2dbc.spi.Statement; |
24 | 27 | import io.r2dbc.spi.Type;
|
25 | 28 | import oracle.sql.json.OracleJsonObject;
|
26 | 29 |
|
|
29 | 32 | import java.time.Duration;
|
30 | 33 | import java.time.LocalDateTime;
|
31 | 34 | import java.time.Period;
|
| 35 | +import java.util.Objects; |
32 | 36 |
|
33 | 37 | /**
|
34 | 38 | * SQL types supported by Oracle Database that are not defined as standard types
|
@@ -99,10 +103,102 @@ private OracleR2dbcTypes() {}
|
99 | 103 | public static final Type REF_CURSOR =
|
100 | 104 | new TypeImpl(Result.class, "SYS_REFCURSOR");
|
101 | 105 |
|
| 106 | + /** |
| 107 | + * <p> |
| 108 | + * Creates an {@link ArrayType} representing a user defined {@code ARRAY} |
| 109 | + * type. The {@code name} passed to this method must identify the name of a |
| 110 | + * user defined {@code ARRAY} type. |
| 111 | + * </p><p> |
| 112 | + * Typically, the name passed to this method should be UPPER CASE, unless the |
| 113 | + * {@code CREATE TYPE} command that created the type used an "enquoted" type |
| 114 | + * name. |
| 115 | + * </p><p> |
| 116 | + * The {@code ArrayType} object returned by this method may be used to create |
| 117 | + * a {@link Parameter} that binds an array value to a {@link Statement}. |
| 118 | + * </p><pre>{@code |
| 119 | + * Publisher<Result> arrayBindExample(Connection connection) { |
| 120 | + * Statement statement = |
| 121 | + * connection.createStatement("INSERT INTO example VALUES (:array_bind)"); |
| 122 | + * |
| 123 | + * // Use the name defined for an ARRAY type: |
| 124 | + * // CREATE TYPE MY_ARRAY AS ARRAY(8) OF NUMBER |
| 125 | + * ArrayType arrayType = OracleR2dbcTypes.arrayType("MY_ARRAY"); |
| 126 | + * Integer[] arrayValues = {1, 2, 3}; |
| 127 | + * statement.bind("arrayBind", Parameters.in(arrayType, arrayValues)); |
| 128 | + * |
| 129 | + * return statement.execute(); |
| 130 | + * } |
| 131 | + * }</pre> |
| 132 | + * @param name Name of a user defined ARRAY type. Not null. |
| 133 | + * @return A {@code Type} object representing the user defined ARRAY type. Not |
| 134 | + * null. |
| 135 | + */ |
| 136 | + public static ArrayType arrayType(String name) { |
| 137 | + return new ArrayTypeImpl(Objects.requireNonNull(name, "name is null")); |
| 138 | + } |
| 139 | + |
| 140 | + /** |
| 141 | + * Extension of the standard {@link Type} interface used to represent user |
| 142 | + * defined ARRAY types. An instance of {@code ArrayType} must be used when |
| 143 | + * binding an array value to a {@link Statement} created by the Oracle R2DBC |
| 144 | + * Driver. |
| 145 | + * </p><p> |
| 146 | + * Oracle Database does not support an anonymous {@code ARRAY} type, which is |
| 147 | + * what the standard {@link R2dbcType#COLLECTION} type represents. Oracle |
| 148 | + * Database only supports {@code ARRAY} types which are declared as a user |
| 149 | + * defined type, as in: |
| 150 | + * <pre>{@code |
| 151 | + * CREATE TYPE MY_ARRAY AS ARRAY(8) OF NUMBER |
| 152 | + * }</pre> |
| 153 | + * In order to bind an array, the name of a user defined ARRAY type must |
| 154 | + * be known to Oracle R2DBC. Instances of {@code ArrayType} retain the name |
| 155 | + * that is provided to the {@link #arrayType(String)} factory method. |
| 156 | + */ |
| 157 | + public interface ArrayType extends Type { |
| 158 | + |
| 159 | + /** |
| 160 | + * {@inheritDoc} |
| 161 | + * Returns {@code Object[].class}, which is the standard mapping for |
| 162 | + * {@link R2dbcType#COLLECTION}. The true default type mapping is the array |
| 163 | + * variant of the default mapping for the element type of the {@code ARRAY}. |
| 164 | + * For instance, an {@code ARRAY} of {@code VARCHAR} maps to a |
| 165 | + * {@code String[]} by default. |
| 166 | + */ |
| 167 | + @Override |
| 168 | + Class<?> getJavaType(); |
| 169 | + |
| 170 | + /** |
| 171 | + * {@inheritDoc} |
| 172 | + * Returns the name of this user defined {@code ARRAY} type. For instance, |
| 173 | + * this method returns "MY_ARRAY" if the type is declared as: |
| 174 | + * <pre>{@code |
| 175 | + * CREATE TYPE MY_ARRAY AS ARRAY(8) OF NUMBER |
| 176 | + * }</pre> |
| 177 | + */ |
| 178 | + @Override |
| 179 | + String getName(); |
| 180 | + } |
| 181 | + |
| 182 | + /** Concrete implementation of the {@code ArrayType} interface */ |
| 183 | + private static final class ArrayTypeImpl |
| 184 | + extends TypeImpl implements ArrayType { |
| 185 | + |
| 186 | + /** |
| 187 | + * Constructs an ARRAY type with the given {@code name}. The constructed |
| 188 | + * {@code ArrayType} as a default Java type mapping of |
| 189 | + * {@code Object[].class}. This is consistent with the standard |
| 190 | + * {@link R2dbcType#COLLECTION} type. |
| 191 | + * @param name User defined name of the type. Not null. |
| 192 | + */ |
| 193 | + ArrayTypeImpl(String name) { |
| 194 | + super(Object[].class, name); |
| 195 | + } |
| 196 | + } |
| 197 | + |
102 | 198 | /**
|
103 | 199 | * Implementation of the {@link Type} SPI.
|
104 | 200 | */
|
105 |
| - private static final class TypeImpl implements Type { |
| 201 | + private static class TypeImpl implements Type { |
106 | 202 |
|
107 | 203 | /**
|
108 | 204 | * The Java Language mapping of this SQL type.
|
|
0 commit comments