@@ -268,7 +268,7 @@ def _read_db(self):
268
268
"""Read the metadata from a database so that we are ready to use it."""
269
269
with self ._dbs [get_thread_id ()] as db :
270
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
272
except Exception as exc :
273
273
raise CoverageException (
274
274
"Data file {!r} doesn't seem to be a coverage data file: {}" .format (
@@ -374,7 +374,7 @@ def _context_id(self, context):
374
374
assert context is not None
375
375
self ._start_using ()
376
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
378
if row is not None :
379
379
return row [0 ]
380
380
else :
@@ -789,7 +789,7 @@ def file_tracer(self, filename):
789
789
file_id = self ._file_id (filename )
790
790
if file_id is None :
791
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
793
if row is not None :
794
794
return row [0 ] or ""
795
795
return "" # File was measured, but no tracer associated.
@@ -1062,6 +1062,23 @@ def execute(self, sql, parameters=()):
1062
1062
self .debug .write ("EXCEPTION from execute: {}" .format (msg ))
1063
1063
raise CoverageException ("Couldn't use data file {!r}: {}" .format (self .filename , msg ))
1064
1064
1065
+ def execute_one (self , sql , parameters = ()):
1066
+ """Execute a statement and return the one row that results.
1067
+
1068
+ This is like execute(sql, parameters).fetchone(), except it is
1069
+ correct in reading the entire result set. This will raise an
1070
+ exception if more than one row results.
1071
+
1072
+ Returns a row, or None if there were no rows.
1073
+ """
1074
+ rows = list (self .execute (sql , parameters ))
1075
+ if len (rows ) == 0 :
1076
+ return None
1077
+ elif len (rows ) == 1 :
1078
+ return rows [0 ]
1079
+ else :
1080
+ raise CoverageException ("Sql {!r} shouldn't return {} rows" .format (sql , len (rows )))
1081
+
1065
1082
def executemany (self , sql , data ):
1066
1083
"""Same as :meth:`python:sqlite3.Connection.executemany`."""
1067
1084
if self .debug :
0 commit comments