pax_global_header00006660000000000000000000000064125603515650014522gustar00rootroot0000000000000052 comment=c3fd30d3aa727319e65ec5eb74701a76a496aac5 pysqlite-2.7.0/000077500000000000000000000000001256035156500134025ustar00rootroot00000000000000pysqlite-2.7.0/.gitignore000066400000000000000000000000761256035156500153750ustar00rootroot00000000000000*~ *.pyc *.swp build sqlite3.c sqlite3.h sqlite3ext.h shell.c pysqlite-2.7.0/.hgignore000066400000000000000000000001001256035156500151740ustar00rootroot00000000000000syntax: glob amalgamation build dist/* pysqlite.egg-info/ *.pyc pysqlite-2.7.0/.travis.yml000066400000000000000000000001451256035156500155130ustar00rootroot00000000000000sudo: false language: python python: - "2.6" - "2.7" install: pip install tox-travis script: tox pysqlite-2.7.0/LICENSE000066400000000000000000000015741256035156500144160ustar00rootroot00000000000000Copyright (c) 2004-2015 Gerhard Häring This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. pysqlite-2.7.0/MANIFEST.in000066400000000000000000000002771256035156500151460ustar00rootroot00000000000000include MANIFEST.in include LICENSE include cross_bdist_wininst.py include doc/*.txt include doc/includes/sqlite3/*.py include doc/sphinx/* include doc/sphinx/.static/.keepme include src/*.h pysqlite-2.7.0/README.md000066400000000000000000000002331256035156500146570ustar00rootroot00000000000000pysqlite ======== Python DB-API module for SQLite 3. Online documentation can be found [here] (https://pysqlite.readthedocs.org/en/latest/sqlite3.html). pysqlite-2.7.0/benchmarks/000077500000000000000000000000001256035156500155175ustar00rootroot00000000000000pysqlite-2.7.0/benchmarks/fetch.py000066400000000000000000000053611256035156500171670ustar00rootroot00000000000000import time def yesno(question): val = raw_input(question + " ") return val.startswith("y") or val.startswith("Y") use_pysqlite2 = yesno("Use pysqlite 2.0?") if use_pysqlite2: use_custom_types = yesno("Use custom types?") use_dictcursor = yesno("Use dict cursor?") use_rowcursor = yesno("Use row cursor?") else: use_tuple = yesno("Use rowclass=tuple?") if use_pysqlite2: from pysqlite2 import dbapi2 as sqlite else: import sqlite def dict_factory(cursor, row): d = {} for idx, col in enumerate(cursor.description): d[col[0]] = row[idx] return d if use_pysqlite2: def dict_factory(cursor, row): d = {} for idx, col in enumerate(cursor.description): d[col[0]] = row[idx] return d class DictCursor(sqlite.Cursor): def __init__(self, *args, **kwargs): sqlite.Cursor.__init__(self, *args, **kwargs) self.row_factory = dict_factory class RowCursor(sqlite.Cursor): def __init__(self, *args, **kwargs): sqlite.Cursor.__init__(self, *args, **kwargs) self.row_factory = sqlite.Row def create_db(): if sqlite.version_info > (2, 0): if use_custom_types: con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES) sqlite.register_converter("text", lambda x: "<%s>" % x) else: con = sqlite.connect(":memory:") if use_dictcursor: cur = con.cursor(factory=DictCursor) elif use_rowcursor: cur = con.cursor(factory=RowCursor) else: cur = con.cursor() else: if use_tuple: con = sqlite.connect(":memory:") con.rowclass = tuple cur = con.cursor() else: con = sqlite.connect(":memory:") cur = con.cursor() cur.execute(""" create table test(v text, f float, i integer) """) return (con, cur) def test(): row = ("sdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffasfd", 3.14, 42) l = [] for i in range(1000): l.append(row) con, cur = create_db() if sqlite.version_info > (2, 0): sql = "insert into test(v, f, i) values (?, ?, ?)" else: sql = "insert into test(v, f, i) values (%s, %s, %s)" for i in range(50): cur.executemany(sql, l) cur.execute("select count(*) as cnt from test") starttime = time.time() for i in range(50): cur.execute("select v, f, i from test") l = cur.fetchall() endtime = time.time() print "elapsed:", endtime - starttime if __name__ == "__main__": test() pysqlite-2.7.0/benchmarks/insert.py000066400000000000000000000027301256035156500173770ustar00rootroot00000000000000import time def yesno(question): val = raw_input(question + " ") return val.startswith("y") or val.startswith("Y") use_pysqlite2 = yesno("Use pysqlite 2.0?") use_autocommit = yesno("Use autocommit?") use_executemany= yesno("Use executemany?") if use_pysqlite2: from pysqlite2 import dbapi2 as sqlite else: import sqlite def create_db(): con = sqlite.connect(":memory:") if use_autocommit: if use_pysqlite2: con.isolation_level = None else: con.autocommit = True cur = con.cursor() cur.execute(""" create table test(v text, f float, i integer) """) cur.close() return con def test(): row = ("sdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffasfd", 3.14, 42) l = [] for i in range(1000): l.append(row) con = create_db() cur = con.cursor() if sqlite.version_info > (2, 0): sql = "insert into test(v, f, i) values (?, ?, ?)" else: sql = "insert into test(v, f, i) values (%s, %s, %s)" starttime = time.time() for i in range(50): if use_executemany: cur.executemany(sql, l) else: for r in l: cur.execute(sql, r) endtime = time.time() print "elapsed", endtime - starttime cur.execute("select count(*) from test") print "rows:", cur.fetchone()[0] if __name__ == "__main__": test() pysqlite-2.7.0/cross_bdist_wininst.py000066400000000000000000000330761256035156500200560ustar00rootroot00000000000000# Gerhard Haering is responsible for the hacked version of this # module. # # This is a modified version of the bdist_wininst distutils command to make it # possible to build installers *with extension modules* on Unix. """distutils.command.bdist_wininst Implements the Distutils 'bdist_wininst' command: create a windows installer exe-program.""" # This module should be kept compatible with Python 2.1. __revision__ = "$Id: bdist_wininst.py 59620 2007-12-31 14:47:07Z christian.heimes $" import sys, os, string from distutils.core import Command from distutils.util import get_platform from distutils.dir_util import create_tree, remove_tree from distutils.errors import * from distutils.sysconfig import get_python_version from distutils import log class bdist_wininst (Command): description = "create an executable installer for MS Windows" user_options = [('bdist-dir=', None, "temporary directory for creating the distribution"), ('keep-temp', 'k', "keep the pseudo-installation tree around after " + "creating the distribution archive"), ('target-version=', None, "require a specific python version" + " on the target system"), ('no-target-compile', 'c', "do not compile .py to .pyc on the target system"), ('no-target-optimize', 'o', "do not compile .py to .pyo (optimized)" "on the target system"), ('dist-dir=', 'd', "directory to put final built distributions in"), ('bitmap=', 'b', "bitmap to use for the installer instead of python-powered logo"), ('title=', 't', "title to display on the installer background instead of default"), ('skip-build', None, "skip rebuilding everything (for testing/debugging)"), ('install-script=', None, "basename of installation script to be run after" "installation or before deinstallation"), ('pre-install-script=', None, "Fully qualified filename of a script to be run before " "any files are installed. This script need not be in the " "distribution"), ] boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize', 'skip-build'] def initialize_options (self): self.bdist_dir = None self.keep_temp = 0 self.no_target_compile = 0 self.no_target_optimize = 0 self.target_version = None self.dist_dir = None self.bitmap = None self.title = None self.skip_build = 0 self.install_script = None self.pre_install_script = None # initialize_options() def finalize_options (self): if self.bdist_dir is None: bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'wininst') if not self.target_version: self.target_version = "" if not self.skip_build and self.distribution.has_ext_modules(): short_version = get_python_version() if self.target_version and self.target_version != short_version: raise DistutilsOptionError, \ "target version can only be %s, or the '--skip_build'" \ " option must be specified" % (short_version,) self.target_version = short_version self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) if self.install_script: for script in self.distribution.scripts: if self.install_script == os.path.basename(script): break else: raise DistutilsOptionError, \ "install_script '%s' not found in scripts" % \ self.install_script # finalize_options() def run (self): # HACK I disabled this check. if 0 and (sys.platform != "win32" and (self.distribution.has_ext_modules() or self.distribution.has_c_libraries())): raise DistutilsPlatformError \ ("distribution contains extensions and/or C libraries; " "must be compiled on a Windows 32 platform") if not self.skip_build: self.run_command('build') install = self.reinitialize_command('install', reinit_subcommands=1) install.root = self.bdist_dir install.skip_build = self.skip_build install.warn_dir = 0 install_lib = self.reinitialize_command('install_lib') # we do not want to include pyc or pyo files install_lib.compile = 0 install_lib.optimize = 0 if self.distribution.has_ext_modules(): # If we are building an installer for a Python version other # than the one we are currently running, then we need to ensure # our build_lib reflects the other Python version rather than ours. # Note that for target_version!=sys.version, we must have skipped the # build step, so there is no issue with enforcing the build of this # version. target_version = self.target_version if not target_version: assert self.skip_build, "Should have already checked this" target_version = sys.version[0:3] plat_specifier = ".%s-%s" % (get_platform(), target_version) build = self.get_finalized_command('build') build.build_lib = os.path.join(build.build_base, 'lib' + plat_specifier) # Use a custom scheme for the zip-file, because we have to decide # at installation time which scheme to use. for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): value = string.upper(key) if key == 'headers': value = value + '/Include/$dist_name' setattr(install, 'install_' + key, value) log.info("installing to %s", self.bdist_dir) install.ensure_finalized() # avoid warning of 'install_lib' about installing # into a directory not in sys.path sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB')) install.run() del sys.path[0] # And make an archive relative to the root of the # pseudo-installation tree. from tempfile import mktemp archive_basename = mktemp() fullname = self.distribution.get_fullname() arcname = self.make_archive(archive_basename, "zip", root_dir=self.bdist_dir) # create an exe containing the zip-file self.create_exe(arcname, fullname, self.bitmap) if self.distribution.has_ext_modules(): pyversion = get_python_version() else: pyversion = 'any' self.distribution.dist_files.append(('bdist_wininst', pyversion, self.get_installer_filename(fullname))) # remove the zip-file again log.debug("removing temporary file '%s'", arcname) os.remove(arcname) if not self.keep_temp: remove_tree(self.bdist_dir, dry_run=self.dry_run) # run() def get_inidata (self): # Return data describing the installation. lines = [] metadata = self.distribution.metadata # Write the [metadata] section. lines.append("[metadata]") # 'info' will be displayed in the installer's dialog box, # describing the items to be installed. info = (metadata.long_description or '') + '\n' # Escape newline characters def escape(s): return string.replace(s, "\n", "\\n") for name in ["author", "author_email", "description", "maintainer", "maintainer_email", "name", "url", "version"]: data = getattr(metadata, name, "") if data: info = info + ("\n %s: %s" % \ (string.capitalize(name), escape(data))) lines.append("%s=%s" % (name, escape(data))) # The [setup] section contains entries controlling # the installer runtime. lines.append("\n[Setup]") if self.install_script: lines.append("install_script=%s" % self.install_script) lines.append("info=%s" % escape(info)) lines.append("target_compile=%d" % (not self.no_target_compile)) lines.append("target_optimize=%d" % (not self.no_target_optimize)) if self.target_version: lines.append("target_version=%s" % self.target_version) title = self.title or self.distribution.get_fullname() lines.append("title=%s" % escape(title)) import time import distutils build_info = "Built %s with distutils-%s" % \ (time.ctime(time.time()), distutils.__version__) lines.append("build_info=%s" % build_info) return string.join(lines, "\n") # get_inidata() def create_exe (self, arcname, fullname, bitmap=None): import struct self.mkpath(self.dist_dir) cfgdata = self.get_inidata() installer_name = self.get_installer_filename(fullname) self.announce("creating %s" % installer_name) if bitmap: bitmapdata = open(bitmap, "rb").read() bitmaplen = len(bitmapdata) else: bitmaplen = 0 file = open(installer_name, "wb") file.write(self.get_exe_bytes()) if bitmap: file.write(bitmapdata) # Convert cfgdata from unicode to ascii, mbcs encoded try: unicode except NameError: pass else: if isinstance(cfgdata, unicode): cfgdata = cfgdata.encode("mbcs") # Append the pre-install script cfgdata = cfgdata + "\0" if self.pre_install_script: script_data = open(self.pre_install_script, "r").read() cfgdata = cfgdata + script_data + "\n\0" else: # empty pre-install script cfgdata = cfgdata + "\0" file.write(cfgdata) # The 'magic number' 0x1234567B is used to make sure that the # binary layout of 'cfgdata' is what the wininst.exe binary # expects. If the layout changes, increment that number, make # the corresponding changes to the wininst.exe sources, and # recompile them. header = struct.pack("", e.args[0] # access ... prohibited try: con.execute("insert into public_table(c1, c2) values (1, 2)") except sqlite3.DatabaseError, e: print "DML command =>", e.args[0] # access ... prohibited pysqlite-2.7.0/doc/includes/sqlite3/collation_reverse.py000066400000000000000000000006511256035156500234340ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 def collate_reverse(string1, string2): return -cmp(string1, string2) con = sqlite3.connect(":memory:") con.create_collation("reverse", collate_reverse) cur = con.cursor() cur.execute("create table test(x)") cur.executemany("insert into test(x) values (?)", [("a",), ("b",)]) cur.execute("select x from test order by x collate reverse") for row in cur: print row con.close() pysqlite-2.7.0/doc/includes/sqlite3/complete_statement.py000066400000000000000000000012661256035156500236140ustar00rootroot00000000000000# A minimal SQLite shell for experiments from pysqlite2 import dbapi2 as sqlite3 con = sqlite3.connect(":memory:") con.isolation_level = None cur = con.cursor() buffer = "" print "Enter your SQL commands to execute in SQLite." print "Enter a blank line to exit." while True: line = raw_input() if line == "": break buffer += line if sqlite3.complete_statement(buffer): try: buffer = buffer.strip() cur.execute(buffer) if buffer.lstrip().upper().startswith("SELECT"): print cur.fetchall() except sqlite3.Error, e: print "An error occurred:", e.args[0] buffer = "" con.close() pysqlite-2.7.0/doc/includes/sqlite3/connect_db_1.py000066400000000000000000000001071256035156500222270ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 con = sqlite3.connect("mydb") pysqlite-2.7.0/doc/includes/sqlite3/connect_db_2.py000066400000000000000000000001131256035156500222250ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 con = sqlite3.connect(":memory:") pysqlite-2.7.0/doc/includes/sqlite3/converter_point.py000066400000000000000000000022561256035156500231400ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 class Point(object): def __init__(self, x, y): self.x, self.y = x, y def __repr__(self): return "(%f;%f)" % (self.x, self.y) def adapt_point(point): return "%f;%f" % (point.x, point.y) def convert_point(s): x, y = map(float, s.split(";")) return Point(x, y) # Register the adapter sqlite3.register_adapter(Point, adapt_point) # Register the converter sqlite3.register_converter("point", convert_point) p = Point(4.0, -3.2) ######################### # 1) Using declared types con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES) cur = con.cursor() cur.execute("create table test(p point)") cur.execute("insert into test(p) values (?)", (p,)) cur.execute("select p from test") print "with declared types:", cur.fetchone()[0] cur.close() con.close() ####################### # 1) Using column names con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES) cur = con.cursor() cur.execute("create table test(p)") cur.execute("insert into test(p) values (?)", (p,)) cur.execute('select p as "p [point]" from test') print "with column names:", cur.fetchone()[0] cur.close() con.close() pysqlite-2.7.0/doc/includes/sqlite3/countcursors.py000066400000000000000000000007401256035156500224650ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 class CountCursorsConnection(sqlite3.Connection): def __init__(self, *args, **kwargs): sqlite3.Connection.__init__(self, *args, **kwargs) self.numcursors = 0 def cursor(self, *args, **kwargs): self.numcursors += 1 return sqlite3.Connection.cursor(self, *args, **kwargs) con = sqlite3.connect(":memory:", factory=CountCursorsConnection) cur1 = con.cursor() cur2 = con.cursor() print con.numcursors pysqlite-2.7.0/doc/includes/sqlite3/createdb.py000066400000000000000000000011501256035156500214610ustar00rootroot00000000000000# Not referenced from the documentation, but builds the database file the other # code snippets expect. from pysqlite2 import dbapi2 as sqlite3 import os DB_FILE = "mydb" if os.path.exists(DB_FILE): os.remove(DB_FILE) con = sqlite3.connect(DB_FILE) cur = con.cursor() cur.execute(""" create table people ( name_last varchar(20), age integer ) """) cur.execute("insert into people (name_last, age) values ('Yeltsin', 72)") cur.execute("insert into people (name_last, age) values ('Putin', 51)") con.commit() cur.close() con.close() pysqlite-2.7.0/doc/includes/sqlite3/ctx_manager.py000066400000000000000000000011701256035156500222020ustar00rootroot00000000000000from __future__ import with_statement from pysqlite2 import dbapi2 as sqlite3 con = sqlite3.connect(":memory:") con.execute("create table person (id integer primary key, firstname varchar unique)") # Successful, con.commit() is called automatically afterwards with con: con.execute("insert into person(firstname) values (?)", ("Joe",)) # con.rollback() is called after the with block finishes with an exception, the # exception is still raised and must be catched try: with con: con.execute("insert into person(firstname) values (?)", ("Joe",)) except sqlite3.IntegrityError: print "couldn't add Joe twice" pysqlite-2.7.0/doc/includes/sqlite3/execsql_fetchonerow.py000066400000000000000000000007641256035156500237710ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 con = sqlite3.connect("mydb") cur = con.cursor() SELECT = "select name_last, age from people order by age, name_last" # 1. Iterate over the rows available from the cursor, unpacking the # resulting sequences to yield their elements (name_last, age): cur.execute(SELECT) for (name_last, age) in cur: print '%s is %d years old.' % (name_last, age) # 2. Equivalently: cur.execute(SELECT) for row in cur: print '%s is %d years old.' % (row[0], row[1]) pysqlite-2.7.0/doc/includes/sqlite3/execsql_printall_1.py000066400000000000000000000005671256035156500235140ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 # Create a connection to the database file "mydb": con = sqlite3.connect("mydb") # Get a Cursor object that operates in the context of Connection con: cur = con.cursor() # Execute the SELECT statement: cur.execute("select * from people order by age") # Retrieve all rows as a sequence and print that sequence: print cur.fetchall() pysqlite-2.7.0/doc/includes/sqlite3/execute_1.py000066400000000000000000000003441256035156500215760ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 con = sqlite3.connect("mydb") cur = con.cursor() who = "Yeltsin" age = 72 cur.execute("select name_last, age from people where name_last=? and age=?", (who, age)) print cur.fetchone() pysqlite-2.7.0/doc/includes/sqlite3/execute_2.py000066400000000000000000000003741256035156500216020ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 con = sqlite3.connect("mydb") cur = con.cursor() who = "Yeltsin" age = 72 cur.execute("select name_last, age from people where name_last=:who and age=:age", {"who": who, "age": age}) print cur.fetchone() pysqlite-2.7.0/doc/includes/sqlite3/execute_3.py000066400000000000000000000003541256035156500216010ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 con = sqlite3.connect("mydb") cur = con.cursor() who = "Yeltsin" age = 72 cur.execute("select name_last, age from people where name_last=:who and age=:age", locals()) print cur.fetchone() pysqlite-2.7.0/doc/includes/sqlite3/executemany_1.py000066400000000000000000000010741256035156500224640ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 class IterChars: def __init__(self): self.count = ord('a') def __iter__(self): return self def next(self): if self.count > ord('z'): raise StopIteration self.count += 1 return (chr(self.count - 1),) # this is a 1-tuple con = sqlite3.connect(":memory:") cur = con.cursor() cur.execute("create table characters(c)") theIter = IterChars() cur.executemany("insert into characters(c) values (?)", theIter) cur.execute("select c from characters") print cur.fetchall() pysqlite-2.7.0/doc/includes/sqlite3/executemany_2.py000066400000000000000000000005571256035156500224720ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 def char_generator(): import string for c in string.letters[:26]: yield (c,) con = sqlite3.connect(":memory:") cur = con.cursor() cur.execute("create table characters(c)") cur.executemany("insert into characters(c) values (?)", char_generator()) cur.execute("select c from characters") print cur.fetchall() pysqlite-2.7.0/doc/includes/sqlite3/executescript.py000066400000000000000000000006741256035156500226110ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 con = sqlite3.connect(":memory:") cur = con.cursor() cur.executescript(""" create table person( firstname, lastname, age ); create table book( title, author, published ); insert into book(title, author, published) values ( 'Dirk Gently''s Holistic Detective Agency', 'Douglas Adams', 1987 ); """) pysqlite-2.7.0/doc/includes/sqlite3/insert_more_people.py000066400000000000000000000005471256035156500236130ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 con = sqlite3.connect("mydb") cur = con.cursor() newPeople = ( ('Lebed' , 53), ('Zhirinovsky' , 57), ) for person in newPeople: cur.execute("insert into people (name_last, age) values (?, ?)", person) # The changes will not be saved unless the transaction is committed explicitly: con.commit() pysqlite-2.7.0/doc/includes/sqlite3/load_extension.py000066400000000000000000000020101256035156500227170ustar00rootroot00000000000000from pysqlite2 import dbapi2 as 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 pysqlite-2.7.0/doc/includes/sqlite3/md5func.py000066400000000000000000000004001256035156500212460ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 import md5 def md5sum(t): return md5.md5(t).hexdigest() con = sqlite3.connect(":memory:") con.create_function("md5", 1, md5sum) cur = con.cursor() cur.execute("select md5(?)", ("foo",)) print cur.fetchone()[0] pysqlite-2.7.0/doc/includes/sqlite3/mysumaggr.py000066400000000000000000000007571256035156500217370ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 class MySum: def __init__(self): self.count = 0 def step(self, value): self.count += value def finalize(self): return self.count con = sqlite3.connect(":memory:") con.create_aggregate("mysum", 1, MySum) cur = con.cursor() cur.execute("create table test(i)") cur.execute("insert into test(i) values (1)") cur.execute("insert into test(i) values (2)") cur.execute("select mysum(i) from test") print cur.fetchone()[0] pysqlite-2.7.0/doc/includes/sqlite3/parse_colnames.py000066400000000000000000000004041256035156500227040ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 import datetime con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES) cur = con.cursor() cur.execute('select ? as "x [timestamp]"', (datetime.datetime.now(),)) dt = cur.fetchone()[0] print dt, type(dt) pysqlite-2.7.0/doc/includes/sqlite3/progress.py000066400000000000000000000012421256035156500215560ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 def progress(): print "Query still executing. Please wait ..." con = sqlite3.connect(":memory:") con.execute("create table test(x)") # Let's create some data con.executemany("insert into test(x) values (?)", [(x,) for x in xrange(300)]) # A progress handler, executed every 10 million opcodes con.set_progress_handler(progress, 10000000) # A particularly long-running query killer_stament = """ select count(*) from ( select t1.x from test t1, test t2, test t3 ) """ con.execute(killer_stament) print "-" * 50 # Clear the progress handler con.set_progress_handler(None, 0) con.execute(killer_stament) pysqlite-2.7.0/doc/includes/sqlite3/pysqlite_datetime.py000066400000000000000000000012651256035156500234450ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 import datetime con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES) cur = con.cursor() cur.execute("create table test(d date, ts timestamp)") today = datetime.date.today() now = datetime.datetime.now() cur.execute("insert into test(d, ts) values (?, ?)", (today, now)) cur.execute("select d, ts from test") row = cur.fetchone() print today, "=>", row[0], type(row[0]) print now, "=>", row[1], type(row[1]) cur.execute('select current_date as "d [date]", current_timestamp as "ts [timestamp]"') row = cur.fetchone() print "current_date", row[0], type(row[0]) print "current_timestamp", row[1], type(row[1]) pysqlite-2.7.0/doc/includes/sqlite3/row_factory.py000066400000000000000000000004741256035156500222560ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 def dict_factory(cursor, row): d = {} for idx, col in enumerate(cursor.description): d[col[0]] = row[idx] return d con = sqlite3.connect(":memory:") con.row_factory = dict_factory cur = con.cursor() cur.execute("select 1 as a") print cur.fetchone()["a"] pysqlite-2.7.0/doc/includes/sqlite3/rowclass.py000066400000000000000000000005201256035156500215450ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 con = sqlite3.connect("mydb") con.row_factory = sqlite3.Row cur = con.cursor() cur.execute("select name_last, age from people") for row in cur: assert row[0] == row["name_last"] assert row["name_last"] == row["nAmE_lAsT"] assert row[1] == row["age"] assert row[1] == row["AgE"] pysqlite-2.7.0/doc/includes/sqlite3/shared_cache.py000066400000000000000000000002761256035156500223110ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 # The shared cache is only available in SQLite versions 3.3.3 or later # See the SQLite documentaton for details. sqlite3.enable_shared_cache(True) pysqlite-2.7.0/doc/includes/sqlite3/shortcut_methods.py000066400000000000000000000011161256035156500233100ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 persons = [ ("Hugo", "Boss"), ("Calvin", "Klein") ] con = sqlite3.connect(":memory:") # Create the table con.execute("create table person(firstname, lastname)") # Fill the table con.executemany("insert into person(firstname, lastname) values (?, ?)", persons) # Print the table contents for row in con.execute("select firstname, lastname from person"): print row # Using a dummy WHERE clause to not let SQLite take the shortcut table deletes. print "I just deleted", con.execute("delete from person where 1=1").rowcount, "rows" pysqlite-2.7.0/doc/includes/sqlite3/simple_tableprinter.py000066400000000000000000000013221256035156500237550ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 FIELD_MAX_WIDTH = 20 TABLE_NAME = 'people' SELECT = 'select * from %s order by age, name_last' % TABLE_NAME con = sqlite3.connect("mydb") cur = con.cursor() cur.execute(SELECT) # Print a header. for fieldDesc in cur.description: print fieldDesc[0].ljust(FIELD_MAX_WIDTH) , print # Finish the header with a newline. print '-' * 78 # For each row, print the value of each field left-justified within # the maximum possible width of that field. fieldIndices = range(len(cur.description)) for row in cur: for fieldIndex in fieldIndices: fieldValue = str(row[fieldIndex]) print fieldValue.ljust(FIELD_MAX_WIDTH) , print # Finish the row with a newline. pysqlite-2.7.0/doc/includes/sqlite3/text_factory.py000066400000000000000000000025321256035156500224300ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 con = sqlite3.connect(":memory:") cur = con.cursor() # Create the table con.execute("create table person(lastname, firstname)") AUSTRIA = u"\xd6sterreich" # by default, rows are returned as Unicode cur.execute("select ?", (AUSTRIA,)) row = cur.fetchone() assert row[0] == AUSTRIA # but we can make pysqlite always return bytestrings ... con.text_factory = str cur.execute("select ?", (AUSTRIA,)) row = cur.fetchone() assert type(row[0]) == str # the bytestrings will be encoded in UTF-8, unless you stored garbage in the # database ... assert row[0] == AUSTRIA.encode("utf-8") # we can also implement a custom text_factory ... # here we implement one that will ignore Unicode characters that cannot be # decoded from UTF-8 con.text_factory = lambda x: unicode(x, "utf-8", "ignore") cur.execute("select ?", ("this is latin1 and would normally create errors" + u"\xe4\xf6\xfc".encode("latin1"),)) row = cur.fetchone() assert type(row[0]) == unicode # pysqlite offers a builtin optimized text_factory that will return bytestring # objects, if the data is in ASCII only, and otherwise return unicode objects con.text_factory = sqlite3.OptimizedUnicode cur.execute("select ?", (AUSTRIA,)) row = cur.fetchone() assert type(row[0]) == unicode cur.execute("select ?", ("Germany",)) row = cur.fetchone() assert type(row[0]) == str pysqlite-2.7.0/doc/sphinx/000077500000000000000000000000001256035156500154605ustar00rootroot00000000000000pysqlite-2.7.0/doc/sphinx/.static/000077500000000000000000000000001256035156500170255ustar00rootroot00000000000000pysqlite-2.7.0/doc/sphinx/.static/.keepme000066400000000000000000000000001256035156500202620ustar00rootroot00000000000000pysqlite-2.7.0/doc/sphinx/.templates/000077500000000000000000000000001256035156500175345ustar00rootroot00000000000000pysqlite-2.7.0/doc/sphinx/.templates/.keepme000066400000000000000000000000001256035156500207710ustar00rootroot00000000000000pysqlite-2.7.0/doc/sphinx/Makefile000066400000000000000000000040731256035156500171240ustar00rootroot00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = ALLSPHINXOPTS = -d .build/doctrees -D latex_paper_size=$(PAPER) \ $(SPHINXOPTS) . .PHONY: help clean html web htmlhelp latex changes linkcheck help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " web to make files usable by Sphinx.web" @echo " htmlhelp to make HTML files and a HTML help project" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " changes to make an overview over all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" clean: -rm -rf .build/* html: mkdir -p .build/html .build/doctrees $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) .build/html @echo @echo "Build finished. The HTML pages are in .build/html." web: mkdir -p .build/web .build/doctrees $(SPHINXBUILD) -b web $(ALLSPHINXOPTS) .build/web @echo @echo "Build finished; now you can run" @echo " python -m sphinx.web .build/web" @echo "to start the server." htmlhelp: mkdir -p .build/htmlhelp .build/doctrees $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) .build/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in .build/htmlhelp." latex: mkdir -p .build/latex .build/doctrees $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) .build/latex @echo @echo "Build finished; the LaTeX files are in .build/latex." @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ "run these through (pdf)latex." changes: mkdir -p .build/changes .build/doctrees $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) .build/changes @echo @echo "The overview file is in .build/changes." linkcheck: mkdir -p .build/linkcheck .build/doctrees $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) .build/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in .build/linkcheck/output.txt." pysqlite-2.7.0/doc/sphinx/conf.py000066400000000000000000000076761256035156500167770ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # pysqlite documentation build configuration file, created by # sphinx-quickstart.py on Sat Mar 22 02:47:54 2008. # # This file is execfile()d with the current directory set to its containing dir. # # The contents of this file are pickled, so don't put values in the namespace # that aren't pickleable (module imports are okay, they're removed automatically). # # All configuration values have a default value; values that are commented out # serve to show the default value. import sys # If your extensions are in another directory, add it here. #sys.path.append('some/directory') # General configuration # --------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.addons.*') or your custom ones. #extensions = [] # Add any paths that contain templates here, relative to this directory. templates_path = ['.templates'] # The suffix of source filenames. source_suffix = '.rst' # The master toctree document. master_doc = 'index' # General substitutions. project = 'pysqlite' copyright = u'2008-2015, Gerhard Häring' # The default replacements for |version| and |release|, also used in various # other places throughout the built documents. # # The short X.Y version. version = '2.7' # The full version, including alpha/beta/rc tags. release = '2.7.0' # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. today_fmt = '%B %d, %Y' # List of documents that shouldn't be included in the build. #unused_docs = [] # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # Options for HTML output # ----------------------- # The style sheet to use for HTML and HTML Help pages. A file of that name # must exist either in Sphinx' static/ path, or in one of the custom paths # given in html_static_path. html_style = 'default.css' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['.static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Content template for the index page. #html_index = '' # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_use_modindex = True # If true, the reST sources are included in the HTML build as _sources/. #html_copy_source = True # Output file base name for HTML help builder. htmlhelp_basename = 'pysqlitedoc' # Options for LaTeX output # ------------------------ # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). #latex_documents = [] # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_use_modindex = True pysqlite-2.7.0/doc/sphinx/index.rst000066400000000000000000000006531256035156500173250ustar00rootroot00000000000000.. pysqlite documentation master file, created by sphinx-quickstart.py on Sat Mar 22 02:47:54 2008. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Welcome to pysqlite's documentation! ==================================== Contents: .. toctree:: :maxdepth: 2 Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` pysqlite-2.7.0/doc/sphinx/sqlite3.rst000066400000000000000000001023171256035156500176020ustar00rootroot00000000000000:mod:`sqlite3` --- DB-API 2.0 interface for SQLite databases ============================================================ .. module:: sqlite3 :synopsis: A DB-API 2.0 implementation using SQLite 3.x. .. sectionauthor:: Gerhard Häring SQLite is a C library that provides a lightweight disk-based database that doesn't require a separate server process and allows accessing the database using a nonstandard variant of the SQL query language. Some applications can use SQLite for internal data storage. It's also possible to prototype an application using SQLite and then port the code to a larger database such as PostgreSQL or Oracle. pysqlite was written by Gerhard Häring and provides a SQL interface compliant with the DB-API 2.0 specification described by :pep:`249`. To use the module, you must first create a :class:`Connection` object that represents the database. Here the data will be stored in the :file:`/tmp/example` file:: conn = sqlite3.connect('/tmp/example') You can also supply the special name ``:memory:`` to create a database in RAM. Once you have a :class:`Connection`, you can create a :class:`Cursor` object and call its :meth:`~Cursor.execute` method to perform SQL commands:: c = conn.cursor() # Create table c.execute('''create table stocks (date text, trans text, symbol text, qty real, price real)''') # Insert a row of data c.execute("""insert into stocks values ('2006-01-05','BUY','RHAT',100,35.14)""") # Save (commit) the changes conn.commit() # We can also close the cursor if we are done with it c.close() Usually your SQL operations will need to use values from Python variables. You shouldn't assemble your query using Python's string operations because doing so is insecure; it makes your program vulnerable to an SQL injection attack. Instead, use the DB-API's parameter substitution. Put ``?`` as a placeholder wherever you want to use a value, and then provide a tuple of values as the second argument to the cursor's :meth:`~Cursor.execute` method. (Other database modules may use a different placeholder, such as ``%s`` or ``:1``.) For example:: # Never do this -- insecure! symbol = 'IBM' c.execute("... where symbol = '%s'" % symbol) # Do this instead t = (symbol,) c.execute('select * from stocks where symbol=?', t) # Larger example for t in [('2006-03-28', 'BUY', 'IBM', 1000, 45.00), ('2006-04-05', 'BUY', 'MSOFT', 1000, 72.00), ('2006-04-06', 'SELL', 'IBM', 500, 53.00), ]: c.execute('insert into stocks values (?,?,?,?,?)', t) To retrieve data after executing a SELECT statement, you can either treat the cursor as an :term:`iterator`, call the cursor's :meth:`~Cursor.fetchone` method to retrieve a single matching row, or call :meth:`~Cursor.fetchall` to get a list of the matching rows. This example uses the iterator form:: >>> c = conn.cursor() >>> c.execute('select * from stocks order by price') >>> for row in c: ... print row ... (u'2006-01-05', u'BUY', u'RHAT', 100, 35.14) (u'2006-03-28', u'BUY', u'IBM', 1000, 45.0) (u'2006-04-06', u'SELL', u'IBM', 500, 53.0) (u'2006-04-05', u'BUY', u'MSOFT', 1000, 72.0) >>> .. seealso:: http://github.com/ghaering/pysqlite The pysqlite web page -- sqlite3 is developed externally under the name "pysqlite". http://www.sqlite.org The SQLite web page; the documentation describes the syntax and the available data types for the supported SQL dialect. :pep:`249` - Database API Specification 2.0 PEP written by Marc-André Lemburg. .. _sqlite3-module-contents: Module functions and constants ------------------------------ .. data:: PARSE_DECLTYPES This constant is meant to be used with the *detect_types* parameter of the :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", 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 This constant is meant to be used with the *detect_types* parameter of the :func:`connect` function. Setting this makes the SQLite interface parse the column name for each column it returns. It will look for a string formed [mytype] in there, and then decide that 'mytype' is the type of the column. It will try to find an entry of 'mytype' in the converters dictionary and then use the converter function found there to return the value. The column name found in :attr:`Cursor.description` is only the first word of the column name, i. e. if you use something like ``'as "x [datetime]"'`` in your SQL, then we will parse out everything until the first blank for the column name: the column name would simply be "x". .. function:: connect(database[, timeout, isolation_level, detect_types, factory]) Opens a connection to the SQLite database file *database*. You can use ``":memory:"`` to open a database connection to a database that resides in RAM instead of on disk. When a database is accessed by multiple connections, and one of the processes modifies the database, the SQLite database is locked until that transaction is committed. The *timeout* parameter specifies how long the connection should wait for the lock to go away until raising an exception. The default for the timeout parameter is 5.0 (five seconds). For the *isolation_level* parameter, please see the :attr:`Connection.isolation_level` property of :class:`Connection` objects. SQLite natively supports only the types TEXT, INTEGER, REAL, BLOB and NULL. If you want to use other types you must add support for them yourself. The *detect_types* parameter and the using custom **converters** registered with the module-level :func:`register_converter` function allow you to easily do that. *detect_types* defaults to 0 (i. e. off, no type detection), you can set it to any combination of :const:`PARSE_DECLTYPES` and :const:`PARSE_COLNAMES` to turn type detection on. By default, the :mod:`sqlite3` module uses its :class:`Connection` class for the connect call. You can, however, subclass the :class:`Connection` class and make :func:`connect` use your class instead by providing your class for the *factory* parameter. Consult the section :ref:`sqlite3-types` of this manual for details. The :mod:`sqlite3` module internally uses a statement cache to avoid SQL parsing overhead. If you want to explicitly set the number of statements that are cached for the connection, you can set the *cached_statements* parameter. The currently implemented default is to cache 100 statements. .. function:: register_converter(typename, callable) Registers a callable to convert a bytestring from the database into a custom Python type. The callable will be invoked for all database values that are of the type *typename*. Confer the parameter *detect_types* of the :func:`connect` function for how the type detection works. Note that the case of *typename* and the name of the type in your query must match! .. function:: register_adapter(type, callable) Registers a callable to convert the custom Python type *type* into one of SQLite's supported types. The callable *callable* accepts as single parameter the Python value, and must return a value of the following types: int, long, float, str (UTF-8 encoded), unicode or buffer. .. function:: complete_statement(sql) Returns :const:`True` if the string *sql* contains one or more complete SQL statements terminated by semicolons. It does not verify that the SQL is syntactically correct, only that there are no unclosed string literals and the statement is terminated by a semicolon. This can be used to build a shell for SQLite, as in the following example: .. literalinclude:: ../includes/sqlite3/complete_statement.py .. function:: enable_callback_tracebacks(flag) By default you will not get any tracebacks in user-defined functions, aggregates, converters, authorizer callbacks etc. If you want to debug them, you can call this function with *flag* as True. Afterwards, you will get tracebacks from callbacks on ``sys.stderr``. Use :const:`False` to disable the feature again. .. _sqlite3-connection-objects: Connection Objects ------------------ .. class:: Connection A SQLite database connection has the following attributes and methods: .. attribute:: Connection.isolation_level Get or set the current isolation level. :const:`None` for autocommit mode or one of "DEFERRED", "IMMEDIATE" or "EXCLUSIVE". See section :ref:`sqlite3-controlling-transactions` for a more detailed explanation. .. method:: Connection.cursor([cursorClass]) The cursor method accepts a single optional parameter *cursorClass*. If supplied, this must be a custom cursor class that extends :class:`sqlite3.Cursor`. .. method:: Connection.commit() This method commits the current transaction. If you don't call this method, anything you did since the last call to ``commit()`` is not visible from from other database connections. If you wonder why you don't see the data you've written to the database, please check you didn't forget to call this method. .. method:: Connection.rollback() This method rolls back any changes to the database since the last call to :meth:`commit`. .. method:: Connection.close() This closes the database connection. Note that this does not automatically call :meth:`commit`. If you just close your database connection without calling :meth:`commit` first, your changes will be lost! .. method:: Connection.execute(sql, [parameters]) This is a nonstandard shortcut that creates an intermediate cursor object by calling the cursor method, then calls the cursor's :meth:`execute` method with the parameters given. .. method:: Connection.executemany(sql, [parameters]) This is a nonstandard shortcut that creates an intermediate cursor object by calling the cursor method, then calls the cursor's :meth:`executemany` method with the parameters given. .. method:: Connection.executescript(sql_script) This is a nonstandard shortcut that creates an intermediate cursor object by calling the cursor method, then calls the cursor's :meth:`executescript` method with the parameters given. .. method:: Connection.create_function(name, num_params, func) Creates a user-defined function that you can later use from within SQL statements under the function name *name*. *num_params* is the number of parameters the function accepts, and *func* is a Python callable that is called as the SQL function. The function can return any of the types supported by SQLite: unicode, str, int, long, float, buffer and None. Example: .. literalinclude:: ../includes/sqlite3/md5func.py .. method:: Connection.create_aggregate(name, num_params, aggregate_class) Creates a user-defined aggregate function. The aggregate class must implement a ``step`` method, which accepts the number of parameters *num_params*, and a ``finalize`` method which will return the final result of the aggregate. The ``finalize`` method can return any of the types supported by SQLite: unicode, str, int, long, float, buffer and None. Example: .. literalinclude:: ../includes/sqlite3/mysumaggr.py .. method:: Connection.create_collation(name, callable) Creates a collation with the specified *name* and *callable*. The callable will be passed two string arguments. It should return -1 if the first is ordered lower than the second, 0 if they are ordered equal and 1 if the first is ordered higher than the second. Note that this controls sorting (ORDER BY in SQL) so your comparisons don't affect other SQL operations. Note that the callable will get its parameters as Python bytestrings, which will normally be encoded in UTF-8. The following example shows a custom collation that sorts "the wrong way": .. literalinclude:: ../includes/sqlite3/collation_reverse.py To remove a collation, call ``create_collation`` with None as callable:: con.create_collation("reverse", None) .. method:: Connection.interrupt() You can call this method from a different thread to abort any queries that might be executing on the connection. The query will then abort and the caller will get an exception. .. method:: Connection.set_authorizer(authorizer_callback) This routine registers a callback. The callback is invoked for each attempt to access a column of a table in the database. The callback should return :const:`SQLITE_OK` if access is allowed, :const:`SQLITE_DENY` if the entire SQL statement should be aborted with an error and :const:`SQLITE_IGNORE` if the column should be treated as a NULL value. These constants are available in the :mod:`sqlite3` module. The first argument to the callback signifies what kind of operation is to be authorized. The second and third argument will be arguments or :const:`None` depending on the first argument. The 4th argument is the name of the database ("main", "temp", etc.) if applicable. The 5th argument is the name of the inner-most trigger or view that is responsible for the access attempt or :const:`None` if this access attempt is directly from input SQL code. Please consult the SQLite documentation about the possible values for the first argument and the meaning of the second and third argument depending on the first one. All necessary constants are available in the :mod:`sqlite3` module. .. method:: Connection.get_limit(limit_id) This routine returns the current value of the limit specified by the constant limit_id. Please consult the SQLite documentation about the possible values for the limit_id parameter. .. method:: Connection.set_limit(limit_id, new_value) This routine sets a new value for the limit specified by the constant limit_id. Please consult the SQLite documentation about the possible values for the limit_id parameter. .. method:: Connection.set_progress_handler(handler, n) This routine registers a callback. The callback is invoked for every *n* instructions of the SQLite virtual machine. This is useful if you want to get called from SQLite during long-running operations, for example to update a GUI. If you want to clear any previously installed progress handler, call the method with :const:`None` for *handler*. .. method:: Connection.enable_load_extension(enabled) 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) 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 You can change this attribute to a callable that accepts the cursor and the original row as a tuple and will return the real result row. This way, you can implement more advanced ways of returning results, such as returning an object that can also access columns by name. Example: .. literalinclude:: ../includes/sqlite3/row_factory.py If returning a tuple doesn't suffice and you want name-based access to columns, you should consider setting :attr:`row_factory` to the highly-optimized :class:`sqlite3.Row` type. :class:`Row` provides both index-based and case-insensitive name-based access to columns with almost no memory overhead. It will probably be better than your own custom dictionary-based approach or even a db_row based solution. .. XXX what's a db_row-based solution? .. attribute:: Connection.text_factory Using this attribute you can control what objects are returned for the ``TEXT`` data type. By default, this attribute is set to :class:`unicode` and the :mod:`sqlite3` module will return Unicode objects for ``TEXT``. If you want to return bytestrings instead, you can set it to :class:`str`. For efficiency reasons, there's also a way to return Unicode objects only for non-ASCII data, and bytestrings otherwise. To activate it, set this attribute to :const:`sqlite3.OptimizedUnicode`. You can also set it to any other callable that accepts a single bytestring parameter and returns the resulting object. See the following example code for illustration: .. literalinclude:: ../includes/sqlite3/text_factory.py .. attribute:: Connection.total_changes Returns the total number of database rows that have been modified, inserted, or deleted since the database connection was opened. .. attribute:: Connection.iterdump Returns an iterator to dump the database in an SQL text format. Useful when saving an in-memory database for later restoration. This function provides the same capabilities as the :kbd:`.dump` command in the :program:`sqlite3` shell. Example:: # Convert file existing_db.db to SQL dump file dump.sql import sqlite3, os con = sqlite3.connect('existing_db.db') full_dump = os.linesep.join([line for line in con.iterdump()]) f = open('dump.sql', 'w') f.writelines(full_dump) f.close() .. _sqlite3-cursor-objects: Cursor Objects -------------- A :class:`Cursor` instance has the following attributes and methods: A SQLite database cursor has the following attributes and methods: .. method:: Cursor.close() Close the cursor now (rather than whenever __del__ is called). The cursor will be unusable from this point forward; an Error (or subclass) exception will be raised if any operation is attempted with the cursor. .. method:: Cursor.execute(sql, [parameters]) Executes an SQL statement. The SQL statement may be parametrized (i. e. placeholders instead of SQL literals). The :mod:`sqlite3` module supports two kinds of placeholders: question marks (qmark style) and named placeholders (named style). This example shows how to use parameters with qmark style: .. literalinclude:: ../includes/sqlite3/execute_1.py This example shows how to use the named style: .. literalinclude:: ../includes/sqlite3/execute_2.py :meth:`execute` will only execute a single SQL statement. If you try to execute more than one statement with it, it will raise a Warning. Use :meth:`executescript` if you want to execute multiple SQL statements with one call. .. method:: Cursor.executemany(sql, seq_of_parameters) Executes an SQL command against all parameter sequences or mappings found in the sequence *sql*. The :mod:`sqlite3` module also allows using an :term:`iterator` yielding parameters instead of a sequence. .. literalinclude:: ../includes/sqlite3/executemany_1.py Here's a shorter example using a :term:`generator`: .. literalinclude:: ../includes/sqlite3/executemany_2.py .. method:: Cursor.executescript(sql_script) This is a nonstandard convenience method for executing multiple SQL statements at once. It issues a ``COMMIT`` statement first, then executes the SQL script it gets as a parameter. *sql_script* can be a bytestring or a Unicode string. Example: .. literalinclude:: ../includes/sqlite3/executescript.py .. method:: Cursor.fetchone() Fetches the next row of a query result set, returning a single sequence, or :const:`None` when no more data is available. .. method:: Cursor.fetchmany([size=cursor.arraysize]) Fetches the next set of rows of a query result, returning a list. An empty list is returned when no more rows are available. The number of rows to fetch per call is specified by the *size* parameter. If it is not given, the cursor's arraysize determines the number of rows to be fetched. The method should try to fetch as many rows as indicated by the size parameter. If this is not possible due to the specified number of rows not being available, fewer rows may be returned. Note there are performance considerations involved with the *size* parameter. For optimal performance, it is usually best to use the arraysize attribute. If the *size* parameter is used, then it is best for it to retain the same value from one :meth:`fetchmany` call to the next. .. method:: Cursor.fetchall() Fetches all (remaining) rows of a query result, returning a list. Note that the cursor's arraysize attribute can affect the performance of this operation. An empty list is returned when no rows are available. .. attribute:: Cursor.rowcount Although the :class:`Cursor` class of the :mod:`sqlite3` module implements this attribute, the database engine's own support for the determination of "rows affected"/"rows selected" is quirky. For ``DELETE`` statements, SQLite reports :attr:`rowcount` as 0 if you make a ``DELETE FROM table`` without any condition. For :meth:`executemany` statements, the number of modifications are summed up into :attr:`rowcount`. As required by the Python DB API Spec, the :attr:`rowcount` attribute "is -1 in case no ``executeXX()`` has been performed on the cursor or the rowcount of the last operation is not determinable by the interface". This includes ``SELECT`` statements because we cannot determine the number of rows a query produced until all rows were fetched. .. attribute:: Cursor.lastrowid This read-only attribute provides the rowid of the last modified row. It is only set if you issued a ``INSERT`` statement using the :meth:`execute` method. For operations other than ``INSERT`` or when :meth:`executemany` is called, :attr:`lastrowid` is set to :const:`None`. .. attribute:: Cursor.description This read-only attribute provides the column names of the last query. To remain compatible with the Python DB API, it returns a 7-tuple for each column where the last six items of each tuple are :const:`None`. It is set for ``SELECT`` statements without any matching rows as well. .. _sqlite3-row-objects: Row Objects ----------- .. class:: Row A :class:`Row` instance serves as a highly optimized :attr:`~Connection.row_factory` for :class:`Connection` objects. It tries to mimic a tuple in most of its features. It supports mapping access by column name and index, iteration, representation, equality testing and :func:`len`. If two :class:`Row` objects have exactly the same columns and their members are equal, they compare equal. .. versionchanged:: 2.6 Added iteration and equality (hashability). .. method:: keys This method returns a tuple of column names. Immediately after a query, it is the first member of each tuple in :attr:`Cursor.description`. .. versionadded:: 2.6 Let's assume we initialize a table as in the example given above:: conn = sqlite3.connect(":memory:") c = conn.cursor() c.execute('''create table stocks (date text, trans text, symbol text, qty real, price real)''') c.execute("""insert into stocks values ('2006-01-05','BUY','RHAT',100,35.14)""") conn.commit() c.close() Now we plug :class:`Row` in:: >>> conn.row_factory = sqlite3.Row >>> c = conn.cursor() >>> c.execute('select * from stocks') >>> r = c.fetchone() >>> type(r) >>> r (u'2006-01-05', u'BUY', u'RHAT', 100.0, 35.14) >>> len(r) 5 >>> r[2] u'RHAT' >>> r.keys() ['date', 'trans', 'symbol', 'qty', 'price'] >>> r['qty'] 100.0 >>> for member in r: print member ... 2006-01-05 BUY RHAT 100.0 35.14 .. _sqlite3-types: SQLite and Python types ----------------------- Introduction ^^^^^^^^^^^^ SQLite natively supports the following types: ``NULL``, ``INTEGER``, ``REAL``, ``TEXT``, ``BLOB``. The following Python types can thus be sent to SQLite without any problem: +-----------------------------+-------------+ | Python type | SQLite type | +=============================+=============+ | :const:`None` | ``NULL`` | +-----------------------------+-------------+ | :class:`int` | ``INTEGER`` | +-----------------------------+-------------+ | :class:`long` | ``INTEGER`` | +-----------------------------+-------------+ | :class:`float` | ``REAL`` | +-----------------------------+-------------+ | :class:`str` (UTF8-encoded) | ``TEXT`` | +-----------------------------+-------------+ | :class:`unicode` | ``TEXT`` | +-----------------------------+-------------+ | :class:`buffer` | ``BLOB`` | +-----------------------------+-------------+ This is how SQLite types are converted to Python types by default: +-------------+----------------------------------------------+ | SQLite type | Python type | +=============+==============================================+ | ``NULL`` | :const:`None` | +-------------+----------------------------------------------+ | ``INTEGER`` | :class:`int` or :class:`long`, | | | depending on size | +-------------+----------------------------------------------+ | ``REAL`` | :class:`float` | +-------------+----------------------------------------------+ | ``TEXT`` | depends on :attr:`~Connection.text_factory`, | | | :class:`unicode` by default | +-------------+----------------------------------------------+ | ``BLOB`` | :class:`buffer` | +-------------+----------------------------------------------+ The type system of the :mod:`sqlite3` module is extensible in two ways: you can store additional Python types in a SQLite database via object adaptation, and you can let the :mod:`sqlite3` module convert SQLite types to different Python types via converters. Using adapters to store additional Python types in SQLite databases ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ As described before, SQLite supports only a limited set of types natively. To use other Python types with SQLite, you must **adapt** them to one of the sqlite3 module's supported types for SQLite: one of NoneType, int, long, float, str, unicode, buffer. The :mod:`sqlite3` module uses Python object adaptation, as described in :pep:`246` for this. The protocol to use is :class:`PrepareProtocol`. There are two ways to enable the :mod:`sqlite3` module to adapt a custom Python type to one of the supported ones. Letting your object adapt itself """""""""""""""""""""""""""""""" This is a good approach if you write the class yourself. Let's suppose you have a class like this:: class Point(object): def __init__(self, x, y): self.x, self.y = x, y Now you want to store the point in a single SQLite column. First you'll have to choose one of the supported types first to be used for representing the point. Let's just use str and separate the coordinates using a semicolon. Then you need to give your class a method ``__conform__(self, protocol)`` which must return the converted value. The parameter *protocol* will be :class:`PrepareProtocol`. .. literalinclude:: ../includes/sqlite3/adapter_point_1.py Registering an adapter callable """"""""""""""""""""""""""""""" The other possibility is to create a function that converts the type to the string representation and register the function with :meth:`register_adapter`. .. note:: The type/class to adapt must be a :term:`new-style class`, i. e. it must have :class:`object` as one of its bases. .. literalinclude:: ../includes/sqlite3/adapter_point_2.py The :mod:`sqlite3` module has two default adapters for Python's built-in :class:`datetime.date` and :class:`datetime.datetime` types. Now let's suppose we want to store :class:`datetime.datetime` objects not in ISO representation, but as a Unix timestamp. .. literalinclude:: ../includes/sqlite3/adapter_datetime.py Converting SQLite values to custom Python types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Writing an adapter lets you send custom Python types to SQLite. But to make it really useful we need to make the Python to SQLite to Python roundtrip work. Enter converters. Let's go back to the :class:`Point` class. We stored the x and y coordinates separated via semicolons as strings in SQLite. First, we'll define a converter function that accepts the string as a parameter and constructs a :class:`Point` object from it. .. note:: Converter functions **always** get called with a string, no matter under which data type you sent the value to SQLite. :: def convert_point(s): x, y = map(float, s.split(";")) return Point(x, y) Now you need to make the :mod:`sqlite3` module know that what you select from the database is actually a point. There are two ways of doing this: * Implicitly via the declared type * Explicitly via the column name Both ways are described in section :ref:`sqlite3-module-contents`, in the entries for the constants :const:`PARSE_DECLTYPES` and :const:`PARSE_COLNAMES`. The following example illustrates both approaches. .. literalinclude:: ../includes/sqlite3/converter_point.py Default adapters and converters ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ There are default adapters for the date and datetime types in the datetime module. They will be sent as ISO dates/ISO timestamps to SQLite. The default converters are registered under the name "date" for :class:`datetime.date` and under the name "timestamp" for :class:`datetime.datetime`. This way, you can use date/timestamps from Python without any additional fiddling in most cases. The format of the adapters is also compatible with the experimental SQLite date/time functions. The following example demonstrates this. .. literalinclude:: ../includes/sqlite3/pysqlite_datetime.py .. _sqlite3-controlling-transactions: Controlling Transactions ------------------------ By default, the :mod:`sqlite3` module opens transactions implicitly before a Data Modification Language (DML) statement (i.e. ``INSERT``/``UPDATE``/``DELETE``/``REPLACE``), and commits transactions implicitly before a non-DML, non-query statement (i. e. anything other than ``SELECT`` or the aforementioned). So if you are within a transaction and issue a command like ``CREATE TABLE ...``, ``VACUUM``, ``PRAGMA``, the :mod:`sqlite3` module will commit implicitly before executing that command. There are two reasons for doing that. The first is that some of these commands don't work within transactions. The other reason is that pysqlite needs to keep track of the transaction state (if a transaction is active or not). You can control which kind of ``BEGIN`` statements sqlite3 implicitly executes (or none at all) via the *isolation_level* parameter to the :func:`connect` call, or via the :attr:`isolation_level` property of connections. If you want **autocommit mode**, then set :attr:`isolation_level` to None. Otherwise leave it at its default, which will result in a plain "BEGIN" statement, or set it to one of SQLite's supported isolation levels: "DEFERRED", "IMMEDIATE" or "EXCLUSIVE". Using :mod:`sqlite3` efficiently -------------------------------- Using shortcut methods ^^^^^^^^^^^^^^^^^^^^^^ Using the nonstandard :meth:`execute`, :meth:`executemany` and :meth:`executescript` methods of the :class:`Connection` object, your code can be written more concisely because you don't have to create the (often superfluous) :class:`Cursor` objects explicitly. Instead, the :class:`Cursor` objects are created implicitly and these shortcut methods return the cursor objects. This way, you can execute a ``SELECT`` statement and iterate over it directly using only a single call on the :class:`Connection` object. .. literalinclude:: ../includes/sqlite3/shortcut_methods.py Accessing columns by name instead of by index ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ One useful feature of the :mod:`sqlite3` module is the built-in :class:`sqlite3.Row` class designed to be used as a row factory. Rows wrapped with this class can be accessed both by index (like tuples) and case-insensitively by name: .. literalinclude:: ../includes/sqlite3/rowclass.py Using the connection as a context manager ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ With Python 2.5 or higher, connection objects can be used as context managers that automatically commit or rollback transactions. In the event of an exception, the transaction is rolled back; otherwise, the transaction is committed: .. literalinclude:: ../includes/sqlite3/ctx_manager.py Common issues ------------- Multithreading ^^^^^^^^^^^^^^ Older SQLite versions had issues with sharing connections between threads. That's why the Python module disallows sharing connections and cursors between threads. If you still try to do so, you will get an exception at runtime. The only exception is calling the :meth:`~Connection.interrupt` method, which only makes sense to call from a different thread. pysqlite-2.7.0/lib/000077500000000000000000000000001256035156500141505ustar00rootroot00000000000000pysqlite-2.7.0/lib/__init__.py000066400000000000000000000017741256035156500162720ustar00rootroot00000000000000#-*- coding: ISO-8859-1 -*- # pysqlite2/__init__.py: the pysqlite2 package. # # Copyright (C) 2005-2015 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. pysqlite-2.7.0/lib/dbapi2.py000066400000000000000000000051671256035156500156740ustar00rootroot00000000000000#-*- coding: ISO-8859-1 -*- # pysqlite2/dbapi2.py: the DB-API 2.0 interface # # Copyright (C) 2004-2015 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. import datetime import time from pysqlite2._sqlite import * paramstyle = "qmark" threadsafety = 1 apilevel = "2.0" Date = datetime.date Time = datetime.time Timestamp = datetime.datetime def DateFromTicks(ticks): return Date(*time.localtime(ticks)[:3]) def TimeFromTicks(ticks): return Time(*time.localtime(ticks)[3:6]) def TimestampFromTicks(ticks): return Timestamp(*time.localtime(ticks)[:6]) version_info = tuple([int(x) for x in version.split(".")]) sqlite_version_info = tuple([int(x) for x in sqlite_version.split(".")]) Binary = buffer def register_adapters_and_converters(): def adapt_date(val): return val.isoformat() def adapt_datetime(val): return val.isoformat(" ") def convert_date(val): return datetime.date(*map(int, val.split("-"))) def convert_timestamp(val): datepart, timepart = val.split(" ") year, month, day = map(int, datepart.split("-")) hours_part, minutes_part, seconds_part = timepart.split(":") hours, minutes = int(hours_part), int(minutes_part) sec_part, _, sub_sec_part = seconds_part.partition(".") seconds = int(sec_part) microseconds = int(sub_sec_part + "0" * (6 - len(sub_sec_part))) val = datetime.datetime(year, month, day, hours, minutes, seconds, microseconds) return val register_adapter(datetime.date, adapt_date) register_adapter(datetime.datetime, adapt_datetime) register_converter("date", convert_date) register_converter("timestamp", convert_timestamp) register_adapters_and_converters() # Clean up namespace del(register_adapters_and_converters) pysqlite-2.7.0/lib/dump.py000066400000000000000000000044561256035156500155000ustar00rootroot00000000000000# Mimic the sqlite3 console shell's .dump command # Author: Paul Kippes def _iterdump(connection): """ Returns an iterator to the dump of the database in an SQL text format. Used to produce an SQL dump of the database. Useful to save an in-memory database for later restoration. This function should not be called directly but instead called from the Connection method, iterdump(). """ cu = connection.cursor() yield('BEGIN TRANSACTION;') # sqlite_master table contains the SQL CREATE statements for the database. q = """ SELECT name, type, sql FROM sqlite_master WHERE sql NOT NULL AND type == 'table' """ schema_res = cu.execute(q) for table_name, type, sql in schema_res.fetchall(): if table_name == 'sqlite_sequence': yield('DELETE FROM sqlite_sequence;') elif table_name == 'sqlite_stat1': yield('ANALYZE sqlite_master;') elif table_name.startswith('sqlite_'): continue # NOTE: Virtual table support not implemented #elif sql.startswith('CREATE VIRTUAL TABLE'): # qtable = table_name.replace("'", "''") # yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"\ # "VALUES('table','%s','%s',0,'%s');" % # qtable, # qtable, # sql.replace("''")) else: yield('%s;' % sql) # Build the insert statement for each row of the current table res = cu.execute("PRAGMA table_info('%s')" % table_name) column_names = [str(table_info[1]) for table_info in res.fetchall()] q = "SELECT 'INSERT INTO \"%(tbl_name)s\" VALUES(" q += ",".join(["'||quote(" + col + ")||'" for col in column_names]) q += ")' FROM '%(tbl_name)s'" query_res = cu.execute(q % {'tbl_name': table_name}) for row in query_res: yield("%s;" % row[0]) # Now when the type is 'index', 'trigger', or 'view' q = """ SELECT name, type, sql FROM sqlite_master WHERE sql NOT NULL AND type IN ('index', 'trigger', 'view') """ schema_res = cu.execute(q) for name, type, sql in schema_res.fetchall(): yield('%s;' % sql) yield('COMMIT;') pysqlite-2.7.0/lib/test/000077500000000000000000000000001256035156500151275ustar00rootroot00000000000000pysqlite-2.7.0/lib/test/__init__.py000066400000000000000000000031001256035156500172320ustar00rootroot00000000000000#-*- coding: ISO-8859-1 -*- # pysqlite2/test/__init__.py: the package containing the test suite # # Copyright (C) 2004-2015 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. import unittest import sys from pysqlite2.test import dbapi, types, userfunctions, factory, transactions,\ hooks, regression, dump def suite(): tests = [dbapi.suite(), types.suite(), userfunctions.suite(), factory.suite(), transactions.suite(), hooks.suite(), regression.suite(), dump.suite()] if sys.version_info >= (2, 5, 0): from pysqlite2.test.py25 import py25tests tests.append(py25tests.suite()) return unittest.TestSuite(tuple(tests)) def test(): runner = unittest.TextTestRunner() runner.run(suite()) pysqlite-2.7.0/lib/test/dbapi.py000066400000000000000000000722761256035156500165760ustar00rootroot00000000000000#-*- coding: ISO-8859-1 -*- # pysqlite2/test/dbapi.py: tests for DB-API compliance # # Copyright (C) 2004-2015 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. import unittest import sys import threading import pysqlite2.dbapi2 as sqlite class ModuleTests(unittest.TestCase): def CheckAPILevel(self): self.assertEqual(sqlite.apilevel, "2.0", "apilevel is %s, should be 2.0" % sqlite.apilevel) def CheckThreadSafety(self): self.assertEqual(sqlite.threadsafety, 1, "threadsafety is %d, should be 1" % sqlite.threadsafety) def CheckParamStyle(self): self.assertEqual(sqlite.paramstyle, "qmark", "paramstyle is '%s', should be 'qmark'" % sqlite.paramstyle) def CheckWarning(self): self.assert_(issubclass(sqlite.Warning, StandardError), "Warning is not a subclass of StandardError") def CheckError(self): self.assertTrue(issubclass(sqlite.Error, StandardError), "Error is not a subclass of StandardError") def CheckInterfaceError(self): self.assertTrue(issubclass(sqlite.InterfaceError, sqlite.Error), "InterfaceError is not a subclass of Error") def CheckDatabaseError(self): self.assertTrue(issubclass(sqlite.DatabaseError, sqlite.Error), "DatabaseError is not a subclass of Error") def CheckDataError(self): self.assertTrue(issubclass(sqlite.DataError, sqlite.DatabaseError), "DataError is not a subclass of DatabaseError") def CheckOperationalError(self): self.assertTrue(issubclass(sqlite.OperationalError, sqlite.DatabaseError), "OperationalError is not a subclass of DatabaseError") def CheckIntegrityError(self): self.assertTrue(issubclass(sqlite.IntegrityError, sqlite.DatabaseError), "IntegrityError is not a subclass of DatabaseError") def CheckInternalError(self): self.assertTrue(issubclass(sqlite.InternalError, sqlite.DatabaseError), "InternalError is not a subclass of DatabaseError") def CheckProgrammingError(self): self.assertTrue(issubclass(sqlite.ProgrammingError, sqlite.DatabaseError), "ProgrammingError is not a subclass of DatabaseError") def CheckNotSupportedError(self): self.assertTrue(issubclass(sqlite.NotSupportedError, sqlite.DatabaseError), "NotSupportedError is not a subclass of DatabaseError") class ConnectionTests(unittest.TestCase): def setUp(self): self.cx = sqlite.connect(":memory:") cu = self.cx.cursor() cu.execute("create table test(id integer primary key, name text)") cu.execute("insert into test(name) values (?)", ("foo",)) def tearDown(self): self.cx.close() def CheckCommit(self): self.cx.commit() def CheckCommitAfterNoChanges(self): """ A commit should also work when no changes were made to the database. """ self.cx.commit() self.cx.commit() def CheckRollback(self): self.cx.rollback() def CheckRollbackAfterNoChanges(self): """ A rollback should also work when no changes were made to the database. """ self.cx.rollback() self.cx.rollback() def CheckCursor(self): cu = self.cx.cursor() def CheckFailedOpen(self): YOU_CANNOT_OPEN_THIS = "/foo/bar/bla/23534/mydb.db" try: con = sqlite.connect(YOU_CANNOT_OPEN_THIS) except sqlite.OperationalError: return self.fail("should have raised an OperationalError") def CheckClose(self): self.cx.close() def CheckExceptions(self): # Optional DB-API extension. self.assertEqual(self.cx.Warning, sqlite.Warning) self.assertEqual(self.cx.Error, sqlite.Error) self.assertEqual(self.cx.InterfaceError, sqlite.InterfaceError) self.assertEqual(self.cx.DatabaseError, sqlite.DatabaseError) self.assertEqual(self.cx.DataError, sqlite.DataError) self.assertEqual(self.cx.OperationalError, sqlite.OperationalError) self.assertEqual(self.cx.IntegrityError, sqlite.IntegrityError) self.assertEqual(self.cx.InternalError, sqlite.InternalError) self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError) self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError) class CursorTests(unittest.TestCase): def setUp(self): self.cx = sqlite.connect(":memory:") self.cu = self.cx.cursor() self.cu.execute("create table test(id integer primary key, name text, income number)") self.cu.execute("insert into test(name) values (?)", ("foo",)) def tearDown(self): self.cu.close() self.cx.close() def CheckExecuteNoArgs(self): self.cu.execute("delete from test") def CheckExecuteIllegalSql(self): try: self.cu.execute("select asdf") self.fail("should have raised an OperationalError") except sqlite.OperationalError: return except: self.fail("raised wrong exception") def CheckExecuteTooMuchSql(self): try: self.cu.execute("select 5+4; select 4+5") self.fail("should have raised a ProgrammingError") except sqlite.ProgrammingError: return except: self.fail("raised wrong exception") def CheckExecuteTooMuchSql2(self): self.cu.execute("select 5+4; -- foo bar") def CheckExecuteTooMuchSql3(self): self.cu.execute(""" select 5+4; /* foo */ """) def CheckExecuteWrongSqlArg(self): try: self.cu.execute(42) self.fail("should have raised a ValueError") except ValueError: return except: self.fail("raised wrong exception.") def CheckExecuteArgInt(self): self.cu.execute("insert into test(id) values (?)", (42,)) def CheckExecuteArgFloat(self): self.cu.execute("insert into test(income) values (?)", (2500.32,)) def CheckExecuteArgString(self): self.cu.execute("insert into test(name) values (?)", ("Hugo",)) def CheckExecuteWrongNoOfArgs1(self): # too many parameters try: self.cu.execute("insert into test(id) values (?)", (17, "Egon")) self.fail("should have raised ProgrammingError") except sqlite.ProgrammingError: pass def CheckExecuteWrongNoOfArgs2(self): # too little parameters try: self.cu.execute("insert into test(id) values (?)") self.fail("should have raised ProgrammingError") except sqlite.ProgrammingError: pass def CheckExecuteWrongNoOfArgs3(self): # no parameters, parameters are needed try: self.cu.execute("insert into test(id) values (?)") self.fail("should have raised ProgrammingError") except sqlite.ProgrammingError: pass def CheckExecuteParamList(self): self.cu.execute("insert into test(name) values ('foo')") self.cu.execute("select name from test where name=?", ["foo"]) row = self.cu.fetchone() self.assertEqual(row[0], "foo") def CheckExecuteParamSequence(self): class L(object): def __len__(self): return 1 def __getitem__(self, x): assert x == 0 return "foo" self.cu.execute("insert into test(name) values ('foo')") self.cu.execute("select name from test where name=?", L()) row = self.cu.fetchone() self.assertEqual(row[0], "foo") def CheckExecuteDictMapping(self): self.cu.execute("insert into test(name) values ('foo')") self.cu.execute("select name from test where name=:name", {"name": "foo"}) row = self.cu.fetchone() self.assertEqual(row[0], "foo") def CheckExecuteDictMapping_Mapping(self): # Test only works with Python 2.5 or later if sys.version_info < (2, 5, 0): return class D(dict): def __missing__(self, key): return "foo" self.cu.execute("insert into test(name) values ('foo')") self.cu.execute("select name from test where name=:name", D()) row = self.cu.fetchone() self.assertEqual(row[0], "foo") def CheckExecuteDictMappingTooLittleArgs(self): self.cu.execute("insert into test(name) values ('foo')") try: self.cu.execute("select name from test where name=:name and id=:id", {"name": "foo"}) self.fail("should have raised ProgrammingError") except sqlite.ProgrammingError: pass def CheckExecuteDictMappingNoArgs(self): self.cu.execute("insert into test(name) values ('foo')") try: self.cu.execute("select name from test where name=:name") self.fail("should have raised ProgrammingError") except sqlite.ProgrammingError: pass def CheckExecuteDictMappingUnnamed(self): self.cu.execute("insert into test(name) values ('foo')") try: self.cu.execute("select name from test where name=?", {"name": "foo"}) self.fail("should have raised ProgrammingError") except sqlite.ProgrammingError: pass def CheckClose(self): self.cu.close() def CheckRowcountExecute(self): self.cu.execute("delete from test") self.cu.execute("insert into test(name) values ('foo')") self.cu.execute("insert into test(name) values ('foo')") self.cu.execute("update test set name='bar'") self.assertEqual(self.cu.rowcount, 2) def CheckRowcountSelect(self): """ pysqlite does not know the rowcount of SELECT statements, because we don't fetch all rows after executing the select statement. The rowcount has thus to be -1. """ self.cu.execute("select 5 union select 6") self.assertEqual(self.cu.rowcount, -1) def CheckRowcountExecutemany(self): self.cu.execute("delete from test") self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)]) self.assertEqual(self.cu.rowcount, 3) def CheckTotalChanges(self): self.cu.execute("insert into test(name) values ('foo')") self.cu.execute("insert into test(name) values ('foo')") if self.cx.total_changes < 2: self.fail("total changes reported wrong value") # Checks for executemany: # Sequences are required by the DB-API, iterators # enhancements in pysqlite. def CheckExecuteManySequence(self): self.cu.executemany("insert into test(income) values (?)", [(x,) for x in range(100, 110)]) def CheckExecuteManyIterator(self): class MyIter: def __init__(self): self.value = 5 def next(self): if self.value == 10: raise StopIteration else: self.value += 1 return (self.value,) self.cu.executemany("insert into test(income) values (?)", MyIter()) def CheckExecuteManyGenerator(self): def mygen(): for i in range(5): yield (i,) self.cu.executemany("insert into test(income) values (?)", mygen()) def CheckExecuteManyWrongSqlArg(self): try: self.cu.executemany(42, [(3,)]) self.fail("should have raised a ValueError") except ValueError: return except: self.fail("raised wrong exception.") def CheckExecuteManySelect(self): try: self.cu.executemany("select ?", [(3,)]) self.fail("should have raised a ProgrammingError") except sqlite.ProgrammingError: return except: self.fail("raised wrong exception.") def CheckExecuteManyNotIterable(self): try: self.cu.executemany("insert into test(income) values (?)", 42) self.fail("should have raised a TypeError") except TypeError: return except Exception, e: print "raised", e.__class__ self.fail("raised wrong exception.") def CheckFetchIter(self): # Optional DB-API extension. self.cu.execute("delete from test") self.cu.execute("insert into test(id) values (?)", (5,)) self.cu.execute("insert into test(id) values (?)", (6,)) self.cu.execute("select id from test order by id") lst = [] for row in self.cu: lst.append(row[0]) self.assertEqual(lst[0], 5) self.assertEqual(lst[1], 6) def CheckFetchone(self): self.cu.execute("select name from test") row = self.cu.fetchone() self.assertEqual(row[0], "foo") row = self.cu.fetchone() self.assertEqual(row, None) def CheckFetchoneNoStatement(self): cur = self.cx.cursor() row = cur.fetchone() self.assertEqual(row, None) def CheckArraySize(self): # must default ot 1 self.assertEqual(self.cu.arraysize, 1) # now set to 2 self.cu.arraysize = 2 # now make the query return 3 rows self.cu.execute("delete from test") self.cu.execute("insert into test(name) values ('A')") self.cu.execute("insert into test(name) values ('B')") self.cu.execute("insert into test(name) values ('C')") self.cu.execute("select name from test") res = self.cu.fetchmany() self.assertEqual(len(res), 2) def CheckFetchmany(self): self.cu.execute("select name from test") res = self.cu.fetchmany(100) self.assertEqual(len(res), 1) res = self.cu.fetchmany(100) self.assertEqual(res, []) def CheckFetchmanyKwArg(self): """Checks if fetchmany works with keyword arguments""" self.cu.execute("select name from test") res = self.cu.fetchmany(size=100) self.assertEqual(len(res), 1) def CheckFetchall(self): self.cu.execute("select name from test") res = self.cu.fetchall() self.assertEqual(len(res), 1) res = self.cu.fetchall() self.assertEqual(res, []) def CheckSetinputsizes(self): self.cu.setinputsizes([3, 4, 5]) def CheckSetoutputsize(self): self.cu.setoutputsize(5, 0) def CheckSetoutputsizeNoColumn(self): self.cu.setoutputsize(42) def CheckCursorConnection(self): # Optional DB-API extension. self.assertEqual(self.cu.connection, self.cx) def CheckWrongCursorCallable(self): try: def f(): pass cur = self.cx.cursor(f) self.fail("should have raised a TypeError") except TypeError: return self.fail("should have raised a ValueError") def CheckCursorWrongClass(self): class Foo: pass foo = Foo() try: cur = sqlite.Cursor(foo) self.fail("should have raised a ValueError") except TypeError: pass class ThreadTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") self.cur = self.con.cursor() self.cur.execute("create table test(id integer primary key, name text, bin binary, ratio number, ts timestamp)") def tearDown(self): self.cur.close() self.con.close() def CheckConCursor(self): def run(con, errors): try: cur = con.cursor() errors.append("did not raise ProgrammingError") return except sqlite.ProgrammingError: return except: errors.append("raised wrong exception") errors = [] t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors}) t.start() t.join() if len(errors) > 0: self.fail("\n".join(errors)) def CheckConCommit(self): def run(con, errors): try: con.commit() errors.append("did not raise ProgrammingError") return except sqlite.ProgrammingError: return except: errors.append("raised wrong exception") errors = [] t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors}) t.start() t.join() if len(errors) > 0: self.fail("\n".join(errors)) def CheckConRollback(self): def run(con, errors): try: con.rollback() errors.append("did not raise ProgrammingError") return except sqlite.ProgrammingError: return except: errors.append("raised wrong exception") errors = [] t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors}) t.start() t.join() if len(errors) > 0: self.fail("\n".join(errors)) def CheckConClose(self): def run(con, errors): try: con.close() errors.append("did not raise ProgrammingError") return except sqlite.ProgrammingError: return except: errors.append("raised wrong exception") errors = [] t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors}) t.start() t.join() if len(errors) > 0: self.fail("\n".join(errors)) def CheckCurImplicitBegin(self): def run(cur, errors): try: cur.execute("insert into test(name) values ('a')") errors.append("did not raise ProgrammingError") return except sqlite.ProgrammingError: return except: errors.append("raised wrong exception") errors = [] t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors}) t.start() t.join() if len(errors) > 0: self.fail("\n".join(errors)) def CheckCurClose(self): def run(cur, errors): try: cur.close() errors.append("did not raise ProgrammingError") return except sqlite.ProgrammingError: return except: errors.append("raised wrong exception") errors = [] t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors}) t.start() t.join() if len(errors) > 0: self.fail("\n".join(errors)) def CheckCurExecute(self): def run(cur, errors): try: cur.execute("select name from test") errors.append("did not raise ProgrammingError") return except sqlite.ProgrammingError: return except: errors.append("raised wrong exception") errors = [] self.cur.execute("insert into test(name) values ('a')") t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors}) t.start() t.join() if len(errors) > 0: self.fail("\n".join(errors)) def CheckCurIterNext(self): def run(cur, errors): try: row = cur.fetchone() errors.append("did not raise ProgrammingError") return except sqlite.ProgrammingError: return except: errors.append("raised wrong exception") errors = [] self.cur.execute("insert into test(name) values ('a')") self.cur.execute("select name from test") t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors}) t.start() t.join() if len(errors) > 0: self.fail("\n".join(errors)) class ConstructorTests(unittest.TestCase): def CheckDate(self): d = sqlite.Date(2004, 10, 28) def CheckTime(self): t = sqlite.Time(12, 39, 35) def CheckTimestamp(self): ts = sqlite.Timestamp(2004, 10, 28, 12, 39, 35) def CheckDateFromTicks(self): d = sqlite.DateFromTicks(42) def CheckTimeFromTicks(self): t = sqlite.TimeFromTicks(42) def CheckTimestampFromTicks(self): ts = sqlite.TimestampFromTicks(42) def CheckBinary(self): b = sqlite.Binary(chr(0) + "'") class ExtensionTests(unittest.TestCase): def CheckScriptStringSql(self): con = sqlite.connect(":memory:") cur = con.cursor() cur.executescript(""" -- bla bla /* a stupid comment */ create table a(i); insert into a(i) values (5); """) cur.execute("select i from a") res = cur.fetchone()[0] self.assertEqual(res, 5) def CheckScriptStringUnicode(self): con = sqlite.connect(":memory:") cur = con.cursor() cur.executescript(u""" create table a(i); insert into a(i) values (5); select i from a; delete from a; insert into a(i) values (6); """) cur.execute("select i from a") res = cur.fetchone()[0] self.assertEqual(res, 6) def CheckScriptSyntaxError(self): con = sqlite.connect(":memory:") cur = con.cursor() raised = False try: cur.executescript("create table test(x); asdf; create table test2(x)") except sqlite.OperationalError: raised = True self.assertEqual(raised, True, "should have raised an exception") def CheckScriptErrorNormal(self): con = sqlite.connect(":memory:") cur = con.cursor() raised = False try: cur.executescript("create table test(sadfsadfdsa); select foo from hurz;") except sqlite.OperationalError: raised = True self.assertEqual(raised, True, "should have raised an exception") def CheckConnectionExecute(self): con = sqlite.connect(":memory:") result = con.execute("select 5").fetchone()[0] self.assertEqual(result, 5, "Basic test of Connection.execute") def CheckConnectionExecutemany(self): con = sqlite.connect(":memory:") con.execute("create table test(foo)") con.executemany("insert into test(foo) values (?)", [(3,), (4,)]) result = con.execute("select foo from test order by foo").fetchall() self.assertEqual(result[0][0], 3, "Basic test of Connection.executemany") self.assertEqual(result[1][0], 4, "Basic test of Connection.executemany") def CheckConnectionExecutescript(self): con = sqlite.connect(":memory:") con.executescript("create table test(foo); insert into test(foo) values (5);") result = con.execute("select foo from test").fetchone()[0] self.assertEqual(result, 5, "Basic test of Connection.executescript") class ClosedConTests(unittest.TestCase): def setUp(self): pass def tearDown(self): pass def CheckClosedConCursor(self): con = sqlite.connect(":memory:") con.close() try: cur = con.cursor() self.fail("Should have raised a ProgrammingError") except sqlite.ProgrammingError: pass except: self.fail("Should have raised a ProgrammingError") def CheckClosedConCommit(self): con = sqlite.connect(":memory:") con.close() try: con.commit() self.fail("Should have raised a ProgrammingError") except sqlite.ProgrammingError: pass except: self.fail("Should have raised a ProgrammingError") def CheckClosedConRollback(self): con = sqlite.connect(":memory:") con.close() try: con.rollback() self.fail("Should have raised a ProgrammingError") except sqlite.ProgrammingError: pass except: self.fail("Should have raised a ProgrammingError") def CheckClosedCurExecute(self): con = sqlite.connect(":memory:") cur = con.cursor() con.close() try: cur.execute("select 4") self.fail("Should have raised a ProgrammingError") except sqlite.ProgrammingError: pass except: 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(): module_suite = unittest.makeSuite(ModuleTests, "Check") connection_suite = unittest.makeSuite(ConnectionTests, "Check") cursor_suite = unittest.makeSuite(CursorTests, "Check") thread_suite = unittest.makeSuite(ThreadTests, "Check") constructor_suite = unittest.makeSuite(ConstructorTests, "Check") ext_suite = unittest.makeSuite(ExtensionTests, "Check") closed_con_suite = unittest.makeSuite(ClosedConTests, "Check") 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(): runner = unittest.TextTestRunner() runner.run(suite()) if __name__ == "__main__": test() pysqlite-2.7.0/lib/test/dump.py000066400000000000000000000033311256035156500164460ustar00rootroot00000000000000# Author: Paul Kippes import unittest from pysqlite2 import dbapi2 as sqlite class DumpTests(unittest.TestCase): def setUp(self): self.cx = sqlite.connect(":memory:") self.cu = self.cx.cursor() def tearDown(self): self.cx.close() def CheckTableDump(self): expected_sqls = [ "CREATE TABLE t1(id integer primary key, s1 text, " \ "t1_i1 integer not null, i2 integer, unique (s1), " \ "constraint t1_idx1 unique (i2));" , "INSERT INTO \"t1\" VALUES(1,'foo',10,20);" , "INSERT INTO \"t1\" VALUES(2,'foo2',30,30);" , "CREATE TABLE t2(id integer, t2_i1 integer, " \ "t2_i2 integer, primary key (id)," \ "foreign key(t2_i1) references t1(t1_i1));" , "CREATE TRIGGER trigger_1 update of t1_i1 on t1 " \ "begin " \ "update t2 set t2_i1 = new.t1_i1 where t2_i1 = old.t1_i1; " \ "end;" , "CREATE VIEW v1 as select * from t1 left join t2 " \ "using (id);" ] [self.cu.execute(s) for s in expected_sqls] i = self.cx.iterdump() actual_sqls = [s for s in i] expected_sqls = ['BEGIN TRANSACTION;'] + expected_sqls + \ ['COMMIT;'] [self.assertEqual(expected_sqls[i], actual_sqls[i]) for i in xrange(len(expected_sqls))] def suite(): return unittest.TestSuite(unittest.makeSuite(DumpTests, "Check")) def test(): runner = unittest.TextTestRunner() runner.run(suite()) if __name__ == "__main__": test() pysqlite-2.7.0/lib/test/factory.py000066400000000000000000000174061256035156500171600ustar00rootroot00000000000000#-*- coding: ISO-8859-1 -*- # pysqlite2/test/factory.py: tests for the various factories in pysqlite # # Copyright (C) 2005-2015 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. import unittest import pysqlite2.dbapi2 as sqlite class MyConnection(sqlite.Connection): def __init__(self, *args, **kwargs): sqlite.Connection.__init__(self, *args, **kwargs) def dict_factory(cursor, row): d = {} for idx, col in enumerate(cursor.description): d[col[0]] = row[idx] return d class MyCursor(sqlite.Cursor): def __init__(self, *args, **kwargs): sqlite.Cursor.__init__(self, *args, **kwargs) self.row_factory = dict_factory class ConnectionFactoryTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:", factory=MyConnection) def tearDown(self): self.con.close() def CheckIsInstance(self): self.assertTrue(isinstance(self.con, MyConnection), "connection is not instance of MyConnection") class CursorFactoryTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") def tearDown(self): self.con.close() def CheckIsInstance(self): cur = self.con.cursor(factory=MyCursor) self.assertTrue(isinstance(cur, MyCursor), "cursor is not instance of MyCursor") class RowFactoryTestsBackwardsCompat(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") def CheckIsProducedByFactory(self): cur = self.con.cursor(factory=MyCursor) cur.execute("select 4+5 as foo") row = cur.fetchone() self.assertTrue(isinstance(row, dict), "row is not instance of dict") cur.close() def tearDown(self): self.con.close() class RowFactoryTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") def CheckCustomFactory(self): self.con.row_factory = lambda cur, row: list(row) row = self.con.execute("select 1, 2").fetchone() self.assertTrue(isinstance(row, list), "row is not instance of list") def CheckSqliteRowIndex(self): self.con.row_factory = sqlite.Row row = self.con.execute("select 1 as a, 2 as b").fetchone() self.assertTrue(isinstance(row, sqlite.Row), "row is not instance of sqlite.Row") col1, col2 = row["a"], row["b"] self.assertTrue(col1 == 1, "by name: wrong result for column 'a'") self.assertTrue(col2 == 2, "by name: wrong result for column 'a'") col1, col2 = row["A"], row["B"] self.assertTrue(col1 == 1, "by name: wrong result for column 'A'") self.assertTrue(col2 == 2, "by name: wrong result for column 'B'") col1, col2 = row[0], row[1] self.assertTrue(col1 == 1, "by index: wrong result for column 0") self.assertTrue(col2 == 2, "by index: wrong result for column 1") def CheckSqliteRowIter(self): """Checks if the row object is iterable""" self.con.row_factory = sqlite.Row row = self.con.execute("select 1 as a, 2 as b").fetchone() for col in row: pass def CheckSqliteRowAsTuple(self): """Checks if the row object can be converted to a tuple""" self.con.row_factory = sqlite.Row row = self.con.execute("select 1 as a, 2 as b").fetchone() t = tuple(row) def CheckSqliteRowAsDict(self): """Checks if the row object can be correctly converted to a dictionary""" self.con.row_factory = sqlite.Row row = self.con.execute("select 1 as a, 2 as b").fetchone() d = dict(row) self.assertEqual(d["a"], row["a"]) self.assertEqual(d["b"], row["b"]) def CheckSqliteRowHashCmp(self): """Checks if the row object compares and hashes correctly""" self.con.row_factory = sqlite.Row row_1 = self.con.execute("select 1 as a, 2 as b").fetchone() row_2 = self.con.execute("select 1 as a, 2 as b").fetchone() row_3 = self.con.execute("select 1 as a, 3 as b").fetchone() self.assertTrue(row_1 == row_1) self.assertTrue(row_1 == row_2) self.assertTrue(row_2 != row_3) self.assertFalse(row_1 != row_1) self.assertFalse(row_1 != row_2) self.assertFalse(row_2 == row_3) self.assertEqual(row_1, row_2) self.assertEqual(hash(row_1), hash(row_2)) self.assertNotEqual(row_1, row_3) self.assertNotEqual(hash(row_1), hash(row_3)) def tearDown(self): self.con.close() class TextFactoryTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") def CheckUnicode(self): austria = unicode("Österreich", "latin1") row = self.con.execute("select ?", (austria,)).fetchone() self.assertTrue(type(row[0]) == unicode, "type of row[0] must be unicode") def CheckString(self): self.con.text_factory = str austria = unicode("Österreich", "latin1") row = self.con.execute("select ?", (austria,)).fetchone() self.assertTrue(type(row[0]) == str, "type of row[0] must be str") self.assertTrue(row[0] == austria.encode("utf-8"), "column must equal original data in UTF-8") def CheckCustom(self): self.con.text_factory = lambda x: unicode(x, "utf-8", "ignore") austria = unicode("Österreich", "latin1") row = self.con.execute("select ?", (austria.encode("latin1"),)).fetchone() self.assertTrue(type(row[0]) == unicode, "type of row[0] must be unicode") self.assertTrue(row[0].endswith(u"reich"), "column must contain original data") def CheckOptimizedUnicode(self): self.con.text_factory = sqlite.OptimizedUnicode austria = unicode("Österreich", "latin1") germany = unicode("Deutchland") a_row = self.con.execute("select ?", (austria,)).fetchone() d_row = self.con.execute("select ?", (germany,)).fetchone() self.assertTrue(type(a_row[0]) == unicode, "type of non-ASCII row must be unicode") self.assertTrue(type(d_row[0]) == str, "type of ASCII-only row must be str") def tearDown(self): self.con.close() def suite(): connection_suite = unittest.makeSuite(ConnectionFactoryTests, "Check") cursor_suite = unittest.makeSuite(CursorFactoryTests, "Check") row_suite_compat = unittest.makeSuite(RowFactoryTestsBackwardsCompat, "Check") row_suite = unittest.makeSuite(RowFactoryTests, "Check") text_suite = unittest.makeSuite(TextFactoryTests, "Check") return unittest.TestSuite((connection_suite, cursor_suite, row_suite_compat, row_suite, text_suite)) def test(): runner = unittest.TextTestRunner() runner.run(suite()) if __name__ == "__main__": test() pysqlite-2.7.0/lib/test/hooks.py000066400000000000000000000147551256035156500166400ustar00rootroot00000000000000#-*- coding: ISO-8859-1 -*- # pysqlite2/test/hooks.py: tests for various SQLite-specific hooks # # Copyright (C) 2006-2015 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. import unittest import pysqlite2.dbapi2 as sqlite class CollationTests(unittest.TestCase): def setUp(self): pass def tearDown(self): pass def CheckCreateCollationNotCallable(self): con = sqlite.connect(":memory:") try: con.create_collation("X", 42) self.fail("should have raised a TypeError") except TypeError, e: self.assertEqual(e.args[0], "parameter must be callable") def CheckCreateCollationNotAscii(self): con = sqlite.connect(":memory:") try: con.create_collation("collä", cmp) self.fail("should have raised a ProgrammingError") except sqlite.ProgrammingError, e: pass def CheckCollationIsUsed(self): if sqlite.version_info < (3, 2, 1): # old SQLite versions crash on this test return def mycoll(x, y): # reverse order return -cmp(x, y) con = sqlite.connect(":memory:") con.create_collation("mycoll", mycoll) sql = """ select x from ( select 'a' as x union select 'b' as x union select 'c' as x ) order by x collate mycoll """ result = con.execute(sql).fetchall() if result[0][0] != "c" or result[1][0] != "b" or result[2][0] != "a": self.fail("the expected order was not returned") con.create_collation("mycoll", None) try: result = con.execute(sql).fetchall() self.fail("should have raised an OperationalError") except sqlite.OperationalError, e: self.assertEqual(e.args[0].lower(), "no such collation sequence: mycoll") def CheckCollationRegisterTwice(self): """ Register two different collation functions under the same name. Verify that the last one is actually used. """ con = sqlite.connect(":memory:") con.create_collation("mycoll", cmp) con.create_collation("mycoll", lambda x, y: -cmp(x, y)) result = con.execute(""" select x from (select 'a' as x union select 'b' as x) order by x collate mycoll """).fetchall() if result[0][0] != 'b' or result[1][0] != 'a': self.fail("wrong collation function is used") def CheckDeregisterCollation(self): """ Register a collation, then deregister it. Make sure an error is raised if we try to use it. """ con = sqlite.connect(":memory:") con.create_collation("mycoll", cmp) con.create_collation("mycoll", None) try: con.execute("select 'a' as x union select 'b' as x order by x collate mycoll") self.fail("should have raised an OperationalError") except sqlite.OperationalError, e: if not e.args[0].startswith("no such collation sequence"): self.fail("wrong OperationalError raised") class ProgressTests(unittest.TestCase): def CheckProgressHandlerUsed(self): """ Test that the progress handler is invoked once it is set. """ con = sqlite.connect(":memory:") progress_calls = [] def progress(): progress_calls.append(None) return 0 con.set_progress_handler(progress, 1) con.execute(""" create table foo(a, b) """) self.assertTrue(progress_calls) def CheckCancelOperation(self): """ Test that returning a non-zero value stops the operation in progress. """ con = sqlite.connect(":memory:") progress_calls = [] def progress(): progress_calls.append(None) return 1 con.set_progress_handler(progress, 1) curs = con.cursor() self.assertRaises( sqlite.OperationalError, curs.execute, "create table bar (a, b)") def CheckClearHandler(self): """ Test that setting the progress handler to None clears the previously set handler. """ con = sqlite.connect(":memory:") action = 0 def progress(): action = 1 return 0 con.set_progress_handler(progress, 1) con.set_progress_handler(None, 1) con.execute("select 1 union select 2 union select 3").fetchall() self.assertEqual(action, 0, "progress handler was not cleared") class LimitTests(unittest.TestCase): def CheckGetLimit(self): """ Test that the get limit method return something useful. """ con = sqlite.connect(":memory:") val = con.get_limit(sqlite.SQLITE_LIMIT_VARIABLE_NUMBER) self.assertTrue(val > 0) def CheckSetLimit(self): """ Test that the set limit method actally changes limits. """ con = sqlite.connect(":memory:") oldval = con.get_limit(sqlite.SQLITE_LIMIT_VARIABLE_NUMBER) con.set_limit(sqlite.SQLITE_LIMIT_VARIABLE_NUMBER, oldval - 1) newval = con.get_limit(sqlite.SQLITE_LIMIT_VARIABLE_NUMBER) self.assertEqual(newval, oldval - 1) def suite(): collation_suite = unittest.makeSuite(CollationTests, "Check") progress_suite = unittest.makeSuite(ProgressTests, "Check") limit_suite = unittest.makeSuite(LimitTests, "Check") return unittest.TestSuite((collation_suite, progress_suite, limit_suite)) def test(): runner = unittest.TextTestRunner() runner.run(suite()) if __name__ == "__main__": test() pysqlite-2.7.0/lib/test/py25/000077500000000000000000000000001256035156500157265ustar00rootroot00000000000000pysqlite-2.7.0/lib/test/py25/__init__.py000066400000000000000000000000011256035156500200260ustar00rootroot00000000000000 pysqlite-2.7.0/lib/test/py25/py25tests.py000066400000000000000000000052761256035156500201740ustar00rootroot00000000000000#-*- coding: ISO-8859-1 -*- # pysqlite2/test/regression.py: pysqlite regression tests # # Copyright (C) 2007-2015 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. from __future__ import with_statement import unittest import pysqlite2.dbapi2 as sqlite did_rollback = False class MyConnection(sqlite.Connection): def rollback(self): global did_rollback did_rollback = True sqlite.Connection.rollback(self) class ContextTests(unittest.TestCase): def setUp(self): global did_rollback self.con = sqlite.connect(":memory:", factory=MyConnection) self.con.execute("create table test(c unique)") did_rollback = False def tearDown(self): self.con.close() def CheckContextManager(self): """Can the connection be used as a context manager at all?""" with self.con: pass def CheckContextManagerCommit(self): """Is a commit called in the context manager?""" with self.con: self.con.execute("insert into test(c) values ('foo')") self.con.rollback() count = self.con.execute("select count(*) from test").fetchone()[0] self.assertEqual(count, 1) def CheckContextManagerRollback(self): """Is a rollback called in the context manager?""" global did_rollback self.assertEqual(did_rollback, False) try: with self.con: self.con.execute("insert into test(c) values (4)") self.con.execute("insert into test(c) values (4)") except sqlite.IntegrityError: pass self.assertEqual(did_rollback, True) def suite(): ctx_suite = unittest.makeSuite(ContextTests, "Check") return unittest.TestSuite((ctx_suite,)) def test(): runner = unittest.TextTestRunner() runner.run(suite()) if __name__ == "__main__": test() pysqlite-2.7.0/lib/test/regression.py000066400000000000000000000243131256035156500176640ustar00rootroot00000000000000#-*- coding: ISO-8859-1 -*- # pysqlite2/test/regression.py: pysqlite regression tests # # Copyright (C) 2006-2015 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. import datetime import unittest import pysqlite2.dbapi2 as sqlite class RegressionTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") def tearDown(self): self.con.close() def CheckPragmaUserVersion(self): # This used to crash pysqlite because this pragma command returns NULL for the column name cur = self.con.cursor() cur.execute("pragma user_version") def CheckPragmaSchemaVersion(self): # This still crashed pysqlite <= 2.2.1 con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES) try: cur = self.con.cursor() cur.execute("pragma schema_version") finally: cur.close() con.close() def CheckStatementReset(self): # pysqlite 2.1.0 to 2.2.0 have the problem that not all statements are # reset before a rollback, but only those that are still in the # statement cache. The others are not accessible from the connection object. con = sqlite.connect(":memory:", cached_statements=5) cursors = [con.cursor() for x in xrange(5)] cursors[0].execute("create table test(x)") for i in range(10): cursors[0].executemany("insert into test(x) values (?)", [(x,) for x in xrange(10)]) for i in range(5): cursors[i].execute(" " * i + "select x from test") con.rollback() def CheckColumnNameWithSpaces(self): cur = self.con.cursor() cur.execute('select 1 as "foo bar [datetime]"') self.assertEqual(cur.description[0][0], "foo bar") cur.execute('select 1 as "foo baz"') self.assertEqual(cur.description[0][0], "foo baz") def CheckStatementFinalizationOnCloseDb(self): # pysqlite versions <= 2.3.3 only finalized statements in the statement # cache when closing the database. statements that were still # referenced in cursors weren't closed an could provoke " # "OperationalError: Unable to close due to unfinalised statements". con = sqlite.connect(":memory:") cursors = [] # default statement cache size is 100 for i in range(105): cur = con.cursor() cursors.append(cur) cur.execute("select 1 x union select " + str(i)) con.close() def CheckOnConflictRollback(self): if sqlite.sqlite_version_info < (3, 2, 2): return con = sqlite.connect(":memory:") con.execute("create table foo(x, unique(x) on conflict rollback)") con.execute("insert into foo(x) values (1)") try: con.execute("insert into foo(x) values (1)") except sqlite.DatabaseError: pass con.execute("insert into foo(x) values (2)") try: con.commit() except sqlite.OperationalError: self.fail("pysqlite knew nothing about the implicit ROLLBACK") def CheckWorkaroundForBuggySqliteTransferBindings(self): """ pysqlite would crash with older SQLite versions unless a workaround is implemented. """ self.con.execute("create table foo(bar)") self.con.execute("drop table foo") self.con.execute("create table foo(bar)") def CheckEmptyStatement(self): """ pysqlite used to segfault with SQLite versions 3.5.x. These return NULL for "no-operation" statements """ self.con.execute("") def CheckUnicodeConnect(self): """ With pysqlite 2.4.0 you needed to use a string or a APSW connection object for opening database connections. Formerly, both bytestrings and unicode strings used to work. Let's make sure unicode strings work in the future. """ con = sqlite.connect(u":memory:") con.close() def CheckTypeMapUsage(self): """ pysqlite until 2.4.1 did not rebuild the row_cast_map when recompiling a statement. This test exhibits the problem. """ SELECT = "select * from foo" con = sqlite.connect(":memory:",detect_types=sqlite.PARSE_DECLTYPES) con.execute("create table foo(bar timestamp)") con.execute("insert into foo(bar) values (?)", (datetime.datetime.now(),)) con.execute(SELECT) con.execute("drop table foo") con.execute("create table foo(bar integer)") con.execute("insert into foo(bar) values (5)") con.execute(SELECT) def CheckRegisterAdapter(self): """ See issue 3312. """ self.assertRaises(TypeError, sqlite.register_adapter, {}, None) def CheckSetIsolationLevel(self): """ See issue 3312. """ con = sqlite.connect(":memory:") self.assertRaises(UnicodeEncodeError, setattr, con, "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 CheckRecursiveCursorUse(self): """ http://bugs.python.org/issue10811 Recursively using a cursor, such as when reusing it from a generator led to segfaults. Now we catch recursive cursor usage and raise a ProgrammingError. """ con = sqlite.connect(":memory:") cur = con.cursor() cur.execute("create table a (bar)") cur.execute("create table b (baz)") def foo(): cur.execute("insert into a (bar) values (?)", (1,)) yield 1 try: cur.executemany("insert into b (baz) values (?)", ((i,) for i in foo())) self.fail("should have raised ProgrammingError") except sqlite.ProgrammingError: pass def suite(): regression_suite = unittest.makeSuite(RegressionTests, "Check") return unittest.TestSuite((regression_suite,)) def test(): runner = unittest.TextTestRunner() runner.run(suite()) if __name__ == "__main__": test() pysqlite-2.7.0/lib/test/transactions.py000066400000000000000000000162671256035156500202250ustar00rootroot00000000000000#-*- coding: ISO-8859-1 -*- # pysqlite2/test/transactions.py: tests transactions # # Copyright (C) 2005-2015 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. import os import unittest import pysqlite2.dbapi2 as sqlite def get_db_path(): return "sqlite_testdb" class TransactionTests(unittest.TestCase): def setUp(self): try: os.remove(get_db_path()) except OSError: pass self.con1 = sqlite.connect(get_db_path(), timeout=0.1) self.cur1 = self.con1.cursor() self.con2 = sqlite.connect(get_db_path(), timeout=0.1) self.cur2 = self.con2.cursor() def tearDown(self): self.cur1.close() self.con1.close() self.cur2.close() self.con2.close() try: os.unlink(get_db_path()) except OSError: pass def CheckDMLdoesAutoCommitBefore(self): self.cur1.execute("create table test(i)") self.cur1.execute("insert into test(i) values (5)") self.cur1.execute("create table test2(j)") self.cur2.execute("select i from test") res = self.cur2.fetchall() self.assertEqual(len(res), 1) def CheckInsertStartsTransaction(self): self.cur1.execute("create table test(i)") self.cur1.execute("insert into test(i) values (5)") self.cur2.execute("select i from test") res = self.cur2.fetchall() self.assertEqual(len(res), 0) def CheckUpdateStartsTransaction(self): self.cur1.execute("create table test(i)") self.cur1.execute("insert into test(i) values (5)") self.con1.commit() self.cur1.execute("update test set i=6") self.cur2.execute("select i from test") res = self.cur2.fetchone()[0] self.assertEqual(res, 5) def CheckDeleteStartsTransaction(self): self.cur1.execute("create table test(i)") self.cur1.execute("insert into test(i) values (5)") self.con1.commit() self.cur1.execute("delete from test") self.cur2.execute("select i from test") res = self.cur2.fetchall() self.assertEqual(len(res), 1) def CheckReplaceStartsTransaction(self): self.cur1.execute("create table test(i)") self.cur1.execute("insert into test(i) values (5)") self.con1.commit() self.cur1.execute("replace into test(i) values (6)") self.cur2.execute("select i from test") res = self.cur2.fetchall() self.assertEqual(len(res), 1) self.assertEqual(res[0][0], 5) def CheckToggleAutoCommit(self): self.cur1.execute("create table test(i)") self.cur1.execute("insert into test(i) values (5)") self.con1.isolation_level = None self.assertEqual(self.con1.isolation_level, None) self.cur2.execute("select i from test") res = self.cur2.fetchall() self.assertEqual(len(res), 1) self.con1.isolation_level = "DEFERRED" self.assertEqual(self.con1.isolation_level , "DEFERRED") self.cur1.execute("insert into test(i) values (5)") self.cur2.execute("select i from test") res = self.cur2.fetchall() self.assertEqual(len(res), 1) def CheckRaiseTimeout(self): if sqlite.sqlite_version_info < (3, 2, 2): # This will fail (hang) on earlier versions of sqlite. # Determine exact version it was fixed. 3.2.1 hangs. return self.cur1.execute("create table test(i)") self.cur1.execute("insert into test(i) values (5)") try: self.cur2.execute("insert into test(i) values (5)") self.fail("should have raised an OperationalError") except sqlite.OperationalError: pass except: self.fail("should have raised an OperationalError") def CheckLocking(self): """ This tests the improved concurrency with pysqlite 2.3.4. You needed to roll back con2 before you could commit con1. """ if sqlite.sqlite_version_info < (3, 2, 2): # This will fail (hang) on earlier versions of sqlite. # Determine exact version it was fixed. 3.2.1 hangs. return self.cur1.execute("create table test(i)") self.cur1.execute("insert into test(i) values (5)") try: self.cur2.execute("insert into test(i) values (5)") self.fail("should have raised an OperationalError") except sqlite.OperationalError: pass except: self.fail("should have raised an OperationalError") # NO self.con2.rollback() HERE!!! 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): def setUp(self): self.con = sqlite.connect(":memory:") self.cur = self.con.cursor() def CheckVacuum(self): self.cur.execute("create table test(i)") self.cur.execute("insert into test(i) values (5)") self.cur.execute("vacuum") def CheckDropTable(self): self.cur.execute("create table test(i)") self.cur.execute("insert into test(i) values (5)") self.cur.execute("drop table test") def CheckPragma(self): self.cur.execute("create table test(i)") self.cur.execute("insert into test(i) values (5)") self.cur.execute("pragma count_changes=1") def tearDown(self): self.cur.close() self.con.close() def suite(): default_suite = unittest.makeSuite(TransactionTests, "Check") special_command_suite = unittest.makeSuite(SpecialCommandTests, "Check") return unittest.TestSuite((default_suite, special_command_suite)) def test(): runner = unittest.TextTestRunner() runner.run(suite()) if __name__ == "__main__": test() pysqlite-2.7.0/lib/test/types.py000066400000000000000000000372431256035156500166560ustar00rootroot00000000000000#-*- coding: ISO-8859-1 -*- # pysqlite2/test/types.py: tests for type conversion and detection # # Copyright (C) 2005-2015 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. import datetime import unittest import pysqlite2.dbapi2 as sqlite import zlib class SqliteTypeTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") self.cur = self.con.cursor() self.cur.execute("create table test(i integer, s varchar, f number, b blob)") def tearDown(self): self.cur.close() self.con.close() def CheckString(self): self.cur.execute("insert into test(s) values (?)", (u"Österreich",)) self.cur.execute("select s from test") row = self.cur.fetchone() self.assertEqual(row[0], u"Österreich") def CheckSmallInt(self): self.cur.execute("insert into test(i) values (?)", (42,)) self.cur.execute("select i from test") row = self.cur.fetchone() self.assertEqual(row[0], 42) def CheckLargeInt(self): num = 2**40 self.cur.execute("insert into test(i) values (?)", (num,)) self.cur.execute("select i from test") row = self.cur.fetchone() self.assertEqual(row[0], num) def CheckFloat(self): val = 3.14 self.cur.execute("insert into test(f) values (?)", (val,)) self.cur.execute("select f from test") row = self.cur.fetchone() self.assertEqual(row[0], val) def CheckBlob(self): val = buffer("Guglhupf") self.cur.execute("insert into test(b) values (?)", (val,)) self.cur.execute("select b from test") row = self.cur.fetchone() self.assertEqual(row[0], val) def CheckUnicodeExecute(self): self.cur.execute(u"select 'Österreich'") row = self.cur.fetchone() 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 def CheckBinaryString(self): bin_string = u"foo\x00bar" self.cur.execute("select ?", (bin_string,)) self.assertEqual(self.cur.fetchone()[0], bin_string) def CheckBinaryByteString(self): bin_string = "bla\x00bla" self.cur.execute("select ?", (bin_string,)) self.assertEqual(self.cur.fetchone()[0], bin_string) class DeclTypesTests(unittest.TestCase): class Foo: def __init__(self, _val): self.val = _val def __cmp__(self, other): if not isinstance(other, DeclTypesTests.Foo): raise ValueError if self.val == other.val: return 0 else: return 1 def __conform__(self, protocol): if protocol is sqlite.PrepareProtocol: return self.val else: return None def __str__(self): return "<%s>" % self.val 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, n1 number, n2 number(5))") # override float, make them always return the same number sqlite.converters["FLOAT"] = lambda x: 47.2 # and implement two custom ones sqlite.converters["BOOL"] = lambda x: bool(int(x)) sqlite.converters["FOO"] = DeclTypesTests.Foo sqlite.converters["WRONG"] = lambda x: "WRONG" sqlite.converters["NUMBER"] = float sqlite.converters["TEXT"] = str 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() def CheckString(self): # default self.cur.execute("insert into test(s) values (?)", ("foo",)) self.cur.execute('select s as "s [WRONG]" from test') row = self.cur.fetchone() self.assertEqual(row[0], "foo") def CheckTextEmptyString(self): """ Make sure that empty strings are converted to empty strings and not to None. """ self.cur.execute("insert into test(s) values (?)", ("",)) self.cur.execute("insert into test(s) values (?)", (None,)) self.cur.execute('select s as "s [TEXT]" from test') row = self.cur.fetchone() self.assertEqual(row[0], "") row = self.cur.fetchone() self.assertEqual(row[0], None) def CheckSmallInt(self): # default self.cur.execute("insert into test(i) values (?)", (42,)) self.cur.execute("select i from test") row = self.cur.fetchone() self.assertEqual(row[0], 42) def CheckLargeInt(self): # default num = 2**40 self.cur.execute("insert into test(i) values (?)", (num,)) self.cur.execute("select i from test") row = self.cur.fetchone() self.assertEqual(row[0], num) def CheckFloat(self): # custom val = 3.14 self.cur.execute("insert into test(f) values (?)", (val,)) self.cur.execute("select f from test") row = self.cur.fetchone() self.assertEqual(row[0], 47.2) def CheckBool(self): # custom self.cur.execute("insert into test(b) values (?)", (False,)) self.cur.execute("select b from test") row = self.cur.fetchone() self.assertEqual(row[0], False) self.cur.execute("delete from test") self.cur.execute("insert into test(b) values (?)", (True,)) self.cur.execute("select b from test") row = self.cur.fetchone() self.assertEqual(row[0], True) def CheckUnicode(self): # default val = u"\xd6sterreich" self.cur.execute("insert into test(u) values (?)", (val,)) self.cur.execute("select u from test") row = self.cur.fetchone() self.assertEqual(row[0], val) def CheckFoo(self): val = DeclTypesTests.Foo("bla") self.cur.execute("insert into test(foo) values (?)", (val,)) self.cur.execute("select foo from test") row = self.cur.fetchone() self.assertEqual(row[0], val) def CheckUnsupportedSeq(self): class Bar: pass val = Bar() try: self.cur.execute("insert into test(f) values (?)", (val,)) self.fail("should have raised an InterfaceError") except sqlite.InterfaceError: pass except: self.fail("should have raised an InterfaceError") def CheckUnsupportedDict(self): class Bar: pass val = Bar() try: self.cur.execute("insert into test(f) values (:val)", {"val": val}) self.fail("should have raised an InterfaceError") except sqlite.InterfaceError: pass except: self.fail("should have raised an InterfaceError") def CheckBlob(self): # default val = buffer("Guglhupf") self.cur.execute("insert into test(bin) values (?)", (val,)) self.cur.execute("select bin from test") row = self.cur.fetchone() self.assertEqual(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.assertEqual(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.assertEqual(type(value), float) class ColNamesTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES) self.cur = self.con.cursor() self.cur.execute("create table test(x foo)") sqlite.converters["FOO"] = lambda x: "[%s]" % x sqlite.converters["BAR"] = lambda x: "<%s>" % x sqlite.converters["EXC"] = lambda x: 5 // 0 sqlite.converters["B1B1"] = lambda x: "MARKER" def tearDown(self): del sqlite.converters["FOO"] del sqlite.converters["BAR"] del sqlite.converters["EXC"] del sqlite.converters["B1B1"] self.cur.close() self.con.close() def CheckDeclTypeNotUsed(self): """ Assures that the declared type is not used when PARSE_DECLTYPES is not set. """ self.cur.execute("insert into test(x) values (?)", ("xxx",)) self.cur.execute("select x from test") val = self.cur.fetchone()[0] self.assertEqual(val, "xxx") def CheckNone(self): self.cur.execute("insert into test(x) values (?)", (None,)) self.cur.execute("select x from test") val = self.cur.fetchone()[0] self.assertEqual(val, None) def CheckColName(self): self.cur.execute("insert into test(x) values (?)", ("xxx",)) self.cur.execute('select x as "x [bar]" from test') val = self.cur.fetchone()[0] self.assertEqual(val, "") # Check if the stripping of colnames works. Everything after the first # whitespace should be stripped. self.assertEqual(self.cur.description[0][0], "x") def CheckCaseInConverterName(self): self.cur.execute("""select 'other' as "x [b1b1]\"""") val = self.cur.fetchone()[0] self.assertEqual(val, "MARKER") def CheckCursorDescriptionNoRow(self): """ cursor.description should at least provide the column name(s), even if no row returned. """ self.cur.execute("select * from test where 0 = 1") self.assert_(self.cur.description[0][0] == "x") class ObjectAdaptationTests(unittest.TestCase): def cast(obj): return float(obj) cast = staticmethod(cast) def setUp(self): self.con = sqlite.connect(":memory:") try: del sqlite.adapters[int] except: pass sqlite.register_adapter(int, ObjectAdaptationTests.cast) self.cur = self.con.cursor() def tearDown(self): del sqlite.adapters[(int, sqlite.PrepareProtocol)] self.cur.close() self.con.close() def CheckCasterIsUsed(self): self.cur.execute("select ?", (4,)) val = self.cur.fetchone()[0] self.assertEqual(type(val), float) class BinaryConverterTests(unittest.TestCase): def convert(s): return zlib.decompress(s) convert = staticmethod(convert) def setUp(self): self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES) sqlite.register_converter("bin", BinaryConverterTests.convert) def tearDown(self): self.con.close() def CheckBinaryInputForConverter(self): testdata = "abcdefg" * 10 result = self.con.execute('select ? as "x [bin]"', (buffer(zlib.compress(testdata)),)).fetchone()[0] self.assertEqual(testdata, result) class DateTimeTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_DECLTYPES) self.cur = self.con.cursor() self.cur.execute("create table test(d date, ts timestamp)") def tearDown(self): self.cur.close() self.con.close() def CheckSqliteDate(self): d = sqlite.Date(2004, 2, 14) self.cur.execute("insert into test(d) values (?)", (d,)) self.cur.execute("select d from test") d2 = self.cur.fetchone()[0] self.assertEqual(d, d2) def CheckSqliteTimestamp(self): ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0) self.cur.execute("insert into test(ts) values (?)", (ts,)) self.cur.execute("select ts from test") ts2 = self.cur.fetchone()[0] self.assertEqual(ts, ts2) def CheckSqlTimestamp(self): # The date functions are only available in SQLite version 3.1 or later if sqlite.sqlite_version_info < (3, 1): return # SQLite's current_timestamp uses UTC time, while datetime.datetime.now() uses local time. now = datetime.datetime.now() self.cur.execute("insert into test(ts) values (current_timestamp)") self.cur.execute("select ts from test") ts = self.cur.fetchone()[0] self.assertEqual(type(ts), datetime.datetime) self.assertEqual(ts.year, now.year) def CheckDateTimeMicroseconds(self): ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0, 500000) self.cur.execute("insert into test(ts) values (?)", (ts,)) self.cur.execute("select ts from test") ts2 = self.cur.fetchone()[0] self.assertEqual(ts, ts2) def CheckDateTimeMicrosecondsFloatingPoint(self): ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0, 510241) self.cur.execute("insert into test(ts) values (?)", (ts,)) self.cur.execute("select ts from test") ts2 = self.cur.fetchone()[0] self.assertEqual(ts, ts2) def CheckDateTimeMiliSeconds(self): ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0, 500000) self.cur.execute("insert into test(ts) values ('2004-02-14 07:15:00.500')") self.cur.execute("select ts from test") ts2 = self.cur.fetchone()[0] self.assertEqual(ts, ts2) def suite(): sqlite_type_suite = unittest.makeSuite(SqliteTypeTests, "Check") decltypes_type_suite = unittest.makeSuite(DeclTypesTests, "Check") colnames_type_suite = unittest.makeSuite(ColNamesTests, "Check") adaptation_suite = unittest.makeSuite(ObjectAdaptationTests, "Check") bin_suite = unittest.makeSuite(BinaryConverterTests, "Check") date_suite = unittest.makeSuite(DateTimeTests, "Check") return unittest.TestSuite((sqlite_type_suite, decltypes_type_suite, colnames_type_suite, adaptation_suite, bin_suite, date_suite)) def test(): runner = unittest.TextTestRunner() runner.run(suite()) if __name__ == "__main__": test() pysqlite-2.7.0/lib/test/userfunctions.py000066400000000000000000000316411256035156500204150ustar00rootroot00000000000000#-*- coding: ISO-8859-1 -*- # pysqlite2/test/userfunctions.py: tests for user-defined functions and # aggregates. # # Copyright (C) 2005-2015 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. import unittest import pysqlite2.dbapi2 as sqlite def func_returntext(): return "foo" def func_returnunicode(): return u"bar" def func_returnint(): return 42 def func_returnfloat(): return 3.14 def func_returnnull(): return None def func_returnblob(): return buffer("blob") def func_raiseexception(): 5 // 0 def func_isstring(v): return type(v) is unicode def func_isint(v): return type(v) is int def func_isfloat(v): return type(v) is float def func_isnone(v): return type(v) is type(None) def func_isblob(v): return type(v) is buffer class AggrNoStep: def __init__(self): pass def finalize(self): return 1 class AggrNoFinalize: def __init__(self): pass def step(self, x): pass class AggrExceptionInInit: def __init__(self): 5 // 0 def step(self, x): pass def finalize(self): pass class AggrExceptionInStep: def __init__(self): pass def step(self, x): 5 // 0 def finalize(self): return 42 class AggrExceptionInFinalize: def __init__(self): pass def step(self, x): pass def finalize(self): 5 // 0 class AggrCheckType: def __init__(self): self.val = None def step(self, whichType, val): theType = {"str": unicode, "int": int, "float": float, "None": type(None), "blob": buffer} self.val = int(theType[whichType] is type(val)) def finalize(self): return self.val class AggrSum: def __init__(self): self.val = 0.0 def step(self, val): self.val += val def finalize(self): return self.val class FunctionTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") self.con.create_function("returntext", 0, func_returntext) self.con.create_function("returnunicode", 0, func_returnunicode) self.con.create_function("returnint", 0, func_returnint) self.con.create_function("returnfloat", 0, func_returnfloat) self.con.create_function("returnnull", 0, func_returnnull) self.con.create_function("returnblob", 0, func_returnblob) self.con.create_function("raiseexception", 0, func_raiseexception) self.con.create_function("isstring", 1, func_isstring) self.con.create_function("isint", 1, func_isint) self.con.create_function("isfloat", 1, func_isfloat) self.con.create_function("isnone", 1, func_isnone) self.con.create_function("isblob", 1, func_isblob) def tearDown(self): self.con.close() def CheckFuncErrorOnCreate(self): try: self.con.create_function("bla", -100, lambda x: 2*x) self.fail("should have raised an OperationalError") except sqlite.OperationalError: pass def CheckFuncRefCount(self): def getfunc(): def f(): return 1 return f f = getfunc() globals()["foo"] = f # self.con.create_function("reftest", 0, getfunc()) self.con.create_function("reftest", 0, f) cur = self.con.cursor() cur.execute("select reftest()") def CheckFuncReturnText(self): cur = self.con.cursor() cur.execute("select returntext()") val = cur.fetchone()[0] self.assertEqual(type(val), unicode) self.assertEqual(val, "foo") def CheckFuncReturnUnicode(self): cur = self.con.cursor() cur.execute("select returnunicode()") val = cur.fetchone()[0] self.assertEqual(type(val), unicode) self.assertEqual(val, u"bar") def CheckFuncReturnInt(self): cur = self.con.cursor() cur.execute("select returnint()") val = cur.fetchone()[0] self.assertEqual(type(val), int) self.assertEqual(val, 42) def CheckFuncReturnFloat(self): cur = self.con.cursor() cur.execute("select returnfloat()") val = cur.fetchone()[0] self.assertEqual(type(val), float) if val < 3.139 or val > 3.141: self.fail("wrong value") def CheckFuncReturnNull(self): cur = self.con.cursor() cur.execute("select returnnull()") val = cur.fetchone()[0] self.assertEqual(type(val), type(None)) self.assertEqual(val, None) def CheckFuncReturnBlob(self): cur = self.con.cursor() cur.execute("select returnblob()") val = cur.fetchone()[0] self.assertEqual(type(val), buffer) self.assertEqual(val, buffer("blob")) def CheckFuncException(self): cur = self.con.cursor() try: cur.execute("select raiseexception()") cur.fetchone() self.fail("should have raised OperationalError") except sqlite.OperationalError, e: self.assertEqual(e.args[0], 'user-defined function raised exception') def CheckParamString(self): cur = self.con.cursor() cur.execute("select isstring(?)", ("foo",)) val = cur.fetchone()[0] self.assertEqual(val, 1) def CheckParamInt(self): cur = self.con.cursor() cur.execute("select isint(?)", (42,)) val = cur.fetchone()[0] self.assertEqual(val, 1) def CheckParamFloat(self): cur = self.con.cursor() cur.execute("select isfloat(?)", (3.14,)) val = cur.fetchone()[0] self.assertEqual(val, 1) def CheckParamNone(self): cur = self.con.cursor() cur.execute("select isnone(?)", (None,)) val = cur.fetchone()[0] self.assertEqual(val, 1) def CheckParamBlob(self): cur = self.con.cursor() cur.execute("select isblob(?)", (buffer("blob"),)) val = cur.fetchone()[0] self.assertEqual(val, 1) class AggregateTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") cur = self.con.cursor() cur.execute(""" create table test( t text, i integer, f float, n, b blob ) """) cur.execute("insert into test(t, i, f, n, b) values (?, ?, ?, ?, ?)", ("foo", 5, 3.14, None, buffer("blob"),)) self.con.create_aggregate("nostep", 1, AggrNoStep) self.con.create_aggregate("nofinalize", 1, AggrNoFinalize) self.con.create_aggregate("excInit", 1, AggrExceptionInInit) self.con.create_aggregate("excStep", 1, AggrExceptionInStep) self.con.create_aggregate("excFinalize", 1, AggrExceptionInFinalize) self.con.create_aggregate("checkType", 2, AggrCheckType) self.con.create_aggregate("mysum", 1, AggrSum) def tearDown(self): #self.cur.close() #self.con.close() pass def CheckAggrErrorOnCreate(self): try: self.con.create_function("bla", -100, AggrSum) self.fail("should have raised an OperationalError") except sqlite.OperationalError: pass def CheckAggrNoStep(self): cur = self.con.cursor() try: cur.execute("select nostep(t) from test") self.fail("should have raised an AttributeError") except AttributeError, e: self.assertEqual(e.args[0], "AggrNoStep instance has no attribute 'step'") def CheckAggrNoFinalize(self): cur = self.con.cursor() try: cur.execute("select nofinalize(t) from test") val = cur.fetchone()[0] self.fail("should have raised an OperationalError") except sqlite.OperationalError, e: self.assertEqual(e.args[0], "user-defined aggregate's 'finalize' method raised error") def CheckAggrExceptionInInit(self): cur = self.con.cursor() try: cur.execute("select excInit(t) from test") val = cur.fetchone()[0] self.fail("should have raised an OperationalError") except sqlite.OperationalError, e: self.assertEqual(e.args[0], "user-defined aggregate's '__init__' method raised error") def CheckAggrExceptionInStep(self): cur = self.con.cursor() try: cur.execute("select excStep(t) from test") val = cur.fetchone()[0] self.fail("should have raised an OperationalError") except sqlite.OperationalError, e: self.assertEqual(e.args[0], "user-defined aggregate's 'step' method raised error") def CheckAggrExceptionInFinalize(self): cur = self.con.cursor() try: cur.execute("select excFinalize(t) from test") val = cur.fetchone()[0] self.fail("should have raised an OperationalError") except sqlite.OperationalError, e: self.assertEqual(e.args[0], "user-defined aggregate's 'finalize' method raised error") def CheckAggrCheckParamStr(self): cur = self.con.cursor() cur.execute("select checkType('str', ?)", ("foo",)) val = cur.fetchone()[0] self.assertEqual(val, 1) def CheckAggrCheckParamInt(self): cur = self.con.cursor() cur.execute("select checkType('int', ?)", (42,)) val = cur.fetchone()[0] self.assertEqual(val, 1) def CheckAggrCheckParamFloat(self): cur = self.con.cursor() cur.execute("select checkType('float', ?)", (3.14,)) val = cur.fetchone()[0] self.assertEqual(val, 1) def CheckAggrCheckParamNone(self): cur = self.con.cursor() cur.execute("select checkType('None', ?)", (None,)) val = cur.fetchone()[0] self.assertEqual(val, 1) def CheckAggrCheckParamBlob(self): cur = self.con.cursor() cur.execute("select checkType('blob', ?)", (buffer("blob"),)) val = cur.fetchone()[0] self.assertEqual(val, 1) def CheckAggrCheckAggrSum(self): cur = self.con.cursor() cur.execute("delete from test") cur.executemany("insert into test(i) values (?)", [(10,), (20,), (30,)]) cur.execute("select mysum(i) from test") val = cur.fetchone()[0] self.assertEqual(val, 60) def authorizer_cb(action, arg1, arg2, dbname, source): if action != sqlite.SQLITE_SELECT: return sqlite.SQLITE_DENY if arg2 == 'c2' or arg1 == 't2': return sqlite.SQLITE_DENY return sqlite.SQLITE_OK class AuthorizerTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") self.con.executescript(""" create table t1 (c1, c2); create table t2 (c1, c2); insert into t1 (c1, c2) values (1, 2); insert into t2 (c1, c2) values (4, 5); """) # For our security test: self.con.execute("select c2 from t2") self.con.set_authorizer(authorizer_cb) def tearDown(self): pass def CheckTableAccess(self): try: self.con.execute("select * from t2") except sqlite.DatabaseError, e: if not e.args[0].endswith("prohibited"): self.fail("wrong exception text: %s" % e.args[0]) return self.fail("should have raised an exception due to missing privileges") def CheckColumnAccess(self): try: self.con.execute("select c2 from t1") except sqlite.DatabaseError, e: if not e.args[0].endswith("prohibited"): self.fail("wrong exception text: %s" % e.args[0]) return self.fail("should have raised an exception due to missing privileges") def suite(): function_suite = unittest.makeSuite(FunctionTests, "Check") aggregate_suite = unittest.makeSuite(AggregateTests, "Check") authorizer_suite = unittest.makeSuite(AuthorizerTests, "Check") return unittest.TestSuite((function_suite, aggregate_suite, authorizer_suite)) def test(): runner = unittest.TextTestRunner() runner.run(suite()) if __name__ == "__main__": test() pysqlite-2.7.0/misc/000077500000000000000000000000001256035156500143355ustar00rootroot00000000000000pysqlite-2.7.0/misc/Makefile000066400000000000000000000045011256035156500157750ustar00rootroot00000000000000##################################################################### # Makefile originally written by Hans Oesterholt-Dijkema # Adapted and sanitized by Gerhard Haering for use with the pysqlite # project. # # It works with the free MSVC2003 toolkit as well as with MS Visual # Studio 2003. # # Makefile for SQLITE for use with GNU Make (MinGW/MSYS) # and the MSVC2003 free toolkit. Expects the MSVC Free SDK # installed along with the MSVC2003 free toolkit. # # Expects $INCLUDE, $LIB, $PATH set right for use with CL.EXE in # MSYS. NEEDS MSYS for clean: and install:, for making only: # Works also in the Visual C++ Toolkit 2003 Command Prompt, # provided %INCLUDE%, %LIB%, %PATH% are set accordingly. ##################################################################### CL=cl CLFLAGS=-O2 -Og -G7 LINK=link PREFIX=$$VCTOOLKITINSTALLDIR INCINST=$(PREFIX)/include LIBINST=$(PREFIX)/lib BININST=$(PREFIX)/bin SQLITE_OBJ = alter.o analyze.o attach.o auth.o btree.o build.o \ callback.o complete.o date.o \ delete.o expr.o func.o hash.o insert.o \ main.o opcodes.o os.o os_unix.o os_win.o \ pager.o parse.o pragma.o prepare.o printf.o random.o \ select.o table.o tokenize.o trigger.o update.o \ util.o vacuum.o \ vdbe.o vdbeapi.o vdbeaux.o vdbefifo.o vdbemem.o \ where.o utf.o legacy.o loadext.o vtab.o SQLITE_OBJ = alter.o analyze.o attach.o auth.o btmutex.o btree.o build.o callback.o \ complete.o date.o delete.o expr.o func.o hash.o insert.o journal.o \ legacy.o loadext.o main.o malloc.o mem1.o mem2.o mem3.o mutex.o \ mutex_w32.o opcodes.o os.o os_win.o pager.o parse.o pragma.o prepare.o \ printf.o random.o select.o table.o tokenize.o trigger.o update.o utf.o \ util.o vacuum.o vdbeapi.o vdbeaux.o vdbeblob.o vdbe.o vdbefifo.o vdbemem.o \ vtab.o where.o SQLITE_PRG_OBJ=shell.o all: sqlite3.lib @echo "done" clean: rm -f *.dll *.lib *.exp *.exe *.o sqlite3.exe: sqlite3.dll $(SQLITE_PRG_OBJ) $(LINK) -OUT:sqlite3.exe $(SQLITE_PRG_OBJ) sqlite3.lib sqlite3static.lib: $(SQLITE_OBJ) $(LINK) -LIB -OUT:sqlite3static.lib $(SQLITE_OBJ) sqlite3.dll: $(SQLITE_OBJ) $(LINK) -OUT:sqlite3.dll -dll -def:sqlite3.def $(SQLITE_OBJ) %.o: %.c $(CL) -c $(CLFLAGS) -Fo$@ $< pysqlite-2.7.0/misc/announce_template.txt000066400000000000000000000006761256035156500206100ustar00rootroot00000000000000pysqlite x.y.z released ======================= Release focus: minor bugfixes, minor new features. pysqlite is a DB-API 2.0-compliant database interface for SQLite. SQLite is a in-process library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine. Go to http://pysqlite.googlecode.com/ for downloads, online documentation and for reporting bugs. Changes ======= Compatibility ============= pysqlite-2.7.0/misc/eager.py000066400000000000000000000023161256035156500157740ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite3 Cursor = sqlite3.Cursor class EagerCursor(Cursor): def __init__(self, con): Cursor.__init__(self, con) self.rows = [] self.pos = 0 def execute(self, *args): sqlite3.Cursor.execute(self, *args) self.rows = Cursor.fetchall(self) self.pos = 0 def fetchone(self): try: row = self.rows[self.pos] self.pos += 1 return row except IndexError: return None def fetchmany(self, num=None): if num is None: num = self.arraysize result = self.rows[self.pos:self.pos+num] self.pos += num return result def fetchall(self): result = self.rows[self.pos:] self.pos = len(self.rows) return result def test(): con = sqlite3.connect(":memory:") cur = con.cursor(EagerCursor) cur.execute("create table test(foo)") cur.executemany("insert into test(foo) values (?)", [(3,), (4,), (5,)]) cur.execute("select * from test") print cur.fetchone() print cur.fetchone() print cur.fetchone() print cur.fetchone() print cur.fetchone() if __name__ == "__main__": test() pysqlite-2.7.0/misc/lru.py000077500000000000000000000104071256035156500155160ustar00rootroot00000000000000#-*- coding: ISO-8859-1 -*- # lru.py - a simple LRU cache, which will be rewritten in C later # # Copyright (C) 2004-2015 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. class Node: def __init__(self, key, data): self.key = key self.data = data self.count = 1 self.prev, self.next = None, None class Cache: def __init__(self, factory, maxlen): self.first, self.last = None, None self.maxlen = maxlen self.mapping = {} self.factory = factory def get(self, key): if key in self.mapping: nd = self.mapping[key] nd.count += 1 if nd.prev and nd.count > nd.prev.count: ptr = nd.prev while ptr.prev is not None and nd.count > ptr.prev.count: ptr = ptr.prev # Move nd before ptr if nd.next: nd.next.prev = nd.prev else: self.last = nd.prev if nd.prev: nd.prev.next = nd.next if ptr.prev: ptr.prev.next = nd else: self.first = nd save = nd.next nd.next = ptr nd.prev = ptr.prev if nd.prev is None: self.first = nd ptr.prev = nd #ptr.next = save else: if len(self.mapping) == self.maxlen: if self.last: nd = self.last self.mapping[self.last.key] = None del self.mapping[self.last.key] if nd.prev: nd.prev.next = None self.last = nd.prev nd.prev = None obj = self.factory(key) nd = Node(key, obj) nd.prev = self.last nd.next = None if self.last: self.last.next = nd else: self.first = nd self.last = nd self.mapping[key] = nd return nd.data def display(self): nd = self.first while nd: prevkey, nextkey = None, None if nd.prev: prevkey = nd.prev.key if nd.next: nextkey = nd.next.key print "%4s <- %4s -> %s\t(%i)" % (prevkey, nd.key, nextkey, nd.count) nd = nd.next if __name__ == "__main__": def create(s): return s import random cache = Cache(create, 5) if 1: chars = list("abcdefghijklmnopqrstuvwxyz") lst = [] for i in range(100): idx = random.randint(0, len(chars) - 1) what = chars[idx] lst.append(what) cache.get(chars[idx]) cache.display() #print "-" * 50 #print lst #print "-" * 50 else: lst = \ ['y', 'y', 'b', 'v', 'x', 'f', 'h', 'n', 'g', 'k', 'o', 'q', 'p', 'e', 'm', 'c', 't', 'y', 'c', 's', 'p', 's', 'j', 'm', \ 'u', 'f', 'z', 'x', 'v', 'r', 'w', 'e', 'm', 'd', 'w', 's', 'b', 'r', 'd', 'e', 'h', 'g', 'e', 't', 'p', 'b', 'e', 'i', \ 'g', 'n'] #lst = ['c', 'c', 'b', 'b', 'd', 'd', 'g', 'c', 'c', 'd'] for item in lst: cache.get(item) cache.display() pysqlite-2.7.0/misc/patterns.py000066400000000000000000000075401256035156500165550ustar00rootroot00000000000000from __future__ import with_statement from pysqlite2 import dbapi2 as sqlite3 from datetime import datetime, timedelta import time def read_modify_write(): # Open connection and create example schema and data. # In reality, open a database file instead of an in-memory database. con = sqlite3.connect(":memory:") cur = con.cursor() cur.executescript(""" create table test(id integer primary key, data); insert into test(data) values ('foo'); insert into test(data) values ('bar'); insert into test(data) values ('baz'); """) # The read part. There are two ways for fetching data using pysqlite. # 1. "Lazy-reading" # cur.execute("select ...") # for row in cur: # ... # # Advantage: Low memory consumption, good for large resultsets, data is # fetched on demand. # Disadvantage: Database locked as long as you iterate over cursor. # # 2. "Eager reading" # cur.fetchone() to fetch one row # cur.fetchall() to fetch all rows # Advantage: Locks cleared ASAP. # Disadvantage: fetchall() may build large lists. cur.execute("select id, data from test where id=?", (2,)) row = cur.fetchone() # Stupid way to modify the data column. lst = list(row) lst[1] = lst[1] + " & more" # This is the suggested recipe to modify data using pysqlite. We use # pysqlite's proprietary API to use the connection object as a context # manager. This is equivalent to the following code: # # try: # cur.execute("...") # except: # con.rollback() # raise # finally: # con.commit() # # This makes sure locks are cleared - either by commiting or rolling back # the transaction. # # If the rollback happens because of concurrency issues, you just have to # try again until it succeeds. Much more likely is that the rollback and # the raised exception happen because of other reasons, though (constraint # violation, etc.) - don't forget to roll back on errors. # # Or use this recipe. It's useful and gets everything done in two lines of # code. with con: cur.execute("update test set data=? where id=?", (lst[1], lst[0])) def delete_older_than(): # Use detect_types if you want to use date/time types in pysqlite. con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES) cur = con.cursor() # With "DEFAULT current_timestamp" we have SQLite fill the timestamp column # automatically. cur.executescript(""" create table test(id integer primary key, data, created timestamp default current_timestamp); """) with con: for i in range(3): cur.execute("insert into test(data) values ('foo')") time.sleep(1) # Delete older than certain interval # SQLite uses UTC time, so we need to create these timestamps in Python, too. with con: delete_before = datetime.utcnow() - timedelta(seconds=2) cur.execute("delete from test where created < ?", (delete_before,)) def modify_insert(): # Use a unique index and the REPLACE command to have the "insert if not # there, but modify if it is there" pattern. Race conditions are taken care # of by transactions. con = sqlite3.connect(":memory:") cur = con.cursor() cur.executescript(""" create table test(id integer primary key, name, age); insert into test(name, age) values ('Adam', 18); insert into test(name, age) values ('Eve', 21); create unique index idx_test_data_unique on test(name); """) with con: # Make Adam age 19 cur.execute("replace into test(name, age) values ('Adam', 19)") # Create new entry cur.execute("replace into test(name, age) values ('Abel', 3)") if __name__ == "__main__": read_modify_write() delete_older_than() modify_insert() pysqlite-2.7.0/mkwin32.py000077500000000000000000000046401256035156500152550ustar00rootroot00000000000000#!/usr/bin/env python # # Cross-compile and build pysqlite installers for win32 on Linux or Mac OS X. # # The way this works is very ugly, but hey, it *works*! And I didn't have to # reinvent the wheel using NSIS. import os import sys import urllib import zipfile from setup import get_amalgamation # Cross-compiler if sys.platform == "darwin": CC = "/usr/local/i386-mingw32-4.3.0/bin/i386-mingw32-gcc" LIBDIR = "lib.macosx-10.6-i386-2.5" STRIP = "/usr/local/i386-mingw32-4.3.0/bin/i386-mingw32-gcc --strip-all" else: CC = "/usr/bin/i586-mingw32msvc-gcc" LIBDIR = "lib.linux-i686-2.5" STRIP = "strip --strip-all" # Optimization settings OPT = "-O2" # pysqlite sources + SQLite amalgamation SRC = "src/module.c src/connection.c src/cursor.c src/cache.c src/microprotocols.c src/prepare_protocol.c src/statement.c src/util.c src/row.c amalgamation/sqlite3.c" # You will need to fetch these from # https://pyext-cross.pysqlite.googlecode.com/hg/ CROSS_TOOLS = "../pysqlite-pyext-cross" def execute(cmd): print cmd return os.system(cmd) def compile_module(pyver): VER = pyver.replace(".", "") INC = "%s/python%s/include" % (CROSS_TOOLS, VER) vars = locals() vars.update(globals()) cmd = '%(CC)s -mno-cygwin %(OPT)s -mdll -DMODULE_NAME=\\"pysqlite2._sqlite\\" -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_FTS3=1 -I amalgamation -I %(INC)s -I . %(SRC)s -L %(CROSS_TOOLS)s/python%(VER)s/libs -lpython%(VER)s -o build/%(LIBDIR)s/pysqlite2/_sqlite.pyd' % vars execute(cmd) execute("%(STRIP)s build/%(LIBDIR)s/pysqlite2/_sqlite.pyd" % vars) def main(): vars = locals() vars.update(globals()) get_amalgamation() for ver in ["2.5", "2.6", "2.7"]: execute("rm -rf build") # First, compile the host version. This is just to get the .py files in place. execute("python2.5 setup.py build") # Yes, now delete the host extension module. What a waste of time. os.unlink("build/%(LIBDIR)s/pysqlite2/_sqlite.so" % vars) # Cross-compile win32 extension module. compile_module(ver) # Prepare for target Python version. libdir_ver = LIBDIR[:-3] + ver os.rename("build/%(LIBDIR)s" % vars, "build/" + libdir_ver) # And create the installer! os.putenv("PYEXT_CROSS", CROSS_TOOLS) execute("python2.5 setup.py cross_bdist_wininst --skip-build --target-version=" + ver) if __name__ == "__main__": main() pysqlite-2.7.0/scripts/000077500000000000000000000000001256035156500150715ustar00rootroot00000000000000pysqlite-2.7.0/scripts/stress.py000066400000000000000000000036711256035156500167750ustar00rootroot00000000000000from pysqlite2 import dbapi2 as sqlite import os, threading def getcon(): #con = sqlite.connect("db", isolation_level=None, timeout=5.0) con = sqlite.connect(":memory:") cur = con.cursor() cur.execute("create table test(i, s)") for i in range(10): cur.execute("insert into test(i, s) values (?, 'asfd')", (i,)) con.commit() cur.close() return con def reader(what): con = getcon() while 1: cur = con.cursor() cur.execute("select i, s from test where i % 1000=?", (what,)) res = cur.fetchall() cur.close() con.close() def appender(): con = getcon() counter = 0 while 1: cur = con.cursor() cur.execute("insert into test(i, s) values (?, ?)", (counter, "foosadfasfasfsfafs")) #cur.execute("insert into test(foo) values (?)", (counter,)) counter += 1 if counter % 100 == 0: #print "appender committing", counter con.commit() cur.close() con.close() def updater(): con = getcon() counter = 0 while 1: cur = con.cursor() counter += 1 if counter % 5 == 0: cur.execute("update test set s='foo' where i % 50=0") #print "updater committing", counter con.commit() cur.close() con.close() def deleter(): con = getcon() counter = 0 while 1: cur = con.cursor() counter += 1 if counter % 5 == 0: #print "deleter committing", counter cur.execute("delete from test where i % 20=0") con.commit() cur.close() con.close() threads = [] for i in range(10): continue threads.append(threading.Thread(target=lambda: reader(i))) for i in range(5): threads.append(threading.Thread(target=appender)) #threads.append(threading.Thread(target=updater)) #threads.append(threading.Thread(target=deleter)) for t in threads: t.start() pysqlite-2.7.0/scripts/test-pysqlite000077500000000000000000000000751256035156500176500ustar00rootroot00000000000000#!/usr/bin/env python from pysqlite2.test import test test() pysqlite-2.7.0/setup.cfg000066400000000000000000000001021256035156500152140ustar00rootroot00000000000000[build_ext] libraries=sqlite3 # define=SQLITE_OMIT_LOAD_EXTENSION pysqlite-2.7.0/setup.py000066400000000000000000000171351256035156500151230ustar00rootroot00000000000000#-*- coding: ISO-8859-1 -*- # setup.py: the distutils script # # Copyright (C) 2004-2015 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. import commands import glob import os import re import shutil import sys from distutils.core import setup, Extension, Command from distutils.command.build import build from distutils.command.build_ext import build_ext import cross_bdist_wininst # If you need to change anything, it should be enough to change setup.cfg. sqlite = "sqlite" PYSQLITE_EXPERIMENTAL = False sources = ["src/module.c", "src/connection.c", "src/cursor.c", "src/cache.c", "src/microprotocols.c", "src/prepare_protocol.c", "src/statement.c", "src/util.c", "src/row.c"] if PYSQLITE_EXPERIMENTAL: sources.append("src/backup.c") include_dirs = [] library_dirs = [] libraries = [] runtime_library_dirs = [] extra_objects = [] define_macros = [] long_description = \ """Python interface to SQLite 3 pysqlite is an interface to the SQLite 3.x embedded relational database engine. It is almost fully compliant with the Python database API version 2.0 also exposes the unique features of SQLite.""" if sys.platform != "win32": define_macros.append(('MODULE_NAME', '"pysqlite2.dbapi2"')) else: define_macros.append(('MODULE_NAME', '\\"pysqlite2.dbapi2\\"')) class TestRunner(Command): description = "Runs the unit tests" user_options = [] def initialize_options(self): pass def finalize_options(self): pass def run(self): build_dir = "build/lib.linux-x86_64-%i.%i" % sys.version_info[:2] sys.path.append(build_dir) from pysqlite2 import test test.test() class DocBuilder(Command): description = "Builds the documentation" user_options = [] def initialize_options(self): pass def finalize_options(self): pass def run(self): try: shutil.rmtree("build/doc") except OSError: pass os.makedirs("build/doc") rc = os.system("sphinx-build doc/sphinx build/doc") if rc != 0: print "Is sphinx installed? If not, try 'sudo pip sphinx'." class AmalgamationBuilder(build): description = "Build a statically built pysqlite using the amalgamtion." def __init__(self, *args, **kwargs): MyBuildExt.amalgamation = True build.__init__(self, *args, **kwargs) class MyBuildExt(build_ext): amalgamation = False def _pkgconfig(self, flag, package): status, output = commands.getstatusoutput("pkg-config %s %s" % (flag, package)) return output def _pkgconfig_include_dirs(self, package): return [x.strip() for x in self._pkgconfig("--cflags-only-I", package).replace("-I", " ").split()] def _pkgconfig_library_dirs(self, package): return [x.strip() for x in self._pkgconfig("--libs-only-L", package).replace("-L", " ").split()] def build_extension(self, ext): if self.amalgamation: ext.define_macros += [ ("SQLITE_ENABLE_FTS5", "1"), ("SQLITE_ENABLE_RTREE", "1")] ext.sources.append("sqlite3.c") try: ext.include_dirs = self._pkgconfig_include_dirs("sqlite3") ext.library_dirs = self._pkgconfig_library_dirs("sqlite3") except OSError: pass # no pkg_config installed build_ext.build_extension(self, ext) def __setattr__(self, k, v): # Make sure we don't link against the SQLite library, no matter what setup.cfg says if self.amalgamation and k == "libraries": v = None self.__dict__[k] = v def get_setup_args(): PYSQLITE_VERSION = None version_re = re.compile('#define PYSQLITE_VERSION "(.*)"') f = open(os.path.join("src", "module.h")) for line in f: match = version_re.match(line) if match: PYSQLITE_VERSION = match.groups()[0] PYSQLITE_MINOR_VERSION = ".".join(PYSQLITE_VERSION.split('.')[:2]) break f.close() if not PYSQLITE_VERSION: print "Fatal error: PYSQLITE_VERSION could not be detected!" sys.exit(1) data_files = [("pysqlite2-doc", glob.glob("doc/*.html") \ + glob.glob("doc/*.txt") \ + glob.glob("doc/*.css")), ("pysqlite2-doc/code", glob.glob("doc/code/*.py"))] py_modules = ["sqlite"] setup_args = dict( name = "pysqlite", version = PYSQLITE_VERSION, description = "DB-API 2.0 interface for SQLite 3.x", long_description=long_description, author = "Gerhard Haering", author_email = "gh@ghaering.de", license = "zlib/libpng license", platforms = "ALL", url = "http://github.com/ghaering/pysqlite", # Description of the modules and packages in the distribution package_dir = {"pysqlite2": "lib"}, packages = ["pysqlite2", "pysqlite2.test"] + (["pysqlite2.test.py25"], [])[sys.version_info < (2, 5)], scripts=[], data_files = data_files, ext_modules = [Extension( name="pysqlite2._sqlite", sources=sources, include_dirs=include_dirs, library_dirs=library_dirs, runtime_library_dirs=runtime_library_dirs, libraries=libraries, extra_objects=extra_objects, define_macros=define_macros )], classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: zlib/libpng License", "Operating System :: MacOS :: MacOS X", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX", "Programming Language :: C", "Programming Language :: Python :: 2 :: Only", "Topic :: Database :: Database Engines/Servers", "Topic :: Software Development :: Libraries :: Python Modules", ], cmdclass = {"build_docs": DocBuilder} ) setup_args["cmdclass"].update({ "build_docs": DocBuilder, "test": TestRunner, "build_ext": MyBuildExt, "build_static": AmalgamationBuilder, "cross_bdist_wininst": cross_bdist_wininst.bdist_wininst }) return setup_args def main(): setup(**get_setup_args()) if __name__ == "__main__": main() pysqlite-2.7.0/src/000077500000000000000000000000001256035156500141715ustar00rootroot00000000000000pysqlite-2.7.0/src/backup.c000066400000000000000000000127521256035156500156110ustar00rootroot00000000000000/* backup.c - the backup type * * Copyright (C) 2010-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #include "module.h" #include "backup.h" #include "sqlitecompat.h" void pysqlite_backup_dealloc(pysqlite_Backup* self) { int rc; if (self->backup) { Py_BEGIN_ALLOW_THREADS rc = sqlite3_backup_finish(self->backup); Py_END_ALLOW_THREADS Py_DECREF(self->source_con); Py_DECREF(self->dest_con); self->backup = NULL; } Py_TYPE(self)->tp_free((PyObject*)self); } PyObject* pysqlite_backup_step(pysqlite_Backup* self, PyObject* args, PyObject* kwargs) { int npages; if (!PyArg_ParseTuple(args, "i", &npages)) { return NULL; } int rc = sqlite3_backup_step(self->backup, npages); if (rc == SQLITE_DONE) { Py_RETURN_TRUE; } else if (rc == SQLITE_OK) { Py_RETURN_FALSE; } else { PyErr_SetString(pysqlite_OperationalError, sqlite3_errmsg(self->source_con->db)); return NULL; } } static PyObject* pysqlite_backup_get_remaining(pysqlite_Backup* self, void* unused) { return Py_BuildValue("i", sqlite3_backup_remaining(self->backup)); } static PyObject* pysqlite_backup_get_pagecount(pysqlite_Backup* self, void* unused) { return Py_BuildValue("i", sqlite3_backup_remaining(self->backup)); } static PyGetSetDef pysqlite_backup_getset[] = { {"remaining", (getter)pysqlite_backup_get_remaining, (setter)0}, {"pagecount", (getter)pysqlite_backup_get_pagecount, (setter)0}, {NULL} }; static PyMethodDef pysqlite_backup_methods[] = { {"step", (PyCFunction)pysqlite_backup_step, METH_VARARGS, PyDoc_STR("Copy pages to backup database.")}, {NULL, NULL} }; PyTypeObject pysqlite_BackupType = { PyVarObject_HEAD_INIT(NULL, 0) MODULE_NAME ".Backup", /* tp_name */ sizeof(pysqlite_Backup), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pysqlite_backup_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ pysqlite_backup_methods, /* tp_methods */ 0, /* tp_members */ pysqlite_backup_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0 /* tp_free */ }; extern int pysqlite_backup_setup_types(void) { pysqlite_BackupType.tp_new = PyType_GenericNew; return PyType_Ready(&pysqlite_BackupType); } pysqlite-2.7.0/src/backup.h000066400000000000000000000025421256035156500156120ustar00rootroot00000000000000/* backup.h - definitions for the backup type * * Copyright (C) 2010-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #ifndef PYSQLITE_BACKUP_H #define PYSQLITE_BACKUP_H #include "Python.h" #include "sqlite3.h" #include "connection.h" typedef struct { PyObject_HEAD sqlite3_backup* backup; pysqlite_Connection* source_con; pysqlite_Connection* dest_con; } pysqlite_Backup; extern PyTypeObject pysqlite_BackupType; int pysqlite_backup_setup_types(void); #endif pysqlite-2.7.0/src/cache.c000066400000000000000000000312041256035156500154000ustar00rootroot00000000000000/* cache .c - a LRU cache * * Copyright (C) 2004-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #include "sqlitecompat.h" #include "cache.h" #include /* only used internally */ pysqlite_Node* pysqlite_new_node(PyObject* key, PyObject* data) { pysqlite_Node* node; node = (pysqlite_Node*) (pysqlite_NodeType.tp_alloc(&pysqlite_NodeType, 0)); if (!node) { return NULL; } Py_INCREF(key); node->key = key; Py_INCREF(data); node->data = data; node->prev = NULL; node->next = NULL; return node; } void pysqlite_node_dealloc(pysqlite_Node* self) { Py_DECREF(self->key); Py_DECREF(self->data); Py_TYPE(self)->tp_free((PyObject*)self); } int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs) { PyObject* factory; int size = 10; self->factory = NULL; if (!PyArg_ParseTuple(args, "O|i", &factory, &size)) { return -1; } /* minimum cache size is 5 entries */ if (size < 5) { size = 5; } self->size = size; self->first = NULL; self->last = NULL; self->mapping = PyDict_New(); if (!self->mapping) { return -1; } Py_INCREF(factory); self->factory = factory; self->decref_factory = 1; return 0; } void pysqlite_cache_dealloc(pysqlite_Cache* self) { pysqlite_Node* node; pysqlite_Node* delete_node; if (!self->factory) { /* constructor failed, just get out of here */ return; } /* iterate over all nodes and deallocate them */ node = self->first; while (node) { delete_node = node; node = node->next; Py_DECREF(delete_node); } if (self->decref_factory) { Py_DECREF(self->factory); } Py_DECREF(self->mapping); Py_TYPE(self)->tp_free((PyObject*)self); } PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args) { PyObject* key = args; pysqlite_Node* node; pysqlite_Node* ptr; PyObject* data; node = (pysqlite_Node*)PyDict_GetItem(self->mapping, key); if (node) { /* an entry for this key already exists in the cache */ /* increase usage counter of the node found */ if (node->count < LONG_MAX) { node->count++; } /* if necessary, reorder entries in the cache by swapping positions */ if (node->prev && node->count > node->prev->count) { ptr = node->prev; while (ptr->prev && node->count > ptr->prev->count) { ptr = ptr->prev; } if (node->next) { node->next->prev = node->prev; } else { self->last = node->prev; } if (node->prev) { node->prev->next = node->next; } if (ptr->prev) { ptr->prev->next = node; } else { self->first = node; } node->next = ptr; node->prev = ptr->prev; if (!node->prev) { self->first = node; } ptr->prev = node; } } else { /* There is no entry for this key in the cache, yet. We'll insert a new * entry in the cache, and make space if necessary by throwing the * least used item out of the cache. */ if (PyDict_Size(self->mapping) == self->size) { if (self->last) { node = self->last; if (PyDict_DelItem(self->mapping, self->last->key) != 0) { return NULL; } if (node->prev) { node->prev->next = NULL; } self->last = node->prev; node->prev = NULL; Py_DECREF(node); } } data = PyObject_CallFunction(self->factory, "O", key); if (!data) { return NULL; } node = pysqlite_new_node(key, data); if (!node) { return NULL; } node->prev = self->last; Py_DECREF(data); if (PyDict_SetItem(self->mapping, key, (PyObject*)node) != 0) { Py_DECREF(node); return NULL; } if (self->last) { self->last->next = node; } else { self->first = node; } self->last = node; } Py_INCREF(node->data); return node->data; } PyObject* pysqlite_cache_display(pysqlite_Cache* self, PyObject* args) { pysqlite_Node* ptr; PyObject* prevkey; PyObject* nextkey; PyObject* fmt_args; PyObject* template; PyObject* display_str; ptr = self->first; while (ptr) { if (ptr->prev) { prevkey = ptr->prev->key; } else { prevkey = Py_None; } Py_INCREF(prevkey); if (ptr->next) { nextkey = ptr->next->key; } else { nextkey = Py_None; } Py_INCREF(nextkey); fmt_args = Py_BuildValue("OOO", prevkey, ptr->key, nextkey); if (!fmt_args) { return NULL; } template = PyString_FromString("%s <- %s ->%s\n"); if (!template) { Py_DECREF(fmt_args); return NULL; } display_str = PyString_Format(template, fmt_args); Py_DECREF(template); Py_DECREF(fmt_args); if (!display_str) { return NULL; } PyObject_Print(display_str, stdout, Py_PRINT_RAW); Py_DECREF(display_str); Py_DECREF(prevkey); Py_DECREF(nextkey); ptr = ptr->next; } Py_INCREF(Py_None); return Py_None; } static PyMethodDef cache_methods[] = { {"get", (PyCFunction)pysqlite_cache_get, METH_O, PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")}, {"display", (PyCFunction)pysqlite_cache_display, METH_NOARGS, PyDoc_STR("For debugging only.")}, {NULL, NULL} }; PyTypeObject pysqlite_NodeType = { PyVarObject_HEAD_INIT(NULL, 0) MODULE_NAME "Node", /* tp_name */ sizeof(pysqlite_Node), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pysqlite_node_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0 /* tp_free */ }; PyTypeObject pysqlite_CacheType = { PyVarObject_HEAD_INIT(NULL, 0) MODULE_NAME ".Cache", /* tp_name */ sizeof(pysqlite_Cache), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pysqlite_cache_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ cache_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)pysqlite_cache_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0 /* tp_free */ }; extern int pysqlite_cache_setup_types(void) { int rc; pysqlite_NodeType.tp_new = PyType_GenericNew; pysqlite_CacheType.tp_new = PyType_GenericNew; rc = PyType_Ready(&pysqlite_NodeType); if (rc < 0) { return rc; } rc = PyType_Ready(&pysqlite_CacheType); return rc; } pysqlite-2.7.0/src/cache.h000066400000000000000000000044331256035156500154110ustar00rootroot00000000000000/* cache.h - definitions for the LRU cache * * Copyright (C) 2004-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #ifndef PYSQLITE_CACHE_H #define PYSQLITE_CACHE_H #include "Python.h" /* The LRU cache is implemented as a combination of a doubly-linked with a * dictionary. The list items are of type 'Node' and the dictionary has the * nodes as values. */ typedef struct _pysqlite_Node { PyObject_HEAD PyObject* key; PyObject* data; long count; struct _pysqlite_Node* prev; struct _pysqlite_Node* next; } pysqlite_Node; typedef struct { PyObject_HEAD int size; /* a dictionary mapping keys to Node entries */ PyObject* mapping; /* the factory callable */ PyObject* factory; pysqlite_Node* first; pysqlite_Node* last; /* if set, decrement the factory function when the Cache is deallocated. * this is almost always desirable, but not in the pysqlite context */ int decref_factory; } pysqlite_Cache; extern PyTypeObject pysqlite_NodeType; extern PyTypeObject pysqlite_CacheType; int pysqlite_node_init(pysqlite_Node* self, PyObject* args, PyObject* kwargs); void pysqlite_node_dealloc(pysqlite_Node* self); int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs); void pysqlite_cache_dealloc(pysqlite_Cache* self); PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args); int pysqlite_cache_setup_types(void); #endif pysqlite-2.7.0/src/connection.c000066400000000000000000001452231256035156500165030ustar00rootroot00000000000000/* connection.c - the connection type * * Copyright (C) 2004-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #include "cache.h" #include "module.h" #include "connection.h" #include "statement.h" #include "cursor.h" #include "prepare_protocol.h" #include "util.h" #include "sqlitecompat.h" #ifdef PYSQLITE_EXPERIMENTAL #include "backup.h" #endif #include "pythread.h" #define ACTION_FINALIZE 1 #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 void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self); static void _sqlite3_result_error(sqlite3_context* ctx, const char* errmsg, int len) { /* in older SQLite versions, calling sqlite3_result_error in callbacks * triggers a bug in SQLite that leads either to irritating results or * segfaults, depending on the SQLite version */ #if SQLITE_VERSION_NUMBER >= 3003003 sqlite3_result_error(ctx, errmsg, len); #else PyErr_SetString(pysqlite_OperationalError, errmsg); #endif } int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL}; PyObject* database; int detect_types = 0; PyObject* isolation_level = NULL; PyObject* factory = NULL; int check_same_thread = 1; int cached_statements = 100; double timeout = 5.0; int rc; PyObject* class_attr = NULL; PyObject* class_attr_str = NULL; int is_apsw_connection = 0; PyObject* database_utf8; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|diOiOi", kwlist, &database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements)) { return -1; } self->initialized = 1; self->begin_statement = NULL; self->statement_cache = NULL; self->statements = NULL; self->cursors = NULL; Py_INCREF(Py_None); self->row_factory = Py_None; Py_INCREF(&PyUnicode_Type); self->text_factory = (PyObject*)&PyUnicode_Type; if (PyString_Check(database) || PyUnicode_Check(database)) { if (PyString_Check(database)) { database_utf8 = database; Py_INCREF(database_utf8); } else { database_utf8 = PyUnicode_AsUTF8String(database); if (!database_utf8) { return -1; } } Py_BEGIN_ALLOW_THREADS rc = sqlite3_open(PyString_AsString(database_utf8), &self->db); Py_END_ALLOW_THREADS Py_DECREF(database_utf8); if (rc != SQLITE_OK) { _pysqlite_seterror(self->db, NULL); return -1; } } else { /* Create a pysqlite connection from a APSW connection */ class_attr = PyObject_GetAttrString(database, "__class__"); if (class_attr) { class_attr_str = PyObject_Str(class_attr); if (class_attr_str) { if (strcmp(PyString_AsString(class_attr_str), "") == 0) { /* In the APSW Connection object, the first entry after * PyObject_HEAD is the sqlite3* we want to get hold of. * Luckily, this is the same layout as we have in our * pysqlite_Connection */ self->db = ((pysqlite_Connection*)database)->db; Py_INCREF(database); self->apsw_connection = database; is_apsw_connection = 1; } } } Py_XDECREF(class_attr_str); Py_XDECREF(class_attr); if (!is_apsw_connection) { PyErr_SetString(PyExc_ValueError, "database parameter must be string or APSW Connection object"); return -1; } } if (!isolation_level) { isolation_level = PyString_FromString(""); if (!isolation_level) { return -1; } } else { Py_INCREF(isolation_level); } self->isolation_level = NULL; pysqlite_connection_set_isolation_level(self, isolation_level); Py_DECREF(isolation_level); self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)&pysqlite_CacheType, "Oi", self, cached_statements); if (PyErr_Occurred()) { return -1; } self->created_statements = 0; self->created_cursors = 0; /* Create lists of weak references to statements/cursors */ self->statements = PyList_New(0); self->cursors = PyList_New(0); if (!self->statements || !self->cursors) { return -1; } /* By default, the Cache class INCREFs the factory in its initializer, and * decrefs it in its deallocator method. Since this would create a circular * reference here, we're breaking it by decrementing self, and telling the * cache class to not decref the factory (self) in its deallocator. */ self->statement_cache->decref_factory = 0; Py_DECREF(self); self->inTransaction = 0; self->detect_types = detect_types; self->timeout = timeout; (void)sqlite3_busy_timeout(self->db, (int)(timeout*1000)); #ifdef WITH_THREAD self->thread_ident = PyThread_get_thread_ident(); #endif self->check_same_thread = check_same_thread; self->function_pinboard = PyDict_New(); if (!self->function_pinboard) { return -1; } self->collations = PyDict_New(); if (!self->collations) { return -1; } self->Warning = pysqlite_Warning; self->Error = pysqlite_Error; self->InterfaceError = pysqlite_InterfaceError; self->DatabaseError = pysqlite_DatabaseError; self->DataError = pysqlite_DataError; self->OperationalError = pysqlite_OperationalError; self->IntegrityError = pysqlite_IntegrityError; self->InternalError = pysqlite_InternalError; self->ProgrammingError = pysqlite_ProgrammingError; self->NotSupportedError = pysqlite_NotSupportedError; return 0; } /* Empty the entire statement cache of this connection */ void pysqlite_flush_statement_cache(pysqlite_Connection* self) { pysqlite_Node* node; pysqlite_Statement* statement; node = self->statement_cache->first; while (node) { statement = (pysqlite_Statement*)(node->data); (void)pysqlite_statement_finalize(statement); node = node->next; } Py_DECREF(self->statement_cache); self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)&pysqlite_CacheType, "O", self); Py_DECREF(self); self->statement_cache->decref_factory = 0; } /* action in (ACTION_RESET, ACTION_FINALIZE) */ void pysqlite_do_all_statements(pysqlite_Connection* self, int action, int reset_cursors) { int i; PyObject* weakref; PyObject* statement; pysqlite_Cursor* cursor; for (i = 0; i < PyList_Size(self->statements); i++) { weakref = PyList_GetItem(self->statements, i); statement = PyWeakref_GetObject(weakref); if (statement != Py_None) { if (action == ACTION_RESET) { (void)pysqlite_statement_reset((pysqlite_Statement*)statement); } else { (void)pysqlite_statement_finalize((pysqlite_Statement*)statement); } } } 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) { PyObject* ret = NULL; Py_XDECREF(self->statement_cache); /* Clean up if user has not called .close() explicitly. */ if (self->db) { Py_BEGIN_ALLOW_THREADS sqlite3_close(self->db); Py_END_ALLOW_THREADS } else if (self->apsw_connection) { ret = PyObject_CallMethod(self->apsw_connection, "close", ""); Py_XDECREF(ret); Py_XDECREF(self->apsw_connection); } if (self->begin_statement) { PyMem_Free(self->begin_statement); } Py_XDECREF(self->isolation_level); Py_XDECREF(self->function_pinboard); Py_XDECREF(self->row_factory); Py_XDECREF(self->text_factory); Py_XDECREF(self->collations); Py_XDECREF(self->statements); Py_XDECREF(self->cursors); 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) { static char *kwlist[] = {"factory", NULL, NULL}; PyObject* factory = NULL; PyObject* cursor; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, &factory)) { return NULL; } if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } if (factory == NULL) { factory = (PyObject*)&pysqlite_CursorType; } cursor = PyObject_CallFunction(factory, "O", self); _pysqlite_drop_unused_cursor_references(self); if (cursor && self->row_factory != Py_None) { Py_XDECREF(((pysqlite_Cursor*)cursor)->row_factory); Py_INCREF(self->row_factory); ((pysqlite_Cursor*)cursor)->row_factory = self->row_factory; } return cursor; } #ifdef PYSQLITE_EXPERIMENTAL PyObject* pysqlite_connection_backup(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = {"dest_db", "source_name", "dest_db_name", NULL, NULL}; char* source_name; char* dest_name; pysqlite_Connection* dest_con; pysqlite_Backup* backup; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!ss", kwlist, &pysqlite_ConnectionType, &dest_con, &source_name, &dest_name)) { return NULL; } if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } backup = PyObject_New(pysqlite_Backup, &pysqlite_BackupType); if (!backup) { return NULL; } Py_INCREF(self); backup->source_con = self; Py_INCREF(dest_con); backup->dest_con = dest_con; backup->backup = sqlite3_backup_init(dest_con->db, dest_name, self->db, source_name); return (PyObject*)backup; } #endif PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args) { PyObject* ret; int rc; if (!pysqlite_check_thread(self)) { return NULL; } pysqlite_do_all_statements(self, ACTION_FINALIZE, 1); if (self->db) { if (self->apsw_connection) { ret = PyObject_CallMethod(self->apsw_connection, "close", ""); Py_XDECREF(ret); Py_XDECREF(self->apsw_connection); self->apsw_connection = NULL; self->db = NULL; } else { Py_BEGIN_ALLOW_THREADS rc = sqlite3_close(self->db); Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { _pysqlite_seterror(self->db, NULL); return NULL; } else { self->db = NULL; } } } Py_INCREF(Py_None); return Py_None; } /* * Checks if a connection object is usable (i. e. not closed). * * 0 => error; 1 => ok */ int pysqlite_check_connection(pysqlite_Connection* con) { if (!con->initialized) { PyErr_SetString(pysqlite_ProgrammingError, "Base Connection.__init__ not called."); return 0; } if (!con->db) { PyErr_SetString(pysqlite_ProgrammingError, "Cannot operate on a closed database."); return 0; } else { return 1; } } PyObject* _pysqlite_connection_begin(pysqlite_Connection* self) { int rc; const char* tail; sqlite3_stmt* statement; Py_BEGIN_ALLOW_THREADS rc = sqlite3_prepare(self->db, self->begin_statement, -1, &statement, &tail); Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { _pysqlite_seterror(self->db, statement); goto error; } rc = pysqlite_step(statement, self); if (rc == SQLITE_DONE) { self->inTransaction = 1; } else { _pysqlite_seterror(self->db, statement); } Py_BEGIN_ALLOW_THREADS rc = sqlite3_finalize(statement); Py_END_ALLOW_THREADS if (rc != SQLITE_OK && !PyErr_Occurred()) { _pysqlite_seterror(self->db, NULL); } error: if (PyErr_Occurred()) { return NULL; } else { Py_INCREF(Py_None); return Py_None; } } PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args) { int rc; const char* tail; sqlite3_stmt* statement; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } if (self->inTransaction) { pysqlite_do_all_statements(self, ACTION_RESET, 0); Py_BEGIN_ALLOW_THREADS rc = sqlite3_prepare(self->db, "COMMIT", -1, &statement, &tail); Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { _pysqlite_seterror(self->db, NULL); goto error; } rc = pysqlite_step(statement, self); if (rc == SQLITE_DONE) { self->inTransaction = 0; } else { _pysqlite_seterror(self->db, statement); } Py_BEGIN_ALLOW_THREADS rc = sqlite3_finalize(statement); Py_END_ALLOW_THREADS if (rc != SQLITE_OK && !PyErr_Occurred()) { _pysqlite_seterror(self->db, NULL); } } error: if (PyErr_Occurred()) { return NULL; } else { Py_INCREF(Py_None); return Py_None; } } PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args) { int rc; const char* tail; sqlite3_stmt* statement; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } if (self->inTransaction) { pysqlite_do_all_statements(self, ACTION_RESET, 1); Py_BEGIN_ALLOW_THREADS rc = sqlite3_prepare(self->db, "ROLLBACK", -1, &statement, &tail); Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { _pysqlite_seterror(self->db, NULL); goto error; } rc = pysqlite_step(statement, self); if (rc == SQLITE_DONE) { self->inTransaction = 0; } else { _pysqlite_seterror(self->db, statement); } Py_BEGIN_ALLOW_THREADS rc = sqlite3_finalize(statement); Py_END_ALLOW_THREADS if (rc != SQLITE_OK && !PyErr_Occurred()) { _pysqlite_seterror(self->db, NULL); } } error: if (PyErr_Occurred()) { return NULL; } else { Py_INCREF(Py_None); return Py_None; } } void _pysqlite_set_result(sqlite3_context* context, PyObject* py_val) { long longval; const char* buffer; Py_ssize_t buflen; PyObject* stringval; if ((!py_val) || PyErr_Occurred()) { sqlite3_result_null(context); } else if (py_val == Py_None) { sqlite3_result_null(context); } else if (PyInt_Check(py_val)) { longval = PyInt_AsLong(py_val); sqlite3_result_int64(context, (PY_LONG_LONG)longval); } else if (PyFloat_Check(py_val)) { sqlite3_result_double(context, PyFloat_AsDouble(py_val)); } else if (PyBuffer_Check(py_val)) { if (PyObject_AsCharBuffer(py_val, &buffer, &buflen) != 0) { PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer"); } else { sqlite3_result_blob(context, buffer, buflen, SQLITE_TRANSIENT); } } else if (PyString_Check(py_val)) { sqlite3_result_text(context, PyString_AsString(py_val), -1, SQLITE_TRANSIENT); } else if (PyUnicode_Check(py_val)) { stringval = PyUnicode_AsUTF8String(py_val); if (stringval) { sqlite3_result_text(context, PyString_AsString(stringval), -1, SQLITE_TRANSIENT); Py_DECREF(stringval); } } else { /* TODO: raise error */ } } PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_value** argv) { PyObject* args; int i; sqlite3_value* cur_value; PyObject* cur_py_value; const char* val_str; PY_LONG_LONG val_int; Py_ssize_t buflen; void* raw_buffer; args = PyTuple_New(argc); if (!args) { return NULL; } for (i = 0; i < argc; i++) { cur_value = argv[i]; switch (sqlite3_value_type(argv[i])) { case SQLITE_INTEGER: val_int = sqlite3_value_int64(cur_value); cur_py_value = PyInt_FromLong((long)val_int); break; case SQLITE_FLOAT: cur_py_value = PyFloat_FromDouble(sqlite3_value_double(cur_value)); break; case SQLITE_TEXT: val_str = (const char*)sqlite3_value_text(cur_value); cur_py_value = PyUnicode_DecodeUTF8(val_str, strlen(val_str), NULL); /* TODO: have a way to show errors here */ if (!cur_py_value) { PyErr_Clear(); Py_INCREF(Py_None); cur_py_value = Py_None; } break; case SQLITE_BLOB: buflen = sqlite3_value_bytes(cur_value); cur_py_value = PyBuffer_New(buflen); if (!cur_py_value) { break; } if (PyObject_AsWriteBuffer(cur_py_value, &raw_buffer, &buflen)) { Py_DECREF(cur_py_value); cur_py_value = NULL; break; } memcpy(raw_buffer, sqlite3_value_blob(cur_value), buflen); break; case SQLITE_NULL: default: Py_INCREF(Py_None); cur_py_value = Py_None; } if (!cur_py_value) { Py_DECREF(args); return NULL; } PyTuple_SetItem(args, i, cur_py_value); } return args; } void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value** argv) { PyObject* args; PyObject* py_func; PyObject* py_retval = NULL; #ifdef WITH_THREAD PyGILState_STATE threadstate; threadstate = PyGILState_Ensure(); #endif py_func = (PyObject*)sqlite3_user_data(context); args = _pysqlite_build_py_params(context, argc, argv); if (args) { py_retval = PyObject_CallObject(py_func, args); Py_DECREF(args); } if (py_retval) { _pysqlite_set_result(context, py_retval); Py_DECREF(py_retval); } else { if (_enable_callback_tracebacks) { PyErr_Print(); } else { PyErr_Clear(); } _sqlite3_result_error(context, "user-defined function raised exception", -1); } #ifdef WITH_THREAD PyGILState_Release(threadstate); #endif } static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_value** params) { PyObject* args; PyObject* function_result = NULL; PyObject* aggregate_class; PyObject** aggregate_instance; PyObject* stepmethod = NULL; #ifdef WITH_THREAD PyGILState_STATE threadstate; threadstate = PyGILState_Ensure(); #endif aggregate_class = (PyObject*)sqlite3_user_data(context); aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*)); if (*aggregate_instance == 0) { *aggregate_instance = PyObject_CallFunction(aggregate_class, ""); if (PyErr_Occurred()) { *aggregate_instance = 0; if (_enable_callback_tracebacks) { PyErr_Print(); } else { PyErr_Clear(); } _sqlite3_result_error(context, "user-defined aggregate's '__init__' method raised error", -1); goto error; } } stepmethod = PyObject_GetAttrString(*aggregate_instance, "step"); if (!stepmethod) { goto error; } args = _pysqlite_build_py_params(context, argc, params); if (!args) { goto error; } function_result = PyObject_CallObject(stepmethod, args); Py_DECREF(args); if (!function_result) { if (_enable_callback_tracebacks) { PyErr_Print(); } else { PyErr_Clear(); } _sqlite3_result_error(context, "user-defined aggregate's 'step' method raised error", -1); } error: Py_XDECREF(stepmethod); Py_XDECREF(function_result); #ifdef WITH_THREAD PyGILState_Release(threadstate); #endif } void _pysqlite_final_callback(sqlite3_context* context) { PyObject* function_result = NULL; PyObject** aggregate_instance; PyObject* aggregate_class; #ifdef WITH_THREAD PyGILState_STATE threadstate; threadstate = PyGILState_Ensure(); #endif aggregate_class = (PyObject*)sqlite3_user_data(context); aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*)); if (!*aggregate_instance) { /* this branch is executed if there was an exception in the aggregate's * __init__ */ goto error; } function_result = PyObject_CallMethod(*aggregate_instance, "finalize", ""); if (!function_result) { if (_enable_callback_tracebacks) { PyErr_Print(); } else { PyErr_Clear(); } _sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1); } else { _pysqlite_set_result(context, function_result); } error: Py_XDECREF(*aggregate_instance); Py_XDECREF(function_result); #ifdef WITH_THREAD PyGILState_Release(threadstate); #endif } static void _pysqlite_drop_unused_statement_references(pysqlite_Connection* self) { PyObject* new_list; PyObject* weakref; int i; /* we only need to do this once in a while */ if (self->created_statements++ < 200) { return; } self->created_statements = 0; new_list = PyList_New(0); if (!new_list) { return; } for (i = 0; i < PyList_Size(self->statements); i++) { weakref = PyList_GetItem(self->statements, i); if (PyWeakref_GetObject(weakref) != Py_None) { if (PyList_Append(new_list, weakref) != 0) { Py_DECREF(new_list); return; } } } Py_DECREF(self->statements); 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) { static char *kwlist[] = {"name", "narg", "func", NULL, NULL}; PyObject* func; char* name; int narg; int rc; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO", kwlist, &name, &narg, &func)) { return NULL; } rc = sqlite3_create_function(self->db, name, narg, SQLITE_UTF8, (void*)func, _pysqlite_func_callback, NULL, NULL); if (rc != SQLITE_OK) { /* Workaround for SQLite bug: no error code or string is available here */ PyErr_SetString(pysqlite_OperationalError, "Error creating function"); return NULL; } else { if (PyDict_SetItem(self->function_pinboard, func, Py_None) == -1) return NULL; Py_INCREF(Py_None); return Py_None; } } PyObject* pysqlite_connection_create_aggregate(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { PyObject* aggregate_class; int n_arg; char* name; static char *kwlist[] = { "name", "n_arg", "aggregate_class", NULL }; int rc; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO:create_aggregate", kwlist, &name, &n_arg, &aggregate_class)) { return NULL; } rc = sqlite3_create_function(self->db, name, n_arg, SQLITE_UTF8, (void*)aggregate_class, 0, &_pysqlite_step_callback, &_pysqlite_final_callback); if (rc != SQLITE_OK) { /* Workaround for SQLite bug: no error code or string is available here */ PyErr_SetString(pysqlite_OperationalError, "Error creating aggregate"); return NULL; } else { if (PyDict_SetItem(self->function_pinboard, aggregate_class, Py_None) == -1) return NULL; Py_INCREF(Py_None); return Py_None; } } static int _authorizer_callback(void* user_arg, int action, const char* arg1, const char* arg2 , const char* dbname, const char* access_attempt_source) { PyObject *ret; int rc; #ifdef WITH_THREAD PyGILState_STATE gilstate; gilstate = PyGILState_Ensure(); #endif ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source); if (!ret) { if (_enable_callback_tracebacks) { PyErr_Print(); } else { PyErr_Clear(); } rc = SQLITE_DENY; } else { if (PyInt_Check(ret)) { rc = (int)PyInt_AsLong(ret); } else { rc = SQLITE_DENY; } Py_DECREF(ret); } #ifdef WITH_THREAD PyGILState_Release(gilstate); #endif return rc; } static int _progress_handler(void* user_arg) { int rc; PyObject *ret; #ifdef WITH_THREAD PyGILState_STATE gilstate; gilstate = PyGILState_Ensure(); #endif ret = PyObject_CallFunction((PyObject*)user_arg, ""); if (!ret) { if (_enable_callback_tracebacks) { PyErr_Print(); } else { PyErr_Clear(); } /* abort query if error occurred */ rc = 1; } else { rc = (int)PyObject_IsTrue(ret); Py_DECREF(ret); } #ifdef WITH_THREAD PyGILState_Release(gilstate); #endif return rc; } static PyObject* pysqlite_connection_get_limit(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { int limit_id, new_val; static char *kwlist[] = { "limit_id", NULL }; int retval; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_limit", kwlist, &limit_id)) { return NULL; } retval = sqlite3_limit(self->db, limit_id, -1); return PyInt_FromLong(retval); } static PyObject* pysqlite_connection_set_limit(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { int limit_id, new_val; static char *kwlist[] = { "limit_id", "new_val", NULL }; int retval; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_limit", kwlist, &limit_id, &new_val)) { return NULL; } retval = sqlite3_limit(self->db, limit_id, new_val); return PyInt_FromLong(retval); } static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { PyObject* authorizer_cb; static char *kwlist[] = { "authorizer_callback", NULL }; int rc; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:set_authorizer", kwlist, &authorizer_cb)) { return NULL; } rc = sqlite3_set_authorizer(self->db, _authorizer_callback, (void*)authorizer_cb); if (rc != SQLITE_OK) { PyErr_SetString(pysqlite_OperationalError, "Error setting authorizer callback"); return NULL; } else { if (PyDict_SetItem(self->function_pinboard, authorizer_cb, Py_None) == -1) return NULL; Py_INCREF(Py_None); return Py_None; } } static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { PyObject* progress_handler; int n; 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", kwlist, &progress_handler, &n)) { return NULL; } if (progress_handler == Py_None) { /* None clears the progress handler previously set */ sqlite3_progress_handler(self->db, 0, 0, (void*)0); } else { sqlite3_progress_handler(self->db, n, _progress_handler, progress_handler); if (PyDict_SetItem(self->function_pinboard, progress_handler, Py_None) == -1) return NULL; } Py_INCREF(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) { #ifdef WITH_THREAD if (self->check_same_thread) { if (PyThread_get_thread_ident() != self->thread_ident) { PyErr_Format(pysqlite_ProgrammingError, "SQLite objects created in a thread can only be used in that same thread." "The object was created in thread id %ld and this is thread id %ld", self->thread_ident, PyThread_get_thread_ident()); return 0; } } #endif return 1; } static PyObject* pysqlite_connection_get_isolation_level(pysqlite_Connection* self, void* unused) { Py_INCREF(self->isolation_level); return self->isolation_level; } static PyObject* pysqlite_connection_get_total_changes(pysqlite_Connection* self, void* unused) { if (!pysqlite_check_connection(self)) { return NULL; } else { return Py_BuildValue("i", sqlite3_total_changes(self->db)); } } static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level) { PyObject* res; PyObject* begin_statement; char* begin_statement_str; Py_XDECREF(self->isolation_level); if (self->begin_statement) { PyMem_Free(self->begin_statement); self->begin_statement = NULL; } if (isolation_level == Py_None) { Py_INCREF(Py_None); self->isolation_level = Py_None; res = pysqlite_connection_commit(self, NULL); if (!res) { return -1; } Py_DECREF(res); self->inTransaction = 0; } else { Py_INCREF(isolation_level); self->isolation_level = isolation_level; begin_statement = PyString_FromString("BEGIN "); if (!begin_statement) { return -1; } PyString_Concat(&begin_statement, isolation_level); if (!begin_statement) { return -1; } begin_statement_str = PyString_AsString(begin_statement); if (!begin_statement_str) { Py_DECREF(begin_statement); return -1; } self->begin_statement = PyMem_Malloc(strlen(begin_statement_str) + 2); if (!self->begin_statement) { Py_DECREF(begin_statement); return -1; } strcpy(self->begin_statement, begin_statement_str); Py_DECREF(begin_statement); } return 0; } PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { PyObject* sql; pysqlite_Statement* statement; PyObject* weakref; int rc; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } if (!PyArg_ParseTuple(args, "O", &sql)) { return NULL; } _pysqlite_drop_unused_statement_references(self); statement = PyObject_New(pysqlite_Statement, &pysqlite_StatementType); if (!statement) { return NULL; } rc = pysqlite_statement_create(statement, self, sql); if (rc != SQLITE_OK) { if (rc == PYSQLITE_TOO_MUCH_SQL) { PyErr_SetString(pysqlite_ProgrammingError, "You can only execute one statement at a time."); } else if (rc == PYSQLITE_SQL_WRONG_TYPE) { PyErr_SetString(pysqlite_ProgrammingError, "SQL is of wrong type. Must be string or unicode."); } else { (void)pysqlite_statement_reset(statement); _pysqlite_seterror(self->db, NULL); } Py_CLEAR(statement); } else { weakref = PyWeakref_NewRef((PyObject*)statement, NULL); if (!weakref) { Py_CLEAR(statement); goto error; } if (PyList_Append(self->statements, weakref) != 0) { Py_CLEAR(weakref); goto error; } Py_DECREF(weakref); } error: return (PyObject*)statement; } PyObject* pysqlite_connection_execute(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { PyObject* cursor = 0; PyObject* result = 0; PyObject* method = 0; cursor = PyObject_CallMethod((PyObject*)self, "cursor", ""); if (!cursor) { goto error; } method = PyObject_GetAttrString(cursor, "execute"); if (!method) { Py_CLEAR(cursor); goto error; } result = PyObject_CallObject(method, args); if (!result) { Py_CLEAR(cursor); } error: Py_XDECREF(result); Py_XDECREF(method); return cursor; } PyObject* pysqlite_connection_executemany(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { PyObject* cursor = 0; PyObject* result = 0; PyObject* method = 0; cursor = PyObject_CallMethod((PyObject*)self, "cursor", ""); if (!cursor) { goto error; } method = PyObject_GetAttrString(cursor, "executemany"); if (!method) { Py_CLEAR(cursor); goto error; } result = PyObject_CallObject(method, args); if (!result) { Py_CLEAR(cursor); } error: Py_XDECREF(result); Py_XDECREF(method); return cursor; } PyObject* pysqlite_connection_executescript(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { PyObject* cursor = 0; PyObject* result = 0; PyObject* method = 0; cursor = PyObject_CallMethod((PyObject*)self, "cursor", ""); if (!cursor) { goto error; } method = PyObject_GetAttrString(cursor, "executescript"); if (!method) { Py_CLEAR(cursor); goto error; } result = PyObject_CallObject(method, args); if (!result) { Py_CLEAR(cursor); } error: Py_XDECREF(result); Py_XDECREF(method); return cursor; } /* ------------------------- COLLATION CODE ------------------------ */ static int pysqlite_collation_callback( void* context, int text1_length, const void* text1_data, int text2_length, const void* text2_data) { PyObject* callback = (PyObject*)context; PyObject* string1 = 0; PyObject* string2 = 0; #ifdef WITH_THREAD PyGILState_STATE gilstate; #endif PyObject* retval = NULL; int result = 0; #ifdef WITH_THREAD gilstate = PyGILState_Ensure(); #endif if (PyErr_Occurred()) { goto finally; } string1 = PyString_FromStringAndSize((const char*)text1_data, text1_length); string2 = PyString_FromStringAndSize((const char*)text2_data, text2_length); if (!string1 || !string2) { goto finally; /* failed to allocate strings */ } retval = PyObject_CallFunctionObjArgs(callback, string1, string2, NULL); if (!retval) { /* execution failed */ goto finally; } result = PyInt_AsLong(retval); if (PyErr_Occurred()) { result = 0; } finally: Py_XDECREF(string1); Py_XDECREF(string2); Py_XDECREF(retval); #ifdef WITH_THREAD PyGILState_Release(gilstate); #endif return result; } static PyObject * pysqlite_connection_interrupt(pysqlite_Connection* self, PyObject* args) { PyObject* retval = NULL; if (!pysqlite_check_connection(self)) { goto finally; } sqlite3_interrupt(self->db); Py_INCREF(Py_None); retval = Py_None; finally: return retval; } /* Function author: Paul Kippes * Class method of Connection to call the Python function _iterdump * of the sqlite3 module. */ static PyObject * pysqlite_connection_iterdump(pysqlite_Connection* self, PyObject* args) { PyObject* retval = NULL; PyObject* module = NULL; PyObject* module_dict; PyObject* pyfn_iterdump; if (!pysqlite_check_connection(self)) { goto finally; } module = PyImport_ImportModule("pysqlite2.dump"); if (!module) { goto finally; } module_dict = PyModule_GetDict(module); if (!module_dict) { goto finally; } pyfn_iterdump = PyDict_GetItemString(module_dict, "_iterdump"); if (!pyfn_iterdump) { PyErr_SetString(pysqlite_OperationalError, "Failed to obtain _iterdump() reference"); goto finally; } args = PyTuple_New(1); if (!args) { goto finally; } Py_INCREF(self); PyTuple_SetItem(args, 0, (PyObject*)self); retval = PyObject_CallObject(pyfn_iterdump, args); finally: Py_XDECREF(args); Py_XDECREF(module); return retval; } static PyObject * pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) { PyObject* callable; PyObject* uppercase_name = 0; PyObject* name; PyObject* retval; char* chk; int rc; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { goto finally; } if (!PyArg_ParseTuple(args, "O!O:create_collation(name, callback)", &PyString_Type, &name, &callable)) { goto finally; } uppercase_name = PyObject_CallMethod(name, "upper", ""); if (!uppercase_name) { goto finally; } chk = PyString_AsString(uppercase_name); while (*chk) { if ((*chk >= '0' && *chk <= '9') || (*chk >= 'A' && *chk <= 'Z') || (*chk == '_')) { chk++; } else { PyErr_SetString(pysqlite_ProgrammingError, "invalid character in collation name"); goto finally; } } if (callable != Py_None && !PyCallable_Check(callable)) { PyErr_SetString(PyExc_TypeError, "parameter must be callable"); goto finally; } if (callable != Py_None) { if (PyDict_SetItem(self->collations, uppercase_name, callable) == -1) goto finally; } else { if (PyDict_DelItem(self->collations, uppercase_name) == -1) goto finally; } rc = sqlite3_create_collation(self->db, PyString_AsString(uppercase_name), SQLITE_UTF8, (callable != Py_None) ? callable : NULL, (callable != Py_None) ? pysqlite_collation_callback : NULL); if (rc != SQLITE_OK) { PyDict_DelItem(self->collations, uppercase_name); _pysqlite_seterror(self->db, NULL); goto finally; } finally: Py_XDECREF(uppercase_name); if (PyErr_Occurred()) { retval = NULL; } else { Py_INCREF(Py_None); retval = Py_None; } return retval; } /* Called when the connection is used as a context manager. Returns itself as a * convenience to the caller. */ static PyObject * pysqlite_connection_enter(pysqlite_Connection* self, PyObject* args) { Py_INCREF(self); return (PyObject*)self; } /** Called when the connection is used as a context manager. If there was any * exception, a rollback takes place; otherwise we commit. */ static PyObject * pysqlite_connection_exit(pysqlite_Connection* self, PyObject* args) { PyObject* exc_type, *exc_value, *exc_tb; char* method_name; PyObject* result; if (!PyArg_ParseTuple(args, "OOO", &exc_type, &exc_value, &exc_tb)) { return NULL; } if (exc_type == Py_None && exc_value == Py_None && exc_tb == Py_None) { method_name = "commit"; } else { method_name = "rollback"; } result = PyObject_CallMethod((PyObject*)self, method_name, ""); if (!result) { return NULL; } Py_DECREF(result); Py_INCREF(Py_False); return Py_False; } static char connection_doc[] = PyDoc_STR("SQLite database connection object."); static PyGetSetDef connection_getset[] = { {"isolation_level", (getter)pysqlite_connection_get_isolation_level, (setter)pysqlite_connection_set_isolation_level}, {"total_changes", (getter)pysqlite_connection_get_total_changes, (setter)0}, {NULL} }; static PyMethodDef connection_methods[] = { #ifdef PYSQLITE_EXPERIMENTAL {"backup", (PyCFunction)pysqlite_connection_backup, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Backup database.")}, #endif {"cursor", (PyCFunction)pysqlite_connection_cursor, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Return a cursor for the connection.")}, {"close", (PyCFunction)pysqlite_connection_close, METH_NOARGS, PyDoc_STR("Closes the connection.")}, {"commit", (PyCFunction)pysqlite_connection_commit, METH_NOARGS, PyDoc_STR("Commit the current transaction.")}, {"rollback", (PyCFunction)pysqlite_connection_rollback, METH_NOARGS, PyDoc_STR("Roll back the current transaction.")}, {"create_function", (PyCFunction)pysqlite_connection_create_function, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Creates a new function. Non-standard.")}, {"create_aggregate", (PyCFunction)pysqlite_connection_create_aggregate, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Creates a new aggregate. Non-standard.")}, {"set_limit", (PyCFunction)pysqlite_connection_set_limit, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Sets SQLite limit. Non-standard.")}, {"get_limit", (PyCFunction)pysqlite_connection_get_limit, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Gets SQLite limit. Non-standard.")}, {"set_authorizer", (PyCFunction)pysqlite_connection_set_authorizer, METH_VARARGS|METH_KEYWORDS, 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, PyDoc_STR("Sets progress handler callback. Non-standard.")}, {"execute", (PyCFunction)pysqlite_connection_execute, METH_VARARGS, PyDoc_STR("Executes a SQL statement. Non-standard.")}, {"executemany", (PyCFunction)pysqlite_connection_executemany, METH_VARARGS, PyDoc_STR("Repeatedly executes a SQL statement. Non-standard.")}, {"executescript", (PyCFunction)pysqlite_connection_executescript, METH_VARARGS, PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")}, {"create_collation", (PyCFunction)pysqlite_connection_create_collation, METH_VARARGS, PyDoc_STR("Creates a collation function. Non-standard.")}, {"interrupt", (PyCFunction)pysqlite_connection_interrupt, METH_NOARGS, PyDoc_STR("Abort any pending database operation. Non-standard.")}, {"iterdump", (PyCFunction)pysqlite_connection_iterdump, METH_NOARGS, PyDoc_STR("Returns iterator to the dump of the database in an SQL text format. Non-standard.")}, {"__enter__", (PyCFunction)pysqlite_connection_enter, METH_NOARGS, PyDoc_STR("For context manager. Non-standard.")}, {"__exit__", (PyCFunction)pysqlite_connection_exit, METH_VARARGS, PyDoc_STR("For context manager. Non-standard.")}, {NULL, NULL} }; static struct PyMemberDef connection_members[] = { {"Warning", T_OBJECT, offsetof(pysqlite_Connection, Warning), RO}, {"Error", T_OBJECT, offsetof(pysqlite_Connection, Error), RO}, {"InterfaceError", T_OBJECT, offsetof(pysqlite_Connection, InterfaceError), RO}, {"DatabaseError", T_OBJECT, offsetof(pysqlite_Connection, DatabaseError), RO}, {"DataError", T_OBJECT, offsetof(pysqlite_Connection, DataError), RO}, {"OperationalError", T_OBJECT, offsetof(pysqlite_Connection, OperationalError), RO}, {"IntegrityError", T_OBJECT, offsetof(pysqlite_Connection, IntegrityError), RO}, {"InternalError", T_OBJECT, offsetof(pysqlite_Connection, InternalError), RO}, {"ProgrammingError", T_OBJECT, offsetof(pysqlite_Connection, ProgrammingError), RO}, {"NotSupportedError", T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), RO}, {"row_factory", T_OBJECT, offsetof(pysqlite_Connection, row_factory)}, {"text_factory", T_OBJECT, offsetof(pysqlite_Connection, text_factory)}, {NULL} }; PyTypeObject pysqlite_ConnectionType = { PyVarObject_HEAD_INIT(NULL, 0) MODULE_NAME ".Connection", /* tp_name */ sizeof(pysqlite_Connection), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pysqlite_connection_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ (ternaryfunc)pysqlite_connection_call, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ connection_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ connection_methods, /* tp_methods */ connection_members, /* tp_members */ connection_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)pysqlite_connection_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0 /* tp_free */ }; extern int pysqlite_connection_setup_types(void) { pysqlite_ConnectionType.tp_new = PyType_GenericNew; return PyType_Ready(&pysqlite_ConnectionType); } pysqlite-2.7.0/src/connection.h000066400000000000000000000120231256035156500164770ustar00rootroot00000000000000/* connection.h - definitions for the connection type * * Copyright (C) 2004-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #ifndef PYSQLITE_CONNECTION_H #define PYSQLITE_CONNECTION_H #include "Python.h" #include "pythread.h" #include "structmember.h" #include "cache.h" #include "module.h" #include "sqlite3.h" typedef struct { PyObject_HEAD sqlite3* db; /* 1 if we are currently within a transaction, i. e. if a BEGIN has been * issued */ int inTransaction; /* the type detection mode. Only 0, PARSE_DECLTYPES, PARSE_COLNAMES or a * bitwise combination thereof makes sense */ int detect_types; /* the timeout value in seconds for database locks */ double timeout; /* for internal use in the timeout handler: when did the timeout handler * first get called with count=0? */ double timeout_started; /* None for autocommit, otherwise a PyString with the isolation level */ PyObject* isolation_level; /* NULL for autocommit, otherwise a string with the BEGIN statment; will be * freed in connection destructor */ char* begin_statement; /* 1 if a check should be performed for each API call if the connection is * used from the same thread it was created in */ int check_same_thread; int initialized; /* thread identification of the thread the connection was created in */ long thread_ident; pysqlite_Cache* statement_cache; /* Lists of weak references to statements and cursors used within this connection */ PyObject* statements; PyObject* cursors; /* Counters for how many statements/cursors were created in the connection. May be * reset to 0 at certain intervals */ int created_statements; int created_cursors; PyObject* row_factory; /* Determines how bytestrings from SQLite are converted to Python objects: * - PyUnicode_Type: Python Unicode objects are constructed from UTF-8 bytestrings * - OptimizedUnicode: Like before, but for ASCII data, only PyStrings are created. * - PyString_Type: PyStrings are created as-is. * - Any custom callable: Any object returned from the callable called with the bytestring * as single parameter. */ PyObject* text_factory; /* remember references to functions/classes used in * create_function/create/aggregate, use these as dictionary keys, so we * can keep the total system refcount constant by clearing that dictionary * in connection_dealloc */ PyObject* function_pinboard; /* a dictionary of registered collation name => collation callable mappings */ PyObject* collations; /* if our connection was created from a APSW connection, we keep a * reference to the APSW connection around and get rid of it in our * destructor */ PyObject* apsw_connection; /* Exception objects */ PyObject* Warning; PyObject* Error; PyObject* InterfaceError; PyObject* DatabaseError; PyObject* DataError; PyObject* OperationalError; PyObject* IntegrityError; PyObject* InternalError; PyObject* ProgrammingError; PyObject* NotSupportedError; } pysqlite_Connection; extern PyTypeObject pysqlite_ConnectionType; PyObject* pysqlite_connection_alloc(PyTypeObject* type, int aware); void pysqlite_connection_dealloc(pysqlite_Connection* self); PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, PyObject* kwargs); PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args); PyObject* _pysqlite_connection_begin(pysqlite_Connection* self); PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args); PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args); PyObject* pysqlite_connection_new(PyTypeObject* type, PyObject* args, PyObject* kw); 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_connection(pysqlite_Connection* con); int pysqlite_connection_setup_types(void); #endif pysqlite-2.7.0/src/cursor.c000066400000000000000000001057441256035156500156650ustar00rootroot00000000000000/* cursor.c - the cursor type * * Copyright (C) 2004-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #include "cursor.h" #include "module.h" #include "util.h" #include "sqlitecompat.h" /* used to decide wether to call PyInt_FromLong or PyLong_FromLongLong */ #ifndef INT32_MIN #define INT32_MIN (-2147483647 - 1) #endif #ifndef INT32_MAX #define INT32_MAX 2147483647 #endif 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) { char buf[20]; char* src; char* dst; src = statement; /* skip over whitepace */ while (*src == '\r' || *src == '\n' || *src == ' ' || *src == '\t') { src++; } if (*src == 0) return STATEMENT_INVALID; dst = buf; *dst = 0; while (isalpha(*src) && dst - buf < sizeof(buf) - 2) { *dst++ = tolower(*src++); } *dst = 0; if (!strcmp(buf, "select")) { return STATEMENT_SELECT; } else if (!strcmp(buf, "insert")) { return STATEMENT_INSERT; } else if (!strcmp(buf, "update")) { return STATEMENT_UPDATE; } else if (!strcmp(buf, "delete")) { return STATEMENT_DELETE; } else if (!strcmp(buf, "replace")) { return STATEMENT_REPLACE; } else { return STATEMENT_OTHER; } } static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs) { pysqlite_Connection* connection; if (!PyArg_ParseTuple(args, "O!", &pysqlite_ConnectionType, &connection)) { return -1; } Py_INCREF(connection); self->connection = connection; self->statement = NULL; self->next_row = NULL; self->in_weakreflist = NULL; self->row_cast_map = PyList_New(0); if (!self->row_cast_map) { return -1; } Py_INCREF(Py_None); self->description = Py_None; Py_INCREF(Py_None); self->lastrowid= Py_None; self->arraysize = 1; self->closed = 0; self->reset = 0; self->rowcount = -1L; Py_INCREF(Py_None); self->row_factory = Py_None; if (!pysqlite_check_thread(self->connection)) { return -1; } if (!pysqlite_connection_register_cursor(connection, (PyObject*)self)) { return -1; } self->initialized = 1; return 0; } static void pysqlite_cursor_dealloc(pysqlite_Cursor* self) { int rc; /* Reset the statement if the user has not closed the cursor */ if (self->statement) { rc = pysqlite_statement_reset(self->statement); Py_DECREF(self->statement); } Py_XDECREF(self->connection); Py_XDECREF(self->row_cast_map); Py_XDECREF(self->description); Py_XDECREF(self->lastrowid); Py_XDECREF(self->row_factory); Py_XDECREF(self->next_row); if (self->in_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject*)self); } self->ob_type->tp_free((PyObject*)self); } PyObject* _pysqlite_get_converter(PyObject* key) { PyObject* upcase_key; PyObject* retval; upcase_key = PyObject_CallMethod(key, "upper", ""); if (!upcase_key) { return NULL; } retval = PyDict_GetItem(converters, upcase_key); Py_DECREF(upcase_key); return retval; } int pysqlite_build_row_cast_map(pysqlite_Cursor* self) { int i; const char* type_start = (const char*)-1; const char* pos; const char* colname; const char* decltype; PyObject* py_decltype; PyObject* converter; PyObject* key; if (!self->connection->detect_types) { return 0; } Py_XDECREF(self->row_cast_map); self->row_cast_map = PyList_New(0); for (i = 0; i < sqlite3_column_count(self->statement->st); i++) { converter = NULL; if (self->connection->detect_types & PARSE_COLNAMES) { colname = sqlite3_column_name(self->statement->st, i); if (colname) { for (pos = colname; *pos != 0; pos++) { if (*pos == '[') { type_start = pos + 1; } else if (*pos == ']' && type_start != (const char*)-1) { key = PyString_FromStringAndSize(type_start, pos - type_start); 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 */ break; } converter = _pysqlite_get_converter(key); Py_DECREF(key); break; } } } } if (!converter && self->connection->detect_types & PARSE_DECLTYPES) { decltype = sqlite3_column_decltype(self->statement->st, i); if (decltype) { for (pos = decltype;;pos++) { /* 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; } break; } } converter = _pysqlite_get_converter(py_decltype); Py_DECREF(py_decltype); } } if (!converter) { converter = Py_None; } if (PyList_Append(self->row_cast_map, converter) != 0) { if (converter != Py_None) { Py_DECREF(converter); } Py_XDECREF(self->row_cast_map); self->row_cast_map = NULL; return -1; } } return 0; } PyObject* _pysqlite_build_column_name(const char* colname) { const char* pos; if (!colname) { Py_INCREF(Py_None); return Py_None; } for (pos = colname;; pos++) { if (*pos == 0 || *pos == '[') { if ((*pos == '[') && (pos > colname) && (*(pos-1) == ' ')) { pos--; } return PyString_FromStringAndSize(colname, pos - colname); } } } static PyObject* pysqlite_unicode_from_string(const char* val_str, Py_ssize_t nbytes, int optimize) { int is_ascii = 0; int i; if (optimize) { is_ascii = 1; for (i = 0; i < nbytes; i++) { if (val_str[i] & 0x80) { is_ascii = 0; break; } } } if (is_ascii) { return PyString_FromStringAndSize(val_str, nbytes); } else { return PyUnicode_DecodeUTF8(val_str, nbytes, NULL); } } /* * Returns a row from the currently active SQLite statement * * Precondidition: * - sqlite3_step() has been called before and it returned SQLITE_ROW. */ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) { int i, numcols; PyObject* row; PyObject* item = NULL; int coltype; PY_LONG_LONG intval; PyObject* converter; PyObject* converted; Py_ssize_t nbytes; PyObject* buffer; void* raw_buffer; const char* val_str; char buf[200]; const char* colname; if (self->reset) { PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback); return NULL; } Py_BEGIN_ALLOW_THREADS numcols = sqlite3_data_count(self->statement->st); Py_END_ALLOW_THREADS row = PyTuple_New(numcols); if (!row) { return NULL; } for (i = 0; i < numcols; i++) { nbytes = sqlite3_column_bytes(self->statement->st, i); if (self->connection->detect_types) { converter = PyList_GetItem(self->row_cast_map, i); if (!converter) { converter = Py_None; } } else { converter = Py_None; } if (converter != Py_None) { if (sqlite3_column_type(self->statement->st, i) == SQLITE_NULL) { Py_INCREF(Py_None); converted = Py_None; } else { val_str = (const char*)sqlite3_column_blob(self->statement->st, i); if (!val_str) { Py_INCREF(Py_None); converted = Py_None; } else { item = PyString_FromStringAndSize(val_str, nbytes); if (!item) { return NULL; } converted = PyObject_CallFunction(converter, "O", item); Py_DECREF(item); if (!converted) { break; } } } } else { Py_BEGIN_ALLOW_THREADS coltype = sqlite3_column_type(self->statement->st, i); Py_END_ALLOW_THREADS if (coltype == SQLITE_NULL) { Py_INCREF(Py_None); converted = Py_None; } else if (coltype == SQLITE_INTEGER) { intval = sqlite3_column_int64(self->statement->st, i); if (intval < INT32_MIN || intval > INT32_MAX) { converted = PyLong_FromLongLong(intval); } else { converted = PyInt_FromLong((long)intval); } } else if (coltype == SQLITE_FLOAT) { converted = PyFloat_FromDouble(sqlite3_column_double(self->statement->st, i)); } else if (coltype == SQLITE_TEXT) { val_str = (const char*)sqlite3_column_text(self->statement->st, i); if ((self->connection->text_factory == (PyObject*)&PyUnicode_Type) || (self->connection->text_factory == pysqlite_OptimizedUnicode)) { converted = pysqlite_unicode_from_string(val_str, nbytes, self->connection->text_factory == pysqlite_OptimizedUnicode ? 1 : 0); if (!converted) { colname = sqlite3_column_name(self->statement->st, i); if (!colname) { colname = ""; } PyOS_snprintf(buf, sizeof(buf) - 1, "Could not decode to UTF-8 column '%s' with text '%s'", colname , val_str); PyErr_SetString(pysqlite_OperationalError, buf); } } else if (self->connection->text_factory == (PyObject*)&PyString_Type) { converted = PyString_FromStringAndSize(val_str, nbytes); } else { converted = PyObject_CallFunction(self->connection->text_factory, "s", val_str); } } else { /* coltype == SQLITE_BLOB */ nbytes = sqlite3_column_bytes(self->statement->st, i); buffer = PyBuffer_New(nbytes); if (!buffer) { break; } if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &nbytes)) { break; } memcpy(raw_buffer, sqlite3_column_blob(self->statement->st, i), nbytes); converted = buffer; } } if (converted) { PyTuple_SetItem(row, i, converted); } else { Py_INCREF(Py_None); PyTuple_SetItem(row, i, Py_None); } } if (PyErr_Occurred()) { Py_DECREF(row); row = NULL; } 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; } if (cur->locked) { PyErr_SetString(pysqlite_ProgrammingError, "Recursive use of cursors not allowed."); return 0; } return pysqlite_check_thread(cur->connection) && pysqlite_check_connection(cur->connection); } PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) { PyObject* operation; PyObject* operation_bytestr = NULL; char* operation_cstr; PyObject* parameters_list = NULL; PyObject* parameters_iter = NULL; PyObject* parameters = NULL; int i; int rc; PyObject* func_args; PyObject* result; int numcols; PY_LONG_LONG lastrowid; int statement_type; PyObject* descriptor; PyObject* second_argument = NULL; int allow_8bit_chars; if (!check_cursor(self)) { goto error; } self->locked = 1; self->reset = 0; /* 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) && (self->connection->text_factory != pysqlite_OptimizedUnicode)); Py_XDECREF(self->next_row); self->next_row = NULL; if (multiple) { /* executemany() */ if (!PyArg_ParseTuple(args, "OO", &operation, &second_argument)) { goto error; } if (!PyString_Check(operation) && !PyUnicode_Check(operation)) { PyErr_SetString(PyExc_ValueError, "operation parameter must be str or unicode"); goto error; } if (PyIter_Check(second_argument)) { /* iterator */ Py_INCREF(second_argument); parameters_iter = second_argument; } else { /* sequence */ parameters_iter = PyObject_GetIter(second_argument); if (!parameters_iter) { goto error; } } } else { /* execute() */ if (!PyArg_ParseTuple(args, "O|O", &operation, &second_argument)) { goto error; } if (!PyString_Check(operation) && !PyUnicode_Check(operation)) { PyErr_SetString(PyExc_ValueError, "operation parameter must be str or unicode"); goto error; } parameters_list = PyList_New(0); if (!parameters_list) { goto error; } if (second_argument == NULL) { second_argument = PyTuple_New(0); if (!second_argument) { goto error; } } else { Py_INCREF(second_argument); } if (PyList_Append(parameters_list, second_argument) != 0) { Py_DECREF(second_argument); goto error; } Py_DECREF(second_argument); parameters_iter = PyObject_GetIter(parameters_list); if (!parameters_iter) { goto error; } } if (self->statement != NULL) { /* There is an active statement */ rc = pysqlite_statement_reset(self->statement); } if (PyString_Check(operation)) { operation_cstr = PyString_AsString(operation); } else { operation_bytestr = PyUnicode_AsUTF8String(operation); if (!operation_bytestr) { goto error; } operation_cstr = PyString_AsString(operation_bytestr); } /* reset description and rowcount */ Py_DECREF(self->description); Py_INCREF(Py_None); self->description = Py_None; self->rowcount = -1L; func_args = PyTuple_New(1); if (!func_args) { goto error; } Py_INCREF(operation); if (PyTuple_SetItem(func_args, 0, operation) != 0) { goto error; } if (self->statement) { (void)pysqlite_statement_reset(self->statement); Py_DECREF(self->statement); } self->statement = (pysqlite_Statement*)pysqlite_cache_get(self->connection->statement_cache, func_args); Py_DECREF(func_args); if (!self->statement) { goto error; } if (self->statement->in_use) { Py_DECREF(self->statement); self->statement = PyObject_New(pysqlite_Statement, &pysqlite_StatementType); if (!self->statement) { goto error; } rc = pysqlite_statement_create(self->statement, self->connection, operation); if (rc != SQLITE_OK) { Py_CLEAR(self->statement); goto error; } } pysqlite_statement_reset(self->statement); pysqlite_statement_mark_dirty(self->statement); statement_type = detect_statement_type(operation_cstr); if (self->connection->begin_statement) { switch (statement_type) { case STATEMENT_UPDATE: case STATEMENT_DELETE: case STATEMENT_INSERT: case STATEMENT_REPLACE: if (!self->connection->inTransaction) { result = _pysqlite_connection_begin(self->connection); if (!result) { goto error; } Py_DECREF(result); } break; case STATEMENT_OTHER: /* it's a DDL statement or something similar - we better COMMIT first so it works for all cases */ if (self->connection->inTransaction) { result = pysqlite_connection_commit(self->connection, NULL); if (!result) { goto error; } Py_DECREF(result); } break; case STATEMENT_SELECT: if (multiple) { PyErr_SetString(pysqlite_ProgrammingError, "You cannot execute SELECT statements in executemany()."); goto error; } break; } } while (1) { parameters = PyIter_Next(parameters_iter); if (!parameters) { break; } pysqlite_statement_mark_dirty(self->statement); pysqlite_statement_bind_parameters(self->statement, parameters, allow_8bit_chars); if (PyErr_Occurred()) { goto error; } /* Keep trying the SQL statement until the schema stops changing. */ while (1) { /* Actually execute the SQL statement. */ rc = pysqlite_step(self->statement->st, self->connection); if (rc == SQLITE_DONE || rc == SQLITE_ROW) { /* If it worked, let's get out of the loop */ break; } /* Something went wrong. Re-set the statement and try again. */ rc = pysqlite_statement_reset(self->statement); if (rc == SQLITE_SCHEMA) { /* If this was a result of the schema changing, let's try again. */ rc = pysqlite_statement_recompile(self->statement, parameters); if (rc == SQLITE_OK) { continue; } else { /* If the database gave us an error, promote it to Python. */ (void)pysqlite_statement_reset(self->statement); _pysqlite_seterror(self->connection->db, NULL); goto error; } } else { if (PyErr_Occurred()) { /* there was an error that occurred in a user-defined callback */ if (_enable_callback_tracebacks) { PyErr_Print(); } else { PyErr_Clear(); } } (void)pysqlite_statement_reset(self->statement); _pysqlite_seterror(self->connection->db, NULL); goto error; } } if (pysqlite_build_row_cast_map(self) != 0) { PyErr_SetString(pysqlite_OperationalError, "Error while building row_cast_map"); goto error; } if (rc == SQLITE_ROW || (rc == SQLITE_DONE && statement_type == STATEMENT_SELECT)) { if (self->description == Py_None) { Py_BEGIN_ALLOW_THREADS numcols = sqlite3_column_count(self->statement->st); Py_END_ALLOW_THREADS Py_DECREF(self->description); self->description = PyTuple_New(numcols); if (!self->description) { goto error; } for (i = 0; i < numcols; i++) { descriptor = PyTuple_New(7); if (!descriptor) { goto error; } PyTuple_SetItem(descriptor, 0, _pysqlite_build_column_name(sqlite3_column_name(self->statement->st, i))); Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None); Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None); Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 3, Py_None); Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 4, Py_None); Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 5, Py_None); Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 6, Py_None); PyTuple_SetItem(self->description, i, descriptor); } } } if (rc == SQLITE_ROW) { if (multiple) { PyErr_SetString(pysqlite_ProgrammingError, "executemany() can only execute DML statements."); goto error; } self->next_row = _pysqlite_fetch_one_row(self); } else if (rc == SQLITE_DONE && !multiple) { pysqlite_statement_reset(self->statement); Py_CLEAR(self->statement); } switch (statement_type) { case STATEMENT_UPDATE: case STATEMENT_DELETE: case STATEMENT_INSERT: case STATEMENT_REPLACE: if (self->rowcount == -1L) { self->rowcount = 0L; } self->rowcount += (long)sqlite3_changes(self->connection->db); } Py_DECREF(self->lastrowid); if (!multiple && statement_type == STATEMENT_INSERT) { Py_BEGIN_ALLOW_THREADS lastrowid = sqlite3_last_insert_rowid(self->connection->db); Py_END_ALLOW_THREADS self->lastrowid = PyInt_FromLong((long)lastrowid); } else { Py_INCREF(Py_None); self->lastrowid = Py_None; } if (multiple) { rc = pysqlite_statement_reset(self->statement); } Py_XDECREF(parameters); } error: /* just to be sure (implicit ROLLBACKs with ON CONFLICT ROLLBACK/OR * ROLLBACK could have happened */ #ifdef SQLITE_VERSION_NUMBER #if SQLITE_VERSION_NUMBER >= 3002002 if (self->connection && self->connection->db) self->connection->inTransaction = !sqlite3_get_autocommit(self->connection->db); #endif #endif Py_XDECREF(operation_bytestr); Py_XDECREF(parameters); Py_XDECREF(parameters_iter); Py_XDECREF(parameters_list); self->locked = 0; if (PyErr_Occurred()) { self->rowcount = -1L; return NULL; } else { Py_INCREF(self); return (PyObject*)self; } } PyObject* pysqlite_cursor_execute(pysqlite_Cursor* self, PyObject* args) { return _pysqlite_query_execute(self, 0, args); } PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args) { return _pysqlite_query_execute(self, 1, args); } PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args) { PyObject* script_obj; PyObject* script_str = NULL; const char* script_cstr; sqlite3_stmt* statement; int rc; PyObject* result; if (!PyArg_ParseTuple(args, "O", &script_obj)) { return NULL; } if (!check_cursor(self)) { return NULL; } self->reset = 0; if (PyString_Check(script_obj)) { script_cstr = PyString_AsString(script_obj); } else if (PyUnicode_Check(script_obj)) { script_str = PyUnicode_AsUTF8String(script_obj); if (!script_str) { return NULL; } script_cstr = PyString_AsString(script_str); } else { PyErr_SetString(PyExc_ValueError, "script argument must be unicode or string."); return NULL; } /* commit first */ result = pysqlite_connection_commit(self->connection, NULL); if (!result) { goto error; } Py_DECREF(result); while (1) { Py_BEGIN_ALLOW_THREADS rc = sqlite3_prepare(self->connection->db, script_cstr, -1, &statement, &script_cstr); Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { _pysqlite_seterror(self->connection->db, NULL); goto error; } /* execute statement, and ignore results of SELECT statements */ rc = SQLITE_ROW; while (rc == SQLITE_ROW) { rc = pysqlite_step(statement, self->connection); /* TODO: we probably need more error handling here */ } if (rc != SQLITE_DONE) { (void)sqlite3_finalize(statement); _pysqlite_seterror(self->connection->db, NULL); goto error; } rc = sqlite3_finalize(statement); if (rc != SQLITE_OK) { _pysqlite_seterror(self->connection->db, NULL); goto error; } if (*script_cstr == (char)0) { break; } } error: Py_XDECREF(script_str); if (PyErr_Occurred()) { return NULL; } else { Py_INCREF(self); return (PyObject*)self; } } PyObject* pysqlite_cursor_getiter(pysqlite_Cursor *self) { Py_INCREF(self); return (PyObject*)self; } PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) { PyObject* next_row_tuple; PyObject* next_row; int rc; if (!check_cursor(self)) { return NULL; } if (self->reset) { PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback); return NULL; } if (!self->next_row) { if (self->statement) { (void)pysqlite_statement_reset(self->statement); Py_DECREF(self->statement); self->statement = NULL; } return NULL; } next_row_tuple = self->next_row; self->next_row = NULL; if (self->row_factory != Py_None) { next_row = PyObject_CallFunction(self->row_factory, "OO", self, next_row_tuple); Py_DECREF(next_row_tuple); } else { next_row = next_row_tuple; } if (self->statement) { rc = pysqlite_step(self->statement->st, self->connection); if (rc != SQLITE_DONE && rc != SQLITE_ROW) { (void)pysqlite_statement_reset(self->statement); Py_DECREF(next_row); _pysqlite_seterror(self->connection->db, NULL); return NULL; } if (rc == SQLITE_ROW) { self->next_row = _pysqlite_fetch_one_row(self); } } return next_row; } PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args) { PyObject* row; row = pysqlite_cursor_iternext(self); if (!row && !PyErr_Occurred()) { Py_INCREF(Py_None); return Py_None; } return row; } PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = {"size", NULL, NULL}; PyObject* row; PyObject* list; int maxrows = self->arraysize; int counter = 0; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:fetchmany", kwlist, &maxrows)) { return NULL; } list = PyList_New(0); if (!list) { return NULL; } /* just make sure we enter the loop */ row = Py_None; while (row) { row = pysqlite_cursor_iternext(self); if (row) { PyList_Append(list, row); Py_DECREF(row); } else { break; } if (++counter == maxrows) { break; } } if (PyErr_Occurred()) { Py_DECREF(list); return NULL; } else { return list; } } PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args) { PyObject* row; PyObject* list; list = PyList_New(0); if (!list) { return NULL; } /* just make sure we enter the loop */ row = (PyObject*)Py_None; while (row) { row = pysqlite_cursor_iternext(self); if (row) { PyList_Append(list, row); Py_DECREF(row); } } if (PyErr_Occurred()) { Py_DECREF(list); return NULL; } else { return list; } } PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args) { /* don't care, return None */ Py_INCREF(Py_None); return Py_None; } PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args) { if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) { return NULL; } if (self->statement) { (void)pysqlite_statement_reset(self->statement); Py_CLEAR(self->statement); } self->closed = 1; Py_INCREF(Py_None); return Py_None; } static PyMethodDef cursor_methods[] = { {"execute", (PyCFunction)pysqlite_cursor_execute, METH_VARARGS, PyDoc_STR("Executes a SQL statement.")}, {"executemany", (PyCFunction)pysqlite_cursor_executemany, METH_VARARGS, PyDoc_STR("Repeatedly executes a SQL statement.")}, {"executescript", (PyCFunction)pysqlite_cursor_executescript, METH_VARARGS, PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")}, {"fetchone", (PyCFunction)pysqlite_cursor_fetchone, METH_NOARGS, PyDoc_STR("Fetches one row from the resultset.")}, {"fetchmany", (PyCFunction)pysqlite_cursor_fetchmany, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Fetches several rows from the resultset.")}, {"fetchall", (PyCFunction)pysqlite_cursor_fetchall, METH_NOARGS, PyDoc_STR("Fetches all rows from the resultset.")}, {"close", (PyCFunction)pysqlite_cursor_close, METH_NOARGS, PyDoc_STR("Closes the cursor.")}, {"setinputsizes", (PyCFunction)pysqlite_noop, METH_VARARGS, PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")}, {"setoutputsize", (PyCFunction)pysqlite_noop, METH_VARARGS, PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")}, {NULL, NULL} }; static struct PyMemberDef cursor_members[] = { {"connection", T_OBJECT, offsetof(pysqlite_Cursor, connection), RO}, {"description", T_OBJECT, offsetof(pysqlite_Cursor, description), RO}, {"arraysize", T_INT, offsetof(pysqlite_Cursor, arraysize), 0}, {"lastrowid", T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), RO}, {"rowcount", T_LONG, offsetof(pysqlite_Cursor, rowcount), RO}, {"row_factory", T_OBJECT, offsetof(pysqlite_Cursor, row_factory), 0}, {NULL} }; static char cursor_doc[] = PyDoc_STR("SQLite database cursor class."); PyTypeObject pysqlite_CursorType = { PyVarObject_HEAD_INIT(NULL, 0) MODULE_NAME ".Cursor", /* tp_name */ sizeof(pysqlite_Cursor), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pysqlite_cursor_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_ITER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */ cursor_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof(pysqlite_Cursor, in_weakreflist), /* tp_weaklistoffset */ (getiterfunc)pysqlite_cursor_getiter, /* tp_iter */ (iternextfunc)pysqlite_cursor_iternext, /* tp_iternext */ cursor_methods, /* tp_methods */ cursor_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)pysqlite_cursor_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0 /* tp_free */ }; extern int pysqlite_cursor_setup_types(void) { pysqlite_CursorType.tp_new = PyType_GenericNew; return PyType_Ready(&pysqlite_CursorType); } pysqlite-2.7.0/src/cursor.h000066400000000000000000000050431256035156500156610ustar00rootroot00000000000000/* cursor.h - definitions for the cursor type * * Copyright (C) 2004-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #ifndef PYSQLITE_CURSOR_H #define PYSQLITE_CURSOR_H #include "Python.h" #include "statement.h" #include "connection.h" #include "module.h" typedef struct { PyObject_HEAD pysqlite_Connection* connection; PyObject* description; PyObject* row_cast_map; int arraysize; PyObject* lastrowid; long rowcount; PyObject* row_factory; pysqlite_Statement* statement; int closed; int reset; int locked; int initialized; /* the next row to be returned, NULL if no next row available */ PyObject* next_row; PyObject* in_weakreflist; /* List of weak references */ } pysqlite_Cursor; typedef enum { STATEMENT_INVALID, STATEMENT_INSERT, STATEMENT_DELETE, STATEMENT_UPDATE, STATEMENT_REPLACE, STATEMENT_SELECT, STATEMENT_OTHER } pysqlite_StatementKind; extern PyTypeObject pysqlite_CursorType; PyObject* pysqlite_cursor_execute(pysqlite_Cursor* self, PyObject* args); PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args); PyObject* pysqlite_cursor_getiter(pysqlite_Cursor *self); PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self); PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args); PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs); PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args); PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args); PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args); int pysqlite_cursor_setup_types(void); #define UNKNOWN (-1) #endif pysqlite-2.7.0/src/microprotocols.c000066400000000000000000000104051256035156500174130ustar00rootroot00000000000000/* microprotocols.c - minimalist and non-validating protocols implementation * * Copyright (C) 2003-2004 Federico Di Gregorio * * This file is part of psycopg and was adapted for pysqlite. Federico Di * Gregorio gave the permission to use it within pysqlite under the following * license: * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #include #include #include "cursor.h" #include "microprotocols.h" #include "prepare_protocol.h" /** the adapters registry **/ PyObject *psyco_adapters; /* pysqlite_microprotocols_init - initialize the adapters dictionary */ int pysqlite_microprotocols_init(PyObject *dict) { /* create adapters dictionary and put it in module namespace */ if ((psyco_adapters = PyDict_New()) == NULL) { return -1; } return PyDict_SetItemString(dict, "adapters", psyco_adapters); } /* pysqlite_microprotocols_add - add a reverse type-caster to the dictionary */ int pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast) { PyObject* key; int rc; if (proto == NULL) proto = (PyObject*)&pysqlite_PrepareProtocolType; key = Py_BuildValue("(OO)", (PyObject*)type, proto); if (!key) { return -1; } rc = PyDict_SetItem(psyco_adapters, key, cast); Py_DECREF(key); return rc; } /* pysqlite_microprotocols_adapt - adapt an object to the built-in protocol */ PyObject * pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) { PyObject *adapter, *key; /* we don't check for exact type conformance as specified in PEP 246 because the pysqlite_PrepareProtocolType type is abstract and there is no way to get a quotable object to be its instance */ /* look for an adapter in the registry */ key = Py_BuildValue("(OO)", (PyObject*)obj->ob_type, proto); if (!key) { return NULL; } adapter = PyDict_GetItem(psyco_adapters, key); Py_DECREF(key); if (adapter) { PyObject *adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL); return adapted; } /* try to have the protocol adapt this object*/ if (PyObject_HasAttrString(proto, "__adapt__")) { PyObject *adapted = PyObject_CallMethod(proto, "__adapt__", "O", obj); if (adapted) { if (adapted != Py_None) { return adapted; } else { Py_DECREF(adapted); } } if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) return NULL; } /* and finally try to have the object adapt itself */ if (PyObject_HasAttrString(obj, "__conform__")) { PyObject *adapted = PyObject_CallMethod(obj, "__conform__","O", proto); if (adapted) { if (adapted != Py_None) { return adapted; } else { Py_DECREF(adapted); } } if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) { return NULL; } } /* else set the right exception and return NULL */ PyErr_SetString(pysqlite_ProgrammingError, "can't adapt"); return NULL; } /** module-level functions **/ PyObject * pysqlite_adapt(pysqlite_Cursor *self, PyObject *args) { PyObject *obj, *alt = NULL; PyObject *proto = (PyObject*)&pysqlite_PrepareProtocolType; if (!PyArg_ParseTuple(args, "O|OO", &obj, &proto, &alt)) return NULL; return pysqlite_microprotocols_adapt(obj, proto, alt); } pysqlite-2.7.0/src/microprotocols.h000066400000000000000000000041061256035156500174210ustar00rootroot00000000000000/* microprotocols.c - definitions for minimalist and non-validating protocols * * Copyright (C) 2003-2004 Federico Di Gregorio * * This file is part of psycopg and was adapted for pysqlite. Federico Di * Gregorio gave the permission to use it within pysqlite under the following * license: * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #ifndef PSYCOPG_MICROPROTOCOLS_H #define PSYCOPG_MICROPROTOCOLS_H 1 #include /** adapters registry **/ extern PyObject *psyco_adapters; /** the names of the three mandatory methods **/ #define MICROPROTOCOLS_GETQUOTED_NAME "getquoted" #define MICROPROTOCOLS_GETSTRING_NAME "getstring" #define MICROPROTOCOLS_GETBINARY_NAME "getbinary" /** exported functions **/ /* used by module.c to init the microprotocols system */ extern int pysqlite_microprotocols_init(PyObject *dict); extern int pysqlite_microprotocols_add( PyTypeObject *type, PyObject *proto, PyObject *cast); extern PyObject *pysqlite_microprotocols_adapt( PyObject *obj, PyObject *proto, PyObject *alt); extern PyObject * pysqlite_adapt(pysqlite_Cursor* self, PyObject *args); #define pysqlite_adapt_doc \ "adapt(obj, protocol, alternate) -> adapt obj to given protocol. Non-standard." #endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */ pysqlite-2.7.0/src/module.c000066400000000000000000000327101256035156500156250ustar00rootroot00000000000000/* module.c - the module itself * * Copyright (C) 2004-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #include "connection.h" #include "statement.h" #include "cursor.h" #include "cache.h" #include "prepare_protocol.h" #include "microprotocols.h" #include "row.h" #ifdef PYSQLITE_EXPERIMENTAL #include "backup.h" #endif #if SQLITE_VERSION_NUMBER >= 3003003 #define HAVE_SHARED_CACHE #endif /* static objects at module-level */ PyObject* pysqlite_Error, *pysqlite_Warning, *pysqlite_InterfaceError, *pysqlite_DatabaseError, *pysqlite_InternalError, *pysqlite_OperationalError, *pysqlite_ProgrammingError, *pysqlite_IntegrityError, *pysqlite_DataError, *pysqlite_NotSupportedError, *pysqlite_OptimizedUnicode; PyObject* converters; int _enable_callback_tracebacks; int pysqlite_BaseTypeAdapted; static PyObject* module_connect(PyObject* self, PyObject* args, PyObject* kwargs) { /* Python seems to have no way of extracting a single keyword-arg at * C-level, so this code is redundant with the one in connection_init in * connection.c and must always be copied from there ... */ static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL}; PyObject* database; int detect_types = 0; PyObject* isolation_level; PyObject* factory = NULL; int check_same_thread = 1; int cached_statements; double timeout = 5.0; PyObject* result; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|diOiOi", kwlist, &database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements)) { return NULL; } if (factory == NULL) { factory = (PyObject*)&pysqlite_ConnectionType; } result = PyObject_Call(factory, args, kwargs); return result; } PyDoc_STRVAR(module_connect_doc, "connect(database[, timeout, isolation_level, detect_types, factory])\n\ \n\ Opens a connection to the SQLite database file *database*. You can use\n\ \":memory:\" to open a database connection to a database that resides in\n\ RAM instead of on disk."); static PyObject* module_complete(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = {"statement", NULL, NULL}; char* statement; PyObject* result; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &statement)) { return NULL; } if (sqlite3_complete(statement)) { result = Py_True; } else { result = Py_False; } Py_INCREF(result); return result; } PyDoc_STRVAR(module_complete_doc, "complete_statement(sql)\n\ \n\ Checks if a string contains a complete SQL statement. Non-standard."); #ifdef HAVE_SHARED_CACHE static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = {"do_enable", NULL, NULL}; int do_enable; int rc; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &do_enable)) { return NULL; } rc = sqlite3_enable_shared_cache(do_enable); if (rc != SQLITE_OK) { PyErr_SetString(pysqlite_OperationalError, "Changing the shared_cache flag failed"); return NULL; } else { Py_INCREF(Py_None); return Py_None; } } PyDoc_STRVAR(module_enable_shared_cache_doc, "enable_shared_cache(do_enable)\n\ \n\ Enable or disable shared cache mode for the calling thread.\n\ Experimental/Non-standard."); #endif /* HAVE_SHARED_CACHE */ static PyObject* module_register_adapter(PyObject* self, PyObject* args) { PyTypeObject* type; PyObject* caster; int rc; if (!PyArg_ParseTuple(args, "OO", &type, &caster)) { return NULL; } /* a basic type is adapted; there's a performance optimization if that's not the case * (99 % of all usages) */ if (type == &PyInt_Type || type == &PyLong_Type || type == &PyFloat_Type || type == &PyString_Type || type == &PyUnicode_Type || type == &PyBuffer_Type) { pysqlite_BaseTypeAdapted = 1; } rc = pysqlite_microprotocols_add(type, (PyObject*)&pysqlite_PrepareProtocolType, caster); if (rc == -1) return NULL; Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(module_register_adapter_doc, "register_adapter(type, callable)\n\ \n\ Registers an adapter with pysqlite's adapter registry. Non-standard."); static PyObject* module_register_converter(PyObject* self, PyObject* args) { PyObject* orig_name; PyObject* name = NULL; PyObject* callable; PyObject* retval = NULL; if (!PyArg_ParseTuple(args, "SO", &orig_name, &callable)) { return NULL; } /* convert the name to upper case */ name = PyObject_CallMethod(orig_name, "upper", ""); if (!name) { goto error; } if (PyDict_SetItem(converters, name, callable) != 0) { goto error; } Py_INCREF(Py_None); retval = Py_None; error: Py_XDECREF(name); return retval; } PyDoc_STRVAR(module_register_converter_doc, "register_converter(typename, callable)\n\ \n\ Registers a converter with pysqlite. Non-standard."); static PyObject* enable_callback_tracebacks(PyObject* self, PyObject* args) { if (!PyArg_ParseTuple(args, "i", &_enable_callback_tracebacks)) { return NULL; } Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(enable_callback_tracebacks_doc, "enable_callback_tracebacks(flag)\n\ \n\ Enable or disable callback functions throwing errors to stderr."); static void converters_init(PyObject* dict) { converters = PyDict_New(); if (!converters) { return; } PyDict_SetItemString(dict, "converters", converters); } static PyMethodDef module_methods[] = { {"connect", (PyCFunction)module_connect, METH_VARARGS | METH_KEYWORDS, module_connect_doc}, {"complete_statement", (PyCFunction)module_complete, METH_VARARGS | METH_KEYWORDS, module_complete_doc}, #ifdef HAVE_SHARED_CACHE {"enable_shared_cache", (PyCFunction)module_enable_shared_cache, METH_VARARGS | METH_KEYWORDS, module_enable_shared_cache_doc}, #endif {"register_adapter", (PyCFunction)module_register_adapter, METH_VARARGS, module_register_adapter_doc}, {"register_converter", (PyCFunction)module_register_converter, METH_VARARGS, module_register_converter_doc}, {"adapt", (PyCFunction)pysqlite_adapt, METH_VARARGS, pysqlite_adapt_doc}, {"enable_callback_tracebacks", (PyCFunction)enable_callback_tracebacks, METH_VARARGS, enable_callback_tracebacks_doc}, {NULL, NULL} }; struct _IntConstantPair { char* constant_name; int constant_value; }; typedef struct _IntConstantPair IntConstantPair; static IntConstantPair _int_constants[] = { {"PARSE_DECLTYPES", PARSE_DECLTYPES}, {"PARSE_COLNAMES", PARSE_COLNAMES}, #include "sqlite_constants.h" {(char*)NULL, 0} }; PyMODINIT_FUNC init_sqlite(void) { PyObject *module, *dict; PyObject *tmp_obj; int i; module = Py_InitModule("pysqlite2._sqlite", module_methods); if (!module || (pysqlite_row_setup_types() < 0) || (pysqlite_cursor_setup_types() < 0) || (pysqlite_connection_setup_types() < 0) || (pysqlite_cache_setup_types() < 0) || (pysqlite_statement_setup_types() < 0) || #ifdef PYSQLITE_EXPERIMENTAL (pysqlite_backup_setup_types() < 0) || #endif (pysqlite_prepare_protocol_setup_types() < 0) ) { return; } Py_INCREF(&pysqlite_ConnectionType); PyModule_AddObject(module, "Connection", (PyObject*) &pysqlite_ConnectionType); Py_INCREF(&pysqlite_CursorType); PyModule_AddObject(module, "Cursor", (PyObject*) &pysqlite_CursorType); Py_INCREF(&pysqlite_CacheType); PyModule_AddObject(module, "Statement", (PyObject*)&pysqlite_StatementType); Py_INCREF(&pysqlite_StatementType); PyModule_AddObject(module, "Cache", (PyObject*) &pysqlite_CacheType); Py_INCREF(&pysqlite_PrepareProtocolType); PyModule_AddObject(module, "PrepareProtocol", (PyObject*) &pysqlite_PrepareProtocolType); Py_INCREF(&pysqlite_RowType); PyModule_AddObject(module, "Row", (PyObject*) &pysqlite_RowType); if (!(dict = PyModule_GetDict(module))) { goto error; } /*** Create DB-API Exception hierarchy */ if (!(pysqlite_Error = PyErr_NewException(MODULE_NAME ".Error", PyExc_StandardError, NULL))) { goto error; } PyDict_SetItemString(dict, "Error", pysqlite_Error); if (!(pysqlite_Warning = PyErr_NewException(MODULE_NAME ".Warning", PyExc_StandardError, NULL))) { goto error; } PyDict_SetItemString(dict, "Warning", pysqlite_Warning); /* Error subclasses */ if (!(pysqlite_InterfaceError = PyErr_NewException(MODULE_NAME ".InterfaceError", pysqlite_Error, NULL))) { goto error; } PyDict_SetItemString(dict, "InterfaceError", pysqlite_InterfaceError); if (!(pysqlite_DatabaseError = PyErr_NewException(MODULE_NAME ".DatabaseError", pysqlite_Error, NULL))) { goto error; } PyDict_SetItemString(dict, "DatabaseError", pysqlite_DatabaseError); /* pysqlite_DatabaseError subclasses */ if (!(pysqlite_InternalError = PyErr_NewException(MODULE_NAME ".InternalError", pysqlite_DatabaseError, NULL))) { goto error; } PyDict_SetItemString(dict, "InternalError", pysqlite_InternalError); if (!(pysqlite_OperationalError = PyErr_NewException(MODULE_NAME ".OperationalError", pysqlite_DatabaseError, NULL))) { goto error; } PyDict_SetItemString(dict, "OperationalError", pysqlite_OperationalError); if (!(pysqlite_ProgrammingError = PyErr_NewException(MODULE_NAME ".ProgrammingError", pysqlite_DatabaseError, NULL))) { goto error; } PyDict_SetItemString(dict, "ProgrammingError", pysqlite_ProgrammingError); if (!(pysqlite_IntegrityError = PyErr_NewException(MODULE_NAME ".IntegrityError", pysqlite_DatabaseError,NULL))) { goto error; } PyDict_SetItemString(dict, "IntegrityError", pysqlite_IntegrityError); if (!(pysqlite_DataError = PyErr_NewException(MODULE_NAME ".DataError", pysqlite_DatabaseError, NULL))) { goto error; } PyDict_SetItemString(dict, "DataError", pysqlite_DataError); if (!(pysqlite_NotSupportedError = PyErr_NewException(MODULE_NAME ".NotSupportedError", pysqlite_DatabaseError, NULL))) { goto error; } PyDict_SetItemString(dict, "NotSupportedError", pysqlite_NotSupportedError); /* We just need "something" unique for pysqlite_OptimizedUnicode. It does not really * need to be a string subclass. Just anything that can act as a special * marker for us. So I pulled PyCell_Type out of my magic hat. */ Py_INCREF((PyObject*)&PyCell_Type); pysqlite_OptimizedUnicode = (PyObject*)&PyCell_Type; PyDict_SetItemString(dict, "OptimizedUnicode", pysqlite_OptimizedUnicode); /* Set integer constants */ for (i = 0; _int_constants[i].constant_name != 0; i++) { tmp_obj = PyInt_FromLong(_int_constants[i].constant_value); if (!tmp_obj) { goto error; } PyDict_SetItemString(dict, _int_constants[i].constant_name, tmp_obj); Py_DECREF(tmp_obj); } if (!(tmp_obj = PyString_FromString(PYSQLITE_VERSION))) { goto error; } PyDict_SetItemString(dict, "version", tmp_obj); Py_DECREF(tmp_obj); if (!(tmp_obj = PyString_FromString(sqlite3_libversion()))) { goto error; } PyDict_SetItemString(dict, "sqlite_version", tmp_obj); Py_DECREF(tmp_obj); /* initialize microprotocols layer */ pysqlite_microprotocols_init(dict); /* initialize the default converters */ converters_init(dict); _enable_callback_tracebacks = 0; pysqlite_BaseTypeAdapted = 0; /* Original comment from _bsddb.c in the Python core. This is also still * needed nowadays for Python 2.3/2.4. * * PyEval_InitThreads is called here due to a quirk in python 1.5 * - 2.2.1 (at least) according to Russell Williamson : * The global interpreter lock is not initialized until the first * thread is created using thread.start_new_thread() or fork() is * called. that would cause the ALLOW_THREADS here to segfault due * to a null pointer reference if no threads or child processes * have been created. This works around that and is a no-op if * threads have already been initialized. * (see pybsddb-users mailing list post on 2002-08-07) */ #ifdef WITH_THREAD PyEval_InitThreads(); #endif error: if (PyErr_Occurred()) { PyErr_SetString(PyExc_ImportError, "pysqlite2._sqlite: init failed"); } } pysqlite-2.7.0/src/module.h000066400000000000000000000037421256035156500156350ustar00rootroot00000000000000/* module.h - definitions for the module * * Copyright (C) 2004-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #ifndef PYSQLITE_MODULE_H #define PYSQLITE_MODULE_H #include "Python.h" #define PYSQLITE_VERSION "2.7.0" extern PyObject* pysqlite_Error; extern PyObject* pysqlite_Warning; extern PyObject* pysqlite_InterfaceError; extern PyObject* pysqlite_DatabaseError; extern PyObject* pysqlite_InternalError; extern PyObject* pysqlite_OperationalError; extern PyObject* pysqlite_ProgrammingError; extern PyObject* pysqlite_IntegrityError; extern PyObject* pysqlite_DataError; extern PyObject* pysqlite_NotSupportedError; extern PyObject* pysqlite_OptimizedUnicode; /* the functions time.time() and time.sleep() */ extern PyObject* time_time; extern PyObject* time_sleep; /* A dictionary, mapping colum types (INTEGER, VARCHAR, etc.) to converter * functions, that convert the SQL value to the appropriate Python value. * The key is uppercase. */ extern PyObject* converters; extern int _enable_callback_tracebacks; extern int pysqlite_BaseTypeAdapted; #define PARSE_DECLTYPES 1 #define PARSE_COLNAMES 2 #endif pysqlite-2.7.0/src/prepare_protocol.c000066400000000000000000000105041256035156500177140ustar00rootroot00000000000000/* prepare_protocol.c - the protocol for preparing values for SQLite * * Copyright (C) 2005-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #include "sqlitecompat.h" #include "prepare_protocol.h" int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs) { return 0; } void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self) { Py_TYPE(self)->tp_free((PyObject*)self); } PyTypeObject pysqlite_PrepareProtocolType= { PyVarObject_HEAD_INIT(NULL, 0) MODULE_NAME ".PrepareProtocol", /* tp_name */ sizeof(pysqlite_PrepareProtocol), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pysqlite_prepare_protocol_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)pysqlite_prepare_protocol_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0 /* tp_free */ }; extern int pysqlite_prepare_protocol_setup_types(void) { pysqlite_PrepareProtocolType.tp_new = PyType_GenericNew; Py_TYPE(&pysqlite_PrepareProtocolType)= &PyType_Type; return PyType_Ready(&pysqlite_PrepareProtocolType); } pysqlite-2.7.0/src/prepare_protocol.h000066400000000000000000000027331256035156500177260ustar00rootroot00000000000000/* prepare_protocol.h - the protocol for preparing values for SQLite * * Copyright (C) 2005-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #ifndef PYSQLITE_PREPARE_PROTOCOL_H #define PYSQLITE_PREPARE_PROTOCOL_H #include "Python.h" typedef struct { PyObject_HEAD } pysqlite_PrepareProtocol; extern PyTypeObject pysqlite_PrepareProtocolType; int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs); void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self); int pysqlite_prepare_protocol_setup_types(void); #define UNKNOWN (-1) #endif pysqlite-2.7.0/src/row.c000066400000000000000000000212331256035156500151450ustar00rootroot00000000000000/* row.c - an enhanced tuple for database rows * * Copyright (C) 2005-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #include "row.h" #include "cursor.h" #include "sqlitecompat.h" void pysqlite_row_dealloc(pysqlite_Row* self) { Py_XDECREF(self->data); Py_XDECREF(self->description); Py_TYPE(self)->tp_free((PyObject*)self); } int pysqlite_row_init(pysqlite_Row* self, PyObject* args, PyObject* kwargs) { PyObject* data; pysqlite_Cursor* cursor; self->data = 0; self->description = 0; if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) { return -1; } if (!PyObject_IsInstance((PyObject*)cursor, (PyObject*)&pysqlite_CursorType)) { PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument"); return -1; } if (!PyTuple_Check(data)) { PyErr_SetString(PyExc_TypeError, "tuple required for second argument"); return -1; } Py_INCREF(data); self->data = data; Py_INCREF(cursor->description); self->description = cursor->description; return 0; } PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) { long _idx; char* key; int nitems, i; char* compare_key; char* p1; char* p2; PyObject* item; if (PyInt_Check(idx)) { _idx = PyInt_AsLong(idx); item = PyTuple_GetItem(self->data, _idx); Py_XINCREF(item); return item; } else if (PyLong_Check(idx)) { _idx = PyLong_AsLong(idx); item = PyTuple_GetItem(self->data, _idx); Py_XINCREF(item); return item; } else if (PyString_Check(idx)) { key = PyString_AsString(idx); nitems = PyTuple_Size(self->description); for (i = 0; i < nitems; i++) { compare_key = PyString_AsString(PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0)); if (!compare_key) { return NULL; } p1 = key; p2 = compare_key; while (1) { if ((*p1 == (char)0) || (*p2 == (char)0)) { break; } if ((*p1 | 0x20) != (*p2 | 0x20)) { break; } p1++; p2++; } if ((*p1 == (char)0) && (*p2 == (char)0)) { /* found item */ item = PyTuple_GetItem(self->data, i); Py_INCREF(item); return item; } } PyErr_SetString(PyExc_IndexError, "No item with that key"); return NULL; } else if (PySlice_Check(idx)) { PyErr_SetString(PyExc_ValueError, "slices not implemented, yet"); return NULL; } else { PyErr_SetString(PyExc_IndexError, "Index must be int or string"); return NULL; } } Py_ssize_t pysqlite_row_length(pysqlite_Row* self, PyObject* args, PyObject* kwargs) { return PyTuple_GET_SIZE(self->data); } PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject* args, PyObject* kwargs) { PyObject* list; int nitems, i; list = PyList_New(0); if (!list) { return NULL; } nitems = PyTuple_Size(self->description); for (i = 0; i < nitems; i++) { if (PyList_Append(list, PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0)) != 0) { Py_DECREF(list); return NULL; } } return list; } static int pysqlite_row_print(pysqlite_Row* self, FILE *fp, int flags) { return (&PyTuple_Type)->tp_print(self->data, fp, flags); } static PyObject* pysqlite_iter(pysqlite_Row* self) { return PyObject_GetIter(self->data); } static long pysqlite_row_hash(pysqlite_Row *self) { return PyObject_Hash(self->description) ^ PyObject_Hash(self->data); } static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, int opid) { if (opid != Py_EQ && opid != Py_NE) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } if (PyType_IsSubtype(Py_TYPE(_other), &pysqlite_RowType)) { pysqlite_Row *other = (pysqlite_Row *)_other; PyObject *res = PyObject_RichCompare(self->description, other->description, opid); if ((opid == Py_EQ && res == Py_True) || (opid == Py_NE && res == Py_False)) { Py_DECREF(res); return PyObject_RichCompare(self->data, other->data, opid); } } Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } PyMappingMethods pysqlite_row_as_mapping = { /* mp_length */ (lenfunc)pysqlite_row_length, /* mp_subscript */ (binaryfunc)pysqlite_row_subscript, /* mp_ass_subscript */ (objobjargproc)0, }; static PyMethodDef pysqlite_row_methods[] = { {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS, PyDoc_STR("Returns the keys of the row.")}, {NULL, NULL} }; PyTypeObject pysqlite_RowType = { PyVarObject_HEAD_INIT(NULL, 0) MODULE_NAME ".Row", /* tp_name */ sizeof(pysqlite_Row), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pysqlite_row_dealloc, /* tp_dealloc */ (printfunc)pysqlite_row_print, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc)pysqlite_row_hash, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ 0, /* tp_doc */ (traverseproc)0, /* tp_traverse */ 0, /* tp_clear */ (richcmpfunc)pysqlite_row_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ (getiterfunc)pysqlite_iter, /* tp_iter */ 0, /* tp_iternext */ pysqlite_row_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)pysqlite_row_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0 /* tp_free */ }; extern int pysqlite_row_setup_types(void) { pysqlite_RowType.tp_new = PyType_GenericNew; pysqlite_RowType.tp_as_mapping = &pysqlite_row_as_mapping; return PyType_Ready(&pysqlite_RowType); } pysqlite-2.7.0/src/row.h000066400000000000000000000023661256035156500151600ustar00rootroot00000000000000/* row.h - an enhanced tuple for database rows * * Copyright (C) 2005-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #ifndef PYSQLITE_ROW_H #define PYSQLITE_ROW_H #include "Python.h" typedef struct _Row { PyObject_HEAD PyObject* data; PyObject* description; } pysqlite_Row; extern PyTypeObject pysqlite_RowType; int pysqlite_row_setup_types(void); #endif pysqlite-2.7.0/src/sqlite_constants.h000066400000000000000000000703341256035156500177460ustar00rootroot00000000000000#ifdef SQLITE_VERSION_NUMBER {"SQLITE_VERSION_NUMBER", SQLITE_VERSION_NUMBER}, #endif #ifdef SQLITE_ABORT {"SQLITE_ABORT", SQLITE_ABORT}, #endif #ifdef SQLITE_AUTH {"SQLITE_AUTH", SQLITE_AUTH}, #endif #ifdef SQLITE_BUSY {"SQLITE_BUSY", SQLITE_BUSY}, #endif #ifdef SQLITE_CANTOPEN {"SQLITE_CANTOPEN", SQLITE_CANTOPEN}, #endif #ifdef SQLITE_CONSTRAINT {"SQLITE_CONSTRAINT", SQLITE_CONSTRAINT}, #endif #ifdef SQLITE_CORRUPT {"SQLITE_CORRUPT", SQLITE_CORRUPT}, #endif #ifdef SQLITE_DONE {"SQLITE_DONE", SQLITE_DONE}, #endif #ifdef SQLITE_EMPTY {"SQLITE_EMPTY", SQLITE_EMPTY}, #endif #ifdef SQLITE_ERROR {"SQLITE_ERROR", SQLITE_ERROR}, #endif #ifdef SQLITE_FORMAT {"SQLITE_FORMAT", SQLITE_FORMAT}, #endif #ifdef SQLITE_FULL {"SQLITE_FULL", SQLITE_FULL}, #endif #ifdef SQLITE_INTERNAL {"SQLITE_INTERNAL", SQLITE_INTERNAL}, #endif #ifdef SQLITE_INTERRUPT {"SQLITE_INTERRUPT", SQLITE_INTERRUPT}, #endif #ifdef SQLITE_IOERR {"SQLITE_IOERR", SQLITE_IOERR}, #endif #ifdef SQLITE_LOCKED {"SQLITE_LOCKED", SQLITE_LOCKED}, #endif #ifdef SQLITE_MISMATCH {"SQLITE_MISMATCH", SQLITE_MISMATCH}, #endif #ifdef SQLITE_MISUSE {"SQLITE_MISUSE", SQLITE_MISUSE}, #endif #ifdef SQLITE_NOLFS {"SQLITE_NOLFS", SQLITE_NOLFS}, #endif #ifdef SQLITE_NOMEM {"SQLITE_NOMEM", SQLITE_NOMEM}, #endif #ifdef SQLITE_NOTADB {"SQLITE_NOTADB", SQLITE_NOTADB}, #endif #ifdef SQLITE_NOTFOUND {"SQLITE_NOTFOUND", SQLITE_NOTFOUND}, #endif #ifdef SQLITE_NOTICE {"SQLITE_NOTICE", SQLITE_NOTICE}, #endif #ifdef SQLITE_OK {"SQLITE_OK", SQLITE_OK}, #endif #ifdef SQLITE_PERM {"SQLITE_PERM", SQLITE_PERM}, #endif #ifdef SQLITE_PROTOCOL {"SQLITE_PROTOCOL", SQLITE_PROTOCOL}, #endif #ifdef SQLITE_RANGE {"SQLITE_RANGE", SQLITE_RANGE}, #endif #ifdef SQLITE_READONLY {"SQLITE_READONLY", SQLITE_READONLY}, #endif #ifdef SQLITE_ROW {"SQLITE_ROW", SQLITE_ROW}, #endif #ifdef SQLITE_SCHEMA {"SQLITE_SCHEMA", SQLITE_SCHEMA}, #endif #ifdef SQLITE_TOOBIG {"SQLITE_TOOBIG", SQLITE_TOOBIG}, #endif #ifdef SQLITE_WARNING {"SQLITE_WARNING", SQLITE_WARNING}, #endif #ifdef SQLITE_ABORT_ROLLBACK {"SQLITE_ABORT_ROLLBACK", SQLITE_ABORT_ROLLBACK}, #endif #ifdef SQLITE_AUTH_USER {"SQLITE_AUTH_USER", SQLITE_AUTH_USER}, #endif #ifdef SQLITE_BUSY_RECOVERY {"SQLITE_BUSY_RECOVERY", SQLITE_BUSY_RECOVERY}, #endif #ifdef SQLITE_BUSY_SNAPSHOT {"SQLITE_BUSY_SNAPSHOT", SQLITE_BUSY_SNAPSHOT}, #endif #ifdef SQLITE_CANTOPEN_CONVPATH {"SQLITE_CANTOPEN_CONVPATH", SQLITE_CANTOPEN_CONVPATH}, #endif #ifdef SQLITE_CANTOPEN_FULLPATH {"SQLITE_CANTOPEN_FULLPATH", SQLITE_CANTOPEN_FULLPATH}, #endif #ifdef SQLITE_CANTOPEN_ISDIR {"SQLITE_CANTOPEN_ISDIR", SQLITE_CANTOPEN_ISDIR}, #endif #ifdef SQLITE_CANTOPEN_NOTEMPDIR {"SQLITE_CANTOPEN_NOTEMPDIR", SQLITE_CANTOPEN_NOTEMPDIR}, #endif #ifdef SQLITE_CONSTRAINT_CHECK {"SQLITE_CONSTRAINT_CHECK", SQLITE_CONSTRAINT_CHECK}, #endif #ifdef SQLITE_CONSTRAINT_COMMITHOOK {"SQLITE_CONSTRAINT_COMMITHOOK", SQLITE_CONSTRAINT_COMMITHOOK}, #endif #ifdef SQLITE_CONSTRAINT_FOREIGNKEY {"SQLITE_CONSTRAINT_FOREIGNKEY", SQLITE_CONSTRAINT_FOREIGNKEY}, #endif #ifdef SQLITE_CONSTRAINT_FUNCTION {"SQLITE_CONSTRAINT_FUNCTION", SQLITE_CONSTRAINT_FUNCTION}, #endif #ifdef SQLITE_CONSTRAINT_NOTNULL {"SQLITE_CONSTRAINT_NOTNULL", SQLITE_CONSTRAINT_NOTNULL}, #endif #ifdef SQLITE_CONSTRAINT_PRIMARYKEY {"SQLITE_CONSTRAINT_PRIMARYKEY", SQLITE_CONSTRAINT_PRIMARYKEY}, #endif #ifdef SQLITE_CONSTRAINT_ROWID {"SQLITE_CONSTRAINT_ROWID", SQLITE_CONSTRAINT_ROWID}, #endif #ifdef SQLITE_CONSTRAINT_TRIGGER {"SQLITE_CONSTRAINT_TRIGGER", SQLITE_CONSTRAINT_TRIGGER}, #endif #ifdef SQLITE_CONSTRAINT_UNIQUE {"SQLITE_CONSTRAINT_UNIQUE", SQLITE_CONSTRAINT_UNIQUE}, #endif #ifdef SQLITE_CONSTRAINT_VTAB {"SQLITE_CONSTRAINT_VTAB", SQLITE_CONSTRAINT_VTAB}, #endif #ifdef SQLITE_CORRUPT_VTAB {"SQLITE_CORRUPT_VTAB", SQLITE_CORRUPT_VTAB}, #endif #ifdef SQLITE_IOERR_ACCESS {"SQLITE_IOERR_ACCESS", SQLITE_IOERR_ACCESS}, #endif #ifdef SQLITE_IOERR_BLOCKED {"SQLITE_IOERR_BLOCKED", SQLITE_IOERR_BLOCKED}, #endif #ifdef SQLITE_IOERR_CHECKRESERVEDLOCK {"SQLITE_IOERR_CHECKRESERVEDLOCK", SQLITE_IOERR_CHECKRESERVEDLOCK}, #endif #ifdef SQLITE_IOERR_CLOSE {"SQLITE_IOERR_CLOSE", SQLITE_IOERR_CLOSE}, #endif #ifdef SQLITE_IOERR_CONVPATH {"SQLITE_IOERR_CONVPATH", SQLITE_IOERR_CONVPATH}, #endif #ifdef SQLITE_IOERR_DELETE {"SQLITE_IOERR_DELETE", SQLITE_IOERR_DELETE}, #endif #ifdef SQLITE_IOERR_DELETE_NOENT {"SQLITE_IOERR_DELETE_NOENT", SQLITE_IOERR_DELETE_NOENT}, #endif #ifdef SQLITE_IOERR_DIR_CLOSE {"SQLITE_IOERR_DIR_CLOSE", SQLITE_IOERR_DIR_CLOSE}, #endif #ifdef SQLITE_IOERR_DIR_FSYNC {"SQLITE_IOERR_DIR_FSYNC", SQLITE_IOERR_DIR_FSYNC}, #endif #ifdef SQLITE_IOERR_FSTAT {"SQLITE_IOERR_FSTAT", SQLITE_IOERR_FSTAT}, #endif #ifdef SQLITE_IOERR_FSYNC {"SQLITE_IOERR_FSYNC", SQLITE_IOERR_FSYNC}, #endif #ifdef SQLITE_IOERR_GETTEMPPATH {"SQLITE_IOERR_GETTEMPPATH", SQLITE_IOERR_GETTEMPPATH}, #endif #ifdef SQLITE_IOERR_LOCK {"SQLITE_IOERR_LOCK", SQLITE_IOERR_LOCK}, #endif #ifdef SQLITE_IOERR_MMAP {"SQLITE_IOERR_MMAP", SQLITE_IOERR_MMAP}, #endif #ifdef SQLITE_IOERR_NOMEM {"SQLITE_IOERR_NOMEM", SQLITE_IOERR_NOMEM}, #endif #ifdef SQLITE_IOERR_RDLOCK {"SQLITE_IOERR_RDLOCK", SQLITE_IOERR_RDLOCK}, #endif #ifdef SQLITE_IOERR_READ {"SQLITE_IOERR_READ", SQLITE_IOERR_READ}, #endif #ifdef SQLITE_IOERR_SEEK {"SQLITE_IOERR_SEEK", SQLITE_IOERR_SEEK}, #endif #ifdef SQLITE_IOERR_SHMLOCK {"SQLITE_IOERR_SHMLOCK", SQLITE_IOERR_SHMLOCK}, #endif #ifdef SQLITE_IOERR_SHMMAP {"SQLITE_IOERR_SHMMAP", SQLITE_IOERR_SHMMAP}, #endif #ifdef SQLITE_IOERR_SHMOPEN {"SQLITE_IOERR_SHMOPEN", SQLITE_IOERR_SHMOPEN}, #endif #ifdef SQLITE_IOERR_SHMSIZE {"SQLITE_IOERR_SHMSIZE", SQLITE_IOERR_SHMSIZE}, #endif #ifdef SQLITE_IOERR_SHORT_READ {"SQLITE_IOERR_SHORT_READ", SQLITE_IOERR_SHORT_READ}, #endif #ifdef SQLITE_IOERR_TRUNCATE {"SQLITE_IOERR_TRUNCATE", SQLITE_IOERR_TRUNCATE}, #endif #ifdef SQLITE_IOERR_UNLOCK {"SQLITE_IOERR_UNLOCK", SQLITE_IOERR_UNLOCK}, #endif #ifdef SQLITE_IOERR_WRITE {"SQLITE_IOERR_WRITE", SQLITE_IOERR_WRITE}, #endif #ifdef SQLITE_LOCKED_SHAREDCACHE {"SQLITE_LOCKED_SHAREDCACHE", SQLITE_LOCKED_SHAREDCACHE}, #endif #ifdef SQLITE_NOTICE_RECOVER_ROLLBACK {"SQLITE_NOTICE_RECOVER_ROLLBACK", SQLITE_NOTICE_RECOVER_ROLLBACK}, #endif #ifdef SQLITE_NOTICE_RECOVER_WAL {"SQLITE_NOTICE_RECOVER_WAL", SQLITE_NOTICE_RECOVER_WAL}, #endif #ifdef SQLITE_READONLY_CANTLOCK {"SQLITE_READONLY_CANTLOCK", SQLITE_READONLY_CANTLOCK}, #endif #ifdef SQLITE_READONLY_DBMOVED {"SQLITE_READONLY_DBMOVED", SQLITE_READONLY_DBMOVED}, #endif #ifdef SQLITE_READONLY_RECOVERY {"SQLITE_READONLY_RECOVERY", SQLITE_READONLY_RECOVERY}, #endif #ifdef SQLITE_READONLY_ROLLBACK {"SQLITE_READONLY_ROLLBACK", SQLITE_READONLY_ROLLBACK}, #endif #ifdef SQLITE_WARNING_AUTOINDEX {"SQLITE_WARNING_AUTOINDEX", SQLITE_WARNING_AUTOINDEX}, #endif #ifdef SQLITE_OPEN_AUTOPROXY {"SQLITE_OPEN_AUTOPROXY", SQLITE_OPEN_AUTOPROXY}, #endif #ifdef SQLITE_OPEN_CREATE {"SQLITE_OPEN_CREATE", SQLITE_OPEN_CREATE}, #endif #ifdef SQLITE_OPEN_DELETEONCLOSE {"SQLITE_OPEN_DELETEONCLOSE", SQLITE_OPEN_DELETEONCLOSE}, #endif #ifdef SQLITE_OPEN_EXCLUSIVE {"SQLITE_OPEN_EXCLUSIVE", SQLITE_OPEN_EXCLUSIVE}, #endif #ifdef SQLITE_OPEN_FULLMUTEX {"SQLITE_OPEN_FULLMUTEX", SQLITE_OPEN_FULLMUTEX}, #endif #ifdef SQLITE_OPEN_MAIN_DB {"SQLITE_OPEN_MAIN_DB", SQLITE_OPEN_MAIN_DB}, #endif #ifdef SQLITE_OPEN_MAIN_JOURNAL {"SQLITE_OPEN_MAIN_JOURNAL", SQLITE_OPEN_MAIN_JOURNAL}, #endif #ifdef SQLITE_OPEN_MASTER_JOURNAL {"SQLITE_OPEN_MASTER_JOURNAL", SQLITE_OPEN_MASTER_JOURNAL}, #endif #ifdef SQLITE_OPEN_MEMORY {"SQLITE_OPEN_MEMORY", SQLITE_OPEN_MEMORY}, #endif #ifdef SQLITE_OPEN_NOMUTEX {"SQLITE_OPEN_NOMUTEX", SQLITE_OPEN_NOMUTEX}, #endif #ifdef SQLITE_OPEN_PRIVATECACHE {"SQLITE_OPEN_PRIVATECACHE", SQLITE_OPEN_PRIVATECACHE}, #endif #ifdef SQLITE_OPEN_READONLY {"SQLITE_OPEN_READONLY", SQLITE_OPEN_READONLY}, #endif #ifdef SQLITE_OPEN_READWRITE {"SQLITE_OPEN_READWRITE", SQLITE_OPEN_READWRITE}, #endif #ifdef SQLITE_OPEN_SHAREDCACHE {"SQLITE_OPEN_SHAREDCACHE", SQLITE_OPEN_SHAREDCACHE}, #endif #ifdef SQLITE_OPEN_SUBJOURNAL {"SQLITE_OPEN_SUBJOURNAL", SQLITE_OPEN_SUBJOURNAL}, #endif #ifdef SQLITE_OPEN_TEMP_DB {"SQLITE_OPEN_TEMP_DB", SQLITE_OPEN_TEMP_DB}, #endif #ifdef SQLITE_OPEN_TEMP_JOURNAL {"SQLITE_OPEN_TEMP_JOURNAL", SQLITE_OPEN_TEMP_JOURNAL}, #endif #ifdef SQLITE_OPEN_TRANSIENT_DB {"SQLITE_OPEN_TRANSIENT_DB", SQLITE_OPEN_TRANSIENT_DB}, #endif #ifdef SQLITE_OPEN_URI {"SQLITE_OPEN_URI", SQLITE_OPEN_URI}, #endif #ifdef SQLITE_OPEN_WAL {"SQLITE_OPEN_WAL", SQLITE_OPEN_WAL}, #endif #ifdef SQLITE_IOCAP_ATOMIC {"SQLITE_IOCAP_ATOMIC", SQLITE_IOCAP_ATOMIC}, #endif #ifdef SQLITE_IOCAP_ATOMIC16K {"SQLITE_IOCAP_ATOMIC16K", SQLITE_IOCAP_ATOMIC16K}, #endif #ifdef SQLITE_IOCAP_ATOMIC1K {"SQLITE_IOCAP_ATOMIC1K", SQLITE_IOCAP_ATOMIC1K}, #endif #ifdef SQLITE_IOCAP_ATOMIC2K {"SQLITE_IOCAP_ATOMIC2K", SQLITE_IOCAP_ATOMIC2K}, #endif #ifdef SQLITE_IOCAP_ATOMIC32K {"SQLITE_IOCAP_ATOMIC32K", SQLITE_IOCAP_ATOMIC32K}, #endif #ifdef SQLITE_IOCAP_ATOMIC4K {"SQLITE_IOCAP_ATOMIC4K", SQLITE_IOCAP_ATOMIC4K}, #endif #ifdef SQLITE_IOCAP_ATOMIC512 {"SQLITE_IOCAP_ATOMIC512", SQLITE_IOCAP_ATOMIC512}, #endif #ifdef SQLITE_IOCAP_ATOMIC64K {"SQLITE_IOCAP_ATOMIC64K", SQLITE_IOCAP_ATOMIC64K}, #endif #ifdef SQLITE_IOCAP_ATOMIC8K {"SQLITE_IOCAP_ATOMIC8K", SQLITE_IOCAP_ATOMIC8K}, #endif #ifdef SQLITE_IOCAP_IMMUTABLE {"SQLITE_IOCAP_IMMUTABLE", SQLITE_IOCAP_IMMUTABLE}, #endif #ifdef SQLITE_IOCAP_POWERSAFE_OVERWRITE {"SQLITE_IOCAP_POWERSAFE_OVERWRITE", SQLITE_IOCAP_POWERSAFE_OVERWRITE}, #endif #ifdef SQLITE_IOCAP_SAFE_APPEND {"SQLITE_IOCAP_SAFE_APPEND", SQLITE_IOCAP_SAFE_APPEND}, #endif #ifdef SQLITE_IOCAP_SEQUENTIAL {"SQLITE_IOCAP_SEQUENTIAL", SQLITE_IOCAP_SEQUENTIAL}, #endif #ifdef SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN {"SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN", SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN}, #endif #ifdef SQLITE_LOCK_EXCLUSIVE {"SQLITE_LOCK_EXCLUSIVE", SQLITE_LOCK_EXCLUSIVE}, #endif #ifdef SQLITE_LOCK_NONE {"SQLITE_LOCK_NONE", SQLITE_LOCK_NONE}, #endif #ifdef SQLITE_LOCK_PENDING {"SQLITE_LOCK_PENDING", SQLITE_LOCK_PENDING}, #endif #ifdef SQLITE_LOCK_RESERVED {"SQLITE_LOCK_RESERVED", SQLITE_LOCK_RESERVED}, #endif #ifdef SQLITE_LOCK_SHARED {"SQLITE_LOCK_SHARED", SQLITE_LOCK_SHARED}, #endif #ifdef SQLITE_SYNC_DATAONLY {"SQLITE_SYNC_DATAONLY", SQLITE_SYNC_DATAONLY}, #endif #ifdef SQLITE_SYNC_FULL {"SQLITE_SYNC_FULL", SQLITE_SYNC_FULL}, #endif #ifdef SQLITE_SYNC_NORMAL {"SQLITE_SYNC_NORMAL", SQLITE_SYNC_NORMAL}, #endif #ifdef SQLITE_FCNTL_BUSYHANDLER {"SQLITE_FCNTL_BUSYHANDLER", SQLITE_FCNTL_BUSYHANDLER}, #endif #ifdef SQLITE_FCNTL_CHUNK_SIZE {"SQLITE_FCNTL_CHUNK_SIZE", SQLITE_FCNTL_CHUNK_SIZE}, #endif #ifdef SQLITE_FCNTL_COMMIT_PHASETWO {"SQLITE_FCNTL_COMMIT_PHASETWO", SQLITE_FCNTL_COMMIT_PHASETWO}, #endif #ifdef SQLITE_FCNTL_FILE_POINTER {"SQLITE_FCNTL_FILE_POINTER", SQLITE_FCNTL_FILE_POINTER}, #endif #ifdef SQLITE_FCNTL_GET_LOCKPROXYFILE {"SQLITE_FCNTL_GET_LOCKPROXYFILE", SQLITE_FCNTL_GET_LOCKPROXYFILE}, #endif #ifdef SQLITE_FCNTL_HAS_MOVED {"SQLITE_FCNTL_HAS_MOVED", SQLITE_FCNTL_HAS_MOVED}, #endif #ifdef SQLITE_FCNTL_LAST_ERRNO {"SQLITE_FCNTL_LAST_ERRNO", SQLITE_FCNTL_LAST_ERRNO}, #endif #ifdef SQLITE_FCNTL_LOCKSTATE {"SQLITE_FCNTL_LOCKSTATE", SQLITE_FCNTL_LOCKSTATE}, #endif #ifdef SQLITE_FCNTL_MMAP_SIZE {"SQLITE_FCNTL_MMAP_SIZE", SQLITE_FCNTL_MMAP_SIZE}, #endif #ifdef SQLITE_FCNTL_OVERWRITE {"SQLITE_FCNTL_OVERWRITE", SQLITE_FCNTL_OVERWRITE}, #endif #ifdef SQLITE_FCNTL_PERSIST_WAL {"SQLITE_FCNTL_PERSIST_WAL", SQLITE_FCNTL_PERSIST_WAL}, #endif #ifdef SQLITE_FCNTL_POWERSAFE_OVERWRITE {"SQLITE_FCNTL_POWERSAFE_OVERWRITE", SQLITE_FCNTL_POWERSAFE_OVERWRITE}, #endif #ifdef SQLITE_FCNTL_PRAGMA {"SQLITE_FCNTL_PRAGMA", SQLITE_FCNTL_PRAGMA}, #endif #ifdef SQLITE_FCNTL_RBU {"SQLITE_FCNTL_RBU", SQLITE_FCNTL_RBU}, #endif #ifdef SQLITE_FCNTL_SET_LOCKPROXYFILE {"SQLITE_FCNTL_SET_LOCKPROXYFILE", SQLITE_FCNTL_SET_LOCKPROXYFILE}, #endif #ifdef SQLITE_FCNTL_SIZE_HINT {"SQLITE_FCNTL_SIZE_HINT", SQLITE_FCNTL_SIZE_HINT}, #endif #ifdef SQLITE_FCNTL_SYNC {"SQLITE_FCNTL_SYNC", SQLITE_FCNTL_SYNC}, #endif #ifdef SQLITE_FCNTL_SYNC_OMITTED {"SQLITE_FCNTL_SYNC_OMITTED", SQLITE_FCNTL_SYNC_OMITTED}, #endif #ifdef SQLITE_FCNTL_TEMPFILENAME {"SQLITE_FCNTL_TEMPFILENAME", SQLITE_FCNTL_TEMPFILENAME}, #endif #ifdef SQLITE_FCNTL_TRACE {"SQLITE_FCNTL_TRACE", SQLITE_FCNTL_TRACE}, #endif #ifdef SQLITE_FCNTL_VFSNAME {"SQLITE_FCNTL_VFSNAME", SQLITE_FCNTL_VFSNAME}, #endif #ifdef SQLITE_FCNTL_WAL_BLOCK {"SQLITE_FCNTL_WAL_BLOCK", SQLITE_FCNTL_WAL_BLOCK}, #endif #ifdef SQLITE_FCNTL_WIN32_AV_RETRY {"SQLITE_FCNTL_WIN32_AV_RETRY", SQLITE_FCNTL_WIN32_AV_RETRY}, #endif #ifdef SQLITE_FCNTL_WIN32_SET_HANDLE {"SQLITE_FCNTL_WIN32_SET_HANDLE", SQLITE_FCNTL_WIN32_SET_HANDLE}, #endif #ifdef SQLITE_FCNTL_ZIPVFS {"SQLITE_FCNTL_ZIPVFS", SQLITE_FCNTL_ZIPVFS}, #endif #ifdef SQLITE_ACCESS_EXISTS {"SQLITE_ACCESS_EXISTS", SQLITE_ACCESS_EXISTS}, #endif #ifdef SQLITE_ACCESS_READ {"SQLITE_ACCESS_READ", SQLITE_ACCESS_READ}, #endif #ifdef SQLITE_ACCESS_READWRITE {"SQLITE_ACCESS_READWRITE", SQLITE_ACCESS_READWRITE}, #endif #ifdef SQLITE_SHM_EXCLUSIVE {"SQLITE_SHM_EXCLUSIVE", SQLITE_SHM_EXCLUSIVE}, #endif #ifdef SQLITE_SHM_LOCK {"SQLITE_SHM_LOCK", SQLITE_SHM_LOCK}, #endif #ifdef SQLITE_SHM_SHARED {"SQLITE_SHM_SHARED", SQLITE_SHM_SHARED}, #endif #ifdef SQLITE_SHM_UNLOCK {"SQLITE_SHM_UNLOCK", SQLITE_SHM_UNLOCK}, #endif #ifdef SQLITE_SHM_NLOCK {"SQLITE_SHM_NLOCK", SQLITE_SHM_NLOCK}, #endif #ifdef SQLITE_CONFIG_COVERING_INDEX_SCAN {"SQLITE_CONFIG_COVERING_INDEX_SCAN", SQLITE_CONFIG_COVERING_INDEX_SCAN}, #endif #ifdef SQLITE_CONFIG_GETMALLOC {"SQLITE_CONFIG_GETMALLOC", SQLITE_CONFIG_GETMALLOC}, #endif #ifdef SQLITE_CONFIG_GETMUTEX {"SQLITE_CONFIG_GETMUTEX", SQLITE_CONFIG_GETMUTEX}, #endif #ifdef SQLITE_CONFIG_GETPCACHE {"SQLITE_CONFIG_GETPCACHE", SQLITE_CONFIG_GETPCACHE}, #endif #ifdef SQLITE_CONFIG_GETPCACHE2 {"SQLITE_CONFIG_GETPCACHE2", SQLITE_CONFIG_GETPCACHE2}, #endif #ifdef SQLITE_CONFIG_HEAP {"SQLITE_CONFIG_HEAP", SQLITE_CONFIG_HEAP}, #endif #ifdef SQLITE_CONFIG_LOG {"SQLITE_CONFIG_LOG", SQLITE_CONFIG_LOG}, #endif #ifdef SQLITE_CONFIG_LOOKASIDE {"SQLITE_CONFIG_LOOKASIDE", SQLITE_CONFIG_LOOKASIDE}, #endif #ifdef SQLITE_CONFIG_MALLOC {"SQLITE_CONFIG_MALLOC", SQLITE_CONFIG_MALLOC}, #endif #ifdef SQLITE_CONFIG_MEMSTATUS {"SQLITE_CONFIG_MEMSTATUS", SQLITE_CONFIG_MEMSTATUS}, #endif #ifdef SQLITE_CONFIG_MMAP_SIZE {"SQLITE_CONFIG_MMAP_SIZE", SQLITE_CONFIG_MMAP_SIZE}, #endif #ifdef SQLITE_CONFIG_MULTITHREAD {"SQLITE_CONFIG_MULTITHREAD", SQLITE_CONFIG_MULTITHREAD}, #endif #ifdef SQLITE_CONFIG_MUTEX {"SQLITE_CONFIG_MUTEX", SQLITE_CONFIG_MUTEX}, #endif #ifdef SQLITE_CONFIG_PAGECACHE {"SQLITE_CONFIG_PAGECACHE", SQLITE_CONFIG_PAGECACHE}, #endif #ifdef SQLITE_CONFIG_PCACHE {"SQLITE_CONFIG_PCACHE", SQLITE_CONFIG_PCACHE}, #endif #ifdef SQLITE_CONFIG_PCACHE2 {"SQLITE_CONFIG_PCACHE2", SQLITE_CONFIG_PCACHE2}, #endif #ifdef SQLITE_CONFIG_PCACHE_HDRSZ {"SQLITE_CONFIG_PCACHE_HDRSZ", SQLITE_CONFIG_PCACHE_HDRSZ}, #endif #ifdef SQLITE_CONFIG_PMASZ {"SQLITE_CONFIG_PMASZ", SQLITE_CONFIG_PMASZ}, #endif #ifdef SQLITE_CONFIG_SCRATCH {"SQLITE_CONFIG_SCRATCH", SQLITE_CONFIG_SCRATCH}, #endif #ifdef SQLITE_CONFIG_SERIALIZED {"SQLITE_CONFIG_SERIALIZED", SQLITE_CONFIG_SERIALIZED}, #endif #ifdef SQLITE_CONFIG_SINGLETHREAD {"SQLITE_CONFIG_SINGLETHREAD", SQLITE_CONFIG_SINGLETHREAD}, #endif #ifdef SQLITE_CONFIG_SQLLOG {"SQLITE_CONFIG_SQLLOG", SQLITE_CONFIG_SQLLOG}, #endif #ifdef SQLITE_CONFIG_URI {"SQLITE_CONFIG_URI", SQLITE_CONFIG_URI}, #endif #ifdef SQLITE_CONFIG_WIN32_HEAPSIZE {"SQLITE_CONFIG_WIN32_HEAPSIZE", SQLITE_CONFIG_WIN32_HEAPSIZE}, #endif #ifdef SQLITE_DBCONFIG_ENABLE_FKEY {"SQLITE_DBCONFIG_ENABLE_FKEY", SQLITE_DBCONFIG_ENABLE_FKEY}, #endif #ifdef SQLITE_DBCONFIG_ENABLE_TRIGGER {"SQLITE_DBCONFIG_ENABLE_TRIGGER", SQLITE_DBCONFIG_ENABLE_TRIGGER}, #endif #ifdef SQLITE_DBCONFIG_LOOKASIDE {"SQLITE_DBCONFIG_LOOKASIDE", SQLITE_DBCONFIG_LOOKASIDE}, #endif #ifdef SQLITE_DENY {"SQLITE_DENY", SQLITE_DENY}, #endif #ifdef SQLITE_IGNORE {"SQLITE_IGNORE", SQLITE_IGNORE}, #endif #ifdef SQLITE_ALTER_TABLE {"SQLITE_ALTER_TABLE", SQLITE_ALTER_TABLE}, #endif #ifdef SQLITE_ANALYZE {"SQLITE_ANALYZE", SQLITE_ANALYZE}, #endif #ifdef SQLITE_ATTACH {"SQLITE_ATTACH", SQLITE_ATTACH}, #endif #ifdef SQLITE_COPY {"SQLITE_COPY", SQLITE_COPY}, #endif #ifdef SQLITE_CREATE_INDEX {"SQLITE_CREATE_INDEX", SQLITE_CREATE_INDEX}, #endif #ifdef SQLITE_CREATE_TABLE {"SQLITE_CREATE_TABLE", SQLITE_CREATE_TABLE}, #endif #ifdef SQLITE_CREATE_TEMP_INDEX {"SQLITE_CREATE_TEMP_INDEX", SQLITE_CREATE_TEMP_INDEX}, #endif #ifdef SQLITE_CREATE_TEMP_TABLE {"SQLITE_CREATE_TEMP_TABLE", SQLITE_CREATE_TEMP_TABLE}, #endif #ifdef SQLITE_CREATE_TEMP_TRIGGER {"SQLITE_CREATE_TEMP_TRIGGER", SQLITE_CREATE_TEMP_TRIGGER}, #endif #ifdef SQLITE_CREATE_TEMP_VIEW {"SQLITE_CREATE_TEMP_VIEW", SQLITE_CREATE_TEMP_VIEW}, #endif #ifdef SQLITE_CREATE_TRIGGER {"SQLITE_CREATE_TRIGGER", SQLITE_CREATE_TRIGGER}, #endif #ifdef SQLITE_CREATE_VIEW {"SQLITE_CREATE_VIEW", SQLITE_CREATE_VIEW}, #endif #ifdef SQLITE_CREATE_VTABLE {"SQLITE_CREATE_VTABLE", SQLITE_CREATE_VTABLE}, #endif #ifdef SQLITE_DELETE {"SQLITE_DELETE", SQLITE_DELETE}, #endif #ifdef SQLITE_DETACH {"SQLITE_DETACH", SQLITE_DETACH}, #endif #ifdef SQLITE_DROP_INDEX {"SQLITE_DROP_INDEX", SQLITE_DROP_INDEX}, #endif #ifdef SQLITE_DROP_TABLE {"SQLITE_DROP_TABLE", SQLITE_DROP_TABLE}, #endif #ifdef SQLITE_DROP_TEMP_INDEX {"SQLITE_DROP_TEMP_INDEX", SQLITE_DROP_TEMP_INDEX}, #endif #ifdef SQLITE_DROP_TEMP_TABLE {"SQLITE_DROP_TEMP_TABLE", SQLITE_DROP_TEMP_TABLE}, #endif #ifdef SQLITE_DROP_TEMP_TRIGGER {"SQLITE_DROP_TEMP_TRIGGER", SQLITE_DROP_TEMP_TRIGGER}, #endif #ifdef SQLITE_DROP_TEMP_VIEW {"SQLITE_DROP_TEMP_VIEW", SQLITE_DROP_TEMP_VIEW}, #endif #ifdef SQLITE_DROP_TRIGGER {"SQLITE_DROP_TRIGGER", SQLITE_DROP_TRIGGER}, #endif #ifdef SQLITE_DROP_VIEW {"SQLITE_DROP_VIEW", SQLITE_DROP_VIEW}, #endif #ifdef SQLITE_DROP_VTABLE {"SQLITE_DROP_VTABLE", SQLITE_DROP_VTABLE}, #endif #ifdef SQLITE_FUNCTION {"SQLITE_FUNCTION", SQLITE_FUNCTION}, #endif #ifdef SQLITE_INSERT {"SQLITE_INSERT", SQLITE_INSERT}, #endif #ifdef SQLITE_PRAGMA {"SQLITE_PRAGMA", SQLITE_PRAGMA}, #endif #ifdef SQLITE_READ {"SQLITE_READ", SQLITE_READ}, #endif #ifdef SQLITE_RECURSIVE {"SQLITE_RECURSIVE", SQLITE_RECURSIVE}, #endif #ifdef SQLITE_REINDEX {"SQLITE_REINDEX", SQLITE_REINDEX}, #endif #ifdef SQLITE_SAVEPOINT {"SQLITE_SAVEPOINT", SQLITE_SAVEPOINT}, #endif #ifdef SQLITE_SELECT {"SQLITE_SELECT", SQLITE_SELECT}, #endif #ifdef SQLITE_TRANSACTION {"SQLITE_TRANSACTION", SQLITE_TRANSACTION}, #endif #ifdef SQLITE_UPDATE {"SQLITE_UPDATE", SQLITE_UPDATE}, #endif #ifdef SQLITE_LIMIT_ATTACHED {"SQLITE_LIMIT_ATTACHED", SQLITE_LIMIT_ATTACHED}, #endif #ifdef SQLITE_LIMIT_COLUMN {"SQLITE_LIMIT_COLUMN", SQLITE_LIMIT_COLUMN}, #endif #ifdef SQLITE_LIMIT_COMPOUND_SELECT {"SQLITE_LIMIT_COMPOUND_SELECT", SQLITE_LIMIT_COMPOUND_SELECT}, #endif #ifdef SQLITE_LIMIT_EXPR_DEPTH {"SQLITE_LIMIT_EXPR_DEPTH", SQLITE_LIMIT_EXPR_DEPTH}, #endif #ifdef SQLITE_LIMIT_FUNCTION_ARG {"SQLITE_LIMIT_FUNCTION_ARG", SQLITE_LIMIT_FUNCTION_ARG}, #endif #ifdef SQLITE_LIMIT_LENGTH {"SQLITE_LIMIT_LENGTH", SQLITE_LIMIT_LENGTH}, #endif #ifdef SQLITE_LIMIT_LIKE_PATTERN_LENGTH {"SQLITE_LIMIT_LIKE_PATTERN_LENGTH", SQLITE_LIMIT_LIKE_PATTERN_LENGTH}, #endif #ifdef SQLITE_LIMIT_SQL_LENGTH {"SQLITE_LIMIT_SQL_LENGTH", SQLITE_LIMIT_SQL_LENGTH}, #endif #ifdef SQLITE_LIMIT_TRIGGER_DEPTH {"SQLITE_LIMIT_TRIGGER_DEPTH", SQLITE_LIMIT_TRIGGER_DEPTH}, #endif #ifdef SQLITE_LIMIT_VARIABLE_NUMBER {"SQLITE_LIMIT_VARIABLE_NUMBER", SQLITE_LIMIT_VARIABLE_NUMBER}, #endif #ifdef SQLITE_LIMIT_VDBE_OP {"SQLITE_LIMIT_VDBE_OP", SQLITE_LIMIT_VDBE_OP}, #endif #ifdef SQLITE_LIMIT_WORKER_THREADS {"SQLITE_LIMIT_WORKER_THREADS", SQLITE_LIMIT_WORKER_THREADS}, #endif #ifdef SQLITE_BLOB {"SQLITE_BLOB", SQLITE_BLOB}, #endif #ifdef SQLITE_FLOAT {"SQLITE_FLOAT", SQLITE_FLOAT}, #endif #ifdef SQLITE_INTEGER {"SQLITE_INTEGER", SQLITE_INTEGER}, #endif #ifdef SQLITE_NULL {"SQLITE_NULL", SQLITE_NULL}, #endif #ifdef SQLITE_TEXT {"SQLITE_TEXT", SQLITE_TEXT}, #endif #ifdef SQLITE_ANY {"SQLITE_ANY", SQLITE_ANY}, #endif #ifdef SQLITE_UTF16 {"SQLITE_UTF16", SQLITE_UTF16}, #endif #ifdef SQLITE_UTF16BE {"SQLITE_UTF16BE", SQLITE_UTF16BE}, #endif #ifdef SQLITE_UTF16LE {"SQLITE_UTF16LE", SQLITE_UTF16LE}, #endif #ifdef SQLITE_UTF16_ALIGNED {"SQLITE_UTF16_ALIGNED", SQLITE_UTF16_ALIGNED}, #endif #ifdef SQLITE_UTF8 {"SQLITE_UTF8", SQLITE_UTF8}, #endif #ifdef SQLITE_DETERMINISTIC {"SQLITE_DETERMINISTIC", SQLITE_DETERMINISTIC}, #endif #ifdef SQLITE_STATIC {"SQLITE_STATIC", SQLITE_STATIC}, #endif #ifdef SQLITE_TRANSIENT {"SQLITE_TRANSIENT", SQLITE_TRANSIENT}, #endif #ifdef SQLITE_INDEX_CONSTRAINT_EQ {"SQLITE_INDEX_CONSTRAINT_EQ", SQLITE_INDEX_CONSTRAINT_EQ}, #endif #ifdef SQLITE_INDEX_CONSTRAINT_GE {"SQLITE_INDEX_CONSTRAINT_GE", SQLITE_INDEX_CONSTRAINT_GE}, #endif #ifdef SQLITE_INDEX_CONSTRAINT_GT {"SQLITE_INDEX_CONSTRAINT_GT", SQLITE_INDEX_CONSTRAINT_GT}, #endif #ifdef SQLITE_INDEX_CONSTRAINT_LE {"SQLITE_INDEX_CONSTRAINT_LE", SQLITE_INDEX_CONSTRAINT_LE}, #endif #ifdef SQLITE_INDEX_CONSTRAINT_LT {"SQLITE_INDEX_CONSTRAINT_LT", SQLITE_INDEX_CONSTRAINT_LT}, #endif #ifdef SQLITE_INDEX_CONSTRAINT_MATCH {"SQLITE_INDEX_CONSTRAINT_MATCH", SQLITE_INDEX_CONSTRAINT_MATCH}, #endif #ifdef SQLITE_MUTEX_FAST {"SQLITE_MUTEX_FAST", SQLITE_MUTEX_FAST}, #endif #ifdef SQLITE_MUTEX_RECURSIVE {"SQLITE_MUTEX_RECURSIVE", SQLITE_MUTEX_RECURSIVE}, #endif #ifdef SQLITE_MUTEX_STATIC_APP1 {"SQLITE_MUTEX_STATIC_APP1", SQLITE_MUTEX_STATIC_APP1}, #endif #ifdef SQLITE_MUTEX_STATIC_APP2 {"SQLITE_MUTEX_STATIC_APP2", SQLITE_MUTEX_STATIC_APP2}, #endif #ifdef SQLITE_MUTEX_STATIC_APP3 {"SQLITE_MUTEX_STATIC_APP3", SQLITE_MUTEX_STATIC_APP3}, #endif #ifdef SQLITE_MUTEX_STATIC_LRU {"SQLITE_MUTEX_STATIC_LRU", SQLITE_MUTEX_STATIC_LRU}, #endif #ifdef SQLITE_MUTEX_STATIC_LRU2 {"SQLITE_MUTEX_STATIC_LRU2", SQLITE_MUTEX_STATIC_LRU2}, #endif #ifdef SQLITE_MUTEX_STATIC_MASTER {"SQLITE_MUTEX_STATIC_MASTER", SQLITE_MUTEX_STATIC_MASTER}, #endif #ifdef SQLITE_MUTEX_STATIC_MEM {"SQLITE_MUTEX_STATIC_MEM", SQLITE_MUTEX_STATIC_MEM}, #endif #ifdef SQLITE_MUTEX_STATIC_MEM2 {"SQLITE_MUTEX_STATIC_MEM2", SQLITE_MUTEX_STATIC_MEM2}, #endif #ifdef SQLITE_MUTEX_STATIC_OPEN {"SQLITE_MUTEX_STATIC_OPEN", SQLITE_MUTEX_STATIC_OPEN}, #endif #ifdef SQLITE_MUTEX_STATIC_PMEM {"SQLITE_MUTEX_STATIC_PMEM", SQLITE_MUTEX_STATIC_PMEM}, #endif #ifdef SQLITE_MUTEX_STATIC_PRNG {"SQLITE_MUTEX_STATIC_PRNG", SQLITE_MUTEX_STATIC_PRNG}, #endif #ifdef SQLITE_MUTEX_STATIC_VFS1 {"SQLITE_MUTEX_STATIC_VFS1", SQLITE_MUTEX_STATIC_VFS1}, #endif #ifdef SQLITE_MUTEX_STATIC_VFS2 {"SQLITE_MUTEX_STATIC_VFS2", SQLITE_MUTEX_STATIC_VFS2}, #endif #ifdef SQLITE_MUTEX_STATIC_VFS3 {"SQLITE_MUTEX_STATIC_VFS3", SQLITE_MUTEX_STATIC_VFS3}, #endif #ifdef SQLITE_TESTCTRL_ALWAYS {"SQLITE_TESTCTRL_ALWAYS", SQLITE_TESTCTRL_ALWAYS}, #endif #ifdef SQLITE_TESTCTRL_ASSERT {"SQLITE_TESTCTRL_ASSERT", SQLITE_TESTCTRL_ASSERT}, #endif #ifdef SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS {"SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS}, #endif #ifdef SQLITE_TESTCTRL_BITVEC_TEST {"SQLITE_TESTCTRL_BITVEC_TEST", SQLITE_TESTCTRL_BITVEC_TEST}, #endif #ifdef SQLITE_TESTCTRL_BYTEORDER {"SQLITE_TESTCTRL_BYTEORDER", SQLITE_TESTCTRL_BYTEORDER}, #endif #ifdef SQLITE_TESTCTRL_EXPLAIN_STMT {"SQLITE_TESTCTRL_EXPLAIN_STMT", SQLITE_TESTCTRL_EXPLAIN_STMT}, #endif #ifdef SQLITE_TESTCTRL_FAULT_INSTALL {"SQLITE_TESTCTRL_FAULT_INSTALL", SQLITE_TESTCTRL_FAULT_INSTALL}, #endif #ifdef SQLITE_TESTCTRL_FIRST {"SQLITE_TESTCTRL_FIRST", SQLITE_TESTCTRL_FIRST}, #endif #ifdef SQLITE_TESTCTRL_IMPOSTER {"SQLITE_TESTCTRL_IMPOSTER", SQLITE_TESTCTRL_IMPOSTER}, #endif #ifdef SQLITE_TESTCTRL_ISINIT {"SQLITE_TESTCTRL_ISINIT", SQLITE_TESTCTRL_ISINIT}, #endif #ifdef SQLITE_TESTCTRL_ISKEYWORD {"SQLITE_TESTCTRL_ISKEYWORD", SQLITE_TESTCTRL_ISKEYWORD}, #endif #ifdef SQLITE_TESTCTRL_LAST {"SQLITE_TESTCTRL_LAST", SQLITE_TESTCTRL_LAST}, #endif #ifdef SQLITE_TESTCTRL_LOCALTIME_FAULT {"SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT}, #endif #ifdef SQLITE_TESTCTRL_NEVER_CORRUPT {"SQLITE_TESTCTRL_NEVER_CORRUPT", SQLITE_TESTCTRL_NEVER_CORRUPT}, #endif #ifdef SQLITE_TESTCTRL_OPTIMIZATIONS {"SQLITE_TESTCTRL_OPTIMIZATIONS", SQLITE_TESTCTRL_OPTIMIZATIONS}, #endif #ifdef SQLITE_TESTCTRL_PENDING_BYTE {"SQLITE_TESTCTRL_PENDING_BYTE", SQLITE_TESTCTRL_PENDING_BYTE}, #endif #ifdef SQLITE_TESTCTRL_PRNG_RESET {"SQLITE_TESTCTRL_PRNG_RESET", SQLITE_TESTCTRL_PRNG_RESET}, #endif #ifdef SQLITE_TESTCTRL_PRNG_RESTORE {"SQLITE_TESTCTRL_PRNG_RESTORE", SQLITE_TESTCTRL_PRNG_RESTORE}, #endif #ifdef SQLITE_TESTCTRL_PRNG_SAVE {"SQLITE_TESTCTRL_PRNG_SAVE", SQLITE_TESTCTRL_PRNG_SAVE}, #endif #ifdef SQLITE_TESTCTRL_RESERVE {"SQLITE_TESTCTRL_RESERVE", SQLITE_TESTCTRL_RESERVE}, #endif #ifdef SQLITE_TESTCTRL_SCRATCHMALLOC {"SQLITE_TESTCTRL_SCRATCHMALLOC", SQLITE_TESTCTRL_SCRATCHMALLOC}, #endif #ifdef SQLITE_TESTCTRL_SORTER_MMAP {"SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP}, #endif #ifdef SQLITE_TESTCTRL_VDBE_COVERAGE {"SQLITE_TESTCTRL_VDBE_COVERAGE", SQLITE_TESTCTRL_VDBE_COVERAGE}, #endif #ifdef SQLITE_STATUS_MALLOC_COUNT {"SQLITE_STATUS_MALLOC_COUNT", SQLITE_STATUS_MALLOC_COUNT}, #endif #ifdef SQLITE_STATUS_MALLOC_SIZE {"SQLITE_STATUS_MALLOC_SIZE", SQLITE_STATUS_MALLOC_SIZE}, #endif #ifdef SQLITE_STATUS_MEMORY_USED {"SQLITE_STATUS_MEMORY_USED", SQLITE_STATUS_MEMORY_USED}, #endif #ifdef SQLITE_STATUS_PAGECACHE_OVERFLOW {"SQLITE_STATUS_PAGECACHE_OVERFLOW", SQLITE_STATUS_PAGECACHE_OVERFLOW}, #endif #ifdef SQLITE_STATUS_PAGECACHE_SIZE {"SQLITE_STATUS_PAGECACHE_SIZE", SQLITE_STATUS_PAGECACHE_SIZE}, #endif #ifdef SQLITE_STATUS_PAGECACHE_USED {"SQLITE_STATUS_PAGECACHE_USED", SQLITE_STATUS_PAGECACHE_USED}, #endif #ifdef SQLITE_STATUS_PARSER_STACK {"SQLITE_STATUS_PARSER_STACK", SQLITE_STATUS_PARSER_STACK}, #endif #ifdef SQLITE_STATUS_SCRATCH_OVERFLOW {"SQLITE_STATUS_SCRATCH_OVERFLOW", SQLITE_STATUS_SCRATCH_OVERFLOW}, #endif #ifdef SQLITE_STATUS_SCRATCH_SIZE {"SQLITE_STATUS_SCRATCH_SIZE", SQLITE_STATUS_SCRATCH_SIZE}, #endif #ifdef SQLITE_STATUS_SCRATCH_USED {"SQLITE_STATUS_SCRATCH_USED", SQLITE_STATUS_SCRATCH_USED}, #endif #ifdef SQLITE_DBSTATUS_CACHE_HIT {"SQLITE_DBSTATUS_CACHE_HIT", SQLITE_DBSTATUS_CACHE_HIT}, #endif #ifdef SQLITE_DBSTATUS_CACHE_MISS {"SQLITE_DBSTATUS_CACHE_MISS", SQLITE_DBSTATUS_CACHE_MISS}, #endif #ifdef SQLITE_DBSTATUS_CACHE_USED {"SQLITE_DBSTATUS_CACHE_USED", SQLITE_DBSTATUS_CACHE_USED}, #endif #ifdef SQLITE_DBSTATUS_CACHE_WRITE {"SQLITE_DBSTATUS_CACHE_WRITE", SQLITE_DBSTATUS_CACHE_WRITE}, #endif #ifdef SQLITE_DBSTATUS_DEFERRED_FKS {"SQLITE_DBSTATUS_DEFERRED_FKS", SQLITE_DBSTATUS_DEFERRED_FKS}, #endif #ifdef SQLITE_DBSTATUS_LOOKASIDE_HIT {"SQLITE_DBSTATUS_LOOKASIDE_HIT", SQLITE_DBSTATUS_LOOKASIDE_HIT}, #endif #ifdef SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL {"SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL", SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL}, #endif #ifdef SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE {"SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE", SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE}, #endif #ifdef SQLITE_DBSTATUS_LOOKASIDE_USED {"SQLITE_DBSTATUS_LOOKASIDE_USED", SQLITE_DBSTATUS_LOOKASIDE_USED}, #endif #ifdef SQLITE_DBSTATUS_MAX {"SQLITE_DBSTATUS_MAX", SQLITE_DBSTATUS_MAX}, #endif #ifdef SQLITE_DBSTATUS_SCHEMA_USED {"SQLITE_DBSTATUS_SCHEMA_USED", SQLITE_DBSTATUS_SCHEMA_USED}, #endif #ifdef SQLITE_DBSTATUS_STMT_USED {"SQLITE_DBSTATUS_STMT_USED", SQLITE_DBSTATUS_STMT_USED}, #endif #ifdef SQLITE_STMTSTATUS_AUTOINDEX {"SQLITE_STMTSTATUS_AUTOINDEX", SQLITE_STMTSTATUS_AUTOINDEX}, #endif #ifdef SQLITE_STMTSTATUS_FULLSCAN_STEP {"SQLITE_STMTSTATUS_FULLSCAN_STEP", SQLITE_STMTSTATUS_FULLSCAN_STEP}, #endif #ifdef SQLITE_STMTSTATUS_SORT {"SQLITE_STMTSTATUS_SORT", SQLITE_STMTSTATUS_SORT}, #endif #ifdef SQLITE_STMTSTATUS_VM_STEP {"SQLITE_STMTSTATUS_VM_STEP", SQLITE_STMTSTATUS_VM_STEP}, #endif #ifdef SQLITE_CHECKPOINT_FULL {"SQLITE_CHECKPOINT_FULL", SQLITE_CHECKPOINT_FULL}, #endif #ifdef SQLITE_CHECKPOINT_PASSIVE {"SQLITE_CHECKPOINT_PASSIVE", SQLITE_CHECKPOINT_PASSIVE}, #endif #ifdef SQLITE_CHECKPOINT_RESTART {"SQLITE_CHECKPOINT_RESTART", SQLITE_CHECKPOINT_RESTART}, #endif #ifdef SQLITE_CHECKPOINT_TRUNCATE {"SQLITE_CHECKPOINT_TRUNCATE", SQLITE_CHECKPOINT_TRUNCATE}, #endif #ifdef SQLITE_VTAB_CONSTRAINT_SUPPORT {"SQLITE_VTAB_CONSTRAINT_SUPPORT", SQLITE_VTAB_CONSTRAINT_SUPPORT}, #endif #ifdef SQLITE_FAIL {"SQLITE_FAIL", SQLITE_FAIL}, #endif #ifdef SQLITE_REPLACE {"SQLITE_REPLACE", SQLITE_REPLACE}, #endif #ifdef SQLITE_ROLLBACK {"SQLITE_ROLLBACK", SQLITE_ROLLBACK}, #endif #ifdef SQLITE_SCANSTAT_EST {"SQLITE_SCANSTAT_EST", SQLITE_SCANSTAT_EST}, #endif #ifdef SQLITE_SCANSTAT_EXPLAIN {"SQLITE_SCANSTAT_EXPLAIN", SQLITE_SCANSTAT_EXPLAIN}, #endif #ifdef SQLITE_SCANSTAT_NAME {"SQLITE_SCANSTAT_NAME", SQLITE_SCANSTAT_NAME}, #endif #ifdef SQLITE_SCANSTAT_NLOOP {"SQLITE_SCANSTAT_NLOOP", SQLITE_SCANSTAT_NLOOP}, #endif #ifdef SQLITE_SCANSTAT_NVISIT {"SQLITE_SCANSTAT_NVISIT", SQLITE_SCANSTAT_NVISIT}, #endif #ifdef SQLITE_SCANSTAT_SELECTID {"SQLITE_SCANSTAT_SELECTID", SQLITE_SCANSTAT_SELECTID}, #endif pysqlite-2.7.0/src/sqlitecompat.h000066400000000000000000000036311256035156500170520ustar00rootroot00000000000000/* sqlitecompat.h - compatibility macros * * Copyright (C) 2006-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #include "Python.h" #ifndef PYSQLITE_COMPAT_H #define PYSQLITE_COMPAT_H /* define Py_ssize_t for pre-2.5 versions of Python */ #if PY_VERSION_HEX < 0x02050000 typedef int Py_ssize_t; typedef int (*lenfunc)(PyObject*); #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 pysqlite-2.7.0/src/statement.c000066400000000000000000000447541256035156500163570ustar00rootroot00000000000000/* statement.c - the statement type * * Copyright (C) 2005-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #include "statement.h" #include "cursor.h" #include "connection.h" #include "microprotocols.h" #include "prepare_protocol.h" #include "sqlitecompat.h" /* prototypes */ static int pysqlite_check_remaining_sql(const char* tail); typedef enum { LINECOMMENT_1, IN_LINECOMMENT, COMMENTSTART_1, IN_COMMENT, COMMENTEND_1, NORMAL } parse_remaining_sql_state; typedef enum { TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_STRING, TYPE_UNICODE, TYPE_BUFFER, TYPE_UNKNOWN } parameter_type; int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql) { const char* tail; int rc; PyObject* sql_str; char* sql_cstr; self->st = NULL; self->in_use = 0; if (PyString_Check(sql)) { sql_str = sql; Py_INCREF(sql_str); } else if (PyUnicode_Check(sql)) { sql_str = PyUnicode_AsUTF8String(sql); if (!sql_str) { rc = PYSQLITE_SQL_WRONG_TYPE; return rc; } } else { rc = PYSQLITE_SQL_WRONG_TYPE; return rc; } self->in_weakreflist = NULL; self->sql = sql_str; sql_cstr = PyString_AsString(sql_str); Py_BEGIN_ALLOW_THREADS rc = sqlite3_prepare(connection->db, sql_cstr, -1, &self->st, &tail); Py_END_ALLOW_THREADS self->db = connection->db; if (rc == SQLITE_OK && pysqlite_check_remaining_sql(tail)) { (void)sqlite3_finalize(self->st); self->st = NULL; rc = PYSQLITE_TOO_MUCH_SQL; } return rc; } int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter, int allow_8bit_chars) { int rc = SQLITE_OK; long longval; PY_LONG_LONG longlongval; const char* buffer; char* string; Py_ssize_t buflen; PyObject* stringval; parameter_type paramtype; char* c; if (parameter == Py_None) { rc = sqlite3_bind_null(self->st, pos); goto final; } if (PyInt_CheckExact(parameter)) { paramtype = TYPE_INT; } else if (PyLong_CheckExact(parameter)) { paramtype = TYPE_LONG; } else if (PyFloat_CheckExact(parameter)) { paramtype = TYPE_FLOAT; } else if (PyString_CheckExact(parameter)) { paramtype = TYPE_STRING; } else if (PyUnicode_CheckExact(parameter)) { paramtype = TYPE_UNICODE; } else if (PyBuffer_Check(parameter)) { paramtype = TYPE_BUFFER; } else if (PyInt_Check(parameter)) { paramtype = TYPE_INT; } else if (PyLong_Check(parameter)) { paramtype = TYPE_LONG; } else if (PyFloat_Check(parameter)) { paramtype = TYPE_FLOAT; } else if (PyString_Check(parameter)) { paramtype = TYPE_STRING; } else if (PyUnicode_Check(parameter)) { paramtype = TYPE_UNICODE; } else { paramtype = TYPE_UNKNOWN; } if (paramtype == TYPE_STRING && !allow_8bit_chars) { string = PyString_AS_STRING(parameter); for (c = string; *c != 0; c++) { if (*c & 0x80) { PyErr_SetString(pysqlite_ProgrammingError, "You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings."); rc = -1; goto final; } } } switch (paramtype) { case TYPE_INT: longval = PyInt_AsLong(parameter); rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longval); break; case TYPE_LONG: longlongval = PyLong_AsLongLong(parameter); /* in the overflow error case, longlongval is -1, and an exception is set */ rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longlongval); break; case TYPE_FLOAT: rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter)); break; case TYPE_STRING: string = PyString_AS_STRING(parameter); buflen = PyString_Size(parameter); rc = sqlite3_bind_text(self->st, pos, string, buflen, SQLITE_TRANSIENT); break; case TYPE_UNICODE: stringval = PyUnicode_AsUTF8String(parameter); string = PyString_AsString(stringval); buflen = PyString_Size(stringval); rc = sqlite3_bind_text(self->st, pos, string, buflen, SQLITE_TRANSIENT); Py_DECREF(stringval); break; case TYPE_BUFFER: if (PyObject_AsCharBuffer(parameter, &buffer, &buflen) == 0) { rc = sqlite3_bind_blob(self->st, pos, buffer, buflen, SQLITE_TRANSIENT); } else { PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer"); rc = -1; } break; case TYPE_UNKNOWN: rc = -1; PyErr_Format(pysqlite_InterfaceError, "Parameter %d is of no supported type", pos); } final: switch (rc) { case SQLITE_TOOBIG: PyErr_Format(pysqlite_DatabaseError, "Parameter %d is too big", pos); break; case SQLITE_RANGE: PyErr_Format(pysqlite_DatabaseError, "Parameter index %d is out of range", pos); break; case SQLITE_NOMEM: PyErr_Format(pysqlite_DatabaseError, "SQlite is out of memory for parameter %d", pos); break; } return rc; } /* returns 0 if the object is one of Python's internal ones that don't need to be adapted */ static int _need_adapt(PyObject* obj) { if (pysqlite_BaseTypeAdapted) { return 1; } if (PyInt_CheckExact(obj) || PyLong_CheckExact(obj) || PyFloat_CheckExact(obj) || PyString_CheckExact(obj) || PyUnicode_CheckExact(obj) || PyBuffer_Check(obj)) { return 0; } else { return 1; } } void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters, int allow_8bit_chars) { PyObject* current_param; PyObject* adapted; const char* binding_name; int i; int rc; int num_params_needed; int num_params; Py_BEGIN_ALLOW_THREADS num_params_needed = sqlite3_bind_parameter_count(self->st); Py_END_ALLOW_THREADS if (PyTuple_CheckExact(parameters) || PyList_CheckExact(parameters) || (!PyDict_Check(parameters) && PySequence_Check(parameters))) { /* parameters passed as sequence */ if (PyTuple_CheckExact(parameters)) { num_params = PyTuple_GET_SIZE(parameters); } else if (PyList_CheckExact(parameters)) { num_params = PyList_GET_SIZE(parameters); } else { num_params = PySequence_Size(parameters); } if (num_params != num_params_needed) { PyErr_Format(pysqlite_ProgrammingError, "Incorrect number of bindings supplied. The current statement uses %d, and there are %d supplied.", num_params_needed, num_params); return; } for (i = 0; i < num_params; i++) { if (PyTuple_CheckExact(parameters)) { current_param = PyTuple_GET_ITEM(parameters, i); Py_XINCREF(current_param); } else if (PyList_CheckExact(parameters)) { current_param = PyList_GET_ITEM(parameters, i); Py_XINCREF(current_param); } else { current_param = PySequence_GetItem(parameters, i); } if (!current_param) { return; } if (!_need_adapt(current_param)) { adapted = current_param; } else { adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, NULL); if (adapted) { Py_DECREF(current_param); } else { PyErr_Clear(); adapted = current_param; } } rc = pysqlite_statement_bind_parameter(self, i + 1, adapted, allow_8bit_chars); Py_DECREF(adapted); if (rc != SQLITE_OK) { if (!PyErr_Occurred()) { PyErr_Format(pysqlite_InterfaceError, "Unknown error binding parameter %d.", i); } return; } } } else if (PyDict_Check(parameters)) { /* parameters passed as dictionary */ for (i = 1; i <= num_params_needed; i++) { Py_BEGIN_ALLOW_THREADS binding_name = sqlite3_bind_parameter_name(self->st, i); Py_END_ALLOW_THREADS if (!binding_name) { PyErr_Format(pysqlite_ProgrammingError, "Binding %d has no name, but you supplied a dictionary (which has only names).", i); return; } binding_name++; /* skip first char (the colon) */ if (PyDict_CheckExact(parameters)) { current_param = PyDict_GetItemString(parameters, binding_name); Py_XINCREF(current_param); } else { current_param = PyMapping_GetItemString(parameters, (char*)binding_name); } if (!current_param) { PyErr_Format(pysqlite_ProgrammingError, "You did not supply a value for binding %d.", i); return; } if (!_need_adapt(current_param)) { adapted = current_param; } else { adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, NULL); if (adapted) { Py_DECREF(current_param); } else { PyErr_Clear(); adapted = current_param; } } rc = pysqlite_statement_bind_parameter(self, i, adapted, allow_8bit_chars); Py_DECREF(adapted); if (rc != SQLITE_OK) { if (!PyErr_Occurred()) { PyErr_Format(pysqlite_InterfaceError, "Unknown error binding parameter %s.", binding_name); } return; } } } else { PyErr_SetString(PyExc_ValueError, "parameters are of unsupported type"); } } int pysqlite_statement_recompile(pysqlite_Statement* self, PyObject* params) { const char* tail; int rc; char* sql_cstr; sqlite3_stmt* new_st; sql_cstr = PyString_AsString(self->sql); Py_BEGIN_ALLOW_THREADS rc = sqlite3_prepare(self->db, sql_cstr, -1, &new_st, &tail); Py_END_ALLOW_THREADS if (rc == SQLITE_OK) { /* The efficient sqlite3_transfer_bindings is only available in SQLite * version 3.2.2 or later. For older SQLite releases, that might not * even define SQLITE_VERSION_NUMBER, we do it the manual way. */ #ifdef SQLITE_VERSION_NUMBER #if SQLITE_VERSION_NUMBER >= 3002002 /* The check for the number of parameters is necessary to not trigger a * bug in certain SQLite versions (experienced in 3.2.8 and 3.3.4). */ if (sqlite3_bind_parameter_count(self->st) > 0) { (void)sqlite3_transfer_bindings(self->st, new_st); } #endif #else statement_bind_parameters(self, params); #endif (void)sqlite3_finalize(self->st); self->st = new_st; } return rc; } int pysqlite_statement_finalize(pysqlite_Statement* self) { int rc; rc = SQLITE_OK; if (self->st) { Py_BEGIN_ALLOW_THREADS rc = sqlite3_finalize(self->st); Py_END_ALLOW_THREADS self->st = NULL; } self->in_use = 0; return rc; } int pysqlite_statement_reset(pysqlite_Statement* self) { int rc; rc = SQLITE_OK; if (self->in_use && self->st) { Py_BEGIN_ALLOW_THREADS rc = sqlite3_reset(self->st); Py_END_ALLOW_THREADS if (rc == SQLITE_OK) { self->in_use = 0; } } return rc; } void pysqlite_statement_mark_dirty(pysqlite_Statement* self) { self->in_use = 1; } void pysqlite_statement_dealloc(pysqlite_Statement* self) { int rc; if (self->st) { Py_BEGIN_ALLOW_THREADS rc = sqlite3_finalize(self->st); Py_END_ALLOW_THREADS } self->st = NULL; Py_XDECREF(self->sql); if (self->in_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject*)self); } Py_TYPE(self)->tp_free((PyObject*)self); } /* * Checks if there is anything left in an SQL string after SQLite compiled it. * This is used to check if somebody tried to execute more than one SQL command * with one execute()/executemany() command, which the DB-API and we don't * allow. * * Returns 1 if there is more left than should be. 0 if ok. */ static int pysqlite_check_remaining_sql(const char* tail) { const char* pos = tail; parse_remaining_sql_state state = NORMAL; for (;;) { switch (*pos) { case 0: return 0; case '-': if (state == NORMAL) { state = LINECOMMENT_1; } else if (state == LINECOMMENT_1) { state = IN_LINECOMMENT; } break; case ' ': case '\t': break; case '\n': case 13: if (state == IN_LINECOMMENT) { state = NORMAL; } break; case '/': if (state == NORMAL) { state = COMMENTSTART_1; } else if (state == COMMENTEND_1) { state = NORMAL; } else if (state == COMMENTSTART_1) { return 1; } break; case '*': if (state == NORMAL) { return 1; } else if (state == LINECOMMENT_1) { return 1; } else if (state == COMMENTSTART_1) { state = IN_COMMENT; } else if (state == IN_COMMENT) { state = COMMENTEND_1; } break; default: if (state == COMMENTEND_1) { state = IN_COMMENT; } else if (state == IN_LINECOMMENT) { } else if (state == IN_COMMENT) { } else { return 1; } } pos++; } return 0; } PyTypeObject pysqlite_StatementType = { PyVarObject_HEAD_INIT(NULL, 0) MODULE_NAME ".Statement", /* tp_name */ sizeof(pysqlite_Statement), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pysqlite_statement_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof(pysqlite_Statement, in_weakreflist), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0 /* tp_free */ }; extern int pysqlite_statement_setup_types(void) { pysqlite_StatementType.tp_new = PyType_GenericNew; return PyType_Ready(&pysqlite_StatementType); } pysqlite-2.7.0/src/statement.h000066400000000000000000000041641256035156500163530ustar00rootroot00000000000000/* statement.h - definitions for the statement type * * Copyright (C) 2005-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #ifndef PYSQLITE_STATEMENT_H #define PYSQLITE_STATEMENT_H #include "Python.h" #include "connection.h" #include "sqlite3.h" #define PYSQLITE_TOO_MUCH_SQL (-100) #define PYSQLITE_SQL_WRONG_TYPE (-101) typedef struct { PyObject_HEAD sqlite3* db; sqlite3_stmt* st; PyObject* sql; int in_use; PyObject* in_weakreflist; /* List of weak references */ } pysqlite_Statement; extern PyTypeObject pysqlite_StatementType; int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql); void pysqlite_statement_dealloc(pysqlite_Statement* self); int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter, int allow_8bit_chars); void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters, int allow_8bit_chars); int pysqlite_statement_recompile(pysqlite_Statement* self, PyObject* parameters); int pysqlite_statement_finalize(pysqlite_Statement* self); int pysqlite_statement_reset(pysqlite_Statement* self); void pysqlite_statement_mark_dirty(pysqlite_Statement* self); int pysqlite_statement_setup_types(void); #endif pysqlite-2.7.0/src/util.c000066400000000000000000000063661256035156500153250ustar00rootroot00000000000000/* util.c - various utility functions * * Copyright (C) 2005-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #include "module.h" #include "connection.h" int pysqlite_step(sqlite3_stmt* statement, pysqlite_Connection* connection) { int rc; if (statement == NULL) { /* this is a workaround for SQLite 3.5 and later. it now apparently * returns NULL for "no-operation" statements */ rc = SQLITE_OK; } else { Py_BEGIN_ALLOW_THREADS rc = sqlite3_step(statement); Py_END_ALLOW_THREADS } return rc; } /** * Checks the SQLite error code and sets the appropriate DB-API exception. * Returns the error code (0 means no error occurred). */ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st) { int errorcode; /* SQLite often doesn't report anything useful, unless you reset the statement first */ if (st != NULL) { (void)sqlite3_reset(st); } errorcode = sqlite3_errcode(db); switch (errorcode) { case SQLITE_OK: PyErr_Clear(); break; case SQLITE_INTERNAL: case SQLITE_NOTFOUND: PyErr_SetString(pysqlite_InternalError, sqlite3_errmsg(db)); break; case SQLITE_NOMEM: (void)PyErr_NoMemory(); break; case SQLITE_ERROR: case SQLITE_PERM: case SQLITE_ABORT: case SQLITE_BUSY: case SQLITE_LOCKED: case SQLITE_READONLY: case SQLITE_INTERRUPT: case SQLITE_IOERR: case SQLITE_FULL: case SQLITE_CANTOPEN: case SQLITE_PROTOCOL: case SQLITE_EMPTY: case SQLITE_SCHEMA: PyErr_SetString(pysqlite_OperationalError, sqlite3_errmsg(db)); break; case SQLITE_CORRUPT: PyErr_SetString(pysqlite_DatabaseError, sqlite3_errmsg(db)); break; case SQLITE_TOOBIG: PyErr_SetString(pysqlite_DataError, sqlite3_errmsg(db)); break; case SQLITE_CONSTRAINT: case SQLITE_MISMATCH: PyErr_SetString(pysqlite_IntegrityError, sqlite3_errmsg(db)); break; case SQLITE_MISUSE: PyErr_SetString(pysqlite_ProgrammingError, sqlite3_errmsg(db)); break; default: PyErr_SetString(pysqlite_DatabaseError, sqlite3_errmsg(db)); break; } return errorcode; } pysqlite-2.7.0/src/util.h000066400000000000000000000026151256035156500153230ustar00rootroot00000000000000/* util.h - various utility functions * * Copyright (C) 2005-2015 Gerhard Häring * * This file is part of pysqlite. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #ifndef PYSQLITE_UTIL_H #define PYSQLITE_UTIL_H #include "Python.h" #include "pythread.h" #include "sqlite3.h" #include "connection.h" int pysqlite_step(sqlite3_stmt* statement, pysqlite_Connection* connection); /** * Checks the SQLite error code and sets the appropriate DB-API exception. * Returns the error code (0 means no error occurred). */ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st); #endif pysqlite-2.7.0/test.sh000077500000000000000000000001771256035156500147250ustar00rootroot00000000000000#!/bin/sh python2.7 setup.py build (cd build/lib.linux-x86_64-2.7 && python2.7 -c "from pysqlite2 import test; test.test()" ) pysqlite-2.7.0/tox.ini000066400000000000000000000005051256035156500147150ustar00rootroot00000000000000# Tox (http://tox.testrun.org/) is a tool for running tests # in multiple virtualenvs. This configuration file will run the # test suite on all supported python versions. To use it, "pip install tox" # and then run "tox" from this directory. [tox] envlist = py27,py26 [testenv] commands = {envpython} setup.py test deps = pysqlite-2.7.0/update_sqlite_constants.py000066400000000000000000000010661256035156500207160ustar00rootroot00000000000000import sqlite3 import urllib FILENAME = "/tmp/toc.db" stream = urllib.urlopen("https://sqlite.org/toc.db") with open(FILENAME, "wb") as f: f.write(stream.read()) con = sqlite3.connect("/tmp/toc.db") cur = con.cursor() cur.execute("select name from toc where type='constant' and name not in ('SQLITE_SOURCE_ID', 'SQLITE_VERSION')") with open("src/sqlite_constants.h", "w") as out: for row in cur: constant = row[0] out.write("#ifdef %s\n" % constant) out.write('{"%s", %s},\n' % (constant, constant)) out.write("#endif\n")