001 /* 002 // $Id: //open/mondrian/src/main/mondrian/olap4j/MondrianOlap4jPreparedStatement.java#1 $ 003 // This software is subject to the terms of the Common Public License 004 // Agreement, available at the following URL: 005 // http://www.opensource.org/licenses/cpl.html. 006 // Copyright (C) 2007-2007 Julian Hyde 007 // All Rights Reserved. 008 // You must accept the terms of that agreement to use this software. 009 */ 010 package mondrian.olap4j; 011 012 import org.olap4j.*; 013 import org.olap4j.type.*; 014 import org.olap4j.metadata.*; 015 016 import java.sql.*; 017 import java.math.BigDecimal; 018 import java.io.InputStream; 019 import java.io.Reader; 020 import java.util.Calendar; 021 import java.net.URL; 022 023 import mondrian.olap.Query; 024 import mondrian.olap.Parameter; 025 026 /** 027 * Implementation of {@link PreparedOlapStatement} 028 * for the Mondrian OLAP engine. 029 * 030 * <p>This class has sub-classes which implement JDBC 3.0 and JDBC 4.0 APIs; 031 * it is instantiated using {@link Factory#newPreparedStatement}.</p> 032 * 033 * @author jhyde 034 * @version $Id: //open/mondrian/src/main/mondrian/olap4j/MondrianOlap4jPreparedStatement.java#1 $ 035 * @since Jun 12, 2007 036 */ 037 abstract class MondrianOlap4jPreparedStatement 038 extends MondrianOlap4jStatement 039 implements PreparedOlapStatement, OlapParameterMetaData 040 { 041 private final String mdx; 042 private Query query; 043 MondrianOlap4jCellSetMetaData cellSetMetaData; 044 045 public MondrianOlap4jPreparedStatement( 046 MondrianOlap4jConnection olap4jConnection, 047 String mdx) 048 { 049 super(olap4jConnection); 050 this.mdx = mdx; 051 this.query = olap4jConnection.connection.parseQuery(mdx); 052 this.cellSetMetaData = new MondrianOlap4jCellSetMetaData(this, query); 053 } 054 055 // override OlapStatement 056 057 public CellSet executeOlapQuery(String mdx) throws OlapException { 058 this.query = olap4jConnection.connection.parseQuery(mdx); 059 this.cellSetMetaData = new MondrianOlap4jCellSetMetaData(this, query); 060 return executeOlapQueryInternal(query); 061 } 062 063 // implement PreparedOlapStatement 064 065 public CellSet executeQuery() throws OlapException { 066 return executeOlapQueryInternal(query); 067 } 068 069 public OlapParameterMetaData getParameterMetaData() throws OlapException { 070 return this; 071 } 072 073 public Cube getCube() { 074 throw new UnsupportedOperationException(); 075 } 076 077 // implement PreparedStatement 078 079 public int executeUpdate() throws SQLException { 080 throw new UnsupportedOperationException(); 081 } 082 083 public void setNull(int parameterIndex, int sqlType) throws SQLException { 084 getParameter(parameterIndex).setValue(null); 085 } 086 087 public void setBoolean(int parameterIndex, boolean x) throws SQLException { 088 getParameter(parameterIndex).setValue(x); 089 } 090 091 public void setByte(int parameterIndex, byte x) throws SQLException { 092 getParameter(parameterIndex).setValue(x); 093 } 094 095 public void setShort(int parameterIndex, short x) throws SQLException { 096 getParameter(parameterIndex).setValue(x); 097 } 098 099 public void setInt(int parameterIndex, int x) throws SQLException { 100 getParameter(parameterIndex).setValue(x); 101 } 102 103 public void setLong(int parameterIndex, long x) throws SQLException { 104 getParameter(parameterIndex).setValue(x); 105 } 106 107 public void setFloat(int parameterIndex, float x) throws SQLException { 108 getParameter(parameterIndex).setValue(x); 109 } 110 111 public void setDouble(int parameterIndex, double x) throws SQLException { 112 getParameter(parameterIndex).setValue(x); 113 } 114 115 public void setBigDecimal( 116 int parameterIndex, BigDecimal x) throws SQLException { 117 getParameter(parameterIndex).setValue(x); 118 } 119 120 public void setString(int parameterIndex, String x) throws SQLException { 121 getParameter(parameterIndex).setValue(x); 122 } 123 124 public void setBytes(int parameterIndex, byte x[]) throws SQLException { 125 getParameter(parameterIndex).setValue(x); 126 } 127 128 public void setDate(int parameterIndex, Date x) throws SQLException { 129 getParameter(parameterIndex).setValue(x); 130 } 131 132 public void setTime(int parameterIndex, Time x) throws SQLException { 133 getParameter(parameterIndex).setValue(x); 134 } 135 136 public void setTimestamp( 137 int parameterIndex, Timestamp x) throws SQLException { 138 getParameter(parameterIndex).setValue(x); 139 } 140 141 public void setAsciiStream( 142 int parameterIndex, InputStream x, int length) throws SQLException { 143 getParameter(parameterIndex).setValue(x); 144 } 145 146 public void setUnicodeStream( 147 int parameterIndex, InputStream x, int length) throws SQLException { 148 getParameter(parameterIndex).setValue(x); 149 } 150 151 public void setBinaryStream( 152 int parameterIndex, InputStream x, int length) throws SQLException { 153 getParameter(parameterIndex).setValue(x); 154 } 155 156 public void clearParameters() throws SQLException { 157 throw new UnsupportedOperationException(); 158 } 159 160 public void setObject( 161 int parameterIndex, Object x, int targetSqlType) throws SQLException { 162 getParameter(parameterIndex).setValue(x); 163 } 164 165 public void setObject(int parameterIndex, Object x) throws SQLException { 166 final Parameter parameter = getParameter(parameterIndex); 167 if (x instanceof MondrianOlap4jMember) { 168 MondrianOlap4jMember mondrianOlap4jMember = 169 (MondrianOlap4jMember) x; 170 x = mondrianOlap4jMember.member; 171 } 172 parameter.setValue(x); 173 } 174 175 public boolean execute() throws SQLException { 176 throw new UnsupportedOperationException(); 177 } 178 179 public void addBatch() throws SQLException { 180 throw new UnsupportedOperationException(); 181 } 182 183 public void setCharacterStream( 184 int parameterIndex, Reader reader, int length) throws SQLException { 185 throw new UnsupportedOperationException(); 186 } 187 188 public void setRef(int parameterIndex, Ref x) throws SQLException { 189 throw new UnsupportedOperationException(); 190 } 191 192 public void setBlob(int parameterIndex, Blob x) throws SQLException { 193 throw new UnsupportedOperationException(); 194 } 195 196 public void setClob(int parameterIndex, Clob x) throws SQLException { 197 throw new UnsupportedOperationException(); 198 } 199 200 public void setArray(int parameterIndex, Array x) throws SQLException { 201 throw new UnsupportedOperationException(); 202 } 203 204 public CellSetMetaData getMetaData() { 205 return cellSetMetaData; 206 } 207 208 public void setDate( 209 int parameterIndex, Date x, Calendar cal) throws SQLException { 210 throw new UnsupportedOperationException(); 211 } 212 213 public void setTime( 214 int parameterIndex, Time x, Calendar cal) throws SQLException { 215 throw new UnsupportedOperationException(); 216 } 217 218 public void setTimestamp( 219 int parameterIndex, Timestamp x, Calendar cal) throws SQLException { 220 throw new UnsupportedOperationException(); 221 } 222 223 public void setNull( 224 int parameterIndex, int sqlType, String typeName) throws SQLException { 225 throw new UnsupportedOperationException(); 226 } 227 228 public void setURL(int parameterIndex, URL x) throws SQLException { 229 throw new UnsupportedOperationException(); 230 } 231 232 public void setObject( 233 int parameterIndex, 234 Object x, 235 int targetSqlType, 236 int scaleOrLength) throws SQLException { 237 throw new UnsupportedOperationException(); 238 } 239 240 // implement OlapParameterMetaData 241 242 public String getParameterName(int param) throws OlapException { 243 Parameter paramDef = getParameter(param); 244 return paramDef.getName(); 245 } 246 247 private Parameter getParameter(int param) throws OlapException { 248 final Parameter[] parameters = query.getParameters(); 249 if (param < 1 || param > parameters.length) { 250 throw this.olap4jConnection.helper.toOlapException( 251 this.olap4jConnection.helper.createException( 252 "parameter ordinal " + param + " out of range")); 253 } 254 return parameters[param - 1]; 255 } 256 257 public Type getParameterOlapType(int param) throws OlapException { 258 Parameter paramDef = getParameter(param); 259 return olap4jConnection.toOlap4j(paramDef.getType()); 260 } 261 262 public int getParameterCount() { 263 return query.getParameters().length; 264 } 265 266 public int isNullable(int param) throws SQLException { 267 return ParameterMetaData.parameterNullableUnknown; 268 } 269 270 public boolean isSigned(int param) throws SQLException { 271 final Type type = getParameterOlapType(param); 272 return type instanceof NumericType; 273 } 274 275 public int getPrecision(int param) throws SQLException { 276 final Type type = getParameterOlapType(param); 277 if (type instanceof NumericType) { 278 return 0; // precision not applicable 279 } 280 if (type instanceof StringType) { 281 return Integer.MAX_VALUE; 282 } 283 return 0; 284 } 285 286 public int getScale(int param) throws SQLException { 287 return 0; // scale not applicable 288 } 289 290 public int getParameterType(int param) throws SQLException { 291 final Type type = getParameterOlapType(param); 292 if (type instanceof NumericType) { 293 return Types.NUMERIC; 294 } else if (type instanceof StringType) { 295 return Types.VARCHAR; 296 } else if (type instanceof NullType) { 297 return Types.NULL; 298 } else { 299 return Types.OTHER; 300 } 301 } 302 303 public String getParameterTypeName(int param) throws SQLException { 304 final Type type = getParameterOlapType(param); 305 return type.toString(); 306 } 307 308 public String getParameterClassName(int param) throws SQLException { 309 final Type type = getParameterOlapType(param); 310 return foo( 311 new TypeHelper<Class>() { 312 public Class booleanType(BooleanType type) { 313 return Boolean.class; 314 } 315 316 public Class<Cube> cubeType(CubeType cubeType) { 317 return Cube.class; 318 } 319 320 public Class<Number> decimalType(DecimalType decimalType) { 321 return Number.class; 322 } 323 324 public Class<Dimension> dimensionType(DimensionType dimensionType) { 325 return Dimension.class; 326 } 327 328 public Class<Hierarchy> hierarchyType(HierarchyType hierarchyType) { 329 return Hierarchy.class; 330 } 331 332 public Class<Level> levelType(LevelType levelType) { 333 return Level.class; 334 } 335 336 public Class<Member> memberType(MemberType memberType) { 337 return Member.class; 338 } 339 340 public Class<Void> nullType(NullType nullType) { 341 return Void.class; 342 } 343 344 public Class<Number> numericType(NumericType numericType) { 345 return Number.class; 346 } 347 348 public Class<Iterable> setType(SetType setType) { 349 return Iterable.class; 350 } 351 352 public Class<String> stringType(StringType stringType) { 353 return String.class; 354 } 355 356 public Class<Member[]> tupleType(TupleType tupleType) { 357 return Member[].class; 358 } 359 360 public Class symbolType(SymbolType symbolType) { 361 // parameters cannot be of this type 362 throw new UnsupportedOperationException(); 363 } 364 }, 365 type).getName(); 366 } 367 368 public int getParameterMode(int param) throws SQLException { 369 Parameter paramDef = getParameter(param); // forces param range check 370 return ParameterMetaData.parameterModeIn; 371 } 372 373 // Helper classes 374 375 private interface TypeHelper<T> { 376 T booleanType(BooleanType type); 377 T cubeType(CubeType cubeType); 378 T decimalType(DecimalType decimalType); 379 T dimensionType(DimensionType dimensionType); 380 T hierarchyType(HierarchyType hierarchyType); 381 T levelType(LevelType levelType); 382 T memberType(MemberType memberType); 383 T nullType(NullType nullType); 384 T numericType(NumericType numericType); 385 T setType(SetType setType); 386 T stringType(StringType stringType); 387 T tupleType(TupleType tupleType); 388 T symbolType(SymbolType symbolType); 389 } 390 391 <T> T foo(TypeHelper<T> helper, Type type) { 392 if (type instanceof BooleanType) { 393 return helper.booleanType((BooleanType) type); 394 } else if (type instanceof CubeType) { 395 return helper.cubeType((CubeType) type); 396 } else if (type instanceof DecimalType) { 397 return helper.decimalType((DecimalType) type); 398 } else if (type instanceof DimensionType) { 399 return helper.dimensionType((DimensionType) type); 400 } else if (type instanceof HierarchyType) { 401 return helper.hierarchyType((HierarchyType) type); 402 } else if (type instanceof LevelType) { 403 return helper.levelType((LevelType) type); 404 } else if (type instanceof MemberType) { 405 return helper.memberType((MemberType) type); 406 } else if (type instanceof NullType) { 407 return helper.nullType((NullType) type); 408 } else if (type instanceof NumericType) { 409 return helper.numericType((NumericType) type); 410 } else if (type instanceof SetType) { 411 return helper.setType((SetType) type); 412 } else if (type instanceof StringType) { 413 return helper.stringType((StringType) type); 414 } else if (type instanceof TupleType) { 415 return helper.tupleType((TupleType) type); 416 } else if (type instanceof SymbolType) { 417 return helper.symbolType((SymbolType) type); 418 } else { 419 throw new UnsupportedOperationException(); 420 } 421 } 422 } 423 424 // End MondrianOlap4jPreparedStatement.java