Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8c42f7a7a | ||
|
|
bc67a3f43d | ||
|
|
763cfeae21 | ||
|
|
983dfdab9f | ||
|
|
511cd7a4cf | ||
|
|
c94d99981c |
@ -42,7 +42,7 @@ author = 'Oracle'
|
||||
# The short X.Y version.
|
||||
version = '7.1'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '7.1.2'
|
||||
release = '7.1.3'
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
|
||||
@ -424,8 +424,10 @@ Cursor Object
|
||||
.. attribute:: Cursor.rowcount
|
||||
|
||||
This read-only attribute specifies the number of rows that have currently
|
||||
been fetched from the cursor (for select statements) or that have been
|
||||
affected by the operation (for insert, update and delete statements).
|
||||
been fetched from the cursor (for select statements), that have been
|
||||
affected by the operation (for insert, update, delete and merge
|
||||
statements), or the number of successful executions of the statement
|
||||
(for PL/SQL statements).
|
||||
|
||||
|
||||
.. attribute:: Cursor.rowfactory
|
||||
|
||||
@ -8,6 +8,26 @@ cx_Oracle Release Notes
|
||||
|
||||
.. _releasenotes70:
|
||||
|
||||
Version 7.1.3 (April 2019)
|
||||
--------------------------
|
||||
|
||||
#) Updated to `ODPI-C 3.1.4
|
||||
<https://oracle.github.io/odpi/doc/releasenotes.html#
|
||||
version-3-1-4-april-24-2019>`__.
|
||||
#) Added support for getting the row count for PL/SQL statements
|
||||
(`issue 285 <https://github.com/oracle/python-cx_Oracle/issues/285>`__).
|
||||
#) Corrected parsing of connect string so that the last @ symbol is searched
|
||||
for instead of the first @ symbol; otherwise, passwords containing an @
|
||||
symbol will result in the incorrect DSN being extracted
|
||||
(`issue 290 <https://github.com/oracle/python-cx_Oracle/issues/290>`__).
|
||||
#) Adjusted return value of cursor.callproc() to follow documentation (only
|
||||
positional arguments are returned since the order of keyword parameters
|
||||
cannot be guaranteed in any case)
|
||||
(`PR 287 <https://github.com/oracle/python-cx_Oracle/pull/287>`__).
|
||||
#) Corrected code getting sample and test parameters by user input when using
|
||||
Python 2.7.
|
||||
|
||||
|
||||
Version 7.1.2 (March 2019)
|
||||
--------------------------
|
||||
|
||||
|
||||
2
odpi
2
odpi
@ -1 +1 @@
|
||||
Subproject commit cdf1531eb435fcb814840a7b1bd666173d0890e4
|
||||
Subproject commit a2ff27bacdcb94bdae1aaec1d010b436206e8384
|
||||
@ -43,6 +43,12 @@ import getpass
|
||||
import os
|
||||
import sys
|
||||
|
||||
# for Python 2.7 we need raw_input
|
||||
try:
|
||||
input = raw_input
|
||||
except NameError:
|
||||
pass
|
||||
|
||||
# default values
|
||||
DEFAULT_MAIN_USER = "pythondemo"
|
||||
DEFAULT_EDITION_USER = "pythoneditions"
|
||||
@ -70,6 +76,7 @@ def GetValue(name, label, defaultValue=""):
|
||||
value = getpass.getpass(label)
|
||||
if not value:
|
||||
value = defaultValue
|
||||
PARAMETERS[name] = value
|
||||
return value
|
||||
|
||||
def GetMainUser():
|
||||
|
||||
2
setup.py
2
setup.py
@ -20,7 +20,7 @@ except:
|
||||
from distutils.extension import Extension
|
||||
|
||||
# define build constants
|
||||
BUILD_VERSION = "7.1.2"
|
||||
BUILD_VERSION = "7.1.3"
|
||||
|
||||
# setup extra link and compile args
|
||||
extraLinkArgs = []
|
||||
|
||||
@ -643,14 +643,16 @@ static PyObject *cxoConnection_new(PyTypeObject *type, PyObject *args,
|
||||
// string in to the target.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int cxoConnection_splitComponent(PyObject **sourceObj,
|
||||
PyObject **targetObj, const char *splitString)
|
||||
PyObject **targetObj, const char *splitString, int first)
|
||||
{
|
||||
PyObject *temp, *posObj;
|
||||
Py_ssize_t size, pos;
|
||||
char *methodName;
|
||||
|
||||
if (!*sourceObj || *targetObj)
|
||||
return 0;
|
||||
posObj = PyObject_CallMethod(*sourceObj, "find", "s", splitString);
|
||||
methodName = (first) ? "find" : "rfind";
|
||||
posObj = PyObject_CallMethod(*sourceObj, methodName, "s", splitString);
|
||||
if (!posObj)
|
||||
return -1;
|
||||
pos = PyInt_AsLong(posObj);
|
||||
@ -742,9 +744,9 @@ static int cxoConnection_init(cxoConnection *conn, PyObject *args,
|
||||
conn->dsn = dsnObj;
|
||||
|
||||
// perform some parsing, if necessary
|
||||
if (cxoConnection_splitComponent(&conn->username, &passwordObj, "/") < 0)
|
||||
if (cxoConnection_splitComponent(&conn->username, &passwordObj, "/", 1) < 0)
|
||||
return -1;
|
||||
if (cxoConnection_splitComponent(&passwordObj, &conn->dsn, "@") < 0)
|
||||
if (cxoConnection_splitComponent(&passwordObj, &conn->dsn, "@", 0) < 0)
|
||||
return -1;
|
||||
|
||||
// setup parameters
|
||||
|
||||
@ -1326,8 +1326,8 @@ static PyObject *cxoCursor_callProc(cxoCursor *cursor, PyObject *args,
|
||||
keywordArguments) < 0)
|
||||
return NULL;
|
||||
|
||||
// create the return value
|
||||
numArgs = PyList_GET_SIZE(cursor->bindVariables);
|
||||
// create the return value (only positional arguments are returned)
|
||||
numArgs = (listOfArguments) ? PySequence_Size(listOfArguments) : 0;
|
||||
results = PyList_New(numArgs);
|
||||
if (!results)
|
||||
return NULL;
|
||||
|
||||
@ -144,6 +144,22 @@ class TestCase(TestEnv.BaseTestCase):
|
||||
self.assertRaises(cx_Oracle.DatabaseError, connection.changepassword,
|
||||
TestEnv.GetMainPassword(), newPassword)
|
||||
|
||||
def testParsePassword(self):
|
||||
"test connecting with password containing / and @ symbols"
|
||||
sysRandom = random.SystemRandom()
|
||||
chars = list(sysRandom.choice(string.ascii_letters) for i in range(20))
|
||||
chars[4] = "/"
|
||||
chars[8] = "@"
|
||||
newPassword = "".join(chars)
|
||||
connection = TestEnv.GetConnection()
|
||||
connection.changepassword(TestEnv.GetMainPassword(), newPassword)
|
||||
try:
|
||||
arg = "%s/%s@%s" % (TestEnv.GetMainUser(), newPassword,
|
||||
TestEnv.GetConnectString())
|
||||
cx_Oracle.connect(arg)
|
||||
finally:
|
||||
connection.changepassword(newPassword, TestEnv.GetMainPassword())
|
||||
|
||||
def testEncodings(self):
|
||||
"connection with only encoding or nencoding specified should work"
|
||||
connection = cx_Oracle.connect(TestEnv.GetMainUser(),
|
||||
|
||||
@ -86,6 +86,30 @@ class TestCase(TestEnv.BaseTestCase):
|
||||
results = self.cursor.callproc("proc_Test", ("hi", 5, var))
|
||||
self.assertEqual(results, ["hi", 10, 2.0])
|
||||
|
||||
def testCallProcAllKeywords(self):
|
||||
"test executing a stored procedure with args in keywordParameters"
|
||||
kwargs = dict(a_InOutValue=self.cursor.var(cx_Oracle.NUMBER),
|
||||
a_InValue="hi", a_OutValue=self.cursor.var(cx_Oracle.NUMBER))
|
||||
kwargs['a_InOutValue'].setvalue(0, 5)
|
||||
results = self.cursor.callproc("proc_Test", keywordParameters=kwargs)
|
||||
self.assertEqual(results, [])
|
||||
self.assertEqual(kwargs['a_InOutValue'].getvalue(), 10)
|
||||
self.assertEqual(kwargs['a_OutValue'].getvalue(), 2.0)
|
||||
|
||||
def testCallProcOnlyLastKeyword(self):
|
||||
"test executing a stored procedure with last arg in keywordParameters"
|
||||
kwargs = dict(a_OutValue = self.cursor.var(cx_Oracle.NUMBER))
|
||||
results = self.cursor.callproc("proc_Test", ("hi", 5), kwargs)
|
||||
self.assertEqual(results, ["hi", 10])
|
||||
self.assertEqual(kwargs['a_OutValue'].getvalue(), 2.0)
|
||||
|
||||
def testCallProcRepeatedKeywordParameters(self):
|
||||
"test executing a stored procedure, repeated arg in keywordParameters"
|
||||
kwargs = dict(a_InValue="hi",
|
||||
a_OutValue=self.cursor.var(cx_Oracle.NUMBER))
|
||||
self.assertRaises(cx_Oracle.DatabaseError, self.cursor.callproc,
|
||||
"proc_Test", parameters=("hi", 5), keywordParameters=kwargs)
|
||||
|
||||
def testCallProcNoArgs(self):
|
||||
"""test executing a stored procedure without any arguments"""
|
||||
results = self.cursor.callproc(u"proc_TestNoArgs")
|
||||
|
||||
@ -49,6 +49,12 @@ import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
# for Python 2.7 we need raw_input
|
||||
try:
|
||||
input = raw_input
|
||||
except NameError:
|
||||
pass
|
||||
|
||||
# default values
|
||||
DEFAULT_MAIN_USER = "pythontest"
|
||||
DEFAULT_PROXY_USER = "pythontestproxy"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user