88from dissect .database .ese .btree import BTree
99from dissect .database .ese .c_ese import (
1010 CODEPAGE ,
11+ FIELDFLAG ,
1112 SYSOBJ ,
1213 JET_coltyp ,
1314)
@@ -239,18 +240,19 @@ def _add_index(self, index: Index) -> None:
239240
240241
241242class Column :
242- def __init__ (self , identifier : int , name : str , type_ : JET_coltyp , record : Record | None = None ):
243+ def __init__ (self , identifier : int , name : str , type : JET_coltyp , flags : FIELDFLAG , record : Record | None = None ):
243244 self .identifier = identifier
244245 self .name = name
245- self .type = type_
246+ self .type = type
247+ self .flags = flags
246248
247249 # Set by the table when added, only relevant for fixed value columns
248250 self ._offset = None
249251
250252 self .record = record
251253
252254 def __repr__ (self ) -> str :
253- return f"<Column name={ self .name !r} identifier={ self .identifier :#x} type={ self .type } size={ self .size } >"
255+ return f"<Column name={ self .name !r} identifier={ self .identifier :#x} type={ self .type } flags= { self . flags . name } size={ self .size } >" # noqa: E501
254256
255257 @property
256258 def offset (self ) -> int :
@@ -276,6 +278,10 @@ def is_text(self) -> bool:
276278 def is_binary (self ) -> bool :
277279 return self .type in (JET_coltyp .Binary , JET_coltyp .LongBinary )
278280
281+ @cached_property
282+ def is_multivalue (self ) -> bool :
283+ return bool (self .flags & FIELDFLAG .Multivalued )
284+
279285 @cached_property
280286 def size (self ) -> int :
281287 if self .record and self .record .get ("SpaceUsage" ):
@@ -310,34 +316,34 @@ class Catalog:
310316 """
311317
312318 CATALOG_COLUMNS = (
313- Column (1 , "ObjidTable" , JET_coltyp .Long ),
314- Column (2 , "Type" , JET_coltyp .Short ),
315- Column (3 , "Id" , JET_coltyp .Long ),
316- Column (4 , "ColtypOrPgnoFDP" , JET_coltyp .Long ),
317- Column (5 , "SpaceUsage" , JET_coltyp .Long ),
318- Column (6 , "Flags" , JET_coltyp .Long ),
319- Column (7 , "PagesOrLocale" , JET_coltyp .Long ),
320- Column (8 , "RootFlag" , JET_coltyp .Bit ),
321- Column (9 , "RecordOffset" , JET_coltyp .Short ),
322- Column (10 , "LCMapFlags" , JET_coltyp .Long ),
323- Column (11 , "KeyMost" , JET_coltyp .UnsignedShort ),
324- Column (12 , "LVChunkMax" , JET_coltyp .Long ),
325- Column (128 , "Name" , JET_coltyp .Text ),
326- Column (129 , "Stats" , JET_coltyp .Binary ),
327- Column (130 , "TemplateTable" , JET_coltyp .Text ),
328- Column (131 , "DefaultValue" , JET_coltyp .Binary ),
329- Column (132 , "KeyFldIDs" , JET_coltyp .Binary ),
330- Column (133 , "VarSegMac" , JET_coltyp .Binary ),
331- Column (134 , "ConditionalColumns" , JET_coltyp .Binary ),
332- Column (135 , "TupleLimits" , JET_coltyp .Binary ),
333- Column (136 , "Version" , JET_coltyp .Binary ),
334- Column (137 , "SortID" , JET_coltyp .Binary ),
335- Column (256 , "CallbackData" , JET_coltyp .LongBinary ),
336- Column (257 , "CallbackDependencies" , JET_coltyp .LongBinary ),
337- Column (258 , "SeparateLV" , JET_coltyp .LongBinary ),
338- Column (259 , "SpaceHints" , JET_coltyp .LongBinary ),
339- Column (260 , "SpaceDeferredLVHints" , JET_coltyp .LongBinary ),
340- Column (261 , "LocaleName" , JET_coltyp .LongBinary ),
319+ Column (1 , "ObjidTable" , JET_coltyp .Long , FIELDFLAG . NotNull ),
320+ Column (2 , "Type" , JET_coltyp .Short , FIELDFLAG . NotNull ),
321+ Column (3 , "Id" , JET_coltyp .Long , FIELDFLAG . NotNull ),
322+ Column (4 , "ColtypOrPgnoFDP" , JET_coltyp .Long , FIELDFLAG . NotNull ),
323+ Column (5 , "SpaceUsage" , JET_coltyp .Long , FIELDFLAG . NotNull ),
324+ Column (6 , "Flags" , JET_coltyp .Long , FIELDFLAG . NotNull ),
325+ Column (7 , "PagesOrLocale" , JET_coltyp .Long , FIELDFLAG . NotNull ),
326+ Column (8 , "RootFlag" , JET_coltyp .Bit , FIELDFLAG ( 0 ) ),
327+ Column (9 , "RecordOffset" , JET_coltyp .Short , FIELDFLAG ( 0 ) ),
328+ Column (10 , "LCMapFlags" , JET_coltyp .Long , FIELDFLAG ( 0 ) ),
329+ Column (11 , "KeyMost" , JET_coltyp .UnsignedShort , FIELDFLAG ( 0 ) ),
330+ Column (12 , "LVChunkMax" , JET_coltyp .Long , FIELDFLAG ( 0 ) ),
331+ Column (128 , "Name" , JET_coltyp .Text , FIELDFLAG . NotNull ),
332+ Column (129 , "Stats" , JET_coltyp .Binary , FIELDFLAG ( 0 ) ),
333+ Column (130 , "TemplateTable" , JET_coltyp .Text , FIELDFLAG ( 0 ) ),
334+ Column (131 , "DefaultValue" , JET_coltyp .Binary , FIELDFLAG ( 0 ) ),
335+ Column (132 , "KeyFldIDs" , JET_coltyp .Binary , FIELDFLAG ( 0 ) ),
336+ Column (133 , "VarSegMac" , JET_coltyp .Binary , FIELDFLAG ( 0 ) ),
337+ Column (134 , "ConditionalColumns" , JET_coltyp .Binary , FIELDFLAG ( 0 ) ),
338+ Column (135 , "TupleLimits" , JET_coltyp .Binary , FIELDFLAG ( 0 ) ),
339+ Column (136 , "Version" , JET_coltyp .Binary , FIELDFLAG ( 0 ) ),
340+ Column (137 , "SortID" , JET_coltyp .Binary , FIELDFLAG ( 0 ) ),
341+ Column (256 , "CallbackData" , JET_coltyp .LongBinary , FIELDFLAG ( 0 ) ),
342+ Column (257 , "CallbackDependencies" , JET_coltyp .LongBinary , FIELDFLAG ( 0 ) ),
343+ Column (258 , "SeparateLV" , JET_coltyp .LongBinary , FIELDFLAG ( 0 ) ),
344+ Column (259 , "SpaceHints" , JET_coltyp .LongBinary , FIELDFLAG ( 0 ) ),
345+ Column (260 , "SpaceDeferredLVHints" , JET_coltyp .LongBinary , FIELDFLAG ( 0 ) ),
346+ Column (261 , "LocaleName" , JET_coltyp .LongBinary , FIELDFLAG ( 0 ) ),
341347 )
342348
343349 def __init__ (self , db : ESE , root_page : Page ):
@@ -358,7 +364,13 @@ def __init__(self, db: ESE, root_page: Page):
358364 self ._table_name_map [rec .get ("Name" )] = cur_table
359365
360366 elif rtype == SYSOBJ .Column :
361- column = Column (rec .get ("Id" ), rec .get ("Name" ), JET_coltyp (rec .get ("ColtypOrPgnoFDP" )), record = rec )
367+ column = Column (
368+ rec .get ("Id" ),
369+ rec .get ("Name" ),
370+ JET_coltyp (rec .get ("ColtypOrPgnoFDP" )),
371+ FIELDFLAG (rec .get ("Flags" )),
372+ record = rec ,
373+ )
362374 cur_table ._add_column (column )
363375
364376 elif rtype == SYSOBJ .Index :
0 commit comments