Author: cito
Date: Thu Nov 26 12:02:32 2015
New Revision: 634

Log:
Add support for bool values in classic module

Bool values have been already supported on input. Now they can also be
enabled on output by calling pg.set_bool(True). With pg.get_bool() you
can check whether the feautre is enabled. The default is "off" for now,
so everything is still fully backward compatible.

Modified:
   trunk/module/TEST_PyGreSQL_classic_connection.py
   trunk/module/TEST_PyGreSQL_classic_functions.py
   trunk/module/pgmodule.c

Modified: trunk/module/TEST_PyGreSQL_classic_connection.py
==============================================================================
--- trunk/module/TEST_PyGreSQL_classic_connection.py    Thu Nov 26 10:46:13 
2015        (r633)
+++ trunk/module/TEST_PyGreSQL_classic_connection.py    Thu Nov 26 12:02:32 
2015        (r634)
@@ -718,26 +718,34 @@
         self.assertEqual(self.c.query("select $1::text", [None]
             ).getresult(), [(None,)])
 
-    def testQueryWithBoolParams(self):
+    def testQueryWithBoolParams(self, use_bool=None):
         query = self.c.query
-        self.assertEqual(query("select false").getresult(), [('f',)])
-        self.assertEqual(query("select true").getresult(), [('t',)])
-        self.assertEqual(query("select $1::bool", (None,)).getresult(),
-            [(None,)])
-        self.assertEqual(query("select $1::bool", ('f',)).getresult(), 
[('f',)])
-        self.assertEqual(query("select $1::bool", ('t',)).getresult(), 
[('t',)])
-        self.assertEqual(query("select $1::bool", ('false',)).getresult(),
-            [('f',)])
-        self.assertEqual(query("select $1::bool", ('true',)).getresult(),
-            [('t',)])
-        self.assertEqual(query("select $1::bool", ('n',)).getresult(), 
[('f',)])
-        self.assertEqual(query("select $1::bool", ('y',)).getresult(), 
[('t',)])
-        self.assertEqual(query("select $1::bool", (0,)).getresult(), [('f',)])
-        self.assertEqual(query("select $1::bool", (1,)).getresult(), [('t',)])
-        self.assertEqual(query("select $1::bool", (False,)).getresult(),
-            [('f',)])
-        self.assertEqual(query("select $1::bool", (True,)).getresult(),
-            [('t',)])
+        if use_bool is not None:
+            use_bool_default = pg.get_bool()
+            pg.set_bool(use_bool)
+        try:
+            v_false, v_true = (False, True) if use_bool else 'ft'
+            r_false, r_true = [(v_false,)], [(v_true,)]
+            self.assertEqual(query("select false").getresult(), r_false)
+            self.assertEqual(query("select true").getresult(), r_true)
+            q = "select $1::bool"
+            self.assertEqual(query(q, (None,)).getresult(), [(None,)])
+            self.assertEqual(query(q, ('f',)).getresult(), r_false)
+            self.assertEqual(query(q, ('t',)).getresult(), r_true)
+            self.assertEqual(query(q, ('false',)).getresult(), r_false)
+            self.assertEqual(query(q, ('true',)).getresult(), r_true)
+            self.assertEqual(query(q, ('n',)).getresult(), r_false)
+            self.assertEqual(query(q, ('y',)).getresult(), r_true)
+            self.assertEqual(query(q, (0,)).getresult(), r_false)
+            self.assertEqual(query(q, (1,)).getresult(), r_true)
+            self.assertEqual(query(q, (False,)).getresult(), r_false)
+            self.assertEqual(query(q, (True,)).getresult(), r_true)
+        finally:
+            if use_bool is not None:
+                pg.set_bool(use_bool_default)
+
+    def testQueryWithBoolParamsAndUseBool(self):
+        self.testQueryWithBoolParams(use_bool=True)
 
     def testQueryWithIntParams(self):
         query = self.c.query
@@ -1471,6 +1479,68 @@
         self.assertIsInstance(r, long)
         self.assertEqual(r, long(3425))
 
+    def testGetBool(self):
+        use_bool = pg.get_bool()
+        # error if a parameter is passed
+        self.assertRaises(TypeError, pg.get_bool, use_bool)
+        self.assertIsInstance(use_bool, bool)
+        self.assertIs(use_bool, False)  # the default setting
+        pg.set_bool(True)
+        try:
+            r = pg.get_bool()
+        finally:
+            pg.set_bool(use_bool)
+        self.assertIsInstance(r, bool)
+        self.assertIs(r, True)
+        pg.set_bool(False)
+        try:
+            r = pg.get_bool()
+        finally:
+            pg.set_bool(use_bool)
+        self.assertIsInstance(r, bool)
+        self.assertIs(r, False)
+        pg.set_bool(1)
+        try:
+            r = pg.get_bool()
+        finally:
+            pg.set_bool(use_bool)
+        self.assertIsInstance(r, bool)
+        self.assertIs(r, True)
+        pg.set_bool(0)
+        try:
+            r = pg.get_bool()
+        finally:
+            pg.set_bool(use_bool)
+        self.assertIsInstance(r, bool)
+        self.assertIs(r, False)
+
+    def testSetBool(self):
+        use_bool = pg.get_bool()
+        query = self.c.query
+        try:
+            r = query("select true::bool")
+        except pg.ProgrammingError:
+            self.skipTest('database does not support bool')
+        r = r.getresult()[0][0]
+        self.assertIsInstance(r, str)
+        self.assertEqual(r, 't')
+        r = query("select true::bool")
+        pg.set_bool(True)
+        try:
+            r = r.getresult()[0][0]
+        finally:
+            pg.set_bool(use_bool)
+        self.assertIsInstance(r, bool)
+        self.assertIs(r, True)
+        r = query("select true::bool")
+        pg.set_bool(False)
+        try:
+            r = r.getresult()[0][0]
+        finally:
+            pg.set_bool(use_bool)
+        self.assertIsInstance(r, str)
+        self.assertIs(r, 't')
+
     def testSetNamedresult(self):
         query = self.c.query
 

Modified: trunk/module/TEST_PyGreSQL_classic_functions.py
==============================================================================
--- trunk/module/TEST_PyGreSQL_classic_functions.py     Thu Nov 26 10:46:13 
2015        (r633)
+++ trunk/module/TEST_PyGreSQL_classic_functions.py     Thu Nov 26 12:02:32 
2015        (r634)
@@ -335,15 +335,33 @@
         point = pg.get_decimal_point()
         pg.set_decimal_point('*')
         r = pg.get_decimal_point()
+        pg.set_decimal_point(point)
         self.assertIsInstance(r, str)
         self.assertEqual(r, '*')
-        pg.set_decimal_point(point)
 
     def testSetDecimal(self):
         decimal_class = pg.Decimal
         pg.set_decimal(long)
         pg.set_decimal(decimal_class)
 
+    def testGetBool(self):
+        r = pg.get_bool()
+        self.assertIsInstance(r, bool)
+        self.assertIs(r, False)
+
+    def testSetBoool(self):
+        use_bool = pg.get_bool()
+        pg.set_bool(True)
+        r = pg.get_bool()
+        pg.set_bool(use_bool)
+        self.assertIsInstance(r, bool)
+        self.assertIs(r, True)
+        pg.set_bool(False)
+        r = pg.get_bool()
+        pg.set_bool(use_bool)
+        self.assertIsInstance(r, bool)
+        self.assertIs(r, False)
+
     def testSetNamedresult(self):
         pg.set_namedresult(lambda q: q.getresult())
         pg.set_namedresult(pg._namedresult)

Modified: trunk/module/pgmodule.c
==============================================================================
--- trunk/module/pgmodule.c     Thu Nov 26 10:46:13 2015        (r633)
+++ trunk/module/pgmodule.c     Thu Nov 26 12:02:32 2015        (r634)
@@ -109,6 +109,7 @@
 static PyObject *decimal = NULL, /* decimal type */
                                *namedresult = NULL; /* function for getting 
named results */
 static char decimal_point = '.'; /* decimal point used in money values */
+static int use_bool = 0; /* whether or not bool objects shall be returned */
 
 static int pg_encoding_utf8 = 0;
 static int pg_encoding_latin1 = 0;
@@ -207,7 +208,8 @@
 #define PYGRES_FLOAT 3
 #define PYGRES_DECIMAL 4
 #define PYGRES_MONEY 5
-#define PYGRES_DEFAULT 6
+#define PYGRES_BOOL 6
+#define PYGRES_DEFAULT 7
 
 /* --------------------------------------------------------------------- */
 /* Internal Functions                                                          
                                         */
@@ -283,6 +285,10 @@
                                typ[j] = PYGRES_MONEY;
                                break;
 
+                       case BOOLOID:
+                               typ[j] = PYGRES_BOOL;
+                               break;
+
                        default:
                                typ[j] = PYGRES_DEFAULT;
                }
@@ -3459,8 +3465,8 @@
                                                }
                                                cashbuf[k] = '\0';
                                                s = cashbuf;
+                                               /* FALLTHROUGH */ /* no break 
here */
 
-                                       /* FALLTHROUGH */ /* no break */
                                        case PYGRES_DECIMAL:
                                                if (decimal)
                                                {
@@ -3479,6 +3485,16 @@
                                                Py_DECREF(tmp_obj);
                                                break;
 
+                                       case PYGRES_BOOL:
+                                               /* convert to bool only if 
bool_type is set */
+                                               if (use_bool)
+                                               {
+                                                       val = *s == 't' ? 
Py_True : Py_False;
+                                                       Py_INCREF(val);
+                                                       break;
+                                               }
+                                               /* FALLTHROUGH */ /* no break 
here */
+
                                        default:
                                        default_case:
                                                size = 
PQgetlength(self->result, i, j);
@@ -3620,8 +3636,8 @@
                                                }
                                                cashbuf[k] = '\0';
                                                s = cashbuf;
+                                               /* FALLTHROUGH */ /* no break 
here */
 
-                                       /* FALLTHROUGH */ /* no break */
                                        case PYGRES_DECIMAL:
                                                if (decimal)
                                                {
@@ -3640,6 +3656,16 @@
                                                Py_DECREF(tmp_obj);
                                                break;
 
+                                       case PYGRES_BOOL:
+                                               /* convert to bool only if 
bool_type is set */
+                                               if (use_bool)
+                                               {
+                                                       val = *s == 't' ? 
Py_True : Py_False;
+                                                       Py_INCREF(val);
+                                                       break;
+                                               }
+                                               /* FALLTHROUGH */ /* no break 
here */
+
                                        default:
                                        default_case:
                                                size = 
PQgetlength(self->result, i, j);
@@ -4111,8 +4137,47 @@
                        Py_INCREF(Py_None); ret = Py_None;
                }
                else
-                       PyErr_SetString(PyExc_TypeError, "decimal type must be 
None or callable");
+                       PyErr_SetString(PyExc_TypeError,
+                               "decimal type must be None or callable");
+       }
+       return ret;
+}
+
+/* set usage of bool values */
+static char pgSetBool__doc__[] =
+"set_bool() -- set whether boolean values should be converted to bool.";
+
+static PyObject *
+pgSetBool(PyObject *self, PyObject * args)
+{
+       PyObject *ret = NULL;
+       int                     i;
+
+       /* gets arguments */
+       if (PyArg_ParseTuple(args, "i", &i))
+       {
+               use_bool = i ? 1 : 0;
+               Py_INCREF(Py_None); ret = Py_None;
        }
+
+       return ret;
+}
+
+/* ge usage of bool values */
+static char pgGetBool__doc__[] =
+"get_bool() -- check whether boolean values are converted to bool.";
+
+static PyObject *
+pgGetBool(PyObject *self, PyObject * args)
+{
+       PyObject *ret = NULL;
+
+       if (PyArg_ParseTuple(args, ""))
+       {
+               ret = use_bool ? Py_True : Py_False;
+               Py_INCREF(ret);
+       }
+
        return ret;
 }
 
@@ -4497,6 +4562,8 @@
                        pgGetDecimalPoint__doc__},
        {"set_decimal", (PyCFunction) pgSetDecimal, METH_VARARGS,
                        pgSetDecimal__doc__},
+       {"set_bool", (PyCFunction) pgSetBool, METH_VARARGS, pgSetBool__doc__},
+       {"get_bool", (PyCFunction) pgGetBool, METH_VARARGS, pgGetBool__doc__},
        {"set_namedresult", (PyCFunction) pgSetNamedresult, METH_VARARGS,
                        pgSetNamedresult__doc__},
 
_______________________________________________
PyGreSQL mailing list
[email protected]
https://mail.vex.net/mailman/listinfo.cgi/pygresql

Reply via email to