Changeset 980 for trunk/pgmodule.c


Ignore:
Timestamp:
Apr 22, 2019, 10:44:58 AM (4 months ago)
Author:
cito
Message:

Query methods for getting single rows and columns

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/pgmodule.c

    r978 r980  
    9292                                *dictiter = NULL, /* function for getting named results */
    9393                                *namediter = NULL, /* function for getting named results */
     94                                *namednext = NULL, /* function for getting one named result */
     95                                *scalariter = NULL, /* function for getting scalar results */
    9496                                *jsondecode = NULL; /* function for decoding json strings */
    9597static const char *date_format = NULL; /* date format that is always assumed */
     
    48314833        row_tuple = queryGetRowAsTuple(self);
    48324834        if (row_tuple) ++self->current_row;
    4833     return row_tuple;
     4835        return row_tuple;
     4836}
     4837
     4838/* Retrieves one row from the result as a tuple. */
     4839static char queryOne__doc__[] =
     4840"one() -- Get one row from the result of a query\n\n"
     4841"Only one row from the result is returned as a tuple of fields.\n"
     4842"This method can be called multiple times to return more rows.\n"
     4843"It returns None if the result does not contain one more row.\n";
     4844
     4845static PyObject *
     4846queryOne(queryObject *self, PyObject *noargs)
     4847{
     4848        PyObject *row_tuple;
     4849
     4850        if (self->current_row >= self->max_row) {
     4851                Py_INCREF(Py_None); return Py_None;
     4852        }
     4853
     4854        row_tuple = queryGetRowAsTuple(self);
     4855        if (row_tuple) ++self->current_row;
     4856        return row_tuple;
     4857}
     4858
     4859/* Retrieves the single row from the result as a tuple. */
     4860static char querySingle__doc__[] =
     4861"single() -- Get the result of a query as single row\n\n"
     4862"The single row from the query result is returned as a tuple of fields.\n"
     4863"This method returns the same single row when called multiple times.\n"
     4864"It raises a ProgrammingError if the result does not have exactly one row.\n";
     4865
     4866static PyObject *
     4867querySingle(queryObject *self, PyObject *noargs)
     4868{
     4869        PyObject *row_tuple;
     4870
     4871        if (self->max_row != 1) {
     4872                set_error_msg(ProgrammingError,
     4873                        self->max_row ? "Multiple results found" : "No result found");
     4874                return NULL;
     4875        }
     4876
     4877        self->current_row = 0;
     4878        row_tuple = queryGetRowAsTuple(self);
     4879        if (row_tuple) ++self->current_row;
     4880        return row_tuple;
    48344881}
    48354882
     
    49004947}
    49014948
     4949/* Retrieve one row from the result as a dictionary. */
     4950static char queryOnedict__doc__[] =
     4951"onedict() -- Get one row from the result of a query\n\n"
     4952"Only one row from the result is returned as a dictionary with\n"
     4953"the field names used as the keys.\n"
     4954"This method can be called multiple times to return more rows.\n"
     4955"It returns None if the result does not contain one more row.\n";
     4956
     4957static PyObject *
     4958queryOnedict(queryObject *self, PyObject *noargs)
     4959{
     4960        PyObject *row_dict;
     4961
     4962        if (self->current_row >= self->max_row) {
     4963                Py_INCREF(Py_None); return Py_None;
     4964        }
     4965
     4966        row_dict = queryGetRowAsDict(self);
     4967        if (row_dict) ++self->current_row;
     4968        return row_dict;
     4969}
     4970
     4971/* Retrieve the single row from the result as a dictionary. */
     4972static char querySingledict__doc__[] =
     4973"singledict() -- Get the result of a query as single row\n\n"
     4974"The single row from the query result is returned as a dictionary with\n"
     4975"the field names used as the keys.\n"
     4976"This method returns the same single row when called multiple times.\n"
     4977"It raises a ProgrammingError if the result does not have exactly one row.\n";
     4978
     4979static PyObject *
     4980querySingledict(queryObject *self, PyObject *noargs)
     4981{
     4982        PyObject *row_dict;
     4983
     4984        if (self->max_row != 1) {
     4985                set_error_msg(ProgrammingError,
     4986                        self->max_row ? "Multiple results found" : "No result found");
     4987                return NULL;
     4988        }
     4989
     4990        self->current_row = 0;
     4991        row_dict = queryGetRowAsDict(self);
     4992        if (row_dict) ++self->current_row;
     4993        return row_dict;
     4994}
     4995
    49024996/* Retrieve the last query result as a list of dictionaries. */
    49034997static char queryDictresult__doc__[] =
     
    49275021}
    49285022
    4929 /* retrieves last result as iterator of dictionaries */
     5023/* Retrieve last result as iterator of dictionaries. */
    49305024static char queryDictiter__doc__[] =
    49315025"dictiter() -- Get the result of a query\n\n"
     
    49365030queryDictiter(queryObject *self, PyObject *noargs)
    49375031{
    4938         if (dictiter) {
    4939                 return PyObject_CallFunction(dictiter, "(O)", self);
    4940         }
    4941         return queryGetIter(self);
    4942 }
    4943 
    4944 
    4945 /* retrieves last result as list of named tuples */
     5032        if (!dictiter)
     5033                return queryDictresult(self, noargs);
     5034
     5035        return PyObject_CallFunction(dictiter, "(O)", self);
     5036}
     5037
     5038/* Retrieve one row from the result as a named tuple. */
     5039static char queryOnenamed__doc__[] =
     5040"onenamed() -- Get one row from the result of a query\n\n"
     5041"Only one row from the result is returned as a named tuple of fields.\n"
     5042"This method can be called multiple times to return more rows.\n"
     5043"It returns None if the result does not contain one more row.\n";
     5044
     5045static PyObject *
     5046queryOnenamed(queryObject *self, PyObject *noargs)
     5047{
     5048        if (!namednext)
     5049                return queryOne(self, noargs);
     5050
     5051        if (self->current_row >= self->max_row) {
     5052                Py_INCREF(Py_None); return Py_None;
     5053        }
     5054
     5055        return PyObject_CallFunction(namednext, "(O)", self);
     5056}
     5057
     5058/* Retrieve the single row from the result as a tuple. */
     5059static char querySinglenamed__doc__[] =
     5060"singlenamed() -- Get the result of a query as single row\n\n"
     5061"The single row from the query result is returned as a named tuple of fields.\n"
     5062"This method returns the same single row when called multiple times.\n"
     5063"It raises a ProgrammingError if the result does not have exactly one row.\n";
     5064
     5065static PyObject *
     5066querySinglenamed(queryObject *self, PyObject *noargs)
     5067{
     5068        if (!namednext)
     5069                return querySingle(self, noargs);
     5070
     5071        if (self->max_row != 1) {
     5072                set_error_msg(ProgrammingError,
     5073                        self->max_row ? "Multiple results found" : "No result found");
     5074                return NULL;
     5075        }
     5076
     5077        self->current_row = 0;
     5078        return PyObject_CallFunction(namednext, "(O)", self);
     5079}
     5080
     5081/* Retrieve last result as list of named tuples. */
    49465082static char queryNamedresult__doc__[] =
    49475083"namedresult() -- Get the result of a query\n\n"
     
    49525088queryNamedresult(queryObject *self, PyObject *noargs)
    49535089{
    4954         if (namediter) {
    4955                 PyObject* res = PyObject_CallFunction(namediter, "(O)", self);
    4956                 if (res && PyList_Check(res))
    4957                         return res;
    4958                 PyObject *res_list = PySequence_List(res);
    4959                 Py_DECREF(res);
    4960                 return res_list;
    4961         }
    4962         return queryGetresult(self, noargs);
    4963 }
    4964 
    4965 /* retrieves last result as iterator of named tuples */
     5090        PyObject   *res, *res_list;
     5091
     5092        if (!namediter)
     5093                return queryGetresult(self, noargs);
     5094
     5095        res = PyObject_CallFunction(namediter, "(O)", self);
     5096        if (!res) return NULL;
     5097        if (PyList_Check(res)) return res;
     5098        res_list = PySequence_List(res);
     5099        Py_DECREF(res);
     5100        return res_list;
     5101}
     5102
     5103/* Retrieve last result as iterator of named tuples. */
    49665104static char queryNamediter__doc__[] =
    49675105"namediter() -- Get the result of a query\n\n"
     
    49725110queryNamediter(queryObject *self, PyObject *noargs)
    49735111{
    4974         if (namediter) {
    4975                 PyObject* res = PyObject_CallFunction(namediter, "(O)", self);
    4976                 if (res && !PyList_Check(res))
    4977                         return res;
    4978                 PyObject* res_iter = (Py_TYPE(res)->tp_iter)((PyObject *)self);
    4979                 Py_DECREF(res);
    4980                 return res_iter;
    4981         }
    4982         return queryGetIter(self);
     5112        PyObject   *res, *res_iter;
     5113
     5114        if (!namediter)
     5115                return queryGetIter(self);
     5116
     5117        res = PyObject_CallFunction(namediter, "(O)", self);
     5118        if (!res) return NULL;
     5119        if (!PyList_Check(res)) return res;
     5120        res_iter = (Py_TYPE(res)->tp_iter)((PyObject *)self);
     5121        Py_DECREF(res);
     5122        return res_iter;
     5123}
     5124
     5125/* Retrieve the last query result as a list of scalar values. */
     5126static char queryScalarresult__doc__[] =
     5127"scalarresult() -- Get query result as scalars\n\n"
     5128"The result is returned as a list of scalar values where the values\n"
     5129"are the first fields of the rows in the order returned by the server.\n";
     5130
     5131static PyObject *
     5132queryScalarresult(queryObject *self, PyObject *noargs)
     5133{
     5134        PyObject   *result_list;
     5135
     5136        if (!self->num_fields) {
     5137                set_error_msg(ProgrammingError, "No fields in result");
     5138                return NULL;
     5139        }
     5140
     5141        if (!(result_list = PyList_New(self->max_row))) return NULL;
     5142
     5143        for (self->current_row = 0; self->current_row < self->max_row;
     5144                ++self->current_row)
     5145        {
     5146                PyObject   *value = getValueInColumn(self, 0);
     5147                if (!value)
     5148                {
     5149                        Py_DECREF(result_list); return NULL;
     5150                }
     5151                PyList_SET_ITEM(result_list, self->current_row, value);
     5152        }
     5153
     5154        return result_list;
     5155}
     5156
     5157/* Retrieve the last query result as iterator of scalar values. */
     5158static char queryScalariter__doc__[] =
     5159"scalariter() -- Get query result as scalars\n\n"
     5160"The result is returned as an iterator of scalar values where the values\n"
     5161"are the first fields of the rows in the order returned by the server.\n";
     5162
     5163static PyObject *
     5164queryScalariter(queryObject *self, PyObject *noargs)
     5165{
     5166        if (!scalariter)
     5167                return queryScalarresult(self, noargs);
     5168
     5169        if (!self->num_fields) {
     5170                set_error_msg(ProgrammingError, "No fields in result");
     5171                return NULL;
     5172        }
     5173
     5174        return PyObject_CallFunction(scalariter, "(O)", self);
     5175}
     5176
     5177/* Retrieve one result as scalar value. */
     5178static char queryOnescalar__doc__[] =
     5179"onescalar() -- Get one scalar value from the result of a query\n\n"
     5180"Returns the first field of the next row from the result as a scalar value.\n"
     5181"This method can be called multiple times to return more rows as scalars.\n"
     5182"It returns None if the result does not contain one more row.\n";
     5183
     5184static PyObject *
     5185queryOnescalar(queryObject *self, PyObject *noargs)
     5186{
     5187        PyObject *value;
     5188
     5189        if (!self->num_fields) {
     5190                set_error_msg(ProgrammingError, "No fields in result");
     5191                return NULL;
     5192        }
     5193
     5194        if (self->current_row >= self->max_row) {
     5195                Py_INCREF(Py_None); return Py_None;
     5196        }
     5197
     5198        value = getValueInColumn(self, 0);
     5199        if (value) ++self->current_row;
     5200        return value;
     5201}
     5202
     5203/* Retrieves the single row from the result as a tuple. */
     5204static char querySinglescalar__doc__[] =
     5205"singlescalar() -- Get scalar value from single result of a query\n\n"
     5206"Returns the first field of the next row from the result as a scalar value.\n"
     5207"This method returns the same single row when called multiple times.\n"
     5208"It raises a ProgrammingError if the result does not have exactly one row.\n";
     5209
     5210static PyObject *
     5211querySinglescalar(queryObject *self, PyObject *noargs)
     5212{
     5213        PyObject *value;
     5214
     5215        if (!self->num_fields) {
     5216                set_error_msg(ProgrammingError, "No fields in result");
     5217                return NULL;
     5218        }
     5219
     5220        if (self->max_row != 1) {
     5221                set_error_msg(ProgrammingError,
     5222                        self->max_row ? "Multiple results found" : "No result found");
     5223                return NULL;
     5224        }
     5225
     5226        self->current_row = 0;
     5227        value = getValueInColumn(self, 0);
     5228        if (value) ++self->current_row;
     5229        return value;
    49835230}
    49845231
     
    51455392        {"namediter", (PyCFunction) queryNamediter, METH_NOARGS,
    51465393                        queryNamediter__doc__},
     5394        {"one", (PyCFunction) queryOne, METH_NOARGS, queryOne__doc__},
     5395        {"single", (PyCFunction) querySingle, METH_NOARGS, querySingle__doc__},
     5396        {"onedict", (PyCFunction) queryOnedict, METH_NOARGS,
     5397                queryOnedict__doc__},
     5398        {"singledict", (PyCFunction) querySingledict, METH_NOARGS,
     5399                querySingledict__doc__},
     5400        {"onenamed", (PyCFunction) queryOnenamed, METH_NOARGS,
     5401                queryOnenamed__doc__},
     5402        {"singlenamed", (PyCFunction) querySinglenamed, METH_NOARGS,
     5403                querySinglenamed__doc__},
     5404        {"scalarresult", (PyCFunction) queryScalarresult, METH_NOARGS,
     5405                        queryScalarresult__doc__},
     5406        {"scalariter", (PyCFunction) queryScalariter, METH_NOARGS,
     5407                        queryScalariter__doc__},
     5408        {"onescalar", (PyCFunction) queryOnescalar, METH_NOARGS,
     5409                        queryOnescalar__doc__},
     5410        {"singlescalar", (PyCFunction) querySinglescalar, METH_NOARGS,
     5411                        querySinglescalar__doc__},
    51475412        {"fieldname", (PyCFunction) queryFieldname, METH_VARARGS,
    51485413                         queryFieldname__doc__},
     
    55995864}
    56005865
    5601 /* get dict result factory */
    5602 static char pgGetDictiter__doc__[] =
    5603 "get_dictiter() -- get the generator used for getting dict results";
    5604 
    5605 static PyObject *
    5606 pgGetDictiter(PyObject *self, PyObject *noargs)
    5607 {
    5608         PyObject *ret;
    5609 
    5610         ret = dictiter ? dictiter : Py_None;
    5611         Py_INCREF(ret);
    5612 
    5613         return ret;
    5614 }
    5615 
    5616 /* set dict result factory */
    5617 static char pgSetDictiter__doc__[] =
    5618 "set_dictiter(func) -- set a generator to be used for getting dict results";
    5619 
    5620 static PyObject *
    5621 pgSetDictiter(PyObject *self, PyObject *func)
    5622 {
    5623         PyObject *ret = NULL;
    5624 
    5625         if (func == Py_None)
    5626         {
    5627                 Py_XDECREF(dictiter); dictiter = NULL;
    5628                 Py_INCREF(Py_None); ret = Py_None;
    5629         }
    5630         else if (PyCallable_Check(func))
    5631         {
    5632                 Py_XINCREF(func); Py_XDECREF(dictiter); dictiter = func;
    5633                 Py_INCREF(Py_None); ret = Py_None;
    5634         }
    5635         else
    5636                 PyErr_SetString(PyExc_TypeError,
    5637                         "Function set_dictiter() expects"
    5638                          " a callable or None as argument");
    5639 
    5640         return ret;
    5641 }
    5642 
    5643 /* get named result factory */
    5644 static char pgGetNamediter__doc__[] =
    5645 "get_namediter() -- get the generator used for getting named results";
    5646 
    5647 static PyObject *
    5648 pgGetNamediter(PyObject *self, PyObject *noargs)
    5649 {
    5650         PyObject *ret;
    5651 
    5652         ret = namediter ? namediter : Py_None;
    5653         Py_INCREF(ret);
    5654 
    5655         return ret;
    5656 }
    5657 
    5658 /* set named result factory */
    5659 static char pgSetNamediter__doc__[] =
    5660 "set_namediter(func) -- set a generator to be used for getting named results";
    5661 
    5662 static PyObject *
    5663 pgSetNamediter(PyObject *self, PyObject *func)
    5664 {
    5665         PyObject *ret = NULL;
    5666 
    5667         if (func == Py_None)
    5668         {
    5669                 Py_XDECREF(namediter); namediter = NULL;
    5670                 Py_INCREF(Py_None); ret = Py_None;
    5671         }
    5672         else if (PyCallable_Check(func))
    5673         {
    5674                 Py_XINCREF(func); Py_XDECREF(namediter); namediter = func;
    5675                 Py_INCREF(Py_None); ret = Py_None;
    5676         }
    5677         else
    5678                 PyErr_SetString(PyExc_TypeError,
    5679                         "Function set_namediter() expects"
    5680                          " a callable or None as argument");
    5681 
    5682         return ret;
     5866/* set query helper functions */
     5867
     5868static char pgSetQueryHelpers__doc__[] =
     5869"set_query_helpers(*helpers) -- set internal query helper functions";
     5870
     5871static PyObject *
     5872pgSetQueryHelpers(PyObject *self, PyObject *args)
     5873{
     5874        /* gets arguments */
     5875        if (!PyArg_ParseTuple(args, "O!O!O!O!",
     5876                &PyFunction_Type, &dictiter,
     5877                &PyFunction_Type, &namediter,
     5878                &PyFunction_Type, &namednext,
     5879                &PyFunction_Type, &scalariter)) return NULL;
     5880
     5881        Py_INCREF(Py_None);
     5882        return Py_None;
    56835883}
    56845884
     
    61676367        {"get_array", (PyCFunction) pgGetArray, METH_NOARGS, pgGetArray__doc__},
    61686368        {"set_array", (PyCFunction) pgSetArray, METH_VARARGS, pgSetArray__doc__},
     6369        {"set_query_helpers", (PyCFunction) pgSetQueryHelpers, METH_VARARGS,
     6370                        pgSetQueryHelpers__doc__},
    61696371        {"get_bytea_escaped", (PyCFunction) pgGetByteaEscaped, METH_NOARGS,
    61706372                pgGetByteaEscaped__doc__},
    61716373        {"set_bytea_escaped", (PyCFunction) pgSetByteaEscaped, METH_VARARGS,
    61726374                pgSetByteaEscaped__doc__},
    6173         {"get_dictiter", (PyCFunction) pgGetDictiter, METH_NOARGS,
    6174                         pgGetDictiter__doc__},
    6175         {"set_dictiter", (PyCFunction) pgSetDictiter, METH_O,
    6176                         pgSetDictiter__doc__},
    6177         {"get_namediter", (PyCFunction) pgGetNamediter, METH_NOARGS,
    6178                         pgGetNamediter__doc__},
    6179         {"set_namediter", (PyCFunction) pgSetNamediter, METH_O,
    6180                         pgSetNamediter__doc__},
    6181         /* get/set_namedresult is deprecated, use get/set_namediter */
    6182         {"get_namedresult", (PyCFunction) pgGetNamediter, METH_NOARGS,
    6183                         pgGetNamediter__doc__},
    6184         {"set_namedresult", (PyCFunction) pgSetNamediter, METH_O,
    6185                         pgSetNamediter__doc__},
    61866375        {"get_jsondecode", (PyCFunction) pgGetJsondecode, METH_NOARGS,
    61876376                        pgGetJsondecode__doc__},
Note: See TracChangeset for help on using the changeset viewer.