1 9 package com.ziclix.python.sql; 10 11 import com.ziclix.python.sql.util.PyArgParser; 12 import org.python.core.ClassDictInit; 13 import org.python.core.Py; 14 import org.python.core.PyBuiltinFunctionSet; 15 import org.python.core.PyClass; 16 import org.python.core.PyInteger; 17 import org.python.core.PyList; 18 import org.python.core.PyObject; 19 import org.python.core.PyString; 20 21 import java.sql.Connection ; 22 import java.sql.SQLException ; 23 import java.util.Collections ; 24 import java.util.HashSet ; 25 import java.util.Iterator ; 26 import java.util.Set ; 27 28 35 public class PyConnection extends PyObject implements ClassDictInit { 36 37 40 protected boolean closed; 41 42 45 protected Connection connection; 46 47 50 protected boolean supportsTransactions; 51 52 55 private Set cursors; 56 57 60 private Set statements; 61 62 65 public static PyClass __class__; 66 67 72 protected PyClass getPyClass() { 73 return __class__; 74 } 75 76 79 protected static PyList __members__; 80 81 84 protected static PyList __methods__; 85 86 static { 87 PyObject[] m = new PyObject[5]; 88 89 m[0] = new PyString("close"); 90 m[1] = new PyString("commit"); 91 m[2] = new PyString("cursor"); 92 m[3] = new PyString("rollback"); 93 m[4] = new PyString("nativesql"); 94 __methods__ = new PyList(m); 95 m = new PyObject[10]; 96 m[0] = new PyString("autocommit"); 97 m[1] = new PyString("dbname"); 98 m[2] = new PyString("dbversion"); 99 m[3] = new PyString("drivername"); 100 m[4] = new PyString("driverversion"); 101 m[5] = new PyString("url"); 102 m[6] = new PyString("__connection__"); 103 m[7] = new PyString("__cursors__"); 104 m[8] = new PyString("__statements__"); 105 m[9] = new PyString("closed"); 106 __members__ = new PyList(m); 107 } 108 109 115 public PyConnection(Connection connection) throws SQLException { 116 117 this.closed = false; 118 this.cursors = new HashSet (); 119 this.connection = connection; 120 this.statements = new HashSet (); 121 this.supportsTransactions = this.connection.getMetaData().supportsTransactions(); 122 123 if (this.supportsTransactions) { 124 this.connection.setAutoCommit(false); 125 } 126 } 127 128 133 public String toString() { 134 135 try { 136 return "<PyConnection user='" + this.connection.getMetaData().getUserName() + "', url='" + this.connection.getMetaData().getURL() + "'>"; 137 } catch (SQLException e) { 138 return "<PyConnection at " + hashCode() + ">"; 139 } 140 } 141 142 147 static public void classDictInit(PyObject dict) { 148 149 dict.__setitem__("autocommit", new PyInteger(0)); 150 dict.__setitem__("__version__", Py.newString("$Revision: 1.14 $").__getslice__(Py.newInteger(11), Py.newInteger(-2), null)); 151 dict.__setitem__("close", new ConnectionFunc("close", 0, 0, 0, zxJDBC.getString("close"))); 152 dict.__setitem__("commit", new ConnectionFunc("commit", 1, 0, 0, zxJDBC.getString("commit"))); 153 dict.__setitem__("cursor", new ConnectionFunc("cursor", 2, 0, 4, zxJDBC.getString("cursor"))); 154 dict.__setitem__("rollback", new ConnectionFunc("rollback", 3, 0, 0, zxJDBC.getString("rollback"))); 155 dict.__setitem__("nativesql", new ConnectionFunc("nativesql", 4, 1, 1, zxJDBC.getString("nativesql"))); 156 157 dict.__setitem__("initModule", null); 159 dict.__setitem__("toString", null); 160 dict.__setitem__("setConnection", null); 161 dict.__setitem__("getPyClass", null); 162 dict.__setitem__("connection", null); 163 dict.__setitem__("classDictInit", null); 164 dict.__setitem__("cursors", null); 165 } 166 167 173 public void __setattr__(String name, PyObject value) { 174 175 if ("autocommit".equals(name)) { 176 try { 177 if (this.supportsTransactions) { 178 this.connection.setAutoCommit(value.__nonzero__()); 179 } 180 } catch (SQLException e) { 181 throw zxJDBC.makeException(zxJDBC.DatabaseError, e); 182 } 183 184 return; 185 } 186 187 super.__setattr__(name, value); 188 } 189 190 196 public PyObject __findattr__(String name) { 197 198 if ("autocommit".equals(name)) { 199 try { 200 return connection.getAutoCommit() ? Py.One : Py.Zero; 201 } catch (SQLException e) { 202 throw zxJDBC.makeException(zxJDBC.DatabaseError, e); 203 } 204 } else if ("dbname".equals(name)) { 205 try { 206 return Py.newString(this.connection.getMetaData().getDatabaseProductName()); 207 } catch (SQLException e) { 208 throw zxJDBC.makeException(zxJDBC.DatabaseError, e); 209 } 210 } else if ("dbversion".equals(name)) { 211 try { 212 return Py.newString(this.connection.getMetaData().getDatabaseProductVersion()); 213 } catch (SQLException e) { 214 throw zxJDBC.makeException(zxJDBC.DatabaseError, e); 215 } 216 } else if ("drivername".equals(name)) { 217 try { 218 return Py.newString(this.connection.getMetaData().getDriverName()); 219 } catch (SQLException e) { 220 throw zxJDBC.makeException(zxJDBC.DatabaseError, e); 221 } 222 } else if ("driverversion".equals(name)) { 223 try { 224 return Py.newString(this.connection.getMetaData().getDriverVersion()); 225 } catch (SQLException e) { 226 throw zxJDBC.makeException(zxJDBC.DatabaseError, e); 227 } 228 } else if ("url".equals(name)) { 229 try { 230 return Py.newString(this.connection.getMetaData().getURL()); 231 } catch (SQLException e) { 232 throw zxJDBC.makeException(zxJDBC.DatabaseError, e); 233 } 234 } else if ("__connection__".equals(name)) { 235 return Py.java2py(this.connection); 236 } else if ("__cursors__".equals(name)) { 237 return Py.java2py(Collections.unmodifiableSet(this.cursors)); 238 } else if ("__statements__".equals(name)) { 239 return Py.java2py(Collections.unmodifiableSet(this.statements)); 240 } else if ("__methods__".equals(name)) { 241 return __methods__; 242 } else if ("__members__".equals(name)) { 243 return __members__; 244 } else if ("closed".equals(name)) { 245 return Py.newBoolean(closed); 246 } 247 248 return super.__findattr__(name); 249 } 250 251 258 public void close() { 259 260 if (closed) { 261 throw zxJDBC.makeException(zxJDBC.ProgrammingError, "connection is closed"); 262 } 263 264 this.closed = true; 268 269 synchronized (this.cursors) { 270 271 for (Iterator i = this.cursors.iterator(); i.hasNext();) { 273 ((PyCursor) i.next()).close(); 274 } 275 276 this.cursors.clear(); 277 } 278 279 synchronized (this.statements) { 280 281 for (Iterator i = this.statements.iterator(); i.hasNext();) { 283 ((PyStatement) i.next()).close(); 284 } 285 286 this.statements.clear(); 287 } 288 289 try { 290 this.connection.close(); 291 } catch (SQLException e) { 292 throw zxJDBC.makeException(e); 293 } 294 } 295 296 304 public void commit() { 305 306 if (closed) { 307 throw zxJDBC.makeException(zxJDBC.ProgrammingError, "connection is closed"); 308 } 309 310 if (!this.supportsTransactions) { 311 return; 312 } 313 314 try { 315 this.connection.commit(); 316 } catch (SQLException e) { 317 throw zxJDBC.makeException(e); 318 } 319 } 320 321 330 public void rollback() { 331 332 if (closed) { 333 throw zxJDBC.makeException(zxJDBC.ProgrammingError, "connection is closed"); 334 } 335 336 if (!this.supportsTransactions) { 337 return; 338 } 339 340 try { 341 this.connection.rollback(); 342 } catch (SQLException e) { 343 throw zxJDBC.makeException(e); 344 } 345 } 346 347 356 public PyObject nativesql(PyObject nativeSQL) { 357 358 if (closed) { 359 throw zxJDBC.makeException(zxJDBC.ProgrammingError, "connection is closed"); 360 } 361 362 if (nativeSQL == Py.None) { 363 return Py.None; 364 } 365 366 try { 367 return Py.newString(this.connection.nativeSQL(nativeSQL.__str__().toString())); 368 } catch (SQLException e) { 369 throw zxJDBC.makeException(e); 370 } 371 } 372 373 380 public PyCursor cursor() { 381 return cursor(false); 382 } 383 384 392 public PyCursor cursor(boolean dynamicFetch) { 393 return this.cursor(dynamicFetch, Py.None, Py.None); 394 } 395 396 406 public PyCursor cursor(boolean dynamicFetch, PyObject rsType, PyObject rsConcur) { 407 408 if (closed) { 409 throw zxJDBC.makeException(zxJDBC.ProgrammingError, "connection is closed"); 410 } 411 412 PyCursor cursor = new PyExtendedCursor(this, dynamicFetch, rsType, rsConcur); 413 414 this.cursors.add(cursor); 415 416 return cursor; 417 } 418 419 424 void remove(PyCursor cursor) { 425 426 if (closed) { 427 return; 428 } 429 430 this.cursors.remove(cursor); 431 } 432 433 438 void add(PyStatement statement) { 439 440 if (closed) { 441 return; 442 } 443 444 this.statements.add(statement); 445 } 446 447 453 boolean contains(PyStatement statement) { 454 455 if (closed) { 456 return false; 457 } 458 459 return this.statements.contains(statement); 460 } 461 } 462 463 class ConnectionFunc extends PyBuiltinFunctionSet { 464 ConnectionFunc(String name, int index, int minargs, int maxargs, String doc) { 465 super(name, index, minargs, maxargs, true, doc); 466 } 467 468 public PyObject __call__() { 469 PyConnection c = (PyConnection) __self__; 470 switch (index) { 471 case 0: 472 c.close(); 473 return Py.None; 474 case 1: 475 c.commit(); 476 return Py.None; 477 case 2: 478 return c.cursor(); 479 case 3: 480 c.rollback(); 481 return Py.None; 482 default : 483 throw argCountError(0); 484 } 485 } 486 487 public PyObject __call__(PyObject arg) { 488 PyConnection c = (PyConnection) __self__; 489 switch (index) { 490 case 2: 491 return c.cursor(arg.__nonzero__()); 492 case 4: 493 return c.nativesql(arg); 494 default : 495 throw argCountError(1); 496 } 497 } 498 499 public PyObject __call__(PyObject arg1, PyObject arg2, PyObject arg3) { 500 PyConnection c = (PyConnection) __self__; 501 switch (index) { 502 case 2: 503 return c.cursor(arg1.__nonzero__(), arg2, arg3); 504 default : 505 throw argCountError(3); 506 } 507 } 508 509 public PyObject __call__(PyObject[] args, String [] keywords) { 510 PyConnection c = (PyConnection) __self__; 511 PyArgParser parser = new PyArgParser(args, keywords); 512 switch (index) { 513 case 2: 514 PyObject dynamic = parser.kw("dynamic", Py.None); 515 PyObject rstype = parser.kw("rstype", Py.None); 516 PyObject rsconcur = parser.kw("rsconcur", Py.None); 517 518 dynamic = (parser.numArg() >= 1) ? parser.arg(0) : dynamic; 519 rstype = (parser.numArg() >= 2) ? parser.arg(1) : rstype; 520 rsconcur = (parser.numArg() >= 3) ? parser.arg(2) : rsconcur; 521 522 return c.cursor(dynamic.__nonzero__(), rstype, rsconcur); 523 524 default : 525 throw argCountError(args.length); 526 } 527 } 528 } 529 | Popular Tags |