001 /* 002 // $Id: //open/mondrian/src/main/mondrian/olap4j/MondrianOlap4jStatement.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 mondrian.olap.*; 013 import org.olap4j.*; 014 import org.olap4j.mdx.*; 015 016 import java.io.PrintWriter; 017 import java.io.StringWriter; 018 import java.sql.*; 019 import java.sql.Connection; 020 021 /** 022 * Implementation of {@link org.olap4j.OlapStatement} 023 * for the Mondrian OLAP engine. 024 * 025 * @author jhyde 026 * @version $Id: //open/mondrian/src/main/mondrian/olap4j/MondrianOlap4jStatement.java#1 $ 027 * @since May 24, 2007 028 */ 029 class MondrianOlap4jStatement implements OlapStatement { 030 final MondrianOlap4jConnection olap4jConnection; 031 private boolean closed; 032 033 /** 034 * Current cell set, or null if the statement is not executing anything. 035 * Any method which modifies this member must synchronize 036 * on the MondrianOlap4jStatement. 037 */ 038 MondrianOlap4jCellSet openCellSet; 039 int timeoutSeconds; 040 041 MondrianOlap4jStatement( 042 MondrianOlap4jConnection olap4jConnection) 043 { 044 assert olap4jConnection != null; 045 this.olap4jConnection = olap4jConnection; 046 this.closed = false; 047 } 048 049 // implement Statement 050 051 public ResultSet executeQuery(String sql) throws SQLException { 052 throw new UnsupportedOperationException(); 053 } 054 055 private void checkOpen() throws SQLException { 056 if (closed) { 057 throw olap4jConnection.helper.createException("closed"); 058 } 059 } 060 061 public int executeUpdate(String sql) throws SQLException { 062 throw new UnsupportedOperationException(); 063 } 064 065 public synchronized void close() throws SQLException { 066 if (!closed) { 067 closed = true; 068 if (openCellSet != null) { 069 CellSet c = openCellSet; 070 openCellSet = null; 071 c.close(); 072 } 073 } 074 } 075 076 public int getMaxFieldSize() throws SQLException { 077 throw new UnsupportedOperationException(); 078 } 079 080 public void setMaxFieldSize(int max) throws SQLException { 081 throw new UnsupportedOperationException(); 082 } 083 084 public int getMaxRows() throws SQLException { 085 throw new UnsupportedOperationException(); 086 } 087 088 public void setMaxRows(int max) throws SQLException { 089 throw new UnsupportedOperationException(); 090 } 091 092 public void setEscapeProcessing(boolean enable) throws SQLException { 093 throw new UnsupportedOperationException(); 094 } 095 096 public int getQueryTimeout() throws SQLException { 097 return timeoutSeconds; 098 } 099 100 public void setQueryTimeout(int seconds) throws SQLException { 101 if (seconds < 0) { 102 throw olap4jConnection.helper.createException( 103 "illegal timeout value " + seconds); 104 } 105 this.timeoutSeconds = seconds; 106 } 107 108 public synchronized void cancel() throws SQLException { 109 if (openCellSet != null) { 110 openCellSet.query.cancel(); 111 } 112 } 113 114 public SQLWarning getWarnings() throws SQLException { 115 throw new UnsupportedOperationException(); 116 } 117 118 public void clearWarnings() throws SQLException { 119 throw new UnsupportedOperationException(); 120 } 121 122 public void setCursorName(String name) throws SQLException { 123 throw new UnsupportedOperationException(); 124 } 125 126 public boolean execute(String sql) throws SQLException { 127 throw new UnsupportedOperationException(); 128 } 129 130 public ResultSet getResultSet() throws SQLException { 131 throw new UnsupportedOperationException(); 132 } 133 134 public int getUpdateCount() throws SQLException { 135 throw new UnsupportedOperationException(); 136 } 137 138 public boolean getMoreResults() throws SQLException { 139 throw new UnsupportedOperationException(); 140 } 141 142 public void setFetchDirection(int direction) throws SQLException { 143 throw new UnsupportedOperationException(); 144 } 145 146 public int getFetchDirection() throws SQLException { 147 throw new UnsupportedOperationException(); 148 } 149 150 public void setFetchSize(int rows) throws SQLException { 151 throw new UnsupportedOperationException(); 152 } 153 154 public int getFetchSize() throws SQLException { 155 throw new UnsupportedOperationException(); 156 } 157 158 public int getResultSetConcurrency() throws SQLException { 159 throw new UnsupportedOperationException(); 160 } 161 162 public int getResultSetType() throws SQLException { 163 throw new UnsupportedOperationException(); 164 } 165 166 public void addBatch(String sql) throws SQLException { 167 throw new UnsupportedOperationException(); 168 } 169 170 public void clearBatch() throws SQLException { 171 throw new UnsupportedOperationException(); 172 } 173 174 public int[] executeBatch() throws SQLException { 175 throw new UnsupportedOperationException(); 176 } 177 178 public Connection getConnection() throws SQLException { 179 throw new UnsupportedOperationException(); 180 } 181 182 public boolean getMoreResults(int current) throws SQLException { 183 throw new UnsupportedOperationException(); 184 } 185 186 public ResultSet getGeneratedKeys() throws SQLException { 187 throw new UnsupportedOperationException(); 188 } 189 190 public int executeUpdate( 191 String sql, int autoGeneratedKeys) throws SQLException { 192 throw new UnsupportedOperationException(); 193 } 194 195 public int executeUpdate( 196 String sql, int columnIndexes[]) throws SQLException { 197 throw new UnsupportedOperationException(); 198 } 199 200 public int executeUpdate( 201 String sql, String columnNames[]) throws SQLException { 202 throw new UnsupportedOperationException(); 203 } 204 205 public boolean execute( 206 String sql, int autoGeneratedKeys) throws SQLException { 207 throw new UnsupportedOperationException(); 208 } 209 210 public boolean execute( 211 String sql, int columnIndexes[]) throws SQLException { 212 throw new UnsupportedOperationException(); 213 } 214 215 public boolean execute( 216 String sql, String columnNames[]) throws SQLException { 217 throw new UnsupportedOperationException(); 218 } 219 220 public int getResultSetHoldability() throws SQLException { 221 throw new UnsupportedOperationException(); 222 } 223 224 public boolean isClosed() throws SQLException { 225 return closed; 226 } 227 228 public void setPoolable(boolean poolable) throws SQLException { 229 throw new UnsupportedOperationException(); 230 } 231 232 public boolean isPoolable() throws SQLException { 233 throw new UnsupportedOperationException(); 234 } 235 236 // implement Wrapper 237 238 public <T> T unwrap(Class<T> iface) throws SQLException { 239 if (iface.isInstance(this)) { 240 return iface.cast(this); 241 } 242 throw olap4jConnection.helper.createException( 243 "does not implement '" + iface + "'"); 244 } 245 246 public boolean isWrapperFor(Class<?> iface) throws SQLException { 247 return iface.isInstance(this); 248 } 249 250 // implement OlapStatement 251 252 public CellSet executeOlapQuery(String mdx) throws OlapException { 253 Query query; 254 try { 255 query = olap4jConnection.connection.parseQuery(mdx); 256 } catch (MondrianException e) { 257 throw olap4jConnection.helper.createException( 258 "mondrian gave exception while parsing query", e); 259 } 260 return executeOlapQueryInternal(query); 261 } 262 263 /** 264 * Executes a parsed query, closing any previously open cellset. 265 * 266 * @param query Parsed query 267 * @return Cell set 268 * @throws OlapException if a database error occurs 269 */ 270 protected CellSet executeOlapQueryInternal( 271 Query query) throws OlapException 272 { 273 // Close the previous open CellSet, if there is one. 274 synchronized (this) { 275 if (openCellSet != null) { 276 final MondrianOlap4jCellSet cs = openCellSet; 277 openCellSet = null; 278 try { 279 cs.close(); 280 } catch (SQLException e) { 281 throw olap4jConnection.helper.createException( 282 null, "Error while closing previous CellSet", e); 283 } 284 } 285 286 openCellSet = olap4jConnection.factory.newCellSet(this, query); 287 } 288 // Release the monitor before executing, to give another thread the 289 // opportunity to call cancel. 290 try { 291 openCellSet.execute(); 292 } catch (QueryCanceledException e) { 293 throw olap4jConnection.helper.createException("Query canceled"); 294 } catch (QueryTimeoutException e) { 295 throw olap4jConnection.helper.createException(e.getMessage()); 296 } 297 return openCellSet; 298 } 299 300 public CellSet executeOlapQuery(SelectNode selectNode) throws OlapException { 301 final String mdx = toString(selectNode); 302 return executeOlapQuery(mdx); 303 } 304 305 /** 306 * Converts a {@link org.olap4j.mdx.ParseTreeNode} to MDX string. 307 * 308 * @param node Parse tree node 309 * @return MDX text 310 */ 311 private static String toString(ParseTreeNode node) { 312 StringWriter sw = new StringWriter(); 313 PrintWriter pw = new PrintWriter(sw); 314 ParseTreeWriter parseTreeWriter = new ParseTreeWriter(pw); 315 node.unparse(parseTreeWriter); 316 pw.flush(); 317 return sw.toString(); 318 } 319 } 320 321 // End MondrianOlap4jStatement.java