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