266 |
266 |
267 def _read_db(self): |
267 def _read_db(self): |
268 """Read the metadata from a database so that we are ready to use it.""" |
268 """Read the metadata from a database so that we are ready to use it.""" |
269 with self._dbs[get_thread_id()] as db: |
269 with self._dbs[get_thread_id()] as db: |
270 try: |
270 try: |
271 schema_version, = db.execute("select version from coverage_schema").fetchone() |
271 schema_version, = db.execute_one("select version from coverage_schema") |
272 except Exception as exc: |
272 except Exception as exc: |
273 raise CoverageException( |
273 raise CoverageException( |
274 "Data file {!r} doesn't seem to be a coverage data file: {}".format( |
274 "Data file {!r} doesn't seem to be a coverage data file: {}".format( |
275 self._filename, exc |
275 self._filename, exc |
276 ) |
276 ) |
372 def _context_id(self, context): |
372 def _context_id(self, context): |
373 """Get the id for a context.""" |
373 """Get the id for a context.""" |
374 assert context is not None |
374 assert context is not None |
375 self._start_using() |
375 self._start_using() |
376 with self._connect() as con: |
376 with self._connect() as con: |
377 row = con.execute("select id from context where context = ?", (context,)).fetchone() |
377 row = con.execute_one("select id from context where context = ?", (context,)) |
378 if row is not None: |
378 if row is not None: |
379 return row[0] |
379 return row[0] |
380 else: |
380 else: |
381 return None |
381 return None |
382 |
382 |
787 self._start_using() |
787 self._start_using() |
788 with self._connect() as con: |
788 with self._connect() as con: |
789 file_id = self._file_id(filename) |
789 file_id = self._file_id(filename) |
790 if file_id is None: |
790 if file_id is None: |
791 return None |
791 return None |
792 row = con.execute("select tracer from tracer where file_id = ?", (file_id,)).fetchone() |
792 row = con.execute_one("select tracer from tracer where file_id = ?", (file_id,)) |
793 if row is not None: |
793 if row is not None: |
794 return row[0] or "" |
794 return row[0] or "" |
795 return "" # File was measured, but no tracer associated. |
795 return "" # File was measured, but no tracer associated. |
796 |
796 |
797 def set_query_context(self, context): |
797 def set_query_context(self, context): |
950 |
950 |
951 Returns a list of (key, value) pairs. |
951 Returns a list of (key, value) pairs. |
952 |
952 |
953 """ |
953 """ |
954 with SqliteDb(":memory:", debug=NoDebugging()) as db: |
954 with SqliteDb(":memory:", debug=NoDebugging()) as db: |
|
955 temp_store = [row[0] for row in db.execute("pragma temp_store")] |
955 compile_options = [row[0] for row in db.execute("pragma compile_options")] |
956 compile_options = [row[0] for row in db.execute("pragma compile_options")] |
956 |
957 |
957 return [ |
958 return [ |
958 ('sqlite3_version', sqlite3.version), |
959 ('sqlite3_version', sqlite3.version), |
959 ('sqlite3_sqlite_version', sqlite3.sqlite_version), |
960 ('sqlite3_sqlite_version', sqlite3.sqlite_version), |
|
961 ('sqlite3_temp_store', temp_store), |
960 ('sqlite3_compile_options', compile_options), |
962 ('sqlite3_compile_options', compile_options), |
961 ] |
963 ] |
962 |
964 |
963 |
965 |
964 class SqliteDb(SimpleReprMixin): |
966 class SqliteDb(SimpleReprMixin): |
1060 pass |
1062 pass |
1061 if self.debug: |
1063 if self.debug: |
1062 self.debug.write("EXCEPTION from execute: {}".format(msg)) |
1064 self.debug.write("EXCEPTION from execute: {}".format(msg)) |
1063 raise CoverageException("Couldn't use data file {!r}: {}".format(self.filename, msg)) |
1065 raise CoverageException("Couldn't use data file {!r}: {}".format(self.filename, msg)) |
1064 |
1066 |
|
1067 def execute_one(self, sql, parameters=()): |
|
1068 """Execute a statement and return the one row that results. |
|
1069 |
|
1070 This is like execute(sql, parameters).fetchone(), except it is |
|
1071 correct in reading the entire result set. This will raise an |
|
1072 exception if more than one row results. |
|
1073 |
|
1074 Returns a row, or None if there were no rows. |
|
1075 """ |
|
1076 rows = list(self.execute(sql, parameters)) |
|
1077 if len(rows) == 0: |
|
1078 return None |
|
1079 elif len(rows) == 1: |
|
1080 return rows[0] |
|
1081 else: |
|
1082 raise CoverageException("Sql {!r} shouldn't return {} rows".format(sql, len(rows))) |
|
1083 |
1065 def executemany(self, sql, data): |
1084 def executemany(self, sql, data): |
1066 """Same as :meth:`python:sqlite3.Connection.executemany`.""" |
1085 """Same as :meth:`python:sqlite3.Connection.executemany`.""" |
1067 if self.debug: |
1086 if self.debug: |
1068 data = list(data) |
1087 data = list(data) |
1069 self.debug.write("Executing many {!r} with {} rows".format(sql, len(data))) |
1088 self.debug.write("Executing many {!r} with {} rows".format(sql, len(data))) |