1 9 package com.ziclix.python.sql; 10 11 import org.python.core.ClassDictInit; 12 import org.python.core.Options; 13 import org.python.core.Py; 14 import org.python.core.PyBuiltinFunctionSet; 15 import org.python.core.PyClass; 16 import org.python.core.PyDictionary; 17 import org.python.core.PyException; 18 import org.python.core.PyInteger; 19 import org.python.core.PyObject; 20 import org.python.core.PyString; 21 import org.python.core.PyStringMap; 22 23 import java.lang.reflect.Field ; 24 import java.sql.SQLException ; 25 import java.text.MessageFormat ; 26 import java.util.ArrayList ; 27 import java.util.List ; 28 import java.util.MissingResourceException ; 29 import java.util.Properties ; 30 import java.util.ResourceBundle ; 31 32 44 public class zxJDBC extends PyObject implements ClassDictInit { 45 46 49 public static PyObject Error = Py.None; 50 51 54 public static PyObject Warning = Py.None; 55 56 59 public static PyObject InterfaceError = Py.None; 60 61 64 public static PyObject DatabaseError = Py.None; 65 66 69 public static PyObject InternalError = Py.None; 70 71 74 public static PyObject OperationalError = Py.None; 75 76 79 public static PyObject ProgrammingError = Py.None; 80 81 84 public static PyObject IntegrityError = Py.None; 85 86 89 public static PyObject DataError = Py.None; 90 91 94 public static PyObject NotSupportedError = Py.None; 95 96 99 private static ResourceBundle resourceBundle = null; 100 101 104 public static DateFactory datefactory = new JavaDateFactory(); 105 106 static { 107 try { 108 resourceBundle = ResourceBundle.getBundle("com.ziclix.python.sql.resource.zxJDBCMessages"); 109 } catch (MissingResourceException e) { 110 throw new RuntimeException ("missing zxjdbc resource bundle"); 111 } 112 } 113 114 119 public static void classDictInit(PyObject dict) { 120 121 dict.__setitem__("apilevel", new PyString("2.0")); 122 dict.__setitem__("threadsafety", new PyInteger(1)); 123 dict.__setitem__("paramstyle", new PyString("qmark")); 124 dict.__setitem__("__version__", Py.newString("$Revision: 1.14 $").__getslice__(Py.newInteger(11), Py.newInteger(-2), null)); 125 dict.__setitem__("Date", new zxJDBCFunc("Date", 1, 3, 3, false, "construct a Date from year, month, day")); 126 dict.__setitem__("Time", new zxJDBCFunc("Time", 2, 3, 3, false, "construct a Date from hour, minute, second")); 127 dict.__setitem__("Timestamp", new zxJDBCFunc("Timestamp", 3, 6, 6, false, "construct a Timestamp from year, month, day, hour, minute, second")); 128 dict.__setitem__("DateFromTicks", new zxJDBCFunc("DateFromTicks", 4, 1, 1, false, "construct a Date from seconds since the epoch")); 129 dict.__setitem__("TimeFromTicks", new zxJDBCFunc("TimeFromTicks", 5, 1, 1, false, "construct a Time from seconds since the epoch")); 130 dict.__setitem__("TimestampFromTicks", new zxJDBCFunc("TimestampFromTicks", 6, 1, 1, false, "construct a Timestamp from seconds since the epoch")); 131 dict.__setitem__("Binary", new zxJDBCFunc("Binary", 7, 1, 1, false, "construct an object capable of holding binary data")); 132 zxJDBC._addSqlTypes(dict); 133 zxJDBC._addConnectors(dict); 134 zxJDBC._buildExceptions(dict); 135 136 dict.__setitem__("initModule", null); 138 dict.__setitem__("toString", null); 139 dict.__setitem__("getPyClass", null); 140 dict.__setitem__("classDictInit", null); 141 dict.__setitem__("_addSqlTypes", null); 142 dict.__setitem__("_addConnectors", null); 143 dict.__setitem__("_buildExceptions", null); 144 dict.__setitem__("_empty__init__", null); 145 dict.__setitem__("buildClass", null); 146 dict.__setitem__("createExceptionMessage", null); 147 dict.__setitem__("resourceBundle", null); 148 dict.__setitem__("getString", null); 149 dict.__setitem__("makeException", null); 150 } 151 152 155 public static PyClass __class__; 156 157 162 protected PyClass getPyClass() { 163 return __class__; 164 } 165 166 172 protected static void _addSqlTypes(PyObject dict) throws PyException { 173 174 PyDictionary sqltype = new PyDictionary(); 175 176 dict.__setitem__("sqltype", sqltype); 177 178 try { 179 Class c = Class.forName("java.sql.Types"); 180 Field [] fields = c.getFields(); 181 182 for (int i = 0; i < fields.length; i++) { 183 Field f = fields[i]; 184 PyString name = Py.newString(f.getName()); 185 PyObject value = new DBApiType(f.getInt(c)); 186 187 dict.__setitem__(name, value); 188 sqltype.__setitem__(value, name); 189 } 190 191 c = Class.forName("java.sql.ResultSet"); 192 fields = c.getFields(); 193 194 for (int i = 0; i < fields.length; i++) { 195 Field f = fields[i]; 196 PyString name = Py.newString(f.getName()); 197 PyObject value = Py.newInteger(f.getInt(c)); 198 199 dict.__setitem__(name, value); 200 } 201 } catch (Throwable t) { 202 throw makeException(t); 203 } 204 205 dict.__setitem__("ROWID", dict.__getitem__(Py.newString("OTHER"))); 206 dict.__setitem__("NUMBER", dict.__getitem__(Py.newString("NUMERIC"))); 207 dict.__setitem__("STRING", dict.__getitem__(Py.newString("VARCHAR"))); 208 dict.__setitem__("DATETIME", dict.__getitem__(Py.newString("TIMESTAMP"))); 209 210 return; 211 } 212 213 219 protected static void _addConnectors(PyObject dict) throws PyException { 220 221 PyObject connector = Py.None; 222 Properties props = new Properties (); 223 224 props.put("connect", "com.ziclix.python.sql.connect.Connect"); 225 props.put("lookup", "com.ziclix.python.sql.connect.Lookup"); 226 props.put("connectx", "com.ziclix.python.sql.connect.Connectx"); 227 228 java.util.Enumeration names = props.propertyNames(); 229 230 while (names.hasMoreElements()) { 231 String name = ((String ) names.nextElement()).trim(); 232 String className = props.getProperty(name).trim(); 233 234 try { 235 connector = (PyObject) Class.forName(className).newInstance(); 236 dict.__setitem__(name, connector); 237 Py.writeComment("zxJDBC", "loaded connector [" + className + "] as [" + name + "]"); 238 } catch (Throwable t) { 239 Py.writeComment("zxJDBC", "failed to load connector [" + name + "] using class [" + className + "]"); 240 } 241 } 242 243 return; 244 } 245 246 251 protected static void _buildExceptions(PyObject dict) { 252 253 Error = buildClass("Error", Py.StandardError, "_empty__init__"); 254 Warning = buildClass("Warning", Py.StandardError, "_empty__init__"); 255 InterfaceError = buildClass("InterfaceError", Error, "_empty__init__"); 256 DatabaseError = buildClass("DatabaseError", Error, "_empty__init__"); 257 InternalError = buildClass("InternalError", DatabaseError, "_empty__init__"); 258 OperationalError = buildClass("OperationalError", DatabaseError, "_empty__init__"); 259 ProgrammingError = buildClass("ProgrammingError", DatabaseError, "_empty__init__"); 260 IntegrityError = buildClass("IntegrityError", DatabaseError, "_empty__init__"); 261 DataError = buildClass("DataError", DatabaseError, "_empty__init__"); 262 NotSupportedError = buildClass("NotSupportedError", DatabaseError, "_empty__init__"); 263 } 264 265 public static PyObject _empty__init__(PyObject[] arg, String [] kws) { 266 PyObject dict = new PyStringMap(); 267 dict.__setitem__("__module__", new PyString("zxJDBC")); 268 return dict; 269 } 270 271 281 public static String getString(String key) { 282 int i = 0; 283 List lines = null; 284 String resource = null; 285 while (true) { 286 try { 287 resource = resourceBundle.getString(key + "." + (i++)); 288 if (lines == null) { 289 lines = new ArrayList (); 290 } 291 lines.add(resource); 292 } catch (MissingResourceException e) { 293 break; 294 } 295 } 296 if ((lines == null) || (lines.size() == 0)) { 297 try { 298 resource = resourceBundle.getString(key); 299 } catch (MissingResourceException e) { 300 return key; 301 } 302 } else { 303 String sep = System.getProperty("line.separator"); 304 StringBuffer sb = new StringBuffer (); 305 for (i = 0; i < lines.size() - 1; i++) { 306 sb.append(lines.get(i)).append(sep); 307 } 308 sb.append(lines.get(lines.size() - 1)); 309 resource = sb.toString(); 310 } 311 return resource; 312 } 313 314 322 public static String getString(String key, Object [] values) { 323 String format = getString(key); 324 return MessageFormat.format(format, values); 325 } 326 327 333 public static PyException makeException(String msg) { 334 return makeException(Error, msg); 335 } 336 337 344 public static PyException makeException(PyObject type, String msg) { 345 return Py.makeException(type, Py.newString((msg == null) ? "" : msg)); 346 } 347 348 354 public static PyException makeException(Throwable throwable) { 355 return makeException(Error, throwable); 356 } 357 358 365 public static PyException makeException(PyObject type, Throwable t) { 366 367 if (Options.showJavaExceptions) { 368 java.io.CharArrayWriter buf = new java.io.CharArrayWriter (); 369 java.io.PrintWriter writer = new java.io.PrintWriter (buf); 370 writer.println("Java Traceback:"); 371 if (t instanceof PyException) { 372 ((PyException) t).super__printStackTrace(writer); 373 } else { 374 t.printStackTrace(writer); 375 } 376 Py.stderr.print(buf.toString()); 377 } 378 379 if (t instanceof PyException) { 380 return (PyException) t; 381 } else if (t instanceof SQLException ) { 382 SQLException sqlException = (SQLException ) t; 383 StringBuffer buffer = new StringBuffer (); 384 do { 385 buffer.append(sqlException.getMessage()); 386 buffer.append(" [SQLCode: " + sqlException.getErrorCode() + "]"); 387 if (sqlException.getSQLState() != null) { 388 buffer.append(", [SQLState: " + sqlException.getSQLState() + "]"); 389 } 390 sqlException = sqlException.getNextException(); 391 if (sqlException != null) { 392 buffer.append(System.getProperty("line.separator")); 393 } 394 } while (sqlException != null); 395 396 return makeException(type, buffer.toString()); 397 } else { 398 return makeException(type, t.getMessage()); 399 } 400 } 401 402 410 protected static PyObject buildClass(String classname, PyObject superclass, String classCodeName) { 411 PyObject[] parents = (superclass == null) ? Py.EmptyObjects : new PyObject[]{superclass}; 412 PyString doc = Py.newString(getString(classname)); 413 PyObject cls = Py.makeClass(classname, parents, Py.newJavaCode(zxJDBC.class, classCodeName), doc); 414 return cls; 415 } 416 } 417 418 class zxJDBCFunc extends PyBuiltinFunctionSet { 419 420 zxJDBCFunc(String name, int index, int minargs, int maxargs, boolean func, String doc) { 421 super(name, index, minargs, maxargs, func, doc); 422 } 423 424 public PyObject __call__(PyObject arg) { 425 long ticks; 426 switch (index) { 427 case 4: 428 ticks = ((Number ) arg.__tojava__(Number .class)).longValue(); 429 return zxJDBC.datefactory.DateFromTicks(ticks); 430 case 5: 431 ticks = ((Number ) arg.__tojava__(Number .class)).longValue(); 432 return zxJDBC.datefactory.TimeFromTicks(ticks); 433 case 6: 434 ticks = ((Number ) arg.__tojava__(Number .class)).longValue(); 435 return zxJDBC.datefactory.TimestampFromTicks(ticks); 436 case 7: 437 return arg; 438 default : 439 throw argCountError(1); 440 } 441 } 442 443 public PyObject __call__(PyObject arga, PyObject argb, PyObject argc) { 444 switch (index) { 445 case 1: 446 int year = ((Number ) arga.__tojava__(Number .class)).intValue(); 447 int month = ((Number ) argb.__tojava__(Number .class)).intValue(); 448 int day = ((Number ) argc.__tojava__(Number .class)).intValue(); 449 return zxJDBC.datefactory.Date(year, month, day); 450 case 2: 451 int hour = ((Number ) arga.__tojava__(Number .class)).intValue(); 452 int minute = ((Number ) argb.__tojava__(Number .class)).intValue(); 453 int second = ((Number ) argc.__tojava__(Number .class)).intValue(); 454 return zxJDBC.datefactory.Time(hour, minute, second); 455 default : 456 throw argCountError(3); 457 } 458 } 459 460 public PyObject fancyCall(PyObject[] args) { 461 switch (index) { 462 case 3: 463 int year = ((Number ) args[0].__tojava__(Number .class)).intValue(); 464 int month = ((Number ) args[1].__tojava__(Number .class)).intValue(); 465 int day = ((Number ) args[2].__tojava__(Number .class)).intValue(); 466 int hour = ((Number ) args[3].__tojava__(Number .class)).intValue(); 467 int minute = ((Number ) args[4].__tojava__(Number .class)).intValue(); 468 int second = ((Number ) args[5].__tojava__(Number .class)).intValue(); 469 return zxJDBC.datefactory.Timestamp(year, month, day, hour, minute, second); 470 default : 471 throw argCountError(args.length); 472 } 473 } 474 } 475 476 | Popular Tags |