Compare commits

...

6 Commits
main ... v7.1.x

Author SHA1 Message Date
Anthony Tuininga
d8c42f7a7a Preparing to release cx_Oracle 7.1.3. 2019-04-24 09:53:09 -06:00
Anthony Tuininga
bc67a3f43d Adjust documentation to indicate what cursor.rowcount returns for PL/SQL block
executions (https://github.com/oracle/python-cx_Oracle/issues/285).
2019-04-17 15:32:23 -06:00
Anthony Tuininga
763cfeae21 For Python 2.7, raw_input is needed to request input; also ensure that sample
parameters are saved once requested.
2019-04-17 15:31:59 -06:00
Anthony Tuininga
983dfdab9f Adjust return value of cursor.callproc() to follow documentation so that only
positional arguments are returned
(https://github.com/oracle/python-cx_Oracle/pull/287).
2019-04-17 15:31:40 -06:00
Anthony Tuininga
511cd7a4cf Correct 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
(https://github.com/oracle/python-cx_Oracle/issues/290).
2019-04-17 15:31:12 -06:00
Anthony Tuininga
c94d99981c Update ODPI-C. 2019-04-17 15:30:44 -06:00
11 changed files with 88 additions and 11 deletions

View File

@ -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:

View File

@ -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

View File

@ -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

@ -1 +1 @@
Subproject commit cdf1531eb435fcb814840a7b1bd666173d0890e4
Subproject commit a2ff27bacdcb94bdae1aaec1d010b436206e8384

View File

@ -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():

View File

@ -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 = []

View File

@ -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

View File

@ -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;

View File

@ -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(),

View File

@ -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")

View File

@ -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"