[pypy-svn] r69710 - in pypy/trunk/pypy/module/oracle: . test
afa at codespeak.net
afa at codespeak.net
Fri Nov 27 19:30:29 CET 2009
Author: afa
Date: Fri Nov 27 19:30:28 2009
New Revision: 69710
Modified:
pypy/trunk/pypy/module/oracle/config.py
pypy/trunk/pypy/module/oracle/interp_connect.py
pypy/trunk/pypy/module/oracle/interp_environ.py
pypy/trunk/pypy/module/oracle/interp_object.py
pypy/trunk/pypy/module/oracle/interp_pool.py
pypy/trunk/pypy/module/oracle/interp_variable.py
pypy/trunk/pypy/module/oracle/roci.py
pypy/trunk/pypy/module/oracle/test/test_connect.py
Log:
Now the cx_Oracle module translates, compiles, and works!
Tested on Windows.
Support for ucs4 builds of pypy is likely incomplete.
Likewise, the "full unicode" mode of cx_Oracle is not implemented.
And the cx_Oracle test suite itself is not complete...
The module works well enough for most usages, though.
Modified: pypy/trunk/pypy/module/oracle/config.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/config.py (original)
+++ pypy/trunk/pypy/module/oracle/config.py Fri Nov 27 19:30:28 2009
@@ -26,24 +26,28 @@
class StringBuffer:
"Fill a char* buffer with data, suitable to pass to Oracle functions"
def __init__(self):
- pass
+ self.ptr = lltype.nullptr(roci.oratext.TO)
+ self.size = 0
- def fill(self, space, w_string):
- if w_string is None or space.is_w(w_string, space.w_None):
+ def fill(self, space, w_value):
+ if w_value is None or space.is_w(w_value, space.w_None):
self.clear()
else:
- self.ptr = string_w(space, w_string)
- self.size = len(self.ptr)
+ strvalue = space.str_w(w_value)
+ self.ptr = rffi.str2charp(strvalue)
+ self.size = len(strvalue)
- def fill_with_unicode(self, space, w_unicode):
- if w_unicode is None or space.is_w(w_unicode, space.w_None):
+ def fill_with_unicode(self, space, w_value):
+ if w_value is None or space.is_w(w_value, space.w_None):
self.clear()
else:
# XXX ucs2 only probably
- unistr = space.unicode_w(w_unicode)
- self.ptr = rffi.cast(roci.oratext, rffi.unicode2wcharp(unistr))
- self.size = len(unistr) * 2
+ univalue = space.unicode_w(w_value)
+ self.ptr = rffi.cast(roci.oratext, rffi.unicode2wcharp(univalue))
+ self.size = len(univalue) * 2
def clear(self):
- self.ptr = None
+ if self.ptr:
+ rffi.free_charp(self.ptr)
+ self.ptr = lltype.nullptr(roci.oratext.TO)
self.size = 0
Modified: pypy/trunk/pypy/module/oracle/interp_connect.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/interp_connect.py (original)
+++ pypy/trunk/pypy/module/oracle/interp_connect.py Fri Nov 27 19:30:28 2009
@@ -21,8 +21,8 @@
self.environment = None
self.autocommit = False
- self.sessionHandle = None
- self.serverHandle = None
+ self.sessionHandle = lltype.nullptr(roci.OCISession.TO)
+ self.serverHandle = lltype.nullptr(roci.OCIServer.TO)
self.w_inputTypeHandler = None
self.w_outputTypeHandler = None
@@ -41,7 +41,7 @@
twophase=False,
events=False,
w_cclass=Null,
- purity=False,
+ purity=0,
w_newpassword=Null):
self = space.allocate_instance(W_Connection, w_subtype)
W_Connection.__init__(self)
@@ -83,7 +83,7 @@
W_Root,
bool, bool, bool,
W_Root,
- bool,
+ int,
W_Root]
def __del__(self):
@@ -244,7 +244,7 @@
rather than using the low level interface for connecting."""
proxyCredentials = False
- authInfo = None
+ authInfo = lltype.nullptr(roci.OCIAuthInfo.TO)
if pool:
w_dbname = pool.w_name
@@ -261,7 +261,7 @@
# set up authorization handle, if needed
if not pool or w_cclass or proxyCredentials:
# create authorization handle
- handleptr = lltype.malloc(rffi.CArrayPtr(roci.OCIServer).TO,
+ handleptr = lltype.malloc(rffi.CArrayPtr(roci.OCIAuthInfo).TO,
1, flavor='raw')
try:
status = roci.OCIHandleAlloc(
@@ -287,7 +287,7 @@
authInfo,
roci.OCI_HTYPE_AUTHINFO,
stringBuffer.ptr, stringBuffer.size,
- roci.OCI_ATTR_PASSWORD,
+ roci.OCI_ATTR_USERNAME,
self.environment.errorHandle)
self.environment.checkForError(
status, "Connection_GetConnection(): set user name")
@@ -303,7 +303,7 @@
authInfo,
roci.OCI_HTYPE_AUTHINFO,
stringBuffer.ptr, stringBuffer.size,
- roci.OCI_ATTR_USERNAME,
+ roci.OCI_ATTR_PASSWORD,
self.environment.errorHandle)
self.environment.checkForError(
status, "Connection_GetConnection(): set password")
@@ -334,12 +334,13 @@
if purity != roci.OCI_ATTR_PURITY_DEFAULT:
purityptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO,
1, flavor='raw')
- purityptr[0] = purity
+ purityptr[0] = rffi.cast(roci.ub4, purity)
try:
status = roci.OCIAttrSet(
authInfo,
roci.OCI_HTYPE_AUTHINFO,
- purityptr, rffi.sizeof(roci.ub4),
+ rffi.cast(roci.dvoidp, purityptr),
+ rffi.sizeof(roci.ub4),
roci.OCI_ATTR_PURITY,
self.environment.errorHandle)
self.environment.checkForError(
Modified: pypy/trunk/pypy/module/oracle/interp_environ.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/interp_environ.py (original)
+++ pypy/trunk/pypy/module/oracle/interp_environ.py Fri Nov 27 19:30:28 2009
@@ -47,8 +47,8 @@
raise OperationError(get(self.space).w_DatabaseError,
self.space.wrap(error))
- @classmethod
- def create(cls, space, threaded, events):
+ @staticmethod
+ def create(space, threaded, events):
"Create a new environment object from scratch"
mode = roci.OCI_OBJECT
if threaded:
@@ -80,7 +80,7 @@
lltype.free(handleptr, flavor='raw')
try:
- newenv = cls(space, handle)
+ newenv = Environment(space, handle)
except:
roci.OCIHandleFree(handle, roci.OCI_HTYPE_ENV)
raise
@@ -92,7 +92,7 @@
def clone(self):
"""Clone an existing environment.
used when acquiring a connection from a session pool, for example."""
- newenv = type(self)(self.space, self.handle)
+ newenv = Environment(self.space, self.handle)
newenv.maxBytesPerCharacter = self.maxBytesPerCharacter
newenv.maxStringBytes = self.maxStringBytes
return newenv
Modified: pypy/trunk/pypy/module/oracle/interp_object.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/interp_object.py (original)
+++ pypy/trunk/pypy/module/oracle/interp_object.py Fri Nov 27 19:30:28 2009
@@ -7,10 +7,11 @@
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.module.oracle import roci, config, transform
+from pypy.module.oracle.interp_error import get
class W_ObjectType(Wrappable):
def __init__(self, connection, param):
- self.tdo = None
+ self.tdo = lltype.nullptr(roci.dvoidp.TO)
self.environment = connection.environment
self.isCollection = False
self.initialize(connection, param)
@@ -153,7 +154,7 @@
self.environment.errorHandle)
self.environment.checkForError(
status, "ObjectType_Describe(): get type code")
- typeCode = typecodeptr[0]
+ typeCode = rffi.cast(lltype.Signed, typecodeptr[0])
finally:
lltype.free(typecodeptr, flavor='raw')
@@ -206,7 +207,7 @@
self.environment.errorHandle)
self.environment.checkForError(
status, "ObjectType_Describe(): get element type code")
- self.elementTypeCode = typecodeptr[0]
+ self.elementTypeCode = rffi.cast(lltype.Signed, typecodeptr[0])
finally:
lltype.free(typecodeptr, flavor='raw')
@@ -318,7 +319,7 @@
connection.environment.errorHandle)
connection.environment.checkForError(
status, "ObjectType_Describe(): get type code")
- self.typeCode = typecodeptr[0]
+ self.typeCode = rffi.cast(lltype.Signed, typecodeptr[0])
finally:
lltype.free(typecodeptr, flavor='raw')
@@ -386,7 +387,8 @@
# determine the proper null indicator
valueIndicator = valueindicatorptr[0]
if not valueIndicator:
- valueIndicator = scalarvalueindicatorptr
+ valueIndicator = rffi.cast(roci.dvoidp,
+ scalarvalueindicatorptr)
value = valueptr[0]
return convertObject(
@@ -413,8 +415,13 @@
def convertObject(space, environment, typeCode,
value, indicator, var, subtype):
+
# null values returned as None
- if rffi.cast(roci.Ptr(roci.OCIInd), indicator)[0] == roci.OCI_IND_NULL:
+ if (rffi.cast(lltype.Signed,
+ rffi.cast(roci.Ptr(roci.OCIInd),
+ indicator)[0])
+ ==
+ rffi.cast(lltype.Signed, roci.OCI_IND_NULL)):
return space.w_None
if typeCode in (roci.OCI_TYPECODE_CHAR,
@@ -435,10 +442,10 @@
dateValue = rffi.cast(roci.Ptr(roci.OCIDateTime), value)
return transform.OracleTimestampToPythonDate(environment, dateValue)
elif typeCode == roci.OCI_TYPECODE_OBJECT:
- return space.wrap(W_ExternalObject(var, subType, value, indicator,
+ return space.wrap(W_ExternalObject(var, subtype, value, indicator,
isIndependent=False))
elif typeCode == roci.OCI_TYPECODE_NAMEDCOLLECTION:
- return convertCollection(space, environment, value, var, subType)
+ return convertCollection(space, environment, value, var, subtype)
raise OperationError(
get(space).w_NotSupportedError,
Modified: pypy/trunk/pypy/module/oracle/interp_pool.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/interp_pool.py (original)
+++ pypy/trunk/pypy/module/oracle/interp_pool.py Fri Nov 27 19:30:28 2009
@@ -29,18 +29,20 @@
W_SessionPool.__init__(self)
if w_connectiontype is not None:
- if not space.is_true(space.issubtype(w_value,
- interp_connect.W_Connection)):
+ if not space.is_true(space.issubtype(w_connectiontype,
+ get(space).w_Connection)):
raise OperationError(
interp_error.get(space).w_ProgrammingError,
space.wrap(
"connectiontype must be a subclass of Connection"))
+ self.w_connectionType = w_connectiontype
+ else:
+ self.w_connectionType = get(space).w_Connection
+
self.w_username = w_user
self.w_password = w_password
self.w_tnsentry = w_dsn
- from pypy.module.oracle.interp_connect import W_Connection
- self.w_connectionType = w_connectiontype or get(space).w_Connection
self.minSessions = min
self.maxSessions = max
self.sessionIncrement = increment
@@ -173,7 +175,7 @@
# ensure that the connection behaves as closed
connection.sessionPool = None
- connection.handle = None
+ connection.handle = lltype.nullptr(roci.OCISvcCtx.TO)
def computedProperty(oci_attr_code, oci_value_type):
def fget(space, self):
@@ -191,7 +193,7 @@
return space.wrap(valueptr[0])
finally:
lltype.free(valueptr, flavor='raw')
- return GetSetProperty(fget)
+ return GetSetProperty(fget, cls=W_SessionPool)
W_SessionPool.typedef = TypeDef(
"SessionPool",
Modified: pypy/trunk/pypy/module/oracle/interp_variable.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/interp_variable.py (original)
+++ pypy/trunk/pypy/module/oracle/interp_variable.py Fri Nov 27 19:30:28 2009
@@ -476,32 +476,28 @@
def getValueProc(self, space, pos):
offset = pos * self.bufferSize
+ dataptr = rffi.ptradd(self.data, offset)
length = rffi.cast(lltype.Signed, self.actualLength[pos])
- l = []
i = 0
if config.WITH_UNICODE:
if isinstance(self, VT_Binary):
- while i < length:
- l.append(self.data[offset + i])
- i += 1
- return space.wrap(''.join(l))
+ return space.wrap(rffi.charpsize2str(dataptr, length))
else:
+ l = []
while i < length:
- l.append(unichr((ord(self.data[offset + i + 1]) << 8) +
- ord(self.data[offset + i])))
+ l.append(unichr((ord(dataptr[i + 1]) << 8) +
+ ord(dataptr[i])))
i += 2
return space.wrap(u''.join(l))
else:
if self.charsetForm == roci.SQLCS_IMPLICIT:
- while i < length:
- l.append(self.data[offset + i])
- i += 1
- return space.wrap(''.join(l))
+ return space.wrap(rffi.charpsize2str(dataptr, length))
else:
+ l = []
while i < length:
- l.append(unichr((ord(self.data[offset + i + 1]) << 8) +
- ord(self.data[offset + i])))
+ l.append(unichr((ord(dataptr[i + 1]) << 8) +
+ ord(dataptr[i])))
i += 2
return space.wrap(u''.join(l))
@@ -1007,7 +1003,7 @@
temporaryLobType = roci.OCI_TEMP_CLOB
def initialize(self, space, cursor):
- super(W_LobVariable, self).initialize(space, cursor)
+ W_VariableWithDescriptor.initialize(self, space, cursor)
self.connection = cursor.connection
def ensureTemporary(self, space, pos):
@@ -1060,7 +1056,8 @@
self.environment.checkForError(
status,
"LobVar_GetLength()")
- return int(lengthptr[0]) # XXX test overflow
+ return rffi.cast(lltype.Signed,
+ lengthptr[0]) # XXX test overflow
finally:
lltype.free(lengthptr, flavor='raw')
@@ -1099,7 +1096,8 @@
self.environment.checkForError(
status,
"LobVar_Read()")
- amount = int(amountptr[0]) # XXX test overflow
+ amount = rffi.cast(lltype.Signed,
+ amountptr[0]) # XXX test overflow
value = rffi.str_from_buffer(raw_buffer, gc_buffer, bufferSize, amount)
return space.wrap(value)
finally:
@@ -1115,7 +1113,7 @@
try:
# nothing to do if no data to write
if databuf.size == 0:
- return
+ return 0
status = roci.OCILobWrite(
self.connection.handle,
@@ -1158,11 +1156,17 @@
space.wrap("BFILEs are read only"))
def read(self, space, pos, offset, amount):
- self.fileOpen()
+ self.openFile()
try:
return W_LobVariable.read(self, space, pos, offset, amount)
finally:
- self.fileClose()
+ self.closeFile()
+
+ def openFile(self):
+ pass # XXX
+
+ def closeFile(self):
+ pass # XXX
class VT_Cursor(W_Variable):
oracleType = roci.SQLT_RSET
@@ -1217,7 +1221,7 @@
size = rffi.sizeof(roci.dvoidp)
canBeInArray = False
- objectIndicator = None
+ objectIndicator = lltype.nullptr(rffi.CArrayPtr(roci.dvoidp).TO)
def initialize(self, space, cursor):
self.connection = cursor.connection
@@ -1260,7 +1264,9 @@
# look at our own indicator array
if not self.objectIndicator[pos]:
return True
- return (rffi.cast(roci.Ptr(roci.OCIInd), self.objectIndicator[pos])[0]
+ return (rffi.cast(lltype.Signed,
+ rffi.cast(roci.Ptr(roci.OCIInd),
+ self.objectIndicator[pos])[0])
==
rffi.cast(lltype.Signed, roci.OCI_IND_NULL))
Modified: pypy/trunk/pypy/module/oracle/roci.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/roci.py (original)
+++ pypy/trunk/pypy/module/oracle/roci.py Fri Nov 27 19:30:28 2009
@@ -64,7 +64,7 @@
OCI_SUCCESS OCI_SUCCESS_WITH_INFO OCI_INVALID_HANDLE OCI_NO_DATA
OCI_HTYPE_ERROR OCI_HTYPE_SVCCTX OCI_HTYPE_SERVER OCI_HTYPE_SESSION
OCI_HTYPE_STMT OCI_HTYPE_DESCRIBE OCI_HTYPE_BIND OCI_HTYPE_DEFINE
- OCI_HTYPE_ENV OCI_HTYPE_SPOOL OCI_HTYPE_AUTHINFO
+ OCI_HTYPE_ENV OCI_HTYPE_SPOOL OCI_HTYPE_AUTHINFO OCI_ATTR_CONNECTION_CLASS
OCI_DTYPE_PARAM OCI_DTYPE_TIMESTAMP OCI_DTYPE_INTERVAL_DS OCI_DTYPE_LOB
OCI_CRED_RDBMS OCI_CRED_EXT OCI_SPOOL_ATTRVAL_NOWAIT
OCI_ATTR_SERVER OCI_ATTR_SESSION OCI_ATTR_USERNAME OCI_ATTR_PASSWORD
@@ -99,7 +99,7 @@
OCI_NLS_MAXBUFSZ OCI_NLS_CS_ORA_TO_IANA OCI_UTF16ID
OCI_SPC_STMTCACHE OCI_SPC_HOMOGENEOUS
OCI_SESSGET_SPOOL OCI_SESSGET_CREDPROXY OCI_SESSGET_STMTCACHE
- OCI_SESSRLS_DROPSESS OCI_ATTR_PURITY_DEFAULT
+ OCI_SESSGET_CREDEXT OCI_SESSRLS_DROPSESS OCI_ATTR_PURITY_DEFAULT
'''.split()
for c in constants:
Modified: pypy/trunk/pypy/module/oracle/test/test_connect.py
==============================================================================
--- pypy/trunk/pypy/module/oracle/test/test_connect.py (original)
+++ pypy/trunk/pypy/module/oracle/test/test_connect.py Fri Nov 27 19:30:28 2009
@@ -158,5 +158,6 @@
2, 8, 3, homogeneous=False)
assert pool.homogeneous is False
e = raises(oracle.DatabaseError, pool.acquire, user="proxyuser")
+ # ORA-01017: invalid username/password; logon denied
# ORA-28150: proxy not authorized to connect as client
- assert e.value[0].code == 28150
+ assert e.value[0].code in (1017, 28150)
More information about the Pypy-commit
mailing list