Merged code from pysqlite 2.6.0.
This commit is contained in:
parent
2bb66e03b7
commit
3bbb67273a
|
@ -0,0 +1,26 @@
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
con = sqlite3.connect(":memory:")
|
||||||
|
|
||||||
|
# enable extension loading
|
||||||
|
con.enable_load_extension(True)
|
||||||
|
|
||||||
|
# Load the fulltext search extension
|
||||||
|
con.execute("select load_extension('./fts3.so')")
|
||||||
|
|
||||||
|
# alternatively you can load the extension using an API call:
|
||||||
|
# con.load_extension("./fts3.so")
|
||||||
|
|
||||||
|
# disable extension laoding again
|
||||||
|
con.enable_load_extension(False)
|
||||||
|
|
||||||
|
# example from SQLite wiki
|
||||||
|
con.execute("create virtual table recipe using fts3(name, ingredients)")
|
||||||
|
con.executescript("""
|
||||||
|
insert into recipe (name, ingredients) values ('broccoli stew', 'broccoli peppers cheese tomatoes');
|
||||||
|
insert into recipe (name, ingredients) values ('pumpkin stew', 'pumpkin onions garlic celery');
|
||||||
|
insert into recipe (name, ingredients) values ('broccoli pie', 'broccoli cheese onions flour');
|
||||||
|
insert into recipe (name, ingredients) values ('pumpkin pie', 'pumpkin sugar flour butter');
|
||||||
|
""")
|
||||||
|
for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"):
|
||||||
|
print row
|
|
@ -368,6 +368,25 @@ Connection Objects
|
||||||
method with :const:`None` for *handler*.
|
method with :const:`None` for *handler*.
|
||||||
|
|
||||||
|
|
||||||
|
.. method:: Connection.enable_load_extension(enabled)
|
||||||
|
|
||||||
|
.. versionadded:: 2.7
|
||||||
|
|
||||||
|
This routine allows/disallows the SQLite engine to load SQLite extensions
|
||||||
|
from shared libraries. SQLite extensions can define new functions,
|
||||||
|
aggregates or whole new virtual table implementations. One well-known
|
||||||
|
extension is the fulltext-search extension distributed with SQLite.
|
||||||
|
|
||||||
|
.. literalinclude:: ../includes/sqlite3/load_extension.py
|
||||||
|
|
||||||
|
.. method:: Connection.load_extension(path)
|
||||||
|
|
||||||
|
.. versionadded:: 2.7
|
||||||
|
|
||||||
|
This routine loads a SQLite extension from a shared library. You have to
|
||||||
|
enable extension loading with ``enable_load_extension`` before you can use
|
||||||
|
this routine.
|
||||||
|
|
||||||
.. attribute:: Connection.row_factory
|
.. attribute:: Connection.row_factory
|
||||||
|
|
||||||
You can change this attribute to a callable that accepts the cursor and the
|
You can change this attribute to a callable that accepts the cursor and the
|
||||||
|
@ -439,7 +458,7 @@ Connection Objects
|
||||||
Cursor Objects
|
Cursor Objects
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
.. class:: Cursor
|
A :class:`Cursor` instance has the following attributes and methods:
|
||||||
|
|
||||||
A SQLite database cursor has the following attributes and methods:
|
A SQLite database cursor has the following attributes and methods:
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#-*- coding: ISO-8859-1 -*-
|
#-*- coding: ISO-8859-1 -*-
|
||||||
# pysqlite2/test/dbapi.py: tests for DB-API compliance
|
# pysqlite2/test/dbapi.py: tests for DB-API compliance
|
||||||
#
|
#
|
||||||
# Copyright (C) 2004-2007 Gerhard Häring <gh@ghaering.de>
|
# Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
#
|
#
|
||||||
# This file is part of pysqlite.
|
# This file is part of pysqlite.
|
||||||
#
|
#
|
||||||
|
@ -672,13 +672,13 @@ class ExtensionTests(unittest.TestCase):
|
||||||
res = cur.fetchone()[0]
|
res = cur.fetchone()[0]
|
||||||
self.assertEqual(res, 6)
|
self.assertEqual(res, 6)
|
||||||
|
|
||||||
def CheckScriptErrorIncomplete(self):
|
def CheckScriptSyntaxError(self):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
raised = False
|
raised = False
|
||||||
try:
|
try:
|
||||||
cur.executescript("create table test(sadfsadfdsa")
|
cur.executescript("create table test(x); asdf; create table test2(x)")
|
||||||
except sqlite.ProgrammingError:
|
except sqlite.OperationalError:
|
||||||
raised = True
|
raised = True
|
||||||
self.assertEqual(raised, True, "should have raised an exception")
|
self.assertEqual(raised, True, "should have raised an exception")
|
||||||
|
|
||||||
|
@ -711,7 +711,7 @@ class ExtensionTests(unittest.TestCase):
|
||||||
result = con.execute("select foo from test").fetchone()[0]
|
result = con.execute("select foo from test").fetchone()[0]
|
||||||
self.assertEqual(result, 5, "Basic test of Connection.executescript")
|
self.assertEqual(result, 5, "Basic test of Connection.executescript")
|
||||||
|
|
||||||
class ClosedTests(unittest.TestCase):
|
class ClosedConTests(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -763,6 +763,102 @@ class ClosedTests(unittest.TestCase):
|
||||||
except:
|
except:
|
||||||
self.fail("Should have raised a ProgrammingError")
|
self.fail("Should have raised a ProgrammingError")
|
||||||
|
|
||||||
|
def CheckClosedCreateFunction(self):
|
||||||
|
con = sqlite.connect(":memory:")
|
||||||
|
con.close()
|
||||||
|
def f(x): return 17
|
||||||
|
try:
|
||||||
|
con.create_function("foo", 1, f)
|
||||||
|
self.fail("Should have raised a ProgrammingError")
|
||||||
|
except sqlite.ProgrammingError:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
self.fail("Should have raised a ProgrammingError")
|
||||||
|
|
||||||
|
def CheckClosedCreateAggregate(self):
|
||||||
|
con = sqlite.connect(":memory:")
|
||||||
|
con.close()
|
||||||
|
class Agg:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
def step(self, x):
|
||||||
|
pass
|
||||||
|
def finalize(self):
|
||||||
|
return 17
|
||||||
|
try:
|
||||||
|
con.create_aggregate("foo", 1, Agg)
|
||||||
|
self.fail("Should have raised a ProgrammingError")
|
||||||
|
except sqlite.ProgrammingError:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
self.fail("Should have raised a ProgrammingError")
|
||||||
|
|
||||||
|
def CheckClosedSetAuthorizer(self):
|
||||||
|
con = sqlite.connect(":memory:")
|
||||||
|
con.close()
|
||||||
|
def authorizer(*args):
|
||||||
|
return sqlite.DENY
|
||||||
|
try:
|
||||||
|
con.set_authorizer(authorizer)
|
||||||
|
self.fail("Should have raised a ProgrammingError")
|
||||||
|
except sqlite.ProgrammingError:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
self.fail("Should have raised a ProgrammingError")
|
||||||
|
|
||||||
|
def CheckClosedSetProgressCallback(self):
|
||||||
|
con = sqlite.connect(":memory:")
|
||||||
|
con.close()
|
||||||
|
def progress(): pass
|
||||||
|
try:
|
||||||
|
con.set_progress_handler(progress, 100)
|
||||||
|
self.fail("Should have raised a ProgrammingError")
|
||||||
|
except sqlite.ProgrammingError:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
self.fail("Should have raised a ProgrammingError")
|
||||||
|
|
||||||
|
def CheckClosedCall(self):
|
||||||
|
con = sqlite.connect(":memory:")
|
||||||
|
con.close()
|
||||||
|
try:
|
||||||
|
con()
|
||||||
|
self.fail("Should have raised a ProgrammingError")
|
||||||
|
except sqlite.ProgrammingError:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
self.fail("Should have raised a ProgrammingError")
|
||||||
|
|
||||||
|
class ClosedCurTests(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def CheckClosed(self):
|
||||||
|
con = sqlite.connect(":memory:")
|
||||||
|
cur = con.cursor()
|
||||||
|
cur.close()
|
||||||
|
|
||||||
|
for method_name in ("execute", "executemany", "executescript", "fetchall", "fetchmany", "fetchone"):
|
||||||
|
if method_name in ("execute", "executescript"):
|
||||||
|
params = ("select 4 union select 5",)
|
||||||
|
elif method_name == "executemany":
|
||||||
|
params = ("insert into foo(bar) values (?)", [(3,), (4,)])
|
||||||
|
else:
|
||||||
|
params = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
method = getattr(cur, method_name)
|
||||||
|
|
||||||
|
method(*params)
|
||||||
|
self.fail("Should have raised a ProgrammingError: method " + method_name)
|
||||||
|
except sqlite.ProgrammingError:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
self.fail("Should have raised a ProgrammingError: " + method_name)
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
module_suite = unittest.makeSuite(ModuleTests, "Check")
|
module_suite = unittest.makeSuite(ModuleTests, "Check")
|
||||||
connection_suite = unittest.makeSuite(ConnectionTests, "Check")
|
connection_suite = unittest.makeSuite(ConnectionTests, "Check")
|
||||||
|
@ -770,8 +866,9 @@ def suite():
|
||||||
thread_suite = unittest.makeSuite(ThreadTests, "Check")
|
thread_suite = unittest.makeSuite(ThreadTests, "Check")
|
||||||
constructor_suite = unittest.makeSuite(ConstructorTests, "Check")
|
constructor_suite = unittest.makeSuite(ConstructorTests, "Check")
|
||||||
ext_suite = unittest.makeSuite(ExtensionTests, "Check")
|
ext_suite = unittest.makeSuite(ExtensionTests, "Check")
|
||||||
closed_suite = unittest.makeSuite(ClosedTests, "Check")
|
closed_con_suite = unittest.makeSuite(ClosedConTests, "Check")
|
||||||
return unittest.TestSuite((module_suite, connection_suite, cursor_suite, thread_suite, constructor_suite, ext_suite, closed_suite))
|
closed_cur_suite = unittest.makeSuite(ClosedCurTests, "Check")
|
||||||
|
return unittest.TestSuite((module_suite, connection_suite, cursor_suite, thread_suite, constructor_suite, ext_suite, closed_con_suite, closed_cur_suite))
|
||||||
|
|
||||||
def test():
|
def test():
|
||||||
runner = unittest.TextTestRunner()
|
runner = unittest.TextTestRunner()
|
||||||
|
|
|
@ -70,16 +70,6 @@ class RegressionTests(unittest.TestCase):
|
||||||
cur.execute('select 1 as "foo baz"')
|
cur.execute('select 1 as "foo baz"')
|
||||||
self.assertEqual(cur.description[0][0], "foo baz")
|
self.assertEqual(cur.description[0][0], "foo baz")
|
||||||
|
|
||||||
def CheckStatementAvailable(self):
|
|
||||||
# pysqlite up to 2.3.2 crashed on this, because the active statement handle was not checked
|
|
||||||
# before trying to fetch data from it. close() destroys the active statement ...
|
|
||||||
con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_DECLTYPES)
|
|
||||||
cur = con.cursor()
|
|
||||||
cur.execute("select 4 union select 5")
|
|
||||||
cur.close()
|
|
||||||
cur.fetchone()
|
|
||||||
cur.fetchone()
|
|
||||||
|
|
||||||
def CheckStatementFinalizationOnCloseDb(self):
|
def CheckStatementFinalizationOnCloseDb(self):
|
||||||
# pysqlite versions <= 2.3.3 only finalized statements in the statement
|
# pysqlite versions <= 2.3.3 only finalized statements in the statement
|
||||||
# cache when closing the database. statements that were still
|
# cache when closing the database. statements that were still
|
||||||
|
@ -167,6 +157,107 @@ class RegressionTests(unittest.TestCase):
|
||||||
self.assertRaises(UnicodeEncodeError, setattr, con,
|
self.assertRaises(UnicodeEncodeError, setattr, con,
|
||||||
"isolation_level", u"\xe9")
|
"isolation_level", u"\xe9")
|
||||||
|
|
||||||
|
def CheckCursorConstructorCallCheck(self):
|
||||||
|
"""
|
||||||
|
Verifies that cursor methods check wether base class __init__ was called.
|
||||||
|
"""
|
||||||
|
class Cursor(sqlite.Cursor):
|
||||||
|
def __init__(self, con):
|
||||||
|
pass
|
||||||
|
|
||||||
|
con = sqlite.connect(":memory:")
|
||||||
|
cur = Cursor(con)
|
||||||
|
try:
|
||||||
|
cur.execute("select 4+5").fetchall()
|
||||||
|
self.fail("should have raised ProgrammingError")
|
||||||
|
except sqlite.ProgrammingError:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
self.fail("should have raised ProgrammingError")
|
||||||
|
|
||||||
|
def CheckConnectionConstructorCallCheck(self):
|
||||||
|
"""
|
||||||
|
Verifies that connection methods check wether base class __init__ was called.
|
||||||
|
"""
|
||||||
|
class Connection(sqlite.Connection):
|
||||||
|
def __init__(self, name):
|
||||||
|
pass
|
||||||
|
|
||||||
|
con = Connection(":memory:")
|
||||||
|
try:
|
||||||
|
cur = con.cursor()
|
||||||
|
self.fail("should have raised ProgrammingError")
|
||||||
|
except sqlite.ProgrammingError:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
self.fail("should have raised ProgrammingError")
|
||||||
|
|
||||||
|
def CheckCursorRegistration(self):
|
||||||
|
"""
|
||||||
|
Verifies that subclassed cursor classes are correctly registered with
|
||||||
|
the connection object, too. (fetch-across-rollback problem)
|
||||||
|
"""
|
||||||
|
class Connection(sqlite.Connection):
|
||||||
|
def cursor(self):
|
||||||
|
return Cursor(self)
|
||||||
|
|
||||||
|
class Cursor(sqlite.Cursor):
|
||||||
|
def __init__(self, con):
|
||||||
|
sqlite.Cursor.__init__(self, con)
|
||||||
|
|
||||||
|
con = Connection(":memory:")
|
||||||
|
cur = con.cursor()
|
||||||
|
cur.execute("create table foo(x)")
|
||||||
|
cur.executemany("insert into foo(x) values (?)", [(3,), (4,), (5,)])
|
||||||
|
cur.execute("select x from foo")
|
||||||
|
con.rollback()
|
||||||
|
try:
|
||||||
|
cur.fetchall()
|
||||||
|
self.fail("should have raised InterfaceError")
|
||||||
|
except sqlite.InterfaceError:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
self.fail("should have raised InterfaceError")
|
||||||
|
|
||||||
|
def CheckAutoCommit(self):
|
||||||
|
"""
|
||||||
|
Verifies that creating a connection in autocommit mode works.
|
||||||
|
2.5.3 introduced a regression so that these could no longer
|
||||||
|
be created.
|
||||||
|
"""
|
||||||
|
con = sqlite.connect(":memory:", isolation_level=None)
|
||||||
|
|
||||||
|
def CheckPragmaAutocommit(self):
|
||||||
|
"""
|
||||||
|
Verifies that running a PRAGMA statement that does an autocommit does
|
||||||
|
work. This did not work in 2.5.3/2.5.4.
|
||||||
|
"""
|
||||||
|
con = sqlite.connect(":memory:")
|
||||||
|
cur = con.cursor()
|
||||||
|
cur.execute("create table foo(bar)")
|
||||||
|
cur.execute("insert into foo(bar) values (5)")
|
||||||
|
|
||||||
|
cur.execute("pragma page_size")
|
||||||
|
row = cur.fetchone()
|
||||||
|
|
||||||
|
def CheckSetDict(self):
|
||||||
|
"""
|
||||||
|
See http://bugs.python.org/issue7478
|
||||||
|
|
||||||
|
It was possible to successfully register callbacks that could not be
|
||||||
|
hashed. Return codes of PyDict_SetItem were not checked properly.
|
||||||
|
"""
|
||||||
|
class NotHashable:
|
||||||
|
def __call__(self, *args, **kw):
|
||||||
|
pass
|
||||||
|
def __hash__(self):
|
||||||
|
raise TypeError()
|
||||||
|
var = NotHashable()
|
||||||
|
con = sqlite.connect(":memory:")
|
||||||
|
self.assertRaises(TypeError, con.create_function, var)
|
||||||
|
self.assertRaises(TypeError, con.create_aggregate, var)
|
||||||
|
self.assertRaises(TypeError, con.set_authorizer, var)
|
||||||
|
self.assertRaises(TypeError, con.set_progress_handler, var)
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
regression_suite = unittest.makeSuite(RegressionTests, "Check")
|
regression_suite = unittest.makeSuite(RegressionTests, "Check")
|
||||||
|
|
|
@ -148,6 +148,26 @@ class TransactionTests(unittest.TestCase):
|
||||||
# NO self.con2.rollback() HERE!!!
|
# NO self.con2.rollback() HERE!!!
|
||||||
self.con1.commit()
|
self.con1.commit()
|
||||||
|
|
||||||
|
def CheckRollbackCursorConsistency(self):
|
||||||
|
"""
|
||||||
|
Checks if cursors on the connection are set into a "reset" state
|
||||||
|
when a rollback is done on the connection.
|
||||||
|
"""
|
||||||
|
con = sqlite.connect(":memory:")
|
||||||
|
cur = con.cursor()
|
||||||
|
cur.execute("create table test(x)")
|
||||||
|
cur.execute("insert into test(x) values (5)")
|
||||||
|
cur.execute("select 1 union select 2 union select 3")
|
||||||
|
|
||||||
|
con.rollback()
|
||||||
|
try:
|
||||||
|
cur.fetchall()
|
||||||
|
self.fail("InterfaceError should have been raised")
|
||||||
|
except sqlite.InterfaceError, e:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
self.fail("InterfaceError should have been raised")
|
||||||
|
|
||||||
class SpecialCommandTests(unittest.TestCase):
|
class SpecialCommandTests(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.con = sqlite.connect(":memory:")
|
self.con = sqlite.connect(":memory:")
|
||||||
|
|
|
@ -78,6 +78,33 @@ class SqliteTypeTests(unittest.TestCase):
|
||||||
row = self.cur.fetchone()
|
row = self.cur.fetchone()
|
||||||
self.assertEqual(row[0], u"Österreich")
|
self.assertEqual(row[0], u"Österreich")
|
||||||
|
|
||||||
|
def CheckNonUtf8_Default(self):
|
||||||
|
try:
|
||||||
|
self.cur.execute("select ?", (chr(150),))
|
||||||
|
self.fail("should have raised a ProgrammingError")
|
||||||
|
except sqlite.ProgrammingError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def CheckNonUtf8_TextFactoryString(self):
|
||||||
|
orig_text_factory = self.con.text_factory
|
||||||
|
try:
|
||||||
|
self.con.text_factory = str
|
||||||
|
self.cur.execute("select ?", (chr(150),))
|
||||||
|
finally:
|
||||||
|
self.con.text_factory = orig_text_factory
|
||||||
|
|
||||||
|
def CheckNonUtf8_TextFactoryOptimizedUnicode(self):
|
||||||
|
orig_text_factory = self.con.text_factory
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
self.con.text_factory = sqlite.OptimizedUnicode
|
||||||
|
self.cur.execute("select ?", (chr(150),))
|
||||||
|
self.fail("should have raised a ProgrammingError")
|
||||||
|
except sqlite.ProgrammingError:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
self.con.text_factory = orig_text_factory
|
||||||
|
|
||||||
class DeclTypesTests(unittest.TestCase):
|
class DeclTypesTests(unittest.TestCase):
|
||||||
class Foo:
|
class Foo:
|
||||||
def __init__(self, _val):
|
def __init__(self, _val):
|
||||||
|
|
|
@ -103,6 +103,9 @@ Library
|
||||||
Extension Modules
|
Extension Modules
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- The sqlite3 module was updated to pysqlite 2.6.0. This fixes several obscure
|
||||||
|
bugs and allows loading SQLite extensions from shared libraries.
|
||||||
|
|
||||||
- Issue #7808: Fix reference leaks in _bsddb and related tests.
|
- Issue #7808: Fix reference leaks in _bsddb and related tests.
|
||||||
|
|
||||||
- Issue #6544: fix a reference leak in the kqueue implementation's error
|
- Issue #6544: fix a reference leak in the kqueue implementation's error
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* cache .c - a LRU cache
|
/* cache .c - a LRU cache
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004-2007 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
@ -21,6 +21,7 @@
|
||||||
* 3. This notice may not be removed or altered from any source distribution.
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "sqlitecompat.h"
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* cache.h - definitions for the LRU cache
|
/* cache.h - definitions for the LRU cache
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004-2007 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* connection.c - the connection type
|
/* connection.c - the connection type
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004-2007 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
@ -35,7 +35,14 @@
|
||||||
#define ACTION_FINALIZE 1
|
#define ACTION_FINALIZE 1
|
||||||
#define ACTION_RESET 2
|
#define ACTION_RESET 2
|
||||||
|
|
||||||
|
#if SQLITE_VERSION_NUMBER >= 3003008
|
||||||
|
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||||
|
#define HAVE_LOAD_EXTENSION
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level);
|
static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level);
|
||||||
|
static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self);
|
||||||
|
|
||||||
|
|
||||||
static void _sqlite3_result_error(sqlite3_context* ctx, const char* errmsg, int len)
|
static void _sqlite3_result_error(sqlite3_context* ctx, const char* errmsg, int len)
|
||||||
|
@ -73,10 +80,13 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->initialized = 1;
|
||||||
|
|
||||||
self->begin_statement = NULL;
|
self->begin_statement = NULL;
|
||||||
|
|
||||||
self->statement_cache = NULL;
|
self->statement_cache = NULL;
|
||||||
self->statements = NULL;
|
self->statements = NULL;
|
||||||
|
self->cursors = NULL;
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
self->row_factory = Py_None;
|
self->row_factory = Py_None;
|
||||||
|
@ -150,11 +160,15 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->created_statements = 0;
|
||||||
|
self->created_cursors = 0;
|
||||||
|
|
||||||
|
/* Create lists of weak references to statements/cursors */
|
||||||
self->statements = PyList_New(0);
|
self->statements = PyList_New(0);
|
||||||
if (!self->statements) {
|
self->cursors = PyList_New(0);
|
||||||
|
if (!self->statements || !self->cursors) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
self->created_statements = 0;
|
|
||||||
|
|
||||||
/* By default, the Cache class INCREFs the factory in its initializer, and
|
/* By default, the Cache class INCREFs the factory in its initializer, and
|
||||||
* decrefs it in its deallocator method. Since this would create a circular
|
* decrefs it in its deallocator method. Since this would create a circular
|
||||||
|
@ -218,11 +232,12 @@ void pysqlite_flush_statement_cache(pysqlite_Connection* self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* action in (ACTION_RESET, ACTION_FINALIZE) */
|
/* action in (ACTION_RESET, ACTION_FINALIZE) */
|
||||||
void pysqlite_do_all_statements(pysqlite_Connection* self, int action)
|
void pysqlite_do_all_statements(pysqlite_Connection* self, int action, int reset_cursors)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
PyObject* weakref;
|
PyObject* weakref;
|
||||||
PyObject* statement;
|
PyObject* statement;
|
||||||
|
pysqlite_Cursor* cursor;
|
||||||
|
|
||||||
for (i = 0; i < PyList_Size(self->statements); i++) {
|
for (i = 0; i < PyList_Size(self->statements); i++) {
|
||||||
weakref = PyList_GetItem(self->statements, i);
|
weakref = PyList_GetItem(self->statements, i);
|
||||||
|
@ -235,6 +250,16 @@ void pysqlite_do_all_statements(pysqlite_Connection* self, int action)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (reset_cursors) {
|
||||||
|
for (i = 0; i < PyList_Size(self->cursors); i++) {
|
||||||
|
weakref = PyList_GetItem(self->cursors, i);
|
||||||
|
cursor = (pysqlite_Cursor*)PyWeakref_GetObject(weakref);
|
||||||
|
if ((PyObject*)cursor != Py_None) {
|
||||||
|
cursor->reset = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pysqlite_connection_dealloc(pysqlite_Connection* self)
|
void pysqlite_connection_dealloc(pysqlite_Connection* self)
|
||||||
|
@ -263,17 +288,43 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self)
|
||||||
Py_XDECREF(self->text_factory);
|
Py_XDECREF(self->text_factory);
|
||||||
Py_XDECREF(self->collations);
|
Py_XDECREF(self->collations);
|
||||||
Py_XDECREF(self->statements);
|
Py_XDECREF(self->statements);
|
||||||
|
Py_XDECREF(self->cursors);
|
||||||
|
|
||||||
self->ob_type->tp_free((PyObject*)self);
|
self->ob_type->tp_free((PyObject*)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Registers a cursor with the connection.
|
||||||
|
*
|
||||||
|
* 0 => error; 1 => ok
|
||||||
|
*/
|
||||||
|
int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObject* cursor)
|
||||||
|
{
|
||||||
|
PyObject* weakref;
|
||||||
|
|
||||||
|
weakref = PyWeakref_NewRef((PyObject*)cursor, NULL);
|
||||||
|
if (!weakref) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyList_Append(connection->cursors, weakref) != 0) {
|
||||||
|
Py_CLEAR(weakref);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF(weakref);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
error:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
|
PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
|
||||||
{
|
{
|
||||||
static char *kwlist[] = {"factory", NULL, NULL};
|
static char *kwlist[] = {"factory", NULL, NULL};
|
||||||
PyObject* factory = NULL;
|
PyObject* factory = NULL;
|
||||||
PyObject* cursor;
|
PyObject* cursor;
|
||||||
|
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist,
|
||||||
&factory)) {
|
&factory)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -289,6 +340,8 @@ PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args,
|
||||||
|
|
||||||
cursor = PyObject_CallFunction(factory, "O", self);
|
cursor = PyObject_CallFunction(factory, "O", self);
|
||||||
|
|
||||||
|
_pysqlite_drop_unused_cursor_references(self);
|
||||||
|
|
||||||
if (cursor && self->row_factory != Py_None) {
|
if (cursor && self->row_factory != Py_None) {
|
||||||
Py_XDECREF(((pysqlite_Cursor*)cursor)->row_factory);
|
Py_XDECREF(((pysqlite_Cursor*)cursor)->row_factory);
|
||||||
Py_INCREF(self->row_factory);
|
Py_INCREF(self->row_factory);
|
||||||
|
@ -307,7 +360,7 @@ PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pysqlite_do_all_statements(self, ACTION_FINALIZE);
|
pysqlite_do_all_statements(self, ACTION_FINALIZE, 1);
|
||||||
|
|
||||||
if (self->db) {
|
if (self->db) {
|
||||||
if (self->apsw_connection) {
|
if (self->apsw_connection) {
|
||||||
|
@ -341,6 +394,11 @@ PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args)
|
||||||
*/
|
*/
|
||||||
int pysqlite_check_connection(pysqlite_Connection* con)
|
int pysqlite_check_connection(pysqlite_Connection* con)
|
||||||
{
|
{
|
||||||
|
if (!con->initialized) {
|
||||||
|
PyErr_SetString(pysqlite_ProgrammingError, "Base Connection.__init__ not called.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!con->db) {
|
if (!con->db) {
|
||||||
PyErr_SetString(pysqlite_ProgrammingError, "Cannot operate on a closed database.");
|
PyErr_SetString(pysqlite_ProgrammingError, "Cannot operate on a closed database.");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -399,6 +457,8 @@ PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->inTransaction) {
|
if (self->inTransaction) {
|
||||||
|
pysqlite_do_all_statements(self, ACTION_RESET, 0);
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
rc = sqlite3_prepare(self->db, "COMMIT", -1, &statement, &tail);
|
rc = sqlite3_prepare(self->db, "COMMIT", -1, &statement, &tail);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
@ -443,7 +503,7 @@ PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->inTransaction) {
|
if (self->inTransaction) {
|
||||||
pysqlite_do_all_statements(self, ACTION_RESET);
|
pysqlite_do_all_statements(self, ACTION_RESET, 1);
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
rc = sqlite3_prepare(self->db, "ROLLBACK", -1, &statement, &tail);
|
rc = sqlite3_prepare(self->db, "ROLLBACK", -1, &statement, &tail);
|
||||||
|
@ -724,7 +784,7 @@ error:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void _pysqlite_drop_unused_statement_references(pysqlite_Connection* self)
|
static void _pysqlite_drop_unused_statement_references(pysqlite_Connection* self)
|
||||||
{
|
{
|
||||||
PyObject* new_list;
|
PyObject* new_list;
|
||||||
PyObject* weakref;
|
PyObject* weakref;
|
||||||
|
@ -756,6 +816,38 @@ void _pysqlite_drop_unused_statement_references(pysqlite_Connection* self)
|
||||||
self->statements = new_list;
|
self->statements = new_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self)
|
||||||
|
{
|
||||||
|
PyObject* new_list;
|
||||||
|
PyObject* weakref;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* we only need to do this once in a while */
|
||||||
|
if (self->created_cursors++ < 200) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->created_cursors = 0;
|
||||||
|
|
||||||
|
new_list = PyList_New(0);
|
||||||
|
if (!new_list) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < PyList_Size(self->cursors); i++) {
|
||||||
|
weakref = PyList_GetItem(self->cursors, i);
|
||||||
|
if (PyWeakref_GetObject(weakref) != Py_None) {
|
||||||
|
if (PyList_Append(new_list, weakref) != 0) {
|
||||||
|
Py_DECREF(new_list);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF(self->cursors);
|
||||||
|
self->cursors = new_list;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
|
PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
|
||||||
{
|
{
|
||||||
static char *kwlist[] = {"name", "narg", "func", NULL, NULL};
|
static char *kwlist[] = {"name", "narg", "func", NULL, NULL};
|
||||||
|
@ -765,6 +857,10 @@ PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObjec
|
||||||
int narg;
|
int narg;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO", kwlist,
|
||||||
&name, &narg, &func))
|
&name, &narg, &func))
|
||||||
{
|
{
|
||||||
|
@ -778,7 +874,8 @@ PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObjec
|
||||||
PyErr_SetString(pysqlite_OperationalError, "Error creating function");
|
PyErr_SetString(pysqlite_OperationalError, "Error creating function");
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
PyDict_SetItem(self->function_pinboard, func, Py_None);
|
if (PyDict_SetItem(self->function_pinboard, func, Py_None) == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
|
@ -794,6 +891,10 @@ PyObject* pysqlite_connection_create_aggregate(pysqlite_Connection* self, PyObje
|
||||||
static char *kwlist[] = { "name", "n_arg", "aggregate_class", NULL };
|
static char *kwlist[] = { "name", "n_arg", "aggregate_class", NULL };
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO:create_aggregate",
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO:create_aggregate",
|
||||||
kwlist, &name, &n_arg, &aggregate_class)) {
|
kwlist, &name, &n_arg, &aggregate_class)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -805,7 +906,8 @@ PyObject* pysqlite_connection_create_aggregate(pysqlite_Connection* self, PyObje
|
||||||
PyErr_SetString(pysqlite_OperationalError, "Error creating aggregate");
|
PyErr_SetString(pysqlite_OperationalError, "Error creating aggregate");
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
PyDict_SetItem(self->function_pinboard, aggregate_class, Py_None);
|
if (PyDict_SetItem(self->function_pinboard, aggregate_class, Py_None) == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
|
@ -877,13 +979,17 @@ static int _progress_handler(void* user_arg)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
|
static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
|
||||||
{
|
{
|
||||||
PyObject* authorizer_cb;
|
PyObject* authorizer_cb;
|
||||||
|
|
||||||
static char *kwlist[] = { "authorizer_callback", NULL };
|
static char *kwlist[] = { "authorizer_callback", NULL };
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:set_authorizer",
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:set_authorizer",
|
||||||
kwlist, &authorizer_cb)) {
|
kwlist, &authorizer_cb)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -895,20 +1001,25 @@ PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, PyObject
|
||||||
PyErr_SetString(pysqlite_OperationalError, "Error setting authorizer callback");
|
PyErr_SetString(pysqlite_OperationalError, "Error setting authorizer callback");
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
PyDict_SetItem(self->function_pinboard, authorizer_cb, Py_None);
|
if (PyDict_SetItem(self->function_pinboard, authorizer_cb, Py_None) == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
|
static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
|
||||||
{
|
{
|
||||||
PyObject* progress_handler;
|
PyObject* progress_handler;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
static char *kwlist[] = { "progress_handler", "n", NULL };
|
static char *kwlist[] = { "progress_handler", "n", NULL };
|
||||||
|
|
||||||
|
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi:set_progress_handler",
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi:set_progress_handler",
|
||||||
kwlist, &progress_handler, &n)) {
|
kwlist, &progress_handler, &n)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -919,13 +1030,64 @@ PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* self, Py
|
||||||
sqlite3_progress_handler(self->db, 0, 0, (void*)0);
|
sqlite3_progress_handler(self->db, 0, 0, (void*)0);
|
||||||
} else {
|
} else {
|
||||||
sqlite3_progress_handler(self->db, n, _progress_handler, progress_handler);
|
sqlite3_progress_handler(self->db, n, _progress_handler, progress_handler);
|
||||||
PyDict_SetItem(self->function_pinboard, progress_handler, Py_None);
|
if (PyDict_SetItem(self->function_pinboard, progress_handler, Py_None) == -1)
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LOAD_EXTENSION
|
||||||
|
static PyObject* pysqlite_enable_load_extension(pysqlite_Connection* self, PyObject* args)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
int onoff;
|
||||||
|
|
||||||
|
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "i", &onoff)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sqlite3_enable_load_extension(self->db, onoff);
|
||||||
|
|
||||||
|
if (rc != SQLITE_OK) {
|
||||||
|
PyErr_SetString(pysqlite_OperationalError, "Error enabling load extension");
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject* pysqlite_load_extension(pysqlite_Connection* self, PyObject* args)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
char* extension_name;
|
||||||
|
char* errmsg;
|
||||||
|
|
||||||
|
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "s", &extension_name)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sqlite3_load_extension(self->db, extension_name, 0, &errmsg);
|
||||||
|
if (rc != 0) {
|
||||||
|
PyErr_SetString(pysqlite_OperationalError, errmsg);
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int pysqlite_check_thread(pysqlite_Connection* self)
|
int pysqlite_check_thread(pysqlite_Connection* self)
|
||||||
{
|
{
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
|
@ -1020,6 +1182,10 @@ PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, Py
|
||||||
PyObject* weakref;
|
PyObject* weakref;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O", &sql)) {
|
if (!PyArg_ParseTuple(args, "O", &sql)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1309,9 +1475,11 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callable != Py_None) {
|
if (callable != Py_None) {
|
||||||
PyDict_SetItem(self->collations, uppercase_name, callable);
|
if (PyDict_SetItem(self->collations, uppercase_name, callable) == -1)
|
||||||
|
goto finally;
|
||||||
} else {
|
} else {
|
||||||
PyDict_DelItem(self->collations, uppercase_name);
|
if (PyDict_DelItem(self->collations, uppercase_name) == -1)
|
||||||
|
goto finally;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = sqlite3_create_collation(self->db,
|
rc = sqlite3_create_collation(self->db,
|
||||||
|
@ -1400,6 +1568,12 @@ static PyMethodDef connection_methods[] = {
|
||||||
PyDoc_STR("Creates a new aggregate. Non-standard.")},
|
PyDoc_STR("Creates a new aggregate. Non-standard.")},
|
||||||
{"set_authorizer", (PyCFunction)pysqlite_connection_set_authorizer, METH_VARARGS|METH_KEYWORDS,
|
{"set_authorizer", (PyCFunction)pysqlite_connection_set_authorizer, METH_VARARGS|METH_KEYWORDS,
|
||||||
PyDoc_STR("Sets authorizer callback. Non-standard.")},
|
PyDoc_STR("Sets authorizer callback. Non-standard.")},
|
||||||
|
#ifdef HAVE_LOAD_EXTENSION
|
||||||
|
{"enable_load_extension", (PyCFunction)pysqlite_enable_load_extension, METH_VARARGS,
|
||||||
|
PyDoc_STR("Enable dynamic loading of SQLite extension modules. Non-standard.")},
|
||||||
|
{"load_extension", (PyCFunction)pysqlite_load_extension, METH_VARARGS,
|
||||||
|
PyDoc_STR("Load SQLite extension module. Non-standard.")},
|
||||||
|
#endif
|
||||||
{"set_progress_handler", (PyCFunction)pysqlite_connection_set_progress_handler, METH_VARARGS|METH_KEYWORDS,
|
{"set_progress_handler", (PyCFunction)pysqlite_connection_set_progress_handler, METH_VARARGS|METH_KEYWORDS,
|
||||||
PyDoc_STR("Sets progress handler callback. Non-standard.")},
|
PyDoc_STR("Sets progress handler callback. Non-standard.")},
|
||||||
{"execute", (PyCFunction)pysqlite_connection_execute, METH_VARARGS,
|
{"execute", (PyCFunction)pysqlite_connection_execute, METH_VARARGS,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* connection.h - definitions for the connection type
|
/* connection.h - definitions for the connection type
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004-2007 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
@ -63,17 +63,21 @@ typedef struct
|
||||||
* used from the same thread it was created in */
|
* used from the same thread it was created in */
|
||||||
int check_same_thread;
|
int check_same_thread;
|
||||||
|
|
||||||
|
int initialized;
|
||||||
|
|
||||||
/* thread identification of the thread the connection was created in */
|
/* thread identification of the thread the connection was created in */
|
||||||
long thread_ident;
|
long thread_ident;
|
||||||
|
|
||||||
pysqlite_Cache* statement_cache;
|
pysqlite_Cache* statement_cache;
|
||||||
|
|
||||||
/* A list of weak references to statements used within this connection */
|
/* Lists of weak references to statements and cursors used within this connection */
|
||||||
PyObject* statements;
|
PyObject* statements;
|
||||||
|
PyObject* cursors;
|
||||||
|
|
||||||
/* a counter for how many statements were created in the connection. May be
|
/* Counters for how many statements/cursors were created in the connection. May be
|
||||||
* reset to 0 at certain intervals */
|
* reset to 0 at certain intervals */
|
||||||
int created_statements;
|
int created_statements;
|
||||||
|
int created_cursors;
|
||||||
|
|
||||||
PyObject* row_factory;
|
PyObject* row_factory;
|
||||||
|
|
||||||
|
@ -125,6 +129,7 @@ PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args
|
||||||
PyObject* pysqlite_connection_new(PyTypeObject* type, PyObject* args, PyObject* kw);
|
PyObject* pysqlite_connection_new(PyTypeObject* type, PyObject* args, PyObject* kw);
|
||||||
int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs);
|
int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs);
|
||||||
|
|
||||||
|
int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObject* cursor);
|
||||||
int pysqlite_check_thread(pysqlite_Connection* self);
|
int pysqlite_check_thread(pysqlite_Connection* self);
|
||||||
int pysqlite_check_connection(pysqlite_Connection* con);
|
int pysqlite_check_connection(pysqlite_Connection* con);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* cursor.c - the cursor type
|
/* cursor.c - the cursor type
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004-2007 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
@ -36,6 +36,8 @@
|
||||||
|
|
||||||
PyObject* pysqlite_cursor_iternext(pysqlite_Cursor* self);
|
PyObject* pysqlite_cursor_iternext(pysqlite_Cursor* self);
|
||||||
|
|
||||||
|
static char* errmsg_fetch_across_rollback = "Cursor needed to be reset because of commit/rollback and can no longer be fetched from.";
|
||||||
|
|
||||||
static pysqlite_StatementKind detect_statement_type(char* statement)
|
static pysqlite_StatementKind detect_statement_type(char* statement)
|
||||||
{
|
{
|
||||||
char buf[20];
|
char buf[20];
|
||||||
|
@ -74,7 +76,7 @@ static pysqlite_StatementKind detect_statement_type(char* statement)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs)
|
static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs)
|
||||||
{
|
{
|
||||||
pysqlite_Connection* connection;
|
pysqlite_Connection* connection;
|
||||||
|
|
||||||
|
@ -87,6 +89,7 @@ int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs
|
||||||
self->connection = connection;
|
self->connection = connection;
|
||||||
self->statement = NULL;
|
self->statement = NULL;
|
||||||
self->next_row = NULL;
|
self->next_row = NULL;
|
||||||
|
self->in_weakreflist = NULL;
|
||||||
|
|
||||||
self->row_cast_map = PyList_New(0);
|
self->row_cast_map = PyList_New(0);
|
||||||
if (!self->row_cast_map) {
|
if (!self->row_cast_map) {
|
||||||
|
@ -100,6 +103,8 @@ int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs
|
||||||
self->lastrowid= Py_None;
|
self->lastrowid= Py_None;
|
||||||
|
|
||||||
self->arraysize = 1;
|
self->arraysize = 1;
|
||||||
|
self->closed = 0;
|
||||||
|
self->reset = 0;
|
||||||
|
|
||||||
self->rowcount = -1L;
|
self->rowcount = -1L;
|
||||||
|
|
||||||
|
@ -110,10 +115,16 @@ int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!pysqlite_connection_register_cursor(connection, (PyObject*)self)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->initialized = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pysqlite_cursor_dealloc(pysqlite_Cursor* self)
|
static void pysqlite_cursor_dealloc(pysqlite_Cursor* self)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -130,7 +141,11 @@ void pysqlite_cursor_dealloc(pysqlite_Cursor* self)
|
||||||
Py_XDECREF(self->row_factory);
|
Py_XDECREF(self->row_factory);
|
||||||
Py_XDECREF(self->next_row);
|
Py_XDECREF(self->next_row);
|
||||||
|
|
||||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
if (self->in_weakreflist != NULL) {
|
||||||
|
PyObject_ClearWeakRefs((PyObject*)self);
|
||||||
|
}
|
||||||
|
|
||||||
|
self->ob_type->tp_free((PyObject*)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* _pysqlite_get_converter(PyObject* key)
|
PyObject* _pysqlite_get_converter(PyObject* key)
|
||||||
|
@ -301,6 +316,11 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
|
||||||
char buf[200];
|
char buf[200];
|
||||||
const char* colname;
|
const char* colname;
|
||||||
|
|
||||||
|
if (self->reset) {
|
||||||
|
PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
numcols = sqlite3_data_count(self->statement->st);
|
numcols = sqlite3_data_count(self->statement->st);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
@ -406,6 +426,26 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks if a cursor object is usable.
|
||||||
|
*
|
||||||
|
* 0 => error; 1 => ok
|
||||||
|
*/
|
||||||
|
static int check_cursor(pysqlite_Cursor* cur)
|
||||||
|
{
|
||||||
|
if (!cur->initialized) {
|
||||||
|
PyErr_SetString(pysqlite_ProgrammingError, "Base Cursor.__init__ not called.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur->closed) {
|
||||||
|
PyErr_SetString(pysqlite_ProgrammingError, "Cannot operate on a closed cursor.");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return pysqlite_check_thread(cur->connection) && pysqlite_check_connection(cur->connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args)
|
PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args)
|
||||||
{
|
{
|
||||||
PyObject* operation;
|
PyObject* operation;
|
||||||
|
@ -425,13 +465,15 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
|
||||||
PyObject* second_argument = NULL;
|
PyObject* second_argument = NULL;
|
||||||
int allow_8bit_chars;
|
int allow_8bit_chars;
|
||||||
|
|
||||||
if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) {
|
if (!check_cursor(self)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->reset = 0;
|
||||||
|
|
||||||
/* Make shooting yourself in the foot with not utf-8 decodable 8-bit-strings harder */
|
/* Make shooting yourself in the foot with not utf-8 decodable 8-bit-strings harder */
|
||||||
allow_8bit_chars = ((self->connection->text_factory != (PyObject*)&PyUnicode_Type) &&
|
allow_8bit_chars = ((self->connection->text_factory != (PyObject*)&PyUnicode_Type) &&
|
||||||
(self->connection->text_factory != (PyObject*)&PyUnicode_Type && pysqlite_OptimizedUnicode));
|
(self->connection->text_factory != pysqlite_OptimizedUnicode));
|
||||||
|
|
||||||
Py_XDECREF(self->next_row);
|
Py_XDECREF(self->next_row);
|
||||||
self->next_row = NULL;
|
self->next_row = NULL;
|
||||||
|
@ -753,16 +795,17 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
|
||||||
sqlite3_stmt* statement;
|
sqlite3_stmt* statement;
|
||||||
int rc;
|
int rc;
|
||||||
PyObject* result;
|
PyObject* result;
|
||||||
int statement_completed = 0;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O", &script_obj)) {
|
if (!PyArg_ParseTuple(args, "O", &script_obj)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) {
|
if (!check_cursor(self)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->reset = 0;
|
||||||
|
|
||||||
if (PyString_Check(script_obj)) {
|
if (PyString_Check(script_obj)) {
|
||||||
script_cstr = PyString_AsString(script_obj);
|
script_cstr = PyString_AsString(script_obj);
|
||||||
} else if (PyUnicode_Check(script_obj)) {
|
} else if (PyUnicode_Check(script_obj)) {
|
||||||
|
@ -785,11 +828,6 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!sqlite3_complete(script_cstr)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
statement_completed = 1;
|
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
rc = sqlite3_prepare(self->connection->db,
|
rc = sqlite3_prepare(self->connection->db,
|
||||||
script_cstr,
|
script_cstr,
|
||||||
|
@ -820,15 +858,15 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
|
||||||
_pysqlite_seterror(self->connection->db, NULL);
|
_pysqlite_seterror(self->connection->db, NULL);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*script_cstr == (char)0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
Py_XDECREF(script_str);
|
Py_XDECREF(script_str);
|
||||||
|
|
||||||
if (!statement_completed) {
|
|
||||||
PyErr_SetString(pysqlite_ProgrammingError, "you did not provide a complete SQL statement");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -849,7 +887,12 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self)
|
||||||
PyObject* next_row;
|
PyObject* next_row;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) {
|
if (!check_cursor(self)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->reset) {
|
||||||
|
PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -992,6 +1035,8 @@ PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args)
|
||||||
Py_CLEAR(self->statement);
|
Py_CLEAR(self->statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->closed = 1;
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
@ -1052,12 +1097,12 @@ PyTypeObject pysqlite_CursorType = {
|
||||||
0, /* tp_getattro */
|
0, /* tp_getattro */
|
||||||
0, /* tp_setattro */
|
0, /* tp_setattro */
|
||||||
0, /* tp_as_buffer */
|
0, /* tp_as_buffer */
|
||||||
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_ITER|Py_TPFLAGS_BASETYPE, /* tp_flags */
|
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_ITER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
|
||||||
cursor_doc, /* tp_doc */
|
cursor_doc, /* tp_doc */
|
||||||
0, /* tp_traverse */
|
0, /* tp_traverse */
|
||||||
0, /* tp_clear */
|
0, /* tp_clear */
|
||||||
0, /* tp_richcompare */
|
0, /* tp_richcompare */
|
||||||
0, /* tp_weaklistoffset */
|
offsetof(pysqlite_Cursor, in_weakreflist), /* tp_weaklistoffset */
|
||||||
(getiterfunc)pysqlite_cursor_getiter, /* tp_iter */
|
(getiterfunc)pysqlite_cursor_getiter, /* tp_iter */
|
||||||
(iternextfunc)pysqlite_cursor_iternext, /* tp_iternext */
|
(iternextfunc)pysqlite_cursor_iternext, /* tp_iternext */
|
||||||
cursor_methods, /* tp_methods */
|
cursor_methods, /* tp_methods */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* cursor.h - definitions for the cursor type
|
/* cursor.h - definitions for the cursor type
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004-2007 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
@ -40,9 +40,14 @@ typedef struct
|
||||||
long rowcount;
|
long rowcount;
|
||||||
PyObject* row_factory;
|
PyObject* row_factory;
|
||||||
pysqlite_Statement* statement;
|
pysqlite_Statement* statement;
|
||||||
|
int closed;
|
||||||
|
int reset;
|
||||||
|
int initialized;
|
||||||
|
|
||||||
/* the next row to be returned, NULL if no next row available */
|
/* the next row to be returned, NULL if no next row available */
|
||||||
PyObject* next_row;
|
PyObject* next_row;
|
||||||
|
|
||||||
|
PyObject* in_weakreflist; /* List of weak references */
|
||||||
} pysqlite_Cursor;
|
} pysqlite_Cursor;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -53,8 +58,6 @@ typedef enum {
|
||||||
|
|
||||||
extern PyTypeObject pysqlite_CursorType;
|
extern PyTypeObject pysqlite_CursorType;
|
||||||
|
|
||||||
int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs);
|
|
||||||
void pysqlite_cursor_dealloc(pysqlite_Cursor* self);
|
|
||||||
PyObject* pysqlite_cursor_execute(pysqlite_Cursor* self, PyObject* args);
|
PyObject* pysqlite_cursor_execute(pysqlite_Cursor* self, PyObject* args);
|
||||||
PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args);
|
PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args);
|
||||||
PyObject* pysqlite_cursor_getiter(pysqlite_Cursor *self);
|
PyObject* pysqlite_cursor_getiter(pysqlite_Cursor *self);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* module.c - the module itself
|
/* module.c - the module itself
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004-2007 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* module.h - definitions for the module
|
/* module.h - definitions for the module
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004-2007 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
#define PYSQLITE_MODULE_H
|
#define PYSQLITE_MODULE_H
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
|
||||||
#define PYSQLITE_VERSION "2.4.1"
|
#define PYSQLITE_VERSION "2.6.0"
|
||||||
|
|
||||||
extern PyObject* pysqlite_Error;
|
extern PyObject* pysqlite_Error;
|
||||||
extern PyObject* pysqlite_Warning;
|
extern PyObject* pysqlite_Warning;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* prepare_protocol.c - the protocol for preparing values for SQLite
|
/* prepare_protocol.c - the protocol for preparing values for SQLite
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
@ -21,6 +21,7 @@
|
||||||
* 3. This notice may not be removed or altered from any source distribution.
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "sqlitecompat.h"
|
||||||
#include "prepare_protocol.h"
|
#include "prepare_protocol.h"
|
||||||
|
|
||||||
int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs)
|
int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* prepare_protocol.h - the protocol for preparing values for SQLite
|
/* prepare_protocol.h - the protocol for preparing values for SQLite
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005-2007 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* row.c - an enhanced tuple for database rows
|
/* row.c - an enhanced tuple for database rows
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
@ -177,17 +177,17 @@ static long pysqlite_row_hash(pysqlite_Row *self)
|
||||||
static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, int opid)
|
static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, int opid)
|
||||||
{
|
{
|
||||||
if (opid != Py_EQ && opid != Py_NE) {
|
if (opid != Py_EQ && opid != Py_NE) {
|
||||||
Py_INCREF(Py_NotImplemented);
|
Py_INCREF(Py_NotImplemented);
|
||||||
return Py_NotImplemented;
|
return Py_NotImplemented;
|
||||||
}
|
}
|
||||||
if (PyType_IsSubtype(Py_TYPE(_other), &pysqlite_RowType)) {
|
if (PyType_IsSubtype(Py_TYPE(_other), &pysqlite_RowType)) {
|
||||||
pysqlite_Row *other = (pysqlite_Row *)_other;
|
pysqlite_Row *other = (pysqlite_Row *)_other;
|
||||||
PyObject *res = PyObject_RichCompare(self->description, other->description, opid);
|
PyObject *res = PyObject_RichCompare(self->description, other->description, opid);
|
||||||
if ((opid == Py_EQ && res == Py_True)
|
if ((opid == Py_EQ && res == Py_True)
|
||||||
|| (opid == Py_NE && res == Py_False)) {
|
|| (opid == Py_NE && res == Py_False)) {
|
||||||
Py_DECREF(res);
|
Py_DECREF(res);
|
||||||
return PyObject_RichCompare(self->data, other->data, opid);
|
return PyObject_RichCompare(self->data, other->data, opid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Py_INCREF(Py_NotImplemented);
|
Py_INCREF(Py_NotImplemented);
|
||||||
return Py_NotImplemented;
|
return Py_NotImplemented;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* row.h - an enhanced tuple for database rows
|
/* row.h - an enhanced tuple for database rows
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005-2007 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* sqlitecompat.h - compatibility macros
|
/* sqlitecompat.h - compatibility macros
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2006-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
@ -21,6 +21,8 @@
|
||||||
* 3. This notice may not be removed or altered from any source distribution.
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "Python.h"
|
||||||
|
|
||||||
#ifndef PYSQLITE_COMPAT_H
|
#ifndef PYSQLITE_COMPAT_H
|
||||||
#define PYSQLITE_COMPAT_H
|
#define PYSQLITE_COMPAT_H
|
||||||
|
|
||||||
|
@ -31,4 +33,31 @@ typedef int Py_ssize_t;
|
||||||
typedef int (*lenfunc)(PyObject*);
|
typedef int (*lenfunc)(PyObject*);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* define PyDict_CheckExact for pre-2.4 versions of Python */
|
||||||
|
#ifndef PyDict_CheckExact
|
||||||
|
#define PyDict_CheckExact(op) ((op)->ob_type == &PyDict_Type)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* define Py_CLEAR for pre-2.4 versions of Python */
|
||||||
|
#ifndef Py_CLEAR
|
||||||
|
#define Py_CLEAR(op) \
|
||||||
|
do { \
|
||||||
|
if (op) { \
|
||||||
|
PyObject *tmp = (PyObject *)(op); \
|
||||||
|
(op) = NULL; \
|
||||||
|
Py_DECREF(tmp); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PyVarObject_HEAD_INIT
|
||||||
|
#define PyVarObject_HEAD_INIT(type, size) \
|
||||||
|
PyObject_HEAD_INIT(type) size,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Py_TYPE
|
||||||
|
#define Py_TYPE(ob) ((ob)->ob_type)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* statement.c - the statement type
|
/* statement.c - the statement type
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005-2007 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* statement.h - definitions for the statement type
|
/* statement.h - definitions for the statement type
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005-2007 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* util.c - various utility functions
|
/* util.c - various utility functions
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005-2007 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* util.h - various utility functions
|
/* util.h - various utility functions
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005-2007 Gerhard Häring <gh@ghaering.de>
|
* Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
|
||||||
*
|
*
|
||||||
* This file is part of pysqlite.
|
* This file is part of pysqlite.
|
||||||
*
|
*
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -955,6 +955,8 @@ class PyBuildExt(build_ext):
|
||||||
else:
|
else:
|
||||||
sqlite_defines.append(('MODULE_NAME', '\\"sqlite3\\"'))
|
sqlite_defines.append(('MODULE_NAME', '\\"sqlite3\\"'))
|
||||||
|
|
||||||
|
# Comment this out if you want the sqlite3 module to be able to load extensions.
|
||||||
|
sqlite_defines.append(("SQLITE_OMIT_LOAD_EXTENSION", "1"))
|
||||||
|
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
# In every directory on the search path search for a dynamic
|
# In every directory on the search path search for a dynamic
|
||||||
|
|
Loading…
Reference in New Issue