Add column decltype to cursor description.
This commit is contained in:
parent
3f8b297958
commit
61e9937224
2 changed files with 49 additions and 3 deletions
25
src/cursor.c
25
src/cursor.c
|
|
@ -219,6 +219,15 @@ _pysqlite_build_column_name(pysqlite_Cursor *self, const char *colname)
|
||||||
return PyUnicode_FromStringAndSize(colname, len);
|
return PyUnicode_FromStringAndSize(colname, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
_pysqlite_build_column_decltype(pysqlite_Cursor *self, const char *decltype)
|
||||||
|
{
|
||||||
|
if (!decltype) {
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
return PyUnicode_FromStringAndSize(decltype, strlen(decltype));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns a row from the currently active SQLite statement
|
* Returns a row from the currently active SQLite statement
|
||||||
*
|
*
|
||||||
|
|
@ -378,6 +387,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args)
|
||||||
PyObject* result;
|
PyObject* result;
|
||||||
int numcols;
|
int numcols;
|
||||||
PyObject* column_name;
|
PyObject* column_name;
|
||||||
|
PyObject* column_decltype;
|
||||||
PyObject* second_argument = NULL;
|
PyObject* second_argument = NULL;
|
||||||
sqlite_int64 lastrowid;
|
sqlite_int64 lastrowid;
|
||||||
|
|
||||||
|
|
@ -541,6 +551,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args)
|
||||||
}
|
}
|
||||||
for (i = 0; i < numcols; i++) {
|
for (i = 0; i < numcols; i++) {
|
||||||
const char *colname;
|
const char *colname;
|
||||||
|
const char *decltype;
|
||||||
colname = sqlite3_column_name(self->statement->st, i);
|
colname = sqlite3_column_name(self->statement->st, i);
|
||||||
if (colname == NULL) {
|
if (colname == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
|
|
@ -550,10 +561,18 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args)
|
||||||
if (!column_name) {
|
if (!column_name) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
PyObject *descriptor = PyTuple_Pack(7, column_name,
|
decltype = sqlite3_column_decltype(self->statement->st, i);
|
||||||
Py_None, Py_None, Py_None,
|
column_decltype = _pysqlite_build_column_decltype(self, decltype);
|
||||||
Py_None, Py_None, Py_None);
|
if (!column_decltype) {
|
||||||
Py_DECREF(column_name);
|
Py_DECREF(column_name);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *descriptor = PyTuple_Pack(7, column_name, column_decltype,
|
||||||
|
Py_None, Py_None, Py_None,
|
||||||
|
Py_None, Py_None);
|
||||||
|
Py_DECREF(column_name);
|
||||||
|
Py_DECREF(column_decltype);
|
||||||
if (descriptor == NULL) {
|
if (descriptor == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1017,6 +1017,32 @@ class ClosedCurTests(unittest.TestCase):
|
||||||
method(*params)
|
method(*params)
|
||||||
|
|
||||||
|
|
||||||
|
class SqliteColumnTypeTests(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.cx = sqlite.connect(':memory:')
|
||||||
|
self.cx.execute('create table test(a text, b datetime)')
|
||||||
|
self.cx.execute('create view test_view as select * from test')
|
||||||
|
|
||||||
|
def CheckDeclTypes(self):
|
||||||
|
curs = self.cx.execute('select * from test')
|
||||||
|
self.assertEqual(curs.description, (
|
||||||
|
('a', 'TEXT', None, None, None, None, None),
|
||||||
|
('b', 'datetime', None, None, None, None, None),
|
||||||
|
))
|
||||||
|
|
||||||
|
curs = self.cx.execute('select * from test_view')
|
||||||
|
self.assertEqual(curs.description, (
|
||||||
|
('a', 'TEXT', None, None, None, None, None),
|
||||||
|
('b', 'datetime', None, None, None, None, None),
|
||||||
|
))
|
||||||
|
|
||||||
|
# Expressions return NULL decltype, reported as None.
|
||||||
|
curs = self.cx.execute('select b + b as c from test_view')
|
||||||
|
self.assertEqual(curs.description, (
|
||||||
|
('c', None, None, None, None, None, None),
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
class SqliteOnConflictTests(unittest.TestCase):
|
class SqliteOnConflictTests(unittest.TestCase):
|
||||||
"""
|
"""
|
||||||
Tests for SQLite's "insert on conflict" feature.
|
Tests for SQLite's "insert on conflict" feature.
|
||||||
|
|
@ -1181,6 +1207,7 @@ def suite():
|
||||||
ext_suite = unittest.makeSuite(ExtensionTests, "Check")
|
ext_suite = unittest.makeSuite(ExtensionTests, "Check")
|
||||||
closed_con_suite = unittest.makeSuite(ClosedConTests, "Check")
|
closed_con_suite = unittest.makeSuite(ClosedConTests, "Check")
|
||||||
closed_cur_suite = unittest.makeSuite(ClosedCurTests, "Check")
|
closed_cur_suite = unittest.makeSuite(ClosedCurTests, "Check")
|
||||||
|
columntypes_suite = unittest.makeSuite(SqliteColumnTypeTests, "Check")
|
||||||
on_conflict_suite = unittest.makeSuite(SqliteOnConflictTests, "Check")
|
on_conflict_suite = unittest.makeSuite(SqliteOnConflictTests, "Check")
|
||||||
blob_suite = unittest.makeSuite(BlobTests, "Check")
|
blob_suite = unittest.makeSuite(BlobTests, "Check")
|
||||||
closed_blob_suite = unittest.makeSuite(ClosedBlobTests, "Check")
|
closed_blob_suite = unittest.makeSuite(ClosedBlobTests, "Check")
|
||||||
|
|
@ -1188,7 +1215,7 @@ def suite():
|
||||||
return unittest.TestSuite((
|
return unittest.TestSuite((
|
||||||
module_suite, connection_suite, cursor_suite, thread_suite,
|
module_suite, connection_suite, cursor_suite, thread_suite,
|
||||||
constructor_suite, ext_suite, closed_con_suite, closed_cur_suite,
|
constructor_suite, ext_suite, closed_con_suite, closed_cur_suite,
|
||||||
on_conflict_suite, blob_suite, closed_blob_suite,
|
columntypes_suite, on_conflict_suite, blob_suite, closed_blob_suite,
|
||||||
blob_context_manager_suite,
|
blob_context_manager_suite,
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue