from typing import (
Self,
ClassVar,
)
from bluebase.core import (
LayoutField,
LayoutMixin,
Domain,
dump,
)
from bluebase.rm import RmRecordData
__all__ = (
'SmTableInfo',
'SmAttrInfo',
)
[docs]
class SmTableInfo(LayoutMixin):
"""
.. rubric:: Layout
.. list-table::
:header-rows: 1
* - Offset
- Size
- Name
- Format
* - 0
- 24
- `name`
- ``'24s'``
* - 24
- 4
- `schema_size`
- ``'<i'``
* - 28
- 4
- `record_size`
- ``'<i'``
* - 32
- 4
- `index_count`
- ``'<i'``
"""
MAX_TABLE_LENGTH: ClassVar[int] = 24
"""table name의 최대 길이를 나타내는 상수."""
fields = (
LayoutField('name', f'{MAX_TABLE_LENGTH}s'),
LayoutField('schema_size', 'i'),
LayoutField('record_size', 'i'),
LayoutField('index_count', 'i'),
)
def __repr__(self) -> str: # pragma: no cover
return f"SmTableInfo({dump(
name=self.name,
schema_size=self.schema_size,
record_size=self.record_size,
index_count=self.index_count,
)})"
[docs]
@classmethod
def new(cls,
name: str,
schema_size: int,
record_size: int,
index_count: int,
) -> Self:
"""
"""
data = RmRecordData.new(cls.size)
info = cls(data)
_, field = cls.lookup['name']
field_domain = Domain.parse(field.format)
info.set('name', field_domain.encode(name))
info.set('schema_size', schema_size)
info.set('record_size', record_size)
info.set('index_count', index_count)
return info
@property
def name(self) -> str:
"""
"""
_, field = SmTableInfo.lookup['name']
field_domain = Domain.parse(field.format)
value = field_domain.decode(self.get('name'))
return str(value)
@property
def schema_size(self) -> int:
"""
"""
return self.get('schema_size')
@property
def record_size(self) -> int:
"""
"""
return self.get('record_size')
@property
def index_count(self) -> int:
"""
"""
return self.get('index_count')
@index_count.setter
def index_count(self, count: int) -> None:
self.set('index_count', count)
[docs]
def encode(self) -> RmRecordData:
"""
"""
return RmRecordData(self.buffer)
[docs]
class SmAttrInfo(LayoutMixin):
"""
.. rubric:: Layout
.. list-table::
:header-rows: 1
* - Offset
- Size
- Name
- Format
* - 0
- 1
- `indexed`
- ``'<B'``
* - 1
- 24
- `table`
- ``'24s'``
* - 25
- 24
- `name`
- ``'24s'``
* - 49
- 4
- `number`
- ``'<i'``
* - 53
- 4
- `domain_enum`
- ``'<i'``
* - 57
- 4
- `domain_size`
- ``'<i'``
* - 61
- 4
- `offset`
- ``'<i'``
"""
MAX_TABLE_LENGTH: ClassVar[int] = SmTableInfo.MAX_TABLE_LENGTH
"""table name의 최대 길이를 나타내는 상수."""
MAX_ATTR_LENGTH: ClassVar[int] = 24
"""attr name의 최대 길이를 나타내는 상수."""
fields = (
LayoutField('indexed', 'B'),
LayoutField('table', f'{MAX_TABLE_LENGTH}s'),
LayoutField('name', f'{MAX_ATTR_LENGTH}s'),
LayoutField('number', 'i'),
LayoutField('domain_enum', 'i'),
LayoutField('domain_size', 'i'),
LayoutField('offset', 'i'),
)
def __repr__(self) -> str: # pragma: no cover
return f"SmAttrInfo({dump(
table=self.table,
name=self.name,
number=self.number,
offset=self.offset,
domain=self.domain,
)})"
[docs]
@classmethod
def new(cls,
table: str,
name: str,
number: int,
domain: Domain,
offset: int,
) -> Self:
"""
"""
data = RmRecordData.new(cls.size)
info = cls(data)
info.set('indexed', False)
_, field = cls.lookup['table']
field_domain = Domain.parse(field.format)
info.set('table', field_domain.encode(table))
_, field = cls.lookup['name']
field_domain = Domain.parse(field.format)
info.set('name', field_domain.encode(name))
info.set('number', number)
info.set('domain_enum', domain.enum)
info.set('domain_size', domain.size)
info.set('offset', offset)
return info
[docs]
def slice(self) -> slice:
"""
"""
return slice(
self.offset,
self.offset + self.domain.size,
)
@property
def indexed(self) -> bool:
"""
"""
return bool(self.get('indexed'))
@indexed.setter
def indexed(self, indexed: bool) -> None:
self.set('indexed', bool(indexed))
@property
def table(self) -> str:
"""
"""
_, field = SmAttrInfo.lookup['table']
field_domain = Domain.parse(field.format)
value = field_domain.decode(self.get('table'))
return str(value)
@property
def name(self) -> str:
"""
"""
_, field = SmAttrInfo.lookup['name']
field_domain = Domain.parse(field.format)
value = field_domain.decode(self.get('name'))
return str(value)
@property
def number(self) -> int:
"""
"""
return self.get('number')
@property
def domain(self) -> Domain:
"""
"""
return Domain.restore(
self.get('domain_enum'),
self.get('domain_size'),
)
@property
def offset(self) -> int:
"""
"""
return self.get('offset')
[docs]
def encode(self) -> RmRecordData:
"""
"""
return RmRecordData(self.buffer)