From 4343dc517f2ca36442561925ce1dbc8e40e886ea Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Tue, 26 Dec 2023 22:09:12 +0100 Subject: [PATCH] add RecordsTable type implemented as a simple list of records --- README.txt | 22 +++++++++++++++++++++- table.py | 28 ++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/README.txt b/README.txt index 5d5a1bc..0353018 100755 --- a/README.txt +++ b/README.txt @@ -23,7 +23,7 @@ with lower-level aspects like type or state management. Let's also import some common stuff needed later. - >>> from loops.common import adapted + >>> from loops.common import adapted, baseObject >>> from loops.setup import addAndConfigureObject @@ -921,6 +921,26 @@ relates ISO country codes with the full name of the country. >>> countries.getRowsByValue('value', 'Germany') [{'value': 'Germany', 'key': 'de'}] +The ``recordstable`` type is a variation of this datable type that contains +a simple list of records - without a key column. A record in this type is a +dictionary with the field name as key and the field value as value. + + >>> from loops.table import IRecordsTable, RecordsTable + >>> component.provideAdapter(RecordsTable, provides=IRecordsTable) + + >>> drType = addAndConfigureObject(concepts, Concept, 'recordstable', + ... title='Records Table', conceptType=concepts['type'], + ... typeInterface=IRecordsTable) + +We just reuse the existing ``countries`` table and convert it to a records table. + + >>> baseObject(countries).setType(drType) + + >>> countries = adapted(concepts['countries']) + + >>> countries.data + [{'value': 'Austria', 'key': 'at'}, {'value': 'Germany', 'key': 'de'}] + Caching ======= diff --git a/table.py b/table.py index 5d539fe..d4edbcc 100644 --- a/table.py +++ b/table.py @@ -24,7 +24,7 @@ from BTrees.OOBTree import OOBTree from zope.cachedescriptors.property import Lazy from zope import component, schema from zope.component import adapts -from zope.interface import implements, Interface, Attribute +from zope.interface import implementer, implements, Interface, Attribute from zope.schema.interfaces import IContextSourceBinder, IIterableSource from cybertools.composer.schema.factory import SchemaFactory @@ -65,6 +65,11 @@ class IDataTable(IConceptSchema, ILoopsAdapter): IDataTable['columns'].hidden = True +class IRecordsTable(IDataTable): + + pass + + class DataTable(AdapterBase): implements(IDataTable) @@ -101,8 +106,11 @@ class DataTable(AdapterBase): data = property(getData, setData) def dataAsRecords(self): + return self.asRecords(self.data) + + def asRecords(self, data): result = [] - for k, v in sorted(self.data.items()): + for k, v in sorted(data.items()): item = {} for idx, c in enumerate(self.columns): if idx == 0: @@ -188,3 +196,19 @@ class DataTableSourceBinder(object): dt = context.getLoopsRoot().getConceptManager()[self.tableName] return self.sourceList(adapted(dt), self.valueProvider) + +@implementer(IRecordsTable) +class RecordsTable(DataTable): + + def getData(self): + data = self.context._data + if not isinstance(data, list): + return self.asRecords(data) + return data + def setData(self, data): + self.context._data = data + data = property(getData, setData) + + def dataAsRecords(self): + return self.data +