summaryrefslogtreecommitdiff
path: root/coverage/sqldata.py
diff options
context:
space:
mode:
Diffstat (limited to 'coverage/sqldata.py')
-rw-r--r--coverage/sqldata.py42
1 files changed, 25 insertions, 17 deletions
diff --git a/coverage/sqldata.py b/coverage/sqldata.py
index 31c454e2..065a1b4e 100644
--- a/coverage/sqldata.py
+++ b/coverage/sqldata.py
@@ -17,12 +17,18 @@ import os
import sqlite3
import sys
+from coverage import env
from coverage.backward import iitems
from coverage.data import filename_suffix
from coverage.debug import NoDebugging, SimpleReprMixin
from coverage.files import PathAliases
from coverage.misc import CoverageException, file_be_gone
+if env.PY2:
+ from thread import get_ident as get_thread_id
+else:
+ from threading import get_ident as get_thread_id
+
# Schema versions:
# 1: Released in 5.0a2
@@ -84,7 +90,7 @@ class CoverageSqliteData(SimpleReprMixin):
self._choose_filename()
self._file_map = {}
- self._db = None
+ self._dbs = {}
self._pid = os.getpid()
# Are we in sync with the data file?
@@ -103,9 +109,10 @@ class CoverageSqliteData(SimpleReprMixin):
self.filename += "." + suffix
def _reset(self):
- if self._db is not None:
- self._db.close()
- self._db = None
+ if self._dbs:
+ for db in self._dbs.values():
+ db.close()
+ self._dbs = {}
self._file_map = {}
self._have_used = False
self._current_context_id = None
@@ -113,14 +120,14 @@ class CoverageSqliteData(SimpleReprMixin):
def _create_db(self):
if self._debug.should('dataio'):
self._debug.write("Creating data file {!r}".format(self.filename))
- self._db = Sqlite(self.filename, self._debug)
- with self._db:
+ self._dbs[get_thread_id()] = Sqlite(self.filename, self._debug)
+ with self._dbs[get_thread_id()] as db:
for stmt in SCHEMA.split(';'):
stmt = " ".join(stmt.strip().split())
if stmt:
- self._db.execute(stmt)
- self._db.execute("insert into coverage_schema (version) values (?)", (SCHEMA_VERSION,))
- self._db.execute(
+ db.execute(stmt)
+ db.execute("insert into coverage_schema (version) values (?)", (SCHEMA_VERSION,))
+ db.execute(
"insert into meta (has_lines, has_arcs, sys_argv) values (?, ?, ?)",
(self._has_lines, self._has_arcs, str(getattr(sys, 'argv', None)))
)
@@ -128,10 +135,10 @@ class CoverageSqliteData(SimpleReprMixin):
def _open_db(self):
if self._debug.should('dataio'):
self._debug.write("Opening data file {!r}".format(self.filename))
- self._db = Sqlite(self.filename, self._debug)
- with self._db:
+ self._dbs[get_thread_id()] = Sqlite(self.filename, self._debug)
+ with self._dbs[get_thread_id()] as db:
try:
- schema_version, = self._db.execute("select version from coverage_schema").fetchone()
+ schema_version, = db.execute("select version from coverage_schema").fetchone()
except Exception as exc:
raise CoverageException(
"Data file {!r} doesn't seem to be a coverage data file: {}".format(
@@ -146,22 +153,23 @@ class CoverageSqliteData(SimpleReprMixin):
)
)
- for row in self._db.execute("select has_lines, has_arcs from meta"):
+ for row in db.execute("select has_lines, has_arcs from meta"):
self._has_lines, self._has_arcs = row
- for path, id in self._db.execute("select path, id from file"):
+ for path, id in db.execute("select path, id from file"):
self._file_map[path] = id
def _connect(self):
- if self._db is None:
+ if get_thread_id() not in self._dbs:
if os.path.exists(self.filename):
self._open_db()
else:
self._create_db()
- return self._db
+ return self._dbs[get_thread_id()]
def __nonzero__(self):
- if self._db is None and not os.path.exists(self.filename):
+ if (get_thread_id() not in self._dbs and
+ not os.path.exists(self.filename)):
return False
try:
with self._connect() as con: