001: /*
002: Copyright (C) 2005 MySQL AB
003:
004: This program is free software; you can redistribute it and/or modify
005: it under the terms of version 2 of the GNU General Public License as
006: published by the Free Software Foundation.
007:
008: There are special exceptions to the terms and conditions of the GPL
009: as it is applied to this software. View the full text of the
010: exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
011: software distribution.
012:
013: This program is distributed in the hope that it will be useful,
014: but WITHOUT ANY WARRANTY; without even the implied warranty of
015: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: GNU General Public License for more details.
017:
018: You should have received a copy of the GNU General Public License
019: along with this program; if not, write to the Free Software
020: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021:
022: */
023:
024: package com.mysql.jdbc;
025:
026: import java.sql.ParameterMetaData;
027: import java.sql.SQLException;
028: import java.sql.Types;
029:
030: import com.mysql.jdbc.exceptions.NotYetImplementedException;
031:
032: public class MysqlParameterMetadata implements ParameterMetaData {
033: boolean returnSimpleMetadata = false;
034:
035: ResultSetMetaData metadata = null;
036:
037: int parameterCount = 0;
038:
039: MysqlParameterMetadata(Field[] fieldInfo, int parameterCount) {
040: this .metadata = new ResultSetMetaData(fieldInfo, false);
041:
042: this .parameterCount = parameterCount;
043: }
044:
045: /**
046: * Used for "fake" basic metadata for client-side prepared statements when
047: * we don't know the parameter types.
048: *
049: * @param parameterCount
050: */
051: MysqlParameterMetadata(int count) {
052: this .parameterCount = count;
053: this .returnSimpleMetadata = true;
054: }
055:
056: public int getParameterCount() throws SQLException {
057: return this .parameterCount;
058: }
059:
060: public int isNullable(int arg0) throws SQLException {
061: checkAvailable();
062:
063: return this .metadata.isNullable(arg0);
064: }
065:
066: private void checkAvailable() throws SQLException {
067: if (this .metadata == null || this .metadata.fields == null) {
068: throw SQLError
069: .createSQLException(
070: "Parameter metadata not available for the given statement",
071: SQLError.SQL_STATE_DRIVER_NOT_CAPABLE);
072: }
073: }
074:
075: public boolean isSigned(int arg0) throws SQLException {
076: if (this .returnSimpleMetadata) {
077: checkBounds(arg0);
078:
079: return false;
080: }
081:
082: checkAvailable();
083:
084: return (this .metadata.isSigned(arg0));
085: }
086:
087: public int getPrecision(int arg0) throws SQLException {
088: if (this .returnSimpleMetadata) {
089: checkBounds(arg0);
090:
091: return 0;
092: }
093:
094: checkAvailable();
095:
096: return (this .metadata.getPrecision(arg0));
097: }
098:
099: public int getScale(int arg0) throws SQLException {
100: if (this .returnSimpleMetadata) {
101: checkBounds(arg0);
102:
103: return 0;
104: }
105:
106: checkAvailable();
107:
108: return (this .metadata.getScale(arg0));
109: }
110:
111: public int getParameterType(int arg0) throws SQLException {
112: if (this .returnSimpleMetadata) {
113: checkBounds(arg0);
114:
115: return Types.VARCHAR;
116: }
117:
118: checkAvailable();
119:
120: return (this .metadata.getColumnType(arg0));
121: }
122:
123: public String getParameterTypeName(int arg0) throws SQLException {
124: if (this .returnSimpleMetadata) {
125: checkBounds(arg0);
126:
127: return "VARCHAR";
128: }
129:
130: checkAvailable();
131:
132: return (this .metadata.getColumnTypeName(arg0));
133: }
134:
135: public String getParameterClassName(int arg0) throws SQLException {
136: if (this .returnSimpleMetadata) {
137: checkBounds(arg0);
138:
139: return "java.lang.String";
140: }
141:
142: checkAvailable();
143:
144: return (this .metadata.getColumnClassName(arg0));
145: }
146:
147: public int getParameterMode(int arg0) throws SQLException {
148: return parameterModeIn;
149: }
150:
151: private void checkBounds(int paramNumber) throws SQLException {
152: if (paramNumber < 1) {
153: throw SQLError.createSQLException("Parameter index of '"
154: + paramNumber + "' is invalid.",
155: SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
156: }
157:
158: if (paramNumber > this .parameterCount) {
159: throw SQLError
160: .createSQLException(
161: "Parameter index of '"
162: + paramNumber
163: + "' is greater than number of parameters, which is '"
164: + this .parameterCount + "'.",
165: SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
166:
167: }
168: }
169:
170: /**
171: * Returns true if this either implements the interface argument or is directly or indirectly a wrapper
172: * for an object that does. Returns false otherwise. If this implements the interface then return true,
173: * else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
174: * object. If this does not implement the interface and is not a wrapper, return false.
175: * This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
176: * callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
177: * returns true then calling <code>unwrap</code> with the same argument should succeed.
178: *
179: * @param interfaces a Class defining an interface.
180: * @return true if this implements the interface or directly or indirectly wraps an object that does.
181: * @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper
182: * for an object with the given interface.
183: * @since 1.6
184: */
185: public boolean isWrapperFor(Class iface) throws SQLException {
186:
187: // This works for classes that aren't actually wrapping
188: // anything
189: return iface.isInstance(this );
190: }
191:
192: /**
193: * Returns an object that implements the given interface to allow access to non-standard methods,
194: * or standard methods not exposed by the proxy.
195: * The result may be either the object found to implement the interface or a proxy for that object.
196: * If the receiver implements the interface then that is the object. If the receiver is a wrapper
197: * and the wrapped object implements the interface then that is the object. Otherwise the object is
198: * the result of calling <code>unwrap</code> recursively on the wrapped object. If the receiver is not a
199: * wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
200: *
201: * @param iface A Class defining an interface that the result must implement.
202: * @return an object that implements the interface. May be a proxy for the actual implementing object.
203: * @throws java.sql.SQLException If no object found that implements the interface
204: * @since 1.6
205: */
206: public Object unwrap(Class iface) throws java.sql.SQLException {
207: try {
208: // This works for classes that aren't actually wrapping
209: // anything
210: return Util.cast(iface, this );
211: } catch (ClassCastException cce) {
212: throw SQLError.createSQLException("Unable to unwrap to "
213: + iface.toString(),
214: SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
215: }
216: }
217: }
|