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