Changeset 639 for branches/4.x


Ignore:
Timestamp:
Nov 26, 2015, 3:32:19 PM (4 years ago)
Author:
cito
Message:

Backport of recently added features to 4.x

Ported the support for bool objects and the additional getter
functions back from the trunk to 4.x. The bool object support
is disabled by support, so we stay fully backward compatible.
The docs for these features have already been taken over.

Location:
branches/4.x/module
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/4.x/module/TEST_PyGreSQL_classic_connection.py

    r623 r639  
    520520            ).getresult(), [(None,)])
    521521
    522     def testQueryWithBoolParams(self):
    523         query = self.c.query
    524         self.assertEqual(query("select false").getresult(), [('f',)])
    525         self.assertEqual(query("select true").getresult(), [('t',)])
    526         self.assertEqual(query("select $1::bool", (None,)).getresult(),
    527             [(None,)])
    528         self.assertEqual(query("select $1::bool", ('f',)).getresult(), [('f',)])
    529         self.assertEqual(query("select $1::bool", ('t',)).getresult(), [('t',)])
    530         self.assertEqual(query("select $1::bool", ('false',)).getresult(),
    531             [('f',)])
    532         self.assertEqual(query("select $1::bool", ('true',)).getresult(),
    533             [('t',)])
    534         self.assertEqual(query("select $1::bool", ('n',)).getresult(), [('f',)])
    535         self.assertEqual(query("select $1::bool", ('y',)).getresult(), [('t',)])
    536         self.assertEqual(query("select $1::bool", (0,)).getresult(), [('f',)])
    537         self.assertEqual(query("select $1::bool", (1,)).getresult(), [('t',)])
    538         self.assertEqual(query("select $1::bool", (False,)).getresult(),
    539             [('f',)])
    540         self.assertEqual(query("select $1::bool", (True,)).getresult(),
    541             [('t',)])
     522    def testQueryWithBoolParams(self, use_bool=None):
     523        query = self.c.query
     524        if use_bool is not None:
     525            use_bool_default = pg.get_bool()
     526            pg.set_bool(use_bool)
     527        try:
     528            v_false, v_true = (False, True) if use_bool else 'ft'
     529            r_false, r_true = [(v_false,)], [(v_true,)]
     530            self.assertEqual(query("select false").getresult(), r_false)
     531            self.assertEqual(query("select true").getresult(), r_true)
     532            q = "select $1::bool"
     533            self.assertEqual(query(q, (None,)).getresult(), [(None,)])
     534            self.assertEqual(query(q, ('f',)).getresult(), r_false)
     535            self.assertEqual(query(q, ('t',)).getresult(), r_true)
     536            self.assertEqual(query(q, ('false',)).getresult(), r_false)
     537            self.assertEqual(query(q, ('true',)).getresult(), r_true)
     538            self.assertEqual(query(q, ('n',)).getresult(), r_false)
     539            self.assertEqual(query(q, ('y',)).getresult(), r_true)
     540            self.assertEqual(query(q, (0,)).getresult(), r_false)
     541            self.assertEqual(query(q, (1,)).getresult(), r_true)
     542            self.assertEqual(query(q, (False,)).getresult(), r_false)
     543            self.assertEqual(query(q, (True,)).getresult(), r_true)
     544        finally:
     545            if use_bool is not None:
     546                pg.set_bool(use_bool_default)
     547
     548    def testQueryWithBoolParamsAndUseBool(self):
     549        self.testQueryWithBoolParams(use_bool=True)
    542550
    543551    def testQueryWithIntParams(self):
  • branches/4.x/module/TEST_PyGreSQL_dbapi20.py

    r521 r639  
    156156            else:
    157157                self.assertEqual(inval, outval)
     158
     159    def test_bool(self):
     160        values = [False, True, None, 't', 'f', 'true', 'false']
     161        table = self.table_prefix + 'booze'
     162        con = self._connect()
     163        try:
     164            cur = con.cursor()
     165            cur.execute(
     166                "create table %s (n smallint, booltest bool)" % table)
     167            params = enumerate(values)
     168            cur.executemany("insert into %s values (%%s,%%s)" % table, params)
     169            cur.execute("select * from %s order by 1" % table)
     170            rows = cur.fetchall()
     171        finally:
     172            con.close()
     173        rows = [row[1] for row in rows]
     174        values[3] = values[5] = True
     175        values[4] = values[6] = False
     176        self.assertEqual(rows, values)
    158177
    159178    def test_set_decimal_type(self):
  • branches/4.x/module/pgmodule.c

    r623 r639  
    121121                                *namedresult = NULL; /* function for getting named results */
    122122static char decimal_point = '.'; /* decimal point used in money values */
    123 
     123static int use_bool = 0; /* whether or not bool objects shall be returned */
    124124
    125125/* --------------------------------------------------------------------- */
     
    338338}
    339339
     340/* define internal types */
     341
     342#define PYGRES_INT 1
     343#define PYGRES_LONG 2
     344#define PYGRES_FLOAT 3
     345#define PYGRES_DECIMAL 4
     346#define PYGRES_MONEY 5
     347#define PYGRES_BOOL 6
     348#define PYGRES_DEFAULT 7
     349
    340350/* shared functions for converting PG types to Python types */
    341351int *
     
    358368                        case INT4OID:
    359369                        case OIDOID:
    360                                 typ[j] = 1;
     370                                typ[j] = PYGRES_INT;
    361371                                break;
    362372
    363373                        case INT8OID:
    364                                 typ[j] = 2;
     374                                typ[j] = PYGRES_LONG;
    365375                                break;
    366376
    367377                        case FLOAT4OID:
    368378                        case FLOAT8OID:
    369                                 typ[j] = 3;
     379                                typ[j] = PYGRES_FLOAT;
    370380                                break;
    371381
    372382                        case NUMERICOID:
    373                                 typ[j] = 4;
     383                                typ[j] = PYGRES_DECIMAL;
    374384                                break;
    375385
    376386                        case CASHOID:
    377                                 typ[j] = 5;
     387                                typ[j] = PYGRES_MONEY;
    378388                                break;
    379389
     390                        case BOOLOID:
     391                                typ[j] = PYGRES_BOOL;
     392                                break;
     393
    380394                        default:
    381                                 typ[j] = 6;
     395                                typ[j] = PYGRES_DEFAULT;
    382396                                break;
    383397                }
     
    21562170                                switch (typ[j])
    21572171                                {
    2158                                         case 1:  /* int2/4 */
     2172                                        case PYGRES_INT:
    21592173                                                val = PyInt_FromString(s, NULL, 10);
    21602174                                                break;
    21612175
    2162                                         case 2:  /* int8 */
     2176                                        case PYGRES_LONG:
    21632177                                                val = PyLong_FromString(s, NULL, 10);
    21642178                                                break;
    21652179
    2166                                         case 3:  /* float/double */
     2180                                        case PYGRES_FLOAT:
    21672181                                                tmp_obj = PyString_FromString(s);
    21682182                                                val = PyFloat_FromString(tmp_obj, NULL);
     
    21702184                                                break;
    21712185
    2172                                         case 5:  /* money */
     2186                                        case PYGRES_MONEY:
    21732187                                                /* convert to decimal only if decimal point is set */
    21742188                                                if (!decimal_point) goto default_case;
     
    21862200                                                cashbuf[k] = 0;
    21872201                                                s = cashbuf;
    2188 
    2189                                         /* FALLTHROUGH */ /* no break */
    2190                                         case 4:  /* numeric */
     2202                                                /* FALLTHROUGH */ /* no break */
     2203
     2204                                        case PYGRES_DECIMAL:
    21912205                                                if (decimal)
    21922206                                                {
     
    22022216                                                break;
    22032217
     2218                                        case PYGRES_BOOL:
     2219                                                /* convert to bool only if bool_type is set */
     2220                                                if (use_bool)
     2221                                                {
     2222                                                        val = *s == 't' ? Py_True : Py_False;
     2223                                                        Py_INCREF(val);
     2224                                                        break;
     2225                                                }
     2226                                                /* FALLTHROUGH */ /* no break */
     2227
    22042228                                        default:
    22052229                                        default_case:
     
    22862310                                switch (typ[j])
    22872311                                {
    2288                                         case 1:  /* int2/4 */
     2312                                        case PYGRES_INT:
    22892313                                                val = PyInt_FromString(s, NULL, 10);
    22902314                                                break;
    22912315
    2292                                         case 2:  /* int8 */
     2316                                        case PYGRES_LONG:
    22932317                                                val = PyLong_FromString(s, NULL, 10);
    22942318                                                break;
    22952319
    2296                                         case 3:  /* float/double */
     2320                                        case PYGRES_FLOAT:
    22972321                                                tmp_obj = PyString_FromString(s);
    22982322                                                val = PyFloat_FromString(tmp_obj, NULL);
     
    23002324                                                break;
    23012325
    2302                                         case 5:  /* money */
     2326                                        case PYGRES_MONEY:
    23032327                                                /* convert to decimal only if decimal point is set */
    23042328                                                if (!decimal_point) goto default_case;
     
    23172341                                                cashbuf[k] = 0;
    23182342                                                s = cashbuf;
    2319 
    2320                                         /* FALLTHROUGH */ /* no break */
    2321                                         case 4:  /* numeric */
     2343                                                /* FALLTHROUGH */ /* no break */
     2344
     2345                                        case PYGRES_DECIMAL:
    23222346                                                if (decimal)
    23232347                                                {
     
    23322356                                                Py_DECREF(tmp_obj);
    23332357                                                break;
     2358
     2359                                        case PYGRES_BOOL:
     2360                                                /* convert to bool only if bool_type is set */
     2361                                                if (use_bool)
     2362                                                {
     2363                                                        val = *s == 't' ? Py_True : Py_False;
     2364                                                        Py_INCREF(val);
     2365                                                        break;
     2366                                                }
     2367                                                /* FALLTHROUGH */ /* no break */
    23342368
    23352369                                        default:
     
    37013735}
    37023736
     3737/* get decimal point */
     3738static char get_decimal_point__doc__[] =
     3739"get_decimal_point() -- get decimal point to be used for money values.";
     3740
     3741static PyObject *
     3742get_decimal_point(PyObject *self, PyObject * args)
     3743{
     3744        PyObject *ret = NULL;
     3745        char s[2];
     3746
     3747        if (PyArg_ParseTuple(args, ""))
     3748        {
     3749                if (decimal_point)
     3750                {
     3751                        s[0] = decimal_point; s[1] = '\0';
     3752                        ret = PyString_FromString(s);
     3753                } else {
     3754                        Py_INCREF(Py_None); ret = Py_None;
     3755                }
     3756        }
     3757        else
     3758        {
     3759                PyErr_SetString(PyExc_TypeError,
     3760                        "get_decimal_point() takes no parameter");
     3761        }
     3762
     3763        return ret;
     3764}
     3765
    37033766/* set decimal point */
    37043767static char set_decimal_point__doc__[] =
    3705 "set_decimal_point() -- set decimal point to be used for money values.";
     3768"set_decimal_point(char) -- set decimal point to be used for money values.";
    37063769
    37073770static PyObject *
     
    37303793}
    37313794
    3732 /* get decimal point */
    3733 static char get_decimal_point__doc__[] =
    3734 "get_decimal_point() -- get decimal point to be used for money values.";
    3735 
    3736 static PyObject *
    3737 get_decimal_point(PyObject *self, PyObject * args)
     3795/* get decimal type */
     3796static char get_decimal__doc__[] =
     3797"get_decimal() -- set a decimal type to be used for numeric values.";
     3798
     3799static PyObject *
     3800get_decimal(PyObject *self, PyObject *args)
    37383801{
    37393802        PyObject *ret = NULL;
    3740         char s[2];
    37413803
    37423804        if (PyArg_ParseTuple(args, ""))
    37433805        {
    3744                 if (decimal_point) {
    3745                         s[0] = decimal_point; s[1] = '\0';
    3746                         ret = PyString_FromString(s);
    3747                 } else {
    3748                         Py_INCREF(Py_None); ret = Py_None;
    3749                 }
    3750         }
    3751         else
    3752         {
    3753                 PyErr_SetString(PyExc_TypeError,
    3754                         "get_decimal_point() takes no parameter");
     3806                ret = decimal ? decimal : Py_None;
     3807                Py_INCREF(ret);
    37553808        }
    37563809
     
    37583811}
    37593812
    3760 /* set decimal */
     3813/* set decimal type */
    37613814static char set_decimal__doc__[] =
    37623815"set_decimal(cls) -- set a decimal type to be used for numeric values.";
     
    37813834                }
    37823835                else
    3783                         PyErr_SetString(PyExc_TypeError, "decimal type must be None or callable");
    3784         }
     3836                        PyErr_SetString(PyExc_TypeError,
     3837                                "decimal type must be None or callable");
     3838        }
     3839
    37853840        return ret;
    37863841}
    37873842
    3788 /* set named result */
     3843/* get usage of bool values */
     3844static char get_bool__doc__[] =
     3845"get_bool() -- check whether boolean values are converted to bool.";
     3846
     3847static PyObject *
     3848get_bool(PyObject *self, PyObject * args)
     3849{
     3850        PyObject *ret = NULL;
     3851
     3852        if (PyArg_ParseTuple(args, ""))
     3853        {
     3854                ret = use_bool ? Py_True : Py_False;
     3855                Py_INCREF(ret);
     3856        }
     3857
     3858        return ret;
     3859}
     3860
     3861/* set usage of bool values */
     3862static char set_bool__doc__[] =
     3863"set_bool(bool) -- set whether boolean values should be converted to bool.";
     3864
     3865static PyObject *
     3866set_bool(PyObject *self, PyObject * args)
     3867{
     3868        PyObject *ret = NULL;
     3869        int                     i;
     3870
     3871        /* gets arguments */
     3872        if (PyArg_ParseTuple(args, "i", &i))
     3873        {
     3874                use_bool = i ? 1 : 0;
     3875                Py_INCREF(Py_None); ret = Py_None;
     3876        }
     3877
     3878        return ret;
     3879}
     3880
     3881/* get named result factory */
     3882static char get_namedresult__doc__[] =
     3883"get_namedresult(cls) -- get the function used for getting named results.";
     3884
     3885static PyObject *
     3886get_namedresult(PyObject *self, PyObject *args)
     3887{
     3888        PyObject *ret = NULL;
     3889
     3890        if (PyArg_ParseTuple(args, ""))
     3891        {
     3892                ret = namedresult ? namedresult : Py_None;
     3893                Py_INCREF(ret);
     3894        }
     3895
     3896        return ret;
     3897}
     3898
     3899/* set named result factory */
    37893900static char set_namedresult__doc__[] =
    37903901"set_namedresult(cls) -- set a function to be used for getting named results.";
     
    38063917                        PyErr_SetString(PyExc_TypeError, "parameter must be callable");
    38073918        }
     3919
    38083920        return ret;
    38093921}
     
    41604272        {"unescape_bytea", (PyCFunction) unescape_bytea, METH_VARARGS,
    41614273                        unescape_bytea__doc__},
     4274        {"get_decimal_point", (PyCFunction) get_decimal_point, METH_VARARGS,
     4275                        get_decimal_point__doc__},
    41624276        {"set_decimal_point", (PyCFunction) set_decimal_point, METH_VARARGS,
    41634277                        set_decimal_point__doc__},
    4164         {"get_decimal_point", (PyCFunction) get_decimal_point, METH_VARARGS,
    4165                         get_decimal_point__doc__},
     4278        {"get_decimal", (PyCFunction) get_decimal, METH_VARARGS,
     4279                        get_decimal__doc__},
    41664280        {"set_decimal", (PyCFunction) set_decimal, METH_VARARGS,
    41674281                        set_decimal__doc__},
     4282        {"get_bool", (PyCFunction) get_bool, METH_VARARGS, get_bool__doc__},
     4283        {"set_bool", (PyCFunction) set_bool, METH_VARARGS, set_bool__doc__},
     4284        {"get_namedresult", (PyCFunction) get_namedresult, METH_VARARGS,
     4285                        get_namedresult__doc__},
    41684286        {"set_namedresult", (PyCFunction) set_namedresult, METH_VARARGS,
    41694287                        set_namedresult__doc__},
Note: See TracChangeset for help on using the changeset viewer.