00001
00002
00003
00004
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,
00035 NULL,
00036 NULL,
00037 PLy_result_item,
00038 PLy_result_slice,
00039 NULL,
00040 PLy_result_ass_slice,
00041 };
00042
00043 static PyMappingMethods PLy_result_as_mapping = {
00044 PLy_result_length,
00045 PLy_result_subscript,
00046 PLy_result_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",
00061 sizeof(PLyResultObject),
00062 0,
00063
00064
00065
00066
00067 PLy_result_dealloc,
00068 0,
00069 0,
00070 0,
00071 0,
00072 0,
00073 0,
00074 &PLy_result_as_sequence,
00075 &PLy_result_as_mapping,
00076 0,
00077 0,
00078 &PLy_result_str,
00079 0,
00080 0,
00081 0,
00082 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
00083 PLy_result_doc,
00084 0,
00085 0,
00086 0,
00087 0,
00088 0,
00089 0,
00090 PLy_result_methods,
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
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 }