Re: #186: registering/using converters

<crass-tdrK/[email protected]>
Newsgroups gmane.comp.python.db.pysqlite.user
Message-ID <20070103140010.45aa7b23@crass>
Gerhard, I've attached a patch to the uppercase bug.  Also, I've
attached a patch to another bug where cursor.c:build_row_cast_map
improperly determines which styles of detect_types to use.  The test.py
is a test program which takes an integer (0, 1, 2, or 3) which is used
as the detect types parameter.  Without applying the detect_types patch
you can see that it doesn't matter which detect_types style you use.
Both will be used regardless.  The test.py was also used to test the
register_converters patch.   Let me know if there are any problems with
the patches that would prevent acceptance.  Thanks.

Glenn

On Tue, 02 Jan 2007 20:53:23 +0100
Gerhard Häring <[email protected]> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> crass-tdrK/[email protected] wrote:
> > Hey, I'm the original submitter of this bug.  I haven't seen a
> > response to this yet, and was wondering if anyone has looked at
> > it.  Would it be addressed faster if I submitted a patch? [...]
> 
> I have read it, but haven't thought it through entirely, yet.
> 
> I have, now. See comments in ticket.
> 
> - -- Gerhard
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.3 (GNU/Linux)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
> 
> iD8DBQFFmrgzdIO4ozGCH14RAvTLAJ9HRzgokmR0sLHPkjET7RXpV13lXwCfazrJ
> UEg36chHZT/1zfIbUcpsTbo=
> =uSN6
> -----END PGP SIGNATURE-----
> _______________________________________________
> pysqlite mailing list
> pysqlite-IAPFreCvJWPBWskQ1e/[email protected]
> http://lists.initd.org/mailman/listinfo/pysqlite

_______________________________________________
pysqlite mailing list
pysqlite-IAPFreCvJWPBWskQ1e/[email protected]
http://lists.initd.org/mailman/listinfo/pysqlite
register_converters.patch (text/x-patch, 1.5 KB)
--- src/module.c~	2006-07-02 12:20:53.000000000 -0500
+++ src/module.c	2007-01-03 12:44:37.000000000 -0600
@@ -142,35 +142,40 @@
 static PyObject* module_register_converter(PyObject* self, PyObject* args, PyObject* kwargs)
 {
     char* orig_name;
-    char* name = NULL;
-    char* c;
     PyObject* callable;
+    PyObject* key;
+    PyObject* upcase_key;
     PyObject* retval = NULL;
 
     if (!PyArg_ParseTuple(args, "sO", &orig_name, &callable)) {
         return NULL;
     }
 
-    /* convert the name to lowercase */
-    name = PyMem_Malloc(strlen(orig_name) + 2);
-    if (!name) {
-        goto error;
-    }
-    strcpy(name, orig_name);
-    for (c = name; *c != (char)0; c++) {
-        *c = (*c) & 0xDF;
+    key = PyString_FromStringAndSize(orig_name, strlen(orig_name));
+    if (!key) {
+        /* creating a string failed, but it is too complicated
+         * to propagate the error here, we just assume there is
+         * no converter and proceed */
+        goto error1;
+    }
+
+    /* convert the name to uppercase */
+    upcase_key = PyObject_CallMethod(key, "upper", "");
+    if (!upcase_key) {
+        goto error2;
     }
 
-    if (PyDict_SetItemString(converters, name, callable) != 0) {
-        goto error;
+    if (PyDict_SetItem(converters, upcase_key, callable) != 0) {
+        goto error3;
     }
 
     Py_INCREF(Py_None);
     retval = Py_None;
-error:
-    if (name) {
-        PyMem_Free(name);
-    }
+error3:
+    Py_DECREF(upcase_key);
+error2:
+    Py_DECREF(key);
+error1:
     return retval;
 }
detect_types.patch (text/x-patch, 863 B)
--- src/cursor.c~	2007-01-03 13:36:43.000000000 -0600
+++ src/cursor.c	2007-01-03 13:37:17.000000000 -0600
@@ -175,7 +175,7 @@
     for (i = 0; i < sqlite3_column_count(self->statement->st); i++) {
         converter = NULL;
 
-        if (self->connection->detect_types | PARSE_COLNAMES) {
+        if (self->connection->detect_types & PARSE_COLNAMES) {
             colname = sqlite3_column_name(self->statement->st, i);
             if (colname) {
                 for (pos = colname; *pos != 0; pos++) {
@@ -198,7 +198,7 @@
             }
         }
 
-        if (!converter && self->connection->detect_types | PARSE_DECLTYPES) {
+        if (!converter && self->connection->detect_types & PARSE_DECLTYPES) {
             decltype = sqlite3_column_decltype(self->statement->st, i);
             if (decltype) {
                 for (pos = decltype;;pos++) {
test.py (text/x-python, 1.4 KB)
#!/usr/bin/env python

import sys
from StringIO import StringIO as sio
from decimal import Decimal
sys.path.insert(0, './build/lib.linux-i686-2.4')
from pysqlite2 import dbapi2 as sqlite
#testdb='/tmp/testdb.sqlite'
testdb=':memory:'
detect_types=(len(sys.argv) > 1 and int(sys.argv[1])) or 0

# type converters
def conv_point(s):
  print 'converting point', s
  return tuple(map(float, s.split(";")))
#  x, y = map(float, s.split(";"))
#  return Point(x, y)

# put in the converters
sqlite.register_converter("point(99)", conv_point)
sqlite.register_converter("vARcHAR(20)", sio)
sqlite.register_converter("SMALLint(2)", Decimal)
#sqlite.register_converter(3423, float)

# get connection
#conn = sqlite.connect(testdb)
#conn = sqlite.connect(testdb, detect_types=sqlite.PARSE_DECLTYPES)
#conn = sqlite.connect(testdb, detect_types=sqlite.PARSE_COLNAMES)
conn = sqlite.connect(testdb, detect_types=detect_types)

# make table
sqltable="""
CREATE TABLE test(
  f1 varCHar(20),
  f2 smallInt(2),
  f3 point(99)
)
"""
conn.execute(sqltable)

# populate table
records = [
  ('a#FH98fHFE*(;dsf', 213, '23.4;.834'),
  ('23;234', 2, '32;5.34'),
  ('EFIH0f4893hrvnuj', 13, '1234567890;0.235'),
]

for r in records:
  conn.execute('INSERT INTO test VALUES (?,?,?)', r)

# query table and see if conversions work properly
#cur = conn.execute('select f1, f2, f3 from test')
cur = conn.execute('select f1, f2, f3 as "f3 [point(99)]" from test')
#print dir(cur)
rows = cur.fetchall()
print rows
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.