mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-02-07 12:50:32 +03:00
Merge remote-tracking branch 'origin/code-cleanup'
This commit is contained in:
commit
4246fdf809
|
@ -90,7 +90,9 @@ list_quote(listObject *self)
|
||||||
* array[array[]] is */
|
* array[array[]] is */
|
||||||
all_nulls = 0;
|
all_nulls = 0;
|
||||||
Py_CLEAR(qs[i]);
|
Py_CLEAR(qs[i]);
|
||||||
qs[i] = Bytes_FromString("ARRAY[]");
|
if (!(qs[i] = Bytes_FromString("ARRAY[]"))) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -113,14 +113,14 @@ 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!", &connectionType, &conn))
|
if (!PyArg_ParseTuple(args, "O!", &connectionType, &conn))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Py_CLEAR(self->conn);
|
Py_CLEAR(self->conn);
|
||||||
Py_INCREF(conn);
|
Py_INCREF(conn);
|
||||||
self->conn = conn;
|
self->conn = (connectionObject *)conn;
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,10 +79,7 @@
|
||||||
|
|
||||||
#define PSYCOPG_MODULE
|
#define PSYCOPG_MODULE
|
||||||
#include "psycopg/psycopg.h"
|
#include "psycopg/psycopg.h"
|
||||||
|
#include "pyport.h"
|
||||||
#ifndef Py_LOCAL_INLINE
|
|
||||||
#define Py_LOCAL_INLINE(type) static type
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Helpers for formatstring */
|
/* Helpers for formatstring */
|
||||||
|
|
||||||
|
@ -102,6 +99,19 @@ getnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* wrapper around _Bytes_Resize offering normal Python call semantics */
|
||||||
|
|
||||||
|
STEALS(1)
|
||||||
|
Py_LOCAL_INLINE(PyObject *)
|
||||||
|
resize_bytes(PyObject *b, Py_ssize_t newsize) {
|
||||||
|
if (0 == _Bytes_Resize(&b, newsize)) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) */
|
/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
|
@ -114,7 +124,7 @@ Bytes_Format(PyObject *format, PyObject *args)
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
PyObject *dict = NULL;
|
PyObject *dict = NULL;
|
||||||
if (format == NULL || !Bytes_Check(format) || args == NULL) {
|
if (format == NULL || !Bytes_Check(format) || args == NULL) {
|
||||||
PyErr_BadInternalCall();
|
PyErr_SetString(PyExc_SystemError, "bad argument to internal function");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
fmt = Bytes_AS_STRING(format);
|
fmt = Bytes_AS_STRING(format);
|
||||||
|
@ -123,7 +133,7 @@ Bytes_Format(PyObject *format, PyObject *args)
|
||||||
result = Bytes_FromStringAndSize((char *)NULL, reslen);
|
result = Bytes_FromStringAndSize((char *)NULL, reslen);
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
res = Bytes_AsString(result);
|
res = Bytes_AS_STRING(result);
|
||||||
if (PyTuple_Check(args)) {
|
if (PyTuple_Check(args)) {
|
||||||
arglen = PyTuple_GET_SIZE(args);
|
arglen = PyTuple_GET_SIZE(args);
|
||||||
argidx = 0;
|
argidx = 0;
|
||||||
|
@ -140,10 +150,10 @@ Bytes_Format(PyObject *format, PyObject *args)
|
||||||
if (--rescnt < 0) {
|
if (--rescnt < 0) {
|
||||||
rescnt = fmtcnt + 100;
|
rescnt = fmtcnt + 100;
|
||||||
reslen += rescnt;
|
reslen += rescnt;
|
||||||
if (_Bytes_Resize(&result, reslen))
|
if (!(result = resize_bytes(result, reslen))) {
|
||||||
return NULL;
|
return NULL;
|
||||||
res = Bytes_AS_STRING(result)
|
}
|
||||||
+ reslen - rescnt;
|
res = Bytes_AS_STRING(result) + reslen - rescnt;
|
||||||
--rescnt;
|
--rescnt;
|
||||||
}
|
}
|
||||||
*res++ = *fmt++;
|
*res++ = *fmt++;
|
||||||
|
@ -210,11 +220,6 @@ Bytes_Format(PyObject *format, PyObject *args)
|
||||||
"incomplete format");
|
"incomplete format");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (c != '%') {
|
|
||||||
v = getnextarg(args, arglen, &argidx);
|
|
||||||
if (v == NULL)
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '%':
|
case '%':
|
||||||
pbuf = "%";
|
pbuf = "%";
|
||||||
|
@ -222,6 +227,8 @@ Bytes_Format(PyObject *format, PyObject *args)
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
/* only bytes! */
|
/* only bytes! */
|
||||||
|
if (!(v = getnextarg(args, arglen, &argidx)))
|
||||||
|
goto error;
|
||||||
if (!Bytes_CheckExact(v)) {
|
if (!Bytes_CheckExact(v)) {
|
||||||
PyErr_Format(PyExc_ValueError,
|
PyErr_Format(PyExc_ValueError,
|
||||||
"only bytes values expected, got %s",
|
"only bytes values expected, got %s",
|
||||||
|
@ -238,8 +245,7 @@ Bytes_Format(PyObject *format, PyObject *args)
|
||||||
"unsupported format character '%c' (0x%x) "
|
"unsupported format character '%c' (0x%x) "
|
||||||
"at index " FORMAT_CODE_PY_SSIZE_T,
|
"at index " FORMAT_CODE_PY_SSIZE_T,
|
||||||
c, c,
|
c, c,
|
||||||
(Py_ssize_t)(fmt - 1 -
|
(Py_ssize_t)(fmt - 1 - Bytes_AS_STRING(format)));
|
||||||
Bytes_AsString(format)));
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (width < len)
|
if (width < len)
|
||||||
|
@ -251,10 +257,14 @@ Bytes_Format(PyObject *format, PyObject *args)
|
||||||
if (reslen < 0) {
|
if (reslen < 0) {
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
Py_XDECREF(temp);
|
Py_XDECREF(temp);
|
||||||
|
if (args_owned)
|
||||||
|
Py_DECREF(args);
|
||||||
return PyErr_NoMemory();
|
return PyErr_NoMemory();
|
||||||
}
|
}
|
||||||
if (_Bytes_Resize(&result, reslen)) {
|
if (!(result = resize_bytes(result, reslen))) {
|
||||||
Py_XDECREF(temp);
|
Py_XDECREF(temp);
|
||||||
|
if (args_owned)
|
||||||
|
Py_DECREF(args);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
res = Bytes_AS_STRING(result)
|
res = Bytes_AS_STRING(result)
|
||||||
|
@ -284,8 +294,9 @@ Bytes_Format(PyObject *format, PyObject *args)
|
||||||
if (args_owned) {
|
if (args_owned) {
|
||||||
Py_DECREF(args);
|
Py_DECREF(args);
|
||||||
}
|
}
|
||||||
if (_Bytes_Resize(&result, reslen - rescnt))
|
if (!(result = resize_bytes(result, reslen - rescnt))) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|
|
@ -248,7 +248,7 @@ static PySequenceMethods column_sequence = {
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
column_getstate(columnObject *self)
|
column_getstate(columnObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
return PyObject_CallFunctionObjArgs(
|
return PyObject_CallFunctionObjArgs(
|
||||||
(PyObject *)&PyTuple_Type, (PyObject *)self, NULL);
|
(PyObject *)&PyTuple_Type, (PyObject *)self, NULL);
|
||||||
|
|
|
@ -121,10 +121,6 @@ exit:
|
||||||
PyObject *
|
PyObject *
|
||||||
conn_decode(connectionObject *self, const char *str, Py_ssize_t len)
|
conn_decode(connectionObject *self, const char *str, Py_ssize_t len)
|
||||||
{
|
{
|
||||||
PyObject *b = NULL;
|
|
||||||
PyObject *t = NULL;
|
|
||||||
PyObject *rv = NULL;
|
|
||||||
|
|
||||||
if (len < 0) { len = strlen(str); }
|
if (len < 0) { len = strlen(str); }
|
||||||
|
|
||||||
if (self) {
|
if (self) {
|
||||||
|
@ -132,22 +128,28 @@ conn_decode(connectionObject *self, const char *str, Py_ssize_t len)
|
||||||
return self->cdecoder(str, len, NULL);
|
return self->cdecoder(str, len, NULL);
|
||||||
}
|
}
|
||||||
else if (self->pydecoder) {
|
else if (self->pydecoder) {
|
||||||
if (!(b = Bytes_FromStringAndSize(str, len))) { goto exit; }
|
PyObject *b = NULL;
|
||||||
|
PyObject *t = NULL;
|
||||||
|
PyObject *rv = NULL;
|
||||||
|
|
||||||
|
if (!(b = Bytes_FromStringAndSize(str, len))) { goto error; }
|
||||||
if (!(t = PyObject_CallFunctionObjArgs(self->pydecoder, b, NULL))) {
|
if (!(t = PyObject_CallFunctionObjArgs(self->pydecoder, b, NULL))) {
|
||||||
goto exit;
|
goto error;
|
||||||
}
|
}
|
||||||
rv = PyTuple_GetItem(t, 0);
|
if (!(rv = PyTuple_GetItem(t, 0))) { goto error; }
|
||||||
Py_XINCREF(rv);
|
Py_INCREF(rv); /* PyTuple_GetItem gives a borrowes one */
|
||||||
|
error:
|
||||||
|
Py_XDECREF(t);
|
||||||
|
Py_XDECREF(b);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return PyUnicode_FromStringAndSize(str, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return PyUnicode_FromStringAndSize(str, len);
|
return PyUnicode_FromStringAndSize(str, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
|
||||||
Py_XDECREF(t);
|
|
||||||
Py_XDECREF(b);
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* conn_notice_callback - process notices */
|
/* conn_notice_callback - process notices */
|
||||||
|
@ -1079,7 +1081,16 @@ conn_poll(connectionObject *self)
|
||||||
/* An async query has just finished: parse the tuple in the
|
/* An async query has just finished: parse the tuple in the
|
||||||
* target cursor. */
|
* target cursor. */
|
||||||
cursorObject *curs;
|
cursorObject *curs;
|
||||||
PyObject *py_curs = PyWeakref_GetObject(self->async_cursor);
|
PyObject *py_curs;
|
||||||
|
if (!(py_curs = PyWeakref_GetObject(self->async_cursor))) {
|
||||||
|
/* It shouldn't happen but consider it to avoid dereferencing
|
||||||
|
* a null pointer below. */
|
||||||
|
pq_clear_async(self);
|
||||||
|
PyErr_SetString(PyExc_SystemError,
|
||||||
|
"got null dereferencing cursor weakref");
|
||||||
|
res = PSYCO_POLL_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (Py_None == py_curs) {
|
if (Py_None == py_curs) {
|
||||||
pq_clear_async(self);
|
pq_clear_async(self);
|
||||||
PyErr_SetString(InterfaceError,
|
PyErr_SetString(InterfaceError,
|
||||||
|
|
|
@ -112,10 +112,10 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *kwargs)
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != psyco_curs_withhold_set((cursorObject *)obj, withhold)) {
|
if (0 > psyco_curs_withhold_set((cursorObject *)obj, withhold)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
if (0 != psyco_curs_scrollable_set((cursorObject *)obj, scrollable)) {
|
if (0 > psyco_curs_scrollable_set((cursorObject *)obj, scrollable)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ exit:
|
||||||
#define psyco_conn_close_doc "close() -- Close the connection."
|
#define psyco_conn_close_doc "close() -- Close the connection."
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_close(connectionObject *self)
|
psyco_conn_close(connectionObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
Dprintf("psyco_conn_close: closing connection at %p", self);
|
Dprintf("psyco_conn_close: closing connection at %p", self);
|
||||||
conn_close(self);
|
conn_close(self);
|
||||||
|
@ -153,7 +153,7 @@ psyco_conn_close(connectionObject *self)
|
||||||
#define psyco_conn_commit_doc "commit() -- Commit all changes to database."
|
#define psyco_conn_commit_doc "commit() -- Commit all changes to database."
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_commit(connectionObject *self)
|
psyco_conn_commit(connectionObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
EXC_IF_CONN_CLOSED(self);
|
EXC_IF_CONN_CLOSED(self);
|
||||||
EXC_IF_CONN_ASYNC(self, commit);
|
EXC_IF_CONN_ASYNC(self, commit);
|
||||||
|
@ -172,7 +172,7 @@ psyco_conn_commit(connectionObject *self)
|
||||||
"rollback() -- Roll back all changes done to database."
|
"rollback() -- Roll back all changes done to database."
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_rollback(connectionObject *self)
|
psyco_conn_rollback(connectionObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
EXC_IF_CONN_CLOSED(self);
|
EXC_IF_CONN_CLOSED(self);
|
||||||
EXC_IF_CONN_ASYNC(self, rollback);
|
EXC_IF_CONN_ASYNC(self, rollback);
|
||||||
|
@ -245,7 +245,7 @@ exit:
|
||||||
"tpc_prepare() -- perform the first phase of a two-phase transaction."
|
"tpc_prepare() -- perform the first phase of a two-phase transaction."
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_tpc_prepare(connectionObject *self)
|
psyco_conn_tpc_prepare(connectionObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
EXC_IF_CONN_CLOSED(self);
|
EXC_IF_CONN_CLOSED(self);
|
||||||
EXC_IF_CONN_ASYNC(self, tpc_prepare);
|
EXC_IF_CONN_ASYNC(self, tpc_prepare);
|
||||||
|
@ -388,7 +388,7 @@ psyco_conn_tpc_rollback(connectionObject *self, PyObject *args)
|
||||||
"tpc_recover() -- returns a list of pending transaction IDs."
|
"tpc_recover() -- returns a list of pending transaction IDs."
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_tpc_recover(connectionObject *self)
|
psyco_conn_tpc_recover(connectionObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
EXC_IF_CONN_CLOSED(self);
|
EXC_IF_CONN_CLOSED(self);
|
||||||
EXC_IF_CONN_ASYNC(self, tpc_recover);
|
EXC_IF_CONN_ASYNC(self, tpc_recover);
|
||||||
|
@ -403,7 +403,7 @@ psyco_conn_tpc_recover(connectionObject *self)
|
||||||
"__enter__ -> self"
|
"__enter__ -> self"
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_enter(connectionObject *self)
|
psyco_conn_enter(connectionObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
EXC_IF_CONN_CLOSED(self);
|
EXC_IF_CONN_CLOSED(self);
|
||||||
|
|
||||||
|
@ -828,7 +828,7 @@ psyco_conn_deferrable_set(connectionObject *self, PyObject *pyvalue)
|
||||||
"get_native_connection() -- Return the internal PGconn* as a Python Capsule."
|
"get_native_connection() -- Return the internal PGconn* as a Python Capsule."
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_get_native_connection(connectionObject *self)
|
psyco_get_native_connection(connectionObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
EXC_IF_CONN_CLOSED(self);
|
EXC_IF_CONN_CLOSED(self);
|
||||||
|
|
||||||
|
@ -866,7 +866,7 @@ psyco_conn_set_client_encoding(connectionObject *self, PyObject *args)
|
||||||
"get_transaction_status() -- Get backend transaction status."
|
"get_transaction_status() -- Get backend transaction status."
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_get_transaction_status(connectionObject *self)
|
psyco_conn_get_transaction_status(connectionObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
return PyInt_FromLong((long)PQtransactionStatus(self->pgconn));
|
return PyInt_FromLong((long)PQtransactionStatus(self->pgconn));
|
||||||
}
|
}
|
||||||
|
@ -905,7 +905,7 @@ psyco_conn_get_parameter_status(connectionObject *self, PyObject *args)
|
||||||
"get_dsn_parameters() -- Get effective connection parameters.\n\n"
|
"get_dsn_parameters() -- Get effective connection parameters.\n\n"
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_get_dsn_parameters(connectionObject *self)
|
psyco_conn_get_dsn_parameters(connectionObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
#if PG_VERSION_NUM >= 90300
|
#if PG_VERSION_NUM >= 90300
|
||||||
PyObject *res = NULL;
|
PyObject *res = NULL;
|
||||||
|
@ -998,7 +998,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 *dummy)
|
||||||
{
|
{
|
||||||
EXC_IF_CONN_CLOSED(self);
|
EXC_IF_CONN_CLOSED(self);
|
||||||
|
|
||||||
|
@ -1025,7 +1025,7 @@ psyco_conn_info_get(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 *dummy)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
@ -1056,7 +1056,7 @@ psyco_conn_get_exception(PyObject *self, void *closure)
|
||||||
"poll() -> int -- Advance the connection or query process without blocking."
|
"poll() -> int -- Advance the connection or query process without blocking."
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_conn_poll(connectionObject *self)
|
psyco_conn_poll(connectionObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
@ -1076,7 +1076,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 *dummy)
|
||||||
{
|
{
|
||||||
long int socket;
|
long int socket;
|
||||||
|
|
||||||
|
@ -1093,7 +1093,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 *dummy)
|
||||||
{
|
{
|
||||||
/* synchronous connections will always return False */
|
/* synchronous connections will always return False */
|
||||||
if (self->async == 0) {
|
if (self->async == 0) {
|
||||||
|
@ -1119,7 +1119,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 *dummy)
|
||||||
{
|
{
|
||||||
char errbuf[256];
|
char errbuf[256];
|
||||||
|
|
||||||
|
|
|
@ -93,8 +93,8 @@ struct cursorObject {
|
||||||
/* C-callable functions in cursor_int.c and cursor_type.c */
|
/* C-callable functions in cursor_int.c and cursor_type.c */
|
||||||
BORROWED 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);
|
||||||
HIDDEN int psyco_curs_withhold_set(cursorObject *self, PyObject *pyvalue);
|
RAISES_NEG HIDDEN int psyco_curs_withhold_set(cursorObject *self, PyObject *pyvalue);
|
||||||
HIDDEN int psyco_curs_scrollable_set(cursorObject *self, PyObject *pyvalue);
|
RAISES_NEG HIDDEN int psyco_curs_scrollable_set(cursorObject *self, PyObject *pyvalue);
|
||||||
HIDDEN PyObject *psyco_curs_validate_sql_basic(cursorObject *self, PyObject *sql);
|
HIDDEN PyObject *psyco_curs_validate_sql_basic(cursorObject *self, PyObject *sql);
|
||||||
|
|
||||||
/* exception-raising macros */
|
/* exception-raising macros */
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
"close() -- Close the cursor."
|
"close() -- Close the cursor."
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_curs_close(cursorObject *self)
|
psyco_curs_close(cursorObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
PyObject *rv = NULL;
|
PyObject *rv = NULL;
|
||||||
char *lname = NULL;
|
char *lname = NULL;
|
||||||
|
@ -372,20 +372,17 @@ _psyco_curs_merge_query_args(cursorObject *self,
|
||||||
|
|
||||||
RAISES_NEG static int
|
RAISES_NEG static int
|
||||||
_psyco_curs_execute(cursorObject *self,
|
_psyco_curs_execute(cursorObject *self,
|
||||||
PyObject *operation, PyObject *vars,
|
PyObject *query, PyObject *vars,
|
||||||
long int async, int no_result)
|
long int async, int no_result)
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
int tmp;
|
int tmp;
|
||||||
PyObject *fquery, *cvt = NULL;
|
PyObject *fquery = NULL, *cvt = NULL;
|
||||||
const char *scroll;
|
|
||||||
|
|
||||||
operation = psyco_curs_validate_sql_basic(self, operation);
|
/* query becomes NULL or refcount +1, so good to XDECREF at the end */
|
||||||
|
if (!(query = psyco_curs_validate_sql_basic(self, query))) {
|
||||||
/* Any failure from here forward should 'goto fail' rather than 'return 0'
|
goto exit;
|
||||||
directly. */
|
}
|
||||||
|
|
||||||
if (operation == NULL) { goto exit; }
|
|
||||||
|
|
||||||
CLEARPGRES(self->pgres);
|
CLEARPGRES(self->pgres);
|
||||||
Py_CLEAR(self->query);
|
Py_CLEAR(self->query);
|
||||||
|
@ -394,65 +391,56 @@ _psyco_curs_execute(cursorObject *self,
|
||||||
/* here we are, and we have a sequence or a dictionary filled with
|
/* here we are, and we have a sequence or a dictionary filled with
|
||||||
objects to be substituted (bound variables). we try to be smart and do
|
objects to be substituted (bound variables). we try to be smart and do
|
||||||
the right thing (i.e., what the user expects) */
|
the right thing (i.e., what the user expects) */
|
||||||
|
|
||||||
if (vars && vars != Py_None)
|
if (vars && vars != Py_None)
|
||||||
{
|
{
|
||||||
if (0 > _mogrify(vars, operation, self, &cvt)) { goto exit; }
|
if (0 > _mogrify(vars, query, self, &cvt)) { goto exit; }
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (self->scrollable) {
|
/* Merge the query to the arguments if needed */
|
||||||
case -1:
|
if (cvt) {
|
||||||
scroll = "";
|
if (!(fquery = _psyco_curs_merge_query_args(self, query, cvt))) {
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
scroll = "NO SCROLL ";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
scroll = "SCROLL ";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
PyErr_SetString(InternalError, "unexpected scrollable value");
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
|
||||||
|
|
||||||
if (vars && cvt) {
|
|
||||||
if (!(fquery = _psyco_curs_merge_query_args(self, operation, cvt))) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self->qname != NULL) {
|
|
||||||
self->query = Bytes_FromFormat(
|
|
||||||
"DECLARE %s %sCURSOR %s HOLD FOR %s",
|
|
||||||
self->qname,
|
|
||||||
scroll,
|
|
||||||
self->withhold ? "WITH" : "WITHOUT",
|
|
||||||
Bytes_AS_STRING(fquery));
|
|
||||||
Py_DECREF(fquery);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self->query = fquery;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (self->qname != NULL) {
|
Py_INCREF(query);
|
||||||
self->query = Bytes_FromFormat(
|
fquery = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->qname != NULL) {
|
||||||
|
const char *scroll;
|
||||||
|
switch (self->scrollable) {
|
||||||
|
case -1:
|
||||||
|
scroll = "";
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
scroll = "NO SCROLL ";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
scroll = "SCROLL ";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PyErr_SetString(InternalError, "unexpected scrollable value");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(self->query = Bytes_FromFormat(
|
||||||
"DECLARE %s %sCURSOR %s HOLD FOR %s",
|
"DECLARE %s %sCURSOR %s HOLD FOR %s",
|
||||||
self->qname,
|
self->qname,
|
||||||
scroll,
|
scroll,
|
||||||
self->withhold ? "WITH" : "WITHOUT",
|
self->withhold ? "WITH" : "WITHOUT",
|
||||||
Bytes_AS_STRING(operation));
|
Bytes_AS_STRING(fquery)))) {
|
||||||
}
|
goto exit;
|
||||||
else {
|
|
||||||
/* Transfer reference ownership of the str in operation to
|
|
||||||
self->query, clearing the local variable to prevent cleanup from
|
|
||||||
DECREFing it */
|
|
||||||
self->query = operation;
|
|
||||||
operation = NULL;
|
|
||||||
}
|
}
|
||||||
|
if (!self->query) { goto exit; }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Transfer ownership */
|
||||||
|
Py_INCREF(fquery);
|
||||||
|
self->query = fquery;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* At this point, the SQL statement must be str, not unicode */
|
/* At this point, the SQL statement must be str, not unicode */
|
||||||
|
|
||||||
tmp = pq_execute(self, Bytes_AS_STRING(self->query), async, no_result, 0);
|
tmp = pq_execute(self, Bytes_AS_STRING(self->query), async, no_result, 0);
|
||||||
Dprintf("psyco_curs_execute: res = %d, pgres = %p", tmp, self->pgres);
|
Dprintf("psyco_curs_execute: res = %d, pgres = %p", tmp, self->pgres);
|
||||||
if (tmp < 0) { goto exit; }
|
if (tmp < 0) { goto exit; }
|
||||||
|
@ -460,10 +448,8 @@ _psyco_curs_execute(cursorObject *self,
|
||||||
res = 0; /* Success */
|
res = 0; /* Success */
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
/* Py_XDECREF(operation) is safe because the original reference passed
|
Py_XDECREF(query);
|
||||||
by the caller was overwritten with either NULL or a new
|
Py_XDECREF(fquery);
|
||||||
reference */
|
|
||||||
Py_XDECREF(operation);
|
|
||||||
Py_XDECREF(cvt);
|
Py_XDECREF(cvt);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -756,7 +742,7 @@ exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_curs_fetchone(cursorObject *self)
|
psyco_curs_fetchone(cursorObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
|
|
||||||
|
@ -947,7 +933,7 @@ exit:
|
||||||
"Return `!None` when no more data is available.\n"
|
"Return `!None` when no more data is available.\n"
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_curs_fetchall(cursorObject *self)
|
psyco_curs_fetchall(cursorObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
int i, size;
|
int i, size;
|
||||||
PyObject *list = NULL;
|
PyObject *list = NULL;
|
||||||
|
@ -1162,7 +1148,7 @@ exit:
|
||||||
"sets) and will raise a NotSupportedError exception."
|
"sets) and will raise a NotSupportedError exception."
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_curs_nextset(cursorObject *self)
|
psyco_curs_nextset(cursorObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
EXC_IF_CURS_CLOSED(self);
|
EXC_IF_CURS_CLOSED(self);
|
||||||
|
|
||||||
|
@ -1279,7 +1265,7 @@ psyco_curs_scroll(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
"__enter__ -> self"
|
"__enter__ -> self"
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_curs_enter(cursorObject *self)
|
psyco_curs_enter(cursorObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
Py_INCREF(self);
|
Py_INCREF(self);
|
||||||
return (PyObject *)self;
|
return (PyObject *)self;
|
||||||
|
@ -1394,27 +1380,6 @@ 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."
|
||||||
|
|
||||||
STEALS(1) static int
|
|
||||||
_psyco_curs_has_read_check(PyObject *o, PyObject **var)
|
|
||||||
{
|
|
||||||
if (PyObject_HasAttrString(o, "readline")
|
|
||||||
&& PyObject_HasAttrString(o, "read")) {
|
|
||||||
/* This routine stores a borrowed reference. Although it is only held
|
|
||||||
* for the duration of psyco_curs_copy_from, nested invocations of
|
|
||||||
* Py_BEGIN_ALLOW_THREADS could surrender control to another thread,
|
|
||||||
* which could invoke the garbage collector. We thus need an
|
|
||||||
* INCREF/DECREF pair if we store this pointer in a GC object, such as
|
|
||||||
* a cursorObject */
|
|
||||||
*var = o;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PyErr_SetString(PyExc_TypeError,
|
|
||||||
"argument 1 must have both .read() and .readline() methods");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs)
|
psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
|
@ -1436,11 +1401,15 @@ psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
Py_ssize_t bufsize = DEFAULT_COPYBUFF;
|
Py_ssize_t bufsize = DEFAULT_COPYBUFF;
|
||||||
PyObject *file, *columns = NULL, *res = NULL;
|
PyObject *file, *columns = NULL, *res = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
if (!PyArg_ParseTupleAndKeywords(
|
||||||
"O&s|ssnO", kwlist,
|
args, kwargs, "Os|ssnO", kwlist,
|
||||||
_psyco_curs_has_read_check, &file, &table_name, &sep, &null, &bufsize,
|
&file, &table_name, &sep, &null, &bufsize, &columns)) {
|
||||||
&columns))
|
return NULL;
|
||||||
{
|
}
|
||||||
|
|
||||||
|
if (!PyObject_HasAttrString(file, "read")) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"argument 1 must have a .read() method");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1474,6 +1443,12 @@ psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
|
|
||||||
Dprintf("psyco_curs_copy_from: query = %s", query);
|
Dprintf("psyco_curs_copy_from: query = %s", query);
|
||||||
|
|
||||||
|
/* This routine stores a borrowed reference. Although it is only held
|
||||||
|
* for the duration of psyco_curs_copy_from, nested invocations of
|
||||||
|
* Py_BEGIN_ALLOW_THREADS could surrender control to another thread,
|
||||||
|
* which could invoke the garbage collector. We thus need an
|
||||||
|
* INCREF/DECREF pair if we store this pointer in a GC object, such as
|
||||||
|
* a cursorObject */
|
||||||
self->copysize = bufsize;
|
self->copysize = bufsize;
|
||||||
Py_INCREF(file);
|
Py_INCREF(file);
|
||||||
self->copyfile = file;
|
self->copyfile = file;
|
||||||
|
@ -1499,20 +1474,6 @@ 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."
|
||||||
|
|
||||||
STEALS(1) static int
|
|
||||||
_psyco_curs_has_write_check(PyObject *o, PyObject **var)
|
|
||||||
{
|
|
||||||
if (PyObject_HasAttrString(o, "write")) {
|
|
||||||
*var = o;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PyErr_SetString(PyExc_TypeError,
|
|
||||||
"argument 1 must have a .write() method");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_curs_copy_to(cursorObject *self, PyObject *args, PyObject *kwargs)
|
psyco_curs_copy_to(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
|
@ -1530,11 +1491,17 @@ psyco_curs_copy_to(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
char *quoted_null = NULL;
|
char *quoted_null = NULL;
|
||||||
|
|
||||||
const char *table_name;
|
const char *table_name;
|
||||||
PyObject *file, *columns = NULL, *res = NULL;
|
PyObject *file = NULL, *columns = NULL, *res = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&s|ssO", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(
|
||||||
_psyco_curs_has_write_check, &file,
|
args, kwargs, "Os|ssO", kwlist,
|
||||||
&table_name, &sep, &null, &columns)) {
|
&file, &table_name, &sep, &null, &columns)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PyObject_HasAttrString(file, "write")) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"argument 1 must have a .write() method");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1681,7 +1648,7 @@ psyco_curs_withhold_get(cursorObject *self)
|
||||||
return PyBool_FromLong(self->withhold);
|
return PyBool_FromLong(self->withhold);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
psyco_curs_withhold_set(cursorObject *self, PyObject *pyvalue)
|
psyco_curs_withhold_set(cursorObject *self, PyObject *pyvalue)
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
|
@ -1726,7 +1693,7 @@ psyco_curs_scrollable_get(cursorObject *self)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
RAISES_NEG int
|
||||||
psyco_curs_scrollable_set(cursorObject *self, PyObject *pyvalue)
|
psyco_curs_scrollable_set(cursorObject *self, PyObject *pyvalue)
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
|
@ -1768,7 +1735,7 @@ cursor_next(PyObject *self)
|
||||||
|
|
||||||
if (NULL == ((cursorObject*)self)->name) {
|
if (NULL == ((cursorObject*)self)->name) {
|
||||||
/* we don't parse arguments: psyco_curs_fetchone will do that for us */
|
/* we don't parse arguments: psyco_curs_fetchone will do that for us */
|
||||||
res = psyco_curs_fetchone((cursorObject*)self);
|
res = psyco_curs_fetchone((cursorObject*)self, NULL);
|
||||||
|
|
||||||
/* convert a None to NULL to signal the end of iteration */
|
/* convert a None to NULL to signal the end of iteration */
|
||||||
if (res && res == Py_None) {
|
if (res && res == Py_None) {
|
||||||
|
|
|
@ -131,7 +131,7 @@ static struct PyGetSetDef error_getsets[] = {
|
||||||
* would require implementing __getstate__, and as of 2012 it's a little
|
* would require implementing __getstate__, and as of 2012 it's a little
|
||||||
* bit too late to care. */
|
* bit too late to care. */
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_error_reduce(errorObject *self)
|
psyco_error_reduce(errorObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
PyObject *meth = NULL;
|
PyObject *meth = NULL;
|
||||||
PyObject *tuple = NULL;
|
PyObject *tuple = NULL;
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
#include "psycopg/config.h"
|
#include "psycopg/config.h"
|
||||||
#include "psycopg/python.h"
|
#include "psycopg/python.h"
|
||||||
|
#include "psycopg/utils.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -115,35 +116,6 @@ typedef struct {
|
||||||
char *pyenc;
|
char *pyenc;
|
||||||
} encodingPair;
|
} encodingPair;
|
||||||
|
|
||||||
/* the Decimal type, used by the DECIMAL typecaster */
|
|
||||||
HIDDEN PyObject *psyco_GetDecimalType(void);
|
|
||||||
|
|
||||||
/* forward declarations */
|
|
||||||
typedef struct cursorObject cursorObject;
|
|
||||||
typedef struct connectionObject connectionObject;
|
|
||||||
typedef struct replicationMessageObject replicationMessageObject;
|
|
||||||
|
|
||||||
/* some utility functions */
|
|
||||||
RAISES HIDDEN PyObject *psyco_set_error(PyObject *exc, cursorObject *curs, const char *msg);
|
|
||||||
|
|
||||||
HIDDEN char *psycopg_escape_string(connectionObject *conn,
|
|
||||||
const char *from, Py_ssize_t len, char *to, Py_ssize_t *tolen);
|
|
||||||
HIDDEN char *psycopg_escape_identifier(connectionObject *conn,
|
|
||||||
const char *str, Py_ssize_t len);
|
|
||||||
HIDDEN int psycopg_strdup(char **to, const char *from, Py_ssize_t len);
|
|
||||||
HIDDEN int psycopg_is_text_file(PyObject *f);
|
|
||||||
HIDDEN PyObject *psycopg_text_from_chars_safe(
|
|
||||||
const char *str, Py_ssize_t len, PyObject *decoder);
|
|
||||||
|
|
||||||
STEALS(1) HIDDEN PyObject * psycopg_ensure_bytes(PyObject *obj);
|
|
||||||
|
|
||||||
STEALS(1) HIDDEN PyObject * psycopg_ensure_text(PyObject *obj);
|
|
||||||
|
|
||||||
HIDDEN PyObject *psycopg_dict_from_conninfo_options(PQconninfoOption *options,
|
|
||||||
int include_password);
|
|
||||||
|
|
||||||
HIDDEN PyObject *psycopg_make_dsn(PyObject *dsn, PyObject *kwargs);
|
|
||||||
|
|
||||||
/* Exceptions docstrings */
|
/* Exceptions docstrings */
|
||||||
#define Error_doc \
|
#define Error_doc \
|
||||||
"Base class for error exceptions."
|
"Base class for error exceptions."
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
#include "psycopg/typecast.h"
|
#include "psycopg/typecast.h"
|
||||||
#include "psycopg/microprotocols.h"
|
#include "psycopg/microprotocols.h"
|
||||||
#include "psycopg/microprotocols_proto.h"
|
#include "psycopg/microprotocols_proto.h"
|
||||||
#include "psycopg/error.h"
|
|
||||||
#include "psycopg/conninfo.h"
|
#include "psycopg/conninfo.h"
|
||||||
#include "psycopg/diagnostics.h"
|
#include "psycopg/diagnostics.h"
|
||||||
|
|
||||||
|
@ -396,7 +395,7 @@ exit:
|
||||||
#define psyco_libpq_version_doc "Query actual libpq version loaded."
|
#define psyco_libpq_version_doc "Query actual libpq version loaded."
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
psyco_libpq_version(PyObject *self)
|
psyco_libpq_version(PyObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
return PyInt_FromLong(PQlibVersion());
|
return PyInt_FromLong(PQlibVersion());
|
||||||
}
|
}
|
||||||
|
@ -722,116 +721,6 @@ psyco_errors_set(PyObject *type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* psyco_set_error
|
|
||||||
|
|
||||||
Create a new error of the given type with extra attributes. */
|
|
||||||
|
|
||||||
/* TODO: may have been changed to BORROWED */
|
|
||||||
RAISES PyObject *
|
|
||||||
psyco_set_error(PyObject *exc, cursorObject *curs, const char *msg)
|
|
||||||
{
|
|
||||||
PyObject *pymsg;
|
|
||||||
PyObject *err = NULL;
|
|
||||||
connectionObject *conn = NULL;
|
|
||||||
|
|
||||||
if (curs) {
|
|
||||||
conn = ((cursorObject *)curs)->conn;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((pymsg = conn_text_from_chars(conn, msg))) {
|
|
||||||
err = PyObject_CallFunctionObjArgs(exc, pymsg, NULL);
|
|
||||||
Py_DECREF(pymsg);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* what's better than an error in an error handler in the morning?
|
|
||||||
* Anyway, some error was set, refcount is ok... get outta here. */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err && PyObject_TypeCheck(err, &errorType)) {
|
|
||||||
errorObject *perr = (errorObject *)err;
|
|
||||||
if (curs) {
|
|
||||||
Py_CLEAR(perr->cursor);
|
|
||||||
Py_INCREF(curs);
|
|
||||||
perr->cursor = curs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
PyErr_SetObject(exc, err);
|
|
||||||
Py_DECREF(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Return nonzero if the current one is the main interpreter */
|
|
||||||
static int
|
|
||||||
psyco_is_main_interp(void)
|
|
||||||
{
|
|
||||||
static PyInterpreterState *main_interp = NULL; /* Cached reference */
|
|
||||||
PyInterpreterState *interp;
|
|
||||||
|
|
||||||
if (main_interp) {
|
|
||||||
return (main_interp == PyThreadState_Get()->interp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No cached value: cache the proper value and try again. */
|
|
||||||
interp = PyInterpreterState_Head();
|
|
||||||
while (interp->next)
|
|
||||||
interp = interp->next;
|
|
||||||
|
|
||||||
main_interp = interp;
|
|
||||||
assert (main_interp);
|
|
||||||
return psyco_is_main_interp();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* psyco_GetDecimalType
|
|
||||||
|
|
||||||
Return a new reference to the adapter for decimal type.
|
|
||||||
|
|
||||||
If decimals should be used but the module import fails, fall back on
|
|
||||||
the float type.
|
|
||||||
|
|
||||||
If decimals are not to be used, return NULL.
|
|
||||||
*/
|
|
||||||
|
|
||||||
PyObject *
|
|
||||||
psyco_GetDecimalType(void)
|
|
||||||
{
|
|
||||||
static PyObject *cachedType = NULL;
|
|
||||||
PyObject *decimalType = NULL;
|
|
||||||
PyObject *decimal;
|
|
||||||
|
|
||||||
/* Use the cached object if running from the main interpreter. */
|
|
||||||
int can_cache = psyco_is_main_interp();
|
|
||||||
if (can_cache && cachedType) {
|
|
||||||
Py_INCREF(cachedType);
|
|
||||||
return cachedType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get a new reference to the Decimal type. */
|
|
||||||
decimal = PyImport_ImportModule("decimal");
|
|
||||||
if (decimal) {
|
|
||||||
decimalType = PyObject_GetAttrString(decimal, "Decimal");
|
|
||||||
Py_DECREF(decimal);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PyErr_Clear();
|
|
||||||
decimalType = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store the object from future uses. */
|
|
||||||
if (can_cache && !cachedType && decimalType) {
|
|
||||||
Py_INCREF(decimalType);
|
|
||||||
cachedType = decimalType;
|
|
||||||
}
|
|
||||||
|
|
||||||
return decimalType;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** method table and module initialization **/
|
/** method table and module initialization **/
|
||||||
|
|
||||||
|
@ -1119,9 +1008,6 @@ INIT_MODULE(_psycopg)(void)
|
||||||
if (0 != psyco_errors_init()) { goto exit; }
|
if (0 != psyco_errors_init()) { goto exit; }
|
||||||
psyco_errors_fill(dict);
|
psyco_errors_fill(dict);
|
||||||
|
|
||||||
replicationPhysicalConst = PyDict_GetItemString(dict, "REPLICATION_PHYSICAL");
|
|
||||||
replicationLogicalConst = PyDict_GetItemString(dict, "REPLICATION_LOGICAL");
|
|
||||||
|
|
||||||
Dprintf("initpsycopg: module initialization complete");
|
Dprintf("initpsycopg: module initialization complete");
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
|
|
@ -45,9 +45,6 @@ typedef struct replicationConnectionObject {
|
||||||
#define REPLICATION_PHYSICAL 12345678
|
#define REPLICATION_PHYSICAL 12345678
|
||||||
#define REPLICATION_LOGICAL 87654321
|
#define REPLICATION_LOGICAL 87654321
|
||||||
|
|
||||||
extern HIDDEN PyObject *replicationPhysicalConst;
|
|
||||||
extern HIDDEN PyObject *replicationLogicalConst;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -41,21 +41,7 @@
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_repl_conn_get_type(replicationConnectionObject *self)
|
psyco_repl_conn_get_type(replicationConnectionObject *self)
|
||||||
{
|
{
|
||||||
connectionObject *conn = &self->conn;
|
return PyInt_FromLong(self->type);
|
||||||
PyObject *res = NULL;
|
|
||||||
|
|
||||||
EXC_IF_CONN_CLOSED(conn);
|
|
||||||
|
|
||||||
if (self->type == REPLICATION_PHYSICAL) {
|
|
||||||
res = replicationPhysicalConst;
|
|
||||||
} else if (self->type == REPLICATION_LOGICAL) {
|
|
||||||
res = replicationLogicalConst;
|
|
||||||
} else {
|
|
||||||
PyErr_Format(PyExc_TypeError, "unknown replication type constant: %ld", self->type);
|
|
||||||
}
|
|
||||||
|
|
||||||
Py_XINCREF(res);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,15 +49,16 @@ static int
|
||||||
replicationConnection_init(replicationConnectionObject *self,
|
replicationConnection_init(replicationConnectionObject *self,
|
||||||
PyObject *args, PyObject *kwargs)
|
PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
PyObject *dsn = NULL, *async = Py_False, *replication_type = NULL,
|
PyObject *dsn = NULL, *async = Py_False,
|
||||||
*item = NULL, *extras = NULL, *cursor = NULL,
|
*item = NULL, *extras = NULL, *cursor = NULL,
|
||||||
*newdsn = NULL, *newargs = NULL, *dsnopts = NULL;
|
*newdsn = NULL, *newargs = NULL, *dsnopts = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
long int replication_type;
|
||||||
|
|
||||||
/* 'replication_type' is not actually optional, but there's no
|
/* 'replication_type' is not actually optional, but there's no
|
||||||
good way to put it before 'async' in the list */
|
good way to put it before 'async' in the list */
|
||||||
static char *kwlist[] = {"dsn", "async", "replication_type", NULL};
|
static char *kwlist[] = {"dsn", "async", "replication_type", NULL};
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OO", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ol", kwlist,
|
||||||
&dsn, &async, &replication_type)) {
|
&dsn, &async, &replication_type)) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -87,9 +74,7 @@ replicationConnection_init(replicationConnectionObject *self,
|
||||||
if (!(extras = PyImport_ImportModule("psycopg2.extras"))) { goto exit; }
|
if (!(extras = PyImport_ImportModule("psycopg2.extras"))) { goto exit; }
|
||||||
if (!(cursor = PyObject_GetAttrString(extras, "ReplicationCursor"))) { goto exit; }
|
if (!(cursor = PyObject_GetAttrString(extras, "ReplicationCursor"))) { goto exit; }
|
||||||
|
|
||||||
/* checking the object reference helps to avoid recognizing
|
if (replication_type == REPLICATION_PHYSICAL) {
|
||||||
unrelated integer constants as valid input values */
|
|
||||||
if (replication_type == replicationPhysicalConst) {
|
|
||||||
self->type = REPLICATION_PHYSICAL;
|
self->type = REPLICATION_PHYSICAL;
|
||||||
|
|
||||||
#define SET_ITEM(k, v) \
|
#define SET_ITEM(k, v) \
|
||||||
|
@ -100,14 +85,15 @@ replicationConnection_init(replicationConnectionObject *self,
|
||||||
|
|
||||||
SET_ITEM(replication, true);
|
SET_ITEM(replication, true);
|
||||||
SET_ITEM(dbname, replication); /* required for .pgpass lookup */
|
SET_ITEM(dbname, replication); /* required for .pgpass lookup */
|
||||||
} else if (replication_type == replicationLogicalConst) {
|
} else if (replication_type == REPLICATION_LOGICAL) {
|
||||||
self->type = REPLICATION_LOGICAL;
|
self->type = REPLICATION_LOGICAL;
|
||||||
|
|
||||||
SET_ITEM(replication, database);
|
SET_ITEM(replication, database);
|
||||||
#undef SET_ITEM
|
#undef SET_ITEM
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"replication_type must be either REPLICATION_PHYSICAL or REPLICATION_LOGICAL");
|
"replication_type must be either "
|
||||||
|
"REPLICATION_PHYSICAL or REPLICATION_LOGICAL");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,6 +190,3 @@ PyTypeObject replicationConnectionType = {
|
||||||
0, /*tp_alloc*/
|
0, /*tp_alloc*/
|
||||||
0, /*tp_new*/
|
0, /*tp_new*/
|
||||||
};
|
};
|
||||||
|
|
||||||
PyObject *replicationPhysicalConst;
|
|
||||||
PyObject *replicationLogicalConst;
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ psyco_repl_curs_consume_stream(replicationCursorObject *self,
|
||||||
"read_message() -- Try reading a replication message from the server (non-blocking)."
|
"read_message() -- Try reading a replication message from the server (non-blocking)."
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_repl_curs_read_message(replicationCursorObject *self)
|
psyco_repl_curs_read_message(replicationCursorObject *self, PyObject *dummy)
|
||||||
{
|
{
|
||||||
cursorObject *curs = &self->cur;
|
cursorObject *curs = &self->cur;
|
||||||
replicationMessageObject *msg = NULL;
|
replicationMessageObject *msg = NULL;
|
||||||
|
|
|
@ -58,12 +58,17 @@ replmsg_repr(replicationMessageObject *self)
|
||||||
static int
|
static int
|
||||||
replmsg_init(PyObject *obj, PyObject *args, PyObject *kwargs)
|
replmsg_init(PyObject *obj, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
replicationMessageObject *self = (replicationMessageObject*) obj;
|
PyObject *cur = NULL;
|
||||||
|
replicationMessageObject *self = (replicationMessageObject *)obj;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O!O", &cursorType, &self->cursor, &self->payload))
|
if (!PyArg_ParseTuple(
|
||||||
|
args, "O!O", &cursorType, &cur, &self->payload)) {
|
||||||
return -1;
|
return -1;
|
||||||
Py_XINCREF(self->cursor);
|
}
|
||||||
Py_XINCREF(self->payload);
|
|
||||||
|
Py_INCREF(cur);
|
||||||
|
self->cursor = (cursorObject *)cur;
|
||||||
|
Py_INCREF(self->payload);
|
||||||
|
|
||||||
self->data_size = 0;
|
self->data_size = 0;
|
||||||
self->data_start = 0;
|
self->data_start = 0;
|
||||||
|
@ -76,7 +81,7 @@ replmsg_init(PyObject *obj, PyObject *args, PyObject *kwargs)
|
||||||
static int
|
static int
|
||||||
replmsg_traverse(replicationMessageObject *self, visitproc visit, void *arg)
|
replmsg_traverse(replicationMessageObject *self, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
Py_VISIT((PyObject* )self->cursor);
|
Py_VISIT((PyObject *)self->cursor);
|
||||||
Py_VISIT(self->payload);
|
Py_VISIT(self->payload);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,6 +148,7 @@ typecast_DECIMAL_cast(const char *s, Py_ssize_t len, PyObject *curs)
|
||||||
Py_DECREF(decimalType);
|
Py_DECREF(decimalType);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
PyErr_Clear();
|
||||||
res = PyObject_CallFunction((PyObject*)&PyFloat_Type, "s", buffer);
|
res = PyObject_CallFunction((PyObject*)&PyFloat_Type, "s", buffer);
|
||||||
}
|
}
|
||||||
PyMem_Free(buffer);
|
PyMem_Free(buffer);
|
||||||
|
|
125
psycopg/utils.c
125
psycopg/utils.c
|
@ -27,7 +27,9 @@
|
||||||
#include "psycopg/psycopg.h"
|
#include "psycopg/psycopg.h"
|
||||||
|
|
||||||
#include "psycopg/connection.h"
|
#include "psycopg/connection.h"
|
||||||
|
#include "psycopg/cursor.h"
|
||||||
#include "psycopg/pgtypes.h"
|
#include "psycopg/pgtypes.h"
|
||||||
|
#include "psycopg/error.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -55,9 +57,9 @@ psycopg_escape_string(connectionObject *conn, const char *from, Py_ssize_t len,
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
len = strlen(from);
|
len = strlen(from);
|
||||||
} else if (strchr(from, '\0') != from + len) {
|
} else if (strchr(from, '\0') != from + len) {
|
||||||
PyErr_Format(PyExc_ValueError, "A string literal cannot contain NUL (0x00) characters.");
|
PyErr_Format(PyExc_ValueError,
|
||||||
|
"A string literal cannot contain NUL (0x00) characters.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to == NULL) {
|
if (to == NULL) {
|
||||||
|
@ -69,11 +71,11 @@ psycopg_escape_string(connectionObject *conn, const char *from, Py_ssize_t len,
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
if (conn && conn->pgconn)
|
if (conn && conn->pgconn)
|
||||||
ql = PQescapeStringConn(conn->pgconn, to+eq+1, from, len, &err);
|
ql = PQescapeStringConn(conn->pgconn, to+eq+1, from, len, &err);
|
||||||
else
|
else
|
||||||
ql = PQescapeString(to+eq+1, from, len);
|
ql = PQescapeString(to+eq+1, from, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eq) {
|
if (eq) {
|
||||||
|
@ -356,3 +358,110 @@ exit:
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* psyco_set_error
|
||||||
|
*
|
||||||
|
* Create a new error of the given type with extra attributes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
RAISES BORROWED PyObject *
|
||||||
|
psyco_set_error(PyObject *exc, cursorObject *curs, const char *msg)
|
||||||
|
{
|
||||||
|
PyObject *pymsg;
|
||||||
|
PyObject *err = NULL;
|
||||||
|
connectionObject *conn = NULL;
|
||||||
|
|
||||||
|
if (curs) {
|
||||||
|
conn = ((cursorObject *)curs)->conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pymsg = conn_text_from_chars(conn, msg))) {
|
||||||
|
err = PyObject_CallFunctionObjArgs(exc, pymsg, NULL);
|
||||||
|
Py_DECREF(pymsg);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* what's better than an error in an error handler in the morning?
|
||||||
|
* Anyway, some error was set, refcount is ok... get outta here. */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err && PyObject_TypeCheck(err, &errorType)) {
|
||||||
|
errorObject *perr = (errorObject *)err;
|
||||||
|
if (curs) {
|
||||||
|
Py_CLEAR(perr->cursor);
|
||||||
|
Py_INCREF(curs);
|
||||||
|
perr->cursor = curs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
PyErr_SetObject(exc, err);
|
||||||
|
Py_DECREF(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return nonzero if the current one is the main interpreter */
|
||||||
|
static int
|
||||||
|
psyco_is_main_interp(void)
|
||||||
|
{
|
||||||
|
static PyInterpreterState *main_interp = NULL; /* Cached reference */
|
||||||
|
PyInterpreterState *interp;
|
||||||
|
|
||||||
|
if (main_interp) {
|
||||||
|
return (main_interp == PyThreadState_Get()->interp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No cached value: cache the proper value and try again. */
|
||||||
|
interp = PyInterpreterState_Head();
|
||||||
|
while (interp->next)
|
||||||
|
interp = interp->next;
|
||||||
|
|
||||||
|
main_interp = interp;
|
||||||
|
assert (main_interp);
|
||||||
|
return psyco_is_main_interp();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* psyco_GetDecimalType
|
||||||
|
|
||||||
|
Return a new reference to the decimal type.
|
||||||
|
|
||||||
|
The function returns a cached version of the object, but only in the main
|
||||||
|
interpreter because subinterpreters are confusing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
psyco_GetDecimalType(void)
|
||||||
|
{
|
||||||
|
static PyObject *cachedType = NULL;
|
||||||
|
PyObject *decimalType = NULL;
|
||||||
|
PyObject *decimal;
|
||||||
|
|
||||||
|
/* Use the cached object if running from the main interpreter. */
|
||||||
|
int can_cache = psyco_is_main_interp();
|
||||||
|
if (can_cache && cachedType) {
|
||||||
|
Py_INCREF(cachedType);
|
||||||
|
return cachedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a new reference to the Decimal type. */
|
||||||
|
decimal = PyImport_ImportModule("decimal");
|
||||||
|
if (decimal) {
|
||||||
|
decimalType = PyObject_GetAttrString(decimal, "Decimal");
|
||||||
|
Py_DECREF(decimal);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
decimalType = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the object from future uses. */
|
||||||
|
if (can_cache && !cachedType && decimalType) {
|
||||||
|
Py_INCREF(decimalType);
|
||||||
|
cachedType = decimalType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return decimalType;
|
||||||
|
}
|
||||||
|
|
61
psycopg/utils.h
Normal file
61
psycopg/utils.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/* utils.h - function definitions for utility file
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018 Daniele Varrazzo <daniele.varrazzo@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of psycopg.
|
||||||
|
*
|
||||||
|
* psycopg2 is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give
|
||||||
|
* permission to link this program with the OpenSSL library (or with
|
||||||
|
* modified versions of OpenSSL that use the same license as OpenSSL),
|
||||||
|
* and distribute linked combinations including the two.
|
||||||
|
*
|
||||||
|
* You must obey the GNU Lesser General Public License in all respects for
|
||||||
|
* all of the code used other than OpenSSL.
|
||||||
|
*
|
||||||
|
* psycopg2 is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UTILS_H
|
||||||
|
#define UTILS_H 1
|
||||||
|
|
||||||
|
/* forward declarations */
|
||||||
|
typedef struct cursorObject cursorObject;
|
||||||
|
typedef struct connectionObject connectionObject;
|
||||||
|
typedef struct replicationMessageObject replicationMessageObject;
|
||||||
|
|
||||||
|
HIDDEN char *psycopg_escape_string(
|
||||||
|
connectionObject *conn,
|
||||||
|
const char *from, Py_ssize_t len, char *to, Py_ssize_t *tolen);
|
||||||
|
|
||||||
|
HIDDEN char *psycopg_escape_identifier(
|
||||||
|
connectionObject *conn, const char *str, Py_ssize_t len);
|
||||||
|
|
||||||
|
HIDDEN int psycopg_strdup(char **to, const char *from, Py_ssize_t len);
|
||||||
|
|
||||||
|
STEALS(1) HIDDEN PyObject * psycopg_ensure_bytes(PyObject *obj);
|
||||||
|
STEALS(1) HIDDEN PyObject * psycopg_ensure_text(PyObject *obj);
|
||||||
|
|
||||||
|
HIDDEN int psycopg_is_text_file(PyObject *f);
|
||||||
|
|
||||||
|
HIDDEN PyObject *psycopg_dict_from_conninfo_options(
|
||||||
|
PQconninfoOption *options, int include_password);
|
||||||
|
|
||||||
|
HIDDEN PyObject *psycopg_make_dsn(PyObject *dsn, PyObject *kwargs);
|
||||||
|
|
||||||
|
HIDDEN PyObject *psycopg_text_from_chars_safe(
|
||||||
|
const char *str, Py_ssize_t len, PyObject *decoder);
|
||||||
|
|
||||||
|
HIDDEN RAISES BORROWED PyObject *psyco_set_error(
|
||||||
|
PyObject *exc, cursorObject *curs, const char *msg);
|
||||||
|
|
||||||
|
HIDDEN PyObject *psyco_GetDecimalType(void);
|
||||||
|
|
||||||
|
#endif /* !defined(UTILS_H) */
|
2
setup.py
2
setup.py
|
@ -509,7 +509,7 @@ depends = [
|
||||||
'replication_cursor.h',
|
'replication_cursor.h',
|
||||||
'replication_message.h',
|
'replication_message.h',
|
||||||
'notify.h', 'pqpath.h', 'xid.h', 'column.h', 'conninfo.h',
|
'notify.h', 'pqpath.h', 'xid.h', 'column.h', 'conninfo.h',
|
||||||
'libpq_support.h', 'win32_support.h',
|
'libpq_support.h', 'win32_support.h', 'utils.h',
|
||||||
|
|
||||||
'adapter_asis.h', 'adapter_binary.h', 'adapter_datetime.h',
|
'adapter_asis.h', 'adapter_binary.h', 'adapter_datetime.h',
|
||||||
'adapter_list.h', 'adapter_pboolean.h', 'adapter_pdecimal.h',
|
'adapter_list.h', 'adapter_pboolean.h', 'adapter_pdecimal.h',
|
||||||
|
|
Loading…
Reference in New Issue
Block a user