예제 #1
0
static PyObject *
psyco_conn_set_session(connectionObject *self, PyObject *args, PyObject *kwargs)
{
    PyObject *isolevel = Py_None;
    PyObject *readonly = Py_None;
    PyObject *deferrable = Py_None;
    PyObject *autocommit = Py_None;

    const char *c_isolevel = NULL;
    const char *c_readonly = NULL;
    const char *c_deferrable = NULL;
    int c_autocommit = self->autocommit;

    static char *kwlist[] =
        {"isolation_level", "readonly", "deferrable", "autocommit", NULL};

    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, set_session);
    EXC_IF_IN_TRANSACTION(self, set_session);

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOO", kwlist,
            &isolevel, &readonly, &deferrable, &autocommit)) {
        return NULL;
    }

    if (Py_None != isolevel) {
        if (!(c_isolevel = _psyco_conn_parse_isolevel(self, isolevel))) {
            return NULL;
        }
    }

    if (Py_None != readonly) {
        if (!(c_readonly = _psyco_conn_parse_onoff(readonly))) {
            return NULL;
        }
    }
    if (Py_None != deferrable) {
        if (self->server_version < 90100) {
            PyErr_SetString(ProgrammingError,
                "the 'deferrable' setting is only available"
                " from PostgreSQL 9.1");
            return NULL;
        }
        if (!(c_deferrable = _psyco_conn_parse_onoff(deferrable))) {
            return NULL;
        }
    }
    if (Py_None != autocommit) {
        c_autocommit = PyObject_IsTrue(autocommit);
        if (-1 == c_autocommit) { return NULL; }
    }

    if (0 > conn_set_session(self,
            c_isolevel, c_readonly, c_deferrable, c_autocommit)) {
        return NULL;
    }

    Py_INCREF(Py_None);
    return Py_None;
}
예제 #2
0
static PyObject *
psyco_conn_set_client_encoding(connectionObject *self, PyObject *args)
{
    const char *enc = NULL;
    char *buffer;
    size_t i, j;

    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, set_client_encoding);

    if (!PyArg_ParseTuple(args, "s", &enc)) return NULL;

    /* convert to upper case and remove '-' and '_' from string */
    buffer = PyMem_Malloc(strlen(enc)+1);
    for (i=j=0 ; i < strlen(enc) ; i++) {
        if (enc[i] == '_' || enc[i] == '-')
            continue;
        else
            buffer[j++] = toupper(enc[i]);
    }
    buffer[j] = '\0';

    if (conn_set_client_encoding(self, buffer) == 0) {
        PyMem_Free(buffer);
        Py_INCREF(Py_None);
        return Py_None;
    }
    else {
        PyMem_Free(buffer);
        return NULL;
    }
}
예제 #3
0
static PyObject *
psyco_conn_set_isolation_level(connectionObject *self, PyObject *args)
{
    int level = 1;

    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, set_isolation_level);

    if (!PyArg_ParseTuple(args, "i", &level)) return NULL;

    if (level < 0 || level > 2) {
        PyErr_SetString(PyExc_ValueError,
                        "isolation level out of bounds (0,3)");
        return NULL;
    }

    if (conn_switch_isolation_level(self, level) < 0) {
        PyErr_SetString(OperationalError,
                        PQerrorMessage(self->pgconn));
        return NULL;
    }


    Py_INCREF(Py_None);
    return Py_None;
}
예제 #4
0
static PyObject *
psyco_conn_tpc_commit(connectionObject *self, PyObject *args)
{
    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, tpc_commit);
    EXC_IF_TPC_NOT_SUPPORTED(self);

    return _psyco_conn_tpc_finish(self, args,
                                  conn_commit, "COMMIT PREPARED");
}
예제 #5
0
static PyObject *
psyco_conn_tpc_rollback(connectionObject *self, PyObject *args)
{
    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, tpc_rollback);
    EXC_IF_TPC_NOT_SUPPORTED(self);

    return _psyco_conn_tpc_finish(self, args,
                                  conn_rollback, "ROLLBACK PREPARED");
}
예제 #6
0
static PyObject *
psyco_conn_tpc_recover(connectionObject *self)
{
    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, tpc_recover);
    EXC_IF_TPC_PREPARED(self, tpc_recover);
    EXC_IF_TPC_NOT_SUPPORTED(self);

    return conn_tpc_recover(self);
}
예제 #7
0
BORROWED static PyObject *
_psyco_conn_autocommit_set_checks(connectionObject *self)
{
    /* wrapper to use the EXC_IF macros.
     * return NULL in case of error, else whatever */
    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, autocommit);
    EXC_IF_IN_TRANSACTION(self, autocommit);
    return Py_None;     /* borrowed */
}
예제 #8
0
static PyObject *
psyco_conn_rollback(connectionObject *self)
{
    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, rollback);
    EXC_IF_TPC_BEGIN(self, rollback);

    if (conn_rollback(self) < 0)
        return NULL;

    Py_RETURN_NONE;
}
예제 #9
0
static PyObject *
psyco_conn_commit(connectionObject *self, PyObject *dummy)
{
    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, commit);
    EXC_IF_TPC_BEGIN(self, commit);

    if (conn_commit(self) < 0)
        return NULL;

    Py_RETURN_NONE;
}
예제 #10
0
static PyObject *
psyco_conn_rollback(connectionObject *self, PyObject *args)
{
    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, rollback);
    EXC_IF_TPC_BEGIN(self, rollback);

    if (conn_rollback(self) < 0)
        return NULL;

    Py_INCREF(Py_None);
    return Py_None;
}
예제 #11
0
static PyObject *
psyco_conn_rollback(connectionObject *self, PyObject *args)
{
    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, rollback);

    if (!PyArg_ParseTuple(args, "")) return NULL;

    if (conn_rollback(self) < 0)
        return NULL;

    Py_INCREF(Py_None);
    return Py_None;
}
예제 #12
0
static PyObject *
psyco_conn_lobject(connectionObject *self, PyObject *args, PyObject *keywds)
{
    Oid oid = InvalidOid, new_oid = InvalidOid;
    const char *new_file = NULL;
    const char *smode = "";
    PyObject *factory = (PyObject *)&lobjectType;
    PyObject *obj;

    static char *kwlist[] = {"oid", "mode", "new_oid", "new_file",
                             "lobject_factory", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, keywds, "|IzIzO", kwlist,
                                     &oid, &smode, &new_oid, &new_file,
                                     &factory)) {
        return NULL;
    }

    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, lobject);
    EXC_IF_GREEN(lobject);
    EXC_IF_TPC_PREPARED(self, lobject);

    Dprintf("psyco_conn_lobject: new lobject for connection at %p", self);
    Dprintf("psyco_conn_lobject:     parameters: oid = %u, mode = %s",
            oid, smode);
    Dprintf("psyco_conn_lobject:     parameters: new_oid = %d, new_file = %s",
            new_oid, new_file);

    if (new_file)
        obj = PyObject_CallFunction(factory, "OIsIs",
            self, oid, smode, new_oid, new_file);
    else
        obj = PyObject_CallFunction(factory, "OIsI",
            self, oid, smode, new_oid);

    if (obj == NULL) return NULL;
    if (PyObject_IsInstance(obj, (PyObject *)&lobjectType) == 0) {
        PyErr_SetString(PyExc_TypeError,
            "lobject factory must be subclass of psycopg2.extensions.lobject");
        Py_DECREF(obj);
        return NULL;
    }

    Dprintf("psyco_conn_lobject: new lobject at %p: refcnt = "
            FORMAT_CODE_PY_SSIZE_T,
            obj, Py_REFCNT(obj));
    return obj;
}
예제 #13
0
static PyObject *
psyco_conn_reset(connectionObject *self)
{
    int res;

    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, reset);

    if (pq_reset(self) < 0)
        return NULL;

    res = conn_setup(self, self->pgconn);
    if (res < 0)
        return NULL;

    Py_RETURN_NONE;
}
예제 #14
0
static PyObject *
psyco_conn_set_isolation_level(connectionObject *self, PyObject *args)
{
    int level = 1;
    PyObject *pyval = NULL;

    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, "isolation_level");
    EXC_IF_TPC_PREPARED(self, "isolation_level");

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

    if (pyval == Py_None) {
        level = ISOLATION_LEVEL_DEFAULT;
    }

    /* parse from one of the level constants */
    else if (PyInt_Check(pyval)) {
        level = PyInt_AsLong(pyval);

        if (level < 0 || level > 4) {
            PyErr_SetString(PyExc_ValueError,
                "isolation level must be between 0 and 4");
            return NULL;
        }
    }

    if (0 > conn_rollback(self)) {
        return NULL;
    }

    if (level == 0) {
        if (0 > conn_set_session(self, 1,
                self->isolevel, self->readonly, self->deferrable)) {
            return NULL;
        }
    }
    else {
        if (0 > conn_set_session(self, 0,
                level, self->readonly, self->deferrable)) {
            return NULL;
        }
    }

    Py_RETURN_NONE;
}
예제 #15
0
static PyObject *
psyco_conn_set_client_encoding(connectionObject *self, PyObject *args)
{
    const char *enc;
    PyObject *rv = NULL;

    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, set_client_encoding);
    EXC_IF_TPC_PREPARED(self, set_client_encoding);

    if (!PyArg_ParseTuple(args, "s", &enc)) return NULL;

    if (conn_set_client_encoding(self, enc) >= 0) {
        Py_INCREF(Py_None);
        rv = Py_None;
    }
    return rv;
}
예제 #16
0
static PyObject *
psyco_conn_reset(connectionObject *self, PyObject *args)
{
    int res;

    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, reset);

    if (pq_reset(self) < 0)
        return NULL;

    res = conn_setup(self, self->pgconn);
    if (res < 0)
        return NULL;

    Py_INCREF(Py_None);
    return Py_None;
}
예제 #17
0
static PyObject *
psyco_conn_tpc_begin(connectionObject *self, PyObject *args)
{
    PyObject *rv = NULL;
    xidObject *xid = NULL;
    PyObject *oxid;

    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, tpc_begin);
    EXC_IF_TPC_NOT_SUPPORTED(self);
    EXC_IF_IN_TRANSACTION(self, tpc_begin);

    if (!PyArg_ParseTuple(args, "O", &oxid)) {
        goto exit;
    }

    if (NULL == (xid = xid_ensure(oxid))) {
        goto exit;
    }

    /* two phase commit and autocommit make no point */
    if (self->autocommit) {
        PyErr_SetString(ProgrammingError,
            "tpc_begin can't be called in autocommit mode");
        goto exit;
    }

    if (conn_tpc_begin(self, xid) < 0) {
        goto exit;
    }

    Py_INCREF(Py_None);
    rv = Py_None;

exit:
    Py_XDECREF(xid);
    return rv;
}
예제 #18
0
static PyObject *
psyco_conn_tpc_prepare(connectionObject *self)
{
    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, tpc_prepare);
    EXC_IF_TPC_PREPARED(self, tpc_prepare);

    if (NULL == self->tpc_xid) {
        PyErr_SetString(ProgrammingError,
            "prepare must be called inside a two-phase transaction");
        return NULL;
    }

    if (0 > conn_tpc_command(self, "PREPARE TRANSACTION", self->tpc_xid)) {
        return NULL;
    }

    /* transaction prepared: set the state so that no operation
     * can be performed until commit. */
    self->status = CONN_STATUS_PREPARED;

    Py_RETURN_NONE;
}
예제 #19
0
static PyObject *
psyco_conn_set_isolation_level(connectionObject *self, PyObject *args)
{
    int level = 1;

    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, set_isolation_level);
    EXC_IF_TPC_PREPARED(self, set_isolation_level);

    if (!PyArg_ParseTuple(args, "i", &level)) return NULL;

    if (level < 0 || level > 4) {
        PyErr_SetString(PyExc_ValueError,
            "isolation level must be between 0 and 4");
        return NULL;
    }

    if (conn_switch_isolation_level(self, level) < 0) {
        return NULL;
    }

    Py_RETURN_NONE;
}
예제 #20
0
static PyObject *
psyco_conn_lobject(connectionObject *self, PyObject *args, PyObject *keywds)
{
    Oid oid=InvalidOid, new_oid=InvalidOid;
    char *smode = NULL, *new_file = NULL;
    int mode=0;
    PyObject *obj, *factory = NULL;

    static char *kwlist[] = {"oid", "mode", "new_oid", "new_file",
                             "cursor_factory", NULL};
    
    if (!PyArg_ParseTupleAndKeywords(args, keywds, "|izizO", kwlist,
                                     &oid, &smode, &new_oid, &new_file, 
                                     &factory)) {
        return NULL;
    }

    EXC_IF_CONN_CLOSED(self);
    EXC_IF_CONN_ASYNC(self, lobject);
    EXC_IF_GREEN(lobject);

    Dprintf("psyco_conn_lobject: new lobject for connection at %p", self);
    Dprintf("psyco_conn_lobject:     parameters: oid = %d, mode = %s",
            oid, smode);
    Dprintf("psyco_conn_lobject:     parameters: new_oid = %d, new_file = %s",
            new_oid, new_file);
    
    /* build a mode number out of the mode string: right now we only accept
       'r', 'w' and 'rw' (but note that 'w' implies 'rw' because PostgreSQL
       backend does that. */
    if (smode) {
        if (strncmp("rw", smode, 2) == 0)
            mode = INV_READ+INV_WRITE;
        else if (smode[0] == 'r')
           mode = INV_READ;
        else if (smode[0] == 'w')
           mode = INV_WRITE;
        else if (smode[0] == 'n')
           mode = -1;
        else {
            PyErr_SetString(PyExc_TypeError,
                "mode should be one of 'r', 'w' or 'rw'");
            return NULL;
        }
    }

    if (factory == NULL) factory = (PyObject *)&lobjectType;
    if (new_file)
        obj = PyObject_CallFunction(factory, "Oiiis", 
            self, oid, mode, new_oid, new_file);
    else
        obj = PyObject_CallFunction(factory, "Oiii",
            self, oid, mode, new_oid);

    if (obj == NULL) return NULL;
    if (PyObject_IsInstance(obj, (PyObject *)&lobjectType) == 0) {
        PyErr_SetString(PyExc_TypeError,
            "lobject factory must be subclass of psycopg2._psycopg.lobject");
        Py_DECREF(obj);
        return NULL;
    }
    
    Dprintf("psyco_conn_lobject: new lobject at %p: refcnt = "
            FORMAT_CODE_PY_SSIZE_T,
            obj, obj->ob_refcnt);
    return obj;
}