@ -37,6 +37,8 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include "psycopg/typecast.h"
|
||||||
|
#include "psycopg/typecast_basic.c"
|
||||||
|
|
||||||
extern HIDDEN const char *srv_isolevels[];
|
extern HIDDEN const char *srv_isolevels[];
|
||||||
extern HIDDEN const char *srv_readonly[];
|
extern HIDDEN const char *srv_readonly[];
|
||||||
@ -1314,6 +1316,54 @@ static struct PyGetSetDef connectionObject_getsets[] = {
|
|||||||
};
|
};
|
||||||
#undef EXCEPTION_GETTER
|
#undef EXCEPTION_GETTER
|
||||||
|
|
||||||
|
|
||||||
|
/* register the uint typecasters */
|
||||||
|
static int
|
||||||
|
register_type_uint(connectionObject *self, PyThreadState **tstate)
|
||||||
|
{
|
||||||
|
int rv = -1;
|
||||||
|
typecastObject *obj = NULL;
|
||||||
|
PyObject *name = NULL, *values = NULL;
|
||||||
|
Py_ssize_t i, len = 0;
|
||||||
|
|
||||||
|
char* uint_arr[] = {"\'uint1\'", "\'uint2\'", "\'uint4\'", "\'uint8\'"};
|
||||||
|
int size = sizeof(uint_arr) / sizeof(uint_arr[0]);
|
||||||
|
long int* _typecast_INTEGER_types;
|
||||||
|
_typecast_INTEGER_types = (long int*)malloc((size+1)*sizeof(long int));
|
||||||
|
|
||||||
|
for (int i=0; i< size; i++) {
|
||||||
|
unsigned int uint_val = pq_get_custom_type_oid(self, uint_arr[i], tstate);
|
||||||
|
_typecast_INTEGER_types[i] = (long int)uint_val;
|
||||||
|
}
|
||||||
|
typecastObject_initlist _typecast_builtins[] = {
|
||||||
|
{"INTEGER", _typecast_INTEGER_types, typecast_INTEGER_cast, NULL},
|
||||||
|
};
|
||||||
|
name = Text_FromUTF8(_typecast_builtins->name);
|
||||||
|
if (!name) goto end;
|
||||||
|
|
||||||
|
while (_typecast_builtins->values[len] != 0) len++;
|
||||||
|
|
||||||
|
values = PyTuple_New(len);
|
||||||
|
if (!values) goto end;
|
||||||
|
|
||||||
|
for (i = 0; i < len ; i++) {
|
||||||
|
PyTuple_SET_ITEM(values, i, PyInt_FromLong(_typecast_builtins->values[i]));
|
||||||
|
}
|
||||||
|
obj = (typecastObject *)typecast_new(name, values, NULL, NULL);
|
||||||
|
if (obj) {
|
||||||
|
obj->ccast = _typecast_builtins->cast;
|
||||||
|
obj->pcast = NULL;
|
||||||
|
}
|
||||||
|
if (typecast_add((PyObject *)obj, self->string_types, 0) < 0) { goto end; }
|
||||||
|
rv = 0;
|
||||||
|
free(_typecast_INTEGER_types);
|
||||||
|
end:
|
||||||
|
Py_XDECREF(values);
|
||||||
|
Py_XDECREF(name);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* initialization and finalization methods */
|
/* initialization and finalization methods */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1364,6 +1414,7 @@ connection_setup(connectionObject *self, const char *dsn, long int async)
|
|||||||
Py_BEGIN_ALLOW_THREADS;
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
pthread_mutex_lock(&self->lock);
|
pthread_mutex_lock(&self->lock);
|
||||||
sql_compatibility_value = pq_get_guc_locked(self, "sql_compatibility", &_save);
|
sql_compatibility_value = pq_get_guc_locked(self, "sql_compatibility", &_save);
|
||||||
|
if (register_type_uint(self, &_save)) { goto exit; }
|
||||||
pthread_mutex_unlock(&self->lock);
|
pthread_mutex_unlock(&self->lock);
|
||||||
Py_END_ALLOW_THREADS;
|
Py_END_ALLOW_THREADS;
|
||||||
|
|
||||||
|
|||||||
@ -43,7 +43,7 @@
|
|||||||
#include "psycopg/pgtypes.h"
|
#include "psycopg/pgtypes.h"
|
||||||
#include "psycopg/error.h"
|
#include "psycopg/error.h"
|
||||||
#include "psycopg/column.h"
|
#include "psycopg/column.h"
|
||||||
|
#include <stdlib.h>
|
||||||
#include "psycopg/libpq_support.h"
|
#include "psycopg/libpq_support.h"
|
||||||
#include "libpq-fe.h"
|
#include "libpq-fe.h"
|
||||||
|
|
||||||
@ -607,6 +607,51 @@ cleanup:
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
pq_get_custom_type_oid(connectionObject *conn, const char *param, PyThreadState **tstate)
|
||||||
|
{
|
||||||
|
char query[256];
|
||||||
|
int size;
|
||||||
|
unsigned int rv = 0;
|
||||||
|
|
||||||
|
size = PyOS_snprintf(query, sizeof(query), "select oid from pg_type where typname= %s", param);
|
||||||
|
if (size < 0 || (size_t)size >= sizeof(query)) {
|
||||||
|
conn_set_error(conn, "query too large");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!psyco_green()) {
|
||||||
|
conn_set_result(conn, PQexec(conn->pgconn, query));
|
||||||
|
} else {
|
||||||
|
PyEval_RestoreThread(*tstate);
|
||||||
|
conn_set_result(conn, psyco_exec_green(conn, query));
|
||||||
|
*tstate = PyEval_SaveThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!conn->pgres) {
|
||||||
|
Dprintf("pq_get_custom_type_oid: PQexec returned NULL");
|
||||||
|
PyEval_RestoreThread(*tstate);
|
||||||
|
if (!PyErr_Occurred()) {
|
||||||
|
conn_set_error(conn, PQerrorMessage(conn->pgconn));
|
||||||
|
}
|
||||||
|
*tstate = PyEval_SaveThread();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (PQresultStatus(conn->pgres) != PGRES_TUPLES_OK) {
|
||||||
|
Dprintf("pq_get_custom_type_oid: result was not TUPLES_OK (%s)",
|
||||||
|
PQresStatus(PQresultStatus(conn->pgres)));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = atoi(strdup(PQgetvalue(conn->pgres, 0, 0)));
|
||||||
|
CLEARPGRES(conn->pgres);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set a session parameter.
|
/* Set a session parameter.
|
||||||
*
|
*
|
||||||
* The function should be called on a locked connection without
|
* The function should be called on a locked connection without
|
||||||
|
|||||||
@ -459,7 +459,7 @@ PyTypeObject typecastType = {
|
|||||||
0, /*tp_new*/
|
0, /*tp_new*/
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *
|
PyObject *
|
||||||
typecast_new(PyObject *name, PyObject *values, PyObject *cast, PyObject *base)
|
typecast_new(PyObject *name, PyObject *values, PyObject *cast, PyObject *base)
|
||||||
{
|
{
|
||||||
typecastObject *obj;
|
typecastObject *obj;
|
||||||
|
|||||||
@ -89,3 +89,4 @@ HIDDEN PyObject *typecast_cast(
|
|||||||
PyObject *self, const char *str, Py_ssize_t len, PyObject *curs);
|
PyObject *self, const char *str, Py_ssize_t len, PyObject *curs);
|
||||||
|
|
||||||
#endif /* !defined(PSYCOPG_TYPECAST_H) */
|
#endif /* !defined(PSYCOPG_TYPECAST_H) */
|
||||||
|
PyObject *typecast_new(PyObject *name, PyObject *values, PyObject *cast, PyObject *base);
|
||||||
Reference in New Issue
Block a user