diff --git a/src/mvt/android/artifacts/dumpsys_dbinfo.py b/src/mvt/android/artifacts/dumpsys_dbinfo.py index 050582d..0972b43 100644 --- a/src/mvt/android/artifacts/dumpsys_dbinfo.py +++ b/src/mvt/android/artifacts/dumpsys_dbinfo.py @@ -29,16 +29,27 @@ class DumpsysDBInfoArtifact(AndroidArtifact): def parse(self, output: str) -> None: rxp = re.compile( - r".*\[((?:[0-9]{4}-)?[0-9]{2}-[0-9]{2} " - r"[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3})\]\s*" - r"(?:\[Pid:\((\d+)\)\])?([\w-]+).*?sql=\"(.+?)\"" - ) # pylint: disable=line-too-long + r"^\s*\d+:\s*\[((?:\d{4}-)?\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3})\]\s*" + r"(?:\[Pid:\((\d+)\)\])?\s*([\w-]+) took (\d+)ms - ([^,]+)," + r"\s*sql=\"(.*)\"(?:, path=(.*))?$" + ) - pool = None + pool: str | None = None + connection_number: int | None = None + is_primary: bool | None = None in_operations = False for line in output.splitlines(): if line.startswith("Connection pool for "): pool = line.replace("Connection pool for ", "").rstrip(":") + in_operations = False + + connection_match = re.match(r"\s+Connection #(\d+):", line) + if connection_match: + connection_number = int(connection_match.group(1)) + is_primary = None + + if line.strip().startswith("isPrimaryConnection:"): + is_primary = line.strip().split(":", 1)[1].strip() == "true" if not pool: continue @@ -52,7 +63,6 @@ class DumpsysDBInfoArtifact(AndroidArtifact): if not line.startswith(" "): in_operations = False - pool = None continue match = rxp.match(line) @@ -60,11 +70,15 @@ class DumpsysDBInfoArtifact(AndroidArtifact): continue result = { - "isodate": match.group(1), + "timestamp": match.group(1), + "pid": int(match.group(2)) if match.group(2) else None, "action": match.group(3), - "sql": match.group(4), - "path": pool, + "duration_ms": int(match.group(4)), + "status": match.group(5), + "sql": match.group(6), + "path": match.group(7) or pool, + "pool_path": pool, + "connection_number": connection_number, + "is_primary": is_primary, } - if match.group(2): - result["pid"] = match.group(2) self.results.append(result) diff --git a/tests/android/test_artifact_dumpsys_dbinfo.py b/tests/android/test_artifact_dumpsys_dbinfo.py index 691d43c..0dcc0bc 100644 --- a/tests/android/test_artifact_dumpsys_dbinfo.py +++ b/tests/android/test_artifact_dumpsys_dbinfo.py @@ -53,9 +53,32 @@ Connection pool for /data/user/0/com.example/databases/current.db: assert dbi.results == [ { - "isodate": "07-15 20:27:39.431", + "timestamp": "07-15 20:27:39.431", + "pid": None, "action": "executeForCursorWindow", + "duration_ms": 1, + "status": "succeeded", "sql": "SELECT 1", "path": "/data/user/0/com.example/databases/current.db", + "pool_path": "/data/user/0/com.example/databases/current.db", + "connection_number": None, + "is_primary": None, } ] + + def test_parses_operations_from_multiple_connections(self): + dbi = DumpsysDBInfoArtifact() + dbi.parse( + """Connection pool for /data/example.db: + Connection #0: + isPrimaryConnection: true + Most recently executed operations: + 0: [2025-01-01 00:00:00.000] execute took 1ms - succeeded, sql="SELECT 1", path=/data/example.db + Connection #1: + isPrimaryConnection: false + Most recently executed operations: + 0: [2025-01-01 00:00:01.000] execute took 2ms - succeeded, sql="SELECT 2", path=/data/example.db +""" + ) + + assert [record["connection_number"] for record in dbi.results] == [0, 1]