Source code for versioned_collection.collection.tracking_collections.metadata
import dataclasses
from copy import copy
from typing import Optional
from pymongo.database import Database
from versioned_collection.collection.tracking_collections import (
_BaseTrackerCollection,
)
[docs]
class MetadataCollection(_BaseTrackerCollection):
"""Stores metadata about the current state of the target collection.
This collection keeps track of the current version of the target
versioned collection, i.e., its version and branch, and information about
the 'head' branch pointer, which specifies whether unregistered changes
were made since the last registered version of the collection and whether
the head pointer is detached, i.e., we are not checked out to a branch (
or more specifically, to the latest registered version on a branch).
"""
_NAME_TEMPLATE = '__metadata_{}'
[docs]
@dataclasses.dataclass
class SCHEMA:
current_version: int
current_branch: str
detached: bool
changed: bool
has_stash: bool
has_conflicts: bool
def __init__(
self, database: Database, parent_collection_name: str, **kwargs
) -> None:
super().__init__(database, parent_collection_name, **kwargs)
self._metadata: Optional[MetadataCollection.SCHEMA] = None
@property
def metadata(self) -> SCHEMA:
if self._metadata is None:
md = self.find_one({}, projection={'_id': False})
self._metadata = self.SCHEMA(**md)
return self._metadata
@metadata.setter
def metadata(self, metadata: SCHEMA):
if self._metadata == metadata:
return
self._metadata = metadata
self.find_one_and_replace(
filter={}, replacement=self._metadata.__dict__
)
[docs]
def set_metadata(
self,
current_version: Optional[int] = None,
current_branch: Optional[str] = None,
detached: Optional[bool] = None,
changed: Optional[bool] = None,
has_stash: Optional[bool] = None,
has_conflicts: Optional[bool] = None,
) -> None:
"""Set some or all of the metadata attributes."""
metadata = copy(self.metadata)
if current_version is not None:
metadata.current_version = current_version
if current_branch is not None:
metadata.current_branch = current_branch
if detached is not None:
metadata.detached = detached
if changed is not None:
metadata.changed = changed
if has_stash is not None:
metadata.has_stash = has_stash
if has_conflicts is not None:
metadata.has_conflicts = has_conflicts
self.metadata = metadata
[docs]
def build(self) -> bool:
"""Build this collection on the database.
:return: ``True`` if the collection was successfully built, ``False``
otherwise.
"""
if self.exists():
return False
self._metadata = self.SCHEMA(
current_version=0,
current_branch='main',
detached=False,
changed=False,
has_stash=False,
has_conflicts=False,
)
self.insert_one(self._metadata.__dict__)
return True