from datetime import datetime from typing import Optional from pymongo.database import Database, Collection from apiserver.bll.task.artifacts import get_artifact_id from apiserver.utilities.dicts import nested_get def _add_active_duration(db: Database): active_duration_key = "active_duration" query = {"$or": [{active_duration_key: {"$eq": None}}, {active_duration_key: {"$eq": 0}}]} collection = db["task"] for doc in collection.find( filter=query, projection=[active_duration_key, "status", "started", "completed"] ): started = doc.get("started") completed = doc.get("completed") running = doc.get("status") == "running" active_duration_value = doc.get(active_duration_key) if active_duration_value == 0: collection.update_one( {"_id": doc["_id"]}, {"$set": {active_duration_key: None}}, ) elif started and active_duration_value is None: collection.update_one( {"_id": doc["_id"]}, {"$set": {active_duration_key: _get_active_duration(completed, running, started)}}, ) def _get_active_duration( completed: datetime, running: bool, started: datetime ) -> Optional[float]: if running: return (datetime.utcnow() - started).total_seconds() elif completed: return (completed - started).total_seconds() else: return None def migrate_backend(db: Database): collection: Collection = db["task"] artifacts_field = "execution.artifacts" query = {artifacts_field: {"$type": 4}} for doc in collection.find(filter=query, projection=(artifacts_field,)): artifacts = nested_get(doc, artifacts_field.split(".")) if not isinstance(artifacts, list): continue new_artifacts = {get_artifact_id(a): a for a in artifacts} collection.update_one( {"_id": doc["_id"]}, {"$set": {artifacts_field: new_artifacts}} ) _add_active_duration(db) def migrate_auth(db: Database): """ Remove the old indices from the user collections to enable building of the updated user email index """ collection: Collection = db["user"] collection.drop_indexes()