def shortname(self) -> str: """ Returns the task's shortname. """ d = tablename_to_task_class_dict() taskclass = d[self.task_table_name] return taskclass.shortname
def task_factory_unfiltered(dbsession: SqlASession, basetable: str, serverpk: int) -> Optional[Task]: """ Load a task from the database and return it. No permission filtering is performed. (Used by :class:`camcops_server.cc_modules.cc_taskindex.TaskIndexEntry`.) Args: dbsession: a :class:`sqlalchemy.orm.session.Session` basetable: name of the task's base table serverpk: server PK of the task Returns: the task, or ``None`` if the PK doesn't exist Raises: :exc:`HTTPBadRequest` if the table doesn't exist """ d = tablename_to_task_class_dict() try: cls = d[basetable] # may raise KeyError except KeyError: raise exc.HTTPBadRequest("No such task table: {!r}".format(basetable)) # noinspection PyProtectedMember q = dbsession.query(cls).filter(cls._pk == serverpk) return q.first()
def update_task_index_for_upload( cls, session: SqlASession, tablechanges: UploadTableChanges, indexed_at_utc: Pendulum, ) -> None: """ Updates the index for a device's upload. - Deletes index entries for records that are on the way out. - Creates index entries for records that are on the way in. - Deletes/recreates index entries for records being preserved. Args: session: an SQLAlchemy Session tablechanges: a :class:`camcops_server.cc_modules.cc_client_api_core.UploadTableChanges` object describing the changes to a table indexed_at_utc: current time in UTC """ # noqa tasktablename = tablechanges.tablename d = tablename_to_task_class_dict() try: taskclass = d[tasktablename] # may raise KeyError except KeyError: fail_user_error(f"Bug: no such task table: {tasktablename!r}") # noinspection PyUnresolvedReferences idxtable = cls.__table__ # type: Table idxcols = idxtable.columns # Delete the old. delete_index_pks = tablechanges.task_delete_index_pks if delete_index_pks: log.debug( "Deleting old task indexes: {}, server PKs {}", tasktablename, delete_index_pks, ) # noinspection PyProtectedMember session.execute( idxtable.delete() .where(idxcols.task_table_name == tasktablename) .where(idxcols.task_pk.in_(delete_index_pks)) ) # Create the new. reindex_pks = tablechanges.task_reindex_pks if reindex_pks: log.debug( "Recreating task indexes: {}, server PKs {}", tasktablename, reindex_pks, ) # noinspection PyUnboundLocalVariable,PyProtectedMember q = session.query(taskclass).filter(taskclass._pk.in_(reindex_pks)) for task in q: cls.index_task(task, session, indexed_at_utc=indexed_at_utc)
def task_factory(req: "CamcopsRequest", basetable: str, serverpk: int) -> Optional[Task]: """ Load a task from the database and return it. Filters to tasks permitted to the current user. Args: req: the :class:`camcops_server.cc_modules.cc_request.CamcopsRequest` basetable: name of the task's base table serverpk: server PK of the task Returns: the task, or ``None`` if the PK doesn't exist Raises: :exc:`HTTPBadRequest` if the table doesn't exist """ d = tablename_to_task_class_dict() try: cls = d[basetable] # may raise KeyError except KeyError: raise exc.HTTPBadRequest("No such task table: {!r}".format(basetable)) dbsession = req.dbsession # noinspection PyProtectedMember q = dbsession.query(cls).filter(cls._pk == serverpk) q = task_query_restricted_to_permitted_users(req, q, cls, as_dump=False) return q.first()
def task_classes_from_table_names( tablenames: List[str], sortmethod: TaskClassSortMethod = TaskClassSortMethod.NONE) \ -> List[Type[Task]]: """ Transforms a list of task base tablenames into a list of task classes, appropriately sorted. Args: tablenames: list of task base table names sortmethod: a :class:`TaskClassSortMethod` enum Returns: a list of task classes, in the order requested Raises: :exc:`KeyError` if a table name is invalid """ d = tablename_to_task_class_dict() classes = [] # type: List[Type[Task]] for tablename in tablenames: cls = d[tablename] classes.append(cls) sort_task_classes_in_place(classes, sortmethod) return classes
def task_factory_clientkeys_no_security_checks( dbsession: SqlASession, basetable: str, client_id: int, device_id: int, era: str, ) -> Optional[Task]: """ Load a task from the database and return it. Filters to tasks permitted to the current user. Args: dbsession: a :class:`sqlalchemy.orm.session.Session` basetable: name of the task's base table client_id: task's ``_id`` value device_id: task's ``_device_id`` value era: task's ``_era`` value Returns: the task, or ``None`` if it doesn't exist Raises: :exc:`KeyError` if the table doesn't exist """ d = tablename_to_task_class_dict() cls = d[basetable] # may raise KeyError # noinspection PyProtectedMember q = ( dbsession.query(cls) .filter(cls.id == client_id) .filter(cls._device_id == device_id) .filter(cls._era == era) ) return q.first()
def task_shortname(self) -> str: """ Short name of the task being scheduled. """ task_class_lookup = tablename_to_task_class_dict() return task_class_lookup[self.task_table_name].shortname
def task_ancestor(self) -> Optional["Task"]: from camcops_server.cc_modules.cc_task import ( tablename_to_task_class_dict, ) # noqa # delayed import d = tablename_to_task_class_dict() try: cls = d[self.tablename] # may raise KeyError return cls.get_linked(self.tablepk, self) except KeyError: return None
def _fetch_tasks_from_indexes(self) -> None: """ Takes the query that has already been stored in :attr:`_all_indexes`, and populate the task attributes, :attr:`_all_tasks` and :attr:`_tasks_by_class`. """ if self._all_tasks is not None: return assert self._all_indexes is not None d = tablename_to_task_class_dict() dbsession = self.req.dbsession self._all_tasks = [] # type: List[Task] # Fetch indexes if isinstance(self._all_indexes, Query): # Query built, but indexes not yet fetched. # Replace the query with actual indexes self._all_indexes = (self._all_indexes.all() ) # type: List[TaskIndexEntry] # noqa indexes = self._all_indexes # Fetch tasks tablenames = set(index.task_table_name for index in indexes) for tablename in tablenames: # We do this by task class, so we can execute a single query per # task type (rather than per task). try: taskclass = d[tablename] except KeyError: log.warning("Bad tablename in index: {!r}", tablename) continue tasklist = self._tasks_by_class.setdefault(taskclass, []) task_pks = [i.task_pk for i in indexes if i.tablename == tablename] # noinspection PyProtectedMember qtask = dbsession.query(taskclass).filter( taskclass._pk.in_(task_pks)) qtask = self._filter_query_for_text_contents(qtask, taskclass) tasks = qtask.all() # type: List[Task] for task in tasks: tasklist.append(task) self._all_tasks.append(task) # Sort tasks for tasklist in self._tasks_by_class.values(): sort_tasks_in_place(tasklist, self._sort_method_by_class) sort_tasks_in_place(self._all_tasks, self._sort_method_global)
def task_factory_no_security_checks(dbsession: SqlASession, basetable: str, serverpk: int) -> Optional[Task]: """ Load a task from the database and return it. Filters to tasks permitted to the current user. Args: dbsession: a :class:`sqlalchemy.orm.session.Session` basetable: name of the task's base table serverpk: server PK of the task Returns: the task, or ``None`` if the PK doesn't exist Raises: :exc:`KeyError` if the table doesn't exist """ d = tablename_to_task_class_dict() cls = d[basetable] # may raise KeyError # noinspection PyProtectedMember q = dbsession.query(cls).filter(cls._pk == serverpk) return q.first()
def get_list_of_scheduled_tasks( self, req: "CamcopsRequest") -> List[ScheduledTaskInfo]: """ Tasks scheduled for this patient. """ task_list = [] task_class_lookup = tablename_to_task_class_dict() for tsi in self.task_schedule.items: start_datetime = None end_datetime = None task = None if self.start_datetime is not None: start_datetime = self.start_datetime.add( days=tsi.due_from.days) end_datetime = self.start_datetime.add(days=tsi.due_by.days) task = self.find_scheduled_task(req, tsi, start_datetime, end_datetime) task_class = task_class_lookup[tsi.task_table_name] task_list.append( ScheduledTaskInfo( task_class.shortname, tsi.task_table_name, is_anonymous=task_class.is_anonymous, task=task, start_datetime=start_datetime, end_datetime=end_datetime, )) return task_list