Changeset 953 for trunk/pgmodule.c


Ignore:
Timestamp:
Jan 3, 2019, 3:38:57 PM (8 months ago)
Author:
cito
Message:

Add special methods for using prepared statements

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/pgmodule.c

    r952 r953  
    21422142
    21432143/* database query */
    2144 static char connQuery__doc__[] =
    2145 "query(sql, [arg]) -- create a new query object for this connection\n\n"
    2146 "You must pass the SQL (string) request and you can optionally pass\n"
    2147 "a tuple with positional parameters.\n";
    2148 
    2149 static PyObject *
    2150 connQuery(connObject *self, PyObject *args)
     2144
     2145/* base method for execution of both unprepared and prepared queries */
     2146static PyObject *
     2147_connQuery(connObject *self, PyObject *args, int prepared)
    21512148{
    21522149        PyObject        *query_obj;
     
    22882285
    22892286                Py_BEGIN_ALLOW_THREADS
    2290                 result = PQexecParams(self->cnx, query, nparms,
    2291                         NULL, parms, NULL, NULL, 0);
     2287                result = prepared ?
     2288                        PQexecPrepared(self->cnx, query, nparms,
     2289                                parms, NULL, NULL, 0) :
     2290                        PQexecParams(self->cnx, query, nparms,
     2291                                NULL, parms, NULL, NULL, 0);
    22922292                Py_END_ALLOW_THREADS
    22932293
     
    22992299        {
    23002300                Py_BEGIN_ALLOW_THREADS
    2301                 result = PQexec(self->cnx, query);
     2301                result = prepared ?
     2302                        PQexecPrepared(self->cnx, query, 0,
     2303                                NULL, NULL, NULL, 0) :
     2304                        PQexec(self->cnx, query);
    23022305                Py_END_ALLOW_THREADS
    23032306        }
     
    23772380}
    23782381
     2382/* database query */
     2383static char connQuery__doc__[] =
     2384"query(sql, [arg]) -- create a new query object for this connection\n\n"
     2385"You must pass the SQL (string) request and you can optionally pass\n"
     2386"a tuple with positional parameters.\n";
     2387
     2388static PyObject *
     2389connQuery(connObject *self, PyObject *args)
     2390{
     2391        return _connQuery(self, args, 0);
     2392}
     2393
     2394/* execute prepared statement */
     2395static char connQueryPrepared__doc__[] =
     2396"query_prepared(name, [arg]) -- execute a prepared statement\n\n"
     2397"You must pass the name (string) of the prepared statement and you can\n"
     2398"optionally pass a tuple with positional parameters.\n";
     2399
     2400static PyObject *
     2401connQueryPrepared(connObject *self, PyObject *args)
     2402{
     2403        return _connQuery(self, args, 1);
     2404}
     2405
     2406/* create prepared statement */
     2407static char connPrepare__doc__[] =
     2408"prepare(name, sql) -- create a prepared statement\n\n"
     2409"You must pass the name (string) of the prepared statement and the\n"
     2410"SQL (string) request for later execution.\n";
     2411
     2412static PyObject *
     2413connPrepare(connObject *self, PyObject *args)
     2414{
     2415        char            *name, *query;
     2416        int             name_length, query_length;
     2417        PGresult        *result;
     2418
     2419        if (!self->cnx)
     2420        {
     2421                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
     2422                return NULL;
     2423        }
     2424
     2425        /* reads args */
     2426        if (!PyArg_ParseTuple(args, "s#s#",
     2427                &name, &name_length, &query, &query_length))
     2428        {
     2429                PyErr_SetString(PyExc_TypeError,
     2430                        "Method prepare() takes two string arguments");
     2431                return NULL;
     2432        }
     2433
     2434        /* create prepared statement */
     2435        Py_BEGIN_ALLOW_THREADS
     2436        result = PQprepare(self->cnx, name, query, 0, NULL);
     2437        Py_END_ALLOW_THREADS
     2438        if (result && PQresultStatus(result) == PGRES_COMMAND_OK)
     2439        {
     2440                PQclear(result);
     2441                Py_INCREF(Py_None);
     2442                return Py_None; /* success */
     2443        }
     2444        set_error(ProgrammingError, "Cannot create prepared statement",
     2445                self->cnx, result);
     2446        if (result)
     2447                PQclear(result);
     2448        return NULL; /* error */
     2449}
     2450
     2451/* describe prepared statement */
     2452static char connDescribePrepared__doc__[] =
     2453"describe_prepared(name, sql) -- describe a prepared statement\n\n"
     2454"You must pass the name (string) of the prepared statement.\n";
     2455
     2456static PyObject *
     2457connDescribePrepared(connObject *self, PyObject *args)
     2458{
     2459        char            *name;
     2460        int             name_length;
     2461        PGresult        *result;
     2462
     2463        if (!self->cnx)
     2464        {
     2465                PyErr_SetString(PyExc_TypeError, "Connection is not valid");
     2466                return NULL;
     2467        }
     2468
     2469        /* reads args */
     2470        if (!PyArg_ParseTuple(args, "s#",
     2471                &name, &name_length))
     2472        {
     2473                PyErr_SetString(PyExc_TypeError,
     2474                        "Method prepare() takes a string argument");
     2475                return NULL;
     2476        }
     2477
     2478        /* describe prepared statement */
     2479        Py_BEGIN_ALLOW_THREADS
     2480        result = PQdescribePrepared(self->cnx, name);
     2481        Py_END_ALLOW_THREADS
     2482        if (result && PQresultStatus(result) == PGRES_COMMAND_OK)
     2483        {
     2484                queryObject *npgobj = PyObject_NEW(queryObject, &queryType);
     2485                if (!npgobj)
     2486                        return PyErr_NoMemory();
     2487                Py_XINCREF(self);
     2488                npgobj->pgcnx = self;
     2489                npgobj->result = result;
     2490                return (PyObject *) npgobj;
     2491        }
     2492        set_error(ProgrammingError, "Cannot describe prepared statement",
     2493                self->cnx, result);
     2494        if (result)
     2495                PQclear(result);
     2496        return NULL; /* error */
     2497}
     2498
    23792499#ifdef DIRECT_ACCESS
    23802500static char connPutLine__doc__[] =
     
    34153535        {"source", (PyCFunction) connSource, METH_NOARGS, connSource__doc__},
    34163536        {"query", (PyCFunction) connQuery, METH_VARARGS, connQuery__doc__},
     3537        {"query_prepared", (PyCFunction) connQueryPrepared, METH_VARARGS,
     3538                        connQueryPrepared__doc__},
     3539        {"prepare", (PyCFunction) connPrepare, METH_VARARGS, connPrepare__doc__},
     3540        {"describe_prepared", (PyCFunction) connDescribePrepared, METH_VARARGS,
     3541                        connDescribePrepared__doc__},
    34173542        {"reset", (PyCFunction) connReset, METH_NOARGS, connReset__doc__},
    34183543        {"cancel", (PyCFunction) connCancel, METH_NOARGS, connCancel__doc__},
Note: See TracChangeset for help on using the changeset viewer.