mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-06-30 09:43:07 +03:00
Name can be passed as None to cursor()
Makes invocation from subclasses and generic code easier. Code simplified by using default values for keyword arguments and avoiding needless conversions back and forth between Python and C strings. Also added connection type check to cursor's init.
This commit is contained in:
parent
c63891af8d
commit
27421f1e41
|
@ -42,7 +42,7 @@
|
||||||
/* cursor method - allocate a new cursor */
|
/* cursor method - allocate a new cursor */
|
||||||
|
|
||||||
#define psyco_conn_cursor_doc \
|
#define psyco_conn_cursor_doc \
|
||||||
"cursor(name=None, cursor_factory=extensions.cursor, withhold=None) -- new cursor\n\n" \
|
"cursor(name=None, cursor_factory=extensions.cursor, withhold=False) -- new cursor\n\n" \
|
||||||
"Return a new cursor.\n\nThe ``cursor_factory`` argument can be used to\n" \
|
"Return a new cursor.\n\nThe ``cursor_factory`` argument can be used to\n" \
|
||||||
"create non-standard cursors by passing a class different from the\n" \
|
"create non-standard cursors by passing a class different from the\n" \
|
||||||
"default. Note that the new class *should* be a sub-class of\n" \
|
"default. Note that the new class *should* be a sub-class of\n" \
|
||||||
|
@ -50,26 +50,26 @@
|
||||||
":rtype: `extensions.cursor`"
|
":rtype: `extensions.cursor`"
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *keywds)
|
psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
const char *name = NULL;
|
PyObject *obj;
|
||||||
PyObject *obj, *factory = NULL, *withhold = NULL;
|
PyObject *name = Py_None;
|
||||||
|
PyObject *factory = (PyObject *)&cursorType;
|
||||||
|
PyObject *withhold = Py_False;
|
||||||
|
|
||||||
static char *kwlist[] = {"name", "cursor_factory", "withhold", NULL};
|
static char *kwlist[] = {"name", "cursor_factory", "withhold", NULL};
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, keywds, "|sOO", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOO", kwlist,
|
||||||
&name, &factory, &withhold)) {
|
&name, &factory, &withhold)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (withhold != NULL) {
|
if (PyObject_IsTrue(withhold) && (name == Py_None)) {
|
||||||
if (PyObject_IsTrue(withhold) && name == NULL) {
|
PyErr_SetString(ProgrammingError,
|
||||||
PyErr_SetString(ProgrammingError,
|
"'withhold=True can be specified only for named cursors");
|
||||||
"'withhold=True can be specified only for named cursors");
|
return NULL;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXC_IF_CONN_CLOSED(self);
|
EXC_IF_CONN_CLOSED(self);
|
||||||
|
|
||||||
if (self->status != CONN_STATUS_READY &&
|
if (self->status != CONN_STATUS_READY &&
|
||||||
|
@ -80,31 +80,28 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *keywds)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name != NULL && self->async == 1) {
|
if (name != Py_None && self->async == 1) {
|
||||||
PyErr_SetString(ProgrammingError,
|
PyErr_SetString(ProgrammingError,
|
||||||
"asynchronous connections "
|
"asynchronous connections "
|
||||||
"cannot produce named cursors");
|
"cannot produce named cursors");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dprintf("psyco_conn_cursor: new cursor for connection at %p", self);
|
Dprintf("psyco_conn_cursor: new %s cursor for connection at %p",
|
||||||
Dprintf("psyco_conn_cursor: parameters: name = %s", name);
|
(name == Py_None ? "unnamed" : "named"), self);
|
||||||
|
|
||||||
if (factory == NULL) factory = (PyObject *)&cursorType;
|
if (!(obj = PyObject_CallFunctionObjArgs(factory, self, name, NULL))) {
|
||||||
if (name)
|
return NULL;
|
||||||
obj = PyObject_CallFunction(factory, "Os", self, name);
|
}
|
||||||
else
|
|
||||||
obj = PyObject_CallFunctionObjArgs(factory, self, NULL);
|
|
||||||
|
|
||||||
if (obj == NULL) return NULL;
|
|
||||||
if (PyObject_IsInstance(obj, (PyObject *)&cursorType) == 0) {
|
if (PyObject_IsInstance(obj, (PyObject *)&cursorType) == 0) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"cursor factory must be subclass of psycopg2._psycopg.cursor");
|
"cursor factory must be subclass of psycopg2._psycopg.cursor");
|
||||||
Py_DECREF(obj);
|
Py_DECREF(obj);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (withhold != NULL && PyObject_IsTrue(withhold))
|
if (PyObject_IsTrue(withhold))
|
||||||
((cursorObject*)obj)->withhold = 1;
|
((cursorObject*)obj)->withhold = 1;
|
||||||
|
|
||||||
Dprintf("psyco_conn_cursor: new cursor at %p: refcnt = "
|
Dprintf("psyco_conn_cursor: new cursor at %p: refcnt = "
|
||||||
|
|
|
@ -1808,15 +1808,28 @@ cursor_dealloc(PyObject* obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cursor_init(PyObject *obj, PyObject *args, PyObject *kwds)
|
cursor_init(PyObject *obj, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
const char *name = NULL;
|
|
||||||
PyObject *conn;
|
PyObject *conn;
|
||||||
|
PyObject *name = Py_None;
|
||||||
|
const char *cname;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O|s", &conn, &name))
|
static char *kwlist[] = {"conn", "name", NULL};
|
||||||
|
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O", kwlist,
|
||||||
|
&connectionType, &conn, &name)) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return cursor_setup((cursorObject *)obj, (connectionObject *)conn, name);
|
if (name == Py_None) {
|
||||||
|
cname = NULL;
|
||||||
|
} else {
|
||||||
|
if (!(cname = Bytes_AsString(name))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cursor_setup((cursorObject *)obj, (connectionObject *)conn, cname);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
|
@ -165,6 +165,10 @@ class CursorTests(unittest.TestCase):
|
||||||
del curs
|
del curs
|
||||||
self.assert_(w() is None)
|
self.assert_(w() is None)
|
||||||
|
|
||||||
|
def test_null_name(self):
|
||||||
|
curs = self.conn.cursor(None)
|
||||||
|
self.assertEqual(curs.name, None)
|
||||||
|
|
||||||
def test_invalid_name(self):
|
def test_invalid_name(self):
|
||||||
curs = self.conn.cursor()
|
curs = self.conn.cursor()
|
||||||
curs.execute("create temp table invname (data int);")
|
curs.execute("create temp table invname (data int);")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user