Changeset - b880115774ac
[Not reviewed]
0 1 0
Brett Smith - 3 years ago 2021-03-15 17:40:09
brettcsmith@brettcsmith.org
query: Refactor DBColumn.

Avoid an issubclass check on every call, and make it easier for subclasses
to override part of the call implementation.
1 file changed with 15 insertions and 5 deletions:
0 comments (0 inline, 0 general)
conservancy_beancount/reports/query.py
Show inline comments
...
 
@@ -169,12 +169,19 @@ class DBColumn(bc_query_compile.EvalColumn):
 
    _db_cursor: ClassVar[sqlite3.Cursor]
 
    _db_query: ClassVar[str]
 
    _dtype: ClassVar[Type] = set
 
    _return: ClassVar[Callable[['DBColumn'], object]]
 
    __intypes__ = [Posting]
 

	
 
    @classmethod
 
    def with_db(cls, connection: sqlite3.Connection) -> Type['DBColumn']:
 
        return type(cls.__name__, (cls,), {'_db_cursor': connection.cursor()})
 

	
 
    def __init_subclass__(cls) -> None:
 
        if issubclass(cls._dtype, set):
 
            cls._return = cls._return_set
 
        else:
 
            cls._return = cls._return_scalar
 

	
 
    def __init__(self, colname: Optional[str]=None) -> None:
 
        if not hasattr(self, '_db_cursor'):
 
            if colname is None:
...
 
@@ -186,14 +193,17 @@ class DBColumn(bc_query_compile.EvalColumn):
 
        entity = meta.get('entity')
 
        return entity if isinstance(entity, str) else '\0'
 

	
 
    def _return_scalar(self) -> object:
 
        row = self._db_cursor.fetchone()
 
        return self._dtype() if row is None else self._dtype(row[0])
 

	
 
    def _return_set(self) -> object:
 
        return self._dtype(value for value, in self._db_cursor)
 

	
 
    def __call__(self, context: PostingContext) -> object:
 
        entity = self._entity(ContextMeta(context))
 
        self._db_cursor.execute(self._db_query, (entity,))
 
        if issubclass(self._dtype, set):
 
            return self._dtype(value for value, in self._db_cursor)
 
        else:
 
            row = self._db_cursor.fetchone()
 
            return self._dtype() if row is None else self._dtype(row[0])
 
        return self._return()
 

	
 

	
 
class DBEmail(DBColumn):
0 comments (0 inline, 0 general)