Skip to content
This repository was archived by the owner on Nov 20, 2025. It is now read-only.

Commit ca05543

Browse files
authored
Add comparison operators to Record class (#44)
1 parent e11d651 commit ca05543

File tree

2 files changed

+79
-17
lines changed

2 files changed

+79
-17
lines changed

dissect/esedb/record.py

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,62 @@ def __init__(self, table: Table, node: Node):
4040
self._node = node
4141
self._data = RecordData(table, node)
4242

43+
def __str__(self) -> str:
44+
column_values = serialise_record_column_values(self, max_columns=None)
45+
return f"<Record {column_values}>"
46+
47+
def __repr__(self) -> str:
48+
column_values = serialise_record_column_values(self)
49+
return f"<Record {column_values}>"
50+
51+
def __hash__(self) -> int:
52+
return hash((self._table, self._node))
53+
54+
def __getitem__(self, attr: str) -> RecordValue:
55+
return self.get(attr)
56+
57+
def __getattr__(self, attr: str) -> RecordValue:
58+
try:
59+
return self.get(attr)
60+
except KeyError:
61+
return object.__getattribute__(self, attr)
62+
63+
def __eq__(self, value: object) -> bool:
64+
if not isinstance(value, Record):
65+
return False
66+
67+
return self._node.key == value._node.key
68+
69+
def __ne__(self, value: object) -> bool:
70+
if not isinstance(value, Record):
71+
return False
72+
73+
return self._node.key != value._node.key
74+
75+
def __lt__(self, value: object) -> bool:
76+
if not isinstance(value, Record):
77+
return False
78+
79+
return self._node.key < value._node.key
80+
81+
def __le__(self, value: object) -> bool:
82+
if not isinstance(value, Record):
83+
return False
84+
85+
return self._node.key <= value._node.key
86+
87+
def __gt__(self, value: object) -> bool:
88+
if not isinstance(value, Record):
89+
return False
90+
91+
return self._node.key > value._node.key
92+
93+
def __ge__(self, value: object) -> bool:
94+
if not isinstance(value, Record):
95+
return False
96+
97+
return self._node.key >= value._node.key
98+
4399
def get(self, attr: str, raw: bool = False) -> RecordValue:
44100
"""Retrieve a value from the record with the given name.
45101
@@ -55,23 +111,6 @@ def get(self, attr: str, raw: bool = False) -> RecordValue:
55111
def as_dict(self, raw: bool = False) -> dict[str, RecordValue]:
56112
return self._data.as_dict(raw)
57113

58-
def __getitem__(self, attr: str) -> RecordValue:
59-
return self.get(attr)
60-
61-
def __getattr__(self, attr: str) -> RecordValue:
62-
try:
63-
return self.get(attr)
64-
except KeyError:
65-
return object.__getattribute__(self, attr)
66-
67-
def __str__(self) -> str:
68-
column_values = serialise_record_column_values(self, max_columns=None)
69-
return f"<Record {column_values}>"
70-
71-
def __repr__(self) -> str:
72-
column_values = serialise_record_column_values(self)
73-
return f"<Record {column_values}>"
74-
75114

76115
class RecordData:
77116
"""Record class for parsing and interacting with the on-disk record format.

tests/test_record.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from typing import BinaryIO
44

55
from dissect.esedb.esedb import EseDB
6+
from dissect.esedb.record import Record
67

78

89
def test_as_dict(basic_db: BinaryIO) -> None:
@@ -40,3 +41,25 @@ def test_as_dict(basic_db: BinaryIO) -> None:
4041
"DateTime": -4537072128574357504,
4142
},
4243
]
44+
45+
46+
def test_comparison(basic_db: BinaryIO) -> None:
47+
db = EseDB(basic_db)
48+
table = db.table("basic")
49+
50+
records = list(table.records())
51+
assert len(records) == 2
52+
53+
assert records[0] == records[0]
54+
assert records[0] != records[1]
55+
56+
obj = Record(table, records[0]._node)
57+
assert records[0] == obj
58+
assert records[0] is not obj
59+
60+
assert records[0] < records[1]
61+
assert records[0] <= records[1]
62+
assert records[0] <= records[0]
63+
64+
assert set(records) == {records[0], records[1]}
65+
assert set(records) | {obj} == {records[0], records[1]}

0 commit comments

Comments
 (0)