1 9 package com.ziclix.python.sql; 10 11 import org.python.core.Py; 12 import org.python.core.PyInteger; 13 import org.python.core.PyList; 14 import org.python.core.PyObject; 15 import org.python.core.PyString; 16 17 import java.sql.CallableStatement ; 18 import java.sql.DatabaseMetaData ; 19 import java.sql.SQLException ; 20 import java.util.BitSet ; 21 22 31 public class Procedure extends Object { 32 33 36 protected static final int NAME = 3; 37 38 41 protected static final int COLUMN_TYPE = 4; 42 43 46 protected static final int DATA_TYPE = 5; 47 48 51 protected static final int DATA_TYPE_NAME = 6; 52 53 56 protected static final int PRECISION = 7; 57 58 61 protected static final int LENGTH = 8; 62 63 66 protected static final int SCALE = 9; 67 68 71 protected static final int NULLABLE = 11; 72 73 76 protected PyCursor cursor; 77 78 81 protected PyObject columns; 82 83 86 protected PyObject procedureCatalog; 87 88 91 protected PyObject procedureSchema; 92 93 96 protected PyObject procedureName; 97 98 101 protected BitSet inputSet; 102 103 110 public Procedure(PyCursor cursor, PyObject name) throws SQLException { 111 112 this.cursor = cursor; 113 this.inputSet = new BitSet (); 114 115 if (name instanceof PyString) { 116 this.procedureCatalog = getDefault(); 117 this.procedureSchema = getDefault(); 118 this.procedureName = name; 119 } else if (PyCursor.isSeq(name)) { 120 if (name.__len__() == 3) { 121 this.procedureCatalog = name.__getitem__(0); 122 this.procedureSchema = name.__getitem__(1); 123 this.procedureName = name.__getitem__(2); 124 } else { 125 126 } 128 } else { 129 130 } 132 133 fetchColumns(); 134 } 135 136 142 public CallableStatement prepareCall() throws SQLException { 143 return prepareCall(Py.None, Py.None); 144 } 145 146 154 public CallableStatement prepareCall(PyObject rsType, PyObject rsConcur) throws SQLException { 155 156 CallableStatement statement = null; 158 boolean normal = ((rsType == Py.None) && (rsConcur == Py.None)); 159 160 try { 161 162 String sqlString = toSql(); 164 165 if (normal) { 166 statement = cursor.connection.connection.prepareCall(sqlString); 167 } else { 168 int t = ((PyInteger)rsType.__int__()).getValue(); 169 int c = ((PyInteger)rsConcur.__int__()).getValue(); 170 171 statement = cursor.connection.connection.prepareCall(sqlString, t, c); 172 } 173 174 registerOutParameters(statement); 176 } catch (SQLException e) { 177 if (statement != null) { 178 try { 179 statement.close(); 180 } catch (Exception ex) { 181 } 182 } 183 184 throw e; 185 } 186 187 return statement; 188 } 189 190 196 public void normalizeInput(PyObject params, PyObject bindings) throws SQLException { 197 198 if (this.columns == Py.None) { 199 return; 200 } 201 202 for (int i = 0, len = this.columns.__len__(), binding = 0; i < len; i++) { 204 PyObject column = this.columns.__getitem__(i); 205 int colType = ((PyInteger)column.__getitem__(COLUMN_TYPE).__int__()).getValue(); 206 207 switch (colType) { 208 209 case DatabaseMetaData.procedureColumnIn: 210 case DatabaseMetaData.procedureColumnInOut: 211 212 PyInteger key = Py.newInteger(binding++); 214 215 if (bindings.__finditem__(key) == null) { 216 int dataType = ((PyInteger)column.__getitem__(DATA_TYPE).__int__()).getValue(); 217 bindings.__setitem__(key, Py.newInteger(dataType)); 218 } 219 220 this.inputSet.set(i + 1); 222 break; 223 } 224 } 225 } 226 227 236 public boolean isInput(int index) throws SQLException { 237 return this.inputSet.get(index); 238 } 239 240 251 public String toSql() throws SQLException { 252 253 int colParam = 0; 254 int colReturn = 0; 255 256 if (this.columns != Py.None) { 257 for (int i = 0, len = this.columns.__len__(); i < len; i++) { 258 PyObject column = this.columns.__getitem__(i); 259 int colType = ((PyInteger)column.__getitem__(COLUMN_TYPE).__int__()).getValue(); 260 261 switch (colType) { 262 263 case DatabaseMetaData.procedureColumnUnknown: 264 throw zxJDBC.makeException(zxJDBC.NotSupportedError, "procedureColumnUnknown"); 265 case DatabaseMetaData.procedureColumnResult: 266 throw zxJDBC.makeException(zxJDBC.NotSupportedError, "procedureColumnResult"); 267 268 case DatabaseMetaData.procedureColumnIn: 270 case DatabaseMetaData.procedureColumnInOut: 271 case DatabaseMetaData.procedureColumnOut: 272 colParam++; 273 break; 274 275 case DatabaseMetaData.procedureColumnReturn: 277 colReturn++; 278 break; 279 280 default : 281 throw zxJDBC.makeException(zxJDBC.DataError, "unknown column type [" + colType + "]"); 282 } 283 } 284 } 285 286 StringBuffer sql = new StringBuffer ("{"); 287 288 if (colReturn > 0) { 289 PyList list = new PyList(); 290 291 for (; colReturn > 0; colReturn--) { 292 list.append(Py.newString("?")); 293 } 294 295 sql.append(Py.newString(",").join(list)).append(" = "); 296 } 297 298 String name = this.getProcedureName(); 299 300 sql.append("call ").append(name).append("("); 301 302 if (colParam > 0) { 303 PyList list = new PyList(); 304 305 for (; colParam > 0; colParam--) { 306 list.append(Py.newString("?")); 307 } 308 309 sql.append(Py.newString(",").join(list)); 310 } 311 312 return sql.append(")}").toString(); 313 } 314 315 321 protected void registerOutParameters(CallableStatement statement) throws SQLException { 322 323 if (this.columns == Py.None) { 324 return; 325 } 326 327 for (int i = 0, len = this.columns.__len__(); i < len; i++) { 328 PyObject column = this.columns.__getitem__(i); 329 int colType = ((PyInteger)column.__getitem__(COLUMN_TYPE).__int__()).getValue(); 330 int dataType = ((PyInteger)column.__getitem__(DATA_TYPE).__int__()).getValue(); 331 String dataTypeName = column.__getitem__(DATA_TYPE_NAME).toString(); 332 333 switch (colType) { 334 335 case DatabaseMetaData.procedureColumnInOut: 336 case DatabaseMetaData.procedureColumnOut: 337 case DatabaseMetaData.procedureColumnReturn: 338 cursor.datahandler.registerOut(statement, i + 1, colType, dataType, dataTypeName); 339 break; 340 } 341 } 342 } 343 344 349 protected void fetchColumns() throws SQLException { 350 351 PyExtendedCursor pec = (PyExtendedCursor) cursor.connection.cursor(); 352 353 try { 354 pec.datahandler = this.cursor.datahandler; 355 356 pec.procedurecolumns(procedureCatalog, procedureSchema, procedureName, Py.None); 357 358 this.columns = pec.fetchall(); 359 } finally { 360 pec.close(); 361 } 362 } 363 364 373 protected PyObject getDefault() { 374 return Py.EmptyString; 375 } 376 377 380 protected String getProcedureName() { 381 382 StringBuffer proc = new StringBuffer (); 383 384 if (this.procedureCatalog.__nonzero__()) { 385 proc.append(this.procedureCatalog.toString()).append("."); 386 } 387 388 return proc.append(this.procedureName.toString()).toString(); 389 } 390 } 391 | Popular Tags |