[Python-checkins] r62702 - in python/trunk: Doc/library/sqlite3.rst Lib/sqlite3/test/types.py Modules/_sqlite/cursor.c

gerhard.haering python-checkins at python.org
Sun May 4 15:42:44 CEST 2008


Author: gerhard.haering
Date: Sun May  4 15:42:44 2008
New Revision: 62702

Log:
Implemented feature request 2157: Converter names are cut off at '('
characters. This avoids the common case of something like 'NUMBER(10)' not
being parsed as 'NUMBER', like expected. Also corrected the docs about
converter names being case-sensitive. They aren't any longer.


Modified:
   python/trunk/Doc/library/sqlite3.rst
   python/trunk/Lib/sqlite3/test/types.py
   python/trunk/Modules/_sqlite/cursor.c

Modified: python/trunk/Doc/library/sqlite3.rst
==============================================================================
--- python/trunk/Doc/library/sqlite3.rst	(original)
+++ python/trunk/Doc/library/sqlite3.rst	Sun May  4 15:42:44 2008
@@ -114,10 +114,11 @@
    :func:`connect` function.
 
    Setting it makes the :mod:`sqlite3` module parse the declared type for each
-   column it returns.  It will parse out the first word of the declared type, i. e.
-   for "integer primary key", it will parse out "integer". Then for that column, it
-   will look into the converters dictionary and use the converter function
-   registered for that type there.  Converter names are case-sensitive!
+   column it returns.  It will parse out the first word of the declared type,
+   i. e.  for "integer primary key", it will parse out "integer", or for
+   "number(10)" it will parse out "number". Then for that column, it will look
+   into the converters dictionary and use the converter function registered for
+   that type there.
 
 
 .. data:: PARSE_COLNAMES
@@ -666,10 +667,6 @@
    Converter functions **always** get called with a string, no matter under which
    data type you sent the value to SQLite.
 
-.. note::
-
-   Converter names are looked up in a case-sensitive manner.
-
 ::
 
    def convert_point(s):

Modified: python/trunk/Lib/sqlite3/test/types.py
==============================================================================
--- python/trunk/Lib/sqlite3/test/types.py	(original)
+++ python/trunk/Lib/sqlite3/test/types.py	Sun May  4 15:42:44 2008
@@ -98,7 +98,7 @@
     def setUp(self):
         self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_DECLTYPES)
         self.cur = self.con.cursor()
-        self.cur.execute("create table test(i int, s str, f float, b bool, u unicode, foo foo, bin blob)")
+        self.cur.execute("create table test(i int, s str, f float, b bool, u unicode, foo foo, bin blob, n1 number, n2 number(5))")
 
         # override float, make them always return the same number
         sqlite.converters["FLOAT"] = lambda x: 47.2
@@ -107,11 +107,13 @@
         sqlite.converters["BOOL"] = lambda x: bool(int(x))
         sqlite.converters["FOO"] = DeclTypesTests.Foo
         sqlite.converters["WRONG"] = lambda x: "WRONG"
+        sqlite.converters["NUMBER"] = float
 
     def tearDown(self):
         del sqlite.converters["FLOAT"]
         del sqlite.converters["BOOL"]
         del sqlite.converters["FOO"]
+        del sqlite.converters["NUMBER"]
         self.cur.close()
         self.con.close()
 
@@ -203,6 +205,19 @@
         row = self.cur.fetchone()
         self.failUnlessEqual(row[0], val)
 
+    def CheckNumber1(self):
+        self.cur.execute("insert into test(n1) values (5)")
+        value = self.cur.execute("select n1 from test").fetchone()[0]
+        # if the converter is not used, it's an int instead of a float
+        self.failUnlessEqual(type(value), float)
+
+    def CheckNumber2(self):
+        """Checks wether converter names are cut off at '(' characters"""
+        self.cur.execute("insert into test(n2) values (5)")
+        value = self.cur.execute("select n2 from test").fetchone()[0]
+        # if the converter is not used, it's an int instead of a float
+        self.failUnlessEqual(type(value), float)
+
 class ColNamesTests(unittest.TestCase):
     def setUp(self):
         self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES)

Modified: python/trunk/Modules/_sqlite/cursor.c
==============================================================================
--- python/trunk/Modules/_sqlite/cursor.c	(original)
+++ python/trunk/Modules/_sqlite/cursor.c	Sun May  4 15:42:44 2008
@@ -202,7 +202,11 @@
             decltype = sqlite3_column_decltype(self->statement->st, i);
             if (decltype) {
                 for (pos = decltype;;pos++) {
-                    if (*pos == ' ' || *pos == 0) {
+                    /* Converter names are split at '(' and blanks.
+                     * This allows 'INTEGER NOT NULL' to be treated as 'INTEGER' and
+                     * 'NUMBER(10)' to be treated as 'NUMBER', for example.
+                     * In other words, it will work as people expect it to work.*/
+                    if (*pos == ' ' || *pos == '(' || *pos == 0) {
                         py_decltype = PyString_FromStringAndSize(decltype, pos - decltype);
                         if (!py_decltype) {
                             return -1;


More information about the Python-checkins mailing list