mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-01-31 17:34:08 +03:00
Merge branch 'gcc-python-plugin' into devel
This commit is contained in:
commit
b8c75d9de0
4
NEWS
4
NEWS
|
@ -15,6 +15,10 @@ What's new in psycopg 2.4.5
|
||||||
Regression introduced in 2.4.4 (ticket #100).
|
Regression introduced in 2.4.4 (ticket #100).
|
||||||
- Added support for 'inet' arrays.
|
- Added support for 'inet' arrays.
|
||||||
- Fixed 'commit()' concurrency problem (ticket #103).
|
- Fixed 'commit()' concurrency problem (ticket #103).
|
||||||
|
- Codebase cleaned up using the GCC Python plugin's static analysis
|
||||||
|
tool, which has revealed several unchecked return values, possible
|
||||||
|
NULL dereferences, reference counting problems. Many thanks to David
|
||||||
|
Malcolm for the useful tool and the assistance provided using it.
|
||||||
|
|
||||||
|
|
||||||
What's new in psycopg 2.4.4
|
What's new in psycopg 2.4.4
|
||||||
|
|
|
@ -65,6 +65,13 @@ binary_quote(binaryObject *self)
|
||||||
int got_view = 0;
|
int got_view = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Allow Binary(None) to work */
|
||||||
|
if (self->wrapped == Py_None) {
|
||||||
|
Py_INCREF(psyco_null);
|
||||||
|
rv = psyco_null;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
/* if we got a plain string or a buffer we escape it and save the buffer */
|
/* if we got a plain string or a buffer we escape it and save the buffer */
|
||||||
|
|
||||||
#if HAS_MEMORYVIEW
|
#if HAS_MEMORYVIEW
|
||||||
|
@ -93,7 +100,7 @@ binary_quote(binaryObject *self)
|
||||||
|
|
||||||
/* escape and build quoted buffer */
|
/* escape and build quoted buffer */
|
||||||
|
|
||||||
to = (char *)binary_escape((unsigned char*)buffer, (size_t) buffer_len,
|
to = (char *)binary_escape((unsigned char*)buffer, (size_t)buffer_len,
|
||||||
&len, self->conn ? ((connectionObject*)self->conn)->pgconn : NULL);
|
&len, self->conn ? ((connectionObject*)self->conn)->pgconn : NULL);
|
||||||
if (to == NULL) {
|
if (to == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
|
@ -113,12 +120,6 @@ exit:
|
||||||
if (got_view) { PyBuffer_Release(&view); }
|
if (got_view) { PyBuffer_Release(&view); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Allow Binary(None) to work */
|
|
||||||
if (self->wrapped == Py_None) {
|
|
||||||
Py_INCREF(psyco_null);
|
|
||||||
rv = psyco_null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if the wrapped object is not bytes or a buffer, this is an error */
|
/* if the wrapped object is not bytes or a buffer, this is an error */
|
||||||
if (!rv && !PyErr_Occurred()) {
|
if (!rv && !PyErr_Occurred()) {
|
||||||
PyErr_Format(PyExc_TypeError, "can't escape %s to binary",
|
PyErr_Format(PyExc_TypeError, "can't escape %s to binary",
|
||||||
|
@ -149,16 +150,14 @@ binary_str(binaryObject *self)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
binary_prepare(binaryObject *self, PyObject *args)
|
binary_prepare(binaryObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
connectionObject *conn;
|
PyObject *conn;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O", &conn))
|
if (!PyArg_ParseTuple(args, "O!", &connectionType, &conn))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Py_XDECREF(self->conn);
|
Py_XDECREF(self->conn);
|
||||||
if (conn) {
|
self->conn = conn;
|
||||||
self->conn = (PyObject*)conn;
|
Py_INCREF(self->conn);
|
||||||
Py_INCREF(self->conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
|
|
|
@ -427,6 +427,10 @@ psyco_DateFromTicks(PyObject *self, PyObject *args)
|
||||||
Py_DECREF(args);
|
Py_DECREF(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
PyErr_SetString(InterfaceError, "failed localtime call");
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,6 +455,10 @@ psyco_TimeFromTicks(PyObject *self, PyObject *args)
|
||||||
Py_DECREF(args);
|
Py_DECREF(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
PyErr_SetString(InterfaceError, "failed localtime call");
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,6 +481,9 @@ psyco_TimestampFromTicks(PyObject *self, PyObject *args)
|
||||||
tm.tm_hour, tm.tm_min, (double)tm.tm_sec + ticks,
|
tm.tm_hour, tm.tm_min, (double)tm.tm_sec + ticks,
|
||||||
pyPsycopgTzLOCAL);
|
pyPsycopgTzLOCAL);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
PyErr_SetString(InterfaceError, "failed localtime call");
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,9 +98,9 @@ list_getquoted(listObject *self, PyObject *args)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
list_prepare(listObject *self, PyObject *args)
|
list_prepare(listObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
connectionObject *conn;
|
PyObject *conn;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O", &conn))
|
if (!PyArg_ParseTuple(args, "O!", &connectionType, &conn))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* note that we don't copy the encoding from the connection, but take a
|
/* note that we don't copy the encoding from the connection, but take a
|
||||||
|
@ -109,7 +109,7 @@ list_prepare(listObject *self, PyObject *args)
|
||||||
work even without a connection to the backend. */
|
work even without a connection to the backend. */
|
||||||
Py_CLEAR(self->connection);
|
Py_CLEAR(self->connection);
|
||||||
Py_INCREF(conn);
|
Py_INCREF(conn);
|
||||||
self->connection = (PyObject*)conn;
|
self->connection = conn;
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
/* qstring_quote - do the quote process on plain and unicode strings */
|
/* qstring_quote - do the quote process on plain and unicode strings */
|
||||||
|
|
||||||
static PyObject *
|
BORROWED static PyObject *
|
||||||
qstring_quote(qstringObject *self)
|
qstring_quote(qstringObject *self)
|
||||||
{
|
{
|
||||||
PyObject *str;
|
PyObject *str;
|
||||||
|
@ -124,24 +124,22 @@ qstring_str(qstringObject *self)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
qstring_prepare(qstringObject *self, PyObject *args)
|
qstring_prepare(qstringObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
connectionObject *conn;
|
PyObject *conn;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O", &conn))
|
if (!PyArg_ParseTuple(args, "O!", &connectionType, &conn))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* we bother copying the encoding only if the wrapped string is unicode,
|
/* we bother copying the encoding only if the wrapped string is unicode,
|
||||||
we don't need the encoding if that's not the case */
|
we don't need the encoding if that's not the case */
|
||||||
if (PyUnicode_Check(self->wrapped)) {
|
if (PyUnicode_Check(self->wrapped)) {
|
||||||
if (self->encoding) free(self->encoding);
|
if (self->encoding) free(self->encoding);
|
||||||
self->encoding = strdup(conn->codec);
|
self->encoding = strdup(((connectionObject *)conn)->codec);
|
||||||
Dprintf("qstring_prepare: set encoding to %s", conn->codec);
|
Dprintf("qstring_prepare: set encoding to %s", self->encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_CLEAR(self->conn);
|
Py_CLEAR(self->conn);
|
||||||
if (conn) {
|
Py_INCREF(conn);
|
||||||
Py_INCREF(conn);
|
self->conn = conn;
|
||||||
self->conn = (PyObject*)conn;
|
|
||||||
}
|
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
|
|
|
@ -86,7 +86,7 @@
|
||||||
|
|
||||||
/* Helpers for formatstring */
|
/* Helpers for formatstring */
|
||||||
|
|
||||||
Py_LOCAL_INLINE(PyObject *)
|
BORROWED Py_LOCAL_INLINE(PyObject *)
|
||||||
getnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx)
|
getnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx)
|
||||||
{
|
{
|
||||||
Py_ssize_t argidx = *p_argidx;
|
Py_ssize_t argidx = *p_argidx;
|
||||||
|
|
|
@ -160,4 +160,33 @@ static double round(double num)
|
||||||
#define isinf(x) (!finite((x)) && (x)==(x))
|
#define isinf(x) (!finite((x)) && (x)==(x))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* decorators for the gcc cpychecker plugin */
|
||||||
|
#if defined(WITH_CPYCHECKER_RETURNS_BORROWED_REF_ATTRIBUTE)
|
||||||
|
#define BORROWED \
|
||||||
|
__attribute__((cpychecker_returns_borrowed_ref))
|
||||||
|
#else
|
||||||
|
#define BORROWED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE)
|
||||||
|
#define STEALS(n) \
|
||||||
|
__attribute__((cpychecker_steals_reference_to_arg(n)))
|
||||||
|
#else
|
||||||
|
#define STEALS(n)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WITH_CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION_ATTRIBUTE)
|
||||||
|
#define RAISES_NEG \
|
||||||
|
__attribute__((cpychecker_negative_result_sets_exception))
|
||||||
|
#else
|
||||||
|
#define RAISES_NEG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WITH_CPYCHECKER_SETS_EXCEPTION_ATTRIBUTE)
|
||||||
|
#define RAISES \
|
||||||
|
__attribute__((cpychecker_sets_exception))
|
||||||
|
#else
|
||||||
|
#define RAISES
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* !defined(PSYCOPG_CONFIG_H) */
|
#endif /* !defined(PSYCOPG_CONFIG_H) */
|
||||||
|
|
|
@ -131,27 +131,27 @@ typedef struct {
|
||||||
/* C-callable functions in connection_int.c and connection_ext.c */
|
/* C-callable functions in connection_int.c and connection_ext.c */
|
||||||
HIDDEN PyObject *conn_text_from_chars(connectionObject *pgconn, const char *str);
|
HIDDEN PyObject *conn_text_from_chars(connectionObject *pgconn, const char *str);
|
||||||
HIDDEN int conn_get_standard_conforming_strings(PGconn *pgconn);
|
HIDDEN int conn_get_standard_conforming_strings(PGconn *pgconn);
|
||||||
HIDDEN int conn_get_isolation_level(connectionObject *self);
|
RAISES_NEG HIDDEN int conn_get_isolation_level(connectionObject *self);
|
||||||
HIDDEN int conn_get_protocol_version(PGconn *pgconn);
|
HIDDEN int conn_get_protocol_version(PGconn *pgconn);
|
||||||
HIDDEN int conn_get_server_version(PGconn *pgconn);
|
HIDDEN int conn_get_server_version(PGconn *pgconn);
|
||||||
HIDDEN PGcancel *conn_get_cancel(PGconn *pgconn);
|
HIDDEN PGcancel *conn_get_cancel(PGconn *pgconn);
|
||||||
HIDDEN void conn_notice_process(connectionObject *self);
|
HIDDEN void conn_notice_process(connectionObject *self);
|
||||||
HIDDEN void conn_notice_clean(connectionObject *self);
|
HIDDEN void conn_notice_clean(connectionObject *self);
|
||||||
HIDDEN void conn_notifies_process(connectionObject *self);
|
HIDDEN void conn_notifies_process(connectionObject *self);
|
||||||
HIDDEN int conn_setup(connectionObject *self, PGconn *pgconn);
|
RAISES_NEG HIDDEN int conn_setup(connectionObject *self, PGconn *pgconn);
|
||||||
HIDDEN int conn_connect(connectionObject *self, long int async);
|
HIDDEN int conn_connect(connectionObject *self, long int async);
|
||||||
HIDDEN void conn_close(connectionObject *self);
|
HIDDEN void conn_close(connectionObject *self);
|
||||||
HIDDEN int conn_commit(connectionObject *self);
|
RAISES_NEG HIDDEN int conn_commit(connectionObject *self);
|
||||||
HIDDEN int conn_rollback(connectionObject *self);
|
RAISES_NEG HIDDEN int conn_rollback(connectionObject *self);
|
||||||
HIDDEN int conn_set_session(connectionObject *self, const char *isolevel,
|
RAISES_NEG HIDDEN int conn_set_session(connectionObject *self, const char *isolevel,
|
||||||
const char *readonly, const char *deferrable,
|
const char *readonly, const char *deferrable,
|
||||||
int autocommit);
|
int autocommit);
|
||||||
HIDDEN int conn_set_autocommit(connectionObject *self, int value);
|
HIDDEN int conn_set_autocommit(connectionObject *self, int value);
|
||||||
HIDDEN int conn_switch_isolation_level(connectionObject *self, int level);
|
RAISES_NEG HIDDEN int conn_switch_isolation_level(connectionObject *self, int level);
|
||||||
HIDDEN int conn_set_client_encoding(connectionObject *self, const char *enc);
|
RAISES_NEG HIDDEN int conn_set_client_encoding(connectionObject *self, const char *enc);
|
||||||
HIDDEN int conn_poll(connectionObject *self);
|
HIDDEN int conn_poll(connectionObject *self);
|
||||||
HIDDEN int conn_tpc_begin(connectionObject *self, XidObject *xid);
|
RAISES_NEG HIDDEN int conn_tpc_begin(connectionObject *self, XidObject *xid);
|
||||||
HIDDEN int conn_tpc_command(connectionObject *self,
|
RAISES_NEG HIDDEN int conn_tpc_command(connectionObject *self,
|
||||||
const char *cmd, XidObject *xid);
|
const char *cmd, XidObject *xid);
|
||||||
HIDDEN PyObject *conn_tpc_recover(connectionObject *self);
|
HIDDEN PyObject *conn_tpc_recover(connectionObject *self);
|
||||||
|
|
||||||
|
|
|
@ -120,8 +120,16 @@ conn_notice_process(connectionObject *self)
|
||||||
|
|
||||||
/* Respect the order in which notices were produced,
|
/* Respect the order in which notices were produced,
|
||||||
because in notice_list they are reversed (see ticket #9) */
|
because in notice_list they are reversed (see ticket #9) */
|
||||||
PyList_Insert(self->notice_list, nnotices, msg);
|
if (msg) {
|
||||||
Py_DECREF(msg);
|
PyList_Insert(self->notice_list, nnotices, msg);
|
||||||
|
Py_DECREF(msg);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* We don't really have a way to report errors, so gulp it.
|
||||||
|
* The function should only fail for out of memory, so we are
|
||||||
|
* likely going to die anyway. */
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
|
||||||
notice = notice->next;
|
notice = notice->next;
|
||||||
}
|
}
|
||||||
|
@ -242,19 +250,20 @@ conn_get_standard_conforming_strings(PGconn *pgconn)
|
||||||
|
|
||||||
/* Remove irrelevant chars from encoding name and turn it uppercase.
|
/* Remove irrelevant chars from encoding name and turn it uppercase.
|
||||||
*
|
*
|
||||||
* Return a buffer allocated on Python heap,
|
* Return a buffer allocated on Python heap into 'clean' and return 0 on
|
||||||
* NULL and set an exception on error.
|
* success, otherwise return -1 and set an exception.
|
||||||
*/
|
*/
|
||||||
static char *
|
RAISES_NEG static int
|
||||||
clean_encoding_name(const char *enc)
|
clear_encoding_name(const char *enc, char **clean)
|
||||||
{
|
{
|
||||||
const char *i = enc;
|
const char *i = enc;
|
||||||
char *rv, *j;
|
char *j, *buf;
|
||||||
|
int rv = -1;
|
||||||
|
|
||||||
/* convert to upper case and remove '-' and '_' from string */
|
/* convert to upper case and remove '-' and '_' from string */
|
||||||
if (!(j = rv = PyMem_Malloc(strlen(enc) + 1))) {
|
if (!(j = buf = PyMem_Malloc(strlen(enc) + 1))) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
return NULL;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*i) {
|
while (*i) {
|
||||||
|
@ -267,25 +276,28 @@ clean_encoding_name(const char *enc)
|
||||||
}
|
}
|
||||||
*j = '\0';
|
*j = '\0';
|
||||||
|
|
||||||
Dprintf("clean_encoding_name: %s -> %s", enc, rv);
|
Dprintf("clear_encoding_name: %s -> %s", enc, buf);
|
||||||
|
*clean = buf;
|
||||||
|
rv = 0;
|
||||||
|
|
||||||
|
exit:
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert a PostgreSQL encoding to a Python codec.
|
/* Convert a PostgreSQL encoding to a Python codec.
|
||||||
*
|
*
|
||||||
* Return a new copy of the codec name allocated on the Python heap,
|
* Set 'codec' to a new copy of the codec name allocated on the Python heap.
|
||||||
* NULL with exception in case of error.
|
* Return 0 in case of success, else -1 and set an exception.
|
||||||
*
|
*
|
||||||
* 'enc' should be already normalized (uppercase, no - or _).
|
* 'enc' should be already normalized (uppercase, no - or _).
|
||||||
*/
|
*/
|
||||||
static char *
|
RAISES_NEG static int
|
||||||
conn_encoding_to_codec(const char *enc)
|
conn_encoding_to_codec(const char *enc, char **codec)
|
||||||
{
|
{
|
||||||
char *tmp;
|
char *tmp;
|
||||||
Py_ssize_t size;
|
Py_ssize_t size;
|
||||||
PyObject *pyenc = NULL;
|
PyObject *pyenc = NULL;
|
||||||
char *rv = NULL;
|
int rv = -1;
|
||||||
|
|
||||||
/* Find the Py codec name from the PG encoding */
|
/* Find the Py codec name from the PG encoding */
|
||||||
if (!(pyenc = PyDict_GetItemString(psycoEncodings, enc))) {
|
if (!(pyenc = PyDict_GetItemString(psycoEncodings, enc))) {
|
||||||
|
@ -305,7 +317,7 @@ conn_encoding_to_codec(const char *enc)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* have our own copy of the python codec name */
|
/* have our own copy of the python codec name */
|
||||||
rv = psycopg_strdup(tmp, size);
|
rv = psycopg_strdup(codec, tmp, size);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(pyenc);
|
Py_XDECREF(pyenc);
|
||||||
|
@ -320,7 +332,7 @@ exit:
|
||||||
*
|
*
|
||||||
* Return 0 on success, else nonzero.
|
* Return 0 on success, else nonzero.
|
||||||
*/
|
*/
|
||||||
static int
|
RAISES_NEG static int
|
||||||
conn_read_encoding(connectionObject *self, PGconn *pgconn)
|
conn_read_encoding(connectionObject *self, PGconn *pgconn)
|
||||||
{
|
{
|
||||||
char *enc = NULL, *codec = NULL;
|
char *enc = NULL, *codec = NULL;
|
||||||
|
@ -335,12 +347,12 @@ conn_read_encoding(connectionObject *self, PGconn *pgconn)
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(enc = clean_encoding_name(tmp))) {
|
if (0 > clear_encoding_name(tmp, &enc)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look for this encoding in Python codecs. */
|
/* Look for this encoding in Python codecs. */
|
||||||
if (!(codec = conn_encoding_to_codec(enc))) {
|
if (0 > conn_encoding_to_codec(enc, &codec)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,7 +374,7 @@ exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
conn_get_isolation_level(connectionObject *self)
|
conn_get_isolation_level(connectionObject *self)
|
||||||
{
|
{
|
||||||
PGresult *pgres = NULL;
|
PGresult *pgres = NULL;
|
||||||
|
@ -456,7 +468,7 @@ conn_is_datestyle_ok(PGconn *pgconn)
|
||||||
|
|
||||||
/* conn_setup - setup and read basic information about the connection */
|
/* conn_setup - setup and read basic information about the connection */
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
conn_setup(connectionObject *self, PGconn *pgconn)
|
conn_setup(connectionObject *self, PGconn *pgconn)
|
||||||
{
|
{
|
||||||
PGresult *pgres = NULL;
|
PGresult *pgres = NULL;
|
||||||
|
@ -470,7 +482,7 @@ conn_setup(connectionObject *self, PGconn *pgconn)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn_read_encoding(self, pgconn)) {
|
if (0 > conn_read_encoding(self, pgconn)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +496,7 @@ conn_setup(connectionObject *self, PGconn *pgconn)
|
||||||
pthread_mutex_lock(&self->lock);
|
pthread_mutex_lock(&self->lock);
|
||||||
Py_BLOCK_THREADS;
|
Py_BLOCK_THREADS;
|
||||||
|
|
||||||
if (psyco_green() && (pq_set_non_blocking(self, 1, 1) != 0)) {
|
if (psyco_green() && (0 > pq_set_non_blocking(self, 1))) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,7 +774,7 @@ _conn_poll_setup_async(connectionObject *self)
|
||||||
switch (self->status) {
|
switch (self->status) {
|
||||||
case CONN_STATUS_CONNECTING:
|
case CONN_STATUS_CONNECTING:
|
||||||
/* Set the connection to nonblocking now. */
|
/* Set the connection to nonblocking now. */
|
||||||
if (pq_set_non_blocking(self, 1, 1) != 0) {
|
if (pq_set_non_blocking(self, 1) != 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -773,7 +785,7 @@ _conn_poll_setup_async(connectionObject *self)
|
||||||
PyErr_SetString(InterfaceError, "only protocol 3 supported");
|
PyErr_SetString(InterfaceError, "only protocol 3 supported");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (conn_read_encoding(self, self->pgconn)) {
|
if (0 > conn_read_encoding(self, self->pgconn)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
self->cancel = conn_get_cancel(self->pgconn);
|
self->cancel = conn_get_cancel(self->pgconn);
|
||||||
|
@ -942,7 +954,7 @@ conn_close(connectionObject *self)
|
||||||
|
|
||||||
/* conn_commit - commit on a connection */
|
/* conn_commit - commit on a connection */
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
conn_commit(connectionObject *self)
|
conn_commit(connectionObject *self)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
@ -953,7 +965,7 @@ conn_commit(connectionObject *self)
|
||||||
|
|
||||||
/* conn_rollback - rollback a connection */
|
/* conn_rollback - rollback a connection */
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
conn_rollback(connectionObject *self)
|
conn_rollback(connectionObject *self)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
@ -962,7 +974,7 @@ conn_rollback(connectionObject *self)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
conn_set_session(connectionObject *self,
|
conn_set_session(connectionObject *self,
|
||||||
const char *isolevel, const char *readonly, const char *deferrable,
|
const char *isolevel, const char *readonly, const char *deferrable,
|
||||||
int autocommit)
|
int autocommit)
|
||||||
|
@ -1035,7 +1047,7 @@ conn_set_autocommit(connectionObject *self, int value)
|
||||||
|
|
||||||
/* conn_switch_isolation_level - switch isolation level on the connection */
|
/* conn_switch_isolation_level - switch isolation level on the connection */
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
conn_switch_isolation_level(connectionObject *self, int level)
|
conn_switch_isolation_level(connectionObject *self, int level)
|
||||||
{
|
{
|
||||||
PGresult *pgres = NULL;
|
PGresult *pgres = NULL;
|
||||||
|
@ -1117,12 +1129,12 @@ endlock:
|
||||||
|
|
||||||
/* conn_set_client_encoding - switch client encoding on connection */
|
/* conn_set_client_encoding - switch client encoding on connection */
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
conn_set_client_encoding(connectionObject *self, const char *enc)
|
conn_set_client_encoding(connectionObject *self, const char *enc)
|
||||||
{
|
{
|
||||||
PGresult *pgres = NULL;
|
PGresult *pgres = NULL;
|
||||||
char *error = NULL;
|
char *error = NULL;
|
||||||
int res = 1;
|
int res = -1;
|
||||||
char *codec = NULL;
|
char *codec = NULL;
|
||||||
char *clean_enc = NULL;
|
char *clean_enc = NULL;
|
||||||
|
|
||||||
|
@ -1131,8 +1143,8 @@ conn_set_client_encoding(connectionObject *self, const char *enc)
|
||||||
if (strcmp(self->encoding, enc) == 0) return 0;
|
if (strcmp(self->encoding, enc) == 0) return 0;
|
||||||
|
|
||||||
/* We must know what python codec this encoding is. */
|
/* We must know what python codec this encoding is. */
|
||||||
if (!(clean_enc = clean_encoding_name(enc))) { goto exit; }
|
if (0 > clear_encoding_name(enc, &clean_enc)) { goto exit; }
|
||||||
if (!(codec = conn_encoding_to_codec(clean_enc))) { goto exit; }
|
if (0 > conn_encoding_to_codec(clean_enc, &codec)) { goto exit; }
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS;
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
pthread_mutex_lock(&self->lock);
|
pthread_mutex_lock(&self->lock);
|
||||||
|
@ -1190,7 +1202,7 @@ exit:
|
||||||
* in regular transactions, as PostgreSQL won't even know we are in a TPC
|
* in regular transactions, as PostgreSQL won't even know we are in a TPC
|
||||||
* until PREPARE. */
|
* until PREPARE. */
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
conn_tpc_begin(connectionObject *self, XidObject *xid)
|
conn_tpc_begin(connectionObject *self, XidObject *xid)
|
||||||
{
|
{
|
||||||
PGresult *pgres = NULL;
|
PGresult *pgres = NULL;
|
||||||
|
@ -1224,7 +1236,7 @@ conn_tpc_begin(connectionObject *self, XidObject *xid)
|
||||||
* The function doesn't change the connection state as it can be used
|
* The function doesn't change the connection state as it can be used
|
||||||
* for many commands and for recovered transactions. */
|
* for many commands and for recovered transactions. */
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
conn_tpc_command(connectionObject *self, const char *cmd, XidObject *xid)
|
conn_tpc_command(connectionObject *self, const char *cmd, XidObject *xid)
|
||||||
{
|
{
|
||||||
PGresult *pgres = NULL;
|
PGresult *pgres = NULL;
|
||||||
|
|
|
@ -526,7 +526,7 @@ psyco_conn_set_session(connectionObject *self, PyObject *args, PyObject *kwargs)
|
||||||
if (-1 == c_autocommit) { return NULL; }
|
if (-1 == c_autocommit) { return NULL; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != conn_set_session(self,
|
if (0 > conn_set_session(self,
|
||||||
c_isolevel, c_readonly, c_deferrable, c_autocommit)) {
|
c_isolevel, c_readonly, c_deferrable, c_autocommit)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -548,7 +548,7 @@ psyco_conn_autocommit_get(connectionObject *self)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
BORROWED static PyObject *
|
||||||
_psyco_conn_autocommit_set_checks(connectionObject *self)
|
_psyco_conn_autocommit_set_checks(connectionObject *self)
|
||||||
{
|
{
|
||||||
/* wrapper to use the EXC_IF macros.
|
/* wrapper to use the EXC_IF macros.
|
||||||
|
@ -635,7 +635,7 @@ psyco_conn_set_client_encoding(connectionObject *self, PyObject *args)
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s", &enc)) return NULL;
|
if (!PyArg_ParseTuple(args, "s", &enc)) return NULL;
|
||||||
|
|
||||||
if (conn_set_client_encoding(self, enc) == 0) {
|
if (conn_set_client_encoding(self, enc) >= 0) {
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
rv = Py_None;
|
rv = Py_None;
|
||||||
}
|
}
|
||||||
|
@ -699,8 +699,8 @@ psyco_conn_get_parameter_status(connectionObject *self, PyObject *args)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_lobject(connectionObject *self, PyObject *args, PyObject *keywds)
|
psyco_conn_lobject(connectionObject *self, PyObject *args, PyObject *keywds)
|
||||||
{
|
{
|
||||||
Oid oid=InvalidOid, new_oid=InvalidOid;
|
int oid = (int)InvalidOid, new_oid = (int)InvalidOid;
|
||||||
char *new_file = NULL;
|
const char *new_file = NULL;
|
||||||
const char *smode = "";
|
const char *smode = "";
|
||||||
PyObject *factory = (PyObject *)&lobjectType;
|
PyObject *factory = (PyObject *)&lobjectType;
|
||||||
PyObject *obj;
|
PyObject *obj;
|
||||||
|
@ -752,7 +752,7 @@ psyco_conn_lobject(connectionObject *self, PyObject *args, PyObject *keywds)
|
||||||
"get_backend_pid() -- Get backend process id."
|
"get_backend_pid() -- Get backend process id."
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_get_backend_pid(connectionObject *self)
|
psyco_conn_get_backend_pid(connectionObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
EXC_IF_CONN_CLOSED(self);
|
EXC_IF_CONN_CLOSED(self);
|
||||||
|
|
||||||
|
@ -765,7 +765,7 @@ psyco_conn_get_backend_pid(connectionObject *self)
|
||||||
"reset() -- Reset current connection to defaults."
|
"reset() -- Reset current connection to defaults."
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_reset(connectionObject *self)
|
psyco_conn_reset(connectionObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
@ -793,7 +793,7 @@ psyco_conn_get_exception(PyObject *self, void *closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_poll(connectionObject *self)
|
psyco_conn_poll(connectionObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
@ -815,7 +815,7 @@ psyco_conn_poll(connectionObject *self)
|
||||||
"fileno() -> int -- Return file descriptor associated to database connection."
|
"fileno() -> int -- Return file descriptor associated to database connection."
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_fileno(connectionObject *self)
|
psyco_conn_fileno(connectionObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
long int socket;
|
long int socket;
|
||||||
|
|
||||||
|
@ -834,7 +834,7 @@ psyco_conn_fileno(connectionObject *self)
|
||||||
"executing an asynchronous operation."
|
"executing an asynchronous operation."
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_isexecuting(connectionObject *self)
|
psyco_conn_isexecuting(connectionObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
/* synchronous connections will always return False */
|
/* synchronous connections will always return False */
|
||||||
if (self->async == 0) {
|
if (self->async == 0) {
|
||||||
|
@ -866,7 +866,7 @@ psyco_conn_isexecuting(connectionObject *self)
|
||||||
"cancel() -- cancel the current operation"
|
"cancel() -- cancel the current operation"
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_cancel(connectionObject *self)
|
psyco_conn_cancel(connectionObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
char errbuf[256];
|
char errbuf[256];
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ struct cursorObject {
|
||||||
|
|
||||||
|
|
||||||
/* C-callable functions in cursor_int.c and cursor_ext.c */
|
/* C-callable functions in cursor_int.c and cursor_ext.c */
|
||||||
HIDDEN PyObject *curs_get_cast(cursorObject *self, PyObject *oid);
|
BORROWED HIDDEN PyObject *curs_get_cast(cursorObject *self, PyObject *oid);
|
||||||
HIDDEN void curs_reset(cursorObject *self);
|
HIDDEN void curs_reset(cursorObject *self);
|
||||||
|
|
||||||
/* exception-raising macros */
|
/* exception-raising macros */
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
* Return a borrowed reference.
|
* Return a borrowed reference.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PyObject *
|
BORROWED PyObject *
|
||||||
curs_get_cast(cursorObject *self, PyObject *oid)
|
curs_get_cast(cursorObject *self, PyObject *oid)
|
||||||
{
|
{
|
||||||
PyObject *cast;
|
PyObject *cast;
|
||||||
|
|
|
@ -79,7 +79,7 @@ exit:
|
||||||
|
|
||||||
/* mogrify a query string and build argument array or dict */
|
/* mogrify a query string and build argument array or dict */
|
||||||
|
|
||||||
static int
|
RAISES_NEG static int
|
||||||
_mogrify(PyObject *var, PyObject *fmt, cursorObject *curs, PyObject **new)
|
_mogrify(PyObject *var, PyObject *fmt, cursorObject *curs, PyObject **new)
|
||||||
{
|
{
|
||||||
PyObject *key, *value, *n;
|
PyObject *key, *value, *n;
|
||||||
|
@ -221,7 +221,10 @@ _mogrify(PyObject *var, PyObject *fmt, cursorObject *curs, PyObject **new)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n == NULL) {
|
if (n == NULL) {
|
||||||
n = PyTuple_New(PyObject_Length(var));
|
if (!(n = PyTuple_New(PyObject_Length(var)))) {
|
||||||
|
Py_DECREF(value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* let's have d point just after the '%' */
|
/* let's have d point just after the '%' */
|
||||||
|
@ -360,11 +363,12 @@ _psyco_curs_merge_query_args(cursorObject *self,
|
||||||
#define psyco_curs_execute_doc \
|
#define psyco_curs_execute_doc \
|
||||||
"execute(query, vars=None) -- Execute query with bound vars."
|
"execute(query, vars=None) -- Execute query with bound vars."
|
||||||
|
|
||||||
static int
|
RAISES_NEG static int
|
||||||
_psyco_curs_execute(cursorObject *self,
|
_psyco_curs_execute(cursorObject *self,
|
||||||
PyObject *operation, PyObject *vars, long int async)
|
PyObject *operation, PyObject *vars, long int async)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = -1;
|
||||||
|
int tmp;
|
||||||
PyObject *fquery, *cvt = NULL;
|
PyObject *fquery, *cvt = NULL;
|
||||||
|
|
||||||
operation = _psyco_curs_validate_sql_basic(self, operation);
|
operation = _psyco_curs_validate_sql_basic(self, operation);
|
||||||
|
@ -372,7 +376,7 @@ _psyco_curs_execute(cursorObject *self,
|
||||||
/* Any failure from here forward should 'goto fail' rather than 'return 0'
|
/* Any failure from here forward should 'goto fail' rather than 'return 0'
|
||||||
directly. */
|
directly. */
|
||||||
|
|
||||||
if (operation == NULL) { goto fail; }
|
if (operation == NULL) { goto exit; }
|
||||||
|
|
||||||
IFCLEARPGRES(self->pgres);
|
IFCLEARPGRES(self->pgres);
|
||||||
|
|
||||||
|
@ -389,12 +393,12 @@ _psyco_curs_execute(cursorObject *self,
|
||||||
|
|
||||||
if (vars && vars != Py_None)
|
if (vars && vars != Py_None)
|
||||||
{
|
{
|
||||||
if(_mogrify(vars, operation, self, &cvt) == -1) { goto fail; }
|
if (0 > _mogrify(vars, operation, self, &cvt)) { goto exit; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vars && cvt) {
|
if (vars && cvt) {
|
||||||
if (!(fquery = _psyco_curs_merge_query_args(self, operation, cvt))) {
|
if (!(fquery = _psyco_curs_merge_query_args(self, operation, cvt))) {
|
||||||
goto fail;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->name != NULL) {
|
if (self->name != NULL) {
|
||||||
|
@ -428,25 +432,20 @@ _psyco_curs_execute(cursorObject *self,
|
||||||
|
|
||||||
/* At this point, the SQL statement must be str, not unicode */
|
/* At this point, the SQL statement must be str, not unicode */
|
||||||
|
|
||||||
res = pq_execute(self, Bytes_AS_STRING(self->query), async);
|
tmp = pq_execute(self, Bytes_AS_STRING(self->query), async);
|
||||||
Dprintf("psyco_curs_execute: res = %d, pgres = %p", res, self->pgres);
|
Dprintf("psyco_curs_execute: res = %d, pgres = %p", tmp, self->pgres);
|
||||||
if (res == -1) { goto fail; }
|
if (tmp < 0) { goto exit; }
|
||||||
|
|
||||||
res = 1; /* Success */
|
res = 0; /* Success */
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
fail:
|
exit:
|
||||||
res = 0;
|
/* Py_XDECREF(operation) is safe because the original reference passed
|
||||||
/* Fall through to cleanup */
|
by the caller was overwritten with either NULL or a new
|
||||||
cleanup:
|
reference */
|
||||||
/* Py_XDECREF(operation) is safe because the original reference passed
|
Py_XDECREF(operation);
|
||||||
by the caller was overwritten with either NULL or a new
|
Py_XDECREF(cvt);
|
||||||
reference */
|
|
||||||
Py_XDECREF(operation);
|
|
||||||
|
|
||||||
Py_XDECREF(cvt);
|
return res;
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -480,13 +479,13 @@ psyco_curs_execute(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
EXC_IF_ASYNC_IN_PROGRESS(self, execute);
|
EXC_IF_ASYNC_IN_PROGRESS(self, execute);
|
||||||
EXC_IF_TPC_PREPARED(self->conn, execute);
|
EXC_IF_TPC_PREPARED(self->conn, execute);
|
||||||
|
|
||||||
if (_psyco_curs_execute(self, operation, vars, self->conn->async)) {
|
if (0 > _psyco_curs_execute(self, operation, vars, self->conn->async)) {
|
||||||
Py_INCREF(Py_None);
|
|
||||||
return Py_None;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define psyco_curs_executemany_doc \
|
#define psyco_curs_executemany_doc \
|
||||||
|
@ -525,7 +524,7 @@ psyco_curs_executemany(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((v = PyIter_Next(vars)) != NULL) {
|
while ((v = PyIter_Next(vars)) != NULL) {
|
||||||
if (_psyco_curs_execute(self, operation, v, 0) == 0) {
|
if (0 > _psyco_curs_execute(self, operation, v, 0)) {
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
Py_XDECREF(iter);
|
Py_XDECREF(iter);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -572,7 +571,7 @@ _psyco_curs_mogrify(cursorObject *self,
|
||||||
|
|
||||||
if (vars && vars != Py_None)
|
if (vars && vars != Py_None)
|
||||||
{
|
{
|
||||||
if (_mogrify(vars, operation, self, &cvt) == -1) {
|
if (0 > _mogrify(vars, operation, self, &cvt)) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -648,7 +647,7 @@ psyco_curs_cast(cursorObject *self, PyObject *args)
|
||||||
"default) or using the sequence factory previously set in the\n" \
|
"default) or using the sequence factory previously set in the\n" \
|
||||||
"`row_factory` attribute. Return `!None` when no more data is available.\n"
|
"`row_factory` attribute. Return `!None` when no more data is available.\n"
|
||||||
|
|
||||||
static int
|
RAISES_NEG static int
|
||||||
_psyco_curs_prefetch(cursorObject *self)
|
_psyco_curs_prefetch(cursorObject *self)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -665,13 +664,14 @@ _psyco_curs_prefetch(cursorObject *self)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
RAISES_NEG static int
|
||||||
_psyco_curs_buildrow_fill(cursorObject *self, PyObject *res,
|
_psyco_curs_buildrow_fill(cursorObject *self, PyObject *res,
|
||||||
int row, int n, int istuple)
|
int row, int n, int istuple)
|
||||||
{
|
{
|
||||||
int i, len, err;
|
int i, len, err;
|
||||||
const char *str;
|
const char *str;
|
||||||
PyObject *val;
|
PyObject *val;
|
||||||
|
int rv = -1;
|
||||||
|
|
||||||
for (i=0; i < n; i++) {
|
for (i=0; i < n; i++) {
|
||||||
if (PQgetisnull(self->pgres, row, i)) {
|
if (PQgetisnull(self->pgres, row, i)) {
|
||||||
|
@ -686,59 +686,59 @@ _psyco_curs_buildrow_fill(cursorObject *self, PyObject *res,
|
||||||
Dprintf("_psyco_curs_buildrow: row %ld, element %d, len %d",
|
Dprintf("_psyco_curs_buildrow: row %ld, element %d, len %d",
|
||||||
self->row, i, len);
|
self->row, i, len);
|
||||||
|
|
||||||
val = typecast_cast(PyTuple_GET_ITEM(self->casts, i), str, len,
|
if (!(val = typecast_cast(PyTuple_GET_ITEM(self->casts, i), str, len,
|
||||||
(PyObject*)self);
|
(PyObject*)self))) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
if (val) {
|
Dprintf("_psyco_curs_buildrow: val->refcnt = "
|
||||||
Dprintf("_psyco_curs_buildrow: val->refcnt = "
|
FORMAT_CODE_PY_SSIZE_T,
|
||||||
FORMAT_CODE_PY_SSIZE_T,
|
Py_REFCNT(val)
|
||||||
Py_REFCNT(val)
|
);
|
||||||
);
|
if (istuple) {
|
||||||
if (istuple) {
|
PyTuple_SET_ITEM(res, i, val);
|
||||||
PyTuple_SET_ITEM(res, i, val);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
err = PySequence_SetItem(res, i, val);
|
|
||||||
Py_DECREF(val);
|
|
||||||
if (err == -1) {
|
|
||||||
Py_DECREF(res);
|
|
||||||
res = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* an error occurred in the type system, we return NULL to raise
|
err = PySequence_SetItem(res, i, val);
|
||||||
an exception. the typecast code should already have set the
|
Py_DECREF(val);
|
||||||
exception type and text */
|
if (err == -1) { goto exit; }
|
||||||
Py_DECREF(res);
|
|
||||||
res = NULL;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
|
||||||
|
rv = 0;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_psyco_curs_buildrow(cursorObject *self, int row)
|
_psyco_curs_buildrow(cursorObject *self, int row)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
int istuple;
|
||||||
|
PyObject *t = NULL;
|
||||||
|
PyObject *rv = NULL;
|
||||||
|
|
||||||
n = PQnfields(self->pgres);
|
n = PQnfields(self->pgres);
|
||||||
return _psyco_curs_buildrow_fill(self, PyTuple_New(n), row, n, 1);
|
istuple = (self->tuple_factory == Py_None);
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
if (istuple) {
|
||||||
_psyco_curs_buildrow_with_factory(cursorObject *self, int row)
|
t = PyTuple_New(n);
|
||||||
{
|
}
|
||||||
int n;
|
else {
|
||||||
PyObject *res;
|
t = PyObject_CallFunctionObjArgs(self->tuple_factory, self, NULL);
|
||||||
|
}
|
||||||
|
if (!t) { goto exit; }
|
||||||
|
|
||||||
n = PQnfields(self->pgres);
|
if (0 <= _psyco_curs_buildrow_fill(self, t, row, n, istuple)) {
|
||||||
if (!(res = PyObject_CallFunctionObjArgs(self->tuple_factory, self, NULL)))
|
rv = t;
|
||||||
return NULL;
|
t = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
Py_XDECREF(t);
|
||||||
|
return rv;
|
||||||
|
|
||||||
return _psyco_curs_buildrow_fill(self, res, row, n, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -770,11 +770,7 @@ psyco_curs_fetchone(cursorObject *self, PyObject *args)
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->tuple_factory == Py_None)
|
res = _psyco_curs_buildrow(self, self->row);
|
||||||
res = _psyco_curs_buildrow(self, self->row);
|
|
||||||
else
|
|
||||||
res = _psyco_curs_buildrow_with_factory(self, self->row);
|
|
||||||
|
|
||||||
self->row++; /* move the counter to next line */
|
self->row++; /* move the counter to next line */
|
||||||
|
|
||||||
/* if the query was async aggresively free pgres, to allow
|
/* if the query was async aggresively free pgres, to allow
|
||||||
|
@ -821,11 +817,7 @@ psyco_curs_next_named(cursorObject *self)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->tuple_factory == Py_None)
|
res = _psyco_curs_buildrow(self, self->row);
|
||||||
res = _psyco_curs_buildrow(self, self->row);
|
|
||||||
else
|
|
||||||
res = _psyco_curs_buildrow_with_factory(self, self->row);
|
|
||||||
|
|
||||||
self->row++; /* move the counter to next line */
|
self->row++; /* move the counter to next line */
|
||||||
|
|
||||||
/* if the query was async aggresively free pgres, to allow
|
/* if the query was async aggresively free pgres, to allow
|
||||||
|
@ -852,7 +844,9 @@ static PyObject *
|
||||||
psyco_curs_fetchmany(cursorObject *self, PyObject *args, PyObject *kwords)
|
psyco_curs_fetchmany(cursorObject *self, PyObject *args, PyObject *kwords)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
PyObject *list, *res;
|
PyObject *list = NULL;
|
||||||
|
PyObject *row = NULL;
|
||||||
|
PyObject *rv = NULL;
|
||||||
|
|
||||||
PyObject *pysize = NULL;
|
PyObject *pysize = NULL;
|
||||||
long int size = self->arraysize;
|
long int size = self->arraysize;
|
||||||
|
@ -883,8 +877,8 @@ psyco_curs_fetchmany(cursorObject *self, PyObject *args, PyObject *kwords)
|
||||||
EXC_IF_TPC_PREPARED(self->conn, fetchone);
|
EXC_IF_TPC_PREPARED(self->conn, fetchone);
|
||||||
PyOS_snprintf(buffer, 127, "FETCH FORWARD %d FROM \"%s\"",
|
PyOS_snprintf(buffer, 127, "FETCH FORWARD %d FROM \"%s\"",
|
||||||
(int)size, self->name);
|
(int)size, self->name);
|
||||||
if (pq_execute(self, buffer, 0) == -1) return NULL;
|
if (pq_execute(self, buffer, 0) == -1) { goto exit; }
|
||||||
if (_psyco_curs_prefetch(self) < 0) return NULL;
|
if (_psyco_curs_prefetch(self) < 0) { goto exit; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make sure size is not > than the available number of rows */
|
/* make sure size is not > than the available number of rows */
|
||||||
|
@ -895,26 +889,21 @@ psyco_curs_fetchmany(cursorObject *self, PyObject *args, PyObject *kwords)
|
||||||
Dprintf("psyco_curs_fetchmany: size = %ld", size);
|
Dprintf("psyco_curs_fetchmany: size = %ld", size);
|
||||||
|
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
return PyList_New(0);
|
rv = PyList_New(0);
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
list = PyList_New(size);
|
if (!(list = PyList_New(size))) { goto exit; }
|
||||||
|
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
if (self->tuple_factory == Py_None)
|
row = _psyco_curs_buildrow(self, self->row);
|
||||||
res = _psyco_curs_buildrow(self, self->row);
|
|
||||||
else
|
|
||||||
res = _psyco_curs_buildrow_with_factory(self, self->row);
|
|
||||||
|
|
||||||
self->row++;
|
self->row++;
|
||||||
|
|
||||||
if (res == NULL) {
|
if (row == NULL) { goto exit; }
|
||||||
Py_DECREF(list);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyList_SET_ITEM(list, i, res);
|
PyList_SET_ITEM(list, i, row);
|
||||||
}
|
}
|
||||||
|
row = NULL;
|
||||||
|
|
||||||
/* if the query was async aggresively free pgres, to allow
|
/* if the query was async aggresively free pgres, to allow
|
||||||
successive requests to reallocate it */
|
successive requests to reallocate it */
|
||||||
|
@ -923,7 +912,15 @@ psyco_curs_fetchmany(cursorObject *self, PyObject *args, PyObject *kwords)
|
||||||
&& PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
|
&& PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
|
||||||
IFCLEARPGRES(self->pgres);
|
IFCLEARPGRES(self->pgres);
|
||||||
|
|
||||||
return list;
|
/* success */
|
||||||
|
rv = list;
|
||||||
|
list = NULL;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
Py_XDECREF(list);
|
||||||
|
Py_XDECREF(row);
|
||||||
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -940,7 +937,9 @@ static PyObject *
|
||||||
psyco_curs_fetchall(cursorObject *self, PyObject *args)
|
psyco_curs_fetchall(cursorObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
int i, size;
|
int i, size;
|
||||||
PyObject *list, *res;
|
PyObject *list = NULL;
|
||||||
|
PyObject *row = NULL;
|
||||||
|
PyObject *rv = NULL;
|
||||||
|
|
||||||
EXC_IF_CURS_CLOSED(self);
|
EXC_IF_CURS_CLOSED(self);
|
||||||
if (_psyco_curs_prefetch(self) < 0) return NULL;
|
if (_psyco_curs_prefetch(self) < 0) return NULL;
|
||||||
|
@ -953,33 +952,27 @@ psyco_curs_fetchall(cursorObject *self, PyObject *args)
|
||||||
EXC_IF_ASYNC_IN_PROGRESS(self, fetchall);
|
EXC_IF_ASYNC_IN_PROGRESS(self, fetchall);
|
||||||
EXC_IF_TPC_PREPARED(self->conn, fetchall);
|
EXC_IF_TPC_PREPARED(self->conn, fetchall);
|
||||||
PyOS_snprintf(buffer, 127, "FETCH FORWARD ALL FROM \"%s\"", self->name);
|
PyOS_snprintf(buffer, 127, "FETCH FORWARD ALL FROM \"%s\"", self->name);
|
||||||
if (pq_execute(self, buffer, 0) == -1) return NULL;
|
if (pq_execute(self, buffer, 0) == -1) { goto exit; }
|
||||||
if (_psyco_curs_prefetch(self) < 0) return NULL;
|
if (_psyco_curs_prefetch(self) < 0) { goto exit; }
|
||||||
}
|
}
|
||||||
|
|
||||||
size = self->rowcount - self->row;
|
size = self->rowcount - self->row;
|
||||||
|
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
return PyList_New(0);
|
rv = PyList_New(0);
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
list = PyList_New(size);
|
if (!(list = PyList_New(size))) { goto exit; }
|
||||||
|
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
if (self->tuple_factory == Py_None)
|
row = _psyco_curs_buildrow(self, self->row);
|
||||||
res = _psyco_curs_buildrow(self, self->row);
|
|
||||||
else
|
|
||||||
res = _psyco_curs_buildrow_with_factory(self, self->row);
|
|
||||||
|
|
||||||
self->row++;
|
self->row++;
|
||||||
|
if (row == NULL) { goto exit; }
|
||||||
|
|
||||||
if (res == NULL) {
|
PyList_SET_ITEM(list, i, row);
|
||||||
Py_DECREF(list);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyList_SET_ITEM(list, i, res);
|
|
||||||
}
|
}
|
||||||
|
row = NULL;
|
||||||
|
|
||||||
/* if the query was async aggresively free pgres, to allow
|
/* if the query was async aggresively free pgres, to allow
|
||||||
successive requests to reallocate it */
|
successive requests to reallocate it */
|
||||||
|
@ -988,7 +981,15 @@ psyco_curs_fetchall(cursorObject *self, PyObject *args)
|
||||||
&& PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
|
&& PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
|
||||||
IFCLEARPGRES(self->pgres);
|
IFCLEARPGRES(self->pgres);
|
||||||
|
|
||||||
return list;
|
/* success */
|
||||||
|
rv = list;
|
||||||
|
list = NULL;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
Py_XDECREF(list);
|
||||||
|
Py_XDECREF(row);
|
||||||
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -998,7 +999,7 @@ psyco_curs_fetchall(cursorObject *self, PyObject *args)
|
||||||
"callproc(procname, parameters=None) -- Execute stored procedure."
|
"callproc(procname, parameters=None) -- Execute stored procedure."
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_curs_callproc(cursorObject *self, PyObject *args, PyObject *kwargs)
|
psyco_curs_callproc(cursorObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
const char *procname = NULL;
|
const char *procname = NULL;
|
||||||
char *sql = NULL;
|
char *sql = NULL;
|
||||||
|
@ -1010,7 +1011,7 @@ psyco_curs_callproc(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
if (!PyArg_ParseTuple(args, "s#|O",
|
if (!PyArg_ParseTuple(args, "s#|O",
|
||||||
&procname, &procname_len, ¶meters
|
&procname, &procname_len, ¶meters
|
||||||
))
|
))
|
||||||
{ return NULL; }
|
{ goto exit; }
|
||||||
|
|
||||||
EXC_IF_CURS_CLOSED(self);
|
EXC_IF_CURS_CLOSED(self);
|
||||||
EXC_IF_ASYNC_IN_PROGRESS(self, callproc);
|
EXC_IF_ASYNC_IN_PROGRESS(self, callproc);
|
||||||
|
@ -1019,10 +1020,10 @@ psyco_curs_callproc(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
if (self->name != NULL) {
|
if (self->name != NULL) {
|
||||||
psyco_set_error(ProgrammingError, self,
|
psyco_set_error(ProgrammingError, self,
|
||||||
"can't call .callproc() on named cursors", NULL, NULL);
|
"can't call .callproc() on named cursors", NULL, NULL);
|
||||||
return NULL;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(parameters != Py_None) {
|
if (parameters != Py_None) {
|
||||||
nparameters = PyObject_Length(parameters);
|
nparameters = PyObject_Length(parameters);
|
||||||
if (nparameters < 0) nparameters = 0;
|
if (nparameters < 0) nparameters = 0;
|
||||||
}
|
}
|
||||||
|
@ -1031,7 +1032,8 @@ psyco_curs_callproc(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
sl = procname_len + 17 + nparameters*3 - (nparameters ? 1 : 0);
|
sl = procname_len + 17 + nparameters*3 - (nparameters ? 1 : 0);
|
||||||
sql = (char*)PyMem_Malloc(sl);
|
sql = (char*)PyMem_Malloc(sl);
|
||||||
if (sql == NULL) {
|
if (sql == NULL) {
|
||||||
return PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(sql, "SELECT * FROM %s(", procname);
|
sprintf(sql, "SELECT * FROM %s(", procname);
|
||||||
|
@ -1041,15 +1043,16 @@ psyco_curs_callproc(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
sql[sl-2] = ')';
|
sql[sl-2] = ')';
|
||||||
sql[sl-1] = '\0';
|
sql[sl-1] = '\0';
|
||||||
|
|
||||||
operation = Bytes_FromString(sql);
|
if (!(operation = Bytes_FromString(sql))) { goto exit; }
|
||||||
PyMem_Free((void*)sql);
|
|
||||||
|
|
||||||
if (_psyco_curs_execute(self, operation, parameters, self->conn->async)) {
|
if (0 <= _psyco_curs_execute(self, operation, parameters, self->conn->async)) {
|
||||||
Py_INCREF(parameters);
|
Py_INCREF(parameters);
|
||||||
res = parameters;
|
res = parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_DECREF(operation);
|
exit:
|
||||||
|
Py_XDECREF(operation);
|
||||||
|
PyMem_Free((void*)sql);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1206,6 +1209,7 @@ static char *_psyco_curs_copy_columns(PyObject *columns)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL == (columnlist = PyMem_Malloc(bufsize))) {
|
if (NULL == (columnlist = PyMem_Malloc(bufsize))) {
|
||||||
|
Py_DECREF(coliter);
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -1262,8 +1266,8 @@ exit:
|
||||||
#define psyco_curs_copy_from_doc \
|
#define psyco_curs_copy_from_doc \
|
||||||
"copy_from(file, table, sep='\\t', null='\\\\N', size=8192, columns=None) -- Copy table from file."
|
"copy_from(file, table, sep='\\t', null='\\\\N', size=8192, columns=None) -- Copy table from file."
|
||||||
|
|
||||||
static int
|
STEALS(1) static int
|
||||||
_psyco_curs_has_read_check(PyObject* o, void* var)
|
_psyco_curs_has_read_check(PyObject *o, PyObject **var)
|
||||||
{
|
{
|
||||||
if (PyObject_HasAttrString(o, "readline")
|
if (PyObject_HasAttrString(o, "readline")
|
||||||
&& PyObject_HasAttrString(o, "read")) {
|
&& PyObject_HasAttrString(o, "read")) {
|
||||||
|
@ -1273,7 +1277,7 @@ _psyco_curs_has_read_check(PyObject* o, void* var)
|
||||||
* which could invoke the garbage collector. We thus need an
|
* which could invoke the garbage collector. We thus need an
|
||||||
* INCREF/DECREF pair if we store this pointer in a GC object, such as
|
* INCREF/DECREF pair if we store this pointer in a GC object, such as
|
||||||
* a cursorObject */
|
* a cursorObject */
|
||||||
*((PyObject**)var) = o;
|
*var = o;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1348,7 +1352,7 @@ psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
Py_INCREF(file);
|
Py_INCREF(file);
|
||||||
self->copyfile = file;
|
self->copyfile = file;
|
||||||
|
|
||||||
if (pq_execute(self, query, 0) == 1) {
|
if (pq_execute(self, query, 0) >= 0) {
|
||||||
res = Py_None;
|
res = Py_None;
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
}
|
}
|
||||||
|
@ -1369,11 +1373,11 @@ exit:
|
||||||
#define psyco_curs_copy_to_doc \
|
#define psyco_curs_copy_to_doc \
|
||||||
"copy_to(file, table, sep='\\t', null='\\\\N', columns=None) -- Copy table to file."
|
"copy_to(file, table, sep='\\t', null='\\\\N', columns=None) -- Copy table to file."
|
||||||
|
|
||||||
static int
|
STEALS(1) static int
|
||||||
_psyco_curs_has_write_check(PyObject* o, void* var)
|
_psyco_curs_has_write_check(PyObject *o, PyObject **var)
|
||||||
{
|
{
|
||||||
if (PyObject_HasAttrString(o, "write")) {
|
if (PyObject_HasAttrString(o, "write")) {
|
||||||
*((PyObject**)var) = o;
|
*var = o;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1444,7 +1448,7 @@ psyco_curs_copy_to(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
Py_INCREF(file);
|
Py_INCREF(file);
|
||||||
self->copyfile = file;
|
self->copyfile = file;
|
||||||
|
|
||||||
if (pq_execute(self, query, 0) == 1) {
|
if (pq_execute(self, query, 0) >= 0) {
|
||||||
res = Py_None;
|
res = Py_None;
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
}
|
}
|
||||||
|
@ -1518,7 +1522,7 @@ psyco_curs_copy_expert(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
self->copyfile = file;
|
self->copyfile = file;
|
||||||
|
|
||||||
/* At this point, the SQL statement must be str, not unicode */
|
/* At this point, the SQL statement must be str, not unicode */
|
||||||
if (pq_execute(self, Bytes_AS_STRING(sql), 0) == 1) {
|
if (pq_execute(self, Bytes_AS_STRING(sql), 0) >= 0) {
|
||||||
res = Py_None;
|
res = Py_None;
|
||||||
Py_INCREF(res);
|
Py_INCREF(res);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,19 +51,19 @@ typedef struct {
|
||||||
|
|
||||||
/* functions exported from lobject_int.c */
|
/* functions exported from lobject_int.c */
|
||||||
|
|
||||||
HIDDEN int lobject_open(lobjectObject *self, connectionObject *conn,
|
RAISES_NEG HIDDEN int lobject_open(lobjectObject *self, connectionObject *conn,
|
||||||
Oid oid, const char *smode, Oid new_oid,
|
Oid oid, const char *smode, Oid new_oid,
|
||||||
const char *new_file);
|
const char *new_file);
|
||||||
HIDDEN int lobject_unlink(lobjectObject *self);
|
RAISES_NEG HIDDEN int lobject_unlink(lobjectObject *self);
|
||||||
HIDDEN int lobject_export(lobjectObject *self, const char *filename);
|
RAISES_NEG HIDDEN int lobject_export(lobjectObject *self, const char *filename);
|
||||||
|
|
||||||
HIDDEN Py_ssize_t lobject_read(lobjectObject *self, char *buf, size_t len);
|
RAISES_NEG HIDDEN Py_ssize_t lobject_read(lobjectObject *self, char *buf, size_t len);
|
||||||
HIDDEN Py_ssize_t lobject_write(lobjectObject *self, const char *buf,
|
RAISES_NEG HIDDEN Py_ssize_t lobject_write(lobjectObject *self, const char *buf,
|
||||||
size_t len);
|
size_t len);
|
||||||
HIDDEN int lobject_seek(lobjectObject *self, int pos, int whence);
|
RAISES_NEG HIDDEN int lobject_seek(lobjectObject *self, int pos, int whence);
|
||||||
HIDDEN int lobject_tell(lobjectObject *self);
|
RAISES_NEG HIDDEN int lobject_tell(lobjectObject *self);
|
||||||
HIDDEN int lobject_truncate(lobjectObject *self, size_t len);
|
RAISES_NEG HIDDEN int lobject_truncate(lobjectObject *self, size_t len);
|
||||||
HIDDEN int lobject_close(lobjectObject *self);
|
RAISES_NEG HIDDEN int lobject_close(lobjectObject *self);
|
||||||
|
|
||||||
#define lobject_is_closed(self) \
|
#define lobject_is_closed(self) \
|
||||||
((self)->fd < 0 || !(self)->conn || (self)->conn->closed)
|
((self)->fd < 0 || !(self)->conn || (self)->conn->closed)
|
||||||
|
|
|
@ -50,7 +50,7 @@ collect_error(connectionObject *conn, char **error)
|
||||||
*
|
*
|
||||||
* Valid mode are [r|w|rw|n][t|b]
|
* Valid mode are [r|w|rw|n][t|b]
|
||||||
*/
|
*/
|
||||||
static int
|
RAISES_NEG static int
|
||||||
_lobject_parse_mode(const char *mode)
|
_lobject_parse_mode(const char *mode)
|
||||||
{
|
{
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
@ -147,7 +147,7 @@ _lobject_unparse_mode(int mode)
|
||||||
|
|
||||||
/* lobject_open - create a new/open an existing lo */
|
/* lobject_open - create a new/open an existing lo */
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
lobject_open(lobjectObject *self, connectionObject *conn,
|
lobject_open(lobjectObject *self, connectionObject *conn,
|
||||||
Oid oid, const char *smode, Oid new_oid, const char *new_file)
|
Oid oid, const char *smode, Oid new_oid, const char *new_file)
|
||||||
{
|
{
|
||||||
|
@ -237,7 +237,7 @@ lobject_open(lobjectObject *self, connectionObject *conn,
|
||||||
|
|
||||||
/* lobject_close - close an existing lo */
|
/* lobject_close - close an existing lo */
|
||||||
|
|
||||||
static int
|
RAISES_NEG static int
|
||||||
lobject_close_locked(lobjectObject *self, char **error)
|
lobject_close_locked(lobjectObject *self, char **error)
|
||||||
{
|
{
|
||||||
int retvalue;
|
int retvalue;
|
||||||
|
@ -270,7 +270,7 @@ lobject_close_locked(lobjectObject *self, char **error)
|
||||||
return retvalue;
|
return retvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
lobject_close(lobjectObject *self)
|
lobject_close(lobjectObject *self)
|
||||||
{
|
{
|
||||||
PGresult *pgres = NULL;
|
PGresult *pgres = NULL;
|
||||||
|
@ -292,7 +292,7 @@ lobject_close(lobjectObject *self)
|
||||||
|
|
||||||
/* lobject_unlink - remove an lo from database */
|
/* lobject_unlink - remove an lo from database */
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
lobject_unlink(lobjectObject *self)
|
lobject_unlink(lobjectObject *self)
|
||||||
{
|
{
|
||||||
PGresult *pgres = NULL;
|
PGresult *pgres = NULL;
|
||||||
|
@ -326,7 +326,7 @@ lobject_unlink(lobjectObject *self)
|
||||||
|
|
||||||
/* lobject_write - write bytes to a lo */
|
/* lobject_write - write bytes to a lo */
|
||||||
|
|
||||||
Py_ssize_t
|
RAISES_NEG Py_ssize_t
|
||||||
lobject_write(lobjectObject *self, const char *buf, size_t len)
|
lobject_write(lobjectObject *self, const char *buf, size_t len)
|
||||||
{
|
{
|
||||||
Py_ssize_t written;
|
Py_ssize_t written;
|
||||||
|
@ -353,7 +353,7 @@ lobject_write(lobjectObject *self, const char *buf, size_t len)
|
||||||
|
|
||||||
/* lobject_read - read bytes from a lo */
|
/* lobject_read - read bytes from a lo */
|
||||||
|
|
||||||
Py_ssize_t
|
RAISES_NEG Py_ssize_t
|
||||||
lobject_read(lobjectObject *self, char *buf, size_t len)
|
lobject_read(lobjectObject *self, char *buf, size_t len)
|
||||||
{
|
{
|
||||||
Py_ssize_t n_read;
|
Py_ssize_t n_read;
|
||||||
|
@ -377,7 +377,7 @@ lobject_read(lobjectObject *self, char *buf, size_t len)
|
||||||
|
|
||||||
/* lobject_seek - move the current position in the lo */
|
/* lobject_seek - move the current position in the lo */
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
lobject_seek(lobjectObject *self, int pos, int whence)
|
lobject_seek(lobjectObject *self, int pos, int whence)
|
||||||
{
|
{
|
||||||
PGresult *pgres = NULL;
|
PGresult *pgres = NULL;
|
||||||
|
@ -405,7 +405,7 @@ lobject_seek(lobjectObject *self, int pos, int whence)
|
||||||
|
|
||||||
/* lobject_tell - tell the current position in the lo */
|
/* lobject_tell - tell the current position in the lo */
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
lobject_tell(lobjectObject *self)
|
lobject_tell(lobjectObject *self)
|
||||||
{
|
{
|
||||||
PGresult *pgres = NULL;
|
PGresult *pgres = NULL;
|
||||||
|
@ -432,7 +432,7 @@ lobject_tell(lobjectObject *self)
|
||||||
|
|
||||||
/* lobject_export - export to a local file */
|
/* lobject_export - export to a local file */
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
lobject_export(lobjectObject *self, const char *filename)
|
lobject_export(lobjectObject *self, const char *filename)
|
||||||
{
|
{
|
||||||
PGresult *pgres = NULL;
|
PGresult *pgres = NULL;
|
||||||
|
@ -461,7 +461,7 @@ lobject_export(lobjectObject *self, const char *filename)
|
||||||
|
|
||||||
#if PG_VERSION_HEX >= 0x080300
|
#if PG_VERSION_HEX >= 0x080300
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
lobject_truncate(lobjectObject *self, size_t len)
|
lobject_truncate(lobjectObject *self, size_t len)
|
||||||
{
|
{
|
||||||
int retvalue;
|
int retvalue;
|
||||||
|
|
|
@ -373,7 +373,7 @@ lobject_dealloc(PyObject* obj)
|
||||||
static int
|
static int
|
||||||
lobject_init(PyObject *obj, PyObject *args, PyObject *kwds)
|
lobject_init(PyObject *obj, PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
Oid oid=InvalidOid, new_oid=InvalidOid;
|
int oid = (int)InvalidOid, new_oid = (int)InvalidOid;
|
||||||
const char *smode = "";
|
const char *smode = "";
|
||||||
const char *new_file = NULL;
|
const char *new_file = NULL;
|
||||||
PyObject *conn;
|
PyObject *conn;
|
||||||
|
@ -383,7 +383,7 @@ lobject_init(PyObject *obj, PyObject *args, PyObject *kwds)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return lobject_setup((lobjectObject *)obj,
|
return lobject_setup((lobjectObject *)obj,
|
||||||
(connectionObject *)conn, oid, smode, new_oid, new_file);
|
(connectionObject *)conn, (Oid)oid, smode, (Oid)new_oid, new_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
|
@ -52,29 +52,35 @@ microprotocols_init(PyObject *dict)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* microprotocols_add - add a reverse type-caster to the dictionary */
|
/* microprotocols_add - add a reverse type-caster to the dictionary
|
||||||
|
*
|
||||||
|
* Return 0 on success, else -1 and set an exception.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
|
microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
|
||||||
{
|
{
|
||||||
PyObject *key;
|
PyObject *key = NULL;
|
||||||
|
int rv = -1;
|
||||||
|
|
||||||
if (proto == NULL) proto = (PyObject*)&isqlquoteType;
|
if (proto == NULL) proto = (PyObject*)&isqlquoteType;
|
||||||
|
|
||||||
Dprintf("microprotocols_add: cast %p for (%s, ?)", cast, type->tp_name);
|
Dprintf("microprotocols_add: cast %p for (%s, ?)", cast, type->tp_name);
|
||||||
|
|
||||||
key = PyTuple_Pack(2, (PyObject*)type, proto);
|
if (!(key = PyTuple_Pack(2, (PyObject*)type, proto))) { goto exit; }
|
||||||
PyDict_SetItem(psyco_adapters, key, cast);
|
if (0 != PyDict_SetItem(psyco_adapters, key, cast)) { goto exit; }
|
||||||
Py_DECREF(key);
|
|
||||||
|
|
||||||
return 0;
|
rv = 0;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
Py_XDECREF(key);
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if one of `obj` superclasses has an adapter for `proto`.
|
/* Check if one of `obj` superclasses has an adapter for `proto`.
|
||||||
*
|
*
|
||||||
* If it does, return a *borrowed reference* to the adapter, else NULL.
|
* If it does, return a *borrowed reference* to the adapter, else to None.
|
||||||
*/
|
*/
|
||||||
static PyObject *
|
BORROWED static PyObject *
|
||||||
_get_superclass_adapter(PyObject *obj, PyObject *proto)
|
_get_superclass_adapter(PyObject *obj, PyObject *proto)
|
||||||
{
|
{
|
||||||
PyTypeObject *type;
|
PyTypeObject *type;
|
||||||
|
@ -89,14 +95,14 @@ _get_superclass_adapter(PyObject *obj, PyObject *proto)
|
||||||
#endif
|
#endif
|
||||||
type->tp_mro)) {
|
type->tp_mro)) {
|
||||||
/* has no mro */
|
/* has no mro */
|
||||||
return NULL;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Walk the mro from the most specific subclass. */
|
/* Walk the mro from the most specific subclass. */
|
||||||
mro = type->tp_mro;
|
mro = type->tp_mro;
|
||||||
for (i = 1, ii = PyTuple_GET_SIZE(mro); i < ii; ++i) {
|
for (i = 1, ii = PyTuple_GET_SIZE(mro); i < ii; ++i) {
|
||||||
st = PyTuple_GET_ITEM(mro, i);
|
st = PyTuple_GET_ITEM(mro, i);
|
||||||
key = PyTuple_Pack(2, st, proto);
|
if (!(key = PyTuple_Pack(2, st, proto))) { return NULL; }
|
||||||
adapter = PyDict_GetItem(psyco_adapters, key);
|
adapter = PyDict_GetItem(psyco_adapters, key);
|
||||||
Py_DECREF(key);
|
Py_DECREF(key);
|
||||||
|
|
||||||
|
@ -119,7 +125,7 @@ _get_superclass_adapter(PyObject *obj, PyObject *proto)
|
||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -139,7 +145,7 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
|
||||||
Py_TYPE(obj)->tp_name);
|
Py_TYPE(obj)->tp_name);
|
||||||
|
|
||||||
/* look for an adapter in the registry */
|
/* look for an adapter in the registry */
|
||||||
key = PyTuple_Pack(2, Py_TYPE(obj), proto);
|
if (!(key = PyTuple_Pack(2, Py_TYPE(obj), proto))) { return NULL; }
|
||||||
adapter = PyDict_GetItem(psyco_adapters, key);
|
adapter = PyDict_GetItem(psyco_adapters, key);
|
||||||
Py_DECREF(key);
|
Py_DECREF(key);
|
||||||
if (adapter) {
|
if (adapter) {
|
||||||
|
@ -148,7 +154,10 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if a superclass can be adapted and use the same adapter. */
|
/* Check if a superclass can be adapted and use the same adapter. */
|
||||||
if (NULL != (adapter = _get_superclass_adapter(obj, proto))) {
|
if (!(adapter = _get_superclass_adapter(obj, proto))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (Py_None != adapter) {
|
||||||
adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
|
adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
|
||||||
return adapted;
|
return adapted;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ strip_severity(const char *msg)
|
||||||
code. A list of error codes can be found at:
|
code. A list of error codes can be found at:
|
||||||
|
|
||||||
http://www.postgresql.org/docs/current/static/errcodes-appendix.html */
|
http://www.postgresql.org/docs/current/static/errcodes-appendix.html */
|
||||||
static PyObject *
|
BORROWED static PyObject *
|
||||||
exception_from_sqlstate(const char *sqlstate)
|
exception_from_sqlstate(const char *sqlstate)
|
||||||
{
|
{
|
||||||
switch (sqlstate[0]) {
|
switch (sqlstate[0]) {
|
||||||
|
@ -151,7 +151,7 @@ exception_from_sqlstate(const char *sqlstate)
|
||||||
|
|
||||||
This function should be called while holding the GIL. */
|
This function should be called while holding the GIL. */
|
||||||
|
|
||||||
static void
|
RAISES static void
|
||||||
pq_raise(connectionObject *conn, cursorObject *curs, PGresult *pgres)
|
pq_raise(connectionObject *conn, cursorObject *curs, PGresult *pgres)
|
||||||
{
|
{
|
||||||
PyObject *exc = NULL;
|
PyObject *exc = NULL;
|
||||||
|
@ -164,7 +164,7 @@ pq_raise(connectionObject *conn, cursorObject *curs, PGresult *pgres)
|
||||||
"psycopg went psycotic and raised a null error");
|
"psycopg went psycotic and raised a null error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if the connection has somehow beed broken, we mark the connection
|
/* if the connection has somehow beed broken, we mark the connection
|
||||||
object as closed but requiring cleanup */
|
object as closed but requiring cleanup */
|
||||||
if (conn->pgconn != NULL && PQstatus(conn->pgconn) == CONNECTION_BAD)
|
if (conn->pgconn != NULL && PQstatus(conn->pgconn) == CONNECTION_BAD)
|
||||||
|
@ -249,7 +249,9 @@ pq_clear_critical(connectionObject *conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
/* return -1 if the exception is set (i.e. if conn->critical is set),
|
||||||
|
* else 0 */
|
||||||
|
RAISES_NEG static int
|
||||||
pq_resolve_critical(connectionObject *conn, int close)
|
pq_resolve_critical(connectionObject *conn, int close)
|
||||||
{
|
{
|
||||||
Dprintf("pq_resolve_critical: resolving %s", conn->critical);
|
Dprintf("pq_resolve_critical: resolving %s", conn->critical);
|
||||||
|
@ -264,11 +266,13 @@ pq_resolve_critical(connectionObject *conn, int close)
|
||||||
|
|
||||||
/* we don't want to destroy this connection but just close it */
|
/* we don't want to destroy this connection but just close it */
|
||||||
if (close == 1) conn_close(conn);
|
if (close == 1) conn_close(conn);
|
||||||
|
|
||||||
/* remember to clear the critical! */
|
/* remember to clear the critical! */
|
||||||
pq_clear_critical(conn);
|
pq_clear_critical(conn);
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pq_clear_async - clear the effects of a previous async query
|
/* pq_clear_async - clear the effects of a previous async query
|
||||||
|
@ -300,19 +304,16 @@ pq_clear_async(connectionObject *conn)
|
||||||
|
|
||||||
Accepted arg values are 1 (nonblocking) and 0 (blocking).
|
Accepted arg values are 1 (nonblocking) and 0 (blocking).
|
||||||
|
|
||||||
Return 0 if everything ok, else nonzero.
|
Return 0 if everything ok, else < 0 and set an exception.
|
||||||
|
|
||||||
In case of error, if pyerr is nonzero, set a Python exception.
|
|
||||||
*/
|
*/
|
||||||
int
|
RAISES_NEG int
|
||||||
pq_set_non_blocking(connectionObject *conn, int arg, int pyerr)
|
pq_set_non_blocking(connectionObject *conn, int arg)
|
||||||
{
|
{
|
||||||
int ret = PQsetnonblocking(conn->pgconn, arg);
|
int ret = PQsetnonblocking(conn->pgconn, arg);
|
||||||
if (0 != ret) {
|
if (0 != ret) {
|
||||||
Dprintf("PQsetnonblocking(%d) FAILED", arg);
|
Dprintf("PQsetnonblocking(%d) FAILED", arg);
|
||||||
if (pyerr) {
|
PyErr_SetString(OperationalError, "PQsetnonblocking() failed");
|
||||||
PyErr_SetString(OperationalError, "PQsetnonblocking() failed");
|
ret = -1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -382,7 +383,7 @@ cleanup:
|
||||||
This function should be called while holding the global interpreter
|
This function should be called while holding the global interpreter
|
||||||
lock.
|
lock.
|
||||||
*/
|
*/
|
||||||
void
|
RAISES void
|
||||||
pq_complete_error(connectionObject *conn, PGresult **pgres, char **error)
|
pq_complete_error(connectionObject *conn, PGresult **pgres, char **error)
|
||||||
{
|
{
|
||||||
Dprintf("pq_complete_error: pgconn = %p, pgres = %p, error = %s",
|
Dprintf("pq_complete_error: pgconn = %p, pgres = %p, error = %s",
|
||||||
|
@ -476,7 +477,7 @@ pq_commit(connectionObject *conn)
|
||||||
return retvalue;
|
return retvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
pq_abort_locked(connectionObject *conn, PGresult **pgres, char **error,
|
pq_abort_locked(connectionObject *conn, PGresult **pgres, char **error,
|
||||||
PyThreadState **tstate)
|
PyThreadState **tstate)
|
||||||
{
|
{
|
||||||
|
@ -503,7 +504,7 @@ pq_abort_locked(connectionObject *conn, PGresult **pgres, char **error,
|
||||||
This function should be called while holding the global interpreter
|
This function should be called while holding the global interpreter
|
||||||
lock. */
|
lock. */
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
pq_abort(connectionObject *conn)
|
pq_abort(connectionObject *conn)
|
||||||
{
|
{
|
||||||
int retvalue = -1;
|
int retvalue = -1;
|
||||||
|
@ -540,7 +541,7 @@ pq_abort(connectionObject *conn)
|
||||||
connection without holding the global interpreter lock.
|
connection without holding the global interpreter lock.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
pq_reset_locked(connectionObject *conn, PGresult **pgres, char **error,
|
pq_reset_locked(connectionObject *conn, PGresult **pgres, char **error,
|
||||||
PyThreadState **tstate)
|
PyThreadState **tstate)
|
||||||
{
|
{
|
||||||
|
@ -832,7 +833,7 @@ pq_flush(connectionObject *conn)
|
||||||
this fucntion locks the connection object
|
this fucntion locks the connection object
|
||||||
this function call Py_*_ALLOW_THREADS macros */
|
this function call Py_*_ALLOW_THREADS macros */
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
pq_execute(cursorObject *curs, const char *query, int async)
|
pq_execute(cursorObject *curs, const char *query, int async)
|
||||||
{
|
{
|
||||||
PGresult *pgres = NULL;
|
PGresult *pgres = NULL;
|
||||||
|
@ -842,8 +843,7 @@ pq_execute(cursorObject *curs, const char *query, int async)
|
||||||
/* if the status of the connection is critical raise an exception and
|
/* if the status of the connection is critical raise an exception and
|
||||||
definitely close the connection */
|
definitely close the connection */
|
||||||
if (curs->conn->critical) {
|
if (curs->conn->critical) {
|
||||||
pq_resolve_critical(curs->conn, 1);
|
return pq_resolve_critical(curs->conn, 1);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check status of connection, raise error if not OK */
|
/* check status of connection, raise error if not OK */
|
||||||
|
@ -938,12 +938,13 @@ pq_execute(cursorObject *curs, const char *query, int async)
|
||||||
to respect the old DBAPI-2.0 compatible behaviour */
|
to respect the old DBAPI-2.0 compatible behaviour */
|
||||||
if (async == 0) {
|
if (async == 0) {
|
||||||
Dprintf("pq_execute: entering syncronous DBAPI compatibility mode");
|
Dprintf("pq_execute: entering syncronous DBAPI compatibility mode");
|
||||||
if (pq_fetch(curs) == -1) return -1;
|
if (pq_fetch(curs) < 0) return -1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
PyObject *tmp;
|
||||||
curs->conn->async_status = async_status;
|
curs->conn->async_status = async_status;
|
||||||
curs->conn->async_cursor = PyWeakref_NewRef((PyObject *)curs, NULL);
|
curs->conn->async_cursor = tmp = PyWeakref_NewRef((PyObject *)curs, NULL);
|
||||||
if (!curs->conn->async_cursor) {
|
if (!tmp) {
|
||||||
/* weakref creation failed */
|
/* weakref creation failed */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1012,7 +1013,7 @@ pq_get_last_result(connectionObject *conn)
|
||||||
1 - result from backend (possibly data is ready)
|
1 - result from backend (possibly data is ready)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
RAISES_NEG static int
|
||||||
_pq_fetch_tuples(cursorObject *curs)
|
_pq_fetch_tuples(cursorObject *curs)
|
||||||
{
|
{
|
||||||
int i, *dsize = NULL;
|
int i, *dsize = NULL;
|
||||||
|
@ -1412,8 +1413,7 @@ pq_fetch(cursorObject *curs)
|
||||||
Dprintf("pq_fetch: got a NULL pgres, checking for critical");
|
Dprintf("pq_fetch: got a NULL pgres, checking for critical");
|
||||||
pq_set_critical(curs->conn);
|
pq_set_critical(curs->conn);
|
||||||
if (curs->conn->critical) {
|
if (curs->conn->critical) {
|
||||||
pq_resolve_critical(curs->conn);
|
return pq_resolve_critical(curs->conn);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1489,13 +1489,7 @@ pq_fetch(cursorObject *curs)
|
||||||
raise the exception but we avoid to close the connection) */
|
raise the exception but we avoid to close the connection) */
|
||||||
Dprintf("pq_fetch: fetching done; check for critical errors");
|
Dprintf("pq_fetch: fetching done; check for critical errors");
|
||||||
if (curs->conn->critical) {
|
if (curs->conn->critical) {
|
||||||
if (ex == -1) {
|
return pq_resolve_critical(curs->conn, ex == -1 ? 1 : 0);
|
||||||
pq_resolve_critical(curs->conn, 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pq_resolve_critical(curs->conn, 0);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ex;
|
return ex;
|
||||||
|
|
|
@ -35,18 +35,18 @@
|
||||||
|
|
||||||
/* exported functions */
|
/* exported functions */
|
||||||
HIDDEN PGresult *pq_get_last_result(connectionObject *conn);
|
HIDDEN PGresult *pq_get_last_result(connectionObject *conn);
|
||||||
HIDDEN int pq_fetch(cursorObject *curs);
|
RAISES_NEG HIDDEN int pq_fetch(cursorObject *curs);
|
||||||
HIDDEN int pq_execute(cursorObject *curs, const char *query, int async);
|
RAISES_NEG HIDDEN int pq_execute(cursorObject *curs, const char *query, int async);
|
||||||
HIDDEN int pq_send_query(connectionObject *conn, const char *query);
|
HIDDEN int pq_send_query(connectionObject *conn, const char *query);
|
||||||
HIDDEN int pq_begin_locked(connectionObject *conn, PGresult **pgres,
|
HIDDEN int pq_begin_locked(connectionObject *conn, PGresult **pgres,
|
||||||
char **error, PyThreadState **tstate);
|
char **error, PyThreadState **tstate);
|
||||||
HIDDEN int pq_commit(connectionObject *conn);
|
HIDDEN int pq_commit(connectionObject *conn);
|
||||||
HIDDEN int pq_abort_locked(connectionObject *conn, PGresult **pgres,
|
RAISES_NEG HIDDEN int pq_abort_locked(connectionObject *conn, PGresult **pgres,
|
||||||
char **error, PyThreadState **tstate);
|
char **error, PyThreadState **tstate);
|
||||||
HIDDEN int pq_abort(connectionObject *conn);
|
RAISES_NEG HIDDEN int pq_abort(connectionObject *conn);
|
||||||
HIDDEN int pq_reset_locked(connectionObject *conn, PGresult **pgres,
|
HIDDEN int pq_reset_locked(connectionObject *conn, PGresult **pgres,
|
||||||
char **error, PyThreadState **tstate);
|
char **error, PyThreadState **tstate);
|
||||||
HIDDEN int pq_reset(connectionObject *conn);
|
RAISES_NEG HIDDEN int pq_reset(connectionObject *conn);
|
||||||
HIDDEN char *pq_get_guc_locked(connectionObject *conn, const char *param,
|
HIDDEN char *pq_get_guc_locked(connectionObject *conn, const char *param,
|
||||||
PGresult **pgres,
|
PGresult **pgres,
|
||||||
char **error, PyThreadState **tstate);
|
char **error, PyThreadState **tstate);
|
||||||
|
@ -61,7 +61,7 @@ HIDDEN int pq_is_busy(connectionObject *conn);
|
||||||
HIDDEN int pq_is_busy_locked(connectionObject *conn);
|
HIDDEN int pq_is_busy_locked(connectionObject *conn);
|
||||||
HIDDEN int pq_flush(connectionObject *conn);
|
HIDDEN int pq_flush(connectionObject *conn);
|
||||||
HIDDEN void pq_clear_async(connectionObject *conn);
|
HIDDEN void pq_clear_async(connectionObject *conn);
|
||||||
HIDDEN int pq_set_non_blocking(connectionObject *conn, int arg, int pyerr);
|
RAISES_NEG HIDDEN int pq_set_non_blocking(connectionObject *conn, int arg);
|
||||||
|
|
||||||
HIDDEN void pq_set_critical(connectionObject *conn, const char *msg);
|
HIDDEN void pq_set_critical(connectionObject *conn, const char *msg);
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ HIDDEN int pq_execute_command_locked(connectionObject *conn,
|
||||||
const char *query,
|
const char *query,
|
||||||
PGresult **pgres, char **error,
|
PGresult **pgres, char **error,
|
||||||
PyThreadState **tstate);
|
PyThreadState **tstate);
|
||||||
HIDDEN void pq_complete_error(connectionObject *conn, PGresult **pgres,
|
RAISES HIDDEN void pq_complete_error(connectionObject *conn, PGresult **pgres,
|
||||||
char **error);
|
char **error);
|
||||||
|
|
||||||
#endif /* !defined(PSYCOPG_PQPATH_H) */
|
#endif /* !defined(PSYCOPG_PQPATH_H) */
|
||||||
|
|
|
@ -120,17 +120,19 @@ HIDDEN PyObject *psyco_GetDecimalType(void);
|
||||||
typedef struct cursorObject cursorObject;
|
typedef struct cursorObject cursorObject;
|
||||||
|
|
||||||
/* some utility functions */
|
/* some utility functions */
|
||||||
HIDDEN void psyco_set_error(PyObject *exc, cursorObject *curs, const char *msg,
|
RAISES HIDDEN void psyco_set_error(PyObject *exc, cursorObject *curs, const char *msg,
|
||||||
const char *pgerror, const char *pgcode);
|
const char *pgerror, const char *pgcode);
|
||||||
|
|
||||||
HIDDEN char *psycopg_escape_string(PyObject *conn,
|
HIDDEN char *psycopg_escape_string(PyObject *conn,
|
||||||
const char *from, Py_ssize_t len, char *to, Py_ssize_t *tolen);
|
const char *from, Py_ssize_t len, char *to, Py_ssize_t *tolen);
|
||||||
HIDDEN char *psycopg_escape_identifier_easy(const char *from, Py_ssize_t len);
|
HIDDEN char *psycopg_escape_identifier_easy(const char *from, Py_ssize_t len);
|
||||||
HIDDEN char *psycopg_strdup(const char *from, Py_ssize_t len);
|
HIDDEN int psycopg_strdup(char **to, const char *from, Py_ssize_t len);
|
||||||
HIDDEN PyObject * psycopg_ensure_bytes(PyObject *obj);
|
|
||||||
HIDDEN PyObject * psycopg_ensure_text(PyObject *obj);
|
|
||||||
HIDDEN int psycopg_is_text_file(PyObject *f);
|
HIDDEN int psycopg_is_text_file(PyObject *f);
|
||||||
|
|
||||||
|
STEALS(1) HIDDEN PyObject * psycopg_ensure_bytes(PyObject *obj);
|
||||||
|
|
||||||
|
STEALS(1) HIDDEN PyObject * psycopg_ensure_text(PyObject *obj);
|
||||||
|
|
||||||
/* Exceptions docstrings */
|
/* Exceptions docstrings */
|
||||||
#define Error_doc \
|
#define Error_doc \
|
||||||
"Base class for error exceptions."
|
"Base class for error exceptions."
|
||||||
|
|
|
@ -143,14 +143,6 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
|
||||||
" * `name`: Name for the new type\n" \
|
" * `name`: Name for the new type\n" \
|
||||||
" * `baseobj`: Adapter to perform type conversion of a single array item."
|
" * `baseobj`: Adapter to perform type conversion of a single array item."
|
||||||
|
|
||||||
static void
|
|
||||||
_psyco_register_type_set(PyObject **dict, PyObject *type)
|
|
||||||
{
|
|
||||||
if (*dict == NULL)
|
|
||||||
*dict = PyDict_New();
|
|
||||||
typecast_add(type, *dict, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_register_type(PyObject *self, PyObject *args)
|
psyco_register_type(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
@ -162,10 +154,16 @@ psyco_register_type(PyObject *self, PyObject *args)
|
||||||
|
|
||||||
if (obj != NULL && obj != Py_None) {
|
if (obj != NULL && obj != Py_None) {
|
||||||
if (PyObject_TypeCheck(obj, &cursorType)) {
|
if (PyObject_TypeCheck(obj, &cursorType)) {
|
||||||
_psyco_register_type_set(&(((cursorObject*)obj)->string_types), type);
|
PyObject **dict = &(((cursorObject*)obj)->string_types);
|
||||||
|
if (*dict == NULL) {
|
||||||
|
if (!(*dict = PyDict_New())) { return NULL; }
|
||||||
|
}
|
||||||
|
if (0 > typecast_add(type, *dict, 0)) { return NULL; }
|
||||||
}
|
}
|
||||||
else if (PyObject_TypeCheck(obj, &connectionType)) {
|
else if (PyObject_TypeCheck(obj, &connectionType)) {
|
||||||
typecast_add(type, ((connectionObject*)obj)->string_types, 0);
|
if (0 > typecast_add(type, ((connectionObject*)obj)->string_types, 0)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
@ -174,7 +172,7 @@ psyco_register_type(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
typecast_add(type, NULL, 0);
|
if (0 > typecast_add(type, NULL, 0)) { return NULL; }
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
|
@ -182,66 +180,108 @@ psyco_register_type(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* default adapters */
|
/* Initialize the default adapters map
|
||||||
|
*
|
||||||
static void
|
* Return 0 on success, else -1 and set an exception.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
psyco_adapters_init(PyObject *mod)
|
psyco_adapters_init(PyObject *mod)
|
||||||
{
|
{
|
||||||
PyObject *call;
|
PyObject *call = NULL;
|
||||||
|
int rv = -1;
|
||||||
|
|
||||||
microprotocols_add(&PyFloat_Type, NULL, (PyObject*)&pfloatType);
|
if (0 != microprotocols_add(&PyFloat_Type, NULL, (PyObject*)&pfloatType)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
#if PY_MAJOR_VERSION < 3
|
#if PY_MAJOR_VERSION < 3
|
||||||
microprotocols_add(&PyInt_Type, NULL, (PyObject*)&pintType);
|
if (0 != microprotocols_add(&PyInt_Type, NULL, (PyObject*)&pintType)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
microprotocols_add(&PyLong_Type, NULL, (PyObject*)&pintType);
|
if (0 != microprotocols_add(&PyLong_Type, NULL, (PyObject*)&pintType)) {
|
||||||
microprotocols_add(&PyBool_Type, NULL, (PyObject*)&pbooleanType);
|
goto exit;
|
||||||
|
}
|
||||||
|
if (0 != microprotocols_add(&PyBool_Type, NULL, (PyObject*)&pbooleanType)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
/* strings */
|
/* strings */
|
||||||
#if PY_MAJOR_VERSION < 3
|
#if PY_MAJOR_VERSION < 3
|
||||||
microprotocols_add(&PyString_Type, NULL, (PyObject*)&qstringType);
|
if (0 != microprotocols_add(&PyString_Type, NULL, (PyObject*)&qstringType)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
microprotocols_add(&PyUnicode_Type, NULL, (PyObject*)&qstringType);
|
if (0 != microprotocols_add(&PyUnicode_Type, NULL, (PyObject*)&qstringType)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
/* binary */
|
/* binary */
|
||||||
#if PY_MAJOR_VERSION < 3
|
#if PY_MAJOR_VERSION < 3
|
||||||
microprotocols_add(&PyBuffer_Type, NULL, (PyObject*)&binaryType);
|
if (0 != microprotocols_add(&PyBuffer_Type, NULL, (PyObject*)&binaryType)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
microprotocols_add(&PyBytes_Type, NULL, (PyObject*)&binaryType);
|
if (0 != microprotocols_add(&PyBytes_Type, NULL, (PyObject*)&binaryType)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3 || PY_MINOR_VERSION >= 6
|
#if PY_MAJOR_VERSION >= 3 || PY_MINOR_VERSION >= 6
|
||||||
microprotocols_add(&PyByteArray_Type, NULL, (PyObject*)&binaryType);
|
if (0 != microprotocols_add(&PyByteArray_Type, NULL, (PyObject*)&binaryType)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if PY_MAJOR_VERSION >= 3 || PY_MINOR_VERSION >= 7
|
#if PY_MAJOR_VERSION >= 3 || PY_MINOR_VERSION >= 7
|
||||||
microprotocols_add(&PyMemoryView_Type, NULL, (PyObject*)&binaryType);
|
if (0 != microprotocols_add(&PyMemoryView_Type, NULL, (PyObject*)&binaryType)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
microprotocols_add(&PyList_Type, NULL, (PyObject*)&listType);
|
if (0 != microprotocols_add(&PyList_Type, NULL, (PyObject*)&listType)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
/* the module has already been initialized, so we can obtain the callable
|
/* the module has already been initialized, so we can obtain the callable
|
||||||
objects directly from its dictionary :) */
|
objects directly from its dictionary :) */
|
||||||
call = PyMapping_GetItemString(mod, "DateFromPy");
|
if (!(call = PyMapping_GetItemString(mod, "DateFromPy"))) { goto exit; }
|
||||||
microprotocols_add(PyDateTimeAPI->DateType, NULL, call);
|
if (0 != microprotocols_add(PyDateTimeAPI->DateType, NULL, call)) { goto exit; }
|
||||||
call = PyMapping_GetItemString(mod, "TimeFromPy");
|
Py_CLEAR(call);
|
||||||
microprotocols_add(PyDateTimeAPI->TimeType, NULL, call);
|
|
||||||
call = PyMapping_GetItemString(mod, "TimestampFromPy");
|
if (!(call = PyMapping_GetItemString(mod, "TimeFromPy"))) { goto exit; }
|
||||||
microprotocols_add(PyDateTimeAPI->DateTimeType, NULL, call);
|
if (0 != microprotocols_add(PyDateTimeAPI->TimeType, NULL, call)) { goto exit; }
|
||||||
call = PyMapping_GetItemString(mod, "IntervalFromPy");
|
Py_CLEAR(call);
|
||||||
microprotocols_add(PyDateTimeAPI->DeltaType, NULL, call);
|
|
||||||
|
if (!(call = PyMapping_GetItemString(mod, "TimestampFromPy"))) { goto exit; }
|
||||||
|
if (0 != microprotocols_add(PyDateTimeAPI->DateTimeType, NULL, call)) { goto exit; }
|
||||||
|
Py_CLEAR(call);
|
||||||
|
|
||||||
|
if (!(call = PyMapping_GetItemString(mod, "IntervalFromPy"))) { goto exit; }
|
||||||
|
if (0 != microprotocols_add(PyDateTimeAPI->DeltaType, NULL, call)) { goto exit; }
|
||||||
|
Py_CLEAR(call);
|
||||||
|
|
||||||
#ifdef HAVE_MXDATETIME
|
#ifdef HAVE_MXDATETIME
|
||||||
/* as above, we use the callable objects from the psycopg module */
|
/* as above, we use the callable objects from the psycopg module */
|
||||||
if (NULL != (call = PyMapping_GetItemString(mod, "TimestampFromMx"))) {
|
if (NULL != (call = PyMapping_GetItemString(mod, "TimestampFromMx"))) {
|
||||||
microprotocols_add(mxDateTime.DateTime_Type, NULL, call);
|
if (0 != microprotocols_add(mxDateTime.DateTime_Type, NULL, call)) { goto exit; }
|
||||||
|
Py_CLEAR(call);
|
||||||
|
|
||||||
/* if we found the above, we have this too. */
|
/* if we found the above, we have this too. */
|
||||||
call = PyMapping_GetItemString(mod, "TimeFromMx");
|
if (!(call = PyMapping_GetItemString(mod, "TimeFromMx"))) { goto exit; }
|
||||||
microprotocols_add(mxDateTime.DateTimeDelta_Type, NULL, call);
|
if (0 != microprotocols_add(mxDateTime.DateTimeDelta_Type, NULL, call)) { goto exit; }
|
||||||
|
Py_CLEAR(call);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Success! */
|
||||||
|
rv = 0;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
Py_XDECREF(call);
|
||||||
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* psyco_encodings_fill
|
/* psyco_encodings_fill
|
||||||
|
@ -326,15 +366,27 @@ static encodingPair encodings[] = {
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void psyco_encodings_fill(PyObject *dict)
|
/* Initialize the encodings table.
|
||||||
|
*
|
||||||
|
* Return 0 on success, else -1 and set an exception.
|
||||||
|
*/
|
||||||
|
static int psyco_encodings_fill(PyObject *dict)
|
||||||
{
|
{
|
||||||
|
PyObject *value = NULL;
|
||||||
encodingPair *enc;
|
encodingPair *enc;
|
||||||
|
int rv = -1;
|
||||||
|
|
||||||
for (enc = encodings; enc->pgenc != NULL; enc++) {
|
for (enc = encodings; enc->pgenc != NULL; enc++) {
|
||||||
PyObject *value = Text_FromUTF8(enc->pyenc);
|
if (!(value = Text_FromUTF8(enc->pyenc))) { goto exit; }
|
||||||
PyDict_SetItemString(dict, enc->pgenc, value);
|
if (0 != PyDict_SetItemString(dict, enc->pgenc, value)) { goto exit; }
|
||||||
Py_DECREF(value);
|
Py_CLEAR(value);
|
||||||
}
|
}
|
||||||
|
rv = 0;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
Py_XDECREF(value);
|
||||||
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* psyco_errors_init, psyco_errors_fill (callable from C)
|
/* psyco_errors_init, psyco_errors_fill (callable from C)
|
||||||
|
@ -440,21 +492,22 @@ psyco_errors_init(void)
|
||||||
live in _psycopg */
|
live in _psycopg */
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
PyObject *dict;
|
PyObject *dict = NULL;
|
||||||
PyObject *base;
|
PyObject *base;
|
||||||
PyObject *str;
|
PyObject *str = NULL;
|
||||||
PyObject *descr;
|
PyObject *descr = NULL;
|
||||||
int rv = -1;
|
int rv = -1;
|
||||||
|
|
||||||
static PyMethodDef psyco_error_reduce_ex_def =
|
static PyMethodDef psyco_error_reduce_ex_def =
|
||||||
{"__reduce_ex__", psyco_error_reduce_ex, METH_VARARGS, "pickle helper"};
|
{"__reduce_ex__", psyco_error_reduce_ex, METH_VARARGS, "pickle helper"};
|
||||||
|
|
||||||
for (i=0; exctable[i].name; i++) {
|
for (i=0; exctable[i].name; i++) {
|
||||||
dict = PyDict_New();
|
if (!(dict = PyDict_New())) { goto exit; }
|
||||||
|
|
||||||
if (exctable[i].docstr) {
|
if (exctable[i].docstr) {
|
||||||
str = Text_FromUTF8(exctable[i].docstr);
|
if (!(str = Text_FromUTF8(exctable[i].docstr))) { goto exit; }
|
||||||
PyDict_SetItemString(dict, "__doc__", str);
|
if (0 != PyDict_SetItemString(dict, "__doc__", str)) { goto exit; }
|
||||||
|
Py_CLEAR(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exctable[i].base == 0) {
|
if (exctable[i].base == 0) {
|
||||||
|
@ -468,7 +521,11 @@ psyco_errors_init(void)
|
||||||
else
|
else
|
||||||
base = *exctable[i].base;
|
base = *exctable[i].base;
|
||||||
|
|
||||||
*exctable[i].exc = PyErr_NewException(exctable[i].name, base, dict);
|
if (!(*exctable[i].exc = PyErr_NewException(
|
||||||
|
exctable[i].name, base, dict))) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
Py_CLEAR(dict);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make pgerror, pgcode and cursor default to None on psycopg
|
/* Make pgerror, pgcode and cursor default to None on psycopg
|
||||||
|
@ -492,60 +549,56 @@ psyco_errors_init(void)
|
||||||
psyco_error_reduce_ex_def.ml_name, descr)) {
|
psyco_error_reduce_ex_def.ml_name, descr)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
Py_DECREF(descr);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rv = 0;
|
rv = 0;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
Py_XDECREF(descr);
|
||||||
|
Py_XDECREF(str);
|
||||||
|
Py_XDECREF(dict);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
psyco_errors_fill(PyObject *dict)
|
psyco_errors_fill(PyObject *dict)
|
||||||
{
|
{
|
||||||
PyDict_SetItemString(dict, "Error", Error);
|
int i;
|
||||||
PyDict_SetItemString(dict, "Warning", Warning);
|
char *name;
|
||||||
PyDict_SetItemString(dict, "InterfaceError", InterfaceError);
|
|
||||||
PyDict_SetItemString(dict, "DatabaseError", DatabaseError);
|
for (i = 0; exctable[i].name; i++) {
|
||||||
PyDict_SetItemString(dict, "InternalError", InternalError);
|
if (NULL == exctable[i].exc) { continue; }
|
||||||
PyDict_SetItemString(dict, "OperationalError", OperationalError);
|
|
||||||
PyDict_SetItemString(dict, "ProgrammingError", ProgrammingError);
|
/* the name is the part after the last dot */
|
||||||
PyDict_SetItemString(dict, "IntegrityError", IntegrityError);
|
name = strrchr(exctable[i].name, '.');
|
||||||
PyDict_SetItemString(dict, "DataError", DataError);
|
name = name ? name + 1 : exctable[i].name;
|
||||||
PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError);
|
|
||||||
#ifdef PSYCOPG_EXTENSIONS
|
PyDict_SetItemString(dict, name, *exctable[i].exc);
|
||||||
PyDict_SetItemString(dict, "QueryCanceledError", QueryCanceledError);
|
}
|
||||||
PyDict_SetItemString(dict, "TransactionRollbackError",
|
|
||||||
TransactionRollbackError);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
psyco_errors_set(PyObject *type)
|
psyco_errors_set(PyObject *type)
|
||||||
{
|
{
|
||||||
PyObject_SetAttrString(type, "Error", Error);
|
int i;
|
||||||
PyObject_SetAttrString(type, "Warning", Warning);
|
char *name;
|
||||||
PyObject_SetAttrString(type, "InterfaceError", InterfaceError);
|
|
||||||
PyObject_SetAttrString(type, "DatabaseError", DatabaseError);
|
for (i = 0; exctable[i].name; i++) {
|
||||||
PyObject_SetAttrString(type, "InternalError", InternalError);
|
if (NULL == exctable[i].exc) { continue; }
|
||||||
PyObject_SetAttrString(type, "OperationalError", OperationalError);
|
|
||||||
PyObject_SetAttrString(type, "ProgrammingError", ProgrammingError);
|
/* the name is the part after the last dot */
|
||||||
PyObject_SetAttrString(type, "IntegrityError", IntegrityError);
|
name = strrchr(exctable[i].name, '.');
|
||||||
PyObject_SetAttrString(type, "DataError", DataError);
|
name = name ? name + 1 : exctable[i].name;
|
||||||
PyObject_SetAttrString(type, "NotSupportedError", NotSupportedError);
|
|
||||||
#ifdef PSYCOPG_EXTENSIONS
|
PyObject_SetAttrString(type, name, *exctable[i].exc);
|
||||||
PyObject_SetAttrString(type, "QueryCanceledError", QueryCanceledError);
|
}
|
||||||
PyObject_SetAttrString(type, "TransactionRollbackError",
|
|
||||||
TransactionRollbackError);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* psyco_error_new
|
/* psyco_set_error
|
||||||
|
|
||||||
Create a new error of the given type with extra attributes. */
|
Create a new error of the given type with extra attributes. */
|
||||||
|
|
||||||
void
|
RAISES void
|
||||||
psyco_set_error(PyObject *exc, cursorObject *curs, const char *msg,
|
psyco_set_error(PyObject *exc, cursorObject *curs, const char *msg,
|
||||||
const char *pgerror, const char *pgcode)
|
const char *pgerror, const char *pgcode)
|
||||||
{
|
{
|
||||||
|
@ -574,15 +627,17 @@ psyco_set_error(PyObject *exc, cursorObject *curs, const char *msg,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pgerror) {
|
if (pgerror) {
|
||||||
t = conn_text_from_chars(conn, pgerror);
|
if ((t = conn_text_from_chars(conn, pgerror))) {
|
||||||
PyObject_SetAttrString(err, "pgerror", t);
|
PyObject_SetAttrString(err, "pgerror", t);
|
||||||
Py_DECREF(t);
|
Py_DECREF(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pgcode) {
|
if (pgcode) {
|
||||||
t = conn_text_from_chars(conn, pgcode);
|
if ((t = conn_text_from_chars(conn, pgcode))) {
|
||||||
PyObject_SetAttrString(err, "pgcode", t);
|
PyObject_SetAttrString(err, "pgcode", t);
|
||||||
Py_DECREF(t);
|
Py_DECREF(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PyErr_SetObject(exc, err);
|
PyErr_SetObject(exc, err);
|
||||||
|
@ -649,7 +704,7 @@ psyco_GetDecimalType(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the object from future uses. */
|
/* Store the object from future uses. */
|
||||||
if (can_cache && !cachedType) {
|
if (can_cache && !cachedType && decimalType) {
|
||||||
Py_INCREF(decimalType);
|
Py_INCREF(decimalType);
|
||||||
cachedType = decimalType;
|
cachedType = decimalType;
|
||||||
}
|
}
|
||||||
|
@ -673,15 +728,11 @@ psyco_make_description_type(void)
|
||||||
/* Try to import collections.namedtuple */
|
/* Try to import collections.namedtuple */
|
||||||
if (!(coll = PyImport_ImportModule("collections"))) {
|
if (!(coll = PyImport_ImportModule("collections"))) {
|
||||||
Dprintf("psyco_make_description_type: collections import failed");
|
Dprintf("psyco_make_description_type: collections import failed");
|
||||||
PyErr_Clear();
|
goto error;
|
||||||
rv = Py_None;
|
|
||||||
goto exit;
|
|
||||||
}
|
}
|
||||||
if (!(nt = PyObject_GetAttrString(coll, "namedtuple"))) {
|
if (!(nt = PyObject_GetAttrString(coll, "namedtuple"))) {
|
||||||
Dprintf("psyco_make_description_type: no collections.namedtuple");
|
Dprintf("psyco_make_description_type: no collections.namedtuple");
|
||||||
PyErr_Clear();
|
goto error;
|
||||||
rv = Py_None;
|
|
||||||
goto exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build the namedtuple */
|
/* Build the namedtuple */
|
||||||
|
@ -693,6 +744,13 @@ exit:
|
||||||
Py_XDECREF(nt);
|
Py_XDECREF(nt);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
|
error:
|
||||||
|
/* controlled error: we will fall back to regular tuples. Return None. */
|
||||||
|
PyErr_Clear();
|
||||||
|
rv = Py_None;
|
||||||
|
Py_INCREF(rv);
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -905,10 +963,10 @@ INIT_MODULE(_psycopg)(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* other mixed initializations of module-level variables */
|
/* other mixed initializations of module-level variables */
|
||||||
psycoEncodings = PyDict_New();
|
if (!(psycoEncodings = PyDict_New())) { goto exit; }
|
||||||
psyco_encodings_fill(psycoEncodings);
|
if (0 != psyco_encodings_fill(psycoEncodings)) { goto exit; }
|
||||||
psyco_null = Bytes_FromString("NULL");
|
psyco_null = Bytes_FromString("NULL");
|
||||||
psyco_DescriptionType = psyco_make_description_type();
|
if (!(psyco_DescriptionType = psyco_make_description_type())) { goto exit; }
|
||||||
|
|
||||||
/* set some module's parameters */
|
/* set some module's parameters */
|
||||||
PyModule_AddStringConstant(module, "__version__", PSYCOPG_VERSION);
|
PyModule_AddStringConstant(module, "__version__", PSYCOPG_VERSION);
|
||||||
|
@ -941,11 +999,11 @@ INIT_MODULE(_psycopg)(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* initialize default set of typecasters */
|
/* initialize default set of typecasters */
|
||||||
typecast_init(dict);
|
if (0 != typecast_init(dict)) { goto exit; }
|
||||||
|
|
||||||
/* initialize microprotocols layer */
|
/* initialize microprotocols layer */
|
||||||
microprotocols_init(dict);
|
microprotocols_init(dict);
|
||||||
psyco_adapters_init(dict);
|
if (0 != psyco_adapters_init(dict)) { goto exit; }
|
||||||
|
|
||||||
/* create a standard set of exceptions and add them to the module's dict */
|
/* create a standard set of exceptions and add them to the module's dict */
|
||||||
if (0 != psyco_errors_init()) { goto exit; }
|
if (0 != psyco_errors_init()) { goto exit; }
|
||||||
|
|
|
@ -250,34 +250,28 @@ PyObject *psyco_default_binary_cast;
|
||||||
|
|
||||||
/* typecast_init - initialize the dictionary and create default types */
|
/* typecast_init - initialize the dictionary and create default types */
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
typecast_init(PyObject *dict)
|
typecast_init(PyObject *dict)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int rv = -1;
|
||||||
|
typecastObject *t = NULL;
|
||||||
|
|
||||||
/* create type dictionary and put it in module namespace */
|
/* create type dictionary and put it in module namespace */
|
||||||
psyco_types = PyDict_New();
|
if (!(psyco_types = PyDict_New())) { goto exit; }
|
||||||
psyco_binary_types = PyDict_New();
|
|
||||||
|
|
||||||
if (!psyco_types || !psyco_binary_types) {
|
|
||||||
Py_XDECREF(psyco_types);
|
|
||||||
Py_XDECREF(psyco_binary_types);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyDict_SetItemString(dict, "string_types", psyco_types);
|
PyDict_SetItemString(dict, "string_types", psyco_types);
|
||||||
|
|
||||||
|
if (!(psyco_binary_types = PyDict_New())) { goto exit; }
|
||||||
PyDict_SetItemString(dict, "binary_types", psyco_binary_types);
|
PyDict_SetItemString(dict, "binary_types", psyco_binary_types);
|
||||||
|
|
||||||
/* insert the cast types into the 'types' dictionary and register them in
|
/* insert the cast types into the 'types' dictionary and register them in
|
||||||
the module dictionary */
|
the module dictionary */
|
||||||
for (i = 0; typecast_builtins[i].name != NULL; i++) {
|
for (i = 0; typecast_builtins[i].name != NULL; i++) {
|
||||||
typecastObject *t;
|
|
||||||
|
|
||||||
Dprintf("typecast_init: initializing %s", typecast_builtins[i].name);
|
Dprintf("typecast_init: initializing %s", typecast_builtins[i].name);
|
||||||
|
|
||||||
t = (typecastObject *)typecast_from_c(&(typecast_builtins[i]), dict);
|
t = (typecastObject *)typecast_from_c(&(typecast_builtins[i]), dict);
|
||||||
if (t == NULL) return -1;
|
if (t == NULL) { goto exit; }
|
||||||
if (typecast_add((PyObject *)t, NULL, 0) != 0) return -1;
|
if (typecast_add((PyObject *)t, NULL, 0) < 0) { goto exit; }
|
||||||
|
|
||||||
PyDict_SetItem(dict, t->name, (PyObject *)t);
|
PyDict_SetItem(dict, t->name, (PyObject *)t);
|
||||||
|
|
||||||
|
@ -285,6 +279,8 @@ typecast_init(PyObject *dict)
|
||||||
if (typecast_builtins[i].values == typecast_BINARY_types) {
|
if (typecast_builtins[i].values == typecast_BINARY_types) {
|
||||||
psyco_default_binary_cast = (PyObject *)t;
|
psyco_default_binary_cast = (PyObject *)t;
|
||||||
}
|
}
|
||||||
|
Py_DECREF((PyObject *)t);
|
||||||
|
t = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create and save a default cast object (but does not register it) */
|
/* create and save a default cast object (but does not register it) */
|
||||||
|
@ -294,29 +290,35 @@ typecast_init(PyObject *dict)
|
||||||
#ifdef HAVE_MXDATETIME
|
#ifdef HAVE_MXDATETIME
|
||||||
if (0 == psyco_typecast_mxdatetime_init()) {
|
if (0 == psyco_typecast_mxdatetime_init()) {
|
||||||
for (i = 0; typecast_mxdatetime[i].name != NULL; i++) {
|
for (i = 0; typecast_mxdatetime[i].name != NULL; i++) {
|
||||||
typecastObject *t;
|
|
||||||
Dprintf("typecast_init: initializing %s", typecast_mxdatetime[i].name);
|
Dprintf("typecast_init: initializing %s", typecast_mxdatetime[i].name);
|
||||||
t = (typecastObject *)typecast_from_c(&(typecast_mxdatetime[i]), dict);
|
t = (typecastObject *)typecast_from_c(&(typecast_mxdatetime[i]), dict);
|
||||||
if (t == NULL) return -1;
|
if (t == NULL) { goto exit; }
|
||||||
PyDict_SetItem(dict, t->name, (PyObject *)t);
|
PyDict_SetItem(dict, t->name, (PyObject *)t);
|
||||||
|
Py_DECREF((PyObject *)t);
|
||||||
|
t = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (psyco_typecast_datetime_init()) { return -1; }
|
if (0 > psyco_typecast_datetime_init()) { goto exit; }
|
||||||
for (i = 0; typecast_pydatetime[i].name != NULL; i++) {
|
for (i = 0; typecast_pydatetime[i].name != NULL; i++) {
|
||||||
typecastObject *t;
|
|
||||||
Dprintf("typecast_init: initializing %s", typecast_pydatetime[i].name);
|
Dprintf("typecast_init: initializing %s", typecast_pydatetime[i].name);
|
||||||
t = (typecastObject *)typecast_from_c(&(typecast_pydatetime[i]), dict);
|
t = (typecastObject *)typecast_from_c(&(typecast_pydatetime[i]), dict);
|
||||||
if (t == NULL) return -1;
|
if (t == NULL) { goto exit; }
|
||||||
PyDict_SetItem(dict, t->name, (PyObject *)t);
|
PyDict_SetItem(dict, t->name, (PyObject *)t);
|
||||||
|
Py_DECREF((PyObject *)t);
|
||||||
|
t = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
rv = 0;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
Py_XDECREF((PyObject *)t);
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* typecast_add - add a type object to the dictionary */
|
/* typecast_add - add a type object to the dictionary */
|
||||||
int
|
RAISES_NEG int
|
||||||
typecast_add(PyObject *obj, PyObject *dict, int binary)
|
typecast_add(PyObject *obj, PyObject *dict, int binary)
|
||||||
{
|
{
|
||||||
PyObject *val;
|
PyObject *val;
|
||||||
|
@ -466,7 +468,7 @@ typecast_repr(PyObject *self)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typecast_call(PyObject *obj, PyObject *args, PyObject *kwargs)
|
typecast_call(PyObject *obj, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
char *string;
|
const char *string;
|
||||||
Py_ssize_t length;
|
Py_ssize_t length;
|
||||||
PyObject *cursor;
|
PyObject *cursor;
|
||||||
|
|
||||||
|
|
|
@ -71,8 +71,8 @@ extern HIDDEN PyObject *psyco_default_binary_cast;
|
||||||
/** exported functions **/
|
/** exported functions **/
|
||||||
|
|
||||||
/* used by module.c to init the type system and register types */
|
/* used by module.c to init the type system and register types */
|
||||||
HIDDEN int typecast_init(PyObject *dict);
|
RAISES_NEG HIDDEN int typecast_init(PyObject *dict);
|
||||||
HIDDEN int typecast_add(PyObject *obj, PyObject *dict, int binary);
|
RAISES_NEG HIDDEN int typecast_add(PyObject *obj, PyObject *dict, int binary);
|
||||||
|
|
||||||
/* the C callable typecastObject creator function */
|
/* the C callable typecastObject creator function */
|
||||||
HIDDEN PyObject *typecast_from_c(typecastObject_initlist *type, PyObject *d);
|
HIDDEN PyObject *typecast_from_c(typecastObject_initlist *type, PyObject *d);
|
||||||
|
|
|
@ -166,7 +166,7 @@ typecast_array_tokenize(const char *str, Py_ssize_t strlength,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
RAISES_NEG static int
|
||||||
typecast_array_scan(const char *str, Py_ssize_t strlength,
|
typecast_array_scan(const char *str, Py_ssize_t strlength,
|
||||||
PyObject *curs, PyObject *base, PyObject *array)
|
PyObject *curs, PyObject *base, PyObject *array)
|
||||||
{
|
{
|
||||||
|
@ -199,7 +199,7 @@ typecast_array_scan(const char *str, Py_ssize_t strlength,
|
||||||
|
|
||||||
/* before anything else we free the memory */
|
/* before anything else we free the memory */
|
||||||
if (state == ASCAN_QUOTED) PyMem_Free(token);
|
if (state == ASCAN_QUOTED) PyMem_Free(token);
|
||||||
if (obj == NULL) return 0;
|
if (obj == NULL) return -1;
|
||||||
|
|
||||||
PyList_Append(array, obj);
|
PyList_Append(array, obj);
|
||||||
Py_DECREF(obj);
|
Py_DECREF(obj);
|
||||||
|
@ -207,25 +207,25 @@ typecast_array_scan(const char *str, Py_ssize_t strlength,
|
||||||
|
|
||||||
else if (state == ASCAN_BEGIN) {
|
else if (state == ASCAN_BEGIN) {
|
||||||
PyObject *sub = PyList_New(0);
|
PyObject *sub = PyList_New(0);
|
||||||
if (sub == NULL) return 0;
|
if (sub == NULL) return -1;
|
||||||
|
|
||||||
PyList_Append(array, sub);
|
PyList_Append(array, sub);
|
||||||
Py_DECREF(sub);
|
Py_DECREF(sub);
|
||||||
|
|
||||||
if (stack_index == MAX_DIMENSIONS)
|
if (stack_index == MAX_DIMENSIONS)
|
||||||
return 0;
|
return -1;
|
||||||
|
|
||||||
stack[stack_index++] = array;
|
stack[stack_index++] = array;
|
||||||
array = sub;
|
array = sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (state == ASCAN_ERROR) {
|
else if (state == ASCAN_ERROR) {
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (state == ASCAN_END) {
|
else if (state == ASCAN_END) {
|
||||||
if (--stack_index < 0)
|
if (--stack_index < 0)
|
||||||
return 0;
|
return -1;
|
||||||
array = stack[stack_index];
|
array = stack[stack_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ typecast_array_scan(const char *str, Py_ssize_t strlength,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -260,12 +260,11 @@ typecast_GENERIC_ARRAY_cast(const char *str, Py_ssize_t len, PyObject *curs)
|
||||||
Dprintf("typecast_GENERIC_ARRAY_cast: str = '%s',"
|
Dprintf("typecast_GENERIC_ARRAY_cast: str = '%s',"
|
||||||
" len = " FORMAT_CODE_PY_SSIZE_T, str, len);
|
" len = " FORMAT_CODE_PY_SSIZE_T, str, len);
|
||||||
|
|
||||||
obj = PyList_New(0);
|
if (!(obj = PyList_New(0))) { return NULL; }
|
||||||
|
|
||||||
/* scan the array skipping the first level of {} */
|
/* scan the array skipping the first level of {} */
|
||||||
if (typecast_array_scan(&str[1], len-2, curs, base, obj) == 0) {
|
if (typecast_array_scan(&str[1], len-2, curs, base, obj) < 0) {
|
||||||
Py_DECREF(obj);
|
Py_CLEAR(obj);
|
||||||
obj = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
|
|
|
@ -65,7 +65,7 @@ typecast_FLOAT_cast(const char *s, Py_ssize_t len, PyObject *curs)
|
||||||
PyObject *str = NULL, *flo = NULL;
|
PyObject *str = NULL, *flo = NULL;
|
||||||
|
|
||||||
if (s == NULL) {Py_INCREF(Py_None); return Py_None;}
|
if (s == NULL) {Py_INCREF(Py_None); return Py_None;}
|
||||||
str = Text_FromUTF8AndSize(s, len);
|
if (!(str = Text_FromUTF8AndSize(s, len))) { return NULL; }
|
||||||
#if PY_MAJOR_VERSION < 3
|
#if PY_MAJOR_VERSION < 3
|
||||||
flo = PyFloat_FromString(str, NULL);
|
flo = PyFloat_FromString(str, NULL);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "datetime.h"
|
#include "datetime.h"
|
||||||
|
|
||||||
static int
|
RAISES_NEG static int
|
||||||
psyco_typecast_datetime_init(void)
|
psyco_typecast_datetime_init(void)
|
||||||
{
|
{
|
||||||
Dprintf("psyco_typecast_datetime_init: datetime init");
|
Dprintf("psyco_typecast_datetime_init: datetime init");
|
||||||
|
@ -239,7 +239,7 @@ typecast_PYINTERVAL_cast(const char *str, Py_ssize_t len, PyObject *curs)
|
||||||
|
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
v = v*10 + (double)*str - (double)'0';
|
v = v * 10.0 + (double)(*str - '0');
|
||||||
if (part == 6){
|
if (part == 6){
|
||||||
denominator *= 10;
|
denominator *= 10;
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,7 @@ typecast_MXINTERVAL_cast(const char *str, Py_ssize_t len, PyObject *curs)
|
||||||
|
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
v = v*10 + (double)*str - (double)'0';
|
v = v * 10.0 + (double)(*str - '0');
|
||||||
Dprintf("typecast_MXINTERVAL_cast: v = %f", v);
|
Dprintf("typecast_MXINTERVAL_cast: v = %f", v);
|
||||||
if (part == 6){
|
if (part == 6){
|
||||||
denominator *= 10;
|
denominator *= 10;
|
||||||
|
|
|
@ -113,20 +113,19 @@ psycopg_escape_identifier_easy(const char *from, Py_ssize_t len)
|
||||||
* Allocate a new buffer on the Python heap containing the new string.
|
* Allocate a new buffer on the Python heap containing the new string.
|
||||||
* 'len' is optional: if 0 the length is calculated.
|
* 'len' is optional: if 0 the length is calculated.
|
||||||
*
|
*
|
||||||
* Return NULL and set an exception in case of error.
|
* Store the return in 'to' and return 0 in case of success, else return -1
|
||||||
|
* and raise an exception.
|
||||||
*/
|
*/
|
||||||
char *
|
RAISES_NEG int
|
||||||
psycopg_strdup(const char *from, Py_ssize_t len)
|
psycopg_strdup(char **to, const char *from, Py_ssize_t len)
|
||||||
{
|
{
|
||||||
char *rv;
|
|
||||||
|
|
||||||
if (!len) { len = strlen(from); }
|
if (!len) { len = strlen(from); }
|
||||||
if (!(rv = PyMem_Malloc(len + 1))) {
|
if (!(*to = PyMem_Malloc(len + 1))) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
strcpy(rv, from);
|
strcpy(*to, from);
|
||||||
return rv;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure a Python object is a bytes string.
|
/* Ensure a Python object is a bytes string.
|
||||||
|
@ -139,7 +138,7 @@ psycopg_strdup(const char *from, Py_ssize_t len)
|
||||||
*
|
*
|
||||||
* It is safe to call the function on NULL.
|
* It is safe to call the function on NULL.
|
||||||
*/
|
*/
|
||||||
PyObject *
|
STEALS(1) PyObject *
|
||||||
psycopg_ensure_bytes(PyObject *obj)
|
psycopg_ensure_bytes(PyObject *obj)
|
||||||
{
|
{
|
||||||
PyObject *rv = NULL;
|
PyObject *rv = NULL;
|
||||||
|
@ -169,7 +168,7 @@ psycopg_ensure_bytes(PyObject *obj)
|
||||||
* The function is ref neutral: steals a ref from obj and adds one to the
|
* The function is ref neutral: steals a ref from obj and adds one to the
|
||||||
* return value. It is safe to call it on NULL.
|
* return value. It is safe to call it on NULL.
|
||||||
*/
|
*/
|
||||||
PyObject *
|
STEALS(1) PyObject *
|
||||||
psycopg_ensure_text(PyObject *obj)
|
psycopg_ensure_text(PyObject *obj)
|
||||||
{
|
{
|
||||||
#if PY_MAJOR_VERSION < 3
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
|
|
@ -78,7 +78,9 @@ static PyMemberDef xid_members[] = {
|
||||||
static PyObject *
|
static PyObject *
|
||||||
xid_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
xid_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
XidObject *self = (XidObject *)type->tp_alloc(type, 0);
|
XidObject *self;
|
||||||
|
|
||||||
|
if (!(self = (XidObject *)type->tp_alloc(type, 0))) { return NULL; }
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
self->format_id = Py_None;
|
self->format_id = Py_None;
|
||||||
|
@ -486,7 +488,7 @@ exit:
|
||||||
*
|
*
|
||||||
* Return a borrowed reference. */
|
* Return a borrowed reference. */
|
||||||
|
|
||||||
static PyObject *
|
BORROWED static PyObject *
|
||||||
_xid_get_parse_regex(void) {
|
_xid_get_parse_regex(void) {
|
||||||
static PyObject *rv;
|
static PyObject *rv;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user