Fixed bug #684909 "Selecting ROWIDs errors out on fetch."

master
baztian 2010-12-07 23:09:26 +01:00
parent 46c502af1f
commit 32c64c47c7
1 changed files with 42 additions and 80 deletions

View File

@ -20,11 +20,21 @@
import datetime import datetime
import exceptions import exceptions
import time import time
import re
import sys import sys
_jdbc_connect = None _jdbc_connect = None
def _jdbc_connect_jython(jclassname, *args): def _jdbc_connect_jython(jclassname, *args):
if _converters is None:
from java.sql import Types
types = Types
types_map = {}
const_re = re.compile('[A-Z][A-Z_]*$')
for i in dir(types):
if const_re.match(i):
types_map[i] = getattr(types, i)
_init_converters(types_map)
# register driver for DriverManager # register driver for DriverManager
__import__(jclassname) __import__(jclassname)
from java.sql import DriverManager from java.sql import DriverManager
@ -42,6 +52,12 @@ def _jdbc_connect_jpype(jclassname, *args):
jpype.startJVM(jpype.getDefaultJVMPath()) jpype.startJVM(jpype.getDefaultJVMPath())
if not jpype.isThreadAttachedToJVM(): if not jpype.isThreadAttachedToJVM():
jpype.attachThreadToJVM() jpype.attachThreadToJVM()
if _converters is None:
types = jpype.java.sql.Types
types_map = {}
for i in types.__javaclass__.getClassFields():
types_map[i.getName()] = i.getStaticAttribute()
_init_converters(types_map)
# register driver for DriverManager # register driver for DriverManager
jpype.JClass(jclassname) jpype.JClass(jclassname)
return jpype.java.sql.DriverManager.getConnection(*args) return jpype.java.sql.DriverManager.getConnection(*args)
@ -219,9 +235,7 @@ class Cursor(object):
def _set_stmt_parms(self, prep_stmt, *parameters): def _set_stmt_parms(self, prep_stmt, *parameters):
for i in range(len(parameters)): for i in range(len(parameters)):
sqltype = TYPE_MAP[type(parameters[i])] prep_stmt.setObject(i + 1, parameters[i])
setter = getattr(prep_stmt, 'set%s' % METHOD_MAP[sqltype])
setter(i + 1, parameters[i])
def execute(self, operation, *parameters): def execute(self, operation, *parameters):
self._close_last() self._close_last()
@ -251,9 +265,8 @@ class Cursor(object):
row = [] row = []
for col in range(1, self._meta.getColumnCount() + 1): for col in range(1, self._meta.getColumnCount() + 1):
sqltype = self._meta.getColumnType(col) sqltype = self._meta.getColumnType(col)
getter = getattr(self._rs, 'get%s' % METHOD_MAP[sqltype]) v = self._rs.getObject(col)
v = getter(col) converter = _converters.get(sqltype)
converter = TO_PY_MAP.get(sqltype)
if converter: if converter:
v = converter(v) v = converter(v)
row.append(v) row.append(v)
@ -296,74 +309,6 @@ class Cursor(object):
def setoutputsize(self, size, column): def setoutputsize(self, size, column):
pass pass
class JavaSqlTypes(object):
# from java.sql.Types
ARRAY=2003
BIGINT=-5
BINARY=-2
BIT=-7
BLOB=2004
BOOLEAN=16
CHAR=1
CLOB=2005
DATALINK=70
DATE=91
DECIMAL=3
DISTINCT=2001
DOUBLE=8
FLOAT=6
INTEGER=4
JAVA_OBJECT=2000
LONGVARBINARY=-4
LONGVARCHAR=-1
NULL=0
NUMERIC=2
OTHER=1111
REAL=7
REF=2006
SMALLINT=5
STRUCT=2002
TIME=92
TIMESTAMP=93
TINYINT=-6
VARBINARY=-3
VARCHAR=12
METHOD_MAP = {
JavaSqlTypes.ARRAY: 'Array',
#AsciiStream
JavaSqlTypes.NUMERIC: 'BigDecimal',
JavaSqlTypes.DECIMAL: 'BigDecimal',
#BinaryStream
JavaSqlTypes.BLOB: 'Blob',
JavaSqlTypes.BOOLEAN: 'Boolean',
JavaSqlTypes.CHAR: 'String',
JavaSqlTypes.BINARY: 'Bytes',
#CharacterStream
JavaSqlTypes.CLOB: 'Clob',
JavaSqlTypes.DOUBLE: 'Double',
JavaSqlTypes.DATE: 'Date',
JavaSqlTypes.FLOAT: 'Float',
JavaSqlTypes.INTEGER: 'Int',
JavaSqlTypes.BIGINT: 'Long',
JavaSqlTypes.SMALLINT: 'Short',
JavaSqlTypes.VARCHAR: 'String',
JavaSqlTypes.TIME: 'Time',
JavaSqlTypes.TIMESTAMP: 'Timestamp',
JavaSqlTypes.NULL: 'Null',
}
TYPE_MAP = {
int: JavaSqlTypes.INTEGER,
long: JavaSqlTypes.BIGINT,
float: JavaSqlTypes.DOUBLE,
type(None): JavaSqlTypes.NULL,
str: JavaSqlTypes.VARCHAR,
bool: JavaSqlTypes.BOOLEAN,
# buffer: JavaSqlTypes.BINARY,
unicode: JavaSqlTypes.VARCHAR,
}
def to_datetime(java_val): def to_datetime(java_val):
# d=datetime.datetime.strptime(timestmp.toString()[:-7], "%Y-%m-%d %H:%M:%S") # d=datetime.datetime.strptime(timestmp.toString()[:-7], "%Y-%m-%d %H:%M:%S")
# return d.replace(microsecond=int(str(timestmp.getNanos())[:6])) # return d.replace(microsecond=int(str(timestmp.getNanos())[:6]))
@ -377,9 +322,26 @@ def to_date(java_val):
def to_float(java_val): def to_float(java_val):
return java_val.doubleValue() return java_val.doubleValue()
TO_PY_MAP = { def _init_converters(types_map):
JavaSqlTypes.TIMESTAMP: to_datetime, """Prepares the converters for conversion of java types to python
JavaSqlTypes.DATE: to_date, objects.
JavaSqlTypes.DECIMAL: to_float, types_map: Mapping of java.sql.Types field name to java.sql.Types
JavaSqlTypes.NUMERIC: to_float, field constant value"""
global _converters
_converters = {}
for i in _DEFAULT_CONVERTERS:
const_val = types_map[i]
_converters[const_val] = _DEFAULT_CONVERTERS[i]
# Mapping from java.sql.Types field to converter method
_converters = None
_DEFAULT_CONVERTERS = {
# see
# http://download.oracle.com/javase/1.4.2/docs/api/java/sql/Types.html
# for possible keys
'TIMESTAMP': to_datetime,
'DATE': to_date,
'DECIMAL': to_float,
'NUMERIC': to_float,
} }