1 2 12 package com.versant.core.jdbc.fetch; 13 14 import com.versant.core.jdbc.sql.exp.SelectExp; 15 import com.versant.core.jdbc.sql.exp.SqlExp; 16 import com.versant.core.jdbc.sql.SqlDriver; 17 import com.versant.core.jdbc.JdbcStorageManager; 18 import com.versant.core.common.BindingSupportImpl; 19 20 import java.io.PrintStream ; 21 import java.sql.Connection ; 22 import java.sql.PreparedStatement ; 23 import java.sql.ResultSet ; 24 import java.sql.SQLException ; 25 26 35 public class FetchSpec { 36 37 private FetchOptions options = new FetchOptions(); 38 private FetchOp[] ops = new FetchOp[2]; 39 private int opCount; 40 private FetchOp[] resultOps = new FetchOp[2]; 41 private int resultOpCount; 42 private boolean singleObjectRow; 43 44 private SqlDriver sqlDriver; 45 private SelectExp root; 46 private SqlExp pos; 47 private int totColumnCount; 48 private boolean inAddFetchOp; 49 50 private SqlBuffer sqlBuffer; 51 52 public FetchSpec(SelectExp root, SqlDriver sqlDriver) { 53 this.root = root; 54 this.sqlDriver = sqlDriver; 55 } 56 57 60 public SelectExp getRoot() { 61 return root; 62 } 63 64 69 public void addFetchOp(FetchOp op, boolean includeInResult) { 70 if (opCount == ops.length) { 71 FetchOp[] a = new FetchOp[opCount * 2]; 72 System.arraycopy(ops, 0, a, 0, opCount); 73 ops = a; 74 } 75 op.setIndex(opCount); 76 ops[opCount++] = op; 77 if (includeInResult) { 78 if (resultOpCount == resultOps.length) { 79 FetchOp[] a = new FetchOp[resultOpCount * 2]; 80 System.arraycopy(resultOps, 0, a, 0, resultOpCount); 81 resultOps = a; 82 } 83 resultOps[resultOpCount++] = op; 84 } 85 if (!inAddFetchOp) { 89 try { 90 inAddFetchOp = true; 91 for (int i = opCount - 1; i < opCount; i++) { 92 SqlExp list = ops[i].init(root, totColumnCount + 1); 93 if (list != null) { 94 ++totColumnCount; 95 if (pos == null) { 96 pos = root.selectList = list; 97 } else { 98 pos.next = list; 99 } 100 for (; pos.next != null; pos = pos.next) { 101 ++totColumnCount; 102 } 103 } 104 } 105 } finally { 106 inAddFetchOp = false; 107 } 108 } 109 } 110 111 114 public int getFetchOpCount() { 115 return opCount; 116 } 117 118 121 public int[] getProjectionTypes() { 122 int[] a = new int[resultOpCount]; 123 for (int i = 0; i < resultOpCount; i++) { 124 a[i] = resultOps[i].getResultType(); 125 } 126 return a; 127 } 128 129 132 public FetchOptions getOptions() { 133 return options; 134 } 135 136 139 public void setParamList(SqlBuffer.Param paramList) { 140 if (sqlBuffer == null) { 141 generateSQL(); 142 } 143 sqlBuffer.setParamList(paramList); 144 } 145 146 149 public void printPlan(PrintStream p, String indent) { 150 for (int i = 0; i < opCount; i++) { 151 ops[i].printPlan(p, indent); 152 } 153 } 154 155 159 public synchronized void generateSQL() { 160 if (sqlBuffer != null) { 161 return; 162 } 163 sqlBuffer = new SqlBuffer(); 164 int aliasCount = root.createAlias(0); 165 if (aliasCount == 1) { 166 root.alias = null; 167 sqlBuffer.setFirstTableOrAlias(root.table.name); 168 } else { 169 sqlBuffer.setFirstTableOrAlias(root.alias); 170 } 171 root.appendSQL(sqlDriver, sqlBuffer.getSqlbuf(), null); 172 sqlBuffer.setSelectListRange(root.distinct, root.selectListStartIndex, 173 root.selectListFirstColEndIndex, root.selectListEndIndex); 174 sqlBuffer.setOrderByRange(root.orderByStartIndex, root.orderByEndIndex); 175 sqlBuffer.getSqlbuf().append(' '); 177 178 for (int i = 0; i < opCount; i++) { 179 ops[i].generateSQL(); 180 } 181 182 root = null; 184 pos = null; 185 } 186 187 199 public FetchResult createFetchResult(JdbcStorageManager sm, Connection con, 200 Object [] params, boolean forUpdate, boolean forCount, 201 long fromIncl, long toExcl, int fetchSize, boolean scrollable) { 202 203 if (scrollable && !sqlDriver.isScrollableResultSetSupported()) { 204 throw BindingSupportImpl.getInstance().datastore( 205 "Scrollable ResultSet's not supported for " + 206 sqlDriver.getName() + " using JDBC driver " + 207 sm.getJdbcConnectionSource().getDriverName()); 208 } 209 210 if (sqlBuffer == null) { 211 generateSQL(); 212 } 213 String sql = sqlBuffer.getSql(sqlDriver, params, forUpdate, forCount, 214 fromIncl, toExcl); 215 boolean error = true; 216 PreparedStatement ps = null; 217 try { 218 try { 219 if (scrollable) { 220 ps = con.prepareStatement(sql, 221 ResultSet.TYPE_SCROLL_INSENSITIVE, 222 ResultSet.CONCUR_READ_ONLY); 223 } else { 224 ps = con.prepareStatement(sql); 225 } 226 } catch (Exception e) { 227 throw BindingSupportImpl.getInstance().datastore( 228 "Error creating PreparedStatement: " + e + "\nSQL:\n" + 229 sql); 230 } 231 sqlBuffer.setParamsOnPS(sm.getJmd(), sqlDriver, ps, params, sql); 232 if (fetchSize > 0) { 233 try { 234 ps.setFetchSize(fetchSize); 235 } catch (Exception e) { 236 throw sqlDriver.mapException(e, e.toString(), true); 237 } 238 } 239 FetchResultImp ans = new FetchResultImp(this, ps, sql, scrollable); 240 error = false; 241 return ans; 242 } finally { 243 if (error && ps != null) { 244 try { 245 ps.close(); 246 } catch (SQLException e) { 247 } 249 } 250 } 251 } 252 253 258 public void fetchResultClosed(FetchResult fetchResult) { 259 for (int i = 0; i < opCount; i++) { 260 ops[i].fetchResultClosed(fetchResult); 261 } 262 } 263 264 public SqlDriver getSqlDriver() { 265 return sqlDriver; 266 } 267 268 public boolean isSingleObjectRow() { 269 return singleObjectRow; 270 } 271 272 276 public void setSingleObjectRow(boolean singleObjectRow) { 277 this.singleObjectRow = singleObjectRow; 278 } 279 280 284 public Object createRow(FetchResultImp fetchResult) { 285 for (int i = 0; i < opCount; i++) { 286 try { 287 ops[i].fetch(fetchResult); 288 } catch (Exception e) { 289 throw sqlDriver.mapException(e, e.toString() + "\nProcessing " + 290 ops[i].getIndex() + ": " + ops[i].getDescription(), 291 true); 292 } 293 } 294 if (singleObjectRow && resultOpCount == 1) { 295 return resultOps[0].getResult(fetchResult); 296 } else { 297 Object [] a = new Object [resultOpCount]; 298 for (int i = 0; i < resultOpCount; i++) { 299 a[i] = resultOps[i].getResult(fetchResult); 300 } 301 return a; 302 } 303 } 304 305 } 306 307 | Popular Tags |