Header And Logo

PostgreSQL
| The world's most advanced open source database.

plpy_resultobject.c

Go to the documentation of this file.
00001 /*
00002  * the PLyResult class
00003  *
00004  * src/pl/plpython/plpy_resultobject.c
00005  */
00006 
00007 #include "postgres.h"
00008 
00009 #include "plpython.h"
00010 
00011 #include "plpy_resultobject.h"
00012 #include "plpy_elog.h"
00013 
00014 
00015 static void PLy_result_dealloc(PyObject *arg);
00016 static PyObject *PLy_result_colnames(PyObject *self, PyObject *unused);
00017 static PyObject *PLy_result_coltypes(PyObject *self, PyObject *unused);
00018 static PyObject *PLy_result_coltypmods(PyObject *self, PyObject *unused);
00019 static PyObject *PLy_result_nrows(PyObject *self, PyObject *args);
00020 static PyObject *PLy_result_status(PyObject *self, PyObject *args);
00021 static Py_ssize_t PLy_result_length(PyObject *arg);
00022 static PyObject *PLy_result_item(PyObject *arg, Py_ssize_t idx);
00023 static PyObject *PLy_result_slice(PyObject *arg, Py_ssize_t lidx, Py_ssize_t hidx);
00024 static int  PLy_result_ass_slice(PyObject *arg, Py_ssize_t lidx, Py_ssize_t hidx, PyObject *slice);
00025 static PyObject *PLy_result_str(PyObject *arg);
00026 static PyObject *PLy_result_subscript(PyObject *arg, PyObject *item);
00027 static int  PLy_result_ass_subscript(PyObject *self, PyObject *item, PyObject *value);
00028 
00029 static char PLy_result_doc[] = {
00030     "Results of a PostgreSQL query"
00031 };
00032 
00033 static PySequenceMethods PLy_result_as_sequence = {
00034     PLy_result_length,          /* sq_length */
00035     NULL,                       /* sq_concat */
00036     NULL,                       /* sq_repeat */
00037     PLy_result_item,            /* sq_item */
00038     PLy_result_slice,           /* sq_slice */
00039     NULL,                       /* sq_ass_item */
00040     PLy_result_ass_slice,       /* sq_ass_slice */
00041 };
00042 
00043 static PyMappingMethods PLy_result_as_mapping = {
00044     PLy_result_length,          /* mp_length */
00045     PLy_result_subscript,       /* mp_subscript */
00046     PLy_result_ass_subscript,   /* mp_ass_subscript */
00047 };
00048 
00049 static PyMethodDef PLy_result_methods[] = {
00050     {"colnames", PLy_result_colnames, METH_NOARGS, NULL},
00051     {"coltypes", PLy_result_coltypes, METH_NOARGS, NULL},
00052     {"coltypmods", PLy_result_coltypmods, METH_NOARGS, NULL},
00053     {"nrows", PLy_result_nrows, METH_VARARGS, NULL},
00054     {"status", PLy_result_status, METH_VARARGS, NULL},
00055     {NULL, NULL, 0, NULL}
00056 };
00057 
00058 static PyTypeObject PLy_ResultType = {
00059     PyVarObject_HEAD_INIT(NULL, 0)
00060     "PLyResult",                /* tp_name */
00061     sizeof(PLyResultObject),    /* tp_size */
00062     0,                          /* tp_itemsize */
00063 
00064     /*
00065      * methods
00066      */
00067     PLy_result_dealloc,         /* tp_dealloc */
00068     0,                          /* tp_print */
00069     0,                          /* tp_getattr */
00070     0,                          /* tp_setattr */
00071     0,                          /* tp_compare */
00072     0,                          /* tp_repr */
00073     0,                          /* tp_as_number */
00074     &PLy_result_as_sequence,    /* tp_as_sequence */
00075     &PLy_result_as_mapping,     /* tp_as_mapping */
00076     0,                          /* tp_hash */
00077     0,                          /* tp_call */
00078     &PLy_result_str,            /* tp_str */
00079     0,                          /* tp_getattro */
00080     0,                          /* tp_setattro */
00081     0,                          /* tp_as_buffer */
00082     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /* tp_flags */
00083     PLy_result_doc,             /* tp_doc */
00084     0,                          /* tp_traverse */
00085     0,                          /* tp_clear */
00086     0,                          /* tp_richcompare */
00087     0,                          /* tp_weaklistoffset */
00088     0,                          /* tp_iter */
00089     0,                          /* tp_iternext */
00090     PLy_result_methods,         /* tp_tpmethods */
00091 };
00092 
00093 void
00094 PLy_result_init_type(void)
00095 {
00096     if (PyType_Ready(&PLy_ResultType) < 0)
00097         elog(ERROR, "could not initialize PLy_ResultType");
00098 }
00099 
00100 PyObject *
00101 PLy_result_new(void)
00102 {
00103     PLyResultObject *ob;
00104 
00105     if ((ob = PyObject_New(PLyResultObject, &PLy_ResultType)) == NULL)
00106         return NULL;
00107 
00108     /* ob->tuples = NULL; */
00109 
00110     Py_INCREF(Py_None);
00111     ob->status = Py_None;
00112     ob->nrows = PyInt_FromLong(-1);
00113     ob->rows = PyList_New(0);
00114     ob->tupdesc = NULL;
00115 
00116     return (PyObject *) ob;
00117 }
00118 
00119 static void
00120 PLy_result_dealloc(PyObject *arg)
00121 {
00122     PLyResultObject *ob = (PLyResultObject *) arg;
00123 
00124     Py_XDECREF(ob->nrows);
00125     Py_XDECREF(ob->rows);
00126     Py_XDECREF(ob->status);
00127     if (ob->tupdesc)
00128     {
00129         FreeTupleDesc(ob->tupdesc);
00130         ob->tupdesc = NULL;
00131     }
00132 
00133     arg->ob_type->tp_free(arg);
00134 }
00135 
00136 static PyObject *
00137 PLy_result_colnames(PyObject *self, PyObject *unused)
00138 {
00139     PLyResultObject *ob = (PLyResultObject *) self;
00140     PyObject   *list;
00141     int         i;
00142 
00143     if (!ob->tupdesc)
00144     {
00145         PLy_exception_set(PLy_exc_error, "command did not produce a result set");
00146         return NULL;
00147     }
00148 
00149     list = PyList_New(ob->tupdesc->natts);
00150     for (i = 0; i < ob->tupdesc->natts; i++)
00151         PyList_SET_ITEM(list, i, PyString_FromString(NameStr(ob->tupdesc->attrs[i]->attname)));
00152 
00153     return list;
00154 }
00155 
00156 static PyObject *
00157 PLy_result_coltypes(PyObject *self, PyObject *unused)
00158 {
00159     PLyResultObject *ob = (PLyResultObject *) self;
00160     PyObject   *list;
00161     int         i;
00162 
00163     if (!ob->tupdesc)
00164     {
00165         PLy_exception_set(PLy_exc_error, "command did not produce a result set");
00166         return NULL;
00167     }
00168 
00169     list = PyList_New(ob->tupdesc->natts);
00170     for (i = 0; i < ob->tupdesc->natts; i++)
00171         PyList_SET_ITEM(list, i, PyInt_FromLong(ob->tupdesc->attrs[i]->atttypid));
00172 
00173     return list;
00174 }
00175 
00176 static PyObject *
00177 PLy_result_coltypmods(PyObject *self, PyObject *unused)
00178 {
00179     PLyResultObject *ob = (PLyResultObject *) self;
00180     PyObject   *list;
00181     int         i;
00182 
00183     if (!ob->tupdesc)
00184     {
00185         PLy_exception_set(PLy_exc_error, "command did not produce a result set");
00186         return NULL;
00187     }
00188 
00189     list = PyList_New(ob->tupdesc->natts);
00190     for (i = 0; i < ob->tupdesc->natts; i++)
00191         PyList_SET_ITEM(list, i, PyInt_FromLong(ob->tupdesc->attrs[i]->atttypmod));
00192 
00193     return list;
00194 }
00195 
00196 static PyObject *
00197 PLy_result_nrows(PyObject *self, PyObject *args)
00198 {
00199     PLyResultObject *ob = (PLyResultObject *) self;
00200 
00201     Py_INCREF(ob->nrows);
00202     return ob->nrows;
00203 }
00204 
00205 static PyObject *
00206 PLy_result_status(PyObject *self, PyObject *args)
00207 {
00208     PLyResultObject *ob = (PLyResultObject *) self;
00209 
00210     Py_INCREF(ob->status);
00211     return ob->status;
00212 }
00213 
00214 static Py_ssize_t
00215 PLy_result_length(PyObject *arg)
00216 {
00217     PLyResultObject *ob = (PLyResultObject *) arg;
00218 
00219     return PyList_Size(ob->rows);
00220 }
00221 
00222 static PyObject *
00223 PLy_result_item(PyObject *arg, Py_ssize_t idx)
00224 {
00225     PyObject   *rv;
00226     PLyResultObject *ob = (PLyResultObject *) arg;
00227 
00228     rv = PyList_GetItem(ob->rows, idx);
00229     if (rv != NULL)
00230         Py_INCREF(rv);
00231     return rv;
00232 }
00233 
00234 static PyObject *
00235 PLy_result_slice(PyObject *arg, Py_ssize_t lidx, Py_ssize_t hidx)
00236 {
00237     PLyResultObject *ob = (PLyResultObject *) arg;
00238 
00239     return PyList_GetSlice(ob->rows, lidx, hidx);
00240 }
00241 
00242 static int
00243 PLy_result_ass_slice(PyObject *arg, Py_ssize_t lidx, Py_ssize_t hidx, PyObject *slice)
00244 {
00245     int         rv;
00246     PLyResultObject *ob = (PLyResultObject *) arg;
00247 
00248     rv = PyList_SetSlice(ob->rows, lidx, hidx, slice);
00249     return rv;
00250 }
00251 
00252 static PyObject *
00253 PLy_result_str(PyObject *arg)
00254 {
00255     PLyResultObject *ob = (PLyResultObject *) arg;
00256 
00257 #if PY_MAJOR_VERSION >= 3
00258     return PyUnicode_FromFormat("<%s status=%S nrows=%S rows=%S>",
00259                                 Py_TYPE(ob)->tp_name,
00260                                 ob->status,
00261                                 ob->nrows,
00262                                 ob->rows);
00263 #else
00264     return PyString_FromFormat("<%s status=%ld nrows=%ld rows=%s>",
00265                                ob->ob_type->tp_name,
00266                                PyInt_AsLong(ob->status),
00267                                PyInt_AsLong(ob->nrows),
00268                                PyString_AsString(PyObject_Str(ob->rows)));
00269 #endif
00270 }
00271 
00272 static PyObject *
00273 PLy_result_subscript(PyObject *arg, PyObject *item)
00274 {
00275     PLyResultObject *ob = (PLyResultObject *) arg;
00276 
00277     return PyObject_GetItem(ob->rows, item);
00278 }
00279 
00280 static int
00281 PLy_result_ass_subscript(PyObject *arg, PyObject *item, PyObject *value)
00282 {
00283     PLyResultObject *ob = (PLyResultObject *) arg;
00284 
00285     return PyObject_SetItem(ob->rows, item, value);
00286 }