| 
 | 1 | +// SPDX-License-Identifier: LGPL-2.1-or-later  | 
 | 2 | +// Copyright (c) 2012-2014 Monty Program Ab  | 
 | 3 | +// Copyright (c) 2015-2021 MariaDB Corporation Ab  | 
 | 4 | + | 
 | 5 | +package org.mariadb.jdbc;  | 
 | 6 | + | 
 | 7 | +import java.sql.SQLException;  | 
 | 8 | +import org.mariadb.jdbc.export.ExceptionFactory;  | 
 | 9 | + | 
 | 10 | +public class SimpleParameterMetaData implements java.sql.ParameterMetaData {  | 
 | 11 | + | 
 | 12 | + private final int paramCount;  | 
 | 13 | + private final ExceptionFactory exceptionFactory;  | 
 | 14 | + | 
 | 15 | + protected SimpleParameterMetaData(ExceptionFactory exceptionFactory, int paramCount) {  | 
 | 16 | + this.exceptionFactory = exceptionFactory;  | 
 | 17 | + this.paramCount = paramCount;  | 
 | 18 | + }  | 
 | 19 | + | 
 | 20 | + /**  | 
 | 21 | + * Retrieves the number of parameters in the <code>PreparedStatement</code> object for which this  | 
 | 22 | + * <code>ParameterMetaData</code> object contains information.  | 
 | 23 | + *  | 
 | 24 | + * @return the number of parameters  | 
 | 25 | + */  | 
 | 26 | + @Override  | 
 | 27 | + public int getParameterCount() {  | 
 | 28 | + return paramCount;  | 
 | 29 | + }  | 
 | 30 | + | 
 | 31 | + private void checkIndex(int index) throws SQLException {  | 
 | 32 | + if (index < 1 || index > paramCount) {  | 
 | 33 | + throw exceptionFactory.create(  | 
 | 34 | + String.format(  | 
 | 35 | + "Wrong index position. Is %s but must be in 1-%s range", index, paramCount));  | 
 | 36 | + }  | 
 | 37 | + }  | 
 | 38 | + | 
 | 39 | + /**  | 
 | 40 | + * Retrieves whether null values are allowed in the designated parameter.  | 
 | 41 | + *  | 
 | 42 | + * @param idx the first parameter is 1, the second is 2, ...  | 
 | 43 | + * @return the nullability status of the given parameter; one of <code>  | 
 | 44 | + * ParameterMetaData.parameterNoNulls</code>, <code>ParameterMetaData.parameterNullable</code>  | 
 | 45 | + * @throws SQLException if wrong index  | 
 | 46 | + */  | 
 | 47 | + @Override  | 
 | 48 | + public int isNullable(int idx) throws SQLException {  | 
 | 49 | + checkIndex(idx);  | 
 | 50 | + return java.sql.ParameterMetaData.parameterNullable;  | 
 | 51 | + }  | 
 | 52 | + | 
 | 53 | + /**  | 
 | 54 | + * Retrieves whether values for the designated parameter can be signed numbers.  | 
 | 55 | + *  | 
 | 56 | + * @param idx the first parameter is 1, the second is 2, ...  | 
 | 57 | + * @return <code>true</code> if so; <code>false</code> otherwise  | 
 | 58 | + * @throws SQLException if wrong index  | 
 | 59 | + */  | 
 | 60 | + @Override  | 
 | 61 | + public boolean isSigned(int idx) throws SQLException {  | 
 | 62 | + checkIndex(idx);  | 
 | 63 | + return true;  | 
 | 64 | + }  | 
 | 65 | + | 
 | 66 | + /**  | 
 | 67 | + * Retrieves the designated parameter's specified column size.  | 
 | 68 | + *  | 
 | 69 | + * <p>The returned value represents the maximum column size for the given parameter. For numeric  | 
 | 70 | + * data, this is the maximum precision. For character data, this is the length in characters. For  | 
 | 71 | + * datetime datatypes, this is the length in characters of the String representation (assuming the  | 
 | 72 | + * maximum allowed precision of the fractional seconds component). For binary data, this is the  | 
 | 73 | + * length in bytes. For the ROWID datatype, this is the length in bytes. 0 is returned for data  | 
 | 74 | + * types where the column size is not applicable.  | 
 | 75 | + *  | 
 | 76 | + * @param idx the first parameter is 1, the second is 2, ...  | 
 | 77 | + * @return precision  | 
 | 78 | + * @throws SQLException if wrong index  | 
 | 79 | + */  | 
 | 80 | + @Override  | 
 | 81 | + public int getPrecision(int idx) throws SQLException {  | 
 | 82 | + checkIndex(idx);  | 
 | 83 | + throw exceptionFactory.create("Unknown parameter metadata precision");  | 
 | 84 | + }  | 
 | 85 | + | 
 | 86 | + /**  | 
 | 87 | + * Retrieves the designated parameter's number of digits to right of the decimal point. 0 is  | 
 | 88 | + * returned for data types where the scale is not applicable. Parameter type are not sent by  | 
 | 89 | + * server. See * https://jira.mariadb.org/browse/CONJ-568 and  | 
 | 90 | + * https://jira.mariadb.org/browse/MDEV-15031  | 
 | 91 | + *  | 
 | 92 | + * @param idx the first parameter is 1, the second is 2, ...  | 
 | 93 | + * @return scale  | 
 | 94 | + * @throws SQLException if a database access error occurs  | 
 | 95 | + */  | 
 | 96 | + @Override  | 
 | 97 | + public int getScale(int idx) throws SQLException {  | 
 | 98 | + checkIndex(idx);  | 
 | 99 | + throw exceptionFactory.create("Unknown parameter metadata scale");  | 
 | 100 | + }  | 
 | 101 | + | 
 | 102 | + /**  | 
 | 103 | + * Retrieves the designated parameter's SQL type. Parameter type are not sent by server. See  | 
 | 104 | + * https://jira.mariadb.org/browse/CONJ-568 and https://jira.mariadb.org/browse/MDEV-15031  | 
 | 105 | + *  | 
 | 106 | + * @param idx the first parameter is 1, the second is 2, ...  | 
 | 107 | + * @return SQL types from <code>java.sql.Types</code>  | 
 | 108 | + * @throws SQLException because not supported  | 
 | 109 | + */  | 
 | 110 | + @Override  | 
 | 111 | + public int getParameterType(int idx) throws SQLException {  | 
 | 112 | + checkIndex(idx);  | 
 | 113 | + throw exceptionFactory.create("Getting parameter type metadata is not supported", "0A000", -1);  | 
 | 114 | + }  | 
 | 115 | + | 
 | 116 | + /**  | 
 | 117 | + * Retrieves the designated parameter's database-specific type name.  | 
 | 118 | + *  | 
 | 119 | + * @param idx the first parameter is 1, the second is 2, ...  | 
 | 120 | + * @return type the name used by the database. If the parameter type is a user-defined type, then  | 
 | 121 | + * a fully-qualified type name is returned.  | 
 | 122 | + * @throws SQLException if wrong index  | 
 | 123 | + */  | 
 | 124 | + @Override  | 
 | 125 | + public String getParameterTypeName(int idx) throws SQLException {  | 
 | 126 | + checkIndex(idx);  | 
 | 127 | + throw exceptionFactory.create("Unknown parameter metadata type name");  | 
 | 128 | + }  | 
 | 129 | + | 
 | 130 | + /**  | 
 | 131 | + * Retrieves the fully-qualified name of the Java class whose instances should be passed to the  | 
 | 132 | + * method <code>PreparedStatement.setObject</code>.  | 
 | 133 | + *  | 
 | 134 | + * @param idx the first parameter is 1, the second is 2, ...  | 
 | 135 | + * @return the fully-qualified name of the class in the Java programming language that would be  | 
 | 136 | + * used by the method <code>PreparedStatement.setObject</code> to set the value in the  | 
 | 137 | + * specified parameter. This is the class name used for custom mapping.  | 
 | 138 | + * @throws SQLException if wrong index  | 
 | 139 | + */  | 
 | 140 | + @Override  | 
 | 141 | + public String getParameterClassName(int idx) throws SQLException {  | 
 | 142 | + checkIndex(idx);  | 
 | 143 | + throw exceptionFactory.create("Unknown parameter metadata class name", "0A000");  | 
 | 144 | + }  | 
 | 145 | + | 
 | 146 | + /**  | 
 | 147 | + * Retrieves the designated parameter's mode.  | 
 | 148 | + *  | 
 | 149 | + * @param idx the first parameter is 1, the second is 2, ...  | 
 | 150 | + * @return mode of the parameter; one of <code>ParameterMetaData.parameterModeIn</code>, <code>  | 
 | 151 | + * ParameterMetaData.parameterModeOut</code>, or <code>ParameterMetaData.parameterModeInOut  | 
 | 152 | + * </code> <code>ParameterMetaData.parameterModeUnknown</code>.  | 
 | 153 | + */  | 
 | 154 | + @Override  | 
 | 155 | + public int getParameterMode(int idx) throws SQLException {  | 
 | 156 | + checkIndex(idx);  | 
 | 157 | + return java.sql.ParameterMetaData.parameterModeIn;  | 
 | 158 | + }  | 
 | 159 | + | 
 | 160 | + /**  | 
 | 161 | + * Returns an object that implements the given interface to allow access to non-standard methods,  | 
 | 162 | + * or standard methods not exposed by the proxy.  | 
 | 163 | + *  | 
 | 164 | + * <p>If the receiver implements the interface then the result is the receiver or a proxy for the  | 
 | 165 | + * receiver. If the receiver is a wrapper and the wrapped object implements the interface then the  | 
 | 166 | + * result is the wrapped object or a proxy for the wrapped object. Otherwise, return the result of  | 
 | 167 | + * calling <code>unwrap</code> recursively on the wrapped object or a proxy for that result. If  | 
 | 168 | + * the receiver is not a wrapper and does not implement the interface, then an <code>SQLException  | 
 | 169 | + * </code> is thrown.  | 
 | 170 | + *  | 
 | 171 | + * @param iface A Class defining an interface that the result must implement.  | 
 | 172 | + * @return an object that implements the interface. Maybe a proxy for the actual implementing  | 
 | 173 | + * object.  | 
 | 174 | + * @throws SQLException If no object found that implements the interface  | 
 | 175 | + */  | 
 | 176 | + @Override  | 
 | 177 | + public <T> T unwrap(Class<T> iface) throws SQLException {  | 
 | 178 | + if (isWrapperFor(iface)) {  | 
 | 179 | + return iface.cast(this);  | 
 | 180 | + }  | 
 | 181 | + throw new SQLException("The receiver is not a wrapper for " + iface.getName());  | 
 | 182 | + }  | 
 | 183 | + | 
 | 184 | + /**  | 
 | 185 | + * Returns true if this either implements the interface argument or is directly or indirectly a  | 
 | 186 | + * wrapper for an object that does. Returns false otherwise. If this implements the interface then  | 
 | 187 | + * return true, else if this is a wrapper then return the result of recursively calling <code>  | 
 | 188 | + * isWrapperFor</code> on the wrapped object. If this does not implement the interface and is not  | 
 | 189 | + * a wrapper, return false. This method should be implemented as a low-cost operation compared to  | 
 | 190 | + * <code>unwrap</code> so that callers can use this method to avoid expensive <code>unwrap</code>  | 
 | 191 | + * calls that may fail. If this method returns true then calling <code>unwrap</code> with the same  | 
 | 192 | + * argument should succeed.  | 
 | 193 | + *  | 
 | 194 | + * @param iface a Class defining an interface.  | 
 | 195 | + * @return true if this implements the interface or directly or indirectly wraps an object that  | 
 | 196 | + * does.  | 
 | 197 | + */  | 
 | 198 | + @Override  | 
 | 199 | + public boolean isWrapperFor(Class<?> iface) {  | 
 | 200 | + return iface.isInstance(this);  | 
 | 201 | + }  | 
 | 202 | +}  | 
0 commit comments