Skip to content

Commit

Permalink
Add comparison operators to Record class
Browse files Browse the repository at this point in the history
  • Loading branch information
Schamper committed Jan 28, 2025
1 parent 70ae493 commit 669aa39
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 17 deletions.
73 changes: 56 additions & 17 deletions dissect/esedb/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,62 @@ def __init__(self, table: Table, node: Node):
self._node = node
self._data = RecordData(table, node)

def __str__(self) -> str:
column_values = serialise_record_column_values(self, max_columns=None)
return f"<Record {column_values}>"

Check warning on line 45 in dissect/esedb/record.py

View check run for this annotation

Codecov / codecov/patch

dissect/esedb/record.py#L44-L45

Added lines #L44 - L45 were not covered by tests

def __repr__(self) -> str:
column_values = serialise_record_column_values(self)
return f"<Record {column_values}>"

Check warning on line 49 in dissect/esedb/record.py

View check run for this annotation

Codecov / codecov/patch

dissect/esedb/record.py#L48-L49

Added lines #L48 - L49 were not covered by tests

def __hash__(self) -> int:
return hash((self._table, self._node))

def __getitem__(self, attr: str) -> RecordValue:
return self.get(attr)

Check warning on line 55 in dissect/esedb/record.py

View check run for this annotation

Codecov / codecov/patch

dissect/esedb/record.py#L55

Added line #L55 was not covered by tests

def __getattr__(self, attr: str) -> RecordValue:
try:
return self.get(attr)
except KeyError:
return object.__getattribute__(self, attr)

Check warning on line 61 in dissect/esedb/record.py

View check run for this annotation

Codecov / codecov/patch

dissect/esedb/record.py#L60-L61

Added lines #L60 - L61 were not covered by tests

def __eq__(self, value: object) -> bool:
if not isinstance(value, Record):
return False

Check warning on line 65 in dissect/esedb/record.py

View check run for this annotation

Codecov / codecov/patch

dissect/esedb/record.py#L65

Added line #L65 was not covered by tests

return self._node.key == value._node.key

def __ne__(self, value: object) -> bool:
if not isinstance(value, Record):
return False

Check warning on line 71 in dissect/esedb/record.py

View check run for this annotation

Codecov / codecov/patch

dissect/esedb/record.py#L71

Added line #L71 was not covered by tests

return self._node.key != value._node.key

def __lt__(self, value: object) -> bool:
if not isinstance(value, Record):
return False

Check warning on line 77 in dissect/esedb/record.py

View check run for this annotation

Codecov / codecov/patch

dissect/esedb/record.py#L77

Added line #L77 was not covered by tests

return self._node.key < value._node.key

def __le__(self, value: object) -> bool:
if not isinstance(value, Record):
return False

Check warning on line 83 in dissect/esedb/record.py

View check run for this annotation

Codecov / codecov/patch

dissect/esedb/record.py#L83

Added line #L83 was not covered by tests

return self._node.key <= value._node.key

def __gt__(self, value: object) -> bool:
if not isinstance(value, Record):
return False

Check warning on line 89 in dissect/esedb/record.py

View check run for this annotation

Codecov / codecov/patch

dissect/esedb/record.py#L88-L89

Added lines #L88 - L89 were not covered by tests

return self._node.key > value._node.key

Check warning on line 91 in dissect/esedb/record.py

View check run for this annotation

Codecov / codecov/patch

dissect/esedb/record.py#L91

Added line #L91 was not covered by tests

def __ge__(self, value: object) -> bool:
if not isinstance(value, Record):
return False

Check warning on line 95 in dissect/esedb/record.py

View check run for this annotation

Codecov / codecov/patch

dissect/esedb/record.py#L94-L95

Added lines #L94 - L95 were not covered by tests

return self._node.key >= value._node.key

Check warning on line 97 in dissect/esedb/record.py

View check run for this annotation

Codecov / codecov/patch

dissect/esedb/record.py#L97

Added line #L97 was not covered by tests

def get(self, attr: str, raw: bool = False) -> RecordValue:
"""Retrieve a value from the record with the given name.
Expand All @@ -55,23 +111,6 @@ def get(self, attr: str, raw: bool = False) -> RecordValue:
def as_dict(self, raw: bool = False) -> dict[str, RecordValue]:
return self._data.as_dict(raw)

def __getitem__(self, attr: str) -> RecordValue:
return self.get(attr)

def __getattr__(self, attr: str) -> RecordValue:
try:
return self.get(attr)
except KeyError:
return object.__getattribute__(self, attr)

def __str__(self) -> str:
column_values = serialise_record_column_values(self, max_columns=None)
return f"<Record {column_values}>"

def __repr__(self) -> str:
column_values = serialise_record_column_values(self)
return f"<Record {column_values}>"


class RecordData:
"""Record class for parsing and interacting with the on-disk record format.
Expand Down
23 changes: 23 additions & 0 deletions tests/test_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import BinaryIO

from dissect.esedb.esedb import EseDB
from dissect.esedb.record import Record


def test_as_dict(basic_db: BinaryIO) -> None:
Expand Down Expand Up @@ -40,3 +41,25 @@ def test_as_dict(basic_db: BinaryIO) -> None:
"DateTime": -4537072128574357504,
},
]


def test_comparison(basic_db: BinaryIO) -> None:
db = EseDB(basic_db)
table = db.table("basic")

records = list(table.records())
assert len(records) == 2

assert records[0] == records[0]
assert records[0] != records[1]

obj = Record(table, records[0]._node)
assert records[0] == obj
assert records[0] is not obj

assert records[0] < records[1]
assert records[0] <= records[1]
assert records[0] <= records[0]

assert set(records) == {records[0], records[1]}
assert set(records) | {obj} == {records[0], records[1]}

0 comments on commit 669aa39

Please sign in to comment.