Ejemplo n.º 1
0
/* Convert a PostgreSQL encoding to a Python codec.
 *
 * Set 'codec' to a new copy of the codec name allocated on the Python heap.
 * Return 0 in case of success, else -1 and set an exception.
 *
 * 'enc' should be already normalized (uppercase, no - or _).
 */
RAISES_NEG static int
conn_encoding_to_codec(const char *enc, char **codec)
{
    char *tmp;
    Py_ssize_t size;
    PyObject *pyenc = NULL;
    int rv = -1;

    /* Find the Py codec name from the PG encoding */
    if (!(pyenc = PyDict_GetItemString(psycoEncodings, enc))) {
        PyErr_Format(OperationalError,
            "no Python codec for client encoding '%s'", enc);
        goto exit;
    }

    /* Convert the codec in a bytes string to extract the c string. */
    Py_INCREF(pyenc);
    if (!(pyenc = psycopg_ensure_bytes(pyenc))) {
        goto exit;
    }

    if (-1 == Bytes_AsStringAndSize(pyenc, &tmp, &size)) {
        goto exit;
    }

    /* have our own copy of the python codec name */
    rv = psycopg_strdup(codec, tmp, size);

exit:
    Py_XDECREF(pyenc);
    return rv;
}
Ejemplo n.º 2
0
static PyObject *
psyco_lobj_write(lobjectObject *self, PyObject *args)
{
    char *buffer;
    Py_ssize_t len;
    Py_ssize_t res;
    PyObject *obj;
    PyObject *data = NULL;
    PyObject *rv = NULL;

    if (!PyArg_ParseTuple(args, "O", &obj)) return NULL;

    EXC_IF_LOBJ_CLOSED(self);
    EXC_IF_LOBJ_LEVEL0(self);
    EXC_IF_LOBJ_UNMARKED(self);

    if (Bytes_Check(obj)) {
        Py_INCREF(obj);
        data = obj;
    }
    else if (PyUnicode_Check(obj)) {
        if (!(data = PyUnicode_AsEncodedString(obj, self->conn->codec, NULL))) {
            goto exit;
        }
    }
    else {
        PyErr_Format(PyExc_TypeError,
            "lobject.write requires a string; got %s instead",
            Py_TYPE(obj)->tp_name);
        goto exit;
    }

    if (-1 == Bytes_AsStringAndSize(data, &buffer, &len)) {
        goto exit;
    }

    if (0 > (res = lobject_write(self, buffer, (size_t)len))) {
        goto exit;
    }

    rv = PyInt_FromLong((long)res);

exit:
    Py_XDECREF(data);
    return rv;
}
static PyObject *
qstring_quote(qstringObject *self)
{
    PyObject *str = NULL;
    char *s, *buffer = NULL;
    Py_ssize_t len, qlen;
    const char *encoding = default_encoding;
    PyObject *rv = NULL;

    /* if the wrapped object is an unicode object we can encode it to match
       conn->encoding but if the encoding is not specified we don't know what
       to do and we raise an exception */
    if (self->conn) {
        encoding = self->conn->codec;
    }

    Dprintf("qstring_quote: encoding to %s", encoding);

    if (PyUnicode_Check(self->wrapped) && encoding) {
        str = PyUnicode_AsEncodedString(self->wrapped, encoding, NULL);
        Dprintf("qstring_quote: got encoded object at %p", str);
        if (str == NULL) goto exit;
    }

#if PY_MAJOR_VERSION < 3
    /* if the wrapped object is a simple string, we don't know how to
       (re)encode it, so we pass it as-is */
    else if (PyString_Check(self->wrapped)) {
        str = self->wrapped;
        /* INCREF to make it ref-wise identical to unicode one */
        Py_INCREF(str);
    }
#endif

    /* if the wrapped object is not a string, this is an error */
    else {
        PyErr_SetString(PyExc_TypeError,
                        "can't quote non-string object (or missing encoding)");
        goto exit;
    }

    /* encode the string into buffer */
    Bytes_AsStringAndSize(str, &s, &len);
    if (!(buffer = psycopg_escape_string(self->conn, s, len, NULL, &qlen))) {
        goto exit;
    }

    if (qlen > (size_t) PY_SSIZE_T_MAX) {
        PyErr_SetString(PyExc_IndexError,
            "PG buffer too large to fit in Python buffer.");
        goto exit;
    }

    rv = Bytes_FromStringAndSize(buffer, qlen);

exit:
    PyMem_Free(buffer);
    Py_XDECREF(str);

    return rv;
}