diff --git a/lib/galaxy/managers/ratable.py b/lib/galaxy/managers/ratable.py index b1bf4a08e67..b86c5505e3d 100644 --- a/lib/galaxy/managers/ratable.py +++ b/lib/galaxy/managers/ratable.py @@ -49,7 +49,7 @@ class RatableManagerMixin: # TODO?: update and create to RatingsManager (if not overkill) rating = self.rating(item, user, as_int=False) if not rating: - rating = self.rating_assoc(user=user) + rating = self.rating_assoc(user, item) self.associate(rating, item) rating.rating = value diff --git a/lib/galaxy/managers/users.py b/lib/galaxy/managers/users.py index 3407a6bd756..52dabfe1c70 100644 --- a/lib/galaxy/managers/users.py +++ b/lib/galaxy/managers/users.py @@ -237,7 +237,7 @@ class UserManager(base.ModelManager, deletable.PurgableManagerMixin): return schema.BootstrapAdminUser() sa_session = sa_session or self.app.model.session try: - provided_key = sa_session.query(self.app.model.APIKeys).filter(self.app.model.APIKeys.table.c.key == api_key).one() + provided_key = sa_session.query(self.app.model.APIKeys).filter(self.app.model.APIKeys.key == api_key).one() except NoResultFound: raise exceptions.AuthenticationFailed('Provided API key is not valid.') if provided_key.user.deleted: diff --git a/lib/galaxy/model/__init__.py b/lib/galaxy/model/__init__.py index ae3d3fcbdee..b26f2cc7b8c 100644 --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -28,43 +28,60 @@ from typing import ( ) from uuid import UUID, uuid4 +import sqlalchemy from boltons.iterutils import remap from social_core.storage import AssociationMixin, CodeMixin, NonceMixin, PartialMixin, UserMixin from sqlalchemy import ( alias, and_, + asc, BigInteger, Boolean, Column, DateTime, + desc, + false, + ForeignKey, func, + Index, inspect, Integer, join, not_, + Numeric, or_, + PrimaryKeyConstraint, select, String, + Table, TEXT, + Text, text, true, tuple_, type_coerce, - types, + Unicode, UniqueConstraint, VARCHAR, ) from sqlalchemy.exc import OperationalError from sqlalchemy.ext import hybrid +from sqlalchemy.ext.associationproxy import association_proxy +from sqlalchemy.ext.orderinglist import ordering_list from sqlalchemy.orm import ( aliased, + column_property, + deferred, joinedload, object_session, Query, reconstructor, registry, + relationship, ) +from sqlalchemy.orm.collections import attribute_mapped_collection from sqlalchemy.orm.decl_api import DeclarativeMeta +from sqlalchemy.sql import exists import galaxy.exceptions import galaxy.model.metadata @@ -72,8 +89,15 @@ import galaxy.model.orm.now import galaxy.model.tags import galaxy.security.passwords import galaxy.util +from galaxy.model.custom_types import ( + JSONType, + MutableJSONType, + TrimmedString, + UUIDType, +) from galaxy.model.item_attrs import get_item_annotation_str, UsesAnnotations from galaxy.model.orm.now import now +from galaxy.model.view import HistoryDatasetCollectionJobStateSummary from galaxy.security import get_permitted_actions from galaxy.security.validate_user_input import validate_password_str from galaxy.util import ( @@ -113,11 +137,8 @@ AUTO_PROPAGATED_TAGS = ["name"] if TYPE_CHECKING: - from sqlalchemy.schema import Table - class _HasTable: table: Table - else: _HasTable = object @@ -282,16 +303,15 @@ class WorkerProcess(Base, UsesCreateAndUpdateTime, _HasTable): UniqueConstraint('server_name', 'hostname'), ) - id = Column("id", Integer, primary_key=True) - server_name = Column("server_name", String(255), index=True) - hostname = Column("hostname", String(255)) - pid = Column("pid", Integer) - update_time = Column("update_time", DateTime, default=now, onupdate=now) + id = Column(Integer, primary_key=True) + server_name = Column(String(255), index=True) + hostname = Column(String(255)) + pid = Column(Integer) + update_time = Column(DateTime, default=now, onupdate=now) def __init__(self, server_name, hostname): self.server_name = server_name self.hostname = hostname - self.pid = None def cached_id(galaxy_model_object): @@ -409,14 +429,84 @@ class JobLike: raise NotImplementedError("Attempt to set stdout, must set tool_stderr or job_stderr") -class User(Dictifiable, RepresentById): +class User(Base, Dictifiable, RepresentById): use_pbkdf2 = True bootstrap_admin_user = False - api_keys: 'List[APIKeys]' + # api_keys: 'List[APIKeys]' already declared as relationship() """ Data for a Galaxy user or admin and relations to their histories, credentials, and roles. """ + + __tablename__ = 'galaxy_user' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + email = Column(TrimmedString(255), index=True, nullable=False) + username = Column(TrimmedString(255), index=True, unique=True) + password = Column(TrimmedString(255), nullable=False) + last_password_change = Column(DateTime, default=now) + external = Column(Boolean, default=False) + form_values_id = Column(Integer, ForeignKey('form_values.id'), index=True) + deleted = Column(Boolean, index=True, default=False) + purged = Column(Boolean, index=True, default=False) + disk_usage = Column(Numeric(15, 0), index=True) + # Column("person_metadata", JSONType), # TODO: add persistent, configurable metadata rep for workflow creator + active = Column(Boolean, index=True, default=True, nullable=False) + activation_token = Column(TrimmedString(64), nullable=True, index=True) + + addresses = relationship('UserAddress', + back_populates='user', + order_by=lambda: desc(UserAddress.update_time)) # type: ignore + cloudauthz = relationship('CloudAuthz', back_populates='user') + custos_auth = relationship('CustosAuthnzToken', back_populates='user') + default_permissions = relationship('DefaultUserPermissions', back_populates='user') + groups = relationship('UserGroupAssociation', back_populates='user') + histories = relationship('History', + back_populates='user', + order_by=lambda: desc(History.update_time)) # type: ignore + active_histories = relationship('History', + primaryjoin=(lambda: (History.user_id == User.id) & (not_(History.deleted))), # type: ignore + viewonly=True, + order_by=lambda: desc(History.update_time)) # type: ignore + galaxy_sessions = relationship('GalaxySession', + back_populates='user', + order_by=lambda: desc(GalaxySession.update_time)) # type: ignore + pages_shared_by_others = relationship('PageUserShareAssociation', back_populates='user') + quotas = relationship('UserQuotaAssociation', back_populates='user') + social_auth = relationship('UserAuthnzToken', back_populates='user') + stored_workflow_menu_entries = relationship('StoredWorkflowMenuEntry', + primaryjoin=(lambda: + (StoredWorkflowMenuEntry.user_id == User.id) # type: ignore + & (StoredWorkflowMenuEntry.stored_workflow_id == StoredWorkflow.id) # type: ignore + & not_(StoredWorkflow.deleted) # type: ignore + ), + back_populates='user', + cascade='all, delete-orphan', + collection_class=ordering_list('order_index')) + _preferences = relationship('UserPreference', + back_populates='user', + collection_class=attribute_mapped_collection('name')) + values = relationship('FormValues', + primaryjoin=(lambda: User.form_values_id == FormValues.id)) # type: ignore + # Add type hint (will this work w/SA?) + api_keys: 'List[APIKeys]' = relationship('APIKeys', + back_populates='user', + order_by=lambda: desc(APIKeys.create_time)) # type: ignore + pages = relationship('Page', back_populates='user') + reset_tokens = relationship('PasswordResetToken', back_populates='user') + histories_shared_by_others = relationship('HistoryUserShareAssociation', back_populates='user') + data_manager_histories = relationship('DataManagerHistoryAssociation', back_populates='user') + workflows_shared_by_others = relationship('StoredWorkflowUserShareAssociation', back_populates='user') + roles = relationship('UserRoleAssociation', back_populates='user') + stored_workflows = relationship('StoredWorkflow', back_populates='user', + primaryjoin=(lambda: User.id == StoredWorkflow.user_id)) # type: ignore + visualizations_shared_by_others = relationship('VisualizationUserShareAssociation', + back_populates='user') + + preferences: association_proxy # defined at the end of this module + # attributes that will be accessed and returned when calling to_dict( view='collection' ) dict_collection_visible_keys = ['id', 'email', 'username', 'deleted', 'active', 'last_password_change'] # attributes that will be accessed and returned when calling to_dict( view='element' ) @@ -673,7 +763,14 @@ class User(Dictifiable, RepresentById): session.flush() -class PasswordResetToken(_HasTable): +class PasswordResetToken(Base, _HasTable): + __tablename__ = 'password_reset_token' + + token = Column(String(32), primary_key=True, unique=True, index=True) + expiration_time = Column(DateTime) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + user = relationship('User', back_populates='reset_tokens') + def __init__(self, user, token=None): if token: self.token = token @@ -683,7 +780,23 @@ class PasswordResetToken(_HasTable): self.expiration_time = galaxy.model.orm.now.now() + timedelta(hours=24) -class DynamicTool(Dictifiable, RepresentById): +class DynamicTool(Base, Dictifiable, RepresentById): + __tablename__ = 'dynamic_tool' + + id = Column(Integer, primary_key=True) + uuid = Column(UUIDType()) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, index=True, default=now, onupdate=now) + tool_id = Column(Unicode(255)) + tool_version = Column(Unicode(255)) + tool_format = Column(Unicode(255)) + tool_path = Column(Unicode(255)) + tool_directory = Column(Unicode(255)) + hidden = Column(Boolean, default=True) + active = Column(Boolean, default=True) + value = Column(MutableJSONType) + workflow_steps = relationship('WorkflowStep', back_populates='dynamic_tool') + dict_collection_visible_keys = ('id', 'tool_id', 'tool_format', 'tool_version', 'uuid', 'active', 'hidden') dict_element_visible_keys = ('id', 'tool_id', 'tool_format', 'tool_version', 'uuid', 'active', 'hidden') @@ -711,30 +824,136 @@ class BaseJobMetric: self.metric_value = metric_value -class JobMetricText(BaseJobMetric, RepresentById): - pass +class JobMetricText(Base, BaseJobMetric, RepresentById): + __tablename__ = 'job_metric_text' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True) + plugin = Column(Unicode(255)) + metric_name = Column(Unicode(255)) + metric_value = Column(Unicode(JOB_METRIC_MAX_LENGTH)) + job = relationship('Job', back_populates='text_metrics') -class JobMetricNumeric(BaseJobMetric, RepresentById): - pass +class JobMetricNumeric(Base, BaseJobMetric, RepresentById): + __tablename__ = 'job_metric_numeric' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True) + plugin = Column(Unicode(255)) + metric_name = Column(Unicode(255)) + metric_value = Column(Numeric(JOB_METRIC_PRECISION, JOB_METRIC_SCALE)) + job = relationship('Job', back_populates='numeric_metrics') -class TaskMetricText(BaseJobMetric, RepresentById): - pass +class TaskMetricText(Base, BaseJobMetric, RepresentById): + __tablename__ = 'task_metric_text' + + id = Column(Integer, primary_key=True) + task_id = Column(Integer, ForeignKey('task.id'), index=True) + plugin = Column(Unicode(255)) + metric_name = Column(Unicode(255)) + metric_value = Column(Unicode(JOB_METRIC_MAX_LENGTH)) + task = relationship('Task', back_populates='text_metrics') -class TaskMetricNumeric(BaseJobMetric, RepresentById): - pass +class TaskMetricNumeric(Base, BaseJobMetric, RepresentById): + __tablename__ = 'task_metric_numeric' + + id = Column(Integer, primary_key=True) + task_id = Column(Integer, ForeignKey('task.id'), index=True) + plugin = Column(Unicode(255)) + metric_name = Column(Unicode(255)) + metric_value = Column(Numeric(JOB_METRIC_PRECISION, JOB_METRIC_SCALE)) + task = relationship('Task', back_populates='numeric_metrics') -class Job(JobLike, UsesCreateAndUpdateTime, Dictifiable, RepresentById): - dict_collection_visible_keys = ['id', 'state', 'exit_code', 'update_time', 'create_time', 'galaxy_version'] - dict_element_visible_keys = ['id', 'state', 'exit_code', 'update_time', 'create_time', 'galaxy_version', 'command_version'] - +class Job(Base, JobLike, UsesCreateAndUpdateTime, Dictifiable, RepresentById): """ A job represents a request to run a tool given input datasets, tool parameters, and output datasets. """ + __tablename__ = 'job' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now, index=True) + history_id = Column(Integer, ForeignKey('history.id'), index=True) + library_folder_id = Column(Integer, ForeignKey('library_folder.id'), index=True) + tool_id = Column(String(255)) + tool_version = Column(TEXT, default='1.0.0') + galaxy_version = Column(String(64), default=None) + dynamic_tool_id = Column(Integer, ForeignKey('dynamic_tool.id'), index=True, nullable=True) + state = Column(String(64), index=True) + info = Column(TrimmedString(255)) + copied_from_job_id = Column(Integer, nullable=True) + command_line = Column(TEXT) + dependencies = Column(MutableJSONType, nullable=True) + job_messages = Column(MutableJSONType, nullable=True) + param_filename = Column(String(1024)) + runner_name = Column(String(255)) + job_stdout = Column(TEXT) + job_stderr = Column(TEXT) + tool_stdout = Column(TEXT) + tool_stderr = Column(TEXT) + exit_code = Column(Integer, nullable=True) + traceback = Column(TEXT) + session_id = Column(Integer, ForeignKey('galaxy_session.id'), index=True, nullable=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True, nullable=True) + job_runner_name = Column(String(255)) + job_runner_external_id = Column(String(255), index=True) + destination_id = Column(String(255), nullable=True) + destination_params = Column(MutableJSONType, nullable=True) + object_store_id = Column(TrimmedString(255), index=True) + imported = Column(Boolean, default=False, index=True) + params = Column(TrimmedString(255), index=True) + handler = Column(TrimmedString(255), index=True) + + user = relationship('User') + galaxy_session = relationship('GalaxySession') + history = relationship('History', back_populates='jobs') + library_folder = relationship('LibraryFolder', lazy=True) + parameters = relationship('JobParameter', lazy=True) + input_datasets = relationship('JobToInputDatasetAssociation', back_populates='job') + input_dataset_collections = relationship('JobToInputDatasetCollectionAssociation', + back_populates='job', lazy=True) + input_dataset_collection_elements = relationship('JobToInputDatasetCollectionElementAssociation', + back_populates='job', lazy=True) + output_dataset_collection_instances = relationship('JobToOutputDatasetCollectionAssociation', + back_populates='job', lazy=True) + output_dataset_collections = relationship('JobToImplicitOutputDatasetCollectionAssociation', + back_populates='job', lazy=True) + post_job_actions = relationship('PostJobActionAssociation', back_populates='job', lazy=False) + input_library_datasets = relationship('JobToInputLibraryDatasetAssociation', + back_populates='job') + output_library_datasets = relationship('JobToOutputLibraryDatasetAssociation', + back_populates='job', lazy=True) + external_output_metadata = relationship('JobExternalOutputMetadata', + lazy=True, back_populates='job') + tasks = relationship('Task', back_populates='job') + output_datasets = relationship('JobToOutputDatasetAssociation', back_populates='job') + state_history = relationship('JobStateHistory', back_populates='job') + text_metrics = relationship('JobMetricText', back_populates='job') + numeric_metrics = relationship('JobMetricNumeric', back_populates='job') + job = relationship('GenomeIndexToolData', back_populates='job') + interactivetool_entry_points = relationship('InteractiveToolEntryPoint', + back_populates='job', uselist=True) + implicit_collection_jobs_association = relationship('ImplicitCollectionJobsJobAssociation', + back_populates='job', uselist=False) + container = relationship('JobContainerAssociation', back_populates='job', uselist=False) + data_manager_association = relationship('DataManagerJobAssociation', + back_populates='job', uselist=False) + history_dataset_collection_associations = relationship('HistoryDatasetCollectionAssociation', + back_populates='job') + workflow_invocation_step = relationship('WorkflowInvocationStep', + back_populates='job', uselist=False) + + any_output_dataset_collection_instances_deleted: column_property # defined at the end of this module + any_output_dataset_deleted: column_property # defined at the end of this module + + dict_collection_visible_keys = ['id', 'state', 'exit_code', 'update_time', 'create_time', 'galaxy_version'] + dict_element_visible_keys = ['id', 'state', 'exit_code', 'update_time', 'create_time', 'galaxy_version', 'command_version'] + _numeric_metric = JobMetricNumeric _text_metric = JobMetricText @@ -1368,10 +1587,37 @@ class Job(JobLike, UsesCreateAndUpdateTime, Dictifiable, RepresentById): return False -class Task(JobLike, RepresentById): +class Task(Base, JobLike, RepresentById): """ A task represents a single component of a job. """ + __tablename__ = 'task' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + execution_time = Column(DateTime) + update_time = Column(DateTime, default=now, onupdate=now) + state = Column(String(64), index=True) + command_line = Column(TEXT) + param_filename = Column(String(1024)) + runner_name = Column(String(255)) + job_stdout = Column(TEXT) # job_stdout makes sense here because it is short for job script standard out + job_stderr = Column(TEXT) + tool_stdout = Column(TEXT) + tool_stderr = Column(TEXT) + exit_code = Column(Integer, nullable=True) + job_messages = Column(MutableJSONType, nullable=True) + info = Column(TrimmedString(255)) + traceback = Column(TEXT) + job_id = Column(Integer, ForeignKey('job.id'), index=True, nullable=False) + working_directory = Column(String(1024)) + task_runner_name = Column(String(255)) + task_runner_external_id = Column(String(255)) + prepare_input_files_cmd = Column(TEXT) + job = relationship('Job', back_populates='tasks') + text_metrics = relationship('TaskMetricText', back_populates='task') + numeric_metrics = relationship('TaskMetricNumeric', back_populates='task') + _numeric_metric = TaskMetricNumeric _text_metric = TaskMetricText @@ -1519,7 +1765,14 @@ class Task(JobLike, RepresentById): self.prepare_input_files_cmd = prepare_input_files_cmd -class JobParameter(RepresentById): +class JobParameter(Base, RepresentById): + __tablename__ = 'job_parameter' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True) + name = Column(String(255)) + value = Column(TEXT) + def __init__(self, name, value): self.name = name self.value = value @@ -1528,26 +1781,68 @@ class JobParameter(RepresentById): return JobParameter(name=self.name, value=self.value) -class JobToInputDatasetAssociation(RepresentById): +class JobToInputDatasetAssociation(Base, RepresentById): + __tablename__ = 'job_to_input_dataset' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True) + dataset_id = Column(Integer, + ForeignKey('history_dataset_association.id'), index=True) + dataset_version = Column(Integer) + name = Column(String(255)) + dataset = relationship('HistoryDatasetAssociation', lazy=False, back_populates='dependent_jobs') + job = relationship('Job', back_populates='input_datasets') + def __init__(self, name, dataset): self.name = name self.dataset = dataset self.dataset_version = 0 # We start with version 0 and update once the job is ready -class JobToOutputDatasetAssociation(RepresentById): +class JobToOutputDatasetAssociation(Base, RepresentById): + __tablename__ = 'job_to_output_dataset' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True) + dataset_id = Column(Integer, ForeignKey('history_dataset_association.id'), index=True) + name = Column(String(255)) + dataset = relationship('HistoryDatasetAssociation', + lazy=False, back_populates='creating_job_associations') + job = relationship('Job', back_populates='output_datasets') + def __init__(self, name, dataset): self.name = name self.dataset = dataset -class JobToInputDatasetCollectionAssociation(RepresentById): +class JobToInputDatasetCollectionAssociation(Base, RepresentById): + __tablename__ = 'job_to_input_dataset_collection' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True) + dataset_collection_id = Column(Integer, + ForeignKey('history_dataset_collection_association.id'), index=True) + dataset_version = Column(Integer) + name = Column(String(255)) + dataset_collection = relationship('HistoryDatasetCollectionAssociation', lazy=False) + job = relationship('Job', back_populates='input_dataset_collections') + def __init__(self, name, dataset_collection): self.name = name self.dataset_collection = dataset_collection -class JobToInputDatasetCollectionElementAssociation(RepresentById): +class JobToInputDatasetCollectionElementAssociation(Base, RepresentById): + __tablename__ = 'job_to_input_dataset_collection_element' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True) + dataset_collection_element_id = Column(Integer, + ForeignKey('dataset_collection_element.id'), index=True) + name = Column(Unicode(255)) + dataset_collection_element = relationship('DatasetCollectionElement', lazy=False) + job = relationship('Job', back_populates='input_dataset_collection_elements') + def __init__(self, name, dataset_collection_element): self.name = name self.dataset_collection_element = dataset_collection_element @@ -1555,7 +1850,20 @@ class JobToInputDatasetCollectionElementAssociation(RepresentById): # Many jobs may map to one HistoryDatasetCollection using these for a given # tool output (if mapping over an input collection). -class JobToOutputDatasetCollectionAssociation(RepresentById): +class JobToOutputDatasetCollectionAssociation(Base, RepresentById): + __tablename__ = 'job_to_output_dataset_collection' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True) + dataset_collection_id = Column(Integer, + ForeignKey('history_dataset_collection_association.id'), index=True) + name = Column(Unicode(255)) + dataset_collection_instance = relationship( + 'HistoryDatasetCollectionAssociation', + lazy=False, + back_populates="output_dataset_collection_instances") + job = relationship('Job', back_populates='output_dataset_collection_instances') + def __init__(self, name, dataset_collection_instance): self.name = name self.dataset_collection_instance = dataset_collection_instance @@ -1564,38 +1872,106 @@ class JobToOutputDatasetCollectionAssociation(RepresentById): # A DatasetCollection will be mapped to at most one job per tool output # using these. (You can think of many of these models as going into the # creation of a JobToOutputDatasetCollectionAssociation.) -class JobToImplicitOutputDatasetCollectionAssociation(RepresentById): +class JobToImplicitOutputDatasetCollectionAssociation(Base, RepresentById): + __tablename__ = 'job_to_implicit_output_dataset_collection' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True) + dataset_collection_id = Column(Integer, ForeignKey('dataset_collection.id'), index=True) + name = Column(Unicode(255)) + dataset_collection = relationship( + 'DatasetCollection', back_populates="output_dataset_collections") + job = relationship('Job', back_populates='output_dataset_collections') + def __init__(self, name, dataset_collection): self.name = name self.dataset_collection = dataset_collection -class JobToInputLibraryDatasetAssociation(RepresentById): +class JobToInputLibraryDatasetAssociation(Base, RepresentById): + __tablename__ = 'job_to_input_library_dataset' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True) + ldda_id = Column(Integer, ForeignKey('library_dataset_dataset_association.id'), index=True) + name = Column(Unicode(255)) + job = relationship('Job', back_populates='input_library_datasets') + dataset = relationship( + 'LibraryDatasetDatasetAssociation', lazy=False, back_populates='dependent_jobs') + def __init__(self, name, dataset): self.name = name self.dataset = dataset -class JobToOutputLibraryDatasetAssociation(RepresentById): +class JobToOutputLibraryDatasetAssociation(Base, RepresentById): + __tablename__ = 'job_to_output_library_dataset' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True) + ldda_id = Column(Integer, ForeignKey('library_dataset_dataset_association.id'), index=True) + name = Column(Unicode(255)) + job = relationship('Job', back_populates='output_library_datasets') + dataset = relationship( + 'LibraryDatasetDatasetAssociation', lazy=False, back_populates='creating_job_associations') + def __init__(self, name, dataset): self.name = name self.dataset = dataset -class JobStateHistory(RepresentById): +class JobStateHistory(Base, RepresentById): + __tablename__ = 'job_state_history' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + job_id = Column(Integer, ForeignKey('job.id'), index=True) + state = Column(String(64), index=True) + info = Column(TrimmedString(255)) + job = relationship('Job', back_populates='state_history') + def __init__(self, job): self.job = job self.state = job.state self.info = job.info -class ImplicitlyCreatedDatasetCollectionInput(RepresentById): +class ImplicitlyCreatedDatasetCollectionInput(Base, RepresentById): + __tablename__ = 'implicitly_created_dataset_collection_inputs' + + id = Column(Integer, primary_key=True) + dataset_collection_id = Column(Integer, + ForeignKey('history_dataset_collection_association.id'), index=True) + input_dataset_collection_id = Column(Integer, + ForeignKey('history_dataset_collection_association.id'), index=True) + name = Column(Unicode(255)) + + input_dataset_collection = relationship('HistoryDatasetCollectionAssociation', + primaryjoin=(lambda: HistoryDatasetCollectionAssociation.id # type: ignore + == ImplicitlyCreatedDatasetCollectionInput.input_dataset_collection_id) # type: ignore + ) + dataset_collection = relationship('HistoryDatasetCollectionAssociation', + primaryjoin=(lambda: HistoryDatasetCollectionAssociation.id # type: ignore + == ImplicitlyCreatedDatasetCollectionInput.dataset_collection_id), # type: ignore + back_populates='implicit_input_collections') + def __init__(self, name, input_dataset_collection): self.name = name self.input_dataset_collection = input_dataset_collection -class ImplicitCollectionJobs(RepresentById): +class ImplicitCollectionJobs(Base, RepresentById): + __tablename__ = 'implicit_collection_jobs' + + id = Column(Integer, primary_key=True) + populated_state = Column(TrimmedString(64), default='new', nullable=False) + jobs = relationship('ImplicitCollectionJobsJobAssociation', + back_populates='implicit_collection_jobs') + history_dataset_collection_associations = relationship('HistoryDatasetCollectionAssociation', + back_populates='implicit_collection_jobs') + workflow_invocation_step = relationship('WorkflowInvocationStep', + back_populates='implicit_collection_jobs', uselist=False) class populated_states(str, Enum): NEW = 'new' # New implicit jobs object, unpopulated job associations @@ -1624,13 +2000,33 @@ class ImplicitCollectionJobs(RepresentById): return rval -class ImplicitCollectionJobsJobAssociation(RepresentById): +class ImplicitCollectionJobsJobAssociation(Base, RepresentById): + __tablename__ = 'implicit_collection_jobs_job_association' + + id = Column(Integer, primary_key=True) + implicit_collection_jobs_id = Column(Integer, ForeignKey('implicit_collection_jobs.id'), index=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True) # Consider making this nullable... + order_index = Column(Integer, nullable=False) + implicit_collection_jobs = relationship('ImplicitCollectionJobs', back_populates='jobs') + job = relationship('Job', back_populates='implicit_collection_jobs_association') def __init__(self): self.implicit_collection_jobs_id = None -class PostJobAction(RepresentById): +class PostJobAction(Base, RepresentById): + __tablename__ = 'post_job_action' + + id = Column(Integer, primary_key=True) + workflow_step_id = Column(Integer, ForeignKey('workflow_step.id'), index=True, nullable=True) + action_type = Column(String(255), nullable=False) + output_name = Column(String(255), nullable=True) + action_arguments = Column(MutableJSONType, nullable=True) + workflow_step = relationship('WorkflowStep', + back_populates='post_job_actions', + primaryjoin=(lambda: WorkflowStep.id == PostJobAction.workflow_step_id) # type: ignore + ) + def __init__(self, action_type, workflow_step=None, output_name=None, action_arguments=None): self.action_type = action_type self.output_name = output_name @@ -1638,7 +2034,15 @@ class PostJobAction(RepresentById): self.workflow_step = workflow_step -class PostJobActionAssociation(RepresentById): +class PostJobActionAssociation(Base, RepresentById): + __tablename__ = 'post_job_action_association' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True, nullable=False) + post_job_action_id = Column(Integer, ForeignKey('post_job_action.id'), index=True, nullable=False) + post_job_action = relationship('PostJobAction') + job = relationship('Job', back_populates='post_job_actions') + def __init__(self, pja, job=None, job_id=None): if job is not None: self.job = job @@ -1649,7 +2053,26 @@ class PostJobActionAssociation(RepresentById): self.post_job_action = pja -class JobExternalOutputMetadata(RepresentById): +class JobExternalOutputMetadata(Base, RepresentById): + __tablename__ = 'job_external_output_metadata' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True) + history_dataset_association_id = Column(Integer, + ForeignKey('history_dataset_association.id'), index=True, nullable=True) + library_dataset_dataset_association_id = Column(Integer, + ForeignKey('library_dataset_dataset_association.id'), index=True, nullable=True) + is_valid = Column(Boolean, default=True) + filename_in = Column(String(255)) + filename_out = Column(String(255)) + filename_results_code = Column(String(255)) + filename_kwds = Column(String(255)) + filename_override_metadata = Column(String(255)) + job_runner_external_pid = Column(String(255)) + history_dataset_association = relationship('HistoryDatasetAssociation', lazy=False) + library_dataset_dataset_association = relationship('LibraryDatasetDatasetAssociation', lazy=False) + job = relationship('Job', back_populates='external_output_metadata') + def __init__(self, job=None, dataset=None): self.job = job if isinstance(dataset, galaxy.model.HistoryDatasetAssociation): @@ -1682,7 +2105,19 @@ class FakeDatasetAssociation: return isinstance(other, FakeDatasetAssociation) and self.dataset == other.dataset -class JobExportHistoryArchive(RepresentById): +class JobExportHistoryArchive(Base, RepresentById): + __tablename__ = 'job_export_history_archive' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True) + history_id = Column(Integer, ForeignKey('history.id'), index=True) + dataset_id = Column(Integer, ForeignKey('dataset.id'), index=True) + compressed = Column(Boolean, index=True, default=False) + history_attrs_filename = Column(TEXT) + job = relationship('Job') + dataset = relationship('Dataset', back_populates='job_export_history_archive') + history = relationship('History', back_populates='exports') + ATTRS_FILENAME_HISTORY = 'history_attrs.txt' def __init__(self, job=None, history=None, dataset=None, compressed=False, @@ -1762,14 +2197,34 @@ class JobExportHistoryArchive(RepresentById): } -class JobImportHistoryArchive(RepresentById): +class JobImportHistoryArchive(Base, RepresentById): + __tablename__ = 'job_import_history_archive' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True) + history_id = Column(Integer, ForeignKey('history.id'), index=True) + archive_dir = Column(TEXT) + job = relationship('Job') + history = relationship('History') + def __init__(self, job=None, history=None, archive_dir=None): self.job = job self.history = history self.archive_dir = archive_dir -class JobContainerAssociation(RepresentById): +class JobContainerAssociation(Base, RepresentById): + __tablename__ = 'job_container_association' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True) + container_type = Column(TEXT) + container_name = Column(TEXT) + container_info = Column(MutableJSONType, nullable=True) + created_time = Column(DateTime, default=now) + modified_time = Column(DateTime, default=now, onupdate=now) + job = relationship('Job', back_populates='container') + def __init__(self, job=None, container_type=None, container_name=None, container_info=None): self.job = job self.container_type = container_type @@ -1777,7 +2232,26 @@ class JobContainerAssociation(RepresentById): self.container_info = container_info or {} -class InteractiveToolEntryPoint(Dictifiable, RepresentById): +class InteractiveToolEntryPoint(Base, Dictifiable, RepresentById): + __tablename__ = 'interactivetool_entry_point' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey("job.id"), index=True) + name = Column(TEXT) + token = Column(TEXT) + tool_port = Column(Integer) + host = Column(TEXT) + port = Column(Integer) + protocol = Column(TEXT) + entry_url = Column(TEXT) + requires_domain = Column(Boolean, default=True) + info = Column(MutableJSONType, nullable=True) + configured = Column(Boolean, default=False) + deleted = Column(Boolean, default=False) + created_time = Column(DateTime, default=now) + modified_time = Column(DateTime, default=now, onupdate=now) + job = relationship('Job', back_populates='interactivetool_entry_points', uselist=False) + dict_collection_visible_keys = ['id', 'name', 'active', 'created_time', 'modified_time'] dict_element_visible_keys = ['id', 'name', 'active', 'created_time', 'modified_time'] @@ -1806,7 +2280,25 @@ class InteractiveToolEntryPoint(Dictifiable, RepresentById): return False -class GenomeIndexToolData(RepresentById): +class GenomeIndexToolData(Base, RepresentById): # TODO: params arg is lost + __tablename__ = 'genome_index_tool_data' + + id = Column(Integer, primary_key=True) + job_id = Column(Integer, ForeignKey("job.id"), index=True) + deferred_job_id = Column(Integer, ForeignKey('deferred_job.id'), index=True) + transfer_job_id = Column(Integer, ForeignKey('transfer_job.id'), index=True) + dataset_id = Column(Integer, ForeignKey('dataset.id'), index=True) + fasta_path = Column(String(255)) + created_time = Column(DateTime, default=now) + modified_time = Column(DateTime, default=now, onupdate=now) + indexer = Column(String(64)) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + job = relationship('Job', back_populates='job') + dataset = relationship('Dataset', back_populates='genome_index_tool_data') + user = relationship('User') + deferred = relationship('DeferredJob', back_populates='deferred_job') + transfer = relationship('TransferJob', back_populates='transfer_job') + def __init__(self, job=None, params=None, dataset=None, deferred_job=None, transfer_job=None, fasta_path=None, created_time=None, modified_time=None, dbkey=None, user=None, indexer=None): @@ -1821,7 +2313,16 @@ class GenomeIndexToolData(RepresentById): self.transfer = transfer_job -class DeferredJob(RepresentById): +class DeferredJob(Base, RepresentById): + __tablename__ = 'deferred_job' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + state = Column(String(64), index=True) + plugin = Column(String(128), index=True) + params = Column(MutableJSONType) + deferred_job = relationship('GenomeIndexToolData', back_populates='deferred') class states(str, Enum): NEW = 'new' @@ -1870,11 +2371,14 @@ class DeferredJob(RepresentById): class Group(Base, Dictifiable, RepresentById): __tablename__ = 'galaxy_group' - id = Column("id", Integer, primary_key=True) - create_time = Column("create_time", DateTime, default=now) - update_time = Column("update_time", DateTime, default=now, onupdate=now) - name = Column("name", String(255), index=True, unique=True) - deleted = Column("deleted", Boolean, index=True, default=False) + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + name = Column(String(255), index=True, unique=True) + deleted = Column(Boolean, index=True, default=False) + quotas = relationship('GroupQuotaAssociation', back_populates='group') + roles = relationship('GroupRoleAssociation', back_populates='group') + users = relationship('UserGroupAssociation', back_populates='group') dict_collection_visible_keys = ['id', 'name'] dict_element_visible_keys = ['id', 'name'] @@ -1884,7 +2388,17 @@ class Group(Base, Dictifiable, RepresentById): self.deleted = False -class UserGroupAssociation(RepresentById): +class UserGroupAssociation(Base, RepresentById): + __tablename__ = 'user_group_association' + + id = Column(Integer, primary_key=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + group_id = Column(Integer, ForeignKey('galaxy_group.id'), index=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + user = relationship('User', back_populates='groups') + group = relationship('Group', back_populates='users') + def __init__(self, user, group): self.user = user self.group = group @@ -1894,7 +2408,16 @@ def is_hda(d): return isinstance(d, HistoryDatasetAssociation) -class HistoryAudit(RepresentById): +class HistoryAudit(Base, RepresentById): + __tablename__ = 'history_audit' + __table_args__ = ( + PrimaryKeyConstraint(sqlite_on_conflict='IGNORE'), + ) + + history_id = Column(Integer, ForeignKey('history.id'), primary_key=True, nullable=False) + update_time = Column(DateTime, default=now, primary_key=True, nullable=False) + history = relationship('History') + def __init__(self, history, update_time): self.history = history self.update_time = update_time @@ -1915,7 +2438,90 @@ class HistoryAudit(RepresentById): sa_session.execute(d.where(tuple_(history_audit_table.c.history_id, history_audit_table.c.update_time).in_(not_latest_query))) -class History(HasTags, Dictifiable, UsesAnnotations, HasName, RepresentById): +class History(Base, HasTags, Dictifiable, UsesAnnotations, HasName, RepresentById): + __tablename__ = 'history' + __table_args__ = ( + Index('ix_history_slug', 'slug', mysql_length=200), + ) + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + _update_time = Column('update_time', DateTime, index=True, default=now, onupdate=now) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + name = Column(TrimmedString(255)) + hid_counter = Column(Integer, default=1) + deleted = Column(Boolean, index=True, default=False) + purged = Column(Boolean, index=True, default=False) + importing = Column(Boolean, index=True, default=False) + genome_build = Column(TrimmedString(40)) + importable = Column(Boolean, default=False) + slug = Column(TEXT) + published = Column(Boolean, index=True, default=False) + + datasets = relationship('HistoryDatasetAssociation', + back_populates='history', + order_by=lambda: asc(HistoryDatasetAssociation.hid)) # type: ignore + exports = relationship('JobExportHistoryArchive', + back_populates='history', + primaryjoin=lambda: JobExportHistoryArchive.history_id == History.id, # type: ignore + order_by=lambda: desc(JobExportHistoryArchive.id)) # type: ignore + active_datasets = relationship('HistoryDatasetAssociation', + primaryjoin=( + lambda: and_(HistoryDatasetAssociation.history_id # type: ignore + == History.id, not_(HistoryDatasetAssociation.deleted)) # type: ignore + ), + order_by=lambda: asc(HistoryDatasetAssociation.hid), # type: ignore + viewonly=True) + dataset_collections = relationship('HistoryDatasetCollectionAssociation', back_populates='history') + active_dataset_collections = relationship('HistoryDatasetCollectionAssociation', + primaryjoin=( + lambda: (and_(HistoryDatasetCollectionAssociation.history_id == History.id, # type: ignore + not_(HistoryDatasetCollectionAssociation.deleted))) # type: ignore + ), + order_by=lambda: asc(HistoryDatasetCollectionAssociation.hid), # type: ignore + viewonly=True) + visible_datasets = relationship('HistoryDatasetAssociation', + primaryjoin=( + lambda: and_(HistoryDatasetAssociation.history_id == History.id, # type: ignore + not_(HistoryDatasetAssociation.deleted), HistoryDatasetAssociation.visible) # type: ignore + ), + order_by=lambda: asc(HistoryDatasetAssociation.hid), # type: ignore + viewonly=True) + visible_dataset_collections = relationship('HistoryDatasetCollectionAssociation', + primaryjoin=( + lambda: and_( + HistoryDatasetCollectionAssociation.history_id == History.id, # type: ignore + not_(HistoryDatasetCollectionAssociation.deleted), # type: ignore + HistoryDatasetCollectionAssociation.visible) # type: ignore + ), + order_by=lambda: asc(HistoryDatasetCollectionAssociation.hid), # type: ignore + viewonly=True) + tags = relationship('HistoryTagAssociation', + order_by=lambda: HistoryTagAssociation.id, # type: ignore + back_populates='history') + annotations = relationship('HistoryAnnotationAssociation', + order_by=lambda: HistoryAnnotationAssociation.id, # type: ignore + back_populates='history') + ratings = relationship('HistoryRatingAssociation', + order_by=lambda: HistoryRatingAssociation.id, # type: ignore + back_populates='history') + default_permissions = relationship('DefaultHistoryPermissions', back_populates='history') + users_shared_with = relationship('HistoryUserShareAssociation', back_populates='history') + galaxy_sessions = relationship('GalaxySessionToHistoryAssociation', back_populates='history') + workflow_invocations = relationship('WorkflowInvocation', back_populates='history') + user = relationship('User', back_populates='histories') + jobs = relationship('Job', back_populates='history') + + update_time = column_property( + select(func.max(HistoryAudit.update_time)).where(HistoryAudit.history_id == id).scalar_subquery(), + ) + users_shared_with_count: column_property # defined at the end of this module + average_rating: column_property # defined at the end of this module + + # Set up proxy so that + # History.users_shared_with + # returns a list of users that history is shared with. + users_shared_with_dot_users = association_proxy('users_shared_with', 'user') dict_collection_visible_keys = ['id', 'name', 'published', 'deleted'] dict_element_visible_keys = ['id', 'name', 'genome_build', 'deleted', 'purged', 'update_time', @@ -2316,19 +2922,59 @@ class UserShareAssociation(RepresentById): user: Optional[User] -class HistoryUserShareAssociation(UserShareAssociation): +class HistoryUserShareAssociation(Base, UserShareAssociation): + __tablename__ = 'history_user_share_association' + + id = Column(Integer, primary_key=True) + history_id = Column(Integer, ForeignKey('history.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + user = relationship('User', back_populates='histories_shared_by_others') + history = relationship('History', back_populates='users_shared_with') + def __init__(self): self.history = None self.user = None -class UserRoleAssociation(RepresentById): +class UserRoleAssociation(Base, RepresentById): + __tablename__ = 'user_role_association' + + id = Column(Integer, primary_key=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + role_id = Column(Integer, ForeignKey('role.id'), index=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + + user = relationship('User', back_populates="roles") + role = relationship('Role', back_populates="users") + + # TODO: should be defined on the User model only? + non_private_roles = relationship( + 'User', + backref="non_private_roles", + viewonly=True, + primaryjoin=(lambda: + (User.id == UserRoleAssociation.user_id) # type: ignore + & (UserRoleAssociation.role_id == Role.id) # type: ignore + & not_(Role.name == User.email)) # type: ignore + ) + def __init__(self, user, role): self.user = user self.role = role -class GroupRoleAssociation(RepresentById): +class GroupRoleAssociation(Base, RepresentById): + __tablename__ = 'group_role_association' + + id = Column(Integer, primary_key=True) + group_id = Column(Integer, ForeignKey('galaxy_group.id'), index=True) + role_id = Column(Integer, ForeignKey('role.id'), index=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + group = relationship('Group', back_populates='roles') + role = relationship('Role', back_populates='groups') + def __init__(self, group, role): self.group = group self.role = role @@ -2336,13 +2982,22 @@ class GroupRoleAssociation(RepresentById): class Role(Base, Dictifiable, RepresentById): __tablename__ = 'role' - id = Column('id', Integer, primary_key=True) - create_time = Column('create_time', DateTime, default=now) - update_time = Column('update_time', DateTime, default=now, onupdate=now) - name = Column('name', String(255), index=True, unique=True) - description = Column('description', TEXT) - type = Column('type', String(40), index=True) - deleted = Column('deleted', Boolean, index=True, default=False) + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + name = Column(String(255), index=True, unique=True) + description = Column(TEXT) + type = Column(String(40), index=True) + deleted = Column(Boolean, index=True, default=False) + dataset_actions = relationship('DatasetPermissions', back_populates='role') + groups = relationship('GroupRoleAssociation', back_populates='role') + library_actions = relationship('LibraryPermissions', back_populates='role') + library_folder_actions = relationship('LibraryFolderPermissions', back_populates='role') + library_dataset_actions = relationship('LibraryDatasetPermissions', back_populates='role') + library_dataset_dataset_actions = relationship( + 'LibraryDatasetDatasetAssociationPermissions', back_populates='role') + users = relationship('UserRoleAssociation', back_populates='role') dict_collection_visible_keys = ['id', 'name'] dict_element_visible_keys = ['id', 'name', 'description', 'type'] @@ -2362,7 +3017,17 @@ class Role(Base, Dictifiable, RepresentById): self.deleted = deleted -class UserQuotaAssociation(Dictifiable, RepresentById): +class UserQuotaAssociation(Base, Dictifiable, RepresentById): + __tablename__ = 'user_quota_association' + + id = Column(Integer, primary_key=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + quota_id = Column(Integer, ForeignKey('quota.id'), index=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + user = relationship('User', back_populates='quotas') + quota = relationship('Quota', back_populates='users') + dict_element_visible_keys = ['user'] def __init__(self, user, quota): @@ -2370,7 +3035,17 @@ class UserQuotaAssociation(Dictifiable, RepresentById): self.quota = quota -class GroupQuotaAssociation(Dictifiable, RepresentById): +class GroupQuotaAssociation(Base, Dictifiable, RepresentById): + __tablename__ = 'group_quota_association' + + id = Column(Integer, primary_key=True) + group_id = Column(Integer, ForeignKey("galaxy_group.id"), index=True) + quota_id = Column(Integer, ForeignKey('quota.id'), index=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + group = relationship('Group', back_populates='quotas') + quota = relationship('Quota', back_populates='groups') + dict_element_visible_keys = ['group'] def __init__(self, group, quota): @@ -2381,14 +3056,17 @@ class GroupQuotaAssociation(Dictifiable, RepresentById): class Quota(Base, Dictifiable, RepresentById): __tablename__ = 'quota' - id = Column('id', Integer, primary_key=True) - create_time = Column('create_time', DateTime, default=now) - update_time = Column('update_time', DateTime, default=now, onupdate=now) - name = Column('name', String(255), index=True, unique=True) - description = Column('description', TEXT) - bytes = Column('bytes', BigInteger) - operation = Column('operation', String(8)) - deleted = Column('deleted', Boolean, index=True, default=False) + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + name = Column(String(255), index=True, unique=True) + description = Column(TEXT) + bytes = Column(BigInteger) + operation = Column(String(8)) + deleted = Column(Boolean, index=True, default=False) + default = relationship('DefaultQuotaAssociation', back_populates='quota') + groups = relationship('GroupQuotaAssociation', back_populates='quota') + users = relationship('UserQuotaAssociation', back_populates='quota') dict_collection_visible_keys = ['id', 'name'] dict_element_visible_keys = ['id', 'name', 'description', 'bytes', 'operation', 'display_amount', 'default', 'users', 'groups'] @@ -2423,7 +3101,16 @@ class Quota(Base, Dictifiable, RepresentById): return galaxy.util.nice_size(self.bytes) -class DefaultQuotaAssociation(Dictifiable, RepresentById): +class DefaultQuotaAssociation(Base, Dictifiable, RepresentById): + __tablename__ = 'default_quota_association' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + type = Column(String(32), index=True, unique=True) + quota_id = Column(Integer, ForeignKey('quota.id'), index=True) + quota = relationship('Quota', back_populates='default') + dict_element_visible_keys = ['type'] class types(str, Enum): @@ -2436,7 +3123,18 @@ class DefaultQuotaAssociation(Dictifiable, RepresentById): self.quota = quota -class DatasetPermissions(RepresentById): +class DatasetPermissions(Base, RepresentById): + __tablename__ = 'dataset_permissions' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + action = Column(TEXT) + dataset_id = Column(Integer, ForeignKey('dataset.id'), index=True) + role_id = Column(Integer, ForeignKey("role.id"), index=True) + dataset = relationship('Dataset', back_populates='actions') + role = relationship('Role', back_populates='dataset_actions') + def __init__(self, action, dataset, role=None, role_id=None): self.action = action self.dataset = dataset @@ -2446,7 +3144,18 @@ class DatasetPermissions(RepresentById): self.role_id = role_id -class LibraryPermissions(RepresentById): +class LibraryPermissions(Base, RepresentById): + __tablename__ = 'library_permissions' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + action = Column(TEXT) + library_id = Column(Integer, ForeignKey('library.id'), nullable=True, index=True) + role_id = Column(Integer, ForeignKey('role.id'), index=True) + library = relationship('Library', back_populates='actions') + role = relationship('Role', back_populates='library_actions') + def __init__(self, action, library_item, role): self.action = action if isinstance(library_item, Library): @@ -2456,7 +3165,18 @@ class LibraryPermissions(RepresentById): self.role = role -class LibraryFolderPermissions(RepresentById): +class LibraryFolderPermissions(Base, RepresentById): + __tablename__ = 'library_folder_permissions' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + action = Column(TEXT) + library_folder_id = Column(Integer, ForeignKey('library_folder.id'), nullable=True, index=True) + role_id = Column(Integer, ForeignKey('role.id'), index=True) + folder = relationship('LibraryFolder', back_populates='actions') + role = relationship('Role', back_populates='library_folder_actions') + def __init__(self, action, library_item, role): self.action = action if isinstance(library_item, LibraryFolder): @@ -2466,7 +3186,18 @@ class LibraryFolderPermissions(RepresentById): self.role = role -class LibraryDatasetPermissions(RepresentById): +class LibraryDatasetPermissions(Base, RepresentById): + __tablename__ = 'library_dataset_permissions' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + action = Column(TEXT) + library_dataset_id = Column(Integer, ForeignKey('library_dataset.id'), nullable=True, index=True) + role_id = Column(Integer, ForeignKey('role.id'), index=True) + library_dataset = relationship('LibraryDataset', back_populates='actions') + role = relationship('Role', back_populates='library_dataset_actions') + def __init__(self, action, library_item, role): self.action = action if isinstance(library_item, LibraryDataset): @@ -2476,7 +3207,20 @@ class LibraryDatasetPermissions(RepresentById): self.role = role -class LibraryDatasetDatasetAssociationPermissions(RepresentById): +class LibraryDatasetDatasetAssociationPermissions(Base, RepresentById): + __tablename__ = 'library_dataset_dataset_association_permissions' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + action = Column(TEXT) + library_dataset_dataset_association_id = Column( + Integer, ForeignKey('library_dataset_dataset_association.id'), nullable=True, index=True) + role_id = Column(Integer, ForeignKey('role.id'), index=True) + library_dataset_dataset_association = relationship('LibraryDatasetDatasetAssociation', + back_populates='actions') + role = relationship('Role', back_populates='library_dataset_dataset_actions') + def __init__(self, action, library_item, role): self.action = action if isinstance(library_item, LibraryDatasetDatasetAssociation): @@ -2486,14 +3230,32 @@ class LibraryDatasetDatasetAssociationPermissions(RepresentById): self.role = role -class DefaultUserPermissions(RepresentById): +class DefaultUserPermissions(Base, RepresentById): + __tablename__ = 'default_user_permissions' + + id = Column(Integer, primary_key=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + action = Column(TEXT) + role_id = Column(Integer, ForeignKey('role.id'), index=True) + user = relationship('User', back_populates='default_permissions') + role = relationship('Role') + def __init__(self, user, action, role): self.user = user self.action = action self.role = role -class DefaultHistoryPermissions(RepresentById): +class DefaultHistoryPermissions(Base, RepresentById): + __tablename__ = 'default_history_permissions' + + id = Column(Integer, primary_key=True) + history_id = Column(Integer, ForeignKey('history.id'), index=True) + action = Column(TEXT) + role_id = Column(Integer, ForeignKey('role.id'), index=True) + history = relationship('History', back_populates='default_permissions') + role = relationship('Role') + def __init__(self, history, action, role): self.history = history self.action = action @@ -2785,16 +3547,37 @@ class Dataset(StorableObject, RepresentById, _HasTable): return rval -class DatasetSource(RepresentById): - """ """ +class DatasetSource(Base, RepresentById): + __tablename__ = 'dataset_source' + + id = Column(Integer, primary_key=True) + dataset_id = Column(Integer, ForeignKey('dataset.id'), index=True) + source_uri = Column(TEXT) + extra_files_path = Column(TEXT) + transform = Column(MutableJSONType) + dataset = relationship('Dataset', back_populates='sources') + hashes = relationship('DatasetSourceHash', back_populates='source') -class DatasetSourceHash(RepresentById): - """ """ +class DatasetSourceHash(Base, RepresentById): + __tablename__ = 'dataset_source_hash' + + id = Column(Integer, primary_key=True) + dataset_source_id = Column(Integer, ForeignKey('dataset_source.id'), index=True) + hash_function = Column(TEXT) + hash_value = Column(TEXT) + source = relationship('DatasetSource', back_populates='hashes') -class DatasetHash(RepresentById): - """ """ +class DatasetHash(Base, RepresentById): + __tablename__ = 'dataset_hash' + + id = Column(Integer, primary_key=True) + dataset_id = Column(Integer, ForeignKey('dataset.id'), index=True) + hash_function = Column(TEXT) + hash_value = Column(TEXT) + extra_files_path = Column(TEXT) + dataset = relationship('Dataset', back_populates='hashes') def serialize(self, id_encoder, serialization_options): # serialize Dataset objects only for jobs that can actually modify these models. @@ -3685,11 +4468,23 @@ class HistoryDatasetAssociation(DatasetInstance, HasTags, Dictifiable, UsesAnnot @type_id.expression # type: ignore def type_id(cls): - return ((type_coerce(cls.content_type, types.Unicode) + '-' - + type_coerce(cls.id, types.Unicode)).label('type_id')) + return ((type_coerce(cls.content_type, Unicode) + '-' + + type_coerce(cls.id, Unicode)).label('type_id')) -class HistoryDatasetAssociationHistory(RepresentById): +class HistoryDatasetAssociationHistory(Base, RepresentById): + __tablename__ = 'history_dataset_association_history' + + id = Column(Integer, primary_key=True) + history_dataset_association_id = Column(Integer, + ForeignKey("history_dataset_association.id"), index=True) + update_time = Column(DateTime, default=now) + version = Column(Integer) + name = Column(TrimmedString(255)) + extension = Column(TrimmedString(64)) + _metadata = Column('metadata', JSONType) + extended_metadata_id = Column(Integer, ForeignKey("extended_metadata.id"), index=True) + def __init__(self, history_dataset_association_id, name, @@ -3710,21 +4505,65 @@ class HistoryDatasetAssociationHistory(RepresentById): self._metadata = metadata -class HistoryDatasetAssociationDisplayAtAuthorization(RepresentById): +# hda read access permission given by a user to a specific site (gen. for external display applications) +class HistoryDatasetAssociationDisplayAtAuthorization(Base, RepresentById): + __tablename__ = 'history_dataset_association_display_at_authorization' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, index=True, default=now, onupdate=now) + history_dataset_association_id = Column(Integer, + ForeignKey('history_dataset_association.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + site = Column(TrimmedString(255)) + history_dataset_association = relationship('HistoryDatasetAssociation') + user = relationship('User') + def __init__(self, hda=None, user=None, site=None): self.history_dataset_association = hda self.user = user self.site = site -class HistoryDatasetAssociationSubset(RepresentById): +class HistoryDatasetAssociationSubset(Base, RepresentById): + __tablename__ = 'history_dataset_association_subset' + + id = Column(Integer, primary_key=True) + history_dataset_association_id = Column(Integer, + ForeignKey('history_dataset_association.id'), index=True) + history_dataset_association_subset_id = Column(Integer, + ForeignKey('history_dataset_association.id'), index=True) + location = Column(Unicode(255), index=True) + + hda = relationship('HistoryDatasetAssociation', + primaryjoin=(lambda: HistoryDatasetAssociationSubset.history_dataset_association_id # type: ignore + == HistoryDatasetAssociation.id)) # type: ignore + subset = relationship('HistoryDatasetAssociation', + primaryjoin=(lambda: HistoryDatasetAssociationSubset.history_dataset_association_subset_id # type: ignore + == HistoryDatasetAssociation.id)) # type: ignore + def __init__(self, hda, subset, location): self.hda = hda self.subset = subset self.location = location -class Library(Dictifiable, HasName, RepresentById): +class Library(Base, Dictifiable, HasName, RepresentById): + __tablename__ = 'library' + + id = Column(Integer, primary_key=True) + root_folder_id = Column(Integer, ForeignKey("library_folder.id"), index=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + name = Column(String(255), index=True) + deleted = Column(Boolean, index=True, default=False) + purged = Column(Boolean, index=True, default=False) + description = Column(TEXT) + synopsis = Column(TEXT) + root_folder = relationship('LibraryFolder', back_populates='library_root') + actions = relationship('LibraryPermissions', back_populates='library') + info_association = relationship('LibraryInfoAssociation', back_populates='library') + permitted_actions = get_permitted_actions(filter='LIBRARY') dict_collection_visible_keys = ['id', 'name'] dict_element_visible_keys = ['id', 'deleted', 'name', 'description', 'synopsis', 'root_folder_id', 'create_time'] @@ -3788,7 +4627,59 @@ class Library(Dictifiable, HasName, RepresentById): return roles -class LibraryFolder(Dictifiable, HasName, RepresentById): +class LibraryFolder(Base, Dictifiable, HasName, RepresentById): + __tablename__ = 'library_folder' + __table_args__ = ( + Index('ix_library_folder_name', 'name', mysql_length=200), + ) + + id = Column(Integer, primary_key=True) + parent_id = Column(Integer, ForeignKey('library_folder.id'), nullable=True, index=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + name = Column(TEXT) + description = Column(TEXT) + order_id = Column(Integer) # not currently being used, but for possible future use + item_count = Column(Integer) + deleted = Column(Boolean, index=True, default=False) + purged = Column(Boolean, index=True, default=False) + genome_build = Column(TrimmedString(40)) + + folders = relationship('LibraryFolder', + primaryjoin=(lambda: LibraryFolder.id == LibraryFolder.parent_id), # type: ignore + order_by=asc(name), + back_populates='parent') + parent = relationship('LibraryFolder', back_populates='folders', remote_side=[id]) + + active_folders = relationship('LibraryFolder', + primaryjoin=( + 'and_(LibraryFolder.parent_id == LibraryFolder.id, not_(LibraryFolder.deleted))'), + order_by=asc(name), + # """sqlalchemy.exc.ArgumentError: Error creating eager relationship 'active_folders' + # on parent class '' to child class '': + # Cant use eager loading on a self referential relationship.""" + # TODO: This is no longer the case. Fix this: https://docs.sqlalchemy.org/en/14/orm/self_referential.html#configuring-self-referential-eager-loading + lazy=True, + viewonly=True) + + datasets = relationship('LibraryDataset', + primaryjoin=(lambda: LibraryDataset.folder_id == LibraryFolder.id), # type: ignore + order_by=(lambda: asc(LibraryDataset._name)), # type: ignore + lazy=True, + viewonly=True) + + active_datasets = relationship('LibraryDataset', + primaryjoin=( + 'and_(LibraryDataset.folder_id == LibraryFolder.id, not_(LibraryDataset.deleted))'), + order_by=(lambda: asc(LibraryDataset._name)), # type: ignore + lazy=True, + viewonly=True) + + dataset_collections = relationship('LibraryDatasetCollectionAssociation', back_populates='folder') + library_root = relationship('Library', back_populates='root_folder') + actions = relationship('LibraryFolderPermissions', back_populates='folder') + info_association = relationship('LibraryFolderInfoAssociation', back_populates='folder') + dict_element_visible_keys = ['id', 'parent_id', 'name', 'description', 'item_count', 'genome_build', 'update_time', 'deleted'] def __init__(self, name=None, description=None, item_count=0, order_id=None, genome_build=None): @@ -3862,7 +4753,40 @@ class LibraryFolder(Dictifiable, HasName, RepresentById): return f.library_root[0] -class LibraryDataset(RepresentById): +class LibraryDataset(Base, RepresentById): + __tablename__ = 'library_dataset' + + id = Column(Integer, primary_key=True) + # current version of dataset, if null, there is not a current version selected + library_dataset_dataset_association_id = Column(Integer, + ForeignKey('library_dataset_dataset_association.id', + use_alter=True, name='library_dataset_dataset_association_id_fk'), + nullable=True, index=True) + folder_id = Column(Integer, ForeignKey('library_folder.id'), index=True) + # not currently being used, but for possible future use + order_id = Column(Integer) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + # when not None/null this will supercede display in library (but not when imported into user's history?) + _name = Column('name', TrimmedString(255), index=True) + # when not None/null this will supercede display in library (but not when imported into user's history?) + _info = Column('info', TrimmedString(255)) + deleted = Column(Boolean, index=True, default=False) + purged = Column(Boolean, index=True, default=False) + folder = relationship('LibraryFolder') + library_dataset_dataset_association = relationship('LibraryDatasetDatasetAssociation', + foreign_keys=library_dataset_dataset_association_id, + post_update=True) + expired_datasets = relationship('LibraryDatasetDatasetAssociation', + foreign_keys=[id, library_dataset_dataset_association_id], + primaryjoin=( + 'and_(LibraryDataset.id == LibraryDatasetDatasetAssociation.library_dataset_id, \ + not_(LibraryDataset.library_dataset_dataset_association_id == LibraryDatasetDatasetAssociation.id))' + ), + viewonly=True, + uselist=True) + actions = relationship('LibraryDatasetPermissions', back_populates='library_dataset') + # This class acts as a proxy to the currently selected LDDA upload_options = [('upload_file', 'Upload files'), ('upload_directory', 'Upload directory of files'), @@ -3954,6 +4878,7 @@ class LibraryDataset(RepresentById): class LibraryDatasetDatasetAssociation(DatasetInstance, HasName, RepresentById): + def __init__(self, copied_from_history_dataset_association=None, copied_from_library_dataset_dataset_association=None, @@ -4127,19 +5052,55 @@ class LibraryDatasetDatasetAssociation(DatasetInstance, HasName, RepresentById): log.warning(f'Attempt to updated parent folder times failed: {ret.rowcount} records updated.') -class ExtendedMetadata(RepresentById): +class ExtendedMetadata(Base, RepresentById): + __tablename__ = 'extended_metadata' + + id = Column(Integer, primary_key=True) + data = Column(MutableJSONType) + children = relationship('ExtendedMetadataIndex', back_populates='extended_metadata') + def __init__(self, data): self.data = data -class ExtendedMetadataIndex(RepresentById): +class ExtendedMetadataIndex(Base, RepresentById): + __tablename__ = 'extended_metadata_index' + + id = Column(Integer, primary_key=True) + extended_metadata_id = Column(Integer, + ForeignKey('extended_metadata.id', onupdate='CASCADE', ondelete='CASCADE'), index=True) + path = Column(String(255)) + value = Column(TEXT) + extended_metadata = relationship('ExtendedMetadata', back_populates='children') + def __init__(self, extended_metadata, path, value): self.extended_metadata = extended_metadata self.path = path self.value = value -class LibraryInfoAssociation(RepresentById): +class LibraryInfoAssociation(Base, RepresentById): + __tablename__ = 'library_info_association' + + id = Column(Integer, primary_key=True) + library_id = Column(Integer, ForeignKey('library.id'), index=True) + form_definition_id = Column(Integer, ForeignKey('form_definition.id'), index=True) + form_values_id = Column(Integer, ForeignKey('form_values.id'), index=True) + inheritable = Column(Boolean, index=True, default=False) + deleted = Column(Boolean, index=True, default=False) + + library = relationship('Library', + primaryjoin=( + lambda: and_( + LibraryInfoAssociation.library_id == Library.id, # type: ignore + not_(LibraryInfoAssociation.deleted)) # type: ignore + ), + back_populates='info_association') + template = relationship('FormDefinition', + primaryjoin=lambda: LibraryInfoAssociation.form_definition_id == FormDefinition.id) # type: ignore + info = relationship('FormValues', + primaryjoin=lambda: LibraryInfoAssociation.form_values_id == FormValues.id) # type: ignore + def __init__(self, library, form_definition, info, inheritable=False): self.library = library self.template = form_definition @@ -4147,7 +5108,26 @@ class LibraryInfoAssociation(RepresentById): self.inheritable = inheritable -class LibraryFolderInfoAssociation(RepresentById): +class LibraryFolderInfoAssociation(Base, RepresentById): + __tablename__ = 'library_folder_info_association' + + id = Column(Integer, primary_key=True) + library_folder_id = Column(Integer, ForeignKey('library_folder.id'), nullable=True, index=True) + form_definition_id = Column(Integer, ForeignKey('form_definition.id'), index=True) + form_values_id = Column(Integer, ForeignKey('form_values.id'), index=True) + inheritable = Column(Boolean, index=True, default=False) + deleted = Column(Boolean, index=True, default=False) + + folder = relationship('LibraryFolder', + primaryjoin=(lambda: + (LibraryFolderInfoAssociation.library_folder_id == LibraryFolder.id) # type: ignore + & (not_(LibraryFolderInfoAssociation.deleted))), # type: ignore + back_populates="info_association") + template = relationship('FormDefinition', + primaryjoin=(lambda: LibraryFolderInfoAssociation.form_definition_id == FormDefinition.id)) # type: ignore + info = relationship('FormValues', + primaryjoin=(lambda: LibraryFolderInfoAssociation.form_values_id == FormValues.id)) # type: ignore + def __init__(self, folder, form_definition, info, inheritable=False): self.folder = folder self.template = form_definition @@ -4155,7 +5135,31 @@ class LibraryFolderInfoAssociation(RepresentById): self.inheritable = inheritable -class LibraryDatasetDatasetInfoAssociation(RepresentById): +class LibraryDatasetDatasetInfoAssociation(Base, RepresentById): + __tablename__ = 'library_dataset_dataset_info_association' + + id = Column(Integer, primary_key=True) + library_dataset_dataset_association_id = Column(Integer, + ForeignKey('library_dataset_dataset_association.id'), nullable=True, index=True) + form_definition_id = Column(Integer, ForeignKey('form_definition.id'), index=True) + form_values_id = Column(Integer, ForeignKey('form_values.id'), index=True) + deleted = Column(Boolean, index=True, default=False) + + library_dataset_dataset_association = relationship('LibraryDatasetDatasetAssociation', + primaryjoin=(lambda: + (LibraryDatasetDatasetInfoAssociation.library_dataset_dataset_association_id + == LibraryDatasetDatasetAssociation.id) + & (not_(LibraryDatasetDatasetInfoAssociation.deleted)) + ), + back_populates="info_association") + + template = relationship('FormDefinition', + primaryjoin=(lambda: + LibraryDatasetDatasetInfoAssociation.form_definition_id == FormDefinition.id)) # type: ignore + info = relationship('FormValues', + primaryjoin=(lambda: + LibraryDatasetDatasetInfoAssociation.form_values_id == FormValues.id)) # type: ignore + def __init__(self, library_dataset_dataset_association, form_definition, info): # TODO: need to figure out if this should be inheritable to the associated LibraryDataset self.library_dataset_dataset_association = library_dataset_dataset_association @@ -4167,7 +5171,37 @@ class LibraryDatasetDatasetInfoAssociation(RepresentById): return True # always allow inheriting, used for replacement -class ImplicitlyConvertedDatasetAssociation(RepresentById): +class ImplicitlyConvertedDatasetAssociation(Base, RepresentById): + __tablename__ = 'implicitly_converted_dataset_association' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + hda_id = Column(Integer, ForeignKey('history_dataset_association.id'), index=True, nullable=True) + ldda_id = Column(Integer, + ForeignKey('library_dataset_dataset_association.id'), index=True, nullable=True) + hda_parent_id = Column(Integer, ForeignKey('history_dataset_association.id'), index=True) + ldda_parent_id = Column(Integer, ForeignKey('library_dataset_dataset_association.id'), index=True) + deleted = Column(Boolean, index=True, default=False) + metadata_safe = Column(Boolean, index=True, default=True) + type = Column(TrimmedString(255)) + + parent_hda = relationship('HistoryDatasetAssociation', + primaryjoin=(lambda: ImplicitlyConvertedDatasetAssociation.hda_parent_id # type: ignore + == HistoryDatasetAssociation.id), # type: ignore + back_populates='implicitly_converted_datasets') + dataset_ldda = relationship('LibraryDatasetDatasetAssociation', + primaryjoin=(lambda: ImplicitlyConvertedDatasetAssociation.ldda_id # type: ignore + == LibraryDatasetDatasetAssociation.id), # type: ignore + back_populates='implicitly_converted_parent_datasets') + dataset = relationship('HistoryDatasetAssociation', + primaryjoin=(lambda: ImplicitlyConvertedDatasetAssociation.hda_id # type: ignore + == HistoryDatasetAssociation.id), # type: ignore + back_populates='implicitly_converted_parent_datasets') + parent_ldda = relationship('LibraryDatasetDatasetAssociation', + primaryjoin=(lambda: ImplicitlyConvertedDatasetAssociation.ldda_parent_id # type: ignore + == LibraryDatasetDatasetAssociation.table.c.id), # type: ignore + back_populates='implicitly_converted_datasets') def __init__(self, id=None, parent=None, dataset=None, file_type=None, deleted=False, purged=False, metadata_safe=True): self.id = id @@ -4206,9 +5240,24 @@ class ImplicitlyConvertedDatasetAssociation(RepresentById): DEFAULT_COLLECTION_NAME = "Unnamed Collection" -class DatasetCollection(Dictifiable, UsesAnnotations, RepresentById): - """ - """ +class DatasetCollection(Base, Dictifiable, UsesAnnotations, RepresentById): + __tablename__ = 'dataset_collection' + + id = Column(Integer, primary_key=True) + collection_type = Column(Unicode(255), nullable=False) + populated_state = Column(TrimmedString(64), default='ok', nullable=False) + populated_state_message = Column(TEXT) + element_count = Column(Integer, nullable=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + + elements = relationship('DatasetCollectionElement', + primaryjoin=(lambda: DatasetCollection.id == DatasetCollectionElement.dataset_collection_id), # type: ignore + back_populates='collection', + order_by=lambda: DatasetCollectionElement.element_index) # type: ignore + output_dataset_collections = relationship( + 'JobToImplicitOutputDatasetCollectionAssociation', back_populates='dataset_collection') + dict_collection_visible_keys = ['id', 'collection_type'] dict_element_visible_keys = ['id', 'collection_type'] @@ -4578,12 +5627,92 @@ class DatasetCollectionInstance(HasName): return changed -class HistoryDatasetCollectionAssociation(DatasetCollectionInstance, - HasTags, - Dictifiable, - UsesAnnotations, - RepresentById): +class HistoryDatasetCollectionAssociation( + Base, + DatasetCollectionInstance, + HasTags, + Dictifiable, + UsesAnnotations, + RepresentById +): """ Associates a DatasetCollection with a History. """ + __tablename__ = 'history_dataset_collection_association' + + id = Column(Integer, primary_key=True) + collection_id = Column(Integer, ForeignKey('dataset_collection.id'), index=True) + history_id = Column(Integer, ForeignKey('history.id'), index=True) + name = Column(TrimmedString(255)) + hid = Column(Integer) + visible = Column(Boolean) + deleted = Column(Boolean, default=False) + copied_from_history_dataset_collection_association_id = Column(Integer, + ForeignKey('history_dataset_collection_association.id'), nullable=True) + implicit_output_name = Column(Unicode(255), nullable=True) + job_id = Column(ForeignKey('job.id'), index=True, nullable=True) + implicit_collection_jobs_id = Column( + ForeignKey('implicit_collection_jobs.id'), index=True, nullable=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now, index=True) + + collection = relationship('DatasetCollection') + history = relationship('History', back_populates='dataset_collections') + + copied_from_history_dataset_collection_association = relationship( + 'HistoryDatasetCollectionAssociation', + primaryjoin=copied_from_history_dataset_collection_association_id == id, + remote_side=[id], + uselist=False, + back_populates='copied_to_history_dataset_collection_association', + ) + copied_to_history_dataset_collection_association = relationship( + 'HistoryDatasetCollectionAssociation', + back_populates='copied_from_history_dataset_collection_association', + ) + implicit_input_collections = relationship('ImplicitlyCreatedDatasetCollectionInput', + primaryjoin=(lambda: HistoryDatasetCollectionAssociation.id # type: ignore + == ImplicitlyCreatedDatasetCollectionInput.dataset_collection_id), # type: ignore + back_populates='dataset_collection', + ) + implicit_collection_jobs = relationship( + 'ImplicitCollectionJobs', + back_populates='history_dataset_collection_associations', + uselist=False + ) + job = relationship( + 'Job', + back_populates='history_dataset_collection_associations', + uselist=False, + ) + job_state_summary = relationship(HistoryDatasetCollectionJobStateSummary, + primaryjoin=(lambda: HistoryDatasetCollectionAssociation.id # type: ignore + == HistoryDatasetCollectionJobStateSummary.__table__.c.hdca_id), # type: ignore + foreign_keys=HistoryDatasetCollectionJobStateSummary.__table__.c.hdca_id, + uselist=False, + ) + tags = relationship( + 'HistoryDatasetCollectionTagAssociation', + order_by=lambda: HistoryDatasetCollectionTagAssociation.id, # type: ignore + back_populates='dataset_collection', + ) + annotations = relationship( + 'HistoryDatasetCollectionAssociationAnnotationAssociation', + order_by=lambda: HistoryDatasetCollectionAssociationAnnotationAssociation.id, # type: ignore + back_populates='history_dataset_collection', + ) + ratings = relationship( + 'HistoryDatasetCollectionRatingAssociation', + order_by=lambda: HistoryDatasetCollectionRatingAssociation.id, # type: ignore + back_populates='dataset_collection', + ) + output_dataset_collection_instances = relationship( + 'JobToOutputDatasetCollectionAssociation', + back_populates='dataset_collection_instance', + ) + hidden_dataset_instances = relationship('HistoryDatasetAssociation', + primaryjoin=(lambda: HistoryDatasetAssociation.table.c.hidden_beneath_collection_instance_id # type: ignore + == HistoryDatasetCollectionAssociation.id), # type: ignore + back_populates='hidden_beneath_collection_instance') + editable_keys = ('name', 'deleted', 'visible') def __init__( @@ -4627,8 +5756,8 @@ class HistoryDatasetCollectionAssociation(DatasetCollectionInstance, @type_id.expression # type: ignore def type_id(cls): - return ((type_coerce(cls.content_type, types.Unicode) + '-' - + type_coerce(cls.id, types.Unicode)).label('type_id')) + return ((type_coerce(cls.content_type, Unicode) + '-' + + type_coerce(cls.id, Unicode)).label('type_id')) @property def job_source_type(self): @@ -4791,8 +5920,29 @@ class HistoryDatasetCollectionAssociation(DatasetCollectionInstance, return len(results) > 0 -class LibraryDatasetCollectionAssociation(DatasetCollectionInstance, RepresentById): +class LibraryDatasetCollectionAssociation(Base, DatasetCollectionInstance, RepresentById): """ Associates a DatasetCollection with a library folder. """ + __tablename__ = 'library_dataset_collection_association' + + id = Column(Integer, primary_key=True) + collection_id = Column(Integer, ForeignKey('dataset_collection.id'), index=True) + folder_id = Column(Integer, ForeignKey('library_folder.id'), index=True) + name = Column(TrimmedString(255)) + deleted = Column(Boolean, default=False) + + collection = relationship('DatasetCollection') + folder = relationship('LibraryFolder', back_populates='dataset_collections') + + tags = relationship('LibraryDatasetCollectionTagAssociation', + order_by=lambda: LibraryDatasetCollectionTagAssociation.id, # type: ignore + back_populates='dataset_collection') + annotations = relationship('LibraryDatasetCollectionAnnotationAssociation', + order_by=lambda: LibraryDatasetCollectionAnnotationAssociation.id, # type: ignore + back_populates="dataset_collection") + ratings = relationship('LibraryDatasetCollectionRatingAssociation', + order_by=lambda: LibraryDatasetCollectionRatingAssociation.id, # type: ignore + back_populates="dataset_collection") + editable_keys = ('name', 'deleted') def __init__( @@ -4819,8 +5969,36 @@ class LibraryDatasetCollectionAssociation(DatasetCollectionInstance, RepresentBy return dict_value -class DatasetCollectionElement(Dictifiable, RepresentById): +class DatasetCollectionElement(Base, Dictifiable, RepresentById): """ Associates a DatasetInstance (hda or ldda) with a DatasetCollection. """ + __tablename__ = 'dataset_collection_element' + + id = Column(Integer, primary_key=True) + # Parent collection id describing what collection this element belongs to. + dataset_collection_id = Column(Integer, + ForeignKey('dataset_collection.id'), index=True, nullable=False) + # Child defined by this association - HDA, LDDA, or another dataset association... + hda_id = Column(Integer, + ForeignKey('history_dataset_association.id'), index=True, nullable=True) + ldda_id = Column(Integer, + ForeignKey('library_dataset_dataset_association.id'), index=True, nullable=True) + child_collection_id = Column(Integer, + ForeignKey('dataset_collection.id'), index=True, nullable=True) + # Element index and identifier to define this parent-child relationship. + element_index = Column(Integer) + element_identifier = Column(Unicode(255)) + + hda = relationship('HistoryDatasetAssociation', + primaryjoin=(lambda: DatasetCollectionElement.hda_id == HistoryDatasetAssociation.id)) # type: ignore + ldda = relationship('LibraryDatasetDatasetAssociation', + primaryjoin=(lambda: DatasetCollectionElement.ldda_id == LibraryDatasetDatasetAssociation.id)) # type: ignore + child_collection = relationship('DatasetCollection', + primaryjoin=(lambda: DatasetCollectionElement.child_collection_id == DatasetCollection.id)) # type: ignore + collection = relationship('DatasetCollection', + primaryjoin=(lambda: DatasetCollection.id == DatasetCollectionElement.dataset_collection_id), # type: ignore + back_populates='elements', + ) + # actionable dataset id needs to be available via API... dict_collection_visible_keys = ['id', 'element_type', 'element_index', 'element_identifier'] dict_element_visible_keys = ['id', 'element_type', 'element_index', 'element_identifier'] @@ -4951,7 +6129,22 @@ class DatasetCollectionElement(Dictifiable, RepresentById): return rval -class Event(RepresentById): +class Event(Base, RepresentById): + __tablename__ = 'event' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + history_id = Column(Integer, ForeignKey('history.id'), index=True, nullable=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True, nullable=True) + message = Column(TrimmedString(1024)) + session_id = Column(Integer, ForeignKey('galaxy_session.id'), index=True, nullable=True) + tool_id = Column(String(255)) + + history = relationship('History') + user = relationship('User') + galaxy_session = relationship('GalaxySession') + def __init__(self, message=None, history=None, user=None, galaxy_session=None): self.history = history self.galaxy_session = galaxy_session @@ -4960,7 +6153,28 @@ class Event(RepresentById): self.message = message -class GalaxySession(RepresentById): +class GalaxySession(Base, RepresentById): + __tablename__ = 'galaxy_session' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True, nullable=True) + remote_host = Column(String(255)) + remote_addr = Column(String(255)) + referer = Column(TEXT) + current_history_id = Column(Integer, ForeignKey('history.id'), nullable=True) + # unique 128 bit random number coerced to a string + session_key = Column(TrimmedString(255), index=True, unique=True) + is_valid = Column(Boolean, default=False) + # saves a reference to the previous session so we have a way to chain them together + prev_session_id = Column(Integer) + disk_usage = Column(Numeric(15, 0), index=True) + last_action = Column(DateTime) + current_history = relationship('History') + histories = relationship('GalaxySessionToHistoryAssociation', back_populates='galaxy_session') + user = relationship('User', back_populates='galaxy_sessions') + def __init__(self, id=None, user=None, @@ -5000,7 +6214,16 @@ class GalaxySession(RepresentById): total_disk_usage = property(get_disk_usage, set_disk_usage) -class GalaxySessionToHistoryAssociation(RepresentById): +class GalaxySessionToHistoryAssociation(Base, RepresentById): + __tablename__ = 'galaxy_session_to_history' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + session_id = Column(Integer, ForeignKey('galaxy_session.id'), index=True) + history_id = Column(Integer, ForeignKey('history.id'), index=True) + galaxy_session = relationship('GalaxySession', back_populates='histories') + history = relationship('History', back_populates='galaxy_sessions') + def __init__(self, galaxy_session, history): self.galaxy_session = galaxy_session self.history = history @@ -5012,7 +6235,7 @@ class UCI: self.user = None -class StoredWorkflow(HasTags, Dictifiable, RepresentById): +class StoredWorkflow(Base, HasTags, Dictifiable, RepresentById): """ StoredWorkflow represents the root node of a tree of objects that compose a workflow, including workflow revisions, steps, and subworkflows. It is responsible for the metadata associated with a workflow including owner, name, published, and create/update time. @@ -5020,6 +6243,63 @@ class StoredWorkflow(HasTags, Dictifiable, RepresentById): Each time a workflow is modified a revision is created, represented by a new :class:`galaxy.model.Workflow` instance. See :class:`galaxy.model.Workflow` for more information """ + __tablename__ = 'stored_workflow' + __table_args__ = ( + Index('ix_stored_workflow_slug', 'slug', mysql_length=200), + ) + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now, index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True, nullable=False) + latest_workflow_id = Column(Integer, + ForeignKey('workflow.id', use_alter=True, name='stored_workflow_latest_workflow_id_fk'), + index=True) + name = Column(TEXT) + deleted = Column(Boolean, default=False) + hidden = Column(Boolean, default=False) + importable = Column(Boolean, default=False) + slug = Column(TEXT) + from_path = Column(TEXT) + published = Column(Boolean, index=True, default=False) + + user = relationship('User', + primaryjoin=(lambda: User.id == StoredWorkflow.user_id), # type: ignore + back_populates='stored_workflows') + workflows = relationship('Workflow', + back_populates='stored_workflow', + cascade="all, delete-orphan", + primaryjoin=(lambda: StoredWorkflow.id == Workflow.stored_workflow_id), # type: ignore + order_by=lambda: -Workflow.id) # type: ignore + latest_workflow = relationship('Workflow', + post_update=True, + primaryjoin=(lambda: StoredWorkflow.latest_workflow_id == Workflow.id), # type: ignore + lazy=False) + tags = relationship('StoredWorkflowTagAssociation', + order_by=lambda: StoredWorkflowTagAssociation.id, # type: ignore + back_populates="stored_workflow") + owner_tags = relationship('StoredWorkflowTagAssociation', + primaryjoin=(lambda: + and_(StoredWorkflow.id == StoredWorkflowTagAssociation.stored_workflow_id, # type: ignore + StoredWorkflow.user_id == StoredWorkflowTagAssociation.user_id) # type: ignore + ), + viewonly=True, + order_by=lambda: StoredWorkflowTagAssociation.id) # type: ignore + annotations = relationship('StoredWorkflowAnnotationAssociation', + order_by=lambda: StoredWorkflowAnnotationAssociation.id, # type: ignore + back_populates="stored_workflow") + ratings = relationship('StoredWorkflowRatingAssociation', + order_by=lambda: StoredWorkflowRatingAssociation.id, # type: ignore + back_populates="stored_workflow") + users_shared_with = relationship('StoredWorkflowUserShareAssociation', + back_populates='stored_workflow') + + average_rating: column_property + + # Set up proxy so that + # StoredWorkflow.users_shared_with + # returns a list of users that workflow is shared with. + users_shared_with_dot_users = association_proxy('users_shared_with', 'user') dict_collection_visible_keys = ['id', 'name', 'create_time', 'update_time', 'published', 'deleted', 'hidden'] dict_element_visible_keys = ['id', 'name', 'create_time', 'update_time', 'published', 'deleted', 'hidden'] @@ -5064,13 +6344,44 @@ class StoredWorkflow(HasTags, Dictifiable, RepresentById): return rval -class Workflow(Dictifiable, RepresentById): +class Workflow(Base, Dictifiable, RepresentById): """ Workflow represents a revision of a :class:`galaxy.model.StoredWorkflow`. A new instance is created for each workflow revision and provides a common parent for the workflow steps. See :class:`galaxy.model.WorkflowStep` for more information """ + __tablename__ = 'workflow' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + # workflows will belong to either a stored workflow or a parent/nesting workflow. + stored_workflow_id = Column(Integer, ForeignKey('stored_workflow.id'), index=True, nullable=True) + parent_workflow_id = Column(Integer, ForeignKey('workflow.id'), index=True, nullable=True) + name = Column(TEXT) + has_cycles = Column(Boolean) + has_errors = Column(Boolean) + reports_config = Column(MutableJSONType) + creator_metadata = Column(MutableJSONType) + license = Column(TEXT) + uuid = Column(UUIDType, nullable=True) + + steps = relationship('WorkflowStep', + back_populates='workflow', + primaryjoin=(lambda: Workflow.id == WorkflowStep.workflow_id), # type: ignore + order_by=lambda: asc(WorkflowStep.order_index), # type: ignore + cascade="all, delete-orphan", + lazy=False) + parent_workflow_steps = relationship( + 'WorkflowStep', + primaryjoin=(lambda: Workflow.id == WorkflowStep.subworkflow_id), # type: ignore + back_populates='subworkflow') + stored_workflow = relationship('StoredWorkflow', + primaryjoin=(lambda: StoredWorkflow.id == Workflow.stored_workflow_id), # type: ignore + back_populates='workflows') + + step_count: column_property dict_collection_visible_keys = ['name', 'has_cycles', 'has_errors'] dict_element_visible_keys = ['name', 'has_cycles', 'has_errors'] @@ -5204,12 +6515,57 @@ class Workflow(Dictifiable, RepresentById): return "Workflow[id=%d%s]" % (self.id, extra) -class WorkflowStep(RepresentById): +class WorkflowStep(Base, RepresentById): """ WorkflowStep represents a tool or subworkflow, its inputs, annotations, and any outputs that are flagged as workflow outputs. See :class:`galaxy.model.WorkflowStepInput` and :class:`galaxy.model.WorkflowStepConnection` for more information. """ + __tablename__ = 'workflow_step' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + workflow_id = Column(Integer, ForeignKey('workflow.id'), index=True, nullable=False) + subworkflow_id = Column(Integer, ForeignKey('workflow.id'), index=True, nullable=True) + dynamic_tool_id = Column(Integer, ForeignKey('dynamic_tool.id'), index=True, nullable=True) + type = Column(String(64)) + tool_id = Column(TEXT) + tool_version = Column(TEXT) + tool_inputs = Column(JSONType) + tool_errors = Column(JSONType) + position = Column(MutableJSONType) + config = Column(JSONType) + order_index = Column(Integer) + uuid = Column(UUIDType) + label = Column(Unicode(255)) + + subworkflow = relationship('Workflow', + primaryjoin=(lambda: Workflow.id == WorkflowStep.subworkflow_id), # type: ignore + back_populates='parent_workflow_steps') + dynamic_tool = relationship('DynamicTool', + primaryjoin=(lambda: DynamicTool.id == WorkflowStep.dynamic_tool_id), # type: ignore + back_populates='workflow_steps') + tags = relationship('WorkflowStepTagAssociation', + order_by=lambda: WorkflowStepTagAssociation.id, # type: ignore + back_populates='workflow_step') + annotations = relationship('WorkflowStepAnnotationAssociation', + order_by=lambda: WorkflowStepAnnotationAssociation.id, # type: ignore + back_populates="workflow_step") + post_job_actions = relationship('PostJobAction', back_populates='workflow_step') + inputs = relationship('WorkflowStepInput', back_populates='workflow_step') + workflow_outputs = relationship('WorkflowOutput', back_populates='workflow_step') + parent_workflow_input_connections = relationship('WorkflowStepConnection', + primaryjoin=(lambda: WorkflowStepConnection.input_subworkflow_step_id == WorkflowStep.id) # type: ignore + ) + output_connections = relationship('WorkflowStepConnection', + primaryjoin=(lambda: WorkflowStepConnection.output_step_id == WorkflowStep.id) # type: ignore + ) + workflow = relationship('Workflow', + primaryjoin=(lambda: Workflow.id == WorkflowStep.workflow_id), # type: ignore + back_populates='steps' + ) + STEP_TYPE_TO_INPUT_TYPE = { "data_input": "dataset", "data_collection_input": "dataset_collection", @@ -5401,7 +6757,33 @@ class WorkflowStep(RepresentById): pass -class WorkflowStepInput(RepresentById): +class WorkflowStepInput(Base, RepresentById): + __tablename__ = 'workflow_step_input' + __table_args__ = ( + Index('ix_workflow_step_input_workflow_step_id_name_unique', + 'workflow_step_id', 'name', unique=True, mysql_length={'name': 200}), + ) + + id = Column(Integer, primary_key=True) + workflow_step_id = Column(Integer, ForeignKey('workflow_step.id'), index=True) + name = Column(TEXT) + merge_type = Column(TEXT) + scatter_type = Column(TEXT) + value_from = Column(MutableJSONType) + value_from_type = Column(TEXT) + default_value = Column(MutableJSONType) + default_value_set = Column(Boolean, default=False) + runtime_value = Column(Boolean, default=False) + + workflow_step = relationship('WorkflowStep', + back_populates='inputs', + cascade='all', + primaryjoin=(lambda: WorkflowStepInput.workflow_step_id == WorkflowStep.id)) # type: ignore + connections = relationship( + 'WorkflowStepConnection', + back_populates='input_step_input', + primaryjoin=(lambda: WorkflowStepConnection.input_step_input_id == WorkflowStepInput.id)) # type: ignore + default_merge_type = None default_scatter_type = None @@ -5425,7 +6807,27 @@ class WorkflowStepInput(RepresentById): return copied_step_input -class WorkflowStepConnection(RepresentById): +class WorkflowStepConnection(Base, RepresentById): + __tablename__ = 'workflow_step_connection' + + id = Column(Integer, primary_key=True) + output_step_id = Column(Integer, ForeignKey('workflow_step.id'), index=True) + input_step_input_id = Column(Integer, ForeignKey('workflow_step_input.id'), index=True) + output_name = Column(TEXT) + input_subworkflow_step_id = Column(Integer, ForeignKey('workflow_step.id'), index=True) + + input_step_input = relationship('WorkflowStepInput', + back_populates='connections', + cascade='all', + primaryjoin=(lambda: WorkflowStepConnection.input_step_input_id == WorkflowStepInput.id)) # type: ignore + input_subworkflow_step = relationship('WorkflowStep', + back_populates='parent_workflow_input_connections', + primaryjoin=(lambda: WorkflowStepConnection.input_subworkflow_step_id == WorkflowStep.id)) # type: ignore + output_step = relationship('WorkflowStep', + back_populates='output_connections', + cascade='all', + primaryjoin=(lambda: WorkflowStepConnection.output_step_id == WorkflowStep.id)) # type: ignore + # Constant used in lieu of output_name and input_name to indicate an # implicit connection between two steps that is not dependent on a dataset # or a dataset collection. Allowing for instance data manager steps to setup @@ -5462,7 +6864,17 @@ class WorkflowStepConnection(RepresentById): return copied_connection -class WorkflowOutput(RepresentById): +class WorkflowOutput(Base, RepresentById): + __tablename__ = 'workflow_output' + + id = Column(Integer, primary_key=True) + workflow_step_id = Column(Integer, ForeignKey('workflow_step.id'), index=True, nullable=False) + output_name = Column(String(255), nullable=True) + label = Column(Unicode(255)) + uuid = Column(UUIDType) + workflow_step = relationship('WorkflowStep', + back_populates='workflow_outputs', + primaryjoin=(lambda: WorkflowStep.id == WorkflowOutput.workflow_step_id)) def __init__(self, workflow_step, output_name=None, label=None, uuid=None): self.workflow_step = workflow_step @@ -5480,14 +6892,35 @@ class WorkflowOutput(RepresentById): return copied_output -class StoredWorkflowUserShareAssociation(UserShareAssociation): +class StoredWorkflowUserShareAssociation(Base, UserShareAssociation): + __tablename__ = 'stored_workflow_user_share_connection' + + id = Column(Integer, primary_key=True) + stored_workflow_id = Column(Integer, ForeignKey('stored_workflow.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + user = relationship('User', back_populates='workflows_shared_by_others') + stored_workflow = relationship('StoredWorkflow', back_populates='users_shared_with') def __init__(self): self.stored_workflow = None self.user = None -class StoredWorkflowMenuEntry(RepresentById): +class StoredWorkflowMenuEntry(Base, RepresentById): + __tablename__ = 'stored_workflow_menu_entry' + + id = Column(Integer, primary_key=True) + stored_workflow_id = Column(Integer, ForeignKey('stored_workflow.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + order_index = Column(Integer) + + stored_workflow = relationship('StoredWorkflow') + user = relationship('User', back_populates='stored_workflow_menu_entries', + primaryjoin=(lambda: + (StoredWorkflowMenuEntry.user_id == User.id) # type: ignore + & (StoredWorkflowMenuEntry.stored_workflow_id == StoredWorkflow.id) # type: ignore + & not_(StoredWorkflow.deleted)) # type: ignore + ) def __init__(self): self.stored_workflow = None @@ -5495,7 +6928,50 @@ class StoredWorkflowMenuEntry(RepresentById): self.order_index = None -class WorkflowInvocation(UsesCreateAndUpdateTime, Dictifiable, RepresentById): +class WorkflowInvocation(Base, UsesCreateAndUpdateTime, Dictifiable, RepresentById): + __tablename__ = 'workflow_invocation' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now, index=True) + workflow_id = Column(Integer, ForeignKey('workflow.id'), index=True, nullable=False) + state = Column(TrimmedString(64), index=True) + scheduler = Column(TrimmedString(255), index=True) + handler = Column(TrimmedString(255), index=True) + uuid = Column(UUIDType()) + history_id = Column(Integer, ForeignKey('history.id'), index=True) + + history = relationship('History', back_populates='workflow_invocations') + input_parameters = relationship('WorkflowRequestInputParameter', + back_populates='workflow_invocation') + step_states = relationship('WorkflowRequestStepState', back_populates='workflow_invocation') + input_step_parameters = relationship('WorkflowRequestInputStepParameter', + back_populates='workflow_invocation') + input_datasets = relationship('WorkflowRequestToInputDatasetAssociation', + back_populates='workflow_invocation') + input_dataset_collections = relationship('WorkflowRequestToInputDatasetCollectionAssociation', + back_populates='workflow_invocation') + subworkflow_invocations = relationship('WorkflowInvocationToSubworkflowInvocationAssociation', + primaryjoin=(lambda: + WorkflowInvocationToSubworkflowInvocationAssociation.workflow_invocation_id # type: ignore + == WorkflowInvocation.id), # type: ignore + back_populates='parent_workflow_invocation', + uselist=True, + ) + steps = relationship('WorkflowInvocationStep', back_populates='workflow_invocation') + workflow = relationship('Workflow') + output_dataset_collections = relationship('WorkflowInvocationOutputDatasetCollectionAssociation', + back_populates='workflow_invocation') + output_datasets = relationship('WorkflowInvocationOutputDatasetAssociation', + back_populates='workflow_invocation') + parent_workflow_invocation_association = relationship( + 'WorkflowInvocationToSubworkflowInvocationAssociation', + primaryjoin=(lambda: + WorkflowInvocationToSubworkflowInvocationAssociation.subworkflow_invocation_id # type: ignore + == WorkflowInvocation.id), # type: ignore + back_populates='subworkflow_invocation') + output_values = relationship('WorkflowInvocationOutputValue', back_populates='workflow_invocation') + dict_collection_visible_keys = ['id', 'update_time', 'create_time', 'workflow_id', 'history_id', 'uuid', 'state'] dict_element_visible_keys = ['id', 'update_time', 'create_time', 'workflow_id', 'history_id', 'uuid', 'state'] @@ -5508,10 +6984,10 @@ class WorkflowInvocation(UsesCreateAndUpdateTime, Dictifiable, RepresentById): non_terminal_states = [states.NEW, states.READY] - def __init__(self): - self.subworkflow_invocations = [] - self.step_states = [] - self.steps = [] + def __init__(self): # TODO no need + self.subworkflow_invocations = [] # TODO instrumented attribute / overwritten + self.step_states = [] # TODO instrumented attribute / overwritten + self.steps = [] # TODO instrumented attribute / overwritten self.workflow_id = None def create_subworkflow_invocation_for_step(self, step): @@ -5849,12 +7325,74 @@ class WorkflowInvocation(UsesCreateAndUpdateTime, Dictifiable, RepresentById): return f"{self.__class__.__name__}[{extra}]" -class WorkflowInvocationToSubworkflowInvocationAssociation(Dictifiable, RepresentById): +class WorkflowInvocationToSubworkflowInvocationAssociation(Base, Dictifiable, RepresentById): + __tablename__ = 'workflow_invocation_to_subworkflow_invocation_association' + + id = Column(Integer, primary_key=True) + workflow_invocation_id = Column(Integer, + ForeignKey('workflow_invocation.id', name='fk_wfi_swi_wfi'), index=True) + subworkflow_invocation_id = Column(Integer, + ForeignKey('workflow_invocation.id', name='fk_wfi_swi_swi'), index=True) + workflow_step_id = Column(Integer, ForeignKey('workflow_step.id', name='fk_wfi_swi_ws')) + + subworkflow_invocation = relationship('WorkflowInvocation', + primaryjoin=(lambda: + WorkflowInvocationToSubworkflowInvocationAssociation.subworkflow_invocation_id # type: ignore + == WorkflowInvocation.id), # type: ignore + back_populates='parent_workflow_invocation_association', + uselist=False, + ) + workflow_step = relationship('WorkflowStep') + parent_workflow_invocation = relationship('WorkflowInvocation', + primaryjoin=(lambda: + WorkflowInvocationToSubworkflowInvocationAssociation.workflow_invocation_id # type: ignore + == WorkflowInvocation.id), # type: ignore + back_populates='subworkflow_invocations', + uselist=False, + ) dict_collection_visible_keys = ['id', 'workflow_step_id', 'workflow_invocation_id', 'subworkflow_invocation_id'] dict_element_visible_keys = ['id', 'workflow_step_id', 'workflow_invocation_id', 'subworkflow_invocation_id'] -class WorkflowInvocationStep(Dictifiable, RepresentById): +class WorkflowInvocationStep(Base, Dictifiable, RepresentById): + __tablename__ = 'workflow_invocation_step' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + workflow_invocation_id = Column(Integer, + ForeignKey('workflow_invocation.id'), index=True, nullable=False) + workflow_step_id = Column(Integer, + ForeignKey('workflow_step.id'), index=True, nullable=False) + state = Column(TrimmedString(64), index=True) + job_id = Column(Integer, ForeignKey('job.id'), index=True, nullable=True) + implicit_collection_jobs_id = Column(Integer, + ForeignKey('implicit_collection_jobs.id'), index=True, nullable=True) + action = Column(MutableJSONType, nullable=True) + + workflow_step = relationship('WorkflowStep') + job = relationship('Job', back_populates='workflow_invocation_step', uselist=False) + implicit_collection_jobs = relationship('ImplicitCollectionJobs', + back_populates='workflow_invocation_step', uselist=False) + output_dataset_collections = relationship( + 'WorkflowInvocationStepOutputDatasetCollectionAssociation', + back_populates='workflow_invocation_step') + output_datasets = relationship('WorkflowInvocationStepOutputDatasetAssociation', + back_populates='workflow_invocation_step') + workflow_invocation = relationship('WorkflowInvocation', back_populates='steps') + output_value = relationship('WorkflowInvocationOutputValue', + foreign_keys='[WorkflowInvocationStep.workflow_invocation_id, WorkflowInvocationStep.workflow_step_id]', + primaryjoin=(lambda: and_( + WorkflowInvocationStep.workflow_invocation_id # type: ignore + == WorkflowInvocationOutputValue.workflow_invocation_id, # type: ignore + WorkflowInvocationStep.workflow_step_id == WorkflowInvocationOutputValue.workflow_step_id, # type: ignore + )), + back_populates='workflow_invocation_step', + viewonly=True + ) + + subworkflow_invocation_id: column_property + dict_collection_visible_keys = ['id', 'update_time', 'job_id', 'workflow_step_id', 'subworkflow_invocation_id', 'state', 'action'] dict_element_visible_keys = ['id', 'update_time', 'job_id', 'workflow_step_id', 'subworkflow_invocation_id', 'state', 'action'] @@ -5934,9 +7472,19 @@ class WorkflowInvocationStep(Dictifiable, RepresentById): return rval -class WorkflowRequestInputParameter(Dictifiable, RepresentById): +class WorkflowRequestInputParameter(Base, Dictifiable, RepresentById): """ Workflow-related parameters not tied to steps or inputs. """ + __tablename__ = 'workflow_request_input_parameters' + + id = Column(Integer, primary_key=True) + workflow_invocation_id = Column( + Integer, ForeignKey('workflow_invocation.id', onupdate='CASCADE', ondelete='CASCADE')) + name = Column(Unicode(255)) + value = Column(TEXT) + type = Column(Unicode(255)) + workflow_invocation = relationship('WorkflowInvocation', back_populates='input_parameters') + dict_collection_visible_keys = ['id', 'name', 'value', 'type'] class types(str, Enum): @@ -5951,66 +7499,209 @@ class WorkflowRequestInputParameter(Dictifiable, RepresentById): self.type = type -class WorkflowRequestStepState(Dictifiable, RepresentById): +class WorkflowRequestStepState(Base, Dictifiable, RepresentById): """ Workflow step value parameters. """ + __tablename__ = 'workflow_request_step_states' + + id = Column(Integer, primary_key=True) + workflow_invocation_id = Column(Integer, + ForeignKey('workflow_invocation.id', onupdate='CASCADE', ondelete='CASCADE')) + workflow_step_id = Column(Integer, ForeignKey('workflow_step.id')) + value = Column(MutableJSONType) + workflow_step = relationship('WorkflowStep') + workflow_invocation = relationship('WorkflowInvocation', back_populates='step_states') + dict_collection_visible_keys = ['id', 'name', 'value', 'workflow_step_id'] def __init__(self, workflow_step=None, name=None, value=None): self.workflow_step = workflow_step - self.name = name + self.name = name # TODO this is unused and not persisted. Verify and remove. self.value = value - self.type = type + self.type = type # TODO this is incorrect. Verify and remove. -class WorkflowRequestToInputDatasetAssociation(Dictifiable, RepresentById): +class WorkflowRequestToInputDatasetAssociation(Base, Dictifiable, RepresentById): """ Workflow step input dataset parameters. """ + __tablename__ = 'workflow_request_to_input_dataset' + + id = Column(Integer, primary_key=True) + name = Column(String(255)) + workflow_invocation_id = Column(Integer, ForeignKey("workflow_invocation.id"), index=True) + workflow_step_id = Column(Integer, ForeignKey("workflow_step.id")) + dataset_id = Column(Integer, ForeignKey("history_dataset_association.id"), index=True) + + workflow_step = relationship('WorkflowStep') + dataset = relationship('HistoryDatasetAssociation') + workflow_invocation = relationship('WorkflowInvocation', back_populates='input_datasets') + history_content_type = "dataset" dict_collection_visible_keys = ['id', 'workflow_invocation_id', 'workflow_step_id', 'dataset_id', 'name'] -class WorkflowRequestToInputDatasetCollectionAssociation(Dictifiable, RepresentById): +class WorkflowRequestToInputDatasetCollectionAssociation(Base, Dictifiable, RepresentById): """ Workflow step input dataset collection parameters. """ + __tablename__ = 'workflow_request_to_input_collection_dataset' + + id = Column(Integer, primary_key=True) + name = Column(String(255)) + workflow_invocation_id = Column(Integer, ForeignKey('workflow_invocation.id'), index=True) + workflow_step_id = Column(Integer, ForeignKey('workflow_step.id')) + dataset_collection_id = Column(Integer, + ForeignKey('history_dataset_collection_association.id'), index=True) + workflow_step = relationship('WorkflowStep') + dataset_collection = relationship('HistoryDatasetCollectionAssociation') + workflow_invocation = relationship('WorkflowInvocation', + back_populates='input_dataset_collections') + history_content_type = "dataset_collection" dict_collection_visible_keys = ['id', 'workflow_invocation_id', 'workflow_step_id', 'dataset_collection_id', 'name'] -class WorkflowRequestInputStepParameter(Dictifiable, RepresentById): +class WorkflowRequestInputStepParameter(Base, Dictifiable, RepresentById): """ Workflow step parameter inputs. """ + __tablename__ = 'workflow_request_input_step_parameter' + + id = Column(Integer, primary_key=True) + workflow_invocation_id = Column(Integer, ForeignKey('workflow_invocation.id'), index=True) + workflow_step_id = Column(Integer, ForeignKey('workflow_step.id')) + parameter_value = Column(MutableJSONType) + + workflow_step = relationship('WorkflowStep') + workflow_invocation = relationship('WorkflowInvocation', back_populates='input_step_parameters') + dict_collection_visible_keys = ['id', 'workflow_invocation_id', 'workflow_step_id', 'parameter_value'] -class WorkflowInvocationOutputDatasetAssociation(Dictifiable, RepresentById): +class WorkflowInvocationOutputDatasetAssociation(Base, Dictifiable, RepresentById): """Represents links to output datasets for the workflow.""" + __tablename__ = 'workflow_invocation_output_dataset_association' + + id = Column(Integer, primary_key=True) + workflow_invocation_id = Column(Integer, ForeignKey('workflow_invocation.id'), index=True) + workflow_step_id = Column(Integer, ForeignKey('workflow_step.id'), index=True) + dataset_id = Column(Integer, ForeignKey('history_dataset_association.id'), index=True) + workflow_output_id = Column(Integer, ForeignKey('workflow_output.id'), index=True) + + workflow_invocation = relationship('WorkflowInvocation', back_populates='output_datasets') + workflow_step = relationship('WorkflowStep') + dataset = relationship('HistoryDatasetAssociation') + workflow_output = relationship('WorkflowOutput') + history_content_type = "dataset" dict_collection_visible_keys = ['id', 'workflow_invocation_id', 'workflow_step_id', 'dataset_id', 'name'] -class WorkflowInvocationOutputDatasetCollectionAssociation(Dictifiable, RepresentById): +class WorkflowInvocationOutputDatasetCollectionAssociation(Base, Dictifiable, RepresentById): """Represents links to output dataset collections for the workflow.""" + __tablename__ = 'workflow_invocation_output_dataset_collection_association' + + id = Column(Integer, primary_key=True) + workflow_invocation_id = Column(Integer, + ForeignKey('workflow_invocation.id', name='fk_wiodca_wii'), index=True) + workflow_step_id = Column(Integer, + ForeignKey('workflow_step.id', name='fk_wiodca_wsi'), index=True) + dataset_collection_id = Column(Integer, + ForeignKey('history_dataset_collection_association.id', name='fk_wiodca_dci'), index=True) + workflow_output_id = Column(Integer, + ForeignKey('workflow_output.id', name='fk_wiodca_woi'), index=True) + + workflow_invocation = relationship('WorkflowInvocation', + back_populates='output_dataset_collections') + workflow_step = relationship('WorkflowStep') + dataset_collection = relationship('HistoryDatasetCollectionAssociation') + workflow_output = relationship('WorkflowOutput') + history_content_type = "dataset_collection" dict_collection_visible_keys = ['id', 'workflow_invocation_id', 'workflow_step_id', 'dataset_collection_id', 'name'] -class WorkflowInvocationOutputValue(Dictifiable, RepresentById): +class WorkflowInvocationOutputValue(Base, Dictifiable, RepresentById): """Represents a link to a specified or computed workflow parameter.""" + __tablename__ = 'workflow_invocation_output_value' + + id = Column(Integer, primary_key=True) + workflow_invocation_id = Column(Integer, ForeignKey('workflow_invocation.id'), index=True) + workflow_step_id = Column(Integer, ForeignKey('workflow_step.id')) + workflow_output_id = Column(Integer, ForeignKey('workflow_output.id'), index=True) + value = Column(MutableJSONType) + + workflow_invocation = relationship('WorkflowInvocation', back_populates="output_values") + + workflow_invocation_step = relationship('WorkflowInvocationStep', + foreign_keys='[WorkflowInvocationStep.workflow_invocation_id, WorkflowInvocationStep.workflow_step_id]', + primaryjoin=(lambda: and_( + WorkflowInvocationStep.workflow_invocation_id == WorkflowInvocationOutputValue.workflow_invocation_id, # type: ignore + WorkflowInvocationStep.workflow_step_id == WorkflowInvocationOutputValue.workflow_step_id, # type: ignore + )), + back_populates='output_value', + viewonly=True + ) + + workflow_step = relationship('WorkflowStep') + workflow_output = relationship('WorkflowOutput') + dict_collection_visible_keys = ['id', 'workflow_invocation_id', 'workflow_step_id', 'value'] -class WorkflowInvocationStepOutputDatasetAssociation(Dictifiable, RepresentById): +class WorkflowInvocationStepOutputDatasetAssociation(Base, Dictifiable, RepresentById): """Represents links to output datasets for the workflow.""" + __tablename__ = 'workflow_invocation_step_output_dataset_association' + + id = Column(Integer, primary_key=True) + workflow_invocation_step_id = Column(Integer, + ForeignKey('workflow_invocation_step.id'), index=True) + dataset_id = Column(Integer, ForeignKey('history_dataset_association.id'), index=True) + output_name = Column(String(255), nullable=True) + workflow_invocation_step = relationship('WorkflowInvocationStep', + back_populates='output_datasets') + dataset = relationship('HistoryDatasetAssociation') + dict_collection_visible_keys = ['id', 'workflow_invocation_step_id', 'dataset_id', 'output_name'] -class WorkflowInvocationStepOutputDatasetCollectionAssociation(Dictifiable, RepresentById): +class WorkflowInvocationStepOutputDatasetCollectionAssociation(Base, Dictifiable, RepresentById): """Represents links to output dataset collections for the workflow.""" + __tablename__ = 'workflow_invocation_step_output_dataset_collection_association' + + id = Column(Integer, primary_key=True) + workflow_invocation_step_id = Column( + Integer, ForeignKey('workflow_invocation_step.id', name='fk_wisodca_wisi'), index=True) + workflow_step_id = Column( + Integer, ForeignKey('workflow_step.id', name='fk_wisodca_wsi'), index=True) + dataset_collection_id = Column( + Integer, + ForeignKey('history_dataset_collection_association.id', name='fk_wisodca_dci'), index=True) + output_name = Column(String(255), nullable=True) + + workflow_invocation_step = relationship('WorkflowInvocationStep', + back_populates='output_dataset_collections') + dataset_collection = relationship('HistoryDatasetCollectionAssociation') + dict_collection_visible_keys = ['id', 'workflow_invocation_step_id', 'dataset_collection_id', 'output_name'] -class MetadataFile(StorableObject, RepresentById): +class MetadataFile(Base, StorableObject, RepresentById): + __tablename__ = 'metadata_file' + + id = Column(Integer, primary_key=True) + name = Column(TEXT) + hda_id = Column(Integer, + ForeignKey('history_dataset_association.id'), index=True, nullable=True) + lda_id = Column(Integer, + ForeignKey('library_dataset_dataset_association.id'), index=True, nullable=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, index=True, default=now, onupdate=now) + object_store_id = Column(TrimmedString(255), index=True) + uuid = Column(UUIDType(), index=True) + deleted = Column(Boolean, index=True, default=False) + purged = Column(Boolean, index=True, default=False) + + history_dataset = relationship('HistoryDatasetAssociation') + library_dataset = relationship('LibraryDatasetDatasetAssociation') def __init__(self, dataset=None, name=None, uuid=None): super().__init__(id=None, uuid=uuid) @@ -6060,7 +7751,24 @@ class MetadataFile(StorableObject, RepresentById): return as_dict -class FormDefinition(Dictifiable, RepresentById): +class FormDefinition(Base, Dictifiable, RepresentById): + __tablename__ = 'form_definition' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + name = Column(TrimmedString(255), nullable=False) + desc = Column(TEXT) + form_definition_current_id = Column(Integer, + ForeignKey('form_definition_current.id', use_alter=True), index=True, nullable=False) + fields = Column(MutableJSONType) + type = Column(TrimmedString(255), index=True) + layout = Column(MutableJSONType) + form_definition_current = relationship( + 'FormDefinitionCurrent', + back_populates='forms', + primaryjoin=(lambda: FormDefinitionCurrent.id == FormDefinition.form_definition_current_id)) # type: ignore + # The following form_builder classes are supported by the FormDefinition class. supported_field_types = [AddressField, CheckboxField, PasswordField, SelectField, TextArea, TextField, WorkflowField, WorkflowMappingField, HistoryField] @@ -6105,18 +7813,67 @@ class FormDefinition(Dictifiable, RepresentById): return gridfields -class FormDefinitionCurrent(RepresentById): +class FormDefinitionCurrent(Base, RepresentById): + __tablename__ = 'form_definition_current' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + latest_form_id = Column(Integer, ForeignKey('form_definition.id'), index=True) + deleted = Column(Boolean, index=True, default=False) + forms = relationship( + 'FormDefinition', + back_populates='form_definition_current', + cascade='all, delete-orphan', + primaryjoin=(lambda: FormDefinitionCurrent.id == FormDefinition.form_definition_current_id)) # type: ignore + latest_form = relationship( + 'FormDefinition', + post_update=True, + primaryjoin=(lambda: FormDefinitionCurrent.latest_form_id == FormDefinition.id)) # type: ignore + def __init__(self, form_definition=None): self.latest_form = form_definition -class FormValues(RepresentById): +class FormValues(Base, RepresentById): + __tablename__ = 'form_values' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + form_definition_id = Column(Integer, ForeignKey('form_definition.id'), index=True) + content = Column(MutableJSONType) + form_definition = relationship( + 'FormDefinition', + primaryjoin=(lambda: FormValues.form_definition_id == FormDefinition.id)) # type: ignore + def __init__(self, form_def=None, content=None): self.form_definition = form_def self.content = content -class UserAddress(RepresentById): +class UserAddress(Base, RepresentById): + __tablename__ = 'user_address' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + desc = Column(TrimmedString(255)) + name = Column(TrimmedString(255), nullable=False) + institution = Column(TrimmedString(255)) + address = Column(TrimmedString(255), nullable=False) + city = Column(TrimmedString(255), nullable=False) + state = Column(TrimmedString(255), nullable=False) + postal_code = Column(TrimmedString(255), nullable=False) + country = Column(TrimmedString(255), nullable=False) + phone = Column(TrimmedString(255)) + deleted = Column(Boolean, index=True, default=False) + purged = Column(Boolean, index=True, default=False) + # `desc` needs to be fully qualified because it is shadowed by `desc` Column defined above + # TODO: db migration to rename column, then use `desc` + user = relationship('User', back_populates='addresses', order_by=sqlalchemy.desc('update_time')) + def __init__(self, user=None, desc=None, name=None, institution=None, address=None, city=None, state=None, postal_code=None, country=None, phone=None): @@ -6147,13 +7904,13 @@ class UserAddress(RepresentById): class PSAAssociation(Base, AssociationMixin, RepresentById): __tablename__ = 'psa_association' - id = Column('id', Integer, primary_key=True) - server_url = Column('server_url', VARCHAR(255)) - handle = Column('handle', VARCHAR(255)) - secret = Column('secret', VARCHAR(255)) - issued = Column('issued', Integer) - lifetime = Column('lifetime', Integer) - assoc_type = Column('assoc_type', VARCHAR(64)) + id = Column(Integer, primary_key=True) + server_url = Column(VARCHAR(255)) + handle = Column(VARCHAR(255)) + secret = Column(VARCHAR(255)) + issued = Column(Integer) + lifetime = Column(Integer) + assoc_type = Column(VARCHAR(64)) # This static property is set at: galaxy.authnz.psa_authnz.PSAAuthnz sa_session = None @@ -6198,9 +7955,9 @@ class PSACode(Base, CodeMixin, RepresentById): UniqueConstraint('code', 'email'), ) - id = Column('id', Integer, primary_key=True) - email = Column('email', VARCHAR(200)) - code = Column('code', VARCHAR(32)) + id = Column(Integer, primary_key=True) + email = Column(VARCHAR(200)) + code = Column(VARCHAR(32)) # This static property is set at: galaxy.authnz.psa_authnz.PSAAuthnz sa_session = None @@ -6221,10 +7978,10 @@ class PSACode(Base, CodeMixin, RepresentById): class PSANonce(Base, NonceMixin, RepresentById): __tablename__ = 'psa_nonce' - id = Column('id', Integer, primary_key=True) - server_url = Column('server_url', VARCHAR(255)) - timestamp = Column('timestamp', Integer) - salt = Column('salt', VARCHAR(40)) + id = Column(Integer, primary_key=True) + server_url = Column(VARCHAR(255)) + timestamp = Column(Integer) + salt = Column(VARCHAR(40)) # This static property is set at: galaxy.authnz.psa_authnz.PSAAuthnz sa_session = None @@ -6252,11 +8009,11 @@ class PSANonce(Base, NonceMixin, RepresentById): class PSAPartial(Base, PartialMixin, RepresentById): __tablename__ = 'psa_partial' - id = Column('id', Integer, primary_key=True) - token = Column('token', VARCHAR(32)) - data = Column('data', TEXT) - next_step = Column('next_step', Integer) - backend = Column('backend', VARCHAR(32)) + id = Column(Integer, primary_key=True) + token = Column(VARCHAR(32)) + data = Column(TEXT) + next_step = Column(Integer) + backend = Column(VARCHAR(32)) # This static property is set at: galaxy.authnz.psa_authnz.PSAAuthnz sa_session = None @@ -6282,9 +8039,20 @@ class PSAPartial(Base, PartialMixin, RepresentById): cls.sa_session.delete(partial) -class UserAuthnzToken(UserMixin, RepresentById): +class UserAuthnzToken(Base, UserMixin, RepresentById): + __tablename__ = 'oidc_user_authnz_tokens' __table_args__ = (UniqueConstraint('provider', 'uid'),) + id = Column(Integer, primary_key=True) + user_id = Column(Integer, ForeignKey("galaxy_user.id"), index=True) + uid = Column(VARCHAR(255)) + provider = Column(VARCHAR(32)) + extra_data = Column(MutableJSONType, nullable=True) + lifetime = Column(Integer) + assoc_type = Column(VARCHAR(64)) + cloudauthz = relationship('CloudAuthz', back_populates='authn') + user = relationship('User', back_populates='social_auth') + # This static property is set at: galaxy.authnz.psa_authnz.PSAAuthnz sa_session = None @@ -6360,7 +8128,7 @@ class UserAuthnzToken(UserMixin, RepresentById): @classmethod def get_users_by_email(cls, email): - return cls.user_query().filter(func.lower(User.table.c.email) == email.lower()) + return cls.user_query().filter(func.lower(User.email) == email.lower()) @classmethod def get_social_auth(cls, provider, uid): @@ -6388,11 +8156,25 @@ class UserAuthnzToken(UserMixin, RepresentById): return instance -class CustosAuthnzToken(RepresentById): +class CustosAuthnzToken(Base, RepresentById): + __tablename__ = 'custos_authnz_token' + __table_args__ = ( + UniqueConstraint('user_id', 'external_user_id', 'provider'), + UniqueConstraint('external_user_id', 'provider'), + ) + + id = Column(Integer, primary_key=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id')) + external_user_id = Column(String(64)) + provider = Column(String(255)) + access_token = Column(Text) + id_token = Column(Text) + refresh_token = Column(Text) + expiration_time = Column(DateTime) + refresh_expiration_time = Column(DateTime) + user = relationship('User', back_populates='custos_auth') def __init__(self, user, external_user_id, provider, access_token, id_token, refresh_token, expiration_time, refresh_expiration_time): - self.id = None - # 'user' is a backref to model.User self.user = user self.external_user_id = external_user_id self.provider = provider @@ -6403,14 +8185,27 @@ class CustosAuthnzToken(RepresentById): self.refresh_expiration_time = refresh_expiration_time -class CloudAuthz(_HasTable): - def __init__(self, user_id, provider, config, authn_id, description=""): - self.id = None +class CloudAuthz(Base, _HasTable): + __tablename__ = 'cloudauthz' + + id = Column(Integer, primary_key=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + provider = Column(String(255)) + config = Column(MutableJSONType) + authn_id = Column(Integer, ForeignKey('oidc_user_authnz_tokens.id'), index=True) + tokens = Column(MutableJSONType) + last_update = Column(DateTime) + last_activity = Column(DateTime) + description = Column(TEXT) + create_time = Column(DateTime, default=now) + user = relationship('User', back_populates='cloudauthz') + authn = relationship('UserAuthnzToken', back_populates='cloudauthz') + + def __init__(self, user_id, provider, config, authn_id, description=None): self.user_id = user_id self.provider = provider self.config = config self.authn_id = authn_id - self.tokens = None self.last_update = datetime.now() self.last_activity = datetime.now() self.description = description @@ -6424,8 +8219,57 @@ class CloudAuthz(_HasTable): and self.config[k] == config[k]}) == len(self.config)) -class Page(Dictifiable, RepresentById): - # username needed for slug generation +class Page(Base, Dictifiable, RepresentById): + __tablename__ = 'page' + __table_args__ = ( + Index('ix_page_slug', 'slug', mysql_length=200), + ) + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True, nullable=False) + latest_revision_id = Column(Integer, + ForeignKey('page_revision.id', use_alter=True, name='page_latest_revision_id_fk'), index=True) + title = Column(TEXT) + deleted = Column(Boolean, index=True, default=False) + importable = Column(Boolean, index=True, default=False) + slug = Column(TEXT) + published = Column(Boolean, index=True, default=False) + user = relationship('User', back_populates='pages') + revisions = relationship( + 'PageRevision', + cascade="all, delete-orphan", + primaryjoin=(lambda: Page.id == PageRevision.page_id), # type: ignore + back_populates='page') + latest_revision = relationship( + 'PageRevision', + post_update=True, + primaryjoin=(lambda: Page.latest_revision_id == PageRevision.id), # type: ignore + lazy=False) + tags = relationship( + 'PageTagAssociation', + order_by=lambda: PageTagAssociation.id, # type: ignore + back_populates='page') + annotations = relationship( + 'PageAnnotationAssociation', + order_by=lambda: PageAnnotationAssociation.id, # type: ignore + back_populates='page') + ratings = relationship( + 'PageRatingAssociation', + order_by=lambda: PageRatingAssociation.id, # type: ignore + back_populates='page') + users_shared_with = relationship( + 'PageUserShareAssociation', + back_populates='page') + + average_rating: column_property # defined at the end of this module + + # Set up proxy so that + # Page.users_shared_with + # returns a list of users that page is shared with. + users_shared_with_dot_users = association_proxy('users_shared_with', 'user') + dict_element_visible_keys = ['id', 'title', 'latest_revision_id', 'slug', 'published', 'importable', 'deleted', 'username'] def __init__(self): @@ -6446,19 +8290,28 @@ class Page(Dictifiable, RepresentById): rval['revision_ids'] = rev return rval + # username needed for slug generation @property def username(self): return self.user.username -class PageRevision(Dictifiable, RepresentById): +class PageRevision(Base, Dictifiable, RepresentById): + __tablename__ = 'page_revision' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + page_id = Column(Integer, ForeignKey('page.id'), index=True, nullable=False) + title = Column(TEXT) + content = Column(TEXT) + content_format = Column(TrimmedString(32)) + page = relationship('Page', + primaryjoin=(lambda: Page.id == PageRevision.page_id)) # type: ignore DEFAULT_CONTENT_FORMAT = 'html' dict_element_visible_keys = ['id', 'page_id', 'title', 'content', 'content_format'] def __init__(self): - self.user = None - self.title = None - self.content = None self.content_format = PageRevision.DEFAULT_CONTENT_FORMAT def to_dict(self, view='element'): @@ -6468,13 +8321,69 @@ class PageRevision(Dictifiable, RepresentById): return rval -class PageUserShareAssociation(UserShareAssociation): +class PageUserShareAssociation(Base, UserShareAssociation): + __tablename__ = 'page_user_share_association' + + id = Column(Integer, primary_key=True) + page_id = Column(Integer, ForeignKey("page.id"), index=True) + user_id = Column(Integer, ForeignKey("galaxy_user.id"), index=True) + user = relationship('User', back_populates='pages_shared_by_others') + page = relationship('Page', back_populates='users_shared_with') + def __init__(self): self.page = None self.user = None -class Visualization(RepresentById): +class Visualization(Base, RepresentById): + __tablename__ = 'visualization' + __table_args__ = ( + Index('ix_visualization_dbkey', 'dbkey', mysql_length=200), + Index('ix_visualization_slug', 'slug', mysql_length=200), + ) + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True, nullable=False) + latest_revision_id = Column(Integer, + ForeignKey('visualization_revision.id', use_alter=True, name='visualization_latest_revision_id_fk'), + index=True) + title = Column(TEXT) + type = Column(TEXT) + dbkey = Column(TEXT) + deleted = Column(Boolean, default=False, index=True) + importable = Column(Boolean, default=False, index=True) + slug = Column(TEXT) + published = Column(Boolean, default=False, index=True) + + user = relationship('User') + revisions = relationship('VisualizationRevision', + back_populates='visualization', + cascade="all, delete-orphan", + primaryjoin=(lambda: Visualization.id == VisualizationRevision.visualization_id)) # type: ignore + latest_revision = relationship('VisualizationRevision', + post_update=True, + primaryjoin=(lambda: Visualization.latest_revision_id == VisualizationRevision.id), # type: ignore + lazy=False) + tags = relationship('VisualizationTagAssociation', + order_by=lambda: VisualizationTagAssociation.id, # type: ignore + back_populates="visualization") + annotations = relationship('VisualizationAnnotationAssociation', + order_by=lambda: VisualizationAnnotationAssociation.id, # type: ignore + back_populates="visualization") + ratings = relationship('VisualizationRatingAssociation', + order_by=lambda: VisualizationRatingAssociation.id, # type: ignore + back_populates="visualization") + users_shared_with = relationship('VisualizationUserShareAssociation', back_populates='visualization') + + average_rating: column_property # defined at the end of this module + + # Set up proxy so that + # Visualization.users_shared_with + # returns a list of users that visualization is shared with. + users_shared_with_dot_users = association_proxy('users_shared_with', 'user') + def __init__(self, id=None, user=None, type=None, title=None, dbkey=None, slug=None, latest_revision=None): self.id = id self.user = user @@ -6483,8 +8392,8 @@ class Visualization(RepresentById): self.dbkey = dbkey self.slug = slug self.latest_revision = latest_revision - self.revisions = [] - if self.latest_revision: + self.revisions = [] # TODO: review: this attempts to overwrite an instrumented attr (SA overwrites this?) + if self.latest_revision: # TODO: but this happens ONLY if passed to constructor. Review. self.revisions.append(latest_revision) def copy(self, user=None, title=None): @@ -6509,7 +8418,23 @@ class Visualization(RepresentById): return copy_viz -class VisualizationRevision(RepresentById): +class VisualizationRevision(Base, RepresentById): + __tablename__ = 'visualization_revision' + __table_args__ = ( + Index('ix_visualization_revision_dbkey', 'dbkey', mysql_length=200), + ) + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + visualization_id = Column(Integer, ForeignKey('visualization.id'), index=True, nullable=False) + title = Column(TEXT) + dbkey = Column(TEXT) + config = Column(MutableJSONType) + visualization = relationship('Visualization', + back_populates='revisions', + primaryjoin=(lambda: Visualization.id == VisualizationRevision.visualization_id)) # type: ignore + def __init__(self, visualization=None, title=None, dbkey=None, config=None): self.id = None self.visualization = visualization @@ -6532,13 +8457,34 @@ class VisualizationRevision(RepresentById): ) -class VisualizationUserShareAssociation(UserShareAssociation): +class VisualizationUserShareAssociation(Base, UserShareAssociation): + __tablename__ = 'visualization_user_share_association' + + id = Column(Integer, primary_key=True) + visualization_id = Column(Integer, ForeignKey('visualization.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + user = relationship('User', back_populates='visualizations_shared_by_others') + visualization = relationship('Visualization', back_populates='users_shared_with') + def __init__(self): self.visualization = None self.user = None -class TransferJob(RepresentById): +class TransferJob(Base, RepresentById): + __tablename__ = 'transfer_job' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, default=now, onupdate=now) + state = Column(String(64), index=True) + path = Column(String(1024)) + info = Column(TEXT) + pid = Column(Integer) + socket = Column(Integer) + params = Column(MutableJSONType) + transfer_job = relationship('GenomeIndexToolData', back_populates='transfer') + # These states are used both by the transfer manager's IPC and the object # state in the database. Not all states are used by both. class states(str, Enum): @@ -6560,12 +8506,32 @@ class TransferJob(RepresentById): self.params = params -class Tag(RepresentById): - def __init__(self, id=None, type=None, parent_id=None, name=None): - self.id = id - self.type = type - self.parent_id = parent_id - self.name = name +class Tag(Base, RepresentById): + __tablename__ = 'tag' + __table_args__ = ( + UniqueConstraint('name'), + ) + + id = Column(Integer, primary_key=True) + type = Column(Integer) + parent_id = Column(Integer, ForeignKey('tag.id')) + name = Column(TrimmedString(255)) + children = relationship('Tag', back_populates='parent') + parent = relationship('Tag', back_populates='children', remote_side=[id]) + tagged_histories = relationship('HistoryTagAssociation', back_populates='tag') + tagged_history_dataset_associations = relationship( + 'HistoryDatasetAssociationTagAssociation', back_populates='tag') + tagged_library_dataset_dataset_associations = relationship( + 'LibraryDatasetDatasetAssociationTagAssociation', back_populates='tag') + tagged_pages = relationship('PageTagAssociation', back_populates='tag') + tagged_workflow_steps = relationship('WorkflowStepTagAssociation', back_populates='tag') + tagged_stored_workflows = relationship('StoredWorkflowTagAssociation', back_populates='tag') + tagged_visualizations = relationship('VisualizationTagAssociation', back_populates='tag') + tagged_history_dataset_collections = relationship( + 'HistoryDatasetCollectionTagAssociation', back_populates='tag') + tagged_library_dataset_collections = relationship( + 'LibraryDatasetCollectionTagAssociation', back_populates='tag') + tagged_tools = relationship('ToolTagAssociation', back_populates='tag') def __str__(self): return "Tag(id=%s, type=%i, parent_id=%s, name=%s)" % (self.id, self.type or -1, self.parent_id, self.name) @@ -6580,15 +8546,6 @@ class ItemTagAssociation(Dictifiable): super().__init_subclass__(**kwargs) cls.associated_item_names.append(cls.__name__.replace("TagAssociation", "")) - def __init__(self, id=None, user=None, item_id=None, tag_id=None, user_tname=None, value=None): - self.id = id - self.user = user - self.item_id = item_id - self.tag_id = tag_id - self.user_tname = user_tname - self.value = None - self.user_value = None - def copy(self, cls=None): if cls: new_ta = cls() @@ -6601,170 +8558,466 @@ class ItemTagAssociation(Dictifiable): return new_ta -class HistoryTagAssociation(ItemTagAssociation, RepresentById): - pass +class HistoryTagAssociation(Base, ItemTagAssociation, RepresentById): + __tablename__ = 'history_tag_association' + + id = Column(Integer, primary_key=True) + history_id = Column(Integer, ForeignKey('history.id'), index=True) + tag_id = Column(Integer, ForeignKey('tag.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + user_tname = Column(TrimmedString(255), index=True) + value = Column(TrimmedString(255), index=True) + user_value = Column(TrimmedString(255), index=True) + history = relationship('History', back_populates='tags') + tag = relationship('Tag', back_populates='tagged_histories') + user = relationship('User') -class HistoryDatasetAssociationTagAssociation(ItemTagAssociation, RepresentById): - pass +class HistoryDatasetAssociationTagAssociation(Base, ItemTagAssociation, RepresentById): + __tablename__ = 'history_dataset_association_tag_association' + + id = Column(Integer, primary_key=True) + history_dataset_association_id = Column(Integer, + ForeignKey('history_dataset_association.id'), index=True) + tag_id = Column(Integer, ForeignKey('tag.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + user_tname = Column(TrimmedString(255), index=True) + value = Column(TrimmedString(255), index=True) + user_value = Column(TrimmedString(255), index=True) + history_dataset_association = relationship('HistoryDatasetAssociation', back_populates='tags') + tag = relationship('Tag', back_populates='tagged_history_dataset_associations') + user = relationship('User') -class LibraryDatasetDatasetAssociationTagAssociation(ItemTagAssociation, RepresentById): - pass +class LibraryDatasetDatasetAssociationTagAssociation(Base, ItemTagAssociation, RepresentById): + __tablename__ = 'library_dataset_dataset_association_tag_association' + + id = Column(Integer, primary_key=True) + library_dataset_dataset_association_id = Column( + Integer, ForeignKey('library_dataset_dataset_association.id'), index=True) + tag_id = Column(Integer, ForeignKey('tag.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + user_tname = Column(TrimmedString(255), index=True) + value = Column(TrimmedString(255), index=True) + user_value = Column(TrimmedString(255), index=True) + library_dataset_dataset_association = relationship( + 'LibraryDatasetDatasetAssociation', back_populates='tags') + tag = relationship('Tag', back_populates='tagged_library_dataset_dataset_associations') + user = relationship('User') -class PageTagAssociation(ItemTagAssociation, RepresentById): - pass +class PageTagAssociation(Base, ItemTagAssociation, RepresentById): + __tablename__ = 'page_tag_association' + + id = Column(Integer, primary_key=True) + page_id = Column(Integer, ForeignKey('page.id'), index=True) + tag_id = Column(Integer, ForeignKey('tag.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + user_tname = Column(TrimmedString(255), index=True) + value = Column(TrimmedString(255), index=True) + user_value = Column(TrimmedString(255), index=True) + page = relationship('Page', back_populates='tags') + tag = relationship('Tag', back_populates='tagged_pages') + user = relationship('User') -class WorkflowStepTagAssociation(ItemTagAssociation, RepresentById): - pass +class WorkflowStepTagAssociation(Base, ItemTagAssociation, RepresentById): + __tablename__ = 'workflow_step_tag_association' + + id = Column(Integer, primary_key=True) + workflow_step_id = Column(Integer, ForeignKey('workflow_step.id'), index=True) + tag_id = Column(Integer, ForeignKey('tag.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + user_tname = Column(TrimmedString(255), index=True) + value = Column(TrimmedString(255), index=True) + user_value = Column(TrimmedString(255), index=True) + workflow_step = relationship('WorkflowStep', back_populates='tags') + tag = relationship('Tag', back_populates='tagged_workflow_steps') + user = relationship('User') -class StoredWorkflowTagAssociation(ItemTagAssociation, RepresentById): - pass +class StoredWorkflowTagAssociation(Base, ItemTagAssociation, RepresentById): + __tablename__ = 'stored_workflow_tag_association' + + id = Column(Integer, primary_key=True) + stored_workflow_id = Column(Integer, ForeignKey('stored_workflow.id'), index=True) + tag_id = Column(Integer, ForeignKey('tag.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + user_tname = Column(TrimmedString(255), index=True) + value = Column(TrimmedString(255), index=True) + user_value = Column(TrimmedString(255), index=True) + stored_workflow = relationship('StoredWorkflow', back_populates='tags') + tag = relationship('Tag', back_populates='tagged_stored_workflows') + user = relationship('User') -class VisualizationTagAssociation(ItemTagAssociation, RepresentById): - pass +class VisualizationTagAssociation(Base, ItemTagAssociation, RepresentById): + __tablename__ = 'visualization_tag_association' + + id = Column(Integer, primary_key=True) + visualization_id = Column(Integer, ForeignKey('visualization.id'), index=True) + tag_id = Column(Integer, ForeignKey('tag.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + user_tname = Column(TrimmedString(255), index=True) + value = Column(TrimmedString(255), index=True) + user_value = Column(TrimmedString(255), index=True) + visualization = relationship('Visualization', back_populates='tags') + tag = relationship('Tag', back_populates='tagged_visualizations') + user = relationship('User') -class HistoryDatasetCollectionTagAssociation(ItemTagAssociation, RepresentById): - pass +class HistoryDatasetCollectionTagAssociation(Base, ItemTagAssociation, RepresentById): + __tablename__ = 'history_dataset_collection_tag_association' + + id = Column(Integer, primary_key=True) + history_dataset_collection_id = Column( + Integer, ForeignKey('history_dataset_collection_association.id'), index=True) + tag_id = Column(Integer, ForeignKey('tag.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + user_tname = Column(TrimmedString(255), index=True) + value = Column(TrimmedString(255), index=True) + user_value = Column(TrimmedString(255), index=True) + dataset_collection = relationship('HistoryDatasetCollectionAssociation', back_populates='tags') + tag = relationship('Tag', back_populates='tagged_history_dataset_collections') + user = relationship('User') -class LibraryDatasetCollectionTagAssociation(ItemTagAssociation, RepresentById): - pass +class LibraryDatasetCollectionTagAssociation(Base, ItemTagAssociation, RepresentById): + __tablename__ = 'library_dataset_collection_tag_association' + + id = Column(Integer, primary_key=True) + library_dataset_collection_id = Column( + Integer, ForeignKey('library_dataset_collection_association.id'), index=True) + tag_id = Column(Integer, ForeignKey('tag.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + user_tname = Column(TrimmedString(255), index=True) + value = Column(TrimmedString(255), index=True) + user_value = Column(TrimmedString(255), index=True) + dataset_collection = relationship('LibraryDatasetCollectionAssociation', back_populates='tags') + tag = relationship('Tag', back_populates='tagged_library_dataset_collections') + user = relationship('User') -class ToolTagAssociation(ItemTagAssociation, RepresentById): - def __init__(self, id=None, user=None, tool_id=None, tag_id=None, user_tname=None, value=None): - self.id = id - self.user = user - self.tool_id = tool_id - self.tag_id = tag_id - self.user_tname = user_tname - self.value = None - self.user_value = None +class ToolTagAssociation(Base, ItemTagAssociation, RepresentById): + __tablename__ = 'tool_tag_association' + + id = Column(Integer, primary_key=True) + tool_id = Column(TrimmedString(255), index=True) + tag_id = Column(Integer, ForeignKey('tag.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + user_tname = Column(TrimmedString(255), index=True) + value = Column(TrimmedString(255), index=True) + user_value = Column(TrimmedString(255), index=True) + tag = relationship('Tag', back_populates='tagged_tools') + user = relationship('User') # Item annotation classes. -class HistoryAnnotationAssociation(RepresentById): - pass +class HistoryAnnotationAssociation(Base, RepresentById): + __tablename__ = 'history_annotation_association' + __table_args__ = ( + Index('ix_history_anno_assoc_annotation', 'annotation', mysql_length=200), + ) + + id = Column(Integer, primary_key=True) + history_id = Column(Integer, ForeignKey('history.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + annotation = Column(TEXT) + history = relationship('History', back_populates='annotations') + user = relationship('User') -class HistoryDatasetAssociationAnnotationAssociation(RepresentById): - pass +class HistoryDatasetAssociationAnnotationAssociation(Base, RepresentById): + __tablename__ = 'history_dataset_association_annotation_association' + __table_args__ = ( + Index('ix_history_dataset_anno_assoc_annotation', 'annotation', mysql_length=200), + ) + + id = Column(Integer, primary_key=True) + history_dataset_association_id = Column(Integer, + ForeignKey('history_dataset_association.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + annotation = Column(TEXT) + hda = relationship('HistoryDatasetAssociation', back_populates='annotations') + user = relationship('User') -class StoredWorkflowAnnotationAssociation(RepresentById): - pass +class StoredWorkflowAnnotationAssociation(Base, RepresentById): + __tablename__ = 'stored_workflow_annotation_association' + __table_args__ = ( + Index('ix_stored_workflow_ann_assoc_annotation', 'annotation', mysql_length=200), + ) + + id = Column(Integer, primary_key=True) + stored_workflow_id = Column(Integer, ForeignKey('stored_workflow.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + annotation = Column(TEXT) + stored_workflow = relationship('StoredWorkflow', back_populates='annotations') + user = relationship('User') -class WorkflowStepAnnotationAssociation(RepresentById): - pass +class WorkflowStepAnnotationAssociation(Base, RepresentById): + __tablename__ = 'workflow_step_annotation_association' + __table_args__ = ( + Index('ix_workflow_step_ann_assoc_annotation', 'annotation', mysql_length=200), + ) + + id = Column(Integer, primary_key=True) + workflow_step_id = Column(Integer, ForeignKey('workflow_step.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + annotation = Column(TEXT) + workflow_step = relationship('WorkflowStep', back_populates='annotations') + user = relationship('User') -class PageAnnotationAssociation(RepresentById): - pass +class PageAnnotationAssociation(Base, RepresentById): + __tablename__ = 'page_annotation_association' + __table_args__ = ( + Index('ix_page_annotation_association_annotation', 'annotation', mysql_length=200), + ) + + id = Column(Integer, primary_key=True) + page_id = Column(Integer, ForeignKey('page.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + annotation = Column(TEXT) + page = relationship('Page', back_populates='annotations') + user = relationship('User') -class VisualizationAnnotationAssociation(RepresentById): - pass +class VisualizationAnnotationAssociation(Base, RepresentById): + __tablename__ = 'visualization_annotation_association' + __table_args__ = ( + Index('ix_visualization_annotation_association_annotation', 'annotation', mysql_length=200), + ) + + id = Column(Integer, primary_key=True) + visualization_id = Column(Integer, ForeignKey('visualization.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + annotation = Column(TEXT) + visualization = relationship('Visualization', back_populates='annotations') + user = relationship('User') -class HistoryDatasetCollectionAssociationAnnotationAssociation(RepresentById): - pass +class HistoryDatasetCollectionAssociationAnnotationAssociation(Base, RepresentById): + __tablename__ = 'history_dataset_collection_annotation_association' + + id = Column(Integer, primary_key=True) + history_dataset_collection_id = Column( + Integer, ForeignKey('history_dataset_collection_association.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + annotation = Column(TEXT) + history_dataset_collection = relationship('HistoryDatasetCollectionAssociation', + back_populates='annotations') + user = relationship('User') -class LibraryDatasetCollectionAnnotationAssociation(RepresentById): - pass +class LibraryDatasetCollectionAnnotationAssociation(Base, RepresentById): + __tablename__ = 'library_dataset_collection_annotation_association' + + id = Column(Integer, primary_key=True) + library_dataset_collection_id = Column( + Integer, ForeignKey('library_dataset_collection_association.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + annotation = Column(TEXT) + dataset_collection = relationship('LibraryDatasetCollectionAssociation', + back_populates='annotations') + user = relationship('User') # Item rating classes. -class ItemRatingAssociation: - def __init__(self, id=None, user=None, item=None, rating=0): - self.id = id - self.user = user - self.item = item - self.rating = rating +class ItemRatingAssociation(Base): + __abstract__ = True - def set_item(self, item): + def __init__(self, user, item, rating=0): + self.user = user + self.rating = rating + self._set_item(item) + + def _set_item(self, item): """ Set association's item. """ + raise NotImplementedError() class HistoryRatingAssociation(ItemRatingAssociation, RepresentById): - def set_item(self, history): + __tablename__ = 'history_rating_association' + + id = Column(Integer, primary_key=True) + history_id = Column(Integer, ForeignKey('history.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + rating = Column(Integer, index=True) + history = relationship('History', back_populates='ratings') + user = relationship('User') + + def _set_item(self, history): self.history = history class HistoryDatasetAssociationRatingAssociation(ItemRatingAssociation, RepresentById): - def set_item(self, history_dataset_association): + __tablename__ = 'history_dataset_association_rating_association' + + id = Column(Integer, primary_key=True) + history_dataset_association_id = Column(Integer, + ForeignKey('history_dataset_association.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + rating = Column(Integer, index=True) + history_dataset_association = relationship('HistoryDatasetAssociation', back_populates='ratings') + user = relationship('User') + + def _set_item(self, history_dataset_association): self.history_dataset_association = history_dataset_association class StoredWorkflowRatingAssociation(ItemRatingAssociation, RepresentById): - def set_item(self, stored_workflow): + __tablename__ = 'stored_workflow_rating_association' + + id = Column(Integer, primary_key=True) + stored_workflow_id = Column(Integer, ForeignKey('stored_workflow.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + rating = Column(Integer, index=True) + stored_workflow = relationship('StoredWorkflow', back_populates='ratings') + user = relationship('User') + + def _set_item(self, stored_workflow): self.stored_workflow = stored_workflow class PageRatingAssociation(ItemRatingAssociation, RepresentById): - def set_item(self, page): + __tablename__ = 'page_rating_association' + + id = Column(Integer, primary_key=True) + page_id = Column(Integer, ForeignKey('page.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + rating = Column(Integer, index=True) + page = relationship('Page', back_populates='ratings') + user = relationship('User') + + def _set_item(self, page): self.page = page class VisualizationRatingAssociation(ItemRatingAssociation, RepresentById): - def set_item(self, visualization): + __tablename__ = 'visualization_rating_association' + + id = Column(Integer, primary_key=True) + visualization_id = Column(Integer, ForeignKey('visualization.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + rating = Column(Integer, index=True) + visualization = relationship('Visualization', back_populates='ratings') + user = relationship('User') + + def _set_item(self, visualization): self.visualization = visualization class HistoryDatasetCollectionRatingAssociation(ItemRatingAssociation, RepresentById): - def set_item(self, dataset_collection): + __tablename__ = 'history_dataset_collection_rating_association' + + id = Column(Integer, primary_key=True) + history_dataset_collection_id = Column( + Integer, ForeignKey('history_dataset_collection_association.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + rating = Column(Integer, index=True) + dataset_collection = relationship('HistoryDatasetCollectionAssociation', back_populates='ratings') + user = relationship('User') + + def _set_item(self, dataset_collection): self.dataset_collection = dataset_collection class LibraryDatasetCollectionRatingAssociation(ItemRatingAssociation, RepresentById): - def set_item(self, dataset_collection): + __tablename__ = 'library_dataset_collection_rating_association' + + id = Column(Integer, primary_key=True) + library_dataset_collection_id = Column( + Integer, ForeignKey('library_dataset_collection_association.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + rating = Column(Integer, index=True) + dataset_collection = relationship('LibraryDatasetCollectionAssociation', back_populates='ratings') + user = relationship('User') + + def _set_item(self, dataset_collection): self.dataset_collection = dataset_collection # Data manager classes. -class DataManagerHistoryAssociation(RepresentById): +class DataManagerHistoryAssociation(Base, RepresentById): + __tablename__ = 'data_manager_history_association' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, index=True, default=now, onupdate=now) + history_id = Column(Integer, ForeignKey('history.id'), index=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + history = relationship('History') + user = relationship('User', back_populates='data_manager_histories') + def __init__(self, id=None, history=None, user=None): self.id = id self.history = history self.user = user -class DataManagerJobAssociation(RepresentById): +class DataManagerJobAssociation(Base, RepresentById): + __tablename__ = 'data_manager_job_association' + __table_args__ = ( + Index('ix_data_manager_job_association_data_manager_id', 'data_manager_id', mysql_length=200), + ) + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + update_time = Column(DateTime, index=True, default=now, onupdate=now) + job_id = Column(Integer, ForeignKey("job.id"), index=True) + data_manager_id = Column(TEXT) + job = relationship('Job', back_populates='data_manager_association', uselist=False) + def __init__(self, id=None, job=None, data_manager_id=None): self.id = id self.job = job self.data_manager_id = data_manager_id -class UserPreference(RepresentById): +class UserPreference(Base, RepresentById): + __tablename__ = 'user_preference' + + id = Column(Integer, primary_key=True) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + name = Column(Unicode(255), index=True) + value = Column(Text) + user = relationship('User', back_populates='_preferences') + def __init__(self, name=None, value=None): self.name = name self.value = value -class UserAction(RepresentById): - def __init__(self, id=None, create_time=None, user_id=None, session_id=None, action=None, params=None, context=None): - self.id = id - self.create_time = create_time - self.user_id = user_id +class UserAction(Base, RepresentById): + __tablename__ = 'user_action' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + user_id = Column(Integer, ForeignKey("galaxy_user.id"), index=True) + session_id = Column(Integer, ForeignKey("galaxy_session.id"), index=True) + action = Column(Unicode(255)) + context = Column(Unicode(512)) + params = Column(Unicode(1024)) + user = relationship('User') + + def __init__(self, user=None, session_id=None, action=None, params=None, context=None): + self.user = user self.session_id = session_id self.action = action self.params = params self.context = context -class APIKeys(RepresentById): - def __init__(self, id=None, user_id=None, key=None): - self.id = id - self.user_id = user_id - self.key = key +class APIKeys(Base, RepresentById): + __tablename__ = 'api_keys' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + user_id = Column(Integer, ForeignKey('galaxy_user.id'), index=True) + key = Column(TrimmedString(32), index=True, unique=True) + user = relationship('User', back_populates='api_keys') def copy_list(lst, *args, **kwds): @@ -6788,3 +9041,405 @@ def _prepare_metadata_for_serialization(id_encoder, serialization_options, metad processed_metadata[name] = value return processed_metadata + + +# The following CleanupEvent* models could be defined as tables only; +# however making them models keeps things simple and consistent. + +class CleanupEvent(Base): + __tablename__ = 'cleanup_event' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + message = Column(TrimmedString(1024)) + + +class CleanupEventDatasetAssociation(Base): + __tablename__ = 'cleanup_event_dataset_association' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + cleanup_event_id = Column(Integer, ForeignKey('cleanup_event.id'), index=True, nullable=True) + dataset_id = Column(Integer, ForeignKey('dataset.id'), index=True) + + +class CleanupEventMetadataFileAssociation(Base): + __tablename__ = 'cleanup_event_metadata_file_association' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + cleanup_event_id = Column(Integer, ForeignKey('cleanup_event.id'), index=True, nullable=True) + metadata_file_id = Column(Integer, ForeignKey('metadata_file.id'), index=True) + + +class CleanupEventHistoryAssociation(Base): + __tablename__ = 'cleanup_event_history_association' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + cleanup_event_id = Column(Integer, ForeignKey('cleanup_event.id'), index=True, nullable=True) + history_id = Column(Integer, ForeignKey('history.id'), index=True) + + +class CleanupEventHistoryDatasetAssociationAssociation(Base): + __tablename__ = 'cleanup_event_hda_association' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + cleanup_event_id = Column(Integer, ForeignKey('cleanup_event.id'), index=True, nullable=True) + hda_id = Column(Integer, ForeignKey('history_dataset_association.id'), index=True) + + +class CleanupEventLibraryAssociation(Base): + __tablename__ = 'cleanup_event_library_association' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + cleanup_event_id = Column(Integer, ForeignKey('cleanup_event.id'), index=True, nullable=True) + library_id = Column(Integer, ForeignKey('library.id'), index=True) + + +class CleanupEventLibraryFolderAssociation(Base): + __tablename__ = 'cleanup_event_library_folder_association' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + cleanup_event_id = Column(Integer, ForeignKey('cleanup_event.id'), index=True, nullable=True) + library_folder_id = Column(Integer, ForeignKey('library_folder.id'), index=True) + + +class CleanupEventLibraryDatasetAssociation(Base): + __tablename__ = 'cleanup_event_library_dataset_association' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + cleanup_event_id = Column(Integer, ForeignKey('cleanup_event.id'), index=True, nullable=True) + library_dataset_id = Column(Integer, ForeignKey('library_dataset.id'), index=True) + + +class CleanupEventLibraryDatasetDatasetAssociationAssociation(Base): + __tablename__ = 'cleanup_event_ldda_association' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + cleanup_event_id = Column(Integer, ForeignKey('cleanup_event.id'), index=True, nullable=True) + ldda_id = Column(Integer, ForeignKey('library_dataset_dataset_association.id'), index=True) + + +class CleanupEventImplicitlyConvertedDatasetAssociationAssociation(Base): + __tablename__ = 'cleanup_event_icda_association' + + id = Column(Integer, primary_key=True) + create_time = Column(DateTime, default=now) + cleanup_event_id = Column(Integer, ForeignKey('cleanup_event.id'), index=True, nullable=True) + icda_id = Column(Integer, ForeignKey('implicitly_converted_dataset_association.id'), index=True) + + +# The following models (Dataset, HDA, LDDA) are mapped imperatively (for details see discussion in PR #12064) +# TLDR: there are issues ('metadata' property, Galaxy object wrapping) that need to be addressed separately +# before these models can be mapped declaratively. Keeping them in the mapping module breaks the auth package +# tests (which import model directly bypassing the mapping module); fixing that is possible by importing +# mapping into the test; however, having all models mapped in the same module is cleaner. + +Dataset.table = Table( + 'dataset', mapper_registry.metadata, + Column('id', Integer, primary_key=True), + Column('job_id', Integer, ForeignKey('job.id'), index=True, nullable=True), + Column('create_time', DateTime, default=now), + Column('update_time', DateTime, index=True, default=now, onupdate=now), + Column('state', TrimmedString(64), index=True), + Column('deleted', Boolean, index=True, default=False), + Column('purged', Boolean, index=True, default=False), + Column('purgable', Boolean, default=True), + Column('object_store_id', TrimmedString(255), index=True), + Column('external_filename', TEXT), + Column('_extra_files_path', TEXT), + Column('created_from_basename', TEXT), + Column('file_size', Numeric(15, 0)), + Column('total_size', Numeric(15, 0)), + Column('uuid', UUIDType())) + +HistoryDatasetAssociation.table = Table( + 'history_dataset_association', mapper_registry.metadata, + Column('id', Integer, primary_key=True), + Column('history_id', Integer, ForeignKey('history.id'), index=True), + Column('dataset_id', Integer, ForeignKey('dataset.id'), index=True), + Column('create_time', DateTime, default=now), + Column('update_time', DateTime, default=now, onupdate=now, index=True), + Column('state', TrimmedString(64), index=True, key='_state'), + Column('copied_from_history_dataset_association_id', Integer, + ForeignKey('history_dataset_association.id'), nullable=True), + Column('copied_from_library_dataset_dataset_association_id', Integer, + ForeignKey('library_dataset_dataset_association.id'), nullable=True), + Column('name', TrimmedString(255)), + Column('info', TrimmedString(255)), + Column('blurb', TrimmedString(255)), + Column('peek', TEXT, key='_peek'), + Column('tool_version', TEXT), + Column('extension', TrimmedString(64)), + Column('metadata', JSONType, key='_metadata'), + Column('parent_id', Integer, ForeignKey('history_dataset_association.id'), nullable=True), + Column('designation', TrimmedString(255)), + Column('deleted', Boolean, index=True, default=False), + Column('visible', Boolean), + Column('extended_metadata_id', Integer, ForeignKey('extended_metadata.id'), index=True), + Column('version', Integer, default=1, nullable=True, index=True), + Column('hid', Integer), + Column('purged', Boolean, index=True, default=False), + Column('validated_state', TrimmedString(64), default='unvalidated', nullable=False), + Column('validated_state_message', TEXT), + Column('hidden_beneath_collection_instance_id', + ForeignKey('history_dataset_collection_association.id'), nullable=True)) + +LibraryDatasetDatasetAssociation.table = Table( + 'library_dataset_dataset_association', mapper_registry.metadata, + Column('id', Integer, primary_key=True), + Column('library_dataset_id', Integer, ForeignKey('library_dataset.id'), index=True), + Column('dataset_id', Integer, ForeignKey('dataset.id'), index=True), + Column('create_time', DateTime, default=now), + Column('update_time', DateTime, default=now, onupdate=now, index=True), + Column('state', TrimmedString(64), index=True, key='_state'), + Column('copied_from_history_dataset_association_id', Integer, + ForeignKey('history_dataset_association.id', + use_alter=True, name='history_dataset_association_dataset_id_fkey'), + nullable=True), + Column('copied_from_library_dataset_dataset_association_id', Integer, + ForeignKey('library_dataset_dataset_association.id', + use_alter=True, name='library_dataset_dataset_association_id_fkey'), + nullable=True), + Column('name', TrimmedString(255), index=True), + Column('info', TrimmedString(255)), + Column('blurb', TrimmedString(255)), + Column('peek', TEXT, key='_peek'), + Column('tool_version', TEXT), + Column('extension', TrimmedString(64)), + Column('metadata', JSONType, key='_metadata'), + Column('parent_id', Integer, ForeignKey('library_dataset_dataset_association.id'), nullable=True), + Column('designation', TrimmedString(255)), + Column('deleted', Boolean, index=True, default=False), + Column('validated_state', TrimmedString(64), default='unvalidated', nullable=False), + Column('validated_state_message', TEXT), + Column('visible', Boolean), + Column('extended_metadata_id', Integer, ForeignKey('extended_metadata.id'), index=True), + Column('user_id', Integer, ForeignKey('galaxy_user.id'), index=True), + Column('message', TrimmedString(255))) + +mapper_registry.map_imperatively( + Dataset, + Dataset.table, + properties=dict( + actions=relationship(DatasetPermissions, back_populates='dataset'), + job=relationship(Job, primaryjoin=(Dataset.table.c.job_id == Job.id)), + active_history_associations=relationship(HistoryDatasetAssociation, + primaryjoin=( + (Dataset.table.c.id == HistoryDatasetAssociation.table.c.dataset_id) + & (HistoryDatasetAssociation.table.c.deleted == false()) + & (HistoryDatasetAssociation.table.c.purged == false())), + viewonly=True), + purged_history_associations=relationship(HistoryDatasetAssociation, + primaryjoin=( + (Dataset.table.c.id == HistoryDatasetAssociation.table.c.dataset_id) + & (HistoryDatasetAssociation.table.c.purged == true())), + viewonly=True), + active_library_associations=relationship(LibraryDatasetDatasetAssociation, + primaryjoin=( + (Dataset.table.c.id == LibraryDatasetDatasetAssociation.table.c.dataset_id) + & (LibraryDatasetDatasetAssociation.table.c.deleted == false())), + viewonly=True), + hashes=relationship(DatasetHash, back_populates='dataset'), + sources=relationship(DatasetSource, back_populates='dataset'), + job_export_history_archive=relationship(JobExportHistoryArchive, back_populates='dataset'), + genome_index_tool_data=relationship(GenomeIndexToolData, back_populates='dataset'), + history_associations=relationship(HistoryDatasetAssociation, back_populates='dataset'), + library_associations=relationship(LibraryDatasetDatasetAssociation, + primaryjoin=(LibraryDatasetDatasetAssociation.table.c.dataset_id == Dataset.table.c.id), + back_populates='dataset'), + ) +) + +mapper_registry.map_imperatively( + HistoryDatasetAssociation, + HistoryDatasetAssociation.table, + properties=dict( + dataset=relationship(Dataset, + primaryjoin=(Dataset.table.c.id == HistoryDatasetAssociation.table.c.dataset_id), + lazy=False, + back_populates='history_associations'), + copied_from_history_dataset_association=relationship(HistoryDatasetAssociation, + primaryjoin=(HistoryDatasetAssociation.table.c.copied_from_history_dataset_association_id + == HistoryDatasetAssociation.table.c.id), + remote_side=[HistoryDatasetAssociation.table.c.id], + uselist=False, + back_populates='copied_to_history_dataset_associations'), + copied_from_library_dataset_dataset_association=relationship(LibraryDatasetDatasetAssociation, + primaryjoin=(LibraryDatasetDatasetAssociation.table.c.id + == HistoryDatasetAssociation.table.c.copied_from_library_dataset_dataset_association_id), + back_populates='copied_to_history_dataset_associations'), + copied_to_history_dataset_associations=relationship(HistoryDatasetAssociation, + primaryjoin=(HistoryDatasetAssociation.table.c.copied_from_history_dataset_association_id + == HistoryDatasetAssociation.table.c.id), + back_populates='copied_from_history_dataset_association'), + copied_to_library_dataset_dataset_associations=relationship(LibraryDatasetDatasetAssociation, + primaryjoin=(HistoryDatasetAssociation.table.c.id + == LibraryDatasetDatasetAssociation.table.c.copied_from_history_dataset_association_id), + back_populates='copied_from_history_dataset_association'), + tags=relationship(HistoryDatasetAssociationTagAssociation, + order_by=HistoryDatasetAssociationTagAssociation.id, + back_populates='history_dataset_association'), + annotations=relationship(HistoryDatasetAssociationAnnotationAssociation, + order_by=HistoryDatasetAssociationAnnotationAssociation.id, + back_populates="hda"), + ratings=relationship(HistoryDatasetAssociationRatingAssociation, + order_by=HistoryDatasetAssociationRatingAssociation.id, + back_populates="history_dataset_association"), + extended_metadata=relationship(ExtendedMetadata, + primaryjoin=(HistoryDatasetAssociation.table.c.extended_metadata_id + == ExtendedMetadata.id)), + hidden_beneath_collection_instance=relationship(HistoryDatasetCollectionAssociation, + primaryjoin=(HistoryDatasetAssociation.table.c.hidden_beneath_collection_instance_id + == HistoryDatasetCollectionAssociation.id), + uselist=False, + back_populates="hidden_dataset_instances"), + _metadata=deferred(HistoryDatasetAssociation.table.c._metadata), + dependent_jobs=relationship(JobToInputDatasetAssociation, back_populates='dataset'), + creating_job_associations=relationship( + JobToOutputDatasetAssociation, back_populates='dataset'), + history=relationship(History, back_populates='datasets'), + implicitly_converted_datasets=relationship(ImplicitlyConvertedDatasetAssociation, + primaryjoin=(lambda: ImplicitlyConvertedDatasetAssociation.hda_parent_id + == HistoryDatasetAssociation.id), + back_populates='parent_hda'), + implicitly_converted_parent_datasets=relationship(ImplicitlyConvertedDatasetAssociation, + primaryjoin=(lambda: ImplicitlyConvertedDatasetAssociation.hda_id + == HistoryDatasetAssociation.id), + back_populates='dataset') + ) +) + +mapper_registry.map_imperatively( + LibraryDatasetDatasetAssociation, + LibraryDatasetDatasetAssociation.table, + properties=dict( + dataset=relationship(Dataset, + primaryjoin=(LibraryDatasetDatasetAssociation.table.c.dataset_id == Dataset.table.c.id), + back_populates='library_associations'), + library_dataset=relationship(LibraryDataset, + foreign_keys=LibraryDatasetDatasetAssociation.table.c.library_dataset_id), + user=relationship(User), + copied_from_library_dataset_dataset_association=relationship(LibraryDatasetDatasetAssociation, + primaryjoin=( + LibraryDatasetDatasetAssociation.table.c.copied_from_library_dataset_dataset_association_id + == LibraryDatasetDatasetAssociation.table.c.id), + remote_side=[LibraryDatasetDatasetAssociation.table.c.id], + uselist=False, + back_populates='copied_to_library_dataset_dataset_associations'), + copied_to_library_dataset_dataset_associations=relationship(LibraryDatasetDatasetAssociation, + primaryjoin=( + LibraryDatasetDatasetAssociation.table.c.copied_from_library_dataset_dataset_association_id + == LibraryDatasetDatasetAssociation.table.c.id), + back_populates='copied_from_library_dataset_dataset_association'), + copied_to_history_dataset_associations=relationship(HistoryDatasetAssociation, + primaryjoin=(LibraryDatasetDatasetAssociation.table.c.id + == HistoryDatasetAssociation.table.c.copied_from_library_dataset_dataset_association_id), + back_populates='copied_from_library_dataset_dataset_association'), + implicitly_converted_datasets=relationship(ImplicitlyConvertedDatasetAssociation, + primaryjoin=(ImplicitlyConvertedDatasetAssociation.ldda_parent_id + == LibraryDatasetDatasetAssociation.table.c.id), + back_populates='parent_ldda'), + tags=relationship(LibraryDatasetDatasetAssociationTagAssociation, + order_by=LibraryDatasetDatasetAssociationTagAssociation.id, + back_populates='library_dataset_dataset_association'), + extended_metadata=relationship(ExtendedMetadata, + primaryjoin=(LibraryDatasetDatasetAssociation.table.c.extended_metadata_id + == ExtendedMetadata.id) + ), + _metadata=deferred(LibraryDatasetDatasetAssociation.table.c._metadata), + actions=relationship( + LibraryDatasetDatasetAssociationPermissions, + back_populates='library_dataset_dataset_association'), + dependent_jobs=relationship( + JobToInputLibraryDatasetAssociation, back_populates='dataset'), + creating_job_associations=relationship( + JobToOutputLibraryDatasetAssociation, back_populates='dataset'), + implicitly_converted_parent_datasets=relationship(ImplicitlyConvertedDatasetAssociation, + primaryjoin=(lambda: ImplicitlyConvertedDatasetAssociation.ldda_id + == LibraryDatasetDatasetAssociation.id), + back_populates='dataset_ldda'), + copied_from_history_dataset_association=relationship(HistoryDatasetAssociation, + primaryjoin=(HistoryDatasetAssociation.table.c.id + == LibraryDatasetDatasetAssociation.table.c.copied_from_history_dataset_association_id), + back_populates='copied_to_library_dataset_dataset_associations'), + info_association=relationship(LibraryDatasetDatasetInfoAssociation, + primaryjoin=(lambda: + (LibraryDatasetDatasetInfoAssociation.library_dataset_dataset_association_id + == LibraryDatasetDatasetAssociation.id) + & (not_(LibraryDatasetDatasetInfoAssociation.deleted)) + ), + back_populates='library_dataset_dataset_association'), + ) +) + +# ---------------------------------------------------------------------------------------- +# The following statements must not precede the mapped models defined above. + +Job.any_output_dataset_collection_instances_deleted = column_property( + exists([HistoryDatasetCollectionAssociation.id], and_( + Job.id == JobToOutputDatasetCollectionAssociation.job_id, + HistoryDatasetCollectionAssociation.id == JobToOutputDatasetCollectionAssociation.dataset_collection_id, + HistoryDatasetCollectionAssociation.deleted == true()) + ) +) + +Job.any_output_dataset_deleted = column_property( + exists([HistoryDatasetAssociation], and_( + Job.id == JobToOutputDatasetAssociation.job_id, + HistoryDatasetAssociation.table.c.id == JobToOutputDatasetAssociation.dataset_id, + HistoryDatasetAssociation.table.c.deleted == true()) + ) +) + +History.average_rating = column_property( + select(func.avg(HistoryRatingAssociation.rating)).where( + HistoryRatingAssociation.history_id == History.id).scalar_subquery(), + deferred=True +) + +History.users_shared_with_count = column_property( + select(func.count(HistoryUserShareAssociation.id)).where( + History.id == HistoryUserShareAssociation.history_id).scalar_subquery(), + deferred=True +) + +Page.average_rating = column_property( + select(func.avg(PageRatingAssociation.rating)).where( + PageRatingAssociation.page_id == Page.id).scalar_subquery(), + deferred=True +) + +StoredWorkflow.average_rating = column_property( + select(func.avg(StoredWorkflowRatingAssociation.rating)).where( + StoredWorkflowRatingAssociation.stored_workflow_id == StoredWorkflow.id).scalar_subquery(), + deferred=True +) + +Visualization.average_rating = column_property( + select(func.avg(VisualizationRatingAssociation.rating)).where( + VisualizationRatingAssociation.visualization_id == Visualization.id).scalar_subquery(), + deferred=True +) + +Workflow.step_count = column_property( + select(func.count(WorkflowStep.id)).where(Workflow.id == WorkflowStep.workflow_id).scalar_subquery(), + deferred=True +) + +WorkflowInvocationStep.subworkflow_invocation_id = column_property( + select(WorkflowInvocationToSubworkflowInvocationAssociation.subworkflow_invocation_id).where(and_( + WorkflowInvocationToSubworkflowInvocationAssociation.workflow_invocation_id == WorkflowInvocationStep.workflow_invocation_id, + WorkflowInvocationToSubworkflowInvocationAssociation.workflow_step_id == WorkflowInvocationStep.workflow_step_id, + )).scalar_subquery(), +) + +# Set up proxy so that this syntax is possible: +# .preferences[pref_name] = pref_value +User.preferences = association_proxy('_preferences', 'value', creator=UserPreference) diff --git a/lib/galaxy/model/item_attrs.py b/lib/galaxy/model/item_attrs.py index 473b3c77ae9..fde16e71515 100644 --- a/lib/galaxy/model/item_attrs.py +++ b/lib/galaxy/model/item_attrs.py @@ -43,10 +43,7 @@ class UsesItemRatings: if not item_rating: # User has not yet rated item; create rating. item_rating_assoc_class = self._get_item_rating_assoc_class(item, webapp_model=webapp_model) - item_rating = item_rating_assoc_class() - item_rating.user = user - item_rating.set_item(item) - item_rating.rating = rating + item_rating = item_rating_assoc_class(user, item, rating) db_session.add(item_rating) db_session.flush() elif item_rating.rating != rating: diff --git a/lib/galaxy/model/mapping.py b/lib/galaxy/model/mapping.py index 9357e1800b9..d4b32513a99 100644 --- a/lib/galaxy/model/mapping.py +++ b/lib/galaxy/model/mapping.py @@ -1,6 +1,7 @@ """ -Details of how the data model objects are mapped onto the relational database -are encapsulated here. +This module no longer contains the mapping of data model classes to the +relational database. +The module will be revised during migration from SQLAlchemy Migrate to Alembic. """ import logging @@ -9,2694 +10,23 @@ from typing import Optional, Type from sqlalchemy import ( and_, - asc, - Boolean, - Column, - DateTime, - desc, - false, - ForeignKey, - func, - Index, - Integer, - not_, - Numeric, - PrimaryKeyConstraint, select, - String, Table, - TEXT, - Text, - true, - Unicode, - UniqueConstraint, - VARCHAR ) -from sqlalchemy.ext.associationproxy import association_proxy -from sqlalchemy.ext.orderinglist import ordering_list -from sqlalchemy.orm import backref, class_mapper, column_property, deferred, object_session, relation -from sqlalchemy.orm.collections import attribute_mapped_collection -from sqlalchemy.sql import exists +from sqlalchemy.orm import class_mapper, object_session, relation from galaxy import model from galaxy.model import mapper_registry from galaxy.model.base import SharedModelMapping -from galaxy.model.custom_types import ( - JSONType, - MutableJSONType, - TrimmedString, - UUIDType, -) from galaxy.model.migrate.triggers.update_audit_table import install as install_timestamp_triggers from galaxy.model.orm.engine_factory import build_engine from galaxy.model.orm.now import now from galaxy.model.security import GalaxyRBACAgent -from galaxy.model.view import HistoryDatasetCollectionJobStateSummary from galaxy.model.view.utils import install_views log = logging.getLogger(__name__) metadata = mapper_registry.metadata - -model.User.table = Table( - "galaxy_user", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("email", TrimmedString(255), index=True, nullable=False), - Column("username", TrimmedString(255), index=True, unique=True), - Column("password", TrimmedString(255), nullable=False), - Column("last_password_change", DateTime, default=now), - Column("external", Boolean, default=False), - Column("form_values_id", Integer, ForeignKey("form_values.id"), index=True), - Column("deleted", Boolean, index=True, default=False), - Column("purged", Boolean, index=True, default=False), - Column("disk_usage", Numeric(15, 0), index=True), - # Column("person_metadata", JSONType), # TODO: add persistent, configurable metadata rep for workflow creator - Column("active", Boolean, index=True, default=True, nullable=False), - Column("activation_token", TrimmedString(64), nullable=True, index=True)) - -model.UserAddress.table = Table( - "user_address", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("desc", TrimmedString(255)), - Column("name", TrimmedString(255), nullable=False), - Column("institution", TrimmedString(255)), - Column("address", TrimmedString(255), nullable=False), - Column("city", TrimmedString(255), nullable=False), - Column("state", TrimmedString(255), nullable=False), - Column("postal_code", TrimmedString(255), nullable=False), - Column("country", TrimmedString(255), nullable=False), - Column("phone", TrimmedString(255)), - Column("deleted", Boolean, index=True, default=False), - Column("purged", Boolean, index=True, default=False)) - -model.UserAuthnzToken.table = Table( - "oidc_user_authnz_tokens", metadata, - Column('id', Integer, primary_key=True), - Column('user_id', Integer, ForeignKey("galaxy_user.id"), index=True), - Column('uid', VARCHAR(255)), - Column('provider', VARCHAR(32)), - Column('extra_data', MutableJSONType, nullable=True), - Column('lifetime', Integer), - Column('assoc_type', VARCHAR(64))) - -model.CustosAuthnzToken.table = Table( - "custos_authnz_token", metadata, - Column('id', Integer, primary_key=True), - Column('user_id', Integer, ForeignKey("galaxy_user.id")), - Column('external_user_id', String(64)), - Column('provider', String(255)), - Column('access_token', Text), - Column('id_token', Text), - Column('refresh_token', Text), - Column("expiration_time", DateTime), - Column("refresh_expiration_time", DateTime), - UniqueConstraint("user_id", "external_user_id", "provider"), - UniqueConstraint("external_user_id", "provider"), -) - -model.CloudAuthz.table = Table( - "cloudauthz", metadata, - Column('id', Integer, primary_key=True), - Column('user_id', Integer, ForeignKey("galaxy_user.id"), index=True), - Column('provider', String(255)), - Column('config', MutableJSONType), - Column('authn_id', Integer, ForeignKey("oidc_user_authnz_tokens.id"), index=True), - Column('tokens', MutableJSONType), - Column('last_update', DateTime), - Column('last_activity', DateTime), - Column('description', TEXT), - Column('create_time', DateTime, default=now)) - -model.PasswordResetToken.table = Table( - "password_reset_token", metadata, - Column("token", String(32), primary_key=True, unique=True, index=True), - Column("expiration_time", DateTime), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True)) - - -model.DynamicTool.table = Table( - "dynamic_tool", metadata, - Column("id", Integer, primary_key=True), - Column("uuid", UUIDType()), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, index=True, default=now, onupdate=now), - Column("tool_id", Unicode(255)), - Column("tool_version", Unicode(255)), - Column("tool_format", Unicode(255)), - Column("tool_path", Unicode(255)), - Column("tool_directory", Unicode(255)), - Column("hidden", Boolean, default=True), - Column("active", Boolean, default=True), - Column("value", MutableJSONType), -) - - -model.History.table = Table( - "history", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, key="_update_time", index=True, default=now, onupdate=now), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("name", TrimmedString(255)), - Column("hid_counter", Integer, default=1), - Column("deleted", Boolean, index=True, default=False), - Column("purged", Boolean, index=True, default=False), - Column("importing", Boolean, index=True, default=False), - Column("genome_build", TrimmedString(40)), - Column("importable", Boolean, default=False), - Column("slug", TEXT), - Column("published", Boolean, index=True, default=False), - Index('ix_history_slug', 'slug', mysql_length=200), -) - -model.HistoryAudit.table = Table( - "history_audit", metadata, - Column("history_id", Integer, ForeignKey("history.id"), primary_key=True, nullable=False), - Column("update_time", DateTime, default=now, primary_key=True, nullable=False), - PrimaryKeyConstraint(sqlite_on_conflict='IGNORE') -) - -model.HistoryUserShareAssociation.table = Table( - "history_user_share_association", metadata, - Column("id", Integer, primary_key=True), - Column("history_id", Integer, ForeignKey("history.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True)) - -model.HistoryDatasetAssociation.table = Table( - "history_dataset_association", metadata, - Column("id", Integer, primary_key=True), - Column("history_id", Integer, ForeignKey("history.id"), index=True), - Column("dataset_id", Integer, ForeignKey("dataset.id"), index=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now, index=True), - Column("state", TrimmedString(64), index=True, key="_state"), - Column("copied_from_history_dataset_association_id", Integer, - ForeignKey("history_dataset_association.id"), nullable=True), - Column("copied_from_library_dataset_dataset_association_id", Integer, - ForeignKey("library_dataset_dataset_association.id"), nullable=True), - Column("name", TrimmedString(255)), - Column("info", TrimmedString(255)), - Column("blurb", TrimmedString(255)), - Column("peek", TEXT, key="_peek"), - Column("tool_version", TEXT), - Column("extension", TrimmedString(64)), - Column("metadata", JSONType, key="_metadata"), - Column("parent_id", Integer, ForeignKey("history_dataset_association.id"), nullable=True), - Column("designation", TrimmedString(255)), - Column("deleted", Boolean, index=True, default=False), - Column("visible", Boolean), - Column("extended_metadata_id", Integer, ForeignKey("extended_metadata.id"), index=True), - Column("version", Integer, default=1, nullable=True, index=True), - Column("hid", Integer), - Column("purged", Boolean, index=True, default=False), - Column("validated_state", TrimmedString(64), default='unvalidated', nullable=False), - Column("validated_state_message", TEXT), - Column("hidden_beneath_collection_instance_id", - ForeignKey("history_dataset_collection_association.id"), nullable=True)) - - -model.HistoryDatasetAssociationHistory.table = Table( - "history_dataset_association_history", metadata, - Column("id", Integer, primary_key=True), - Column("history_dataset_association_id", Integer, ForeignKey("history_dataset_association.id"), index=True), - Column("update_time", DateTime, default=now), - Column("version", Integer), - Column("name", TrimmedString(255)), - Column("extension", TrimmedString(64)), - Column("metadata", JSONType, key="_metadata"), - Column("extended_metadata_id", Integer, ForeignKey("extended_metadata.id"), index=True), -) - - -model.Dataset.table = Table( - "dataset", metadata, - Column("id", Integer, primary_key=True), - Column('job_id', Integer, ForeignKey('job.id'), index=True, nullable=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, index=True, default=now, onupdate=now), - Column("state", TrimmedString(64), index=True), - Column("deleted", Boolean, index=True, default=False), - Column("purged", Boolean, index=True, default=False), - Column("purgable", Boolean, default=True), - Column("object_store_id", TrimmedString(255), index=True), - Column("external_filename", TEXT), - Column("_extra_files_path", TEXT), - Column("created_from_basename", TEXT), - Column('file_size', Numeric(15, 0)), - Column('total_size', Numeric(15, 0)), - Column('uuid', UUIDType())) - -model.DatasetSource.table = Table( - "dataset_source", metadata, - Column("id", Integer, primary_key=True), - Column("dataset_id", Integer, ForeignKey("dataset.id"), index=True), - Column("source_uri", TEXT), - Column("extra_files_path", TEXT), - Column("transform", MutableJSONType) -) - -model.DatasetHash.table = Table( - "dataset_hash", metadata, - Column("id", Integer, primary_key=True), - Column("dataset_id", Integer, ForeignKey("dataset.id"), index=True), - Column("hash_function", TEXT), - Column("hash_value", TEXT), - Column("extra_files_path", TEXT), -) - -model.DatasetSourceHash.table = Table( - "dataset_source_hash", metadata, - Column("id", Integer, primary_key=True), - Column("dataset_source_id", Integer, ForeignKey("dataset_source.id"), index=True), - Column("hash_function", TEXT), - Column("hash_value", TEXT) -) - -# hda read access permission given by a user to a specific site (gen. for external display applications) -model.HistoryDatasetAssociationDisplayAtAuthorization.table = Table( - "history_dataset_association_display_at_authorization", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, index=True, default=now, onupdate=now), - Column("history_dataset_association_id", Integer, ForeignKey("history_dataset_association.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("site", TrimmedString(255))) - -model.HistoryDatasetAssociationSubset.table = Table( - "history_dataset_association_subset", metadata, - Column("id", Integer, primary_key=True), - Column("history_dataset_association_id", Integer, ForeignKey("history_dataset_association.id"), index=True), - Column("history_dataset_association_subset_id", Integer, ForeignKey("history_dataset_association.id"), index=True), - Column("location", Unicode(255), index=True)) - -model.ImplicitlyConvertedDatasetAssociation.table = Table( - "implicitly_converted_dataset_association", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("hda_id", Integer, ForeignKey("history_dataset_association.id"), index=True, nullable=True), - Column("ldda_id", Integer, ForeignKey("library_dataset_dataset_association.id"), index=True, nullable=True), - Column("hda_parent_id", Integer, ForeignKey("history_dataset_association.id"), index=True), - Column("ldda_parent_id", Integer, ForeignKey("library_dataset_dataset_association.id"), index=True), - Column("deleted", Boolean, index=True, default=False), - Column("metadata_safe", Boolean, index=True, default=True), - Column("type", TrimmedString(255))) - -model.UserGroupAssociation.table = Table( - "user_group_association", metadata, - Column("id", Integer, primary_key=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("group_id", Integer, ForeignKey("galaxy_group.id"), index=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now)) - -model.UserRoleAssociation.table = Table( - "user_role_association", metadata, - Column("id", Integer, primary_key=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("role_id", Integer, ForeignKey("role.id"), index=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now)) - -model.GroupRoleAssociation.table = Table( - "group_role_association", metadata, - Column("id", Integer, primary_key=True), - Column("group_id", Integer, ForeignKey("galaxy_group.id"), index=True), - Column("role_id", Integer, ForeignKey("role.id"), index=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now)) - -model.UserQuotaAssociation.table = Table( - "user_quota_association", metadata, - Column("id", Integer, primary_key=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("quota_id", Integer, ForeignKey("quota.id"), index=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now)) - -model.GroupQuotaAssociation.table = Table( - "group_quota_association", metadata, - Column("id", Integer, primary_key=True), - Column("group_id", Integer, ForeignKey("galaxy_group.id"), index=True), - Column("quota_id", Integer, ForeignKey("quota.id"), index=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now)) - -model.DefaultQuotaAssociation.table = Table( - "default_quota_association", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("type", String(32), index=True, unique=True), - Column("quota_id", Integer, ForeignKey("quota.id"), index=True)) - -model.DatasetPermissions.table = Table( - "dataset_permissions", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("action", TEXT), - Column("dataset_id", Integer, ForeignKey("dataset.id"), index=True), - Column("role_id", Integer, ForeignKey("role.id"), index=True)) - -model.LibraryPermissions.table = Table( - "library_permissions", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("action", TEXT), - Column("library_id", Integer, ForeignKey("library.id"), nullable=True, index=True), - Column("role_id", Integer, ForeignKey("role.id"), index=True)) - -model.LibraryFolderPermissions.table = Table( - "library_folder_permissions", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("action", TEXT), - Column("library_folder_id", Integer, ForeignKey("library_folder.id"), nullable=True, index=True), - Column("role_id", Integer, ForeignKey("role.id"), index=True)) - -model.LibraryDatasetPermissions.table = Table( - "library_dataset_permissions", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("action", TEXT), - Column("library_dataset_id", Integer, ForeignKey("library_dataset.id"), nullable=True, index=True), - Column("role_id", Integer, ForeignKey("role.id"), index=True)) - -model.LibraryDatasetDatasetAssociationPermissions.table = Table( - "library_dataset_dataset_association_permissions", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("action", TEXT), - Column("library_dataset_dataset_association_id", Integer, - ForeignKey("library_dataset_dataset_association.id"), - nullable=True, index=True), - Column("role_id", Integer, ForeignKey("role.id"), index=True)) - -model.DefaultUserPermissions.table = Table( - "default_user_permissions", metadata, - Column("id", Integer, primary_key=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("action", TEXT), - Column("role_id", Integer, ForeignKey("role.id"), index=True)) - -model.DefaultHistoryPermissions.table = Table( - "default_history_permissions", metadata, - Column("id", Integer, primary_key=True), - Column("history_id", Integer, ForeignKey("history.id"), index=True), - Column("action", TEXT), - Column("role_id", Integer, ForeignKey("role.id"), index=True)) - -model.LibraryDataset.table = Table( - "library_dataset", metadata, - Column("id", Integer, primary_key=True), - # current version of dataset, if null, there is not a current version selected - Column("library_dataset_dataset_association_id", Integer, - ForeignKey("library_dataset_dataset_association.id", use_alter=True, name="library_dataset_dataset_association_id_fk"), - nullable=True, index=True), - Column("folder_id", Integer, ForeignKey("library_folder.id"), index=True), - # not currently being used, but for possible future use - Column("order_id", Integer), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - # when not None/null this will supercede display in library (but not when imported into user's history?) - Column("name", TrimmedString(255), key="_name", index=True), - # when not None/null this will supercede display in library (but not when imported into user's history?) - Column("info", TrimmedString(255), key="_info"), - Column("deleted", Boolean, index=True, default=False), - Column("purged", Boolean, index=True, default=False)) - -model.LibraryDatasetDatasetAssociation.table = Table( - "library_dataset_dataset_association", metadata, - Column("id", Integer, primary_key=True), - Column("library_dataset_id", Integer, ForeignKey("library_dataset.id"), index=True), - Column("dataset_id", Integer, ForeignKey("dataset.id"), index=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now, index=True), - Column("state", TrimmedString(64), index=True, key="_state"), - Column("copied_from_history_dataset_association_id", Integer, - ForeignKey("history_dataset_association.id", use_alter=True, name='history_dataset_association_dataset_id_fkey'), - nullable=True), - - Column("copied_from_library_dataset_dataset_association_id", Integer, - ForeignKey("library_dataset_dataset_association.id", use_alter=True, name='library_dataset_dataset_association_id_fkey'), - nullable=True), - - Column("name", TrimmedString(255), index=True), - Column("info", TrimmedString(255)), - Column("blurb", TrimmedString(255)), - Column("peek", TEXT, key="_peek"), - Column("tool_version", TEXT), - Column("extension", TrimmedString(64)), - Column("metadata", JSONType, key="_metadata"), - Column("parent_id", Integer, ForeignKey("library_dataset_dataset_association.id"), nullable=True), - Column("designation", TrimmedString(255)), - Column("deleted", Boolean, index=True, default=False), - Column("validated_state", TrimmedString(64), default='unvalidated', nullable=False), - Column("validated_state_message", TEXT), - Column("visible", Boolean), - Column("extended_metadata_id", Integer, ForeignKey("extended_metadata.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("message", TrimmedString(255))) - -model.ExtendedMetadata.table = Table( - "extended_metadata", metadata, - Column("id", Integer, primary_key=True), - Column("data", MutableJSONType)) - -model.ExtendedMetadataIndex.table = Table( - "extended_metadata_index", metadata, - Column("id", Integer, primary_key=True), - Column("extended_metadata_id", Integer, - ForeignKey("extended_metadata.id", onupdate="CASCADE", ondelete="CASCADE"), index=True), - Column("path", String(255)), - Column("value", TEXT)) - -model.Library.table = Table( - "library", metadata, - Column("id", Integer, primary_key=True), - Column("root_folder_id", Integer, ForeignKey("library_folder.id"), index=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("name", String(255), index=True), - Column("deleted", Boolean, index=True, default=False), - Column("purged", Boolean, index=True, default=False), - Column("description", TEXT), - Column("synopsis", TEXT)) - -model.LibraryFolder.table = Table( - "library_folder", metadata, - Column("id", Integer, primary_key=True), - Column("parent_id", Integer, ForeignKey("library_folder.id"), nullable=True, index=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("name", TEXT), - Column("description", TEXT), - Column("order_id", Integer), # not currently being used, but for possible future use - Column("item_count", Integer), - Column("deleted", Boolean, index=True, default=False), - Column("purged", Boolean, index=True, default=False), - Column("genome_build", TrimmedString(40)), - Index('ix_library_folder_name', 'name', mysql_length=200), -) - -model.LibraryInfoAssociation.table = Table( - "library_info_association", metadata, - Column("id", Integer, primary_key=True), - Column("library_id", Integer, ForeignKey("library.id"), index=True), - Column("form_definition_id", Integer, ForeignKey("form_definition.id"), index=True), - Column("form_values_id", Integer, ForeignKey("form_values.id"), index=True), - Column("inheritable", Boolean, index=True, default=False), - Column("deleted", Boolean, index=True, default=False)) - -model.LibraryFolderInfoAssociation.table = Table( - "library_folder_info_association", metadata, - Column("id", Integer, primary_key=True), - Column("library_folder_id", Integer, ForeignKey("library_folder.id"), nullable=True, index=True), - Column("form_definition_id", Integer, ForeignKey("form_definition.id"), index=True), - Column("form_values_id", Integer, ForeignKey("form_values.id"), index=True), - Column("inheritable", Boolean, index=True, default=False), - Column("deleted", Boolean, index=True, default=False)) - -model.LibraryDatasetDatasetInfoAssociation.table = Table( - "library_dataset_dataset_info_association", metadata, - Column("id", Integer, primary_key=True), - Column("library_dataset_dataset_association_id", Integer, - ForeignKey("library_dataset_dataset_association.id"), nullable=True, index=True), - Column("form_definition_id", Integer, ForeignKey("form_definition.id"), index=True), - Column("form_values_id", Integer, ForeignKey("form_values.id"), index=True), - Column("deleted", Boolean, index=True, default=False)) - -model.Job.table = Table( - "job", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now, index=True), - Column("history_id", Integer, ForeignKey("history.id"), index=True), - Column("library_folder_id", Integer, ForeignKey("library_folder.id"), index=True), - Column("tool_id", String(255)), - Column("tool_version", TEXT, default="1.0.0"), - Column("galaxy_version", String(64), default=None), - Column("dynamic_tool_id", Integer, ForeignKey("dynamic_tool.id"), index=True, nullable=True), - Column("state", String(64), index=True), - Column("info", TrimmedString(255)), - Column("copied_from_job_id", Integer, nullable=True), - Column("command_line", TEXT), - Column("dependencies", MutableJSONType, nullable=True), - Column("job_messages", MutableJSONType, nullable=True), - Column("param_filename", String(1024)), - Column("runner_name", String(255)), - Column("job_stdout", TEXT), - Column("job_stderr", TEXT), - Column("tool_stdout", TEXT), - Column("tool_stderr", TEXT), - Column("exit_code", Integer, nullable=True), - Column("traceback", TEXT), - Column("session_id", Integer, ForeignKey("galaxy_session.id"), index=True, nullable=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True, nullable=True), - Column("job_runner_name", String(255)), - Column("job_runner_external_id", String(255), index=True), - Column("destination_id", String(255), nullable=True), - Column("destination_params", MutableJSONType, nullable=True), - Column("object_store_id", TrimmedString(255), index=True), - Column("imported", Boolean, default=False, index=True), - Column("params", TrimmedString(255), index=True), - Column("handler", TrimmedString(255), index=True)) - -model.JobStateHistory.table = Table( - "job_state_history", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("state", String(64), index=True), - Column("info", TrimmedString(255))) - -model.JobParameter.table = Table( - "job_parameter", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("name", String(255)), - Column("value", TEXT)) - -model.JobToInputDatasetAssociation.table = Table( - "job_to_input_dataset", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("dataset_id", Integer, ForeignKey("history_dataset_association.id"), index=True), - Column("dataset_version", Integer), - Column("name", String(255))) - -model.JobToOutputDatasetAssociation.table = Table( - "job_to_output_dataset", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("dataset_id", Integer, ForeignKey("history_dataset_association.id"), index=True), - Column("name", String(255))) - -model.JobToInputDatasetCollectionAssociation.table = Table( - "job_to_input_dataset_collection", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("dataset_collection_id", Integer, ForeignKey("history_dataset_collection_association.id"), index=True), - Column("name", Unicode(255))) - -model.JobToInputDatasetCollectionElementAssociation.table = Table( - "job_to_input_dataset_collection_element", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("dataset_collection_element_id", Integer, ForeignKey("dataset_collection_element.id"), index=True), - Column("name", Unicode(255))) - -model.JobToImplicitOutputDatasetCollectionAssociation.table = Table( - "job_to_implicit_output_dataset_collection", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("dataset_collection_id", Integer, ForeignKey("dataset_collection.id"), index=True), - Column("name", Unicode(255))) - -model.JobToOutputDatasetCollectionAssociation.table = Table( - "job_to_output_dataset_collection", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("dataset_collection_id", Integer, ForeignKey("history_dataset_collection_association.id"), index=True), - Column("name", Unicode(255))) - -model.JobToInputLibraryDatasetAssociation.table = Table( - "job_to_input_library_dataset", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("ldda_id", Integer, ForeignKey("library_dataset_dataset_association.id"), index=True), - Column("name", String(255))) - -model.JobToOutputLibraryDatasetAssociation.table = Table( - "job_to_output_library_dataset", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("ldda_id", Integer, ForeignKey("library_dataset_dataset_association.id"), index=True), - Column("name", String(255))) - -model.ImplicitlyCreatedDatasetCollectionInput.table = Table( - "implicitly_created_dataset_collection_inputs", metadata, - Column("id", Integer, primary_key=True), - Column("dataset_collection_id", Integer, - ForeignKey("history_dataset_collection_association.id"), index=True), - Column("input_dataset_collection_id", Integer, - ForeignKey("history_dataset_collection_association.id"), index=True), - Column("name", Unicode(255))) - -model.ImplicitCollectionJobs.table = Table( - "implicit_collection_jobs", metadata, - Column("id", Integer, primary_key=True), - Column("populated_state", TrimmedString(64), default='new', nullable=False), -) - -model.ImplicitCollectionJobsJobAssociation.table = Table( - "implicit_collection_jobs_job_association", metadata, - Column("id", Integer, primary_key=True), - Column("implicit_collection_jobs_id", Integer, ForeignKey("implicit_collection_jobs.id"), index=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), # Consider making this nullable... - Column("order_index", Integer, nullable=False), -) - -model.JobExternalOutputMetadata.table = Table( - "job_external_output_metadata", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("history_dataset_association_id", Integer, - ForeignKey("history_dataset_association.id"), index=True, nullable=True), - Column("library_dataset_dataset_association_id", Integer, - ForeignKey("library_dataset_dataset_association.id"), index=True, nullable=True), - Column("is_valid", Boolean, default=True), - Column("filename_in", String(255)), - Column("filename_out", String(255)), - Column("filename_results_code", String(255)), - Column("filename_kwds", String(255)), - Column("filename_override_metadata", String(255)), - Column("job_runner_external_pid", String(255))) - -model.JobExportHistoryArchive.table = Table( - "job_export_history_archive", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("history_id", Integer, ForeignKey("history.id"), index=True), - Column("dataset_id", Integer, ForeignKey("dataset.id"), index=True), - Column("compressed", Boolean, index=True, default=False), - Column("history_attrs_filename", TEXT)) - -model.JobImportHistoryArchive.table = Table( - "job_import_history_archive", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("history_id", Integer, ForeignKey("history.id"), index=True), - Column("archive_dir", TEXT)) - -model.JobMetricText.table = Table( - "job_metric_text", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("plugin", Unicode(255)), - Column("metric_name", Unicode(255)), - Column("metric_value", Unicode(model.JOB_METRIC_MAX_LENGTH))) - -model.TaskMetricText.table = Table( - "task_metric_text", metadata, - Column("id", Integer, primary_key=True), - Column("task_id", Integer, ForeignKey("task.id"), index=True), - Column("plugin", Unicode(255)), - Column("metric_name", Unicode(255)), - Column("metric_value", Unicode(model.JOB_METRIC_MAX_LENGTH))) - -model.JobMetricNumeric.table = Table( - "job_metric_numeric", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("plugin", Unicode(255)), - Column("metric_name", Unicode(255)), - Column("metric_value", Numeric(model.JOB_METRIC_PRECISION, model.JOB_METRIC_SCALE))) - -model.TaskMetricNumeric.table = Table( - "task_metric_numeric", metadata, - Column("id", Integer, primary_key=True), - Column("task_id", Integer, ForeignKey("task.id"), index=True), - Column("plugin", Unicode(255)), - Column("metric_name", Unicode(255)), - Column("metric_value", Numeric(model.JOB_METRIC_PRECISION, model.JOB_METRIC_SCALE))) - - -model.GenomeIndexToolData.table = Table( - "genome_index_tool_data", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("deferred_job_id", Integer, ForeignKey("deferred_job.id"), index=True), - Column("transfer_job_id", Integer, ForeignKey("transfer_job.id"), index=True), - Column("dataset_id", Integer, ForeignKey("dataset.id"), index=True), - Column("fasta_path", String(255)), - Column("created_time", DateTime, default=now), - Column("modified_time", DateTime, default=now, onupdate=now), - Column("indexer", String(64)), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True)) - -model.InteractiveToolEntryPoint.table = Table( - "interactivetool_entry_point", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("name", TEXT), - Column("token", TEXT), - Column("tool_port", Integer), - Column("host", TEXT), - Column("port", Integer), - Column("protocol", TEXT), - Column("entry_url", TEXT), - Column("requires_domain", Boolean, default=True), - Column("info", MutableJSONType, nullable=True), - Column("configured", Boolean, default=False), - Column("deleted", Boolean, default=False), - Column("created_time", DateTime, default=now), - Column("modified_time", DateTime, default=now, onupdate=now)) - -model.JobContainerAssociation.table = Table( - "job_container_association", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("container_type", TEXT), - Column("container_name", TEXT), - Column("container_info", MutableJSONType, nullable=True), - Column("created_time", DateTime, default=now), - Column("modified_time", DateTime, default=now, onupdate=now)) - -model.Task.table = Table( - "task", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("execution_time", DateTime), - Column("update_time", DateTime, default=now, onupdate=now), - Column("state", String(64), index=True), - Column("command_line", TEXT), - Column("param_filename", String(1024)), - Column("runner_name", String(255)), - Column("job_stdout", TEXT), # job_stdout makes sense here because it is short for job script standard out. - Column("job_stderr", TEXT), - Column("tool_stdout", TEXT), - Column("tool_stderr", TEXT), - Column("exit_code", Integer, nullable=True), - Column("job_messages", MutableJSONType, nullable=True), - Column("info", TrimmedString(255)), - Column("traceback", TEXT), - Column("job_id", Integer, ForeignKey("job.id"), index=True, nullable=False), - Column("working_directory", String(1024)), - Column("task_runner_name", String(255)), - Column("task_runner_external_id", String(255)), - Column("prepare_input_files_cmd", TEXT)) - -model.PostJobAction.table = Table( - "post_job_action", metadata, - Column("id", Integer, primary_key=True), - Column("workflow_step_id", Integer, ForeignKey("workflow_step.id"), index=True, nullable=True), - Column("action_type", String(255), nullable=False), - Column("output_name", String(255), nullable=True), - Column("action_arguments", MutableJSONType, nullable=True)) - -model.PostJobActionAssociation.table = Table( - "post_job_action_association", metadata, - Column("id", Integer, primary_key=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True, nullable=False), - Column("post_job_action_id", Integer, ForeignKey("post_job_action.id"), index=True, nullable=False)) - -model.DeferredJob.table = Table( - "deferred_job", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("state", String(64), index=True), - Column("plugin", String(128), index=True), - Column("params", MutableJSONType)) - -model.TransferJob.table = Table( - "transfer_job", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("state", String(64), index=True), - Column("path", String(1024)), - Column("info", TEXT), - Column("pid", Integer), - Column("socket", Integer), - Column("params", MutableJSONType)) - -model.DatasetCollection.table = Table( - "dataset_collection", metadata, - Column("id", Integer, primary_key=True), - Column("collection_type", Unicode(255), nullable=False), - Column("populated_state", TrimmedString(64), default='ok', nullable=False), - Column("populated_state_message", TEXT), - Column("element_count", Integer, nullable=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now)) - -model.HistoryDatasetCollectionAssociation.table = Table( - "history_dataset_collection_association", metadata, - Column("id", Integer, primary_key=True), - Column("collection_id", Integer, ForeignKey("dataset_collection.id"), index=True), - Column("history_id", Integer, ForeignKey("history.id"), index=True), - Column("name", TrimmedString(255)), - Column("hid", Integer), - Column("visible", Boolean), - Column("deleted", Boolean, default=False), - Column("copied_from_history_dataset_collection_association_id", Integer, - ForeignKey("history_dataset_collection_association.id"), nullable=True), - Column("implicit_output_name", Unicode(255), nullable=True), - Column("job_id", ForeignKey("job.id"), index=True, nullable=True), - Column("implicit_collection_jobs_id", ForeignKey("implicit_collection_jobs.id"), index=True, nullable=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now, index=True)) - -model.LibraryDatasetCollectionAssociation.table = Table( - "library_dataset_collection_association", metadata, - Column("id", Integer, primary_key=True), - Column("collection_id", Integer, ForeignKey("dataset_collection.id"), index=True), - Column("folder_id", Integer, ForeignKey("library_folder.id"), index=True), - Column("name", TrimmedString(255)), - Column("deleted", Boolean, default=False)) - -model.DatasetCollectionElement.table = Table( - "dataset_collection_element", metadata, - Column("id", Integer, primary_key=True), - # Parent collection id describing what collection this element belongs to. - Column("dataset_collection_id", Integer, ForeignKey("dataset_collection.id"), index=True, nullable=False), - # Child defined by this association - HDA, LDDA, or another dataset association... - Column("hda_id", Integer, ForeignKey("history_dataset_association.id"), index=True, nullable=True), - Column("ldda_id", Integer, ForeignKey("library_dataset_dataset_association.id"), index=True, nullable=True), - Column("child_collection_id", Integer, ForeignKey("dataset_collection.id"), index=True, nullable=True), - # Element index and identifier to define this parent-child relationship. - Column("element_index", Integer), - Column("element_identifier", Unicode(255), )) - -model.Event.table = Table( - "event", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("history_id", Integer, ForeignKey("history.id"), index=True, nullable=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True, nullable=True), - Column("message", TrimmedString(1024)), - Column("session_id", Integer, ForeignKey("galaxy_session.id"), index=True, nullable=True), - Column("tool_id", String(255))) - -model.GalaxySession.table = Table( - "galaxy_session", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True, nullable=True), - Column("remote_host", String(255)), - Column("remote_addr", String(255)), - Column("referer", TEXT), - Column("current_history_id", Integer, ForeignKey("history.id"), nullable=True), - # unique 128 bit random number coerced to a string - Column("session_key", TrimmedString(255), index=True, unique=True), - Column("is_valid", Boolean, default=False), - # saves a reference to the previous session so we have a way to chain them together - Column("prev_session_id", Integer), - Column("disk_usage", Numeric(15, 0), index=True), - Column("last_action", DateTime)) - -model.GalaxySessionToHistoryAssociation.table = Table( - "galaxy_session_to_history", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("session_id", Integer, ForeignKey("galaxy_session.id"), index=True), - Column("history_id", Integer, ForeignKey("history.id"), index=True)) - -model.StoredWorkflow.table = Table( - "stored_workflow", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now, index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True, nullable=False), - Column("latest_workflow_id", Integer, - ForeignKey("workflow.id", use_alter=True, name='stored_workflow_latest_workflow_id_fk'), index=True), - Column("name", TEXT), - Column("deleted", Boolean, default=False), - Column("hidden", Boolean, default=False), - Column("importable", Boolean, default=False), - Column("slug", TEXT), - Column("from_path", TEXT), - Column("published", Boolean, index=True, default=False), - Index('ix_stored_workflow_slug', 'slug', mysql_length=200), -) - -model.Workflow.table = Table( - "workflow", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - # workflows will belong to either a stored workflow or a parent/nesting workflow. - Column("stored_workflow_id", Integer, ForeignKey("stored_workflow.id"), index=True, nullable=True), - Column("parent_workflow_id", Integer, ForeignKey("workflow.id"), index=True, nullable=True), - Column("name", TEXT), - Column("has_cycles", Boolean), - Column("has_errors", Boolean), - Column("reports_config", MutableJSONType), - Column("creator_metadata", MutableJSONType), - Column("license", TEXT), - Column("uuid", UUIDType, nullable=True)) - -model.WorkflowStep.table = Table( - "workflow_step", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("workflow_id", Integer, ForeignKey("workflow.id"), index=True, nullable=False), - Column("subworkflow_id", Integer, ForeignKey("workflow.id"), index=True, nullable=True), - Column("dynamic_tool_id", Integer, ForeignKey("dynamic_tool.id"), index=True, nullable=True), - Column("type", String(64)), - Column("tool_id", TEXT), - Column("tool_version", TEXT), - Column("tool_inputs", JSONType), - Column("tool_errors", JSONType), - Column("position", MutableJSONType), - Column("config", JSONType), - Column("order_index", Integer), - Column("uuid", UUIDType), - # Column( "input_connections", JSONType ), - Column("label", Unicode(255))) - - -model.WorkflowStepInput.table = Table( - "workflow_step_input", metadata, - Column("id", Integer, primary_key=True), - Column("workflow_step_id", Integer, ForeignKey("workflow_step.id"), index=True), - Column("name", TEXT), - Column("merge_type", TEXT), - Column("scatter_type", TEXT), - Column("value_from", MutableJSONType), - Column("value_from_type", TEXT), - Column("default_value", MutableJSONType), - Column("default_value_set", Boolean, default=False), - Column("runtime_value", Boolean, default=False), - Index('ix_workflow_step_input_workflow_step_id_name_unique', "workflow_step_id", "name", unique=True, mysql_length={'name': 200}), -) - - -model.WorkflowRequestStepState.table = Table( - "workflow_request_step_states", metadata, - Column("id", Integer, primary_key=True), - Column("workflow_invocation_id", Integer, - ForeignKey("workflow_invocation.id", onupdate="CASCADE", ondelete="CASCADE")), - Column("workflow_step_id", Integer, ForeignKey("workflow_step.id")), - Column("value", MutableJSONType)) - -model.WorkflowRequestInputParameter.table = Table( - "workflow_request_input_parameters", metadata, - Column("id", Integer, primary_key=True), - Column("workflow_invocation_id", Integer, - ForeignKey("workflow_invocation.id", onupdate="CASCADE", ondelete="CASCADE")), - Column("name", Unicode(255)), - Column("value", TEXT), - Column("type", Unicode(255))) - -model.WorkflowRequestInputStepParameter.table = Table( - "workflow_request_input_step_parameter", metadata, - Column("id", Integer, primary_key=True), - Column("workflow_invocation_id", Integer, ForeignKey("workflow_invocation.id"), index=True), - Column("workflow_step_id", Integer, ForeignKey("workflow_step.id")), - Column("parameter_value", MutableJSONType), -) - -model.WorkflowRequestToInputDatasetAssociation.table = Table( - "workflow_request_to_input_dataset", metadata, - Column("id", Integer, primary_key=True), - Column("name", String(255)), - Column("workflow_invocation_id", Integer, ForeignKey("workflow_invocation.id"), index=True), - Column("workflow_step_id", Integer, ForeignKey("workflow_step.id")), - Column("dataset_id", Integer, ForeignKey("history_dataset_association.id"), index=True)) - -model.WorkflowRequestToInputDatasetCollectionAssociation.table = Table( - "workflow_request_to_input_collection_dataset", metadata, - Column("id", Integer, primary_key=True), - Column("name", String(255)), - Column("workflow_invocation_id", Integer, ForeignKey("workflow_invocation.id"), index=True), - Column("workflow_step_id", Integer, ForeignKey("workflow_step.id")), - Column("dataset_collection_id", Integer, ForeignKey("history_dataset_collection_association.id"), index=True)) - -model.WorkflowStepConnection.table = Table( - "workflow_step_connection", metadata, - Column("id", Integer, primary_key=True), - Column("output_step_id", Integer, ForeignKey("workflow_step.id"), index=True), - Column("input_step_input_id", Integer, ForeignKey("workflow_step_input.id"), index=True), - Column("output_name", TEXT), - Column("input_subworkflow_step_id", Integer, ForeignKey("workflow_step.id"), index=True), -) - -model.WorkflowOutput.table = Table( - "workflow_output", metadata, - Column("id", Integer, primary_key=True), - Column("workflow_step_id", Integer, ForeignKey("workflow_step.id"), index=True, nullable=False), - Column("output_name", String(255), nullable=True), - Column("label", Unicode(255)), - Column("uuid", UUIDType), -) - -model.WorkflowInvocation.table = Table( - "workflow_invocation", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now, index=True), - Column("workflow_id", Integer, ForeignKey("workflow.id"), index=True, nullable=False), - Column("state", TrimmedString(64), index=True), - Column("scheduler", TrimmedString(255), index=True), - Column("handler", TrimmedString(255), index=True), - Column('uuid', UUIDType()), - Column("history_id", Integer, ForeignKey("history.id"), index=True)) - -model.WorkflowInvocationStep.table = Table( - "workflow_invocation_step", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("workflow_invocation_id", Integer, ForeignKey("workflow_invocation.id"), index=True, nullable=False), - Column("workflow_step_id", Integer, ForeignKey("workflow_step.id"), index=True, nullable=False), - Column("state", TrimmedString(64), index=True), - Column("job_id", Integer, ForeignKey("job.id"), index=True, nullable=True), - Column("implicit_collection_jobs_id", Integer, ForeignKey("implicit_collection_jobs.id"), index=True, nullable=True), - Column("action", MutableJSONType, nullable=True)) - -model.WorkflowInvocationOutputDatasetAssociation.table = Table( - "workflow_invocation_output_dataset_association", metadata, - Column("id", Integer, primary_key=True), - Column("workflow_invocation_id", Integer, ForeignKey("workflow_invocation.id"), index=True), - Column("workflow_step_id", Integer, ForeignKey("workflow_step.id"), index=True), - Column("dataset_id", Integer, ForeignKey("history_dataset_association.id"), index=True), - Column("workflow_output_id", Integer, ForeignKey("workflow_output.id"), index=True), -) - -model.WorkflowInvocationOutputDatasetCollectionAssociation.table = Table( - "workflow_invocation_output_dataset_collection_association", metadata, - Column("id", Integer, primary_key=True), - Column("workflow_invocation_id", Integer, ForeignKey("workflow_invocation.id", name='fk_wiodca_wii'), index=True), - Column("workflow_step_id", Integer, ForeignKey("workflow_step.id", name='fk_wiodca_wsi'), index=True), - Column("dataset_collection_id", Integer, ForeignKey("history_dataset_collection_association.id", name='fk_wiodca_dci'), index=True), - Column("workflow_output_id", Integer, ForeignKey("workflow_output.id", name='fk_wiodca_woi'), index=True), -) - -model.WorkflowInvocationOutputValue.table = Table( - "workflow_invocation_output_value", metadata, - Column("id", Integer, primary_key=True), - Column("workflow_invocation_id", Integer, ForeignKey("workflow_invocation.id"), index=True), - Column("workflow_step_id", Integer, ForeignKey("workflow_step.id")), - Column("workflow_output_id", Integer, ForeignKey("workflow_output.id"), index=True), - Column("value", MutableJSONType), -) - -model.WorkflowInvocationStepOutputDatasetAssociation.table = Table( - "workflow_invocation_step_output_dataset_association", metadata, - Column("id", Integer, primary_key=True), - Column("workflow_invocation_step_id", Integer, ForeignKey("workflow_invocation_step.id"), index=True), - Column("dataset_id", Integer, ForeignKey("history_dataset_association.id"), index=True), - Column("output_name", String(255), nullable=True), -) - -model.WorkflowInvocationStepOutputDatasetCollectionAssociation.table = Table( - "workflow_invocation_step_output_dataset_collection_association", metadata, - Column("id", Integer, primary_key=True), - Column("workflow_invocation_step_id", Integer, ForeignKey("workflow_invocation_step.id", name='fk_wisodca_wisi'), index=True), - Column("workflow_step_id", Integer, ForeignKey("workflow_step.id", name='fk_wisodca_wsi'), index=True), - Column("dataset_collection_id", Integer, ForeignKey("history_dataset_collection_association.id", name='fk_wisodca_dci'), index=True), - Column("output_name", String(255), nullable=True), -) - -model.WorkflowInvocationToSubworkflowInvocationAssociation.table = Table( - "workflow_invocation_to_subworkflow_invocation_association", metadata, - Column("id", Integer, primary_key=True), - Column("workflow_invocation_id", Integer, ForeignKey("workflow_invocation.id", name='fk_wfi_swi_wfi'), index=True), - Column("subworkflow_invocation_id", Integer, ForeignKey("workflow_invocation.id", name='fk_wfi_swi_swi'), index=True), - Column("workflow_step_id", Integer, ForeignKey("workflow_step.id", name='fk_wfi_swi_ws')), -) - -model.StoredWorkflowUserShareAssociation.table = Table( - "stored_workflow_user_share_connection", metadata, - Column("id", Integer, primary_key=True), - Column("stored_workflow_id", Integer, ForeignKey("stored_workflow.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True)) - -model.StoredWorkflowMenuEntry.table = Table( - "stored_workflow_menu_entry", metadata, - Column("id", Integer, primary_key=True), - Column("stored_workflow_id", Integer, ForeignKey("stored_workflow.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("order_index", Integer)) - -model.MetadataFile.table = Table( - "metadata_file", metadata, - Column("id", Integer, primary_key=True), - Column("name", TEXT), - Column("hda_id", Integer, ForeignKey("history_dataset_association.id"), index=True, nullable=True), - Column("lda_id", Integer, ForeignKey("library_dataset_dataset_association.id"), index=True, nullable=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, index=True, default=now, onupdate=now), - Column("object_store_id", TrimmedString(255), index=True), - Column("uuid", UUIDType(), index=True), - Column("deleted", Boolean, index=True, default=False), - Column("purged", Boolean, index=True, default=False)) - -model.FormDefinitionCurrent.table = Table( - "form_definition_current", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("latest_form_id", Integer, ForeignKey("form_definition.id"), index=True), - Column("deleted", Boolean, index=True, default=False)) - -model.FormDefinition.table = Table( - "form_definition", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("name", TrimmedString(255), nullable=False), - Column("desc", TEXT), - Column("form_definition_current_id", Integer, ForeignKey("form_definition_current.id", use_alter=True), index=True, nullable=False), - Column("fields", MutableJSONType), - Column("type", TrimmedString(255), index=True), - Column("layout", MutableJSONType)) - -model.FormValues.table = Table( - "form_values", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("form_definition_id", Integer, ForeignKey("form_definition.id"), index=True), - Column("content", MutableJSONType)) - -model.Page.table = Table( - "page", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True, nullable=False), - Column("latest_revision_id", Integer, - ForeignKey("page_revision.id", use_alter=True, name='page_latest_revision_id_fk'), index=True), - Column("title", TEXT), - Column("deleted", Boolean, index=True, default=False), - Column("importable", Boolean, index=True, default=False), - Column("slug", TEXT), - Column("published", Boolean, index=True, default=False), - Index('ix_page_slug', 'slug', mysql_length=200), -) - -model.PageRevision.table = Table( - "page_revision", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("page_id", Integer, ForeignKey("page.id"), index=True, nullable=False), - Column("title", TEXT), - Column("content", TEXT), - Column("content_format", TrimmedString(32))) - -model.PageUserShareAssociation.table = Table( - "page_user_share_association", metadata, - Column("id", Integer, primary_key=True), - Column("page_id", Integer, ForeignKey("page.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True)) - -model.Visualization.table = Table( - "visualization", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True, nullable=False), - Column("latest_revision_id", Integer, - ForeignKey("visualization_revision.id", use_alter=True, name='visualization_latest_revision_id_fk'), index=True), - Column("title", TEXT), - Column("type", TEXT), - Column("dbkey", TEXT), - Column("deleted", Boolean, default=False, index=True), - Column("importable", Boolean, default=False, index=True), - Column("slug", TEXT), - Column("published", Boolean, default=False, index=True), - Index('ix_visualization_dbkey', 'dbkey', mysql_length=200), - Index('ix_visualization_slug', 'slug', mysql_length=200), -) - -model.VisualizationRevision.table = Table( - "visualization_revision", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, default=now, onupdate=now), - Column("visualization_id", Integer, ForeignKey("visualization.id"), index=True, nullable=False), - Column("title", TEXT), - Column("dbkey", TEXT), - Column("config", MutableJSONType), - Index('ix_visualization_revision_dbkey', 'dbkey', mysql_length=200), -) - -model.VisualizationUserShareAssociation.table = Table( - "visualization_user_share_association", metadata, - Column("id", Integer, primary_key=True), - Column("visualization_id", Integer, ForeignKey("visualization.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True)) - -# Data Manager tables -model.DataManagerHistoryAssociation.table = Table( - "data_manager_history_association", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, index=True, default=now, onupdate=now), - Column("history_id", Integer, ForeignKey("history.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True)) - -model.DataManagerJobAssociation.table = Table( - "data_manager_job_association", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("update_time", DateTime, index=True, default=now, onupdate=now), - Column("job_id", Integer, ForeignKey("job.id"), index=True), - Column("data_manager_id", TEXT), - Index('ix_data_manager_job_association_data_manager_id', 'data_manager_id', mysql_length=200), -) - -# Tagging tables. -model.Tag.table = Table( - "tag", metadata, - Column("id", Integer, primary_key=True), - Column("type", Integer), - Column("parent_id", Integer, ForeignKey("tag.id")), - Column("name", TrimmedString(255)), - UniqueConstraint("name")) - -model.HistoryTagAssociation.table = Table( - "history_tag_association", metadata, - Column("id", Integer, primary_key=True), - Column("history_id", Integer, ForeignKey("history.id"), index=True), - Column("tag_id", Integer, ForeignKey("tag.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("user_tname", TrimmedString(255), index=True), - Column("value", TrimmedString(255), index=True), - Column("user_value", TrimmedString(255), index=True)) - -model.HistoryDatasetAssociationTagAssociation.table = Table( - "history_dataset_association_tag_association", metadata, - Column("id", Integer, primary_key=True), - Column("history_dataset_association_id", Integer, ForeignKey("history_dataset_association.id"), index=True), - Column("tag_id", Integer, ForeignKey("tag.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("user_tname", TrimmedString(255), index=True), - Column("value", TrimmedString(255), index=True), - Column("user_value", TrimmedString(255), index=True)) - -model.LibraryDatasetDatasetAssociationTagAssociation.table = Table( - "library_dataset_dataset_association_tag_association", metadata, - Column("id", Integer, primary_key=True), - Column("library_dataset_dataset_association_id", Integer, ForeignKey("library_dataset_dataset_association.id"), index=True), - Column("tag_id", Integer, ForeignKey("tag.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("user_tname", TrimmedString(255), index=True), - Column("value", TrimmedString(255), index=True), - Column("user_value", TrimmedString(255), index=True)) - -model.StoredWorkflowTagAssociation.table = Table( - "stored_workflow_tag_association", metadata, - Column("id", Integer, primary_key=True), - Column("stored_workflow_id", Integer, ForeignKey("stored_workflow.id"), index=True), - Column("tag_id", Integer, ForeignKey("tag.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("user_tname", Unicode(255), index=True), - Column("value", Unicode(255), index=True), - Column("user_value", Unicode(255), index=True)) - -model.PageTagAssociation.table = Table( - "page_tag_association", metadata, - Column("id", Integer, primary_key=True), - Column("page_id", Integer, ForeignKey("page.id"), index=True), - Column("tag_id", Integer, ForeignKey("tag.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("user_tname", TrimmedString(255), index=True), - Column("value", TrimmedString(255), index=True), - Column("user_value", TrimmedString(255), index=True)) - -model.WorkflowStepTagAssociation.table = Table( - "workflow_step_tag_association", metadata, - Column("id", Integer, primary_key=True), - Column("workflow_step_id", Integer, ForeignKey("workflow_step.id"), index=True), - Column("tag_id", Integer, ForeignKey("tag.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("user_tname", Unicode(255), index=True), - Column("value", Unicode(255), index=True), - Column("user_value", Unicode(255), index=True)) - -model.VisualizationTagAssociation.table = Table( - "visualization_tag_association", metadata, - Column("id", Integer, primary_key=True), - Column("visualization_id", Integer, ForeignKey("visualization.id"), index=True), - Column("tag_id", Integer, ForeignKey("tag.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("user_tname", TrimmedString(255), index=True), - Column("value", TrimmedString(255), index=True), - Column("user_value", TrimmedString(255), index=True)) - -model.HistoryDatasetCollectionTagAssociation.table = Table( - "history_dataset_collection_tag_association", metadata, - Column("id", Integer, primary_key=True), - Column("history_dataset_collection_id", Integer, - ForeignKey("history_dataset_collection_association.id"), index=True), - Column("tag_id", Integer, ForeignKey("tag.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("user_tname", TrimmedString(255), index=True), - Column("value", TrimmedString(255), index=True), - Column("user_value", TrimmedString(255), index=True)) - -model.LibraryDatasetCollectionTagAssociation.table = Table( - "library_dataset_collection_tag_association", metadata, - Column("id", Integer, primary_key=True), - Column("library_dataset_collection_id", Integer, - ForeignKey("library_dataset_collection_association.id"), index=True), - Column("tag_id", Integer, ForeignKey("tag.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("user_tname", TrimmedString(255), index=True), - Column("value", TrimmedString(255), index=True), - Column("user_value", TrimmedString(255), index=True)) - -model.ToolTagAssociation.table = Table( - "tool_tag_association", metadata, - Column("id", Integer, primary_key=True), - Column("tool_id", TrimmedString(255), index=True), - Column("tag_id", Integer, ForeignKey("tag.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("user_tname", TrimmedString(255), index=True), - Column("value", TrimmedString(255), index=True), - Column("user_value", TrimmedString(255), index=True)) - -# Annotation tables. - -model.HistoryAnnotationAssociation.table = Table( - "history_annotation_association", metadata, - Column("id", Integer, primary_key=True), - Column("history_id", Integer, ForeignKey("history.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("annotation", TEXT), - Index('ix_history_anno_assoc_annotation', 'annotation', mysql_length=200), -) - -model.HistoryDatasetAssociationAnnotationAssociation.table = Table( - "history_dataset_association_annotation_association", metadata, - Column("id", Integer, primary_key=True), - Column("history_dataset_association_id", Integer, - ForeignKey("history_dataset_association.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("annotation", TEXT), - Index('ix_history_dataset_anno_assoc_annotation', 'annotation', mysql_length=200), -) - -model.StoredWorkflowAnnotationAssociation.table = Table( - "stored_workflow_annotation_association", metadata, - Column("id", Integer, primary_key=True), - Column("stored_workflow_id", Integer, ForeignKey("stored_workflow.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("annotation", TEXT), - Index('ix_stored_workflow_ann_assoc_annotation', 'annotation', mysql_length=200), -) - -model.WorkflowStepAnnotationAssociation.table = Table( - "workflow_step_annotation_association", metadata, - Column("id", Integer, primary_key=True), - Column("workflow_step_id", Integer, ForeignKey("workflow_step.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("annotation", TEXT), - Index('ix_workflow_step_ann_assoc_annotation', 'annotation', mysql_length=200), -) - -model.PageAnnotationAssociation.table = Table( - "page_annotation_association", metadata, - Column("id", Integer, primary_key=True), - Column("page_id", Integer, ForeignKey("page.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("annotation", TEXT), - Index('ix_page_annotation_association_annotation', 'annotation', mysql_length=200), -) - -model.VisualizationAnnotationAssociation.table = Table( - "visualization_annotation_association", metadata, - Column("id", Integer, primary_key=True), - Column("visualization_id", Integer, ForeignKey("visualization.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("annotation", TEXT), - Index('ix_visualization_annotation_association_annotation', 'annotation', mysql_length=200), -) - -model.HistoryDatasetCollectionAssociationAnnotationAssociation.table = Table( - "history_dataset_collection_annotation_association", metadata, - Column("id", Integer, primary_key=True), - Column("history_dataset_collection_id", Integer, - ForeignKey("history_dataset_collection_association.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("annotation", TEXT), -) - -model.LibraryDatasetCollectionAnnotationAssociation.table = Table( - "library_dataset_collection_annotation_association", metadata, - Column("id", Integer, primary_key=True), - Column("library_dataset_collection_id", Integer, - ForeignKey("library_dataset_collection_association.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("annotation", TEXT), -) - -# Ratings tables. -model.HistoryRatingAssociation.table = Table("history_rating_association", metadata, - Column("id", Integer, primary_key=True), - Column("history_id", Integer, ForeignKey("history.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("rating", Integer, index=True)) - -model.HistoryDatasetAssociationRatingAssociation.table = Table( - "history_dataset_association_rating_association", metadata, - Column("id", Integer, primary_key=True), - Column("history_dataset_association_id", Integer, - ForeignKey("history_dataset_association.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("rating", Integer, index=True)) - -model.StoredWorkflowRatingAssociation.table = Table( - "stored_workflow_rating_association", metadata, - Column("id", Integer, primary_key=True), - Column("stored_workflow_id", Integer, ForeignKey("stored_workflow.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("rating", Integer, index=True)) - -model.PageRatingAssociation.table = Table( - "page_rating_association", metadata, - Column("id", Integer, primary_key=True), - Column("page_id", Integer, ForeignKey("page.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("rating", Integer, index=True)) - -model.VisualizationRatingAssociation.table = Table( - "visualization_rating_association", metadata, - Column("id", Integer, primary_key=True), - Column("visualization_id", Integer, ForeignKey("visualization.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("rating", Integer, index=True)) - -model.HistoryDatasetCollectionRatingAssociation.table = Table( - "history_dataset_collection_rating_association", metadata, - Column("id", Integer, primary_key=True), - Column("history_dataset_collection_id", Integer, - ForeignKey("history_dataset_collection_association.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("rating", Integer, index=True)) - -model.LibraryDatasetCollectionRatingAssociation.table = Table( - "library_dataset_collection_rating_association", metadata, - Column("id", Integer, primary_key=True), - Column("library_dataset_collection_id", Integer, - ForeignKey("library_dataset_collection_association.id"), index=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("rating", Integer, index=True)) - -# User tables. -model.UserPreference.table = Table( - "user_preference", metadata, - Column("id", Integer, primary_key=True), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("name", Unicode(255), index=True), - Column("value", Text)) - -model.UserAction.table = Table( - "user_action", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("session_id", Integer, ForeignKey("galaxy_session.id"), index=True), - Column("action", Unicode(255)), - Column("context", Unicode(512)), - Column("params", Unicode(1024))) - -model.APIKeys.table = Table( - "api_keys", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("user_id", Integer, ForeignKey("galaxy_user.id"), index=True), - Column("key", TrimmedString(32), index=True, unique=True)) - -CleanupEvent_table = Table("cleanup_event", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("message", TrimmedString(1024))) - -CleanupEventDatasetAssociation_table = Table("cleanup_event_dataset_association", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("cleanup_event_id", Integer, ForeignKey("cleanup_event.id"), index=True, nullable=True), - Column("dataset_id", Integer, ForeignKey("dataset.id"), index=True)) - -CleanupEventMetadataFileAssociation_table = Table("cleanup_event_metadata_file_association", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("cleanup_event_id", Integer, ForeignKey("cleanup_event.id"), index=True, nullable=True), - Column("metadata_file_id", Integer, ForeignKey("metadata_file.id"), index=True)) - -CleanupEventHistoryAssociation_table = Table("cleanup_event_history_association", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("cleanup_event_id", Integer, ForeignKey("cleanup_event.id"), index=True, nullable=True), - Column("history_id", Integer, ForeignKey("history.id"), index=True)) - -CleanupEventHistoryDatasetAssociationAssociation_table = Table("cleanup_event_hda_association", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("cleanup_event_id", Integer, ForeignKey("cleanup_event.id"), index=True, nullable=True), - Column("hda_id", Integer, ForeignKey("history_dataset_association.id"), index=True)) - -CleanupEventLibraryAssociation_table = Table("cleanup_event_library_association", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("cleanup_event_id", Integer, ForeignKey("cleanup_event.id"), index=True, nullable=True), - Column("library_id", Integer, ForeignKey("library.id"), index=True)) - -CleanupEventLibraryFolderAssociation_table = Table("cleanup_event_library_folder_association", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("cleanup_event_id", Integer, ForeignKey("cleanup_event.id"), index=True, nullable=True), - Column("library_folder_id", Integer, ForeignKey("library_folder.id"), index=True)) - -CleanupEventLibraryDatasetAssociation_table = Table("cleanup_event_library_dataset_association", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("cleanup_event_id", Integer, ForeignKey("cleanup_event.id"), index=True, nullable=True), - Column("library_dataset_id", Integer, ForeignKey("library_dataset.id"), index=True)) - -CleanupEventLibraryDatasetDatasetAssociationAssociation_table = Table("cleanup_event_ldda_association", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("cleanup_event_id", Integer, ForeignKey("cleanup_event.id"), index=True, nullable=True), - Column("ldda_id", Integer, ForeignKey("library_dataset_dataset_association.id"), index=True)) - -CleanupEventImplicitlyConvertedDatasetAssociationAssociation_table = Table("cleanup_event_icda_association", metadata, - Column("id", Integer, primary_key=True), - Column("create_time", DateTime, default=now), - Column("cleanup_event_id", Integer, ForeignKey("cleanup_event.id"), index=True, nullable=True), - Column("icda_id", Integer, ForeignKey("implicitly_converted_dataset_association.id"), index=True)) - - -# With the tables defined we can define the mappers and setup the -# relationships between the model objects. -def simple_mapping(model, **kwds): - mapper_registry.map_imperatively(model, model.table, properties=kwds) - - -# User tables. -mapper_registry.map_imperatively(model.UserPreference, model.UserPreference.table, properties={}) -mapper_registry.map_imperatively(model.UserAction, model.UserAction.table, properties=dict( - # user=relation( model.User.mapper ) - user=relation(model.User) -)) -mapper_registry.map_imperatively(model.APIKeys, model.APIKeys.table, properties={}) - - -mapper_registry.map_imperatively(model.FormValues, model.FormValues.table, properties=dict( - form_definition=relation(model.FormDefinition, - primaryjoin=(model.FormValues.table.c.form_definition_id == model.FormDefinition.table.c.id)) -)) - -mapper_registry.map_imperatively(model.FormDefinition, model.FormDefinition.table) - -mapper_registry.map_imperatively(model.FormDefinitionCurrent, model.FormDefinitionCurrent.table, properties=dict( - forms=relation(model.FormDefinition, - backref='form_definition_current', - cascade="all, delete-orphan", - primaryjoin=(model.FormDefinitionCurrent.table.c.id == model.FormDefinition.table.c.form_definition_current_id)), - latest_form=relation(model.FormDefinition, - post_update=True, - primaryjoin=(model.FormDefinitionCurrent.table.c.latest_form_id == model.FormDefinition.table.c.id)) -)) - -mapper_registry.map_imperatively(model.UserAddress, model.UserAddress.table, properties=dict( - user=relation(model.User, - primaryjoin=(model.UserAddress.table.c.user_id == model.User.table.c.id), - backref='addresses', - order_by=desc(model.UserAddress.table.c.update_time)), -)) - -mapper_registry.map_imperatively(model.UserAuthnzToken, model.UserAuthnzToken.table, properties=dict( - user=relation(model.User, - primaryjoin=(model.UserAuthnzToken.table.c.user_id == model.User.table.c.id), - backref='social_auth') -)) - -mapper_registry.map_imperatively(model.CustosAuthnzToken, model.CustosAuthnzToken.table, properties=dict( - user=relation(model.User, - primaryjoin=(model.CustosAuthnzToken.table.c.user_id == model.User.table.c.id), - backref='custos_auth') -)) - -mapper_registry.map_imperatively(model.CloudAuthz, model.CloudAuthz.table, properties=dict( - user=relation(model.User, - primaryjoin=(model.CloudAuthz.table.c.user_id == model.User.table.c.id), - backref='cloudauthz'), - authn=relation(model.UserAuthnzToken, - primaryjoin=(model.CloudAuthz.table.c.authn_id == model.UserAuthnzToken.table.c.id), - backref='cloudauthz') -)) - -simple_mapping(model.DynamicTool) - -simple_mapping(model.HistoryDatasetAssociation, - dataset=relation(model.Dataset, - primaryjoin=(model.Dataset.table.c.id == model.HistoryDatasetAssociation.table.c.dataset_id), - lazy=False, - backref='history_associations'), - # .history defined in History mapper - copied_from_history_dataset_association=relation(model.HistoryDatasetAssociation, - primaryjoin=(model.HistoryDatasetAssociation.table.c.copied_from_history_dataset_association_id - == model.HistoryDatasetAssociation.table.c.id), - remote_side=[model.HistoryDatasetAssociation.table.c.id], - uselist=False, - backref='copied_to_history_dataset_associations'), - copied_to_library_dataset_dataset_associations=relation(model.LibraryDatasetDatasetAssociation, - primaryjoin=(model.HistoryDatasetAssociation.table.c.id - == model.LibraryDatasetDatasetAssociation.table.c.copied_from_history_dataset_association_id), - backref='copied_from_history_dataset_association'), - tags=relation(model.HistoryDatasetAssociationTagAssociation, - order_by=model.HistoryDatasetAssociationTagAssociation.table.c.id, - backref='history_tag_associations'), - annotations=relation(model.HistoryDatasetAssociationAnnotationAssociation, - order_by=model.HistoryDatasetAssociationAnnotationAssociation.table.c.id, - backref="hda"), - ratings=relation(model.HistoryDatasetAssociationRatingAssociation, - order_by=model.HistoryDatasetAssociationRatingAssociation.table.c.id, - backref="hda"), - extended_metadata=relation(model.ExtendedMetadata, - primaryjoin=(model.HistoryDatasetAssociation.table.c.extended_metadata_id - == model.ExtendedMetadata.table.c.id)), - hidden_beneath_collection_instance=relation(model.HistoryDatasetCollectionAssociation, - primaryjoin=(model.HistoryDatasetAssociation.table.c.hidden_beneath_collection_instance_id - == model.HistoryDatasetCollectionAssociation.table.c.id), - uselist=False, - backref="hidden_dataset_instances"), - _metadata=deferred(model.HistoryDatasetAssociation.table.c._metadata) -) - -simple_mapping(model.Dataset, - job=relation(model.Job, primaryjoin=(model.Dataset.table.c.job_id == model.Job.table.c.id)), - active_history_associations=relation(model.HistoryDatasetAssociation, - primaryjoin=( - (model.Dataset.table.c.id == model.HistoryDatasetAssociation.table.c.dataset_id) - & (model.HistoryDatasetAssociation.table.c.deleted == false()) - & (model.HistoryDatasetAssociation.table.c.purged == false())), - viewonly=True), - purged_history_associations=relation(model.HistoryDatasetAssociation, - primaryjoin=( - (model.Dataset.table.c.id == model.HistoryDatasetAssociation.table.c.dataset_id) - & (model.HistoryDatasetAssociation.table.c.purged == true())), - viewonly=True), - active_library_associations=relation(model.LibraryDatasetDatasetAssociation, - primaryjoin=( - (model.Dataset.table.c.id == model.LibraryDatasetDatasetAssociation.table.c.dataset_id) - & (model.LibraryDatasetDatasetAssociation.table.c.deleted == false())), - viewonly=True), -) - -mapper_registry.map_imperatively(model.DatasetHash, model.DatasetHash.table, properties=dict( - dataset=relation(model.Dataset, backref='hashes') -)) - -mapper_registry.map_imperatively(model.DatasetSource, model.DatasetSource.table, properties=dict( - dataset=relation(model.Dataset, backref='sources') -)) - -mapper_registry.map_imperatively(model.DatasetSourceHash, model.DatasetSourceHash.table, properties=dict( - source=relation(model.DatasetSource, backref='hashes') -)) - -mapper_registry.map_imperatively(model.HistoryDatasetAssociationHistory, model.HistoryDatasetAssociationHistory.table) - -mapper_registry.map_imperatively(model.HistoryDatasetAssociationDisplayAtAuthorization, model.HistoryDatasetAssociationDisplayAtAuthorization.table, properties=dict( - history_dataset_association=relation(model.HistoryDatasetAssociation), - user=relation(model.User) -)) - -mapper_registry.map_imperatively(model.HistoryDatasetAssociationSubset, model.HistoryDatasetAssociationSubset.table, properties=dict( - hda=relation(model.HistoryDatasetAssociation, - primaryjoin=(model.HistoryDatasetAssociationSubset.table.c.history_dataset_association_id - == model.HistoryDatasetAssociation.table.c.id)), - subset=relation(model.HistoryDatasetAssociation, - primaryjoin=(model.HistoryDatasetAssociationSubset.table.c.history_dataset_association_subset_id - == model.HistoryDatasetAssociation.table.c.id)) -)) - -mapper_registry.map_imperatively(model.ImplicitlyConvertedDatasetAssociation, model.ImplicitlyConvertedDatasetAssociation.table, properties=dict( - parent_hda=relation(model.HistoryDatasetAssociation, - primaryjoin=(model.ImplicitlyConvertedDatasetAssociation.table.c.hda_parent_id - == model.HistoryDatasetAssociation.table.c.id), - backref='implicitly_converted_datasets'), - dataset_ldda=relation(model.LibraryDatasetDatasetAssociation, - primaryjoin=(model.ImplicitlyConvertedDatasetAssociation.table.c.ldda_id - == model.LibraryDatasetDatasetAssociation.table.c.id), - backref="implicitly_converted_parent_datasets"), - dataset=relation(model.HistoryDatasetAssociation, - primaryjoin=(model.ImplicitlyConvertedDatasetAssociation.table.c.hda_id - == model.HistoryDatasetAssociation.table.c.id), - backref="implicitly_converted_parent_datasets") -)) - -mapper_registry.map_imperatively(model.History, model.History.table, properties=dict( - datasets=relation(model.HistoryDatasetAssociation, - backref="history", - order_by=asc(model.HistoryDatasetAssociation.table.c.hid)), - exports=relation(model.JobExportHistoryArchive, - backref="history", - primaryjoin=(model.JobExportHistoryArchive.table.c.history_id == model.History.table.c.id), - order_by=desc(model.JobExportHistoryArchive.table.c.id)), - active_datasets=relation(model.HistoryDatasetAssociation, - primaryjoin=( - (model.HistoryDatasetAssociation.table.c.history_id == model.History.table.c.id) - & not_(model.HistoryDatasetAssociation.table.c.deleted) - ), - order_by=asc(model.HistoryDatasetAssociation.table.c.hid), - viewonly=True), - active_dataset_collections=relation(model.HistoryDatasetCollectionAssociation, - primaryjoin=( - (model.HistoryDatasetCollectionAssociation.table.c.history_id == model.History.table.c.id) - & not_(model.HistoryDatasetCollectionAssociation.table.c.deleted) - ), - order_by=asc(model.HistoryDatasetCollectionAssociation.table.c.hid), - viewonly=True), - visible_datasets=relation(model.HistoryDatasetAssociation, - primaryjoin=( - (model.HistoryDatasetAssociation.table.c.history_id == model.History.table.c.id) - & not_(model.HistoryDatasetAssociation.table.c.deleted) - & model.HistoryDatasetAssociation.table.c.visible - ), - order_by=asc(model.HistoryDatasetAssociation.table.c.hid), - viewonly=True), - visible_dataset_collections=relation(model.HistoryDatasetCollectionAssociation, - primaryjoin=( - (model.HistoryDatasetCollectionAssociation.table.c.history_id == model.History.table.c.id) - & not_(model.HistoryDatasetCollectionAssociation.table.c.deleted) - & model.HistoryDatasetCollectionAssociation.table.c.visible - ), - order_by=asc(model.HistoryDatasetCollectionAssociation.table.c.hid), - viewonly=True), - tags=relation(model.HistoryTagAssociation, - order_by=model.HistoryTagAssociation.table.c.id, - backref="histories"), - annotations=relation(model.HistoryAnnotationAssociation, - order_by=model.HistoryAnnotationAssociation.table.c.id, - backref="history"), - ratings=relation(model.HistoryRatingAssociation, - order_by=model.HistoryRatingAssociation.table.c.id, - backref="history"), - average_rating=column_property( - select(func.avg(model.HistoryRatingAssociation.table.c.rating)).where(model.HistoryRatingAssociation.table.c.history_id == model.History.table.c.id).scalar_subquery(), - deferred=True - ), - users_shared_with_count=column_property( - select(func.count(model.HistoryUserShareAssociation.table.c.id)).where(model.History.table.c.id == model.HistoryUserShareAssociation.table.c.history_id).scalar_subquery(), - deferred=True - ), - update_time=column_property( - select(func.max(model.HistoryAudit.table.c.update_time)).where(model.HistoryAudit.table.c.history_id == model.History.table.c.id).scalar_subquery(), - ), -)) - -# Set up proxy so that -# History.users_shared_with -# returns a list of users that history is shared with. -model.History.users_shared_with_dot_users = association_proxy('users_shared_with', 'user') # type: ignore - -mapper_registry.map_imperatively(model.HistoryUserShareAssociation, model.HistoryUserShareAssociation.table, properties=dict( - user=relation(model.User, backref='histories_shared_by_others'), - history=relation(model.History, backref='users_shared_with') -)) - -mapper_registry.map_imperatively(model.User, model.User.table, properties=dict( - histories=relation(model.History, - backref="user", - order_by=desc(model.History.update_time)), - active_histories=relation(model.History, - primaryjoin=( - (model.History.table.c.user_id == model.User.table.c.id) - & (not_(model.History.table.c.deleted)) - ), - viewonly=True, - order_by=desc(model.History.update_time)), - galaxy_sessions=relation(model.GalaxySession, - backref="user", - order_by=desc(model.GalaxySession.table.c.update_time)), - stored_workflow_menu_entries=relation(model.StoredWorkflowMenuEntry, - primaryjoin=( - (model.StoredWorkflowMenuEntry.table.c.user_id == model.User.table.c.id) - & (model.StoredWorkflowMenuEntry.table.c.stored_workflow_id == model.StoredWorkflow.table.c.id) - & not_(model.StoredWorkflow.table.c.deleted) - ), - backref="user", - cascade="all, delete-orphan", - collection_class=ordering_list('order_index')), - _preferences=relation(model.UserPreference, - backref="user", - collection_class=attribute_mapped_collection('name')), - # addresses=relation( UserAddress, - # primaryjoin=( User.table.c.id == UserAddress.table.c.user_id ) ), - values=relation(model.FormValues, - primaryjoin=(model.User.table.c.form_values_id == model.FormValues.table.c.id)), - api_keys=relation(model.APIKeys, - backref="user", - order_by=desc(model.APIKeys.table.c.create_time)), -)) - -mapper_registry.map_imperatively(model.PasswordResetToken, model.PasswordResetToken.table, - properties=dict(user=relation(model.User, backref="reset_tokens"))) - - -# Set up proxy so that this syntax is possible: -# .preferences[pref_name] = pref_value -model.User.preferences = association_proxy('_preferences', 'value', creator=model.UserPreference) # type: ignore - -mapper_registry.map_imperatively(model.UserGroupAssociation, model.UserGroupAssociation.table, properties=dict( - user=relation(model.User, backref="groups"), - group=relation(model.Group, backref="users") -)) - -mapper_registry.map_imperatively(model.DefaultUserPermissions, model.DefaultUserPermissions.table, properties=dict( - user=relation(model.User, backref="default_permissions"), - role=relation(model.Role) -)) - -mapper_registry.map_imperatively(model.DefaultHistoryPermissions, model.DefaultHistoryPermissions.table, properties=dict( - history=relation(model.History, backref="default_permissions"), - role=relation(model.Role) -)) - -mapper_registry.map_imperatively(model.UserRoleAssociation, model.UserRoleAssociation.table, properties=dict( - user=relation(model.User, backref="roles"), - role=relation(model.Role, backref="users"), - non_private_roles=relation( - model.User, - backref="non_private_roles", - viewonly=True, - primaryjoin=( - (model.User.table.c.id == model.UserRoleAssociation.table.c.user_id) - & (model.UserRoleAssociation.table.c.role_id == model.Role.id) - & not_(model.Role.name == model.User.table.c.email)) - ) -)) - -mapper_registry.map_imperatively(model.GroupRoleAssociation, model.GroupRoleAssociation.table, properties=dict( - group=relation(model.Group, backref="roles"), - role=relation(model.Role, backref="groups") -)) - -mapper_registry.map_imperatively(model.UserQuotaAssociation, model.UserQuotaAssociation.table, properties=dict( - user=relation(model.User, backref="quotas"), - quota=relation(model.Quota, backref="users") -)) - -mapper_registry.map_imperatively(model.GroupQuotaAssociation, model.GroupQuotaAssociation.table, properties=dict( - group=relation(model.Group, backref="quotas"), - quota=relation(model.Quota, backref="groups") -)) - -mapper_registry.map_imperatively(model.DefaultQuotaAssociation, model.DefaultQuotaAssociation.table, properties=dict( - quota=relation(model.Quota, backref="default") -)) - -mapper_registry.map_imperatively(model.DatasetPermissions, model.DatasetPermissions.table, properties=dict( - dataset=relation(model.Dataset, backref="actions"), - role=relation(model.Role, backref="dataset_actions") -)) - -mapper_registry.map_imperatively(model.LibraryPermissions, model.LibraryPermissions.table, properties=dict( - library=relation(model.Library, backref="actions"), - role=relation(model.Role, backref="library_actions") -)) - -mapper_registry.map_imperatively(model.LibraryFolderPermissions, model.LibraryFolderPermissions.table, properties=dict( - folder=relation(model.LibraryFolder, backref="actions"), - role=relation(model.Role, backref="library_folder_actions") -)) - -mapper_registry.map_imperatively(model.LibraryDatasetPermissions, model.LibraryDatasetPermissions.table, properties=dict( - library_dataset=relation(model.LibraryDataset, backref="actions"), - role=relation(model.Role, backref="library_dataset_actions") -)) - -mapper_registry.map_imperatively(model.LibraryDatasetDatasetAssociationPermissions, model.LibraryDatasetDatasetAssociationPermissions.table, properties=dict( - library_dataset_dataset_association=relation(model.LibraryDatasetDatasetAssociation, backref="actions"), - role=relation(model.Role, backref="library_dataset_dataset_actions") -)) - -mapper_registry.map_imperatively(model.Library, model.Library.table, properties=dict( - root_folder=relation(model.LibraryFolder, backref=backref("library_root")) -)) - -mapper_registry.map_imperatively(model.ExtendedMetadata, model.ExtendedMetadata.table, properties=dict( - children=relation(model.ExtendedMetadataIndex, backref='extended_metadata') -)) - -mapper_registry.map_imperatively(model.ExtendedMetadataIndex, model.ExtendedMetadataIndex.table) - -mapper_registry.map_imperatively(model.LibraryInfoAssociation, model.LibraryInfoAssociation.table, properties=dict( - library=relation(model.Library, - primaryjoin=( - (model.LibraryInfoAssociation.table.c.library_id == model.Library.table.c.id) - & (not_(model.LibraryInfoAssociation.table.c.deleted)) - ), - backref="info_association"), - template=relation(model.FormDefinition, - primaryjoin=(model.LibraryInfoAssociation.table.c.form_definition_id == model.FormDefinition.table.c.id)), - info=relation(model.FormValues, - primaryjoin=(model.LibraryInfoAssociation.table.c.form_values_id == model.FormValues.table.c.id)) -)) - -mapper_registry.map_imperatively(model.LibraryFolder, model.LibraryFolder.table, properties=dict( - folders=relation(model.LibraryFolder, - primaryjoin=(model.LibraryFolder.table.c.parent_id == model.LibraryFolder.table.c.id), - order_by=asc(model.LibraryFolder.table.c.name), - backref=backref("parent", - primaryjoin=(model.LibraryFolder.table.c.parent_id == model.LibraryFolder.table.c.id), - remote_side=[model.LibraryFolder.table.c.id])), - active_folders=relation(model.LibraryFolder, - primaryjoin=( - (model.LibraryFolder.table.c.parent_id == model.LibraryFolder.table.c.id) - & (not_(model.LibraryFolder.table.c.deleted)) - ), - order_by=asc(model.LibraryFolder.table.c.name), - # """sqlalchemy.exc.ArgumentError: Error creating eager relationship 'active_folders' - # on parent class '' to child class '': - # Cant use eager loading on a self referential relationship.""" - lazy=True, - viewonly=True), - datasets=relation(model.LibraryDataset, - primaryjoin=(model.LibraryDataset.table.c.folder_id == model.LibraryFolder.table.c.id), - order_by=asc(model.LibraryDataset.table.c._name), - lazy=True, - viewonly=True), - active_datasets=relation(model.LibraryDataset, - primaryjoin=( - (model.LibraryDataset.table.c.folder_id == model.LibraryFolder.table.c.id) - & (not_(model.LibraryDataset.table.c.deleted)) - ), - order_by=asc(model.LibraryDataset.table.c._name), - lazy=True, - viewonly=True) -)) - -mapper_registry.map_imperatively(model.LibraryFolderInfoAssociation, model.LibraryFolderInfoAssociation.table, properties=dict( - folder=relation(model.LibraryFolder, - primaryjoin=( - (model.LibraryFolderInfoAssociation.table.c.library_folder_id == model.LibraryFolder.table.c.id) - & (not_(model.LibraryFolderInfoAssociation.table.c.deleted)) - ), - backref="info_association"), - template=relation(model.FormDefinition, - primaryjoin=(model.LibraryFolderInfoAssociation.table.c.form_definition_id == model.FormDefinition.table.c.id)), - info=relation(model.FormValues, - primaryjoin=(model.LibraryFolderInfoAssociation.table.c.form_values_id == model.FormValues.table.c.id)) -)) - -mapper_registry.map_imperatively(model.LibraryDataset, model.LibraryDataset.table, properties=dict( - folder=relation(model.LibraryFolder), - library_dataset_dataset_association=relation(model.LibraryDatasetDatasetAssociation, - foreign_keys=model.LibraryDataset.table.c.library_dataset_dataset_association_id, - post_update=True), - expired_datasets=relation(model.LibraryDatasetDatasetAssociation, - foreign_keys=[model.LibraryDataset.table.c.id, model.LibraryDataset.table.c.library_dataset_dataset_association_id], - primaryjoin=( - (model.LibraryDataset.table.c.id == model.LibraryDatasetDatasetAssociation.table.c.library_dataset_id) - & (not_(model.LibraryDataset.table.c.library_dataset_dataset_association_id - == model.LibraryDatasetDatasetAssociation.table.c.id)) - ), - viewonly=True, - uselist=True) -)) - -mapper_registry.map_imperatively(model.LibraryDatasetDatasetAssociation, model.LibraryDatasetDatasetAssociation.table, properties=dict( - dataset=relation(model.Dataset, - primaryjoin=(model.LibraryDatasetDatasetAssociation.table.c.dataset_id == model.Dataset.table.c.id), - backref='library_associations'), - library_dataset=relation(model.LibraryDataset, - foreign_keys=model.LibraryDatasetDatasetAssociation.table.c.library_dataset_id), - # user=relation( model.User.mapper ), - user=relation(model.User), - copied_from_library_dataset_dataset_association=relation(model.LibraryDatasetDatasetAssociation, - primaryjoin=(model.LibraryDatasetDatasetAssociation.table.c.copied_from_library_dataset_dataset_association_id - == model.LibraryDatasetDatasetAssociation.table.c.id), - remote_side=[model.LibraryDatasetDatasetAssociation.table.c.id], - uselist=False, - backref='copied_to_library_dataset_dataset_associations'), - copied_to_history_dataset_associations=relation(model.HistoryDatasetAssociation, - primaryjoin=(model.LibraryDatasetDatasetAssociation.table.c.id - == model.HistoryDatasetAssociation.table.c.copied_from_library_dataset_dataset_association_id), - backref='copied_from_library_dataset_dataset_association'), - implicitly_converted_datasets=relation(model.ImplicitlyConvertedDatasetAssociation, - primaryjoin=(model.ImplicitlyConvertedDatasetAssociation.table.c.ldda_parent_id - == model.LibraryDatasetDatasetAssociation.table.c.id), - backref='parent_ldda'), - tags=relation(model.LibraryDatasetDatasetAssociationTagAssociation, - order_by=model.LibraryDatasetDatasetAssociationTagAssociation.table.c.id, - backref='history_tag_associations'), - extended_metadata=relation(model.ExtendedMetadata, - primaryjoin=(model.LibraryDatasetDatasetAssociation.table.c.extended_metadata_id == model.ExtendedMetadata.table.c.id) - ), - _metadata=deferred(model.LibraryDatasetDatasetAssociation.table.c._metadata) -)) - -mapper_registry.map_imperatively(model.LibraryDatasetDatasetInfoAssociation, model.LibraryDatasetDatasetInfoAssociation.table, properties=dict( - library_dataset_dataset_association=relation(model.LibraryDatasetDatasetAssociation, - primaryjoin=( - (model.LibraryDatasetDatasetInfoAssociation.table.c.library_dataset_dataset_association_id - == model.LibraryDatasetDatasetAssociation.table.c.id) - & (not_(model.LibraryDatasetDatasetInfoAssociation.table.c.deleted)) - ), - backref="info_association"), - template=relation(model.FormDefinition, - primaryjoin=(model.LibraryDatasetDatasetInfoAssociation.table.c.form_definition_id == model.FormDefinition.table.c.id)), - info=relation(model.FormValues, - primaryjoin=(model.LibraryDatasetDatasetInfoAssociation.table.c.form_values_id == model.FormValues.table.c.id)) -)) - -mapper_registry.map_imperatively(model.JobToInputDatasetAssociation, model.JobToInputDatasetAssociation.table, properties=dict( - dataset=relation(model.HistoryDatasetAssociation, - lazy=False, - backref="dependent_jobs") -)) - -mapper_registry.map_imperatively(model.JobToOutputDatasetAssociation, model.JobToOutputDatasetAssociation.table, properties=dict( - job=relation(model.Job, - backref="output_datasets"), - dataset=relation(model.HistoryDatasetAssociation, - lazy=False, - backref="creating_job_associations") -)) - -mapper_registry.map_imperatively(model.JobToInputDatasetCollectionAssociation, model.JobToInputDatasetCollectionAssociation.table, properties=dict( - dataset_collection=relation(model.HistoryDatasetCollectionAssociation, - lazy=False) -)) - -mapper_registry.map_imperatively(model.JobToInputDatasetCollectionElementAssociation, model.JobToInputDatasetCollectionElementAssociation.table, properties=dict( - dataset_collection_element=relation(model.DatasetCollectionElement, - lazy=False) -)) - -mapper_registry.map_imperatively(model.JobToOutputDatasetCollectionAssociation, model.JobToOutputDatasetCollectionAssociation.table, properties=dict( - dataset_collection_instance=relation(model.HistoryDatasetCollectionAssociation, - lazy=False, - backref="output_dataset_collection_instances") -)) - -mapper_registry.map_imperatively(model.JobToImplicitOutputDatasetCollectionAssociation, model.JobToImplicitOutputDatasetCollectionAssociation.table, properties=dict( - dataset_collection=relation(model.DatasetCollection, - backref="output_dataset_collections") -)) - -mapper_registry.map_imperatively(model.JobToInputLibraryDatasetAssociation, model.JobToInputLibraryDatasetAssociation.table, properties=dict( - dataset=relation(model.LibraryDatasetDatasetAssociation, - lazy=False, - backref="dependent_jobs") -)) - -mapper_registry.map_imperatively(model.JobToOutputLibraryDatasetAssociation, model.JobToOutputLibraryDatasetAssociation.table, properties=dict( - dataset=relation(model.LibraryDatasetDatasetAssociation, - lazy=False, - backref="creating_job_associations") -)) - -simple_mapping(model.JobStateHistory, - job=relation(model.Job, backref="state_history")) - -simple_mapping(model.JobMetricText, - job=relation(model.Job, backref="text_metrics")) - -simple_mapping(model.TaskMetricText, - task=relation(model.Task, backref="text_metrics")) - -simple_mapping(model.JobMetricNumeric, - job=relation(model.Job, backref="numeric_metrics")) - -simple_mapping(model.TaskMetricNumeric, - task=relation(model.Task, backref="numeric_metrics")) - -simple_mapping(model.ImplicitlyCreatedDatasetCollectionInput, - input_dataset_collection=relation(model.HistoryDatasetCollectionAssociation, - primaryjoin=(model.HistoryDatasetCollectionAssociation.table.c.id - == model.ImplicitlyCreatedDatasetCollectionInput.table.c.input_dataset_collection_id), - # backref="implicitly_created_dataset_collections", - ), -) - -simple_mapping(model.ImplicitCollectionJobs) - -# simple_mapping( -# model.ImplicitCollectionJobsHistoryDatasetCollectionAssociation, -# history_dataset_collection_associations=relation( -# model.HistoryDatasetCollectionAssociation, -# backref=backref("implicit_collection_jobs_association", uselist=False), -# uselist=True, -# ), -# ) - -simple_mapping( - model.ImplicitCollectionJobsJobAssociation, - implicit_collection_jobs=relation( - model.ImplicitCollectionJobs, - backref=backref("jobs", uselist=True), - uselist=False, - ), - job=relation( - model.Job, - backref=backref("implicit_collection_jobs_association", uselist=False), - uselist=False, - ), -) - -mapper_registry.map_imperatively(model.JobParameter, model.JobParameter.table) - -mapper_registry.map_imperatively(model.JobExternalOutputMetadata, model.JobExternalOutputMetadata.table, properties=dict( - history_dataset_association=relation(model.HistoryDatasetAssociation, lazy=False), - library_dataset_dataset_association=relation(model.LibraryDatasetDatasetAssociation, lazy=False) -)) - -mapper_registry.map_imperatively(model.JobExportHistoryArchive, model.JobExportHistoryArchive.table, properties=dict( - job=relation(model.Job), - dataset=relation(model.Dataset, backref='job_export_history_archive') -)) - -mapper_registry.map_imperatively(model.JobImportHistoryArchive, model.JobImportHistoryArchive.table, properties=dict( - job=relation(model.Job), - history=relation(model.History) -)) - -mapper_registry.map_imperatively(model.GenomeIndexToolData, model.GenomeIndexToolData.table, properties=dict( - job=relation(model.Job, backref='job'), - dataset=relation(model.Dataset, backref='genome_index_tool_data'), - user=relation(model.User), - deferred=relation(model.DeferredJob, backref='deferred_job'), - transfer=relation(model.TransferJob, backref='transfer_job') -)) - -mapper_registry.map_imperatively(model.InteractiveToolEntryPoint, model.InteractiveToolEntryPoint.table, properties=dict( - job=relation(model.Job, backref=backref('interactivetool_entry_points', uselist=True), uselist=False) -)) - -mapper_registry.map_imperatively(model.JobContainerAssociation, model.JobContainerAssociation.table, properties=dict( - job=relation(model.Job, backref=backref('container', uselist=False), uselist=False) -)) - -mapper_registry.map_imperatively(model.PostJobAction, model.PostJobAction.table, properties=dict( - workflow_step=relation(model.WorkflowStep, - backref='post_job_actions', - primaryjoin=(model.WorkflowStep.table.c.id == model.PostJobAction.table.c.workflow_step_id)) -)) - -mapper_registry.map_imperatively(model.PostJobActionAssociation, model.PostJobActionAssociation.table, properties=dict( - post_job_action=relation(model.PostJobAction) -)) - -mapper_registry.map_imperatively(model.Task, model.Task.table) - -mapper_registry.map_imperatively(model.DeferredJob, model.DeferredJob.table, properties={}) - -mapper_registry.map_imperatively(model.TransferJob, model.TransferJob.table, properties={}) - - -simple_mapping(model.DatasetCollection, - elements=relation(model.DatasetCollectionElement, - primaryjoin=(model.DatasetCollection.table.c.id == model.DatasetCollectionElement.table.c.dataset_collection_id), - remote_side=[model.DatasetCollectionElement.table.c.dataset_collection_id], - backref="collection", - order_by=model.DatasetCollectionElement.table.c.element_index) -) - -simple_mapping(model.HistoryDatasetCollectionAssociation, - collection=relation(model.DatasetCollection), - history=relation(model.History, - backref='dataset_collections'), - copied_from_history_dataset_collection_association=relation(model.HistoryDatasetCollectionAssociation, - primaryjoin=(model.HistoryDatasetCollectionAssociation.table.c.copied_from_history_dataset_collection_association_id - == model.HistoryDatasetCollectionAssociation.table.c.id), - remote_side=[model.HistoryDatasetCollectionAssociation.table.c.id], - backref='copied_to_history_dataset_collection_associations', - uselist=False), - implicit_input_collections=relation(model.ImplicitlyCreatedDatasetCollectionInput, - primaryjoin=(model.HistoryDatasetCollectionAssociation.table.c.id - == model.ImplicitlyCreatedDatasetCollectionInput.table.c.dataset_collection_id), - backref="dataset_collection", - ), - implicit_collection_jobs=relation( - model.ImplicitCollectionJobs, - backref=backref("history_dataset_collection_associations", uselist=True), - uselist=False, - ), - job=relation( - model.Job, - backref=backref("history_dataset_collection_associations", uselist=True), - uselist=False, - ), - job_state_summary=relation(HistoryDatasetCollectionJobStateSummary, - primaryjoin=(model.HistoryDatasetCollectionAssociation.table.c.id == HistoryDatasetCollectionJobStateSummary.__table__.c.hdca_id), - foreign_keys=HistoryDatasetCollectionJobStateSummary.__table__.c.hdca_id, - uselist=False - ), - tags=relation(model.HistoryDatasetCollectionTagAssociation, - order_by=model.HistoryDatasetCollectionTagAssociation.table.c.id, - backref='dataset_collections'), - annotations=relation(model.HistoryDatasetCollectionAssociationAnnotationAssociation, - order_by=model.HistoryDatasetCollectionAssociationAnnotationAssociation.table.c.id, - backref="history_dataset_collection"), - ratings=relation(model.HistoryDatasetCollectionRatingAssociation, - order_by=model.HistoryDatasetCollectionRatingAssociation.table.c.id, - backref="dataset_collection") -) - -simple_mapping(model.LibraryDatasetCollectionAssociation, - collection=relation(model.DatasetCollection), - folder=relation(model.LibraryFolder, - backref='dataset_collections'), - tags=relation(model.LibraryDatasetCollectionTagAssociation, - order_by=model.LibraryDatasetCollectionTagAssociation.table.c.id, - backref='dataset_collections'), - annotations=relation(model.LibraryDatasetCollectionAnnotationAssociation, - order_by=model.LibraryDatasetCollectionAnnotationAssociation.table.c.id, - backref="dataset_collection"), - ratings=relation(model.LibraryDatasetCollectionRatingAssociation, - order_by=model.LibraryDatasetCollectionRatingAssociation.table.c.id, - backref="dataset_collection")) - -simple_mapping(model.DatasetCollectionElement, - hda=relation(model.HistoryDatasetAssociation, - primaryjoin=(model.DatasetCollectionElement.table.c.hda_id == model.HistoryDatasetAssociation.table.c.id)), - ldda=relation(model.LibraryDatasetDatasetAssociation, - primaryjoin=(model.DatasetCollectionElement.table.c.ldda_id == model.LibraryDatasetDatasetAssociation.table.c.id)), - child_collection=relation(model.DatasetCollection, - primaryjoin=(model.DatasetCollectionElement.table.c.child_collection_id == model.DatasetCollection.table.c.id))) - -mapper_registry.map_imperatively(model.Event, model.Event.table, properties=dict( - history=relation(model.History), - galaxy_session=relation(model.GalaxySession), - # user=relation( model.User.mapper ) ) ) - user=relation(model.User) -)) - -mapper_registry.map_imperatively(model.GalaxySession, model.GalaxySession.table, properties=dict( - current_history=relation(model.History), -)) - -mapper_registry.map_imperatively(model.GalaxySessionToHistoryAssociation, model.GalaxySessionToHistoryAssociation.table, properties=dict( - galaxy_session=relation(model.GalaxySession, backref='histories'), - history=relation(model.History, backref='galaxy_sessions') -)) - -mapper_registry.map_imperatively(model.Workflow, model.Workflow.table, properties=dict( - steps=relation(model.WorkflowStep, - backref='workflow', - primaryjoin=(model.Workflow.table.c.id == model.WorkflowStep.table.c.workflow_id), - order_by=asc(model.WorkflowStep.table.c.order_index), - cascade="all, delete-orphan", - lazy=False), - step_count=column_property( - select(func.count(model.WorkflowStep.table.c.id)).where(model.Workflow.table.c.id == model.WorkflowStep.table.c.workflow_id).scalar_subquery(), - deferred=True - ) - -)) - -mapper_registry.map_imperatively(model.WorkflowStep, model.WorkflowStep.table, properties=dict( - subworkflow=relation(model.Workflow, - primaryjoin=(model.Workflow.table.c.id == model.WorkflowStep.table.c.subworkflow_id), - backref="parent_workflow_steps"), - dynamic_tool=relation(model.DynamicTool, - primaryjoin=(model.DynamicTool.table.c.id == model.WorkflowStep.table.c.dynamic_tool_id), - backref="workflow_steps"), - tags=relation(model.WorkflowStepTagAssociation, - order_by=model.WorkflowStepTagAssociation.table.c.id, - backref="workflow_steps"), - annotations=relation(model.WorkflowStepAnnotationAssociation, - order_by=model.WorkflowStepAnnotationAssociation.table.c.id, - backref="workflow_step") -)) - -mapper_registry.map_imperatively(model.WorkflowStepInput, model.WorkflowStepInput.table, properties=dict( - workflow_step=relation(model.WorkflowStep, - backref=backref("inputs", uselist=True), - cascade="all", - primaryjoin=(model.WorkflowStepInput.table.c.workflow_step_id == model.WorkflowStep.table.c.id)) -)) - -mapper_registry.map_imperatively(model.WorkflowOutput, model.WorkflowOutput.table, properties=dict( - workflow_step=relation(model.WorkflowStep, - backref='workflow_outputs', - primaryjoin=(model.WorkflowStep.table.c.id == model.WorkflowOutput.table.c.workflow_step_id)) -)) - -mapper_registry.map_imperatively(model.WorkflowStepConnection, model.WorkflowStepConnection.table, properties=dict( - input_step_input=relation(model.WorkflowStepInput, - backref="connections", - cascade="all", - primaryjoin=(model.WorkflowStepConnection.table.c.input_step_input_id == model.WorkflowStepInput.table.c.id)), - input_subworkflow_step=relation(model.WorkflowStep, - backref=backref("parent_workflow_input_connections", uselist=True), - primaryjoin=(model.WorkflowStepConnection.table.c.input_subworkflow_step_id == model.WorkflowStep.table.c.id), - ), - output_step=relation(model.WorkflowStep, - backref="output_connections", - cascade="all", - primaryjoin=(model.WorkflowStepConnection.table.c.output_step_id == model.WorkflowStep.table.c.id)), -)) - - -mapper_registry.map_imperatively(model.StoredWorkflow, model.StoredWorkflow.table, properties=dict( - user=relation(model.User, - primaryjoin=(model.User.table.c.id == model.StoredWorkflow.table.c.user_id), - backref='stored_workflows'), - workflows=relation(model.Workflow, - backref='stored_workflow', - cascade="all, delete-orphan", - primaryjoin=(model.StoredWorkflow.table.c.id == model.Workflow.table.c.stored_workflow_id), - order_by=-model.Workflow.id), - latest_workflow=relation(model.Workflow, - post_update=True, - primaryjoin=(model.StoredWorkflow.table.c.latest_workflow_id == model.Workflow.table.c.id), - lazy=False), - tags=relation(model.StoredWorkflowTagAssociation, - order_by=model.StoredWorkflowTagAssociation.table.c.id, - backref="stored_workflows"), - owner_tags=relation(model.StoredWorkflowTagAssociation, - primaryjoin=( - and_(model.StoredWorkflow.table.c.id == model.StoredWorkflowTagAssociation.table.c.stored_workflow_id, - model.StoredWorkflow.table.c.user_id == model.StoredWorkflowTagAssociation.table.c.user_id) - ), - viewonly=True, - order_by=model.StoredWorkflowTagAssociation.table.c.id), - annotations=relation(model.StoredWorkflowAnnotationAssociation, - order_by=model.StoredWorkflowAnnotationAssociation.table.c.id, - backref="stored_workflow"), - ratings=relation(model.StoredWorkflowRatingAssociation, - order_by=model.StoredWorkflowRatingAssociation.table.c.id, - backref="stored_workflow"), - average_rating=column_property( - select(func.avg(model.StoredWorkflowRatingAssociation.table.c.rating)).where(model.StoredWorkflowRatingAssociation.table.c.stored_workflow_id == model.StoredWorkflow.table.c.id).scalar_subquery(), - deferred=True - ) -)) - -# Set up proxy so that -# StoredWorkflow.users_shared_with -# returns a list of users that workflow is shared with. -model.StoredWorkflow.users_shared_with_dot_users = association_proxy('users_shared_with', 'user') # type: ignore - -mapper_registry.map_imperatively(model.StoredWorkflowUserShareAssociation, model.StoredWorkflowUserShareAssociation.table, properties=dict( - user=relation(model.User, - backref='workflows_shared_by_others'), - stored_workflow=relation(model.StoredWorkflow, - backref='users_shared_with') -)) - -mapper_registry.map_imperatively(model.StoredWorkflowMenuEntry, model.StoredWorkflowMenuEntry.table, properties=dict( - stored_workflow=relation(model.StoredWorkflow) -)) - -mapper_registry.map_imperatively(model.WorkflowInvocation, model.WorkflowInvocation.table, properties=dict( - history=relation(model.History, backref=backref('workflow_invocations', uselist=True)), - input_parameters=relation(model.WorkflowRequestInputParameter, backref='workflow_invocation'), - step_states=relation(model.WorkflowRequestStepState, backref='workflow_invocation'), - input_step_parameters=relation(model.WorkflowRequestInputStepParameter, - backref='workflow_invocation'), - input_datasets=relation(model.WorkflowRequestToInputDatasetAssociation, - backref='workflow_invocation'), - input_dataset_collections=relation(model.WorkflowRequestToInputDatasetCollectionAssociation, - backref='workflow_invocation'), - subworkflow_invocations=relation(model.WorkflowInvocationToSubworkflowInvocationAssociation, - primaryjoin=(model.WorkflowInvocationToSubworkflowInvocationAssociation.table.c.workflow_invocation_id == model.WorkflowInvocation.table.c.id), - backref=backref("parent_workflow_invocation", uselist=False), - uselist=True, - ), - steps=relation(model.WorkflowInvocationStep, - backref="workflow_invocation"), - workflow=relation(model.Workflow) -)) - -mapper_registry.map_imperatively(model.WorkflowInvocationToSubworkflowInvocationAssociation, model.WorkflowInvocationToSubworkflowInvocationAssociation.table, properties=dict( - subworkflow_invocation=relation(model.WorkflowInvocation, - primaryjoin=(model.WorkflowInvocationToSubworkflowInvocationAssociation.table.c.subworkflow_invocation_id == model.WorkflowInvocation.table.c.id), - backref="parent_workflow_invocation_association", - uselist=False, - ), - workflow_step=relation(model.WorkflowStep), -)) - -simple_mapping(model.WorkflowInvocationStep, - workflow_step=relation(model.WorkflowStep), - job=relation(model.Job, backref=backref('workflow_invocation_step', uselist=False), uselist=False), - implicit_collection_jobs=relation(model.ImplicitCollectionJobs, backref=backref('workflow_invocation_step', uselist=False), uselist=False), - subworkflow_invocation_id=column_property( - select(model.WorkflowInvocationToSubworkflowInvocationAssociation.table.c.subworkflow_invocation_id).where(and_( - model.WorkflowInvocationToSubworkflowInvocationAssociation.table.c.workflow_invocation_id == model.WorkflowInvocationStep.table.c.workflow_invocation_id, - model.WorkflowInvocationToSubworkflowInvocationAssociation.table.c.workflow_step_id == model.WorkflowInvocationStep.table.c.workflow_step_id, - )).scalar_subquery(), - ), -) - - -simple_mapping(model.WorkflowRequestInputParameter) - -simple_mapping(model.WorkflowRequestStepState, - workflow_step=relation(model.WorkflowStep)) - -simple_mapping(model.WorkflowRequestInputStepParameter, - workflow_step=relation(model.WorkflowStep)) - -simple_mapping(model.WorkflowRequestToInputDatasetAssociation, - workflow_step=relation(model.WorkflowStep), - dataset=relation(model.HistoryDatasetAssociation)) - - -simple_mapping(model.WorkflowRequestToInputDatasetCollectionAssociation, - workflow_step=relation(model.WorkflowStep), - dataset_collection=relation(model.HistoryDatasetCollectionAssociation)) - - -mapper_registry.map_imperatively(model.MetadataFile, model.MetadataFile.table, properties=dict( - history_dataset=relation(model.HistoryDatasetAssociation), - library_dataset=relation(model.LibraryDatasetDatasetAssociation) -)) - - -simple_mapping( - model.WorkflowInvocationOutputDatasetAssociation, - workflow_invocation=relation(model.WorkflowInvocation, backref="output_datasets"), - workflow_step=relation(model.WorkflowStep), - dataset=relation(model.HistoryDatasetAssociation), - workflow_output=relation(model.WorkflowOutput), -) - - -simple_mapping( - model.WorkflowInvocationOutputDatasetCollectionAssociation, - workflow_invocation=relation(model.WorkflowInvocation, backref="output_dataset_collections"), - workflow_step=relation(model.WorkflowStep), - dataset_collection=relation(model.HistoryDatasetCollectionAssociation), - workflow_output=relation(model.WorkflowOutput), -) - - -simple_mapping( - model.WorkflowInvocationOutputValue, - workflow_invocation=relation(model.WorkflowInvocation, backref="output_values"), - workflow_invocation_step=relation(model.WorkflowInvocationStep, - foreign_keys=[model.WorkflowInvocationStep.table.c.workflow_invocation_id, model.WorkflowInvocationStep.table.c.workflow_step_id], - primaryjoin=and_( - model.WorkflowInvocationStep.table.c.workflow_invocation_id == model.WorkflowInvocationOutputValue.table.c.workflow_invocation_id, - model.WorkflowInvocationStep.table.c.workflow_step_id == model.WorkflowInvocationOutputValue.table.c.workflow_step_id, - ), - backref='output_value', - viewonly=True - ), - workflow_step=relation(model.WorkflowStep), - workflow_output=relation(model.WorkflowOutput), -) - - -simple_mapping( - model.WorkflowInvocationStepOutputDatasetAssociation, - workflow_invocation_step=relation(model.WorkflowInvocationStep, backref="output_datasets"), - dataset=relation(model.HistoryDatasetAssociation), -) - - -simple_mapping( - model.WorkflowInvocationStepOutputDatasetCollectionAssociation, - workflow_invocation_step=relation(model.WorkflowInvocationStep, backref="output_dataset_collections"), - dataset_collection=relation(model.HistoryDatasetCollectionAssociation), -) - - -mapper_registry.map_imperatively(model.PageRevision, model.PageRevision.table) - -mapper_registry.map_imperatively(model.Page, model.Page.table, properties=dict( - user=relation(model.User), - revisions=relation(model.PageRevision, - backref='page', - cascade="all, delete-orphan", - primaryjoin=(model.Page.table.c.id == model.PageRevision.table.c.page_id)), - latest_revision=relation(model.PageRevision, - post_update=True, - primaryjoin=(model.Page.table.c.latest_revision_id == model.PageRevision.table.c.id), - lazy=False), - tags=relation(model.PageTagAssociation, - order_by=model.PageTagAssociation.table.c.id, - backref="pages"), - annotations=relation(model.PageAnnotationAssociation, - order_by=model.PageAnnotationAssociation.table.c.id, - backref="page"), - ratings=relation(model.PageRatingAssociation, - order_by=model.PageRatingAssociation.table.c.id, - backref="page"), - average_rating=column_property( - select(func.avg(model.PageRatingAssociation.table.c.rating)).where(model.PageRatingAssociation.table.c.page_id == model.Page.table.c.id).scalar_subquery(), - deferred=True - ) -)) - -# Set up proxy so that -# Page.users_shared_with -# returns a list of users that page is shared with. -model.Page.users_shared_with_dot_users = association_proxy('users_shared_with', 'user') # type: ignore - -mapper_registry.map_imperatively(model.PageUserShareAssociation, model.PageUserShareAssociation.table, - properties=dict(user=relation(model.User, backref='pages_shared_by_others'), - page=relation(model.Page, backref='users_shared_with'))) - -mapper_registry.map_imperatively(model.VisualizationRevision, model.VisualizationRevision.table) - -mapper_registry.map_imperatively(model.Visualization, model.Visualization.table, properties=dict( - user=relation(model.User), - revisions=relation(model.VisualizationRevision, - backref='visualization', - cascade="all, delete-orphan", - primaryjoin=(model.Visualization.table.c.id == model.VisualizationRevision.table.c.visualization_id)), - latest_revision=relation(model.VisualizationRevision, - post_update=True, - primaryjoin=(model.Visualization.table.c.latest_revision_id == model.VisualizationRevision.table.c.id), - lazy=False), - tags=relation(model.VisualizationTagAssociation, - order_by=model.VisualizationTagAssociation.table.c.id, - backref="visualizations"), - annotations=relation(model.VisualizationAnnotationAssociation, - order_by=model.VisualizationAnnotationAssociation.table.c.id, - backref="visualization"), - ratings=relation(model.VisualizationRatingAssociation, - order_by=model.VisualizationRatingAssociation.table.c.id, - backref="visualization"), - average_rating=column_property( - select(func.avg(model.VisualizationRatingAssociation.table.c.rating)).where(model.VisualizationRatingAssociation.table.c.visualization_id == model.Visualization.table.c.id).scalar_subquery(), - deferred=True - ) -)) - -# Set up proxy so that -# Visualization.users_shared_with -# returns a list of users that visualization is shared with. -model.Visualization.users_shared_with_dot_users = association_proxy('users_shared_with', 'user') # type: ignore - -mapper_registry.map_imperatively(model.VisualizationUserShareAssociation, model.VisualizationUserShareAssociation.table, properties=dict( - user=relation(model.User, - backref='visualizations_shared_by_others'), - visualization=relation(model.Visualization, - backref='users_shared_with') -)) - -# Tag tables. -simple_mapping(model.Tag, - children=relation(model.Tag, backref=backref('parent', remote_side=[model.Tag.table.c.id]))) - - -def tag_mapping(tag_association_class, backref_name): - simple_mapping(tag_association_class, tag=relation(model.Tag, backref=backref_name), user=relation(model.User)) - - -tag_mapping(model.HistoryTagAssociation, "tagged_histories") -tag_mapping(model.HistoryDatasetAssociationTagAssociation, "tagged_history_dataset_associations") -tag_mapping(model.LibraryDatasetDatasetAssociationTagAssociation, "tagged_library_dataset_dataset_associations") -tag_mapping(model.PageTagAssociation, "tagged_pages") -tag_mapping(model.StoredWorkflowTagAssociation, "tagged_workflows") -tag_mapping(model.WorkflowStepTagAssociation, "tagged_workflow_steps") -tag_mapping(model.VisualizationTagAssociation, "tagged_visualizations") -tag_mapping(model.HistoryDatasetCollectionTagAssociation, "tagged_history_dataset_collections") -tag_mapping(model.LibraryDatasetCollectionTagAssociation, "tagged_library_dataset_collections") -tag_mapping(model.ToolTagAssociation, "tagged_tools") - - -# Annotation tables. -def annotation_mapping(annotation_class, **kwds): - kwds = {key: relation(value) for key, value in kwds.items()} - simple_mapping(annotation_class, **dict(user=relation(model.User), **kwds)) - - -annotation_mapping(model.HistoryAnnotationAssociation) -annotation_mapping(model.HistoryDatasetAssociationAnnotationAssociation) -annotation_mapping(model.StoredWorkflowAnnotationAssociation) -annotation_mapping(model.WorkflowStepAnnotationAssociation) -annotation_mapping(model.PageAnnotationAssociation) -annotation_mapping(model.VisualizationAnnotationAssociation) -annotation_mapping(model.HistoryDatasetCollectionAssociationAnnotationAssociation) -annotation_mapping(model.LibraryDatasetCollectionAnnotationAssociation) - - -# Rating tables. -def rating_mapping(rating_class, **kwds): - kwds = {key: relation(value) for key, value in kwds.items()} - simple_mapping(rating_class, **dict(user=relation(model.User), **kwds)) - - -rating_mapping(model.HistoryRatingAssociation) -rating_mapping(model.HistoryDatasetAssociationRatingAssociation) -rating_mapping(model.StoredWorkflowRatingAssociation) -rating_mapping(model.PageRatingAssociation) -rating_mapping(model.VisualizationRatingAssociation) -rating_mapping(model.HistoryDatasetCollectionRatingAssociation) -rating_mapping(model.LibraryDatasetCollectionRatingAssociation) - -mapper_registry.map_imperatively(model.Job, model.Job.table, properties=dict( - # user=relation( model.User.mapper ), - user=relation(model.User), - galaxy_session=relation(model.GalaxySession), - history=relation(model.History, backref="jobs"), - library_folder=relation(model.LibraryFolder, lazy=True), - parameters=relation(model.JobParameter, lazy=True), - input_datasets=relation(model.JobToInputDatasetAssociation, backref="job"), - input_dataset_collections=relation(model.JobToInputDatasetCollectionAssociation, backref="job", lazy=True), - input_dataset_collection_elements=relation(model.JobToInputDatasetCollectionElementAssociation, - backref="job", lazy=True), - output_dataset_collection_instances=relation(model.JobToOutputDatasetCollectionAssociation, - backref="job", lazy=True), - output_dataset_collections=relation(model.JobToImplicitOutputDatasetCollectionAssociation, - backref="job", lazy=True), - post_job_actions=relation(model.PostJobActionAssociation, backref="job", lazy=False), - input_library_datasets=relation(model.JobToInputLibraryDatasetAssociation, backref="job"), - output_library_datasets=relation(model.JobToOutputLibraryDatasetAssociation, - backref="job", lazy=True), - external_output_metadata=relation(model.JobExternalOutputMetadata, lazy=True, backref='job'), - tasks=relation(model.Task, backref='job') -)) -model.Job.any_output_dataset_deleted = column_property( # type: ignore - exists([model.HistoryDatasetAssociation], - and_(model.Job.table.c.id == model.JobToOutputDatasetAssociation.table.c.job_id, - model.HistoryDatasetAssociation.table.c.id == model.JobToOutputDatasetAssociation.table.c.dataset_id, - model.HistoryDatasetAssociation.table.c.deleted == true()) - ) -) -model.Job.any_output_dataset_collection_instances_deleted = column_property( # type: ignore - exists([model.HistoryDatasetCollectionAssociation.table.c.id], - and_(model.Job.table.c.id == model.JobToOutputDatasetCollectionAssociation.table.c.job_id, - model.HistoryDatasetCollectionAssociation.table.c.id == model.JobToOutputDatasetCollectionAssociation.table.c.dataset_collection_id, - model.HistoryDatasetCollectionAssociation.table.c.deleted == true()) - ) -) - -# Data Manager tables -mapper_registry.map_imperatively(model.DataManagerHistoryAssociation, model.DataManagerHistoryAssociation.table, properties=dict( - history=relation(model.History), - user=relation(model.User, - backref='data_manager_histories') -)) - -mapper_registry.map_imperatively(model.DataManagerJobAssociation, model.DataManagerJobAssociation.table, properties=dict( - job=relation(model.Job, - backref=backref('data_manager_association', uselist=False), - uselist=False) -)) - class_mapper(model.HistoryDatasetCollectionAssociation).add_property( "creating_job_associations", relation(model.JobToOutputDatasetCollectionAssociation, viewonly=True)) diff --git a/lib/galaxy/model/metadata.py b/lib/galaxy/model/metadata.py index ea504a0aba8..9d448d6df36 100644 --- a/lib/galaxy/model/metadata.py +++ b/lib/galaxy/model/metadata.py @@ -18,6 +18,7 @@ from sqlalchemy.orm import object_session from sqlalchemy.orm.attributes import flag_modified import galaxy.model +from galaxy.security.object_wrapper import sanitize_lists_to_string from galaxy.util import ( form_builder, listify, @@ -26,7 +27,6 @@ from galaxy.util import ( unicodify, ) from galaxy.util.json import safe_dumps -from galaxy.util.object_wrapper import sanitize_lists_to_string log = logging.getLogger(__name__) diff --git a/lib/galaxy/model/tags.py b/lib/galaxy/model/tags.py index 14cf79c4d1c..45c742c13a5 100644 --- a/lib/galaxy/model/tags.py +++ b/lib/galaxy/model/tags.py @@ -358,28 +358,28 @@ class GalaxyTagHandler(TagHandler): TagHandler.__init__(self, sa_session) self.item_tag_assoc_info["History"] = ItemTagAssocInfo(model.History, model.HistoryTagAssociation, - model.HistoryTagAssociation.table.c.history_id) + model.HistoryTagAssociation.history_id) self.item_tag_assoc_info["HistoryDatasetAssociation"] = \ ItemTagAssocInfo(model.HistoryDatasetAssociation, model.HistoryDatasetAssociationTagAssociation, - model.HistoryDatasetAssociationTagAssociation.table.c.history_dataset_association_id) + model.HistoryDatasetAssociationTagAssociation.history_dataset_association_id) self.item_tag_assoc_info["HistoryDatasetCollectionAssociation"] = \ ItemTagAssocInfo(model.HistoryDatasetCollectionAssociation, model.HistoryDatasetCollectionTagAssociation, - model.HistoryDatasetCollectionTagAssociation.table.c.history_dataset_collection_id) + model.HistoryDatasetCollectionTagAssociation.history_dataset_collection_id) self.item_tag_assoc_info["LibraryDatasetDatasetAssociation"] = \ ItemTagAssocInfo(model.LibraryDatasetDatasetAssociation, model.LibraryDatasetDatasetAssociationTagAssociation, - model.LibraryDatasetDatasetAssociationTagAssociation.table.c.library_dataset_dataset_association_id) + model.LibraryDatasetDatasetAssociationTagAssociation.library_dataset_dataset_association_id) self.item_tag_assoc_info["Page"] = ItemTagAssocInfo(model.Page, model.PageTagAssociation, - model.PageTagAssociation.table.c.page_id) + model.PageTagAssociation.page_id) self.item_tag_assoc_info["StoredWorkflow"] = ItemTagAssocInfo(model.StoredWorkflow, model.StoredWorkflowTagAssociation, - model.StoredWorkflowTagAssociation.table.c.stored_workflow_id) + model.StoredWorkflowTagAssociation.stored_workflow_id) self.item_tag_assoc_info["Visualization"] = ItemTagAssocInfo(model.Visualization, model.VisualizationTagAssociation, - model.VisualizationTagAssociation.table.c.visualization_id) + model.VisualizationTagAssociation.visualization_id) class GalaxyTagHandlerSession(GalaxyTagHandler): diff --git a/lib/galaxy/quota/__init__.py b/lib/galaxy/quota/__init__.py index d1ca9873593..baa8101cb53 100644 --- a/lib/galaxy/quota/__init__.py +++ b/lib/galaxy/quota/__init__.py @@ -144,7 +144,7 @@ class DatabaseQuotaAgent(QuotaAgent): return self._default_quota(self.model.DefaultQuotaAssociation.types.REGISTERED) def _default_quota(self, default_type): - dqa = self.sa_session.query(self.model.DefaultQuotaAssociation).filter(self.model.DefaultQuotaAssociation.table.c.type == default_type).first() + dqa = self.sa_session.query(self.model.DefaultQuotaAssociation).filter(self.model.DefaultQuotaAssociation.type == default_type).first() if not dqa: return None if dqa.quota.bytes < 0: @@ -161,7 +161,7 @@ class DatabaseQuotaAgent(QuotaAgent): for gqa in quota.groups: self.sa_session.delete(gqa) # Find the old default, assign the new quota if it exists - dqa = self.sa_session.query(self.model.DefaultQuotaAssociation).filter(self.model.DefaultQuotaAssociation.table.c.type == default_type).first() + dqa = self.sa_session.query(self.model.DefaultQuotaAssociation).filter(self.model.DefaultQuotaAssociation.type == default_type).first() if dqa: dqa.quota = quota # Or create if necessary diff --git a/lib/galaxy/util/object_wrapper.py b/lib/galaxy/security/object_wrapper.py similarity index 96% rename from lib/galaxy/util/object_wrapper.py rename to lib/galaxy/security/object_wrapper.py index 16b71f599f3..bec7d268710 100644 --- a/lib/galaxy/util/object_wrapper.py +++ b/lib/galaxy/security/object_wrapper.py @@ -23,6 +23,8 @@ from types import ( TracebackType, ) +import sqlalchemy + NoneType = type(None) NotImplementedType = type(NotImplemented) EllipsisType = type(Ellipsis) @@ -261,6 +263,14 @@ class SafeStringWrapper: return self.__safe_string_wrapper_function__(getattr(self.unsanitized, name)) def __setattr__(self, name, value): + # A class mapped declaratively is a subclass of DeclarativeMeta. It will check at creation time + # if self has _sa_instance_state set, and if not, it'll try to set it. This happens BEFORE self.__init__ + # has been called, so self.unsanitized does not exists, which raises an AttributeError. + # To avoid this, as well as to avoid SQLAlchemy state to be set on SafeStringWrapper, + # we simply ignore this call. + if isinstance(value, sqlalchemy.orm.state.InstanceState): + return + if name in SafeStringWrapper.__NO_WRAP_NAMES__: return object.__setattr__(self, name, value) return setattr(self.unsanitized, name, value) diff --git a/lib/galaxy/tools/evaluation.py b/lib/galaxy/tools/evaluation.py index 0b542b8c323..5e2e748155c 100644 --- a/lib/galaxy/tools/evaluation.py +++ b/lib/galaxy/tools/evaluation.py @@ -4,11 +4,11 @@ import os import shlex import tempfile - from galaxy import model from galaxy.files import ProvidesUserFileSourcesUserContext from galaxy.job_execution.setup import ensure_configs_directory from galaxy.model.none_like import NoneDataset +from galaxy.security.object_wrapper import wrap_with_safe_string from galaxy.tools import global_tool_errors from galaxy.tools.parameters import ( visit_input_values, @@ -42,7 +42,6 @@ from galaxy.util import ( unicodify, ) from galaxy.util.bunch import Bunch -from galaxy.util.object_wrapper import wrap_with_safe_string from galaxy.util.template import fill_template from galaxy.work.context import WorkRequestContext diff --git a/lib/galaxy/tools/wrappers.py b/lib/galaxy/tools/wrappers.py index 5da9940b158..414c0a4ae5a 100644 --- a/lib/galaxy/tools/wrappers.py +++ b/lib/galaxy/tools/wrappers.py @@ -6,12 +6,12 @@ from functools import total_ordering from galaxy import exceptions from galaxy.model.none_like import NoneDataset +from galaxy.security.object_wrapper import wrap_with_safe_string from galaxy.tools.parameters.wrapped_json import ( data_collection_input_to_staging_path_and_source_path, data_input_to_staging_path_and_source_path, ) from galaxy.util import filesystem_safe_string -from galaxy.util.object_wrapper import wrap_with_safe_string log = logging.getLogger(__name__) diff --git a/lib/galaxy/util/dbkeys.py b/lib/galaxy/util/dbkeys.py index c29daf574c3..09525da1ade 100644 --- a/lib/galaxy/util/dbkeys.py +++ b/lib/galaxy/util/dbkeys.py @@ -8,9 +8,9 @@ from json import loads from galaxy.util import ( galaxy_directory, + sanitize_lists_to_string, unicodify, ) -from galaxy.util.object_wrapper import sanitize_lists_to_string log = logging.getLogger(__name__) diff --git a/lib/galaxy/webapps/galaxy/controllers/workflow.py b/lib/galaxy/webapps/galaxy/controllers/workflow.py index c9f456047f6..e181a082456 100644 --- a/lib/galaxy/webapps/galaxy/controllers/workflow.py +++ b/lib/galaxy/webapps/galaxy/controllers/workflow.py @@ -5,7 +5,7 @@ from html.parser import HTMLParser from http.client import HTTPConnection from markupsafe import escape -from sqlalchemy import and_ +from sqlalchemy import and_, desc from sqlalchemy.orm import eagerload, joinedload, lazyload, undefer from sqlalchemy.sql import expression @@ -20,7 +20,6 @@ from galaxy.managers.workflows import ( WorkflowUpdateOptions, ) from galaxy.model.item_attrs import UsesItemRatings -from galaxy.model.mapping import desc from galaxy.security.validate_user_input import validate_publicname from galaxy.tools.parameters.basic import workflow_building_modes from galaxy.util import ( diff --git a/packages/util/requirements.txt b/packages/util/requirements.txt index 47b453fb12f..4c0db6e879a 100644 --- a/packages/util/requirements.txt +++ b/packages/util/requirements.txt @@ -3,6 +3,7 @@ boltons docutils markupsafe packaging +pycryptodome pyyaml requests routes diff --git a/test/unit/data/test_galaxy_mapping.py b/test/unit/data/test_galaxy_mapping.py index 430b333dc0a..a5b347c9c55 100644 --- a/test/unit/data/test_galaxy_mapping.py +++ b/test/unit/data/test_galaxy_mapping.py @@ -130,52 +130,50 @@ class MappingTests(BaseModelTestCase): def test_ratings(self): model = self.model - u = model.User(email="rater@example.com", password="password") + user_email = "rater@example.com" + u = model.User(email=user_email, password="password") self.persist(u) - def persist_and_check_rating(rating_class, **kwds): - rating_association = rating_class() - rating_association.rating = 5 - rating_association.user = u - for key, value in kwds.items(): - setattr(rating_association, key, value) + def persist_and_check_rating(rating_class, item): + rating = 5 + rating_association = rating_class(u, item, rating) self.persist(rating_association) self.expunge() - stored_annotation = self.query(rating_class).all()[0] - assert stored_annotation.rating == 5 - assert stored_annotation.user.email == "rater@example.com" + stored_rating = self.query(rating_class).all()[0] + assert stored_rating.rating == rating + assert stored_rating.user.email == user_email sw = model.StoredWorkflow() sw.user = u self.persist(sw) - persist_and_check_rating(model.StoredWorkflowRatingAssociation, stored_workflow=sw) + persist_and_check_rating(model.StoredWorkflowRatingAssociation, sw) h = model.History(name="History for Rating", user=u) self.persist(h) - persist_and_check_rating(model.HistoryRatingAssociation, history=h) + persist_and_check_rating(model.HistoryRatingAssociation, h) d1 = model.HistoryDatasetAssociation(extension="txt", history=h, create_dataset=True, sa_session=model.session) self.persist(d1) - persist_and_check_rating(model.HistoryDatasetAssociationRatingAssociation, hda=d1) + persist_and_check_rating(model.HistoryDatasetAssociationRatingAssociation, d1) page = model.Page() page.user = u self.persist(page) - persist_and_check_rating(model.PageRatingAssociation, page=page) + persist_and_check_rating(model.PageRatingAssociation, page) visualization = model.Visualization() visualization.user = u self.persist(visualization) - persist_and_check_rating(model.VisualizationRatingAssociation, visualization=visualization) + persist_and_check_rating(model.VisualizationRatingAssociation, visualization) dataset_collection = model.DatasetCollection(collection_type="paired") history_dataset_collection = model.HistoryDatasetCollectionAssociation(collection=dataset_collection) self.persist(history_dataset_collection) - persist_and_check_rating(model.HistoryDatasetCollectionRatingAssociation, history_dataset_collection=history_dataset_collection) + persist_and_check_rating(model.HistoryDatasetCollectionRatingAssociation, history_dataset_collection) library_dataset_collection = model.LibraryDatasetCollectionAssociation(collection=dataset_collection) self.persist(library_dataset_collection) - persist_and_check_rating(model.LibraryDatasetCollectionRatingAssociation, library_dataset_collection=library_dataset_collection) + persist_and_check_rating(model.LibraryDatasetCollectionRatingAssociation, library_dataset_collection) def test_display_name(self): @@ -255,7 +253,7 @@ class MappingTests(BaseModelTestCase): sw = model.StoredWorkflow() sw.user = u - tag_and_test(sw, model.StoredWorkflowTagAssociation, "tagged_workflows") + tag_and_test(sw, model.StoredWorkflowTagAssociation, "tagged_stored_workflows") h = model.History(name="History for Tagging", user=u) tag_and_test(h, model.HistoryTagAssociation, "tagged_histories") diff --git a/test/unit/model/test_mapping.py b/test/unit/model/test_mapping.py new file mode 100644 index 00000000000..831fd5544f4 --- /dev/null +++ b/test/unit/model/test_mapping.py @@ -0,0 +1,7692 @@ +""" +This module contains tests for column- and relationship-mapped attributes of +models, table names, as well as table-level indexes and constraints. These +tests do not address any business logic defined in the model. + +Tests are grouped into classes, one for each model (tests do NOT share class instances: +https://docs.pytest.org/en/6.2.x/getting-started.html#group-multiple-tests-in-a-class) + + +Example of a simple model and its tests: + +class Planet(Base): + __tablename__ = 'planet' + __table_args__ = (Index('index_name', 'name'),) + + id = Column(Integer, primary_key=True) + name = Column(String) + star_id = Column(Integer, ForeignKey('star.id')) + + star = relationship('Star') + satellites = relationship('Satellite') + + def __init__(self, name): + self.name = name + + +class TestPlanet(BaseTest): # BaseTest is a base class; we need it to get the type of the model under test + + # test table name and table-level indexes and constraints + def test_table(self, cls_): # cls_ is a fixture defined in BaseTest, returns the type under test. + assert cls_.__tablename__ == 'planet' # verify table name + assert has_index(cls.__table__, ('name',)) # verify index; second arg is a tuple containg field names + + # test column-mapped fields + def test_columns(self, session, cls_, star): # star is a fixture that provides a persisted instance of Star + name = 'Saturn' # create test values + obj = cls_(name=name) # pass test values to constructor + obj.star = star # assign test values to obj if can't pass to constructor + + with dbcleanup(session, obj) as obj_id: # use context manager to ensure obj is deleted from db on exit. + stored_obj = get_stored_obj(session, cls_, obj_id) # retrieve data from db and create new obj. + # check ALL column-mapped fields + assert stored_obj.id == obj_id + assert stored_obj.name == name + assert stored_obj.star_id == star.id # test the column attribute star_id + + # test relationship-mapped fields + def test_relationships(self, session, cls_, star, satellite): # satellite is a fixture for Satellite + obj = cls_(name=name) # use minimal possible constructor + obj.star = star # assign test values to test relationship-mapped attributes (not passed to constructor) + obj.satellites.append(satellite) # add a related object + + with dbcleanup(session, obj) as obj_id: # same as in previous test: store, then retrieve + stored_obj = get_stored_obj(session, cls_, obj_id) + # check ALL relationship-mapped fields + assert stored_obj.star.id == star.id # test the relationship attribute star.id (note the dot operator) + assert stored_obj.satellites == [satellite] # verify collecion of related objects + + +See other model tests in this module for examples of more complex setups. +""" + +from contextlib import contextmanager +from datetime import datetime, timedelta +from uuid import uuid4 + +import pytest +from sqlalchemy import ( + and_, + delete, + select, + UniqueConstraint, +) + +import galaxy.model.mapping as mapping + + +class BaseTest: + @pytest.fixture + def cls_(self, model): + """ + Return class under test. + Assumptions: if the class under test is Foo, then the class grouping + the tests should be a subclass of BaseTest, named TestFoo. + """ + prefix = len('Test') + class_name = self.__class__.__name__[prefix:] + return getattr(model, class_name) + + +class TestAPIKeys(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'api_keys' + + def test_columns(self, session, cls_, user): + create_time, user_id, key = datetime.now(), user.id, get_unique_value() + obj = cls_(user_id=user_id, key=key, create_time=create_time) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.user_id == user_id + assert stored_obj.key == key + + def test_relationships(self, session, cls_, user): + obj = cls_(user_id=user.id, key=get_unique_value()) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.user.id == user.id + + +class TestCleanupEvent(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'cleanup_event' + + def test_columns(self, session, cls_): + create_time, message = datetime.now(), 'a' + obj = cls_(create_time=create_time, message=message) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.message == message + + +class TestCleanupEventDatasetAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'cleanup_event_dataset_association' + + def test_columns(self, session, cls_, cleanup_event, dataset): + create_time = datetime.now() + obj = cls_(create_time=create_time, cleanup_event_id=cleanup_event.id, dataset_id=dataset.id) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.cleanup_event_id == cleanup_event.id + assert stored_obj.dataset_id == dataset.id + + +class TestCleanupEventHistoryAssociation(BaseTest): + def test_table(self, cls_): + assert cls_.__tablename__ == 'cleanup_event_history_association' + + def test_columns(self, session, cls_, cleanup_event, history): + create_time = datetime.now() + obj = cls_(create_time=create_time, cleanup_event_id=cleanup_event.id, history_id=history.id) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.cleanup_event_id == cleanup_event.id + assert stored_obj.history_id == history.id + + +class TestCleanupEventHistoryDatasetAssociationAssociation(BaseTest): + def test_table(self, cls_): + assert cls_.__tablename__ == 'cleanup_event_hda_association' + + def test_columns(self, session, cls_, cleanup_event, history_dataset_association): + create_time = datetime.now() + obj = cls_( + create_time=create_time, + cleanup_event_id=cleanup_event.id, + hda_id=history_dataset_association.id + ) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.cleanup_event_id == cleanup_event.id + assert stored_obj.hda_id == history_dataset_association.id + + +class TestCleanupEventImplicitlyConvertedDatasetAssociationAssociation(BaseTest): + def test_table(self, cls_): + assert cls_.__tablename__ == 'cleanup_event_icda_association' + + def test_columns(self, session, cls_, cleanup_event, implicitly_converted_dataset_association): + create_time = datetime.now() + obj = cls_( + create_time=create_time, + cleanup_event_id=cleanup_event.id, + icda_id=implicitly_converted_dataset_association.id + ) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.cleanup_event_id == cleanup_event.id + assert stored_obj.icda_id == implicitly_converted_dataset_association.id + + +class TestCleanupEventLibraryAssociation(BaseTest): + def test_table(self, cls_): + assert cls_.__tablename__ == 'cleanup_event_library_association' + + def test_columns(self, session, cls_, cleanup_event, library): + create_time = datetime.now() + obj = cls_(create_time=create_time, cleanup_event_id=cleanup_event.id, library_id=library.id) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.cleanup_event_id == cleanup_event.id + assert stored_obj.library_id == library.id + + +class TestCleanupEventLibraryDatasetAssociation(BaseTest): + def test_table(self, cls_): + assert cls_.__tablename__ == 'cleanup_event_library_dataset_association' + + def test_columns(self, session, cls_, cleanup_event, library_dataset): + create_time = datetime.now() + obj = cls_( + create_time=create_time, + cleanup_event_id=cleanup_event.id, + library_dataset_id=library_dataset.id + ) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.cleanup_event_id == cleanup_event.id + assert stored_obj.library_dataset_id == library_dataset.id + + +class TestCleanupEventLibraryDatasetDatasetAssociationAssociation(BaseTest): + def test_table(self, cls_): + assert cls_.__tablename__ == 'cleanup_event_ldda_association' + + def test_columns(self, session, cls_, cleanup_event, library_dataset_dataset_association): + create_time = datetime.now() + obj = cls_( + create_time=create_time, + cleanup_event_id=cleanup_event.id, + ldda_id=library_dataset_dataset_association.id + ) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.cleanup_event_id == cleanup_event.id + assert stored_obj.ldda_id == library_dataset_dataset_association.id + + +class TestCleanupEventLibraryFolderAssociation(BaseTest): + def test_table(self, cls_): + assert cls_.__tablename__ == 'cleanup_event_library_folder_association' + + def test_columns(self, session, cls_, cleanup_event, library_folder): + create_time = datetime.now() + obj = cls_( + create_time=create_time, + cleanup_event_id=cleanup_event.id, + library_folder_id=library_folder.id + ) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.cleanup_event_id == cleanup_event.id + assert stored_obj.library_folder_id == library_folder.id + + +class TestCleanupEventMetadataFileAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'cleanup_event_metadata_file_association' + + def test_columns(self, session, cls_, cleanup_event, metadata_file): + create_time = datetime.now() + obj = cls_( + create_time=create_time, + cleanup_event_id=cleanup_event.id, + metadata_file_id=metadata_file.id + ) + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.cleanup_event_id == cleanup_event.id + assert stored_obj.metadata_file_id == metadata_file.id + + +class TestCloudAuthz(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'cloudauthz' + + def test_columns(self, session, cls_, user, user_authnz_token): + provider, config, description = 'a', 'b', 'c' + obj = cls_(user.id, provider, config, user_authnz_token.id, description) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.user_id == user.id + assert stored_obj.provider == provider + assert stored_obj.config == config + assert stored_obj.authn_id == user_authnz_token.id + assert stored_obj.tokens is None + assert stored_obj.last_update + assert stored_obj.last_activity + assert stored_obj.description == description + assert stored_obj.create_time + + def test_relationships(self, session, cls_, user, user_authnz_token): + obj = cls_(user.id, None, None, user_authnz_token.id, 'c') + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.user.id == user.id + assert stored_obj.authn.id == user_authnz_token.id + + +class TestDataManagerHistoryAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'data_manager_history_association' + + def test_columns(self, session, cls_, history, user): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_() + obj.create_time = create_time + obj.update_time = update_time + obj.history = history + obj.user = user + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.history_id == history.id + assert stored_obj.user_id == user.id + + def test_relationships(self, session, cls_, history, user): + obj = cls_() + obj.history = history + obj.user = user + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.history.id == history.id + assert stored_obj.user.id == user.id + + +class TestDataManagerJobAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'data_manager_job_association' + assert has_index(cls_.__table__, ('data_manager_id',)) + + def test_columns(self, session, cls_, job): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + data_manager_id = 'a' + obj = cls_() + obj.create_time = create_time + obj.update_time = update_time + session.add(job) # must be bound to a session for lazy load of attributes + obj.job = job + obj.data_manager_id = data_manager_id + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.job_id == job.id + assert stored_obj.data_manager_id == data_manager_id + + def test_relationships(self, session, cls_, job): + session.add(job) # must be bound to a session for lazy load of attributes + obj = cls_(job=job) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + + +class TestDataset(BaseTest): + + def test_table(self, cls_): + # mapped imperatively, so do not test cls_.__tablename__ + assert cls_.table.name == 'dataset' + + def test_columns(self, session, cls_, job): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + state = 'a' + deleted = True + purged = True + purgable = False + object_store_id = 'b' + external_filename = 'c' + _extra_files_path = 'd' + created_from_basename = 'e' + file_size = 1 + total_size = 2 + + obj = cls_() + obj.job = job + obj.create_time = create_time + obj.update_time = update_time + obj.state = state + obj.deleted = deleted + obj.purged = purged + obj.purgable = purgable + obj.object_store_id = object_store_id + obj.external_filename = external_filename + obj._extra_files_path = _extra_files_path + obj.created_from_basename = created_from_basename + obj.file_size = file_size + obj.total_size = total_size + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.state == state + assert stored_obj.deleted == deleted + assert stored_obj.purged == purged + assert stored_obj.purgable == purgable + assert stored_obj.object_store_id == object_store_id + assert stored_obj.external_filename == external_filename + assert stored_obj._extra_files_path == _extra_files_path + assert stored_obj.created_from_basename == created_from_basename + assert stored_obj.file_size == file_size + assert stored_obj.total_size == total_size + + def test_relationships( + self, + session, + cls_, + job, + dataset_permission, + history_dataset_association, + library_dataset_dataset_association, + dataset_hash, + dataset_source, + history_dataset_association_factory, + ): + obj = cls_() + obj.job = job + obj.actions.append(dataset_permission) + obj.history_associations.append(history_dataset_association) + obj.library_associations.append(library_dataset_dataset_association) + obj.hashes.append(dataset_hash) + obj.sources.append(dataset_source) + + hda = history_dataset_association_factory() + hda.purged = True + obj.history_associations.append(hda) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + assert stored_obj.actions == [dataset_permission] + assert stored_obj.active_history_associations == [history_dataset_association] + assert stored_obj.purged_history_associations[0].id == hda.id + assert stored_obj.active_library_associations == [library_dataset_dataset_association] + assert stored_obj.hashes == [dataset_hash] + assert stored_obj.sources == [dataset_source] + assert stored_obj.library_associations == [library_dataset_dataset_association] + assert are_same_entity_collections( + stored_obj.history_associations, [hda, history_dataset_association]) + + delete_from_database(session, hda) + + +class TestDatasetCollection(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'dataset_collection' + + def test_columns(self, session, cls_): + collection_type = 'a' + populated_state = 'b' + populated_state_message = 'c' + element_count = 1 + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + + obj = cls_() + obj.collection_type = collection_type + obj.populated_state = populated_state + obj.populated_state_message = populated_state_message + obj.element_count = element_count + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.collection_type == collection_type + assert stored_obj.populated_state == populated_state + assert stored_obj.populated_state_message == populated_state_message + assert stored_obj.element_count == element_count + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + + def test_relationships( + self, + session, + cls_, + dataset_collection_element, + job_to_implicit_output_dataset_collection_association, + ): + obj = cls_() + obj.collection_type, obj.populated_state = 'a', 'b' + obj.elements.append(dataset_collection_element) + obj.output_dataset_collections.append(job_to_implicit_output_dataset_collection_association) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.elements == [dataset_collection_element] + assert (stored_obj.output_dataset_collections + == [job_to_implicit_output_dataset_collection_association]) + + +class TestDatasetCollectionElement(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'dataset_collection_element' + + def test_columns( + self, + session, + cls_, + dataset_collection, + history_dataset_association, + library_dataset_dataset_association, + dataset_collection_factory, + ): + element_index, element_identifier = 1, 'a' + obj = cls_(element=history_dataset_association) # using hda is sufficient for this test + obj.element_index = element_index + obj.element_identifier = element_identifier + obj.hda = history_dataset_association + obj.ldda = library_dataset_dataset_association + obj.child_collection = dataset_collection + + # set dataset_collection_id (can't set directly; persisted automatically) + parent_collection = dataset_collection_factory() + parent_collection.elements.append(obj) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.dataset_collection_id == parent_collection.id + assert stored_obj.hda_id == history_dataset_association.id + assert stored_obj.ldda_id == library_dataset_dataset_association.id + assert stored_obj.child_collection_id == dataset_collection.id + assert stored_obj.element_index == element_index + assert stored_obj.element_identifier == element_identifier + + delete_from_database(session, parent_collection) + + def test_relationships( + self, + session, + cls_, + dataset_collection, + history_dataset_association, + library_dataset_dataset_association, + dataset_collection_factory, + ): + obj = cls_(element=history_dataset_association) # using hda is sufficient for this test + obj.hda = history_dataset_association + obj.ldda = library_dataset_dataset_association + obj.child_collection = dataset_collection + + parent_collection = dataset_collection_factory() + obj.collection = parent_collection # same as parent_collection.elements.append(obj) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.hda.id == history_dataset_association.id + assert stored_obj.ldda.id == library_dataset_dataset_association.id + assert stored_obj.child_collection.id == dataset_collection.id + assert stored_obj.collection.id == parent_collection.id + + delete_from_database(session, parent_collection) + + +class TestDatasetHash(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'dataset_hash' + + def test_columns(self, session, cls_, dataset): + hash_function, hash_value, extra_files_path = 'a', 'b', 'c' + obj = cls_() + obj.dataset = dataset + obj.hash_function = hash_function + obj.hash_value = hash_value + obj.extra_files_path = extra_files_path + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.dataset_id == dataset.id + assert stored_obj.hash_function == hash_function + assert stored_obj.hash_value == hash_value + assert stored_obj.extra_files_path == extra_files_path + + def test_relationships(self, session, cls_, dataset): + obj = cls_() + obj.dataset = dataset + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.dataset.id == dataset.id + + +class TestDatasetPermissions(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'dataset_permissions' + + def test_columns(self, session, cls_, dataset, role): + action = 'a' + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_(action, dataset, role) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.update_time == update_time + assert stored_obj.action == action + assert stored_obj.dataset_id == dataset.id + assert stored_obj.role_id == role.id + + def test_relationships(self, session, cls_, dataset, role): + obj = cls_(None, dataset, role) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.dataset == dataset + assert stored_obj.role == role + + +class TestDatasetSource(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'dataset_source' + + def test_columns(self, session, cls_, dataset): + source_uri, extra_files_path, transform = 'a', 'b', 'c' + obj = cls_() + obj.dataset = dataset + obj.source_uri = source_uri + obj.extra_files_path = extra_files_path + obj.transform = transform + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.dataset_id == dataset.id + assert stored_obj.source_uri == source_uri + assert stored_obj.extra_files_path == extra_files_path + assert stored_obj.transform == transform + + def test_relationships(self, session, cls_, dataset, dataset_source_hash): + obj = cls_() + obj.dataset = dataset + obj.hashes.append(dataset_source_hash) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.dataset.id == dataset.id + assert stored_obj.hashes == [dataset_source_hash] + + +class TestDatasetSourceHash(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'dataset_source_hash' + + def test_columns(self, session, cls_, dataset_source): + hash_function, hash_value = 'a', 'b' + obj = cls_() + obj.source = dataset_source + obj.hash_function = hash_function + obj.hash_value = hash_value + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.dataset_source_id == dataset_source.id + assert stored_obj.hash_function == hash_function + assert stored_obj.hash_value == hash_value + + def test_relationships(self, session, cls_, dataset_source): + obj = cls_() + obj.source = dataset_source + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.source.id == dataset_source.id + + +class TestDefaultHistoryPermissions(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'default_history_permissions' + + def test_columns(self, session, cls_, history, role): + action = 'a' + obj = cls_(history, action, role) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.action == action + assert stored_obj.history_id == history.id + assert stored_obj.role_id == role.id + + def test_relationships(self, session, cls_, history, role): + obj = cls_(history, None, role) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.history.id == history.id + assert stored_obj.role == role + + +class TestDefaultQuotaAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'default_quota_association' + + def test_columns(self, session, cls_, quota): + type_ = cls_.types.REGISTERED + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_(type_, quota) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.type == type_ + assert stored_obj.quota_id == quota.id + + def test_relationships(self, session, cls_, quota): + obj = cls_(cls_.types.REGISTERED, quota) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.quota.id == quota.id + + +class TestDefaultUserPermissions(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'default_user_permissions' + + def test_columns(self, session, cls_, user, role): + action = 'a' + obj = cls_(user, action, role) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.user_id == user.id + assert stored_obj.action == action + assert stored_obj.role_id == role.id + + def test_relationships(self, session, cls_, user, role): + obj = cls_(user, None, role) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.user.id == user.id + assert stored_obj.role.id == role.id + + +class TestDeferredJob(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'deferred_job' + + def test_columns(self, session, cls_): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + state, plugin, params = 'a', 'b', 'c' + obj = cls_(state, plugin, params) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.state == state + assert stored_obj.plugin == plugin + assert stored_obj.params == params + + def test_relationships(self, session, cls_, genome_index_tool_data): + obj = cls_() + obj.deferred_job.append(genome_index_tool_data) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.deferred_job == [genome_index_tool_data] + + +class TestDynamicTool(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'dynamic_tool' + + def test_columns(self, session, cls_): + tool_format = 'a' + tool_id = 'b' + tool_version = 'c' + tool_path = 'd' + tool_directory = 'e' + uuid = uuid4() + active = True + hidden = True + value = 'f' + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_(tool_format, tool_id, tool_version, tool_path, tool_directory, uuid, + active, hidden, value) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.uuid == uuid + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.tool_id == tool_id + assert stored_obj.tool_version == tool_version + assert stored_obj.tool_format == tool_format + assert stored_obj.tool_path == tool_path + assert stored_obj.tool_directory == tool_directory + assert stored_obj.hidden == hidden + assert stored_obj.active == active + assert stored_obj.value == value + + def test_relationships(self, session, cls_, workflow_step): + obj = cls_() + obj.workflow_steps.append(workflow_step) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_steps == [workflow_step] + + +class TestEvent(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'event' + + def test_columns(self, session, cls_, history, galaxy_session, user): + message, tool_id = 'a', 'b' + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_(message, history, user, galaxy_session) + obj.create_time = create_time + obj.update_time = update_time + obj.tool_id = tool_id + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.history_id == history.id + assert stored_obj.user_id == user.id + assert stored_obj.message == message + assert stored_obj.session_id == galaxy_session.id + assert stored_obj.tool_id == tool_id + + def test_relationships(self, session, cls_, history, galaxy_session, user): + obj = cls_(None, history, user, galaxy_session) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.history.id == history.id + assert stored_obj.user.id == user.id + assert stored_obj.galaxy_session.id == galaxy_session.id + + +class TestExtendedMetadata(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'extended_metadata' + + def test_columns(self, session, cls_): + data = 'a' + obj = cls_(data) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.data == data + + def test_relationships(self, session, cls_, extended_metadata_index): + obj = cls_(None) + obj.children.append(extended_metadata_index) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.children == [extended_metadata_index] + + +class TestExtendedMetadataIndex(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'extended_metadata_index' + + def test_columns(self, session, cls_, extended_metadata): + path, value = 'a', 'b' + obj = cls_(extended_metadata, path, value) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.extended_metadata_id == extended_metadata.id + assert stored_obj.path == path + assert stored_obj.value == value + + def test_relationships(self, session, cls_, extended_metadata): + obj = cls_(extended_metadata, None, None) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.extended_metadata.id == extended_metadata.id + + +class TestFormDefinition(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'form_definition' + + def test_columns(self, session, cls_, form_definition_current): + name, desc, fields, type, layout = 'a', 'b', 'c', 'd', 'e' + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_() + obj.name = name + obj.desc = desc + obj.form_definition_current = form_definition_current + obj.fields = fields + obj.type = type + obj.layout = layout + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.name == name + assert stored_obj.desc == desc + assert stored_obj.form_definition_current_id == form_definition_current.id + assert stored_obj.fields == fields + assert stored_obj.type == type + assert stored_obj.layout == layout + + def test_relationships(self, session, cls_, form_definition_current): + obj = cls_(name='a', form_definition_current=form_definition_current) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.form_definition_current.id == form_definition_current.id + + +class TestFormDefinitionCurrent(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'form_definition_current' + + def test_columns(self, session, cls_, form_definition): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + deleted = True + obj = cls_() + obj.create_time = create_time + obj.update_time = update_time + obj.latest_form = form_definition + obj.deleted = deleted + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.latest_form_id == form_definition.id + assert stored_obj.deleted == deleted + + def test_relationships(self, session, cls_, form_definition): + obj = cls_(form_definition) + obj.forms.append(form_definition) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.latest_form.id == form_definition.id + assert stored_obj.forms == [form_definition] + + +class TestFormValues(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'form_values' + + def test_columns(self, session, cls_, form_definition): + content = 'a' + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_() + obj.form_definition = form_definition + obj.content = content + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.content == content + assert stored_obj.form_definition_id == form_definition.id + + def test_relationships(self, session, cls_, form_definition): + obj = cls_(form_definition) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.form_definition.id == form_definition.id + + +class TestGalaxySession(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'galaxy_session' + + def test_columns(self, session, cls_, user, history, galaxy_session): + + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + remote_host = 'a' + remote_addr = 'b' + referer = 'c' + session_key = get_unique_value() + is_valid = True + disk_usage = 9 + last_action = update_time + timedelta(hours=1) + + obj = cls_(user=user, current_history=history, prev_session_id=galaxy_session.id) + + obj.create_time = create_time + obj.update_time = update_time + obj.remote_host = remote_host + obj.remote_addr = remote_addr + obj.referer = referer + obj.session_key = session_key + obj.is_valid = is_valid + obj.disk_usage = disk_usage + obj.last_action = last_action + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.user_id == user.id + assert stored_obj.remote_host == remote_host + assert stored_obj.remote_addr == remote_addr + assert stored_obj.referer == referer + assert stored_obj.current_history_id == history.id + assert stored_obj.session_key == session_key + assert stored_obj.is_valid == is_valid + assert stored_obj.prev_session_id == galaxy_session.id + assert stored_obj.disk_usage == disk_usage + assert stored_obj.last_action == last_action + + def test_relationships(self, session, cls_, user, history, galaxy_session_history_association): + obj = cls_(user=user, current_history=history) + obj.session_key = get_unique_value() + obj.histories.append(galaxy_session_history_association) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.user.id == user.id + assert stored_obj.current_history.id == history.id + assert stored_obj.histories == [galaxy_session_history_association] + + +class TestGalaxySessionToHistoryAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'galaxy_session_to_history' + + def test_columns(self, session, cls_, galaxy_session, history): + create_time = datetime.now() + obj = cls_(galaxy_session, history) + obj.create_time = create_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.session_id == galaxy_session.id + assert stored_obj.history_id == history.id + + def test_relationships(self, session, cls_, galaxy_session, history): + obj = cls_(galaxy_session, history) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.galaxy_session.id == galaxy_session.id + assert stored_obj.history.id == history.id + + +class TestGenomeIndexToolData(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'genome_index_tool_data' + + def test_columns(self, session, cls_, job, deferred_job, transfer_job, dataset, user): + fasta_path = 'a' + created_time = datetime.now() + modified_time = created_time + timedelta(hours=1) + indexer = 'b' + obj = cls_() + obj.job = job + obj.deferred = deferred_job + obj.transfer = transfer_job + obj.dataset = dataset + obj.fasta_path = fasta_path + obj.created_time = created_time + obj.modified_time = modified_time + obj.indexer = indexer + obj.user = user + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.deferred_job_id == deferred_job.id + assert stored_obj.transfer_job_id == transfer_job.id + assert stored_obj.dataset_id == dataset.id + assert stored_obj.fasta_path == fasta_path + assert stored_obj.created_time == created_time + assert stored_obj.modified_time == modified_time + assert stored_obj.indexer == indexer + assert stored_obj.user_id == user.id + + def test_relationships(self, session, cls_, job, deferred_job, transfer_job, dataset, user): + obj = cls_() + obj.job = job + obj.deferred = deferred_job + obj.transfer = transfer_job + obj.dataset = dataset + obj.user = user + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + assert stored_obj.deferred.id == deferred_job.id + assert stored_obj.transfer.id == transfer_job.id + assert stored_obj.dataset.id == dataset.id + assert stored_obj.user.id == user.id + + +class TestGroup(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'galaxy_group' + + def test_columns(self, session, cls_): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + name = get_unique_value() + deleted = True + + obj = cls_() + obj.create_time = create_time + obj.update_time = update_time + obj.name = name + obj.deleted = deleted + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.name == name + assert stored_obj.deleted == deleted + + def test_relationships( + self, + session, + cls_, + group_quota_association, + group_role_association, + user_group_association, + ): + obj = cls_(name=get_unique_value()) + obj.quotas.append(group_quota_association) + obj.roles.append(group_role_association) + obj.users.append(user_group_association) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.quotas == [group_quota_association] + assert stored_obj.roles == [group_role_association] + assert stored_obj.users == [user_group_association] + + +class TestGroupQuotaAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'group_quota_association' + + def test_columns(self, session, cls_, group, quota): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_(group, quota) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.group_id == group.id + assert stored_obj.quota_id == quota.id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + + def test_relationships(self, session, cls_, group, quota): + obj = cls_(group, quota) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.group.id == group.id + assert stored_obj.quota.id == quota.id + + +class TestGroupRoleAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'group_role_association' + + def test_columns(self, session, cls_, group, role): + obj = cls_(group, role) + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.group_id == group.id + assert stored_obj.role_id == role.id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + + def test_relationships(self, session, cls_, group, role): + obj = cls_(group, role) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.group.id == group.id + assert stored_obj.role.id == role.id + + +class TestHistory(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'history' + assert has_index(cls_.__table__, ('slug',)) + + def test_columns(self, session, cls_, user): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + name = 'a' + hid_counter = 2 + deleted = True + purged = True + importing = True + genome_build = 'b' + importable = True + slug = 'c' + published = True + obj = cls_(name=name, user=user) + obj.create_time = create_time + obj.update_time = update_time + obj.hid_counter = hid_counter + obj.deleted = deleted + obj.purged = purged + obj.importing = importing + obj.genome_build = genome_build + obj.importable = importable + obj.slug = slug + obj.published = published + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + # cannot test directly (trigger); applies to both column and column property + assert stored_obj.update_time + assert stored_obj.user_id == user.id + assert stored_obj.name == name + assert stored_obj.hid_counter == hid_counter + assert stored_obj.deleted == deleted + assert stored_obj.purged == purged + assert stored_obj.importing == importing + assert stored_obj.genome_build == genome_build + assert stored_obj.importable == importable + assert stored_obj.slug == slug + assert stored_obj.published == published + + def test_relationships( + self, + session, + cls_, + user, + history_dataset_association, + job_export_history_archive, + history_dataset_collection_association, + history_tag_association, + history_annotation_association, + history_rating_association, + default_history_permissions, + history_user_share_association, + galaxy_session_history_association, + workflow_invocation, + job, + ): + obj = cls_() + obj.user = user + obj.datasets.append(history_dataset_association) + obj.dataset_collections.append(history_dataset_collection_association) + obj.exports.append(job_export_history_archive) + obj.tags.append(history_tag_association) + obj.annotations.append(history_annotation_association) + obj.ratings.append(history_rating_association) + obj.default_permissions.append(default_history_permissions) + obj.users_shared_with.append(history_user_share_association) + obj.galaxy_sessions.append(galaxy_session_history_association) + obj.workflow_invocations.append(workflow_invocation) + obj.jobs.append(job) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.user.id == user.id + assert stored_obj.datasets == [history_dataset_association] + assert stored_obj.exports == [job_export_history_archive] + assert stored_obj.active_datasets == [history_dataset_association] + assert stored_obj.active_dataset_collections == [history_dataset_collection_association] + assert stored_obj.visible_datasets == [history_dataset_association] + assert stored_obj.visible_dataset_collections == [history_dataset_collection_association] + assert stored_obj.tags == [history_tag_association] + assert stored_obj.annotations == [history_annotation_association] + assert stored_obj.ratings == [history_rating_association] + # This doesn't test the average amount, just the mapping. + assert stored_obj.average_rating == history_rating_association.rating + assert stored_obj.users_shared_with_count == 1 + assert stored_obj.users_shared_with == [history_user_share_association] + assert stored_obj.default_permissions == [default_history_permissions] + assert stored_obj.galaxy_sessions == [galaxy_session_history_association] + assert stored_obj.workflow_invocations == [workflow_invocation] + assert stored_obj.jobs == [job] + + def test_average_rating(self, session, history, user, history_rating_association_factory): + _run_average_rating_test(session, history, user, history_rating_association_factory) + + +class TestHistoryAnnotationAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'history_annotation_association' + assert has_index(cls_.__table__, ('annotation',)) + + def test_columns(self, session, cls_, history, user): + annotation = 'a' + obj = cls_() + obj.user = user + obj.history = history + obj.annotation = annotation + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.history_id == history.id + assert stored_obj.user_id == user.id + assert stored_obj.annotation == annotation + + def test_relationships(self, session, cls_, history, user): + obj = cls_() + obj.user = user + obj.history = history + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.history.id == history.id + assert stored_obj.user.id == user.id + + +class TestHistoryAudit(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'history_audit' + + def test_columns_and_relationships(self, session, cls_, history): + update_time = datetime.now() + obj = cls_(history, update_time) + + where_clause = and_(cls_.history_id == history.id, cls_.update_time == update_time) + + with dbcleanup(session, obj, where_clause): + stored_obj = get_stored_obj(session, cls_, where_clause=where_clause) + # test columns + assert stored_obj.history_id == history.id + assert stored_obj.update_time == update_time + # test relationships + assert stored_obj.history.id == history.id + + +class TestHistoryDatasetAssociation(BaseTest): + + def test_table(self, cls_): + # mapped imperatively, so do not test cls_.__tablename__ + assert cls_.table.name == 'history_dataset_association' + + def test_columns( + self, + session, + cls_, + history, + dataset, + library_dataset_dataset_association, + extended_metadata, + history_dataset_collection_association, + history_dataset_association_factory, + ): + copied_from_hda = history_dataset_association_factory() + parent = history_dataset_association_factory() + + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + state = 'a' + name = 'b' + info = 'c' + blurb = 'd' + peek = 'e' + tool_version = 'f' + extension = 'g' + _metadata = 'h' + designation = 'i' + deleted = False + visible = False + version = 1 + hid = 2 + purged = False + validated_state = 'j' + validated_state_message = 'k' + + obj = cls_() + obj.history = history + obj.dataset = dataset + obj.create_time = create_time + obj.update_time = update_time + obj.state = state + obj.copied_from_history_dataset_association = copied_from_hda + obj.copied_from_library_dataset_dataset_association = library_dataset_dataset_association + obj.name = name + obj.info = info + obj.blurb = blurb + obj.peek = peek + obj.tool_version = tool_version + obj.extension = extension + obj._metadata = _metadata + obj.parent_id = parent.id + obj.designation = designation + obj.deleted = deleted + obj.visible = visible + obj.extended_metadata = extended_metadata + obj.version = version + obj.hid = hid + obj.purged = purged + obj.validated_state = validated_state + obj.validated_state_message = validated_state_message + obj.hidden_beneath_collection_instance = history_dataset_collection_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.history_id == history.id + assert stored_obj.dataset_id == dataset.id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.state == state + assert stored_obj.copied_from_history_dataset_association_id == copied_from_hda.id + assert (stored_obj.copied_from_library_dataset_dataset_association_id + == library_dataset_dataset_association.id) + assert stored_obj.name == name + assert stored_obj.info == info + assert stored_obj.blurb == blurb + assert stored_obj.peek == peek + assert stored_obj.tool_version == tool_version + assert stored_obj.extension == extension + assert stored_obj._metadata == _metadata + assert stored_obj.parent_id == parent.id + assert stored_obj.designation == designation + assert stored_obj.deleted == deleted + assert stored_obj.visible == visible + assert stored_obj.extended_metadata_id == extended_metadata.id + assert stored_obj.version == version + assert stored_obj.hid == hid + assert stored_obj.purged == purged + assert stored_obj.validated_state == validated_state + assert stored_obj.validated_state_message == validated_state_message + assert (stored_obj.hidden_beneath_collection_instance_id + == history_dataset_collection_association.id) + + delete_from_database(session, [copied_from_hda, parent]) + + def test_relationships( + self, + session, + cls_, + history, + dataset, + extended_metadata, + history_dataset_collection_association, + history_dataset_association_factory, + history_dataset_association_tag_association, + history_dataset_association_annotation_association, + history_dataset_association_rating_association, + job_to_input_dataset_association, + job_to_output_dataset_association, + implicitly_converted_dataset_association_factory, + library_dataset_dataset_association_factory, + ): + copied_from_hda = history_dataset_association_factory() + copied_to_hda = history_dataset_association_factory() + copied_from_ldda = library_dataset_dataset_association_factory() + copied_to_ldda = library_dataset_dataset_association_factory() + icda = implicitly_converted_dataset_association_factory() + icpda = implicitly_converted_dataset_association_factory() + persisted = [copied_from_hda, copied_to_hda, copied_from_ldda, copied_to_ldda, icda, icpda] + + obj = cls_() + obj.history = history + obj.dataset = dataset + obj.copied_from_history_dataset_association = copied_from_hda + obj.copied_from_library_dataset_dataset_association = copied_from_ldda + obj.extended_metadata = extended_metadata + obj.validated_state = 'a' + obj.hidden_beneath_collection_instance = history_dataset_collection_association + obj.copied_to_library_dataset_dataset_associations.append(copied_to_ldda) + obj.copied_to_history_dataset_associations.append(copied_to_hda) + obj.tags.append(history_dataset_association_tag_association) + obj.annotations.append(history_dataset_association_annotation_association) + obj.ratings.append(history_dataset_association_rating_association) + obj.dependent_jobs.append(job_to_input_dataset_association) + obj.creating_job_associations.append(job_to_output_dataset_association) + obj.implicitly_converted_datasets.append(icda) + obj.implicitly_converted_parent_datasets.append(icpda) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.history.id == history.id + assert stored_obj.dataset.id == dataset.id + assert stored_obj.copied_from_history_dataset_association.id == copied_from_hda.id + assert stored_obj.copied_from_library_dataset_dataset_association.id == copied_from_ldda.id + assert stored_obj.extended_metadata.id == extended_metadata.id + assert (stored_obj.hidden_beneath_collection_instance.id + == history_dataset_collection_association.id) + assert stored_obj.copied_to_library_dataset_dataset_associations == [copied_to_ldda] + assert stored_obj.copied_to_history_dataset_associations == [copied_to_hda] + assert stored_obj.tags == [history_dataset_association_tag_association] + assert stored_obj.annotations == [history_dataset_association_annotation_association] + assert stored_obj.ratings == [history_dataset_association_rating_association] + assert stored_obj.dependent_jobs == [job_to_input_dataset_association] + assert stored_obj.creating_job_associations == [job_to_output_dataset_association] + assert stored_obj.implicitly_converted_datasets == [icda] + assert stored_obj.implicitly_converted_parent_datasets == [icpda] + + delete_from_database(session, persisted) + + +class TestHistoryDatasetAssociationAnnotationAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'history_dataset_association_annotation_association' + assert has_index(cls_.__table__, ('annotation',)) + + def test_columns(self, session, cls_, history_dataset_association, user): + annotation = 'a' + obj = cls_() + obj.user = user + obj.hda = history_dataset_association + obj.annotation = annotation + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.history_dataset_association_id == history_dataset_association.id + assert stored_obj.user_id == user.id + assert stored_obj.annotation == annotation + + def test_relationships(self, session, cls_, history_dataset_association, user): + obj = cls_() + obj.user = user + obj.hda = history_dataset_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.hda.id == history_dataset_association.id + assert stored_obj.user.id == user.id + + +class TestHistoryDatasetAssociationDisplayAtAuthorization(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'history_dataset_association_display_at_authorization' + + def test_columns(self, session, cls_, history_dataset_association, user): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + site = 'a' + obj = cls_(history_dataset_association, user, site) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.history_dataset_association_id == history_dataset_association.id + assert stored_obj.user_id == user.id + assert stored_obj.site == site + + def test_relationships(self, session, cls_, history_dataset_association, user): + obj = cls_(history_dataset_association, user) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.history_dataset_association.id == history_dataset_association.id + assert stored_obj.user.id == user.id + + +class TestHistoryDatasetAssociationHistory(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'history_dataset_association_history' + + def test_columns(self, session, cls_, history_dataset_association, extended_metadata): + name, update_time, version, extension, metadata = 'a', datetime.now(), 2, 'b', 'c' + obj = cls_( + history_dataset_association.id, + name, + None, + update_time, + version, + extension, + extended_metadata.id, + metadata + ) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.history_dataset_association_id == history_dataset_association.id + assert stored_obj.name == name + assert stored_obj.update_time == update_time + assert stored_obj.version == version + assert stored_obj.extension == extension + assert stored_obj.extended_metadata_id == extended_metadata.id + assert stored_obj._metadata == metadata + + +class TestHistoryDatasetAssociationRatingAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'history_dataset_association_rating_association' + + def test_columns(self, session, cls_, history_dataset_association, user): + rating = 9 + obj = cls_(user, history_dataset_association, rating) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.user_id == user.id + assert stored_obj.rating == rating + + def test_relationships(self, session, cls_, history_dataset_association, user): + obj = cls_(user, history_dataset_association, 1) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.history_dataset_association.id == history_dataset_association.id + assert stored_obj.user.id == user.id + + +class TestHistoryDatasetAssociationSubset(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'history_dataset_association_subset' + + def test_columns( + self, + session, + cls_, + history_dataset_association, + history_dataset_association_factory, + ): + hda_subset = history_dataset_association_factory() + persist(session, hda_subset) + + location = 'a' + obj = cls_(history_dataset_association, hda_subset, location) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.history_dataset_association_id == history_dataset_association.id + assert stored_obj.history_dataset_association_subset_id == hda_subset.id + assert stored_obj.location == location + + delete_from_database(session, hda_subset) + + def test_relationships( + self, + session, + cls_, + history_dataset_association, + history_dataset_association_factory, + ): + hda_subset = history_dataset_association_factory() + persist(session, hda_subset) + + obj = cls_(history_dataset_association, hda_subset, None) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.hda.id == history_dataset_association.id + assert stored_obj.subset.id == hda_subset.id + + delete_from_database(session, hda_subset) + + +class TestHistoryDatasetAssociationTagAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'history_dataset_association_tag_association' + + def test_columns(self, session, cls_, history_dataset_association, tag, user): + user_tname, value, user_value = 'a', 'b', 'c' + obj = cls_(user=user, tag=tag, user_tname=user_tname, value=value, user_value=user_value) + obj.history_dataset_association = history_dataset_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.history_dataset_association_id == history_dataset_association.id + assert stored_obj.tag_id == tag.id + assert stored_obj.user_id == user.id + assert stored_obj.user_tname == user_tname + assert stored_obj.value == value + assert stored_obj.user_value == user_value + + def test_relationships(self, session, cls_, history_dataset_association, tag, user): + obj = cls_(user=user, tag=tag) + obj.history_dataset_association = history_dataset_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.history_dataset_association.id == history_dataset_association.id + assert stored_obj.tag.id == tag.id + assert stored_obj.user.id == user.id + + +class TestHistoryDatasetCollectionAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'history_dataset_collection_association' + + def test_columns( + self, + session, + cls_, + dataset_collection, + history, + history_dataset_collection_association, + job, + implicit_collection_jobs, + ): + name = 'a' + hid = 1 + visible = True + deleted = True + implicit_output_name = 'b' + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + + obj = cls_() + obj.collection = dataset_collection + obj.history = history + obj.name = name + obj.hid = hid + obj.visible = visible + obj.deleted = deleted + obj.copied_from_history_dataset_collection_association = history_dataset_collection_association + obj.implicit_output_name = implicit_output_name + obj.job = job + obj.implicit_collection_jobs = implicit_collection_jobs + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.collection_id == dataset_collection.id + assert stored_obj.history_id == history.id + assert stored_obj.name == name + assert stored_obj.hid == hid + assert stored_obj.visible == visible + assert stored_obj.deleted == deleted + assert (stored_obj.copied_from_history_dataset_collection_association_id + == history_dataset_collection_association.id) + assert stored_obj.implicit_output_name == implicit_output_name + assert stored_obj.job_id == job.id + assert stored_obj.implicit_collection_jobs_id == implicit_collection_jobs.id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + + def test_relationships( + self, + session, + cls_, + dataset_collection, + history, + history_dataset_collection_association, + history_dataset_collection_association_factory, + job, + implicit_collection_jobs, + implicitly_created_dataset_collection_input, + history_dataset_collection_annotation_association, + history_dataset_collection_rating_association, + history_dataset_collection_tag_association, + job_to_output_dataset_collection_association, + history_dataset_association, + ): + copied_to_hdca = history_dataset_collection_association_factory() + + obj = cls_() + obj.collection = dataset_collection + obj.history = history + obj.copied_from_history_dataset_collection_association = history_dataset_collection_association + obj.copied_to_history_dataset_collection_association.append(copied_to_hdca) + obj.job = job + obj.implicit_collection_jobs = implicit_collection_jobs + obj.implicit_input_collections.append(implicitly_created_dataset_collection_input) + obj.tags.append(history_dataset_collection_tag_association) + obj.annotations.append(history_dataset_collection_annotation_association) + obj.ratings.append(history_dataset_collection_rating_association) + obj.output_dataset_collection_instances.append(job_to_output_dataset_collection_association) + obj.hidden_dataset_instances.append(history_dataset_association) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.collection.id == dataset_collection.id + assert stored_obj.history.id == history.id + assert (stored_obj.copied_from_history_dataset_collection_association.id + == history_dataset_collection_association.id) + assert stored_obj.copied_to_history_dataset_collection_association == [copied_to_hdca] + assert stored_obj.job.id == job.id + assert stored_obj.implicit_collection_jobs.id == implicit_collection_jobs.id + assert stored_obj.implicit_input_collections == [implicitly_created_dataset_collection_input] + assert stored_obj.tags == [history_dataset_collection_tag_association] + assert stored_obj.annotations == [history_dataset_collection_annotation_association] + assert stored_obj.ratings == [history_dataset_collection_rating_association] + assert (stored_obj.output_dataset_collection_instances + == [job_to_output_dataset_collection_association]) + assert stored_obj.job_state_summary # this is a view; TODO: can we test this better? + assert stored_obj.hidden_dataset_instances == [history_dataset_association] + + delete_from_database(session, copied_to_hdca) + + +class TestHistoryDatasetCollectionAssociationAnnotationAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'history_dataset_collection_annotation_association' + + def test_columns(self, session, cls_, history_dataset_collection_association, user): + annotation = 'a' + obj = cls_() + obj.user = user + obj.history_dataset_collection = history_dataset_collection_association + obj.annotation = annotation + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.history_dataset_collection_id == history_dataset_collection_association.id + assert stored_obj.user_id == user.id + assert stored_obj.annotation == annotation + + def test_relationships(self, session, cls_, history_dataset_collection_association, user): + obj = cls_() + obj.user = user + obj.history_dataset_collection = history_dataset_collection_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.history_dataset_collection.id == history_dataset_collection_association.id + assert stored_obj.user.id == user.id + + +class TestHistoryDatasetCollectionRatingAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'history_dataset_collection_rating_association' + + def test_columns(self, session, cls_, history_dataset_collection_association, user): + rating = 9 + obj = cls_(user, history_dataset_collection_association, rating) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.history_dataset_collection_id == history_dataset_collection_association.id + assert stored_obj.user.id == user.id + assert stored_obj.rating == rating + + def test_relationships(self, session, cls_, history_dataset_collection_association, user): + obj = cls_(user, history_dataset_collection_association, 1) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.dataset_collection.id == history_dataset_collection_association.id + assert stored_obj.user.id == user.id + + +class TestHistoryDatasetCollectionTagAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'history_dataset_collection_tag_association' + + def test_columns(self, session, cls_, history_dataset_collection_association, tag, user): + user_tname, value, user_value = 'a', 'b', 'c' + obj = cls_(user=user, tag=tag, user_tname=user_tname, value=value, user_value=user_value) + obj.dataset_collection = history_dataset_collection_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.history_dataset_collection_id == history_dataset_collection_association.id + assert stored_obj.tag_id == tag.id + assert stored_obj.user_id == user.id + assert stored_obj.user_tname == user_tname + assert stored_obj.value == value + assert stored_obj.user_value == user_value + + def test_relationships(self, session, cls_, history_dataset_collection_association, tag, user): + obj = cls_(user=user, tag=tag) + obj.dataset_collection = history_dataset_collection_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.dataset_collection.id == history_dataset_collection_association.id + assert stored_obj.tag.id == tag.id + assert stored_obj.user.id == user.id + + +class TestHistoryRatingAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'history_rating_association' + + def test_columns(self, session, cls_, history, user): + rating = 9 + obj = cls_(user, history, rating) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.history_id == history.id + assert stored_obj.user_id == user.id + assert stored_obj.rating == rating + + def test_relationships(self, session, cls_, history, user): + obj = cls_(user, history, 1) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.history.id == history.id + assert stored_obj.user.id == user.id + + +class TestHistoryTagAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'history_tag_association' + + def test_columns(self, session, cls_, history, tag, user): + user_tname, value, user_value = 'a', 'b', 'c' + obj = cls_(user=user, tag=tag, user_tname=user_tname, value=value) + obj.user_value = user_value + obj.history = history + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.history_id == history.id + assert stored_obj.tag_id == tag.id + assert stored_obj.user_id == user.id + assert stored_obj.user_tname == user_tname + assert stored_obj.value == value + assert stored_obj.user_value == user_value + + def test_relationships(self, session, cls_, history, tag, user): + obj = cls_(user=user, tag=tag) + obj.history = history + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.history.id == history.id + assert stored_obj.tag.id == tag.id + assert stored_obj.user.id == user.id + + +class TestHistoryUserShareAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'history_user_share_association' + + def test_columns(self, session, cls_, history, user): + obj = cls_() + obj.history = history + obj.user = user + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.history_id == history.id + assert stored_obj.user_id == user.id + + def test_relationships(self, session, cls_, history, user): + obj = cls_() + obj.history = history + obj.user = user + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.history.id == history.id + assert stored_obj.user.id == user.id + + +class TestImplicitCollectionJobs(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'implicit_collection_jobs' + + def test_columns(self, session, cls_): + populated_state = 'a' + obj = cls_() + obj.populated_state = populated_state + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.populated_state == populated_state + + def test_relationships( + self, + session, + cls_, + implicit_collection_jobs_job_association, + history_dataset_collection_association, + workflow_invocation_step, + ): + obj = cls_() + obj.jobs.append(implicit_collection_jobs_job_association) + obj.history_dataset_collection_associations.append(history_dataset_collection_association) + obj.workflow_invocation_step = workflow_invocation_step + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.jobs == [implicit_collection_jobs_job_association] + assert (stored_obj.history_dataset_collection_associations + == [history_dataset_collection_association]) + assert stored_obj.workflow_invocation_step.id == workflow_invocation_step.id + + +class TestImplicitCollectionJobsJobAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'implicit_collection_jobs_job_association' + + def test_columns(self, session, cls_, implicit_collection_jobs, job): + order_index = 1 + obj = cls_() + obj.implicit_collection_jobs = implicit_collection_jobs + session.add(job) # must be bound to a session for lazy load of attributes + obj.job = job + obj.order_index = order_index + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.implicit_collection_jobs_id == implicit_collection_jobs.id + assert stored_obj.job_id == job.id + assert stored_obj.order_index == order_index + + def test_relationships(self, session, cls_, implicit_collection_jobs, job): + obj = cls_() + obj.implicit_collection_jobs = implicit_collection_jobs + session.add(job) # must be bound to a session for lazy load of attributes + obj.job = job + obj.order_index = 1 + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.implicit_collection_jobs.id == implicit_collection_jobs.id + assert stored_obj.job.id == job.id + + +class TestImplicitlyConvertedDatasetAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'implicitly_converted_dataset_association' + + def test_columns( + self, + session, + cls_, + history_dataset_association, + library_dataset_dataset_association, + ): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + deleted = True + metadata_safe = False + type = 'a' + + # Test this combination (dataset/parent, hda/ldda); assume this is sufficient for other combinations. + obj = cls_(parent=library_dataset_dataset_association, dataset=history_dataset_association) + obj.create_time = create_time + obj.update_time = update_time + obj.deleted = deleted + obj.metadata_safe = metadata_safe + obj.type = type + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.hda_id == history_dataset_association.id + assert stored_obj.ldda_id is None + assert stored_obj.hda_parent_id is None + assert stored_obj.ldda_parent_id == library_dataset_dataset_association.id + assert stored_obj.deleted == deleted + assert stored_obj.metadata_safe == metadata_safe + assert stored_obj.type == type + + def test_relationships( + self, + session, + cls_, + history_dataset_association, + library_dataset_dataset_association, + ): + # Switch hda and ldda (different from test_columns() setup) + obj = cls_(parent=history_dataset_association, dataset=library_dataset_dataset_association) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.dataset is None + assert stored_obj.dataset_ldda.id == library_dataset_dataset_association.id + assert stored_obj.parent_hda.id == history_dataset_association.id + assert stored_obj.parent_ldda is None + + +class TestImplicitlyCreatedDatasetCollectionInput(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'implicitly_created_dataset_collection_inputs' + + def test_columns( + self, + session, + cls_, + history_dataset_collection_association, + history_dataset_collection_association_factory, + ): + name = 'a' + + hdca2 = history_dataset_collection_association_factory() + persist(session, hdca2) + + obj = cls_(name, history_dataset_collection_association) + obj.dataset_collection_id = hdca2.id + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.input_dataset_collection_id == history_dataset_collection_association.id + assert stored_obj.dataset_collection_id == hdca2.id + assert stored_obj.name == name + + delete_from_database(session, [hdca2]) + + def test_relationships( + self, + session, + cls_, + history_dataset_collection_association, + history_dataset_collection_association_factory, + ): + hdca2 = history_dataset_collection_association_factory() + persist(session, hdca2) + + obj = cls_(None, history_dataset_collection_association) + obj.dataset_collection_id = hdca2.id + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.input_dataset_collection.id == history_dataset_collection_association.id + assert stored_obj.dataset_collection.id == hdca2.id + + delete_from_database(session, [hdca2]) + + +class TestInteractiveToolEntryPoint(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'interactivetool_entry_point' + + def test_columns(self, session, cls_, job): + name = 'a' + token = 'b' + tool_port = 1 + host = 'c' + port = 2 + protocol = 'd' + entry_url = 'e' + requires_domain = False + info = 'f' + configured = True + deleted = True + created_time = datetime.now() + modified_time = created_time + timedelta(hours=1) + + obj = cls_() + + obj.job = job + obj.name = name + obj.token = token + obj.tool_port = tool_port + obj.host = host + obj.port = port + obj.protocol = protocol + obj.entry_url = entry_url + obj.requires_domain = requires_domain + obj.info = info + obj.configured = configured + obj.deleted = deleted + obj.created_time = created_time + obj.modified_time = modified_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.name == name + assert stored_obj.token == token + assert stored_obj.tool_port == tool_port + assert stored_obj.host == host + assert stored_obj.port == port + assert stored_obj.protocol == protocol + assert stored_obj.entry_url == entry_url + assert stored_obj.requires_domain == requires_domain + assert stored_obj.info == info + assert stored_obj.configured == configured + assert stored_obj.deleted == deleted + assert stored_obj.created_time == created_time + assert stored_obj.modified_time == modified_time + + def test_relationships(self, session, cls_, job): + obj = cls_(job=job) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + + +class TestJob(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job' + + def test_columns( + self, + session, + cls_, + history, + library_folder, + dynamic_tool, + galaxy_session, + user, + ): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + tool_id = 'a' + tool_version = 'b' + galaxy_version = 'c' + state = 'd' + info = 'e' + copied_from_job_id = 1 + command_line = 'f' + dependencies = 'g' + job_messages = 'h' + param_filename = 'i' + runner_name = 'j' + job_stdout = 'k' + job_stderr = 'm' + tool_stdout = 'n' + tool_stderr = 'o' + exit_code = 2 + traceback = 'p' + job_runner_name = 'q' + job_runner_external_id = 'r' + destination_id = 's' + destination_params = 'u' + object_store_id = 'v' + imported = False + params = 'w' + handler = 'x' + + obj = cls_() + obj.create_time = create_time + obj.update_time = update_time + obj.history = history + obj.library_folder = library_folder + obj.tool_id = tool_id + obj.tool_version = tool_version + obj.galaxy_version = galaxy_version + obj.dynamic_tool_id = dynamic_tool.id + obj.state = state + obj.info = info + obj.copied_from_job_id = copied_from_job_id + obj.command_line = command_line + obj.dependencies = dependencies + obj.job_messages = job_messages + obj.param_filename = param_filename + obj.runner_name = runner_name + obj.job_stdout = job_stdout + obj.job_stderr = job_stderr + obj.tool_stdout = tool_stdout + obj.tool_stderr = tool_stderr + obj.exit_code = exit_code + obj.traceback = traceback + obj.galaxy_session = galaxy_session + obj.user = user + obj.job_runner_name = job_runner_name + obj.job_runner_external_id = job_runner_external_id + obj.destination_id = destination_id + obj.destination_params = destination_params + obj.object_store_id = object_store_id + obj.imported = imported + obj.params = params + obj.handler = handler + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id, unique=True) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.history_id == history.id + assert stored_obj.library_folder_id == library_folder.id + assert stored_obj.tool_id == tool_id + assert stored_obj.tool_version == tool_version + assert stored_obj.galaxy_version == galaxy_version + assert stored_obj.dynamic_tool_id == dynamic_tool.id + assert stored_obj.state == state + assert stored_obj.info == info + assert stored_obj.copied_from_job_id == copied_from_job_id + assert stored_obj.command_line == command_line + assert stored_obj.dependencies == dependencies + assert stored_obj.job_messages == job_messages + assert stored_obj.param_filename == param_filename + assert stored_obj.runner_name == runner_name + assert stored_obj.job_stdout == job_stdout + assert stored_obj.job_stderr == job_stderr + assert stored_obj.tool_stdout == tool_stdout + assert stored_obj.tool_stderr == tool_stderr + assert stored_obj.exit_code == exit_code + assert stored_obj.traceback == traceback + assert stored_obj.session_id == galaxy_session.id + assert stored_obj.user_id == user.id + assert stored_obj.job_runner_name == job_runner_name + assert stored_obj.job_runner_external_id == job_runner_external_id + assert stored_obj.destination_id == destination_id + assert stored_obj.destination_params == destination_params + assert stored_obj.object_store_id == object_store_id + assert stored_obj.imported == imported + assert stored_obj.params == params + assert stored_obj.handler == handler + + def test_relationships( + self, + session, + cls_, + history, + library_folder, + dynamic_tool, + galaxy_session, + user, + job_parameter, + job_to_input_dataset_association, + job_to_input_dataset_collection_association, + job_to_input_dataset_collection_element_association, + job_to_output_dataset_collection_association, + job_to_implicit_output_dataset_collection_association, + post_job_action_association, + job_to_input_library_dataset_association, + job_to_output_library_dataset_association, + job_external_output_metadata, + task, + job_to_output_dataset_association, + job_state_history, + job_metric_text, + job_metric_numeric, + genome_index_tool_data, + interactive_tool_entry_point, + implicit_collection_jobs_job_association, + job_container_association, + data_manager_job_association, + history_dataset_collection_association, + workflow_invocation_step, + ): + obj = cls_() + obj.history = history + obj.library_folder = library_folder + obj.galaxy_session = galaxy_session + obj.user = user + obj.parameters.append(job_parameter) + obj.input_datasets.append(job_to_input_dataset_association) + obj.input_dataset_collections.append(job_to_input_dataset_collection_association) + obj.input_dataset_collection_elements.append(job_to_input_dataset_collection_element_association) + obj.output_dataset_collection_instances.append(job_to_output_dataset_collection_association) + obj.output_dataset_collections.append(job_to_implicit_output_dataset_collection_association) + obj.post_job_actions.append(post_job_action_association) + obj.input_library_datasets.append(job_to_input_library_dataset_association) + obj.output_library_datasets.append(job_to_output_library_dataset_association) + obj.external_output_metadata.append(job_external_output_metadata) + obj.tasks.append(task) + obj.output_datasets.append(job_to_output_dataset_association) + obj.state_history.append(job_state_history) + obj.text_metrics.append(job_metric_text) + obj.numeric_metrics.append(job_metric_numeric) + obj.job.append(genome_index_tool_data) + obj.interactivetool_entry_points.append(interactive_tool_entry_point) + obj.implicit_collection_jobs_association = implicit_collection_jobs_job_association + obj.container = job_container_association + obj.data_manager_association = data_manager_job_association + obj.history_dataset_collection_associations.append(history_dataset_collection_association) + obj.workflow_invocation_step = workflow_invocation_step + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id, unique=True) + assert stored_obj.history_id == history.id + assert stored_obj.library_folder_id == library_folder.id + assert stored_obj.session_id == galaxy_session.id + assert stored_obj.user_id == user.id + assert stored_obj.parameters == [job_parameter] + assert stored_obj.input_datasets == [job_to_input_dataset_association] + assert stored_obj.input_dataset_collections == [job_to_input_dataset_collection_association] + assert (stored_obj.input_dataset_collection_elements + == [job_to_input_dataset_collection_element_association]) + assert (stored_obj.output_dataset_collection_instances + == [job_to_output_dataset_collection_association]) + assert (stored_obj.output_dataset_collections + == [job_to_implicit_output_dataset_collection_association]) + assert stored_obj.post_job_actions == [post_job_action_association] + assert stored_obj.input_library_datasets == [job_to_input_library_dataset_association] + assert stored_obj.output_library_datasets == [job_to_output_library_dataset_association] + assert stored_obj.external_output_metadata == [job_external_output_metadata] + assert stored_obj.tasks == [task] + assert stored_obj.output_datasets == [job_to_output_dataset_association] + assert job_state_history in stored_obj.state_history # sufficient for test + assert stored_obj.text_metrics == [job_metric_text] + assert stored_obj.numeric_metrics == [job_metric_numeric] + assert stored_obj.job == [genome_index_tool_data] + assert stored_obj.interactivetool_entry_points == [interactive_tool_entry_point] + assert (stored_obj.implicit_collection_jobs_association + == implicit_collection_jobs_job_association) + assert stored_obj.container == job_container_association + assert stored_obj.data_manager_association == data_manager_job_association + assert (stored_obj.history_dataset_collection_associations + == [history_dataset_collection_association]) + assert stored_obj.workflow_invocation_step == workflow_invocation_step + + +class TestJobContainerAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job_container_association' + + def test_columns(self, session, cls_, job): + container_type = 'a' + container_name = 'b' + container_info = 'c' + created_time = datetime.now() + modified_time = created_time + timedelta(hours=1) + + session.add(job) # must be bound to a session for lazy load of attributes + obj = cls_(job, container_type, container_name, container_info) + obj.created_time = created_time + obj.modified_time = modified_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.container_type == container_type + assert stored_obj.container_name == container_name + assert stored_obj.container_info == container_info + assert stored_obj.created_time == created_time + assert stored_obj.modified_time == modified_time + + def test_relationships(self, session, cls_, job): + session.add(job) # must be bound to a session for lazy load of attributes + obj = cls_(job, None, None, None) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + + +class TestJobExportHistoryArchive(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job_export_history_archive' + + def test_columns(self, session, cls_, job, history, dataset): + compressed, history_attrs_filename = True, 'a' + obj = cls_(job, history, dataset, compressed, history_attrs_filename) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.history_id == history.id + assert stored_obj.dataset_id == dataset.id + assert stored_obj.compressed == compressed + assert stored_obj.history_attrs_filename == history_attrs_filename + + def test_relationships(self, session, cls_, job, history, dataset): + obj = cls_(job, history, dataset, True, None) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + assert stored_obj.history.id == history.id + assert stored_obj.dataset.id == dataset.id + + +class TestJobExternalOutputMetadata(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job_external_output_metadata' + + def test_columns( + self, + session, + cls_, + job, + history_dataset_association, + library_dataset_dataset_association + ): + is_valid = False + filename_in = 'a' + filename_out = 'b' + filename_results_code = 'c' + filename_kwds = 'd' + filename_override_metadata = 'e' + job_runner_external_pid = 'f' + + # We can only pass one dataset: an hda or a ldda, but we need to test both. + # First test passing an hda + obj = cls_(job, history_dataset_association) + + obj.is_valid = is_valid + obj.filename_in = filename_in + obj.filename_out = filename_out + obj.filename_results_code = filename_results_code + obj.filename_kwds = filename_kwds + obj.filename_override_metadata = filename_override_metadata + obj.job_runner_external_pid = job_runner_external_pid + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.history_dataset_association_id == history_dataset_association.id + assert stored_obj.is_valid == is_valid + assert stored_obj.filename_in == filename_in + assert stored_obj.filename_out == filename_out + assert stored_obj.filename_results_code == filename_results_code + assert stored_obj.filename_kwds == filename_kwds + assert stored_obj.filename_override_metadata == filename_override_metadata + assert stored_obj.job_runner_external_pid == job_runner_external_pid + + # Expunge from session: we're creating and storing a new object that will recieve + # the same primary key. This will trigger a SAWarning, since this identity already + # exists in SQLAlchemy's identity map. + session.expunge(stored_obj) + # Now pass an ldda (w/no extra fields, since we've just tested them) + obj = cls_(job, library_dataset_dataset_association) + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert (stored_obj.library_dataset_dataset_association_id + == library_dataset_dataset_association.id) + + def test_relationships( + self, + session, + cls_, + job, + history_dataset_association, + library_dataset_dataset_association + ): + # First test passing an hda + obj = cls_(job, history_dataset_association) + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + assert stored_obj.dataset.id == history_dataset_association.id + + # Expunge: see comment in test_columns() + session.expunge(stored_obj) + # Now pass an ldda + obj = cls_(job, library_dataset_dataset_association) + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.dataset.id == library_dataset_dataset_association.id + + +class TestJobImportHistoryArchive(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job_import_history_archive' + + def test_columns(self, session, cls_, job, history): + archive_dir = 'a' + obj = cls_(job, history, archive_dir) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.history_id == history.id + assert stored_obj. archive_dir == archive_dir + + def test_relationships(self, session, cls_, job, history): + obj = cls_(job, history) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + assert stored_obj.history.id == history.id + + +class TestJobMetricNumeric(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job_metric_numeric' + + def test_columns(self, session, cls_, job): + plugin, metric_name, metric_value = 'a', 'b', 9 + obj = cls_(plugin, metric_name, metric_value) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.plugin == plugin + assert stored_obj.metric_value == metric_value + + def test_relationships(self, session, cls_, job): + obj = cls_(None, None, None) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + + +class TestJobMetricText(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job_metric_text' + + def test_columns(self, session, cls_, job): + plugin, metric_name, metric_value = 'a', 'b', 'c' + obj = cls_(plugin, metric_name, metric_value) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.plugin == plugin + assert stored_obj.metric_value == metric_value + + def test_relationships(self, session, cls_, job): + obj = cls_(None, None, None) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + + +class TestJobParameter(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job_parameter' + + def test_columns(self, session, cls_, job): + name, value = 'a', 'b' + obj = cls_(name, value) + obj.job_id = job.id + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.name == name + assert stored_obj.value == value + + +class TestJobStateHistory(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job_state_history' + + def test_columns(self, session, cls_, job): + state, info = job.state, job.info + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_(job) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.job_id == job.id + assert stored_obj.state == state + assert stored_obj.info == info + + def test_relationships(self, session, cls_, job): + obj = cls_(job) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + + +class TestJobToImplicitOutputDatasetCollectionAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job_to_implicit_output_dataset_collection' + + def test_columns(self, session, cls_, dataset_collection, job): + name = 'a' + obj = cls_(name, dataset_collection) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.dataset_collection_id == dataset_collection.id + assert stored_obj.name == name + + def test_relationships(self, session, cls_, dataset_collection, job): + obj = cls_(None, dataset_collection) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + assert stored_obj.dataset_collection.id == dataset_collection.id + + +class TestJobToInputDatasetAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job_to_input_dataset' + + def test_columns(self, session, cls_, history_dataset_association, job): + name, dataset_version = 'a', 9 + obj = cls_(name, history_dataset_association) + obj.job = job + obj.dataset_version = dataset_version + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.dataset_id == history_dataset_association.id + assert stored_obj.dataset_version == dataset_version + assert stored_obj.name == name + + def test_relationships(self, session, cls_, history_dataset_association, job): + obj = cls_(None, history_dataset_association) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + assert stored_obj.dataset.id == history_dataset_association.id + + +class TestJobToInputDatasetCollectionAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job_to_input_dataset_collection' + + def test_columns(self, session, cls_, history_dataset_collection_association, job): + name = 'a' + obj = cls_(name, history_dataset_collection_association) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.dataset_collection_id == history_dataset_collection_association.id + assert stored_obj.name == name + + def test_relationships(self, session, cls_, history_dataset_collection_association, job): + obj = cls_(None, history_dataset_collection_association) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + assert stored_obj.dataset_collection.id == history_dataset_collection_association.id + + +class TestJobToInputDatasetCollectionElementAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job_to_input_dataset_collection_element' + + def test_columns(self, session, cls_, dataset_collection_element, job): + name = 'a' + obj = cls_(name, dataset_collection_element) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.dataset_collection_element_id == dataset_collection_element.id + assert stored_obj.name == name + + def test_relationships(self, session, cls_, dataset_collection_element, job): + obj = cls_(None, dataset_collection_element) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + assert stored_obj.dataset_collection_element.id == dataset_collection_element.id + + +class TestJobToInputLibraryDatasetAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job_to_input_library_dataset' + + def test_columns(self, session, cls_, library_dataset_dataset_association, job): + name = 'a' + obj = cls_(name, library_dataset_dataset_association) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.ldda_id == library_dataset_dataset_association.id + assert stored_obj.name == name + + def test_relationships(self, session, cls_, library_dataset_dataset_association, job): + obj = cls_(None, library_dataset_dataset_association) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + assert stored_obj.dataset.id == library_dataset_dataset_association.id + + +class TestJobToOutputDatasetAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job_to_output_dataset' + + def test_columns(self, session, cls_, history_dataset_association, job): + name = 'a' + obj = cls_(name, history_dataset_association) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.dataset_id == history_dataset_association.id + assert stored_obj.name == name + + def test_relationships(self, session, cls_, history_dataset_association, job): + obj = cls_(None, history_dataset_association) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + assert stored_obj.dataset.id == history_dataset_association.id + + +class TestJobToOutputDatasetCollectionAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job_to_output_dataset_collection' + + def test_columns(self, session, cls_, history_dataset_collection_association, job): + name = 'a' + obj = cls_(name, history_dataset_collection_association) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.dataset_collection_id == history_dataset_collection_association.id + assert stored_obj.name == name + + def test_relationships(self, session, cls_, history_dataset_collection_association, job): + obj = cls_(None, history_dataset_collection_association) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + assert (stored_obj.dataset_collection_instance.id + == history_dataset_collection_association.id) + + +class TestJobToOutputLibraryDatasetAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'job_to_output_library_dataset' + + def test_columns(self, session, cls_, library_dataset_dataset_association, job): + name = 'a' + obj = cls_(name, library_dataset_dataset_association) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.ldda_id == library_dataset_dataset_association.id + assert stored_obj.name == name + + def test_relationships(self, session, cls_, library_dataset_dataset_association, job): + obj = cls_(None, library_dataset_dataset_association) + obj.job = job + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + assert stored_obj.dataset.id == library_dataset_dataset_association.id + + +class TestLibrary(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'library' + + def test_columns(self, session, cls_, library_folder): + name, deleted, purged, description, synopsis = 'a', True, True, 'b', 'c' + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_(name, description, synopsis, library_folder) + obj.create_time = create_time + obj.update_time = update_time + obj.deleted = deleted + obj.purged = purged + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.root_folder_id == library_folder.id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.name == name + assert stored_obj.deleted == deleted + assert stored_obj.purged == purged + assert stored_obj.description == description + assert stored_obj.synopsis == synopsis + + def test_relationships( + self, + session, + cls_, + library_folder, + library_permission, + library_info_association, + ): + obj = cls_(None, None, None, library_folder) + obj.actions.append(library_permission) + session.add(library_info_association) # must be bound to a session for lazy load of attributes + obj.info_association.append(library_info_association) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.root_folder.id == library_folder.id + assert stored_obj.actions == [library_permission] + assert stored_obj.info_association == [library_info_association] + + +class TestLibraryDataset(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'library_dataset' + + def test_columns(self, session, cls_, library_folder): + order_id = 9 + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + name = 'a' + info = 'b' + deleted = False + purged = False + + obj = cls_() + obj.folder = library_folder + obj.order_id = order_id + obj.create_time = create_time + obj.update_time = update_time + obj.name = name + obj.info = info + obj.deleted = deleted + obj.purged = purged + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.folder_id == library_folder.id + assert stored_obj.order_id == order_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.name == name + assert stored_obj.info == info + assert stored_obj.deleted == deleted + assert stored_obj.purged == purged + + def test_relationships( + self, + session, + cls_, + library_dataset_dataset_association, + library_folder, + library_dataset_permission, + library_dataset_dataset_association_factory, + ): + obj = cls_() + obj.folder = library_folder + obj.library_dataset_dataset_association = library_dataset_dataset_association + obj.actions.append(library_dataset_permission) + + ldda = library_dataset_dataset_association_factory() + ldda.library_dataset = obj + obj.actions.append(library_dataset_permission) + persist(session, ldda) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert (stored_obj.library_dataset_dataset_association.id + == library_dataset_dataset_association.id) + assert stored_obj.folder.id == library_folder.id + assert stored_obj.expired_datasets[0].id == ldda.id + assert stored_obj.actions == [library_dataset_permission] + + delete_from_database(session, ldda) + + +class TestLibraryDatasetCollectionAnnotationAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'library_dataset_collection_annotation_association' + + def test_columns(self, session, cls_, library_dataset_collection_association, user): + annotation = 'a' + obj = cls_() + obj.user = user + obj.dataset_collection = library_dataset_collection_association + obj.annotation = annotation + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert (stored_obj.library_dataset_collection_id + == library_dataset_collection_association.id) + assert stored_obj.user_id == user.id + assert stored_obj.annotation == annotation + + def test_relationships(self, session, cls_, library_dataset_collection_association, user): + obj = cls_() + obj.user = user + obj.dataset_collection = library_dataset_collection_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.dataset_collection.id == library_dataset_collection_association.id + assert stored_obj.user.id == user.id + + +class TestLibraryDatasetCollectionAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'library_dataset_collection_association' + + def test_columns(self, session, cls_, dataset_collection, library_folder): + name, deleted = 'a', True + obj = cls_() + obj.collection = dataset_collection + obj.folder = library_folder + obj.name = name + obj.deleted = deleted + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.collection_id == dataset_collection.id + assert stored_obj.folder_id == library_folder.id + assert stored_obj.name == name + assert stored_obj.deleted == deleted + + def test_relationships( + self, + session, + cls_, + dataset_collection, + library_folder, + library_dataset_collection_annotation_association, + library_dataset_collection_rating_association, + library_dataset_collection_tag_association, + ): + + obj = cls_() + obj.collection = dataset_collection + obj.folder = library_folder + obj.tags.append(library_dataset_collection_tag_association) + obj.annotations.append(library_dataset_collection_annotation_association) + obj.ratings.append(library_dataset_collection_rating_association) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.collection.id == dataset_collection.id + assert stored_obj.folder.id == library_folder.id + assert stored_obj.tags == [library_dataset_collection_tag_association] + assert stored_obj.annotations == [library_dataset_collection_annotation_association] + assert stored_obj.ratings == [library_dataset_collection_rating_association] + + +class TestLibraryDatasetCollectionRatingAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'library_dataset_collection_rating_association' + + def test_columns(self, session, cls_, library_dataset_collection_association, user): + rating = 9 + obj = cls_(user, library_dataset_collection_association, rating) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert (stored_obj.library_dataset_collection_id + == library_dataset_collection_association.id) + assert stored_obj.user_id == user.id + assert stored_obj.rating == rating + + def test_relationships(self, session, cls_, library_dataset_collection_association, user): + obj = cls_(user, library_dataset_collection_association, 1) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.dataset_collection.id == library_dataset_collection_association.id + assert stored_obj.user.id == user.id + + +class TestLibraryDatasetCollectionTagAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'library_dataset_collection_tag_association' + + def test_columns(self, session, cls_, library_dataset_collection_association, tag, user): + user_tname, value, user_value = 'a', 'b', 'c' + obj = cls_(user=user, tag=tag, user_tname=user_tname, value=value) + obj.user_value = user_value + obj.dataset_collection = library_dataset_collection_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert (stored_obj.library_dataset_collection_id + == library_dataset_collection_association.id) + assert stored_obj.tag_id == tag.id + assert stored_obj.user_id == user.id + assert stored_obj.user_tname == user_tname + assert stored_obj.value == value + assert stored_obj.user_value == user_value + + def test_relationships(self, session, cls_, library_dataset_collection_association, tag, user): + obj = cls_(user=user, tag=tag) + obj.dataset_collection = library_dataset_collection_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.dataset_collection.id == library_dataset_collection_association.id + assert stored_obj.tag.id == tag.id + assert stored_obj.user.id == user.id + + +class TestLibraryDatasetDatasetAssociation(BaseTest): + + def test_table(self, cls_): + # mapped imperatively, so do not test cls_.__tablename__ + assert cls_.table.name == 'library_dataset_dataset_association' + + def test_columns( + self, + session, + cls_, + library_dataset, + dataset, + history_dataset_association, + library_dataset_dataset_association_factory, + extended_metadata, + user, + ): + create_time = datetime.now() + state = 'a' + name = 'b' + info = 'c' + blurb = 'd' + peek = 'e' + tool_version = 'f' + extension = 'g' + designation = 'i' + deleted = True + validated_state = 'j' + validated_state_message = 'k' + visible = True + message = 'm' + _metadata = 'n' + copied_from_ldda = library_dataset_dataset_association_factory() + parent = library_dataset_dataset_association_factory() + persist(session, copied_from_ldda) + persist(session, parent) + + obj = cls_() + obj.library_dataset = library_dataset + obj.dataset = dataset + obj.create_time = create_time + obj.copied_from_history_dataset_association = history_dataset_association + obj.copied_from_library_dataset_dataset_association = copied_from_ldda + obj.state = state + obj.name = name + obj.info = info + obj.blurb = blurb + obj.peek = peek + obj.tool_version = tool_version + obj.extension = extension + obj.parent_id = parent.id + obj.designation = designation + obj.deleted = deleted + obj.validated_state = validated_state + obj.validated_state_message = validated_state_message + obj.visible = visible + obj.extended_metadata = extended_metadata + obj.user = user + obj.message = message + obj._metadata = _metadata + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.library_dataset_id == library_dataset.id + assert stored_obj.dataset_id == dataset.id + assert stored_obj.create_time == create_time + assert stored_obj.update_time >= create_time # this is sufficient for testing + assert (stored_obj.copied_from_history_dataset_association_id + == history_dataset_association.id) + assert (stored_obj.copied_from_library_dataset_dataset_association_id + == copied_from_ldda.id) + assert stored_obj.state == state + assert stored_obj.name == name + assert stored_obj.info == info + assert stored_obj.blurb == blurb + assert stored_obj.peek == peek + assert stored_obj.tool_version == tool_version + assert stored_obj.extension == extension + assert stored_obj.parent_id == parent.id + assert stored_obj.designation == designation + assert stored_obj.deleted == deleted + assert stored_obj.validated_state == validated_state + assert stored_obj.validated_state_message == validated_state_message + assert stored_obj.visible == visible + assert stored_obj.extended_metadata_id == extended_metadata.id + assert stored_obj.user_id == user.id + assert stored_obj.message == message + # We cannot test obj.metadata by setting it directly (like the other attributes). + # However, the following assertion verifies that it exists and has been initialized correctly. + assert stored_obj.metadata.parent.id == obj_id + assert stored_obj._metadata == _metadata + + delete_from_database(session, [copied_from_ldda, parent]) + + def test_relationships( + self, + session, + cls_, + library_dataset, + dataset, + history_dataset_association, + library_dataset_dataset_association_factory, + extended_metadata, + user, + library_dataset_dataset_association_tag_association, + library_dataset_dataset_association_permission, + history_dataset_association_factory, + implicitly_converted_dataset_association_factory, + job_to_input_library_dataset_association, + job_to_output_library_dataset_association, + library_dataset_dataset_info_association, + ): + copied_from_ldda = library_dataset_dataset_association_factory() + copied_to_ldda = library_dataset_dataset_association_factory() + parent = library_dataset_dataset_association_factory() + copied_to_hda = history_dataset_association_factory() + icda = implicitly_converted_dataset_association_factory() + icpda = implicitly_converted_dataset_association_factory() + persisted = [copied_from_ldda, copied_to_ldda, parent, copied_to_hda, icda, icpda] + + obj = cls_() + obj.library_dataset = library_dataset + obj.dataset = dataset + obj.copied_from_history_dataset_association = history_dataset_association + obj.copied_from_library_dataset_dataset_association = copied_from_ldda + obj.extended_metadata = extended_metadata + obj.user = user + obj.tags.append(library_dataset_dataset_association_tag_association) + obj.actions.append(library_dataset_dataset_association_permission) + obj.copied_to_history_dataset_associations.append(copied_to_hda) + obj.copied_to_library_dataset_dataset_associations.append(copied_to_ldda) + obj.implicitly_converted_datasets.append(icda) + obj.implicitly_converted_parent_datasets.append(icpda) + obj.dependent_jobs.append(job_to_input_library_dataset_association) + obj.creating_job_associations.append(job_to_output_library_dataset_association) + obj.info_association.append(library_dataset_dataset_info_association) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.library_dataset.id == library_dataset.id + assert stored_obj.dataset.id == dataset.id + assert (stored_obj.copied_from_history_dataset_association.id + == history_dataset_association.id) + assert (stored_obj.copied_from_library_dataset_dataset_association.id + == copied_from_ldda.id) + assert stored_obj.extended_metadata.id == extended_metadata.id + assert stored_obj.user.id == user.id + assert stored_obj.tags == [library_dataset_dataset_association_tag_association] + assert stored_obj.actions == [library_dataset_dataset_association_permission] + assert stored_obj.copied_to_history_dataset_associations == [copied_to_hda] + assert stored_obj.copied_to_library_dataset_dataset_associations == [copied_to_ldda] + assert stored_obj.implicitly_converted_datasets == [icda] + assert stored_obj.implicitly_converted_parent_datasets == [icpda] + assert stored_obj.dependent_jobs == [job_to_input_library_dataset_association] + assert (stored_obj.creating_job_associations + == [job_to_output_library_dataset_association]) + assert stored_obj.info_association == [library_dataset_dataset_info_association] + + delete_from_database(session, persisted) + + +class TestLibraryDatasetDatasetAssociationPermissions(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'library_dataset_dataset_association_permissions' + + def test_columns(self, session, cls_, library_dataset_dataset_association, role): + action = 'a' + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_(action, library_dataset_dataset_association, role) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.action == action + assert (stored_obj.library_dataset_dataset_association_id + == library_dataset_dataset_association.id) + assert stored_obj.role_id == role.id + + def test_relationships(self, session, cls_, library_dataset_dataset_association, role): + obj = cls_(None, library_dataset_dataset_association, role) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert (stored_obj.library_dataset_dataset_association.id + == library_dataset_dataset_association.id) + assert stored_obj.role.id == role.id + + +class TestLibraryDatasetDatasetAssociationTagAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'library_dataset_dataset_association_tag_association' + + def test_columns(self, session, cls_, library_dataset_dataset_association, tag, user): + user_tname, value, user_value = 'a', 'b', 'c' + obj = cls_(user=user, tag=tag, user_tname=user_tname, value=value) + obj.user_value = user_value + obj.library_dataset_dataset_association = library_dataset_dataset_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert (stored_obj.library_dataset_dataset_association_id + == library_dataset_dataset_association.id) + assert stored_obj.tag_id == tag.id + assert stored_obj.user_id == user.id + assert stored_obj.user_tname == user_tname + assert stored_obj.value == value + assert stored_obj.user_value == user_value + + def test_relationships(self, session, cls_, library_dataset_dataset_association, tag, user): + obj = cls_(user=user, tag=tag) + obj.library_dataset_dataset_association = library_dataset_dataset_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert (stored_obj.library_dataset_dataset_association.id + == library_dataset_dataset_association.id) + assert stored_obj.tag.id == tag.id + assert stored_obj.user.id == user.id + + +class TestLibraryDatasetDatasetInfoAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'library_dataset_dataset_info_association' + + def test_columns( + self, + session, + cls_, + library_dataset_dataset_association, + form_definition, + form_values, + ): + deleted = True + obj = cls_(library_dataset_dataset_association, form_definition, form_values) + obj.deleted = deleted + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert (stored_obj.library_dataset_dataset_association_id + == library_dataset_dataset_association.id) + assert stored_obj.form_definition_id == form_definition.id + assert stored_obj.form_values_id == form_values.id + assert stored_obj.deleted == deleted + + def test_relationships( + self, + session, + cls_, + library_dataset_dataset_association, + form_definition, + form_values, + ): + obj = cls_(library_dataset_dataset_association, form_definition, form_values) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert (stored_obj.library_dataset_dataset_association.id + == library_dataset_dataset_association.id) + assert stored_obj.template.id == form_definition.id + assert stored_obj.info.id == form_values.id + + +class TestLibraryDatasetPermissions(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'library_dataset_permissions' + + def test_columns(self, session, cls_, library_dataset, role): + action = 'a' + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_(action, library_dataset, role) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.action == action + assert stored_obj.library_dataset_id == library_dataset.id + assert stored_obj.role_id == role.id + + def test_relationships(self, session, cls_, library_dataset, role): + obj = cls_(None, library_dataset, role) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.library_dataset.id == library_dataset.id + assert stored_obj.role.id == role.id + + +class TestLibraryFolder(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'library_folder' + assert has_index(cls_.__table__, ('name',)) + + def test_columns(self, session, cls_, library_folder): + parent = library_folder + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + name = 'a' + description = 'b' + order_id = 9 + item_count = 1 + deleted = False + purged = False + genome_build = 'c' + + obj = cls_() + obj.parent = parent + obj.create_time = create_time + obj.update_time = update_time + obj.name = name + obj.description = description + obj.order_id = order_id + obj.item_count = item_count + obj.deleted = deleted + obj.purged = purged + obj.genome_build = genome_build + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.parent_id == parent.id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.name == name + assert stored_obj.description == description + assert stored_obj.order_id == order_id + assert stored_obj.item_count == item_count + assert stored_obj.deleted == deleted + assert stored_obj.purged == purged + assert stored_obj.genome_build == genome_build + + def test_relationships( + self, + session, + cls_, + library_folder, + library_dataset, + library, + library_dataset_collection_association, + library_folder_permission, + library_folder_info_association, + library_folder_factory, + ): + obj = cls_() + obj.parent = library_folder + folder1 = library_folder_factory() + obj.folders.append(folder1) + obj.dataset_collections.append(library_dataset_collection_association) + obj.library_root.append(library) + obj.actions.append(library_folder_permission) + obj.info_association.append(library_folder_info_association) + + # There's no back reference, so dataset does not update folder; so we have to flush to the database + library_dataset.folder = obj + persist(session, library_dataset) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.parent.id == library_folder.id + assert stored_obj.folders == [folder1] + assert stored_obj.active_folders == [folder1] + assert stored_obj.library_root == [library] + assert stored_obj.actions == [library_folder_permission] + # use identity equality instread of object equality. + assert stored_obj.datasets[0].id == library_dataset.id + assert stored_obj.active_datasets[0].id == library_dataset.id + assert stored_obj.dataset_collections == [library_dataset_collection_association] + assert stored_obj.info_association == [library_folder_info_association] + + delete_from_database(session, folder1) + + +class TestLibraryFolderInfoAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'library_folder_info_association' + + def test_columns(self, session, cls_, library_folder, form_definition, form_values): + inheritable, deleted = True, True + obj = cls_(library_folder, form_definition, form_values, inheritable) + obj.deleted = deleted + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.library_folder_id == library_folder.id + assert stored_obj.form_definition_id == form_definition.id + assert stored_obj.form_values_id == form_values.id + assert stored_obj.inheritable == inheritable + assert stored_obj.deleted == deleted + + def test_relationships(self, session, cls_, library_folder, form_definition, form_values): + obj = cls_(library_folder, form_definition, form_values) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.folder.id == library_folder.id + assert stored_obj.template.id == form_definition.id + assert stored_obj.info.id == form_values.id + + +class TestLibraryFolderPermissions(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'library_folder_permissions' + + def test_columns(self, session, cls_, library_folder, role): + action = 'a' + obj = cls_(action, library_folder, role) + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.action == action + assert stored_obj.library_folder_id == library_folder.id + assert stored_obj.role_id == role.id + + def test_relationships(self, session, cls_, library_folder, role): + obj = cls_(None, library_folder, role) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.folder.id == library_folder.id + assert stored_obj.role.id == role.id + + +class TestLibraryInfoAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'library_info_association' + + def test_columns(self, session, cls_, library, form_definition, form_values): + inheritable, deleted = True, True + obj = cls_(library, form_definition, form_values, inheritable) + obj.deleted = deleted + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.library_id == library.id + assert stored_obj.form_definition_id == form_definition.id + assert stored_obj.form_values_id == form_values.id + assert stored_obj.inheritable == inheritable + assert stored_obj.deleted == deleted + + def test_relationships(self, session, cls_, library, form_definition, form_values): + obj = cls_(library, form_definition, form_values, None) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.library.id == library.id + assert stored_obj.template.id == form_definition.id + assert stored_obj.info.id == form_values.id + + +class TestLibraryPermissions(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'library_permissions' + + def test_columns(self, session, cls_, library, role): + action = 'a' + obj = cls_(action, library, role) + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_(action, library, role) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.action == action + assert stored_obj.library_id == library.id + assert stored_obj.role_id == role.id + + def test_relationships(self, session, cls_, library, role): + obj = cls_(None, library, role) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.library.id == library.id + assert stored_obj.role.id == role.id + + +class TestMetadataFile(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'metadata_file' + + def test_columns( + self, + session, + cls_, + history_dataset_association, + library_dataset_dataset_association, + ): + name = 'a' + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + object_store_id = 'b' + uuid = uuid4() + deleted = True + purged = True + + obj = cls_() + obj.name = name + obj.history_dataset = history_dataset_association + obj.library_dataset = library_dataset_dataset_association + obj.create_time = create_time + obj.update_time = update_time + obj.object_store_id = object_store_id + obj.uuid = uuid + obj.deleted = deleted + obj.purged = purged + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.name == name + assert stored_obj.hda_id == history_dataset_association.id + assert stored_obj.lda_id == library_dataset_dataset_association.id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.object_store_id == object_store_id + assert stored_obj.uuid == uuid + assert stored_obj.deleted == deleted + assert stored_obj.purged == purged + + def test_relationships( + self, + session, + cls_, + history_dataset_association, + library_dataset_dataset_association, + ): + obj = cls_() + obj.history_dataset = history_dataset_association + obj.library_dataset = library_dataset_dataset_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.history_dataset.id == history_dataset_association.id + assert stored_obj.library_dataset.id == library_dataset_dataset_association.id + + +class TestPSAAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'psa_association' + + def test_columns(self, session, cls_): + server_url, handle, secret, issued, lifetime, assoc_type = 'a', 'b', 'c', 1, 2, 'd' + obj = cls_(server_url, handle, secret, issued, lifetime, assoc_type) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.server_url == server_url + assert stored_obj.handle == handle + assert stored_obj.secret == secret + assert stored_obj.issued == issued + assert stored_obj.lifetime == lifetime + assert stored_obj.assoc_type == assoc_type + + +class TestPSACode(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'psa_code' + assert has_unique_constraint(cls_.__table__, ('code', 'email')) + + def test_columns(self, session, cls_): + email, code = 'a', get_unique_value() + obj = cls_(email, code) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.email == email + assert stored_obj.code == code + + +class TestPSANonce(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'psa_nonce' + + def test_columns(self, session, cls_): + server_url, timestamp, salt = 'a', 1, 'b' + obj = cls_(server_url, timestamp, salt) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.server_url + assert stored_obj.timestamp == timestamp + assert stored_obj.salt == salt + + +class TestPSAPartial(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'psa_partial' + + def test_columns(self, session, cls_): + token, data, next_step, backend = 'a', 'b', 1, 'c' + obj = cls_(token, data, next_step, backend) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.token == token + assert stored_obj.data == data + assert stored_obj.next_step == next_step + assert stored_obj.backend == backend + + +class TestPage(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'page' + assert has_index(cls_.__table__, ('slug',)) + + def test_columns(self, session, cls_, user, page_revision): + title, deleted, importable, slug, published = 'a', True, True, 'b', True + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_() + obj.user = user + obj.title = title + obj.deleted = deleted + obj.importable = importable + obj.slug = slug + obj.published = published + obj.create_time = create_time + obj.update_time = update_time + # This is OK for this test; however, page_revision.page != obj. Can we do better? + obj.latest_revision = page_revision + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.user_id == user.id + assert stored_obj.latest_revision_id == page_revision.id + assert stored_obj.title == title + assert stored_obj.deleted == deleted + assert stored_obj.importable == importable + assert stored_obj.slug == slug + assert stored_obj.published == published + + def test_relationships( + self, + session, + cls_, + user, + page_revision, + page_tag_association, + page_annotation_association, + page_rating_association, + page_user_share_association, + ): + obj = cls_() + obj.user = user + # This is OK for this test; however, page_revision.page != obj. Can we do better? + obj.latest_revision = page_revision + obj.revisions.append(page_revision) + obj.tags.append(page_tag_association) + obj.annotations.append(page_annotation_association) + obj.ratings.append(page_rating_association) + obj.users_shared_with.append(page_user_share_association) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.user.id == user.id + assert stored_obj.revisions == [page_revision] + assert stored_obj.latest_revision.id == page_revision.id + assert stored_obj.tags == [page_tag_association] + assert stored_obj.annotations == [page_annotation_association] + assert stored_obj.ratings == [page_rating_association] + assert stored_obj.users_shared_with == [page_user_share_association] + # This doesn't test the average amount, just the mapping. + assert stored_obj.average_rating == page_rating_association.rating + + def test_average_rating(self, session, page, user, page_rating_association_factory): + _run_average_rating_test(session, page, user, page_rating_association_factory) + + +class TestPageAnnotationAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'page_annotation_association' + assert has_index(cls_.__table__, ('annotation',)) + + def test_columns(self, session, cls_, page, user): + annotation = 'a' + obj = cls_() + obj.user = user + obj.page = page + obj.annotation = annotation + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.page_id == page.id + assert stored_obj.user_id == user.id + assert stored_obj.annotation == annotation + + def test_relationships(self, session, cls_, page, user): + obj = cls_() + obj.user = user + obj.page = page + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.page.id == page.id + assert stored_obj.user.id == user.id + + +class TestPageRatingAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'page_rating_association' + + def test_columns(self, session, cls_, page, user): + rating = 9 + obj = cls_(user, page, rating) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.page_id == page.id + assert stored_obj.user_id == user.id + assert stored_obj.rating == rating + + def test_relationships(self, session, cls_, page, user): + obj = cls_(user, page, 1) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.page.id == page.id + assert stored_obj.user.id == user.id + + +class TestPageRevision(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'page_revision' + + def test_columns(self, session, cls_, model, page): + title, content = 'a', 'b' + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_() + obj.page = page + obj.create_time = create_time + obj.update_time = update_time + obj.title = title + obj.content = content + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.page_id == page.id + assert stored_obj.title == title + assert stored_obj.content == content + assert stored_obj.content_format == model.PageRevision.DEFAULT_CONTENT_FORMAT + + def test_relationships(self, session, cls_, page): + obj = cls_() + obj.page = page + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.page.id == page.id + + +class TestPageTagAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'page_tag_association' + + def test_columns(self, session, cls_, page, tag, user): + user_tname, value, user_value = 'a', 'b', 'c' + obj = cls_(user=user, tag=tag, user_tname=user_tname, value=value) + obj.user_value = user_value + obj.page = page + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.page_id == page.id + assert stored_obj.tag_id == tag.id + assert stored_obj.user_id == user.id + assert stored_obj.user_tname == user_tname + assert stored_obj.value == value + assert stored_obj.user_value == user_value + + def test_relationships(self, session, cls_, page, tag, user): + obj = cls_(user=user, tag=tag) + obj.page = page + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.page.id == page.id + assert stored_obj.tag.id == tag.id + assert stored_obj.user.id == user.id + + +class TestPageUserShareAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'page_user_share_association' + + def test_columns(self, session, cls_, page, user): + obj = cls_() + obj.page = page + obj.user = user + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.page_id == page.id + assert stored_obj.user_id == user.id + + def test_relationships(self, session, cls_, page, user): + obj = cls_() + obj.page = page + obj.user = user + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.page.id == page.id + assert stored_obj.user.id == user.id + + +class TestPasswordResetToken(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'password_reset_token' + + def test_columns_and_relationships(self, session, cls_, user): + token = get_unique_value() + expiration_time = datetime.now() + obj = cls_(user, token) + obj.expiration_time = expiration_time + + where_clause = cls_.token == token + + with dbcleanup(session, obj, where_clause): + stored_obj = get_stored_obj(session, cls_, where_clause=where_clause) + # test columns + assert stored_obj.token == token + assert stored_obj.expiration_time == expiration_time + assert stored_obj.user_id == user.id + # test relationships + assert stored_obj.user.id == user.id + + +class TestPostJobAction(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'post_job_action' + + def test_columns(self, session, cls_, workflow_step): + action_type = 'a' + output_name = 'b' + action_arguments = 'c' + obj = cls_(action_type, workflow_step, output_name, action_arguments) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.workflow_step_id == workflow_step.id + assert stored_obj.action_type == action_type + assert stored_obj.output_name == output_name + assert stored_obj.action_arguments == action_arguments + + def test_relationships(self, session, cls_, workflow_step): + obj = cls_('a', workflow_step, None, None) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_step.id == workflow_step.id + + +class TestPostJobActionAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'post_job_action_association' + + def test_columns(self, session, cls_, job, post_job_action): + obj = cls_(post_job_action, job) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.job_id == job.id + assert stored_obj.post_job_action_id == post_job_action.id + + def test_relationships(self, session, cls_, job, post_job_action): + obj = cls_(post_job_action, job) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + assert stored_obj.post_job_action.id == post_job_action.id + + +class TestQuota(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'quota' + + def test_columns(self, session, cls_): + name, description, amount, operation = get_unique_value(), 'b', 42, '+' + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_(name, description, amount, operation) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.name == name + assert stored_obj.description == description + assert stored_obj.bytes == amount + assert stored_obj.operation == operation + assert stored_obj.deleted is False + + def test_relationships( + self, + session, + cls_, + default_quota_association, + group_quota_association, + user_quota_association + ): + def add_association(assoc_object, assoc_attribute): + assoc_object.quota = obj + getattr(obj, assoc_attribute).append(assoc_object) + + obj = cls_(get_unique_value(), None, 1, '+') + add_association(default_quota_association, 'default') + add_association(group_quota_association, 'groups') + add_association(user_quota_association, 'users') + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.default == [default_quota_association] + assert stored_obj.groups == [group_quota_association] + assert stored_obj.users == [user_quota_association] + + +class TestRole(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'role' + + def test_columns(self, session, cls_): + name, description, type_, deleted = get_unique_value(), 'b', cls_.types.SYSTEM, True + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_(name, description, type_, deleted) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.name == name + assert stored_obj.description == description + assert stored_obj.type == type_ + assert stored_obj.deleted == deleted + + def test_relationships( + self, + session, + cls_, + dataset_permission, + group_role_association, + library_permission, + library_folder_permission, + library_dataset_permission, + library_dataset_dataset_association_permission, + user_role_association, + ): + name, description, type_ = get_unique_value(), 'b', cls_.types.SYSTEM + obj = cls_(name, description, type_) + obj.dataset_actions.append(dataset_permission) + obj.library_actions.append(library_permission) + obj.library_folder_actions.append(library_folder_permission) + obj.library_dataset_actions.append(library_dataset_permission) + obj.library_dataset_dataset_actions.append(library_dataset_dataset_association_permission) + obj.groups.append(group_role_association) + obj.users.append(user_role_association) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.dataset_actions == [dataset_permission] + assert stored_obj.groups == [group_role_association] + assert stored_obj.library_actions == [library_permission] + assert stored_obj.library_folder_actions == [library_folder_permission] + assert stored_obj.library_dataset_actions == [library_dataset_permission] + assert (stored_obj.library_dataset_dataset_actions + == [library_dataset_dataset_association_permission]) + assert stored_obj.users == [user_role_association] + + +class TestStoredWorkflow(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'stored_workflow' + assert has_index(cls_.__table__, ('slug',)) + + def test_columns(self, session, cls_, workflow, user): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + name = 'a' + deleted = True + hidden = True + importable = True + slug = 'b' + from_path = 'c' + published = True + + obj = cls_() + obj.create_time = create_time + obj.update_time = update_time + obj.user = user + obj.latest_workflow = workflow + obj.name = name + obj.deleted = deleted + obj.hidden = hidden + obj.importable = importable + obj.slug = slug + obj.from_path = from_path + obj.published = published + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id, unique=True) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.user_id == user.id + assert stored_obj.latest_workflow_id == workflow.id + assert stored_obj.name == name + assert stored_obj.deleted == deleted + assert stored_obj.hidden == hidden + assert stored_obj.importable == importable + assert stored_obj.slug == slug + assert stored_obj.from_path == from_path + assert stored_obj.published == published + + def test_relationships( + self, + session, + cls_, + workflow, + user, + workflow_factory, + stored_workflow_tag_association, + stored_workflow_annotation_association, + stored_workflow_rating_association, + stored_workflow_tag_association_factory, + stored_workflow_user_share_association, + ): + obj = cls_() + obj.user = user + obj.latest_workflow = workflow + obj.tags.append(stored_workflow_tag_association) + obj.annotations.append(stored_workflow_annotation_association) + obj.ratings.append(stored_workflow_rating_association) + obj.users_shared_with.append(stored_workflow_user_share_association) + + # setup workflow for testing workflows attribure + wf = workflow_factory() + wf.stored_workflow = obj + + # setup owner tag association for testing owner_tags + tag_assoc2 = stored_workflow_tag_association_factory() + tag_assoc2.user = user + tag_assoc2.stored_workflow = obj + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id, unique=True) + assert stored_obj.user.id == user.id + assert stored_obj.latest_workflow.id == workflow.id + assert stored_obj.workflows[0].id == wf.id + assert stored_obj.annotations == [stored_workflow_annotation_association] + assert stored_obj.ratings == [stored_workflow_rating_association] + # This doesn't test the average amount, just the mapping. + assert stored_obj.average_rating == stored_workflow_rating_association.rating + assert are_same_entity_collections( + stored_obj.tags, [stored_workflow_tag_association, tag_assoc2]) + assert stored_obj.owner_tags == [tag_assoc2] + assert stored_obj.users_shared_with == [stored_workflow_user_share_association] + + delete_from_database(session, [wf, tag_assoc2]) + + def test_average_rating( + self, + session, + stored_workflow, + user, + stored_workflow_rating_association_factory + ): + _run_average_rating_test( + session, stored_workflow, user, stored_workflow_rating_association_factory) + + +class TestStoredWorkflowAnnotationAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'stored_workflow_annotation_association' + assert has_index(cls_.__table__, ('annotation',)) + + def test_columns(self, session, cls_, stored_workflow, user): + annotation = 'a' + obj = cls_() + obj.stored_workflow = stored_workflow + obj.user = user + obj.annotation = annotation + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.stored_workflow_id == stored_workflow.id + assert stored_obj.user_id == user.id + assert stored_obj.annotation == annotation + + def test_relationships(self, session, cls_, stored_workflow, user): + obj = cls_() + obj.stored_workflow = stored_workflow + obj.user = user + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.stored_workflow.id == stored_workflow.id + assert stored_obj.user.id == user.id + + +class TestStoredWorkflowMenuEntry(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'stored_workflow_menu_entry' + + def test_columns(self, session, cls_, stored_workflow, user): + order_index = 1 + obj = cls_() + obj.stored_workflow = stored_workflow + obj.user = user + obj.order_index = order_index + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.stored_workflow_id == stored_workflow.id + assert stored_obj.user_id == user.id + assert stored_obj.order_index == order_index + + def test_relationships(self, session, cls_, stored_workflow, user): + obj = cls_() + obj.stored_workflow = stored_workflow + obj.user = user + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.stored_workflow.id == stored_workflow.id + assert stored_obj.user.id == user.id + + +class TestStoredWorkflowRatingAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'stored_workflow_rating_association' + + def test_columns(self, session, cls_, stored_workflow, user): + rating = 9 + obj = cls_(user, stored_workflow, rating) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.stored_workflow_id == stored_workflow.id + assert stored_obj.user_id == user.id + assert stored_obj.rating == rating + + def test_relationships(self, session, cls_, stored_workflow, user): + obj = cls_(user, stored_workflow, 1) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.stored_workflow.id == stored_workflow.id + assert stored_obj.user.id == user.id + + +class TestStoredWorkflowTagAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'stored_workflow_tag_association' + + def test_columns(self, session, cls_, stored_workflow, tag, user): + user_tname, value, user_value = 'a', 'b', 'c' + obj = cls_(user=user, tag=tag, user_tname=user_tname, value=value) + obj.user_value = user_value + obj.stored_workflow = stored_workflow + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.stored_workflow_id == stored_workflow.id + assert stored_obj.tag_id == tag.id + assert stored_obj.user_id == user.id + assert stored_obj.user_tname == user_tname + assert stored_obj.value == value + assert stored_obj.user_value == user_value + + def test_relationships(self, session, cls_, stored_workflow, tag, user): + obj = cls_(user=user, tag=tag) + obj.stored_workflow = stored_workflow + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.stored_workflow.id == stored_workflow.id + assert stored_obj.tag.id == tag.id + assert stored_obj.user.id == user.id + + +class TestStoredWorkflowUserShareAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'stored_workflow_user_share_connection' + + def test_columns(self, session, cls_, stored_workflow, user): + obj = cls_() + obj.stored_workflow = stored_workflow + obj.user = user + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.stored_workflow_id == stored_workflow.id + assert stored_obj.user_id == user.id + + def test_relationships(self, session, cls_, stored_workflow, user): + obj = cls_() + obj.stored_workflow = stored_workflow + obj.user = user + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.stored_workflow.id == stored_workflow.id + assert stored_obj.user.id == user.id + + +class TestTag(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'tag' + assert has_unique_constraint(cls_.__table__, ('name',)) + + def test_columns(self, session, cls_): + parent_tag = cls_() + type_, name = 1, 'a' + obj = cls_(type=type_, name=name) + obj.parent = parent_tag + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.type == type_ + assert stored_obj.parent_id == parent_tag.id + assert stored_obj.name == name + + def test_relationships( + self, + session, + cls_, + history_tag_association, + history_dataset_association_tag_association, + library_dataset_dataset_association_tag_association, + page_tag_association, + workflow_step_tag_association, + stored_workflow_tag_association, + visualization_tag_association, + history_dataset_collection_tag_association, + library_dataset_collection_tag_association, + tool_tag_association, + ): + obj = cls_() + parent_tag = cls_() + child_tag = cls_() + obj.parent = parent_tag + obj.children.append(child_tag) + + def add_association(assoc_object, assoc_attribute): + assoc_object.tag = obj + getattr(obj, assoc_attribute).append(assoc_object) + + add_association(history_tag_association, 'tagged_histories') + add_association( + history_dataset_association_tag_association, 'tagged_history_dataset_associations') + add_association( + library_dataset_dataset_association_tag_association, + 'tagged_library_dataset_dataset_associations') + add_association(page_tag_association, 'tagged_pages') + add_association(workflow_step_tag_association, 'tagged_workflow_steps') + add_association(stored_workflow_tag_association, 'tagged_stored_workflows') + add_association(visualization_tag_association, 'tagged_visualizations') + add_association( + history_dataset_collection_tag_association, 'tagged_history_dataset_collections') + add_association( + library_dataset_collection_tag_association, 'tagged_library_dataset_collections') + add_association(tool_tag_association, 'tagged_tools') + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.parent.id == parent_tag.id + assert stored_obj.children == [child_tag] + assert stored_obj.tagged_histories == [history_tag_association] + assert (stored_obj.tagged_history_dataset_associations + == [history_dataset_association_tag_association]) + assert (stored_obj.tagged_library_dataset_dataset_associations + == [library_dataset_dataset_association_tag_association]) + assert stored_obj.tagged_pages == [page_tag_association] + assert stored_obj.tagged_workflow_steps == [workflow_step_tag_association] + assert stored_obj.tagged_stored_workflows == [stored_workflow_tag_association] + assert stored_obj.tagged_visualizations == [visualization_tag_association] + assert (stored_obj.tagged_history_dataset_collections + == [history_dataset_collection_tag_association]) + assert (stored_obj.tagged_library_dataset_collections + == [library_dataset_collection_tag_association]) + assert stored_obj.tagged_tools == [tool_tag_association] + + +class TestTask(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'task' + + def test_columns(self, session, cls_, job): + create_time = datetime.now() + execution_time = create_time + timedelta(hours=1) + update_time = execution_time + timedelta(hours=1) + state = 'p' + command_line = 'a' + param_filename = 'b' + runner_name = 'c' + job_stdout = 'd' + job_stderr = 'e' + tool_stdout = 'f' + tool_stderr = 'g' + exit_code = 9 + job_messages = 'h' + info = 'i' + traceback = 'j' + working_directory = 'k' + task_runner_name = 'l' + task_runner_external_id = 'm' + prepare_input_files_cmd = 'n' + + obj = cls_(job, working_directory, prepare_input_files_cmd) + obj.create_time = create_time + obj.execution_time = execution_time + obj.update_time = update_time + obj.state = state + obj.command_line = command_line + obj.param_filename = param_filename + obj.runner_name = runner_name + obj.job_stdout = job_stdout + obj.job_stderr = job_stderr + obj.tool_stdout = tool_stdout + obj.tool_stderr = tool_stderr + obj.exit_code = exit_code + obj.job_messages = job_messages + obj.info = info + obj.traceback = traceback + obj.task_runner_name = task_runner_name + obj.task_runner_external_id = task_runner_external_id + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.execution_time == execution_time + assert stored_obj.update_time == update_time + assert stored_obj.state == state + assert stored_obj.command_line == command_line + assert stored_obj.param_filename == param_filename + assert stored_obj.runner_name == runner_name + assert stored_obj.job_stdout == job_stdout + assert stored_obj.job_stderr == job_stderr + assert stored_obj.tool_stdout == tool_stdout + assert stored_obj.tool_stderr == tool_stderr + assert stored_obj.exit_code == exit_code + assert stored_obj.job_messages == job_messages + assert stored_obj.info == info + assert stored_obj.traceback == traceback + assert stored_obj.task_runner_name == task_runner_name + assert stored_obj.task_runner_external_id == task_runner_external_id + + def test_relationships(self, session, cls_, job, task_metric_numeric, task_metric_text): + obj = cls_(job, None, None) + obj.numeric_metrics.append(task_metric_numeric) + obj.text_metrics.append(task_metric_text) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.job.id == job.id + assert stored_obj.numeric_metrics == [task_metric_numeric] + assert stored_obj.text_metrics == [task_metric_text] + + +class TestTaskMetricNumeric(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'task_metric_numeric' + + def test_columns(self, session, cls_, task): + plugin, metric_name, metric_value = 'a', 'b', 9 + obj = cls_(plugin, metric_name, metric_value) + obj.task = task + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.task_id == task.id + assert stored_obj.plugin == plugin + assert stored_obj.metric_value == metric_value + + def test_relationships(self, session, cls_, task): + obj = cls_(None, None, None) + obj.task = task + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.task.id == task.id + + +class TestTaskMetricText(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'task_metric_text' + + def test_columns(self, session, cls_, task): + plugin, metric_name, metric_value = 'a', 'b', 'c' + obj = cls_(plugin, metric_name, metric_value) + obj.task = task + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.task_id == task.id + assert stored_obj.plugin == plugin + assert stored_obj.metric_value == metric_value + + def test_relationships(self, session, cls_, task): + obj = cls_(None, None, None) + obj.task = task + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.task.id == task.id + + +class TestToolTagAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'tool_tag_association' + + def test_columns(self, session, cls_, tag, user): + user_tname, value, user_value, tool_id = 'a', 'b', 'c', 'd' + obj = cls_(user=user, tag=tag, user_tname=user_tname, value=value) + obj.user_value = user_value + obj.tool_id = tool_id + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.tool_id == tool_id + assert stored_obj.tag_id == tag.id + assert stored_obj.user_id == user.id + assert stored_obj.user_tname == user_tname + assert stored_obj.value == value + assert stored_obj.user_value == user_value + + def test_relationships(self, session, cls_, tag, user): + obj = cls_(user=user, tag=tag) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.tag.id == tag.id + assert stored_obj.user.id == user.id + + +class TestTransferJob(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'transfer_job' + + def test_columns(self, session, cls_): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + state, path, info, pid, socket, params = 'd', 'a', 'b', 2, 3, 'c' + obj = cls_(state, path, info, pid, socket, params) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.state == state + assert stored_obj.path == path + assert stored_obj.info == info + assert stored_obj.pid == pid + assert stored_obj.socket == socket + assert stored_obj.params == params + + def test_relationships(self, session, cls_, genome_index_tool_data): + obj = cls_() + obj.transfer_job.append(genome_index_tool_data) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.transfer_job == [genome_index_tool_data] + + +class TestUser(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'galaxy_user' + + def test_columns(self, session, cls_, form_values): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + email = get_unique_value() + username = get_unique_value() + password = 'c' + last_password_change = update_time + external = True + deleted = True + purged = True + disk_usage = 1 + active = False + activation_token = 'd' + + obj = cls_() + obj.create_time = create_time + obj.update_time = update_time + obj.email = email + obj.username = username + obj.password = password + obj.last_password_change = last_password_change + obj.external = external + obj.values = form_values + obj.deleted = deleted + obj.purged = purged + obj.disk_usage = disk_usage + obj.active = active + obj.activation_token = activation_token + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.email == email + assert stored_obj.username == username + assert stored_obj.password == password + assert stored_obj.last_password_change == last_password_change + assert stored_obj.external == external + assert stored_obj.form_values_id == form_values.id + assert stored_obj.deleted == deleted + assert stored_obj.purged == purged + assert stored_obj.disk_usage == disk_usage + assert stored_obj.active == active + assert stored_obj.activation_token == activation_token + + def test_relationships( + self, + session, + cls_, + form_values, + user_address, + cloud_authz, + custos_authnz_token, + default_user_permissions, + user_group_association, + history_factory, + galaxy_session, + page_user_share_association, + user_quota_association, + user_authnz_token, + user_preference, + api_keys, + page, + password_reset_token, + history_user_share_association, + data_manager_history_association, + stored_workflow_user_share_association, + user_role_association, + stored_workflow, + stored_workflow_menu_entry_factory, + visualization_user_share_association, + ): + history1 = history_factory(deleted=False) + history2 = history_factory(deleted=True) + + obj = cls_() + + obj.email = get_unique_value() + obj.username = get_unique_value() + obj.password = 'a' + obj.values = form_values + obj.addresses.append(user_address) + obj.cloudauthz.append(cloud_authz) + obj.custos_auth.append(custos_authnz_token) + obj.default_permissions.append(default_user_permissions) + obj.groups.append(user_group_association) + obj.histories.append(history1) + obj.histories.append(history2) + obj.galaxy_sessions.append(galaxy_session) + obj.pages_shared_by_others.append(page_user_share_association) + obj.quotas.append(user_quota_association) + obj.social_auth.append(user_authnz_token) + + swme = stored_workflow_menu_entry_factory() + swme.stored_workflow = stored_workflow + swme.user = obj + + user_preference.name = 'a' + obj._preferences.set(user_preference) + + obj.api_keys.append(api_keys) + obj.pages.append(page) + obj.reset_tokens.append(password_reset_token) + obj.histories_shared_by_others.append(history_user_share_association) + obj.data_manager_histories.append(data_manager_history_association) + obj.workflows_shared_by_others.append(stored_workflow_user_share_association) + obj.roles.append(user_role_association) + obj.stored_workflows.append(stored_workflow) + obj.visualizations_shared_by_others.append(visualization_user_share_association) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.values.id == form_values.id + assert stored_obj.addresses == [user_address] + assert stored_obj.cloudauthz == [cloud_authz] + assert stored_obj.custos_auth == [custos_authnz_token] + assert stored_obj.default_permissions == [default_user_permissions] + assert stored_obj.groups == [user_group_association] + assert are_same_entity_collections(stored_obj.histories, [history1, history2]) + assert stored_obj.active_histories == [history1] + assert stored_obj.galaxy_sessions == [galaxy_session] + assert stored_obj.pages_shared_by_others == [page_user_share_association] + assert stored_obj.quotas == [user_quota_association] + assert stored_obj.social_auth == [user_authnz_token] + assert stored_obj.stored_workflow_menu_entries == [swme] + assert user_preference in stored_obj._preferences.values() + assert stored_obj.api_keys == [api_keys] + assert stored_obj.pages == [page] + assert stored_obj.reset_tokens == [password_reset_token] + assert stored_obj.histories_shared_by_others == [history_user_share_association] + assert stored_obj.data_manager_histories == [data_manager_history_association] + assert stored_obj.workflows_shared_by_others == [stored_workflow_user_share_association] + assert stored_obj.roles == [user_role_association] + assert stored_obj.stored_workflows == [stored_workflow] + assert (stored_obj.visualizations_shared_by_others + == [visualization_user_share_association]) + + delete_from_database(session, [history1, history2, swme]) + + +class TestUserAction(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'user_action' + + def test_columns(self, session, cls_, user, galaxy_session): + action, params, context = 'a', 'b', 'c' + create_time = datetime.now() + obj = cls_(user, galaxy_session.id, action, params, context) + obj.create_time = create_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.user_id == user.id + assert stored_obj.session_id == galaxy_session.id + assert stored_obj.action == action + assert stored_obj.context == context + assert stored_obj.params == params + + def test_relationships(self, session, cls_, user, galaxy_session): + obj = cls_(user, galaxy_session.id, None, None, None) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.user.id == user.id + + +class TestUserAddress(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'user_address' + + def test_columns_and_relationships(self, session, cls_, user): + desc, name, institution, address, city, state, postal_code, country, phone, deleted, purged = \ + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', True, False + obj = cls_(user, desc, name, institution, address, city, state, postal_code, country, phone) + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj.create_time = create_time + obj.update_time = update_time + obj.deleted = deleted + obj.purged = purged + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + # test columns + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.user_id == user.id + assert stored_obj.desc == desc + assert stored_obj.name == name + assert stored_obj.institution == institution + assert stored_obj.address == address + assert stored_obj.city == city + assert stored_obj.state == state + assert stored_obj.postal_code == postal_code + assert stored_obj.country == country + assert stored_obj.phone == phone + assert stored_obj.deleted == deleted + assert stored_obj.purged == purged + # test relationships + assert stored_obj.user.id == user.id + + +class TestUserAuthnzToken(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'oidc_user_authnz_tokens' + assert has_unique_constraint(cls_.__table__, ('provider', 'uid')) + + def test_columns(self, session, cls_, user): + provider, uid, extra_data, lifetime, assoc_type = get_unique_value(), 'b', 'c', 1, 'd' + obj = cls_(provider, uid, extra_data, lifetime, assoc_type, user) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.user_id == user.id + assert stored_obj.uid == uid + assert stored_obj.provider == provider + assert stored_obj.extra_data == extra_data + assert stored_obj.lifetime == lifetime + assert stored_obj.assoc_type == assoc_type + + def test_relationships(self, session, cls_, user, cloud_authz): + obj = cls_(get_unique_value(), None, user=user) + obj.cloudauthz.append(cloud_authz) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.cloudauthz == [cloud_authz] + assert stored_obj.user.id == user.id + + +class TestUserGroupAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'user_group_association' + + def test_columns(self, session, cls_, user, group): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_(user, group) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.user_id == user.id + assert stored_obj.group_id == group.id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + + def test_relationships(self, session, cls_, user, group): + obj = cls_(user, group) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.user.id == user.id + assert stored_obj.group.id == group.id + + +class TestUserPreference(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'user_preference' + + def test_columns(self, session, cls_, user): + name, value = 'a', 'b' + obj = cls_(name, value) + obj.user = user + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.name == name + assert stored_obj.value == value + assert stored_obj.user_id == user.id + + def test_relationships(self, session, cls_, user): + obj = cls_() + obj.user = user + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.user.id == user.id + + +class TestUserQuotaAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'user_quota_association' + + def test_columns(self, session, cls_, user, quota): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_(user, quota) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.user_id == user.id + assert stored_obj.quota_id == quota.id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + + def test_relationships(self, session, cls_, user, quota): + obj = cls_(user, quota) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.user.id == user.id + assert stored_obj.quota.id == quota.id + + +class TestUserRoleAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'user_role_association' + + def test_columns(self, session, cls_, user, role): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_(user, role) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.user_id == user.id + assert stored_obj.role_id == role.id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + + def test_relationships(self, session, cls_, user, role): + obj = cls_(user, role) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.user.id == user.id + assert stored_obj.role.id == role.id + + +class TestVisualization(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'visualization' + assert has_index(cls_.__table__, ('dbkey',)) + assert has_index(cls_.__table__, ('slug',)) + + def test_columns(self, session, cls_, user, visualization_revision): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + title = 'a' + type = 'b' + dbkey = 'c' + deleted = True + importable = True + slug = 'd' + published = True + + obj = cls_() + obj.create_time = create_time + obj.update_time = update_time + obj.user = user + obj.latest_revision = visualization_revision + obj.title = title + obj.type = type + obj.dbkey = dbkey + obj.deleted = deleted + obj.importable = importable + obj.slug = slug + obj.published = published + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.user_id == user.id + assert stored_obj.latest_revision_id == visualization_revision.id + assert stored_obj.title == title + assert stored_obj.type == type + assert stored_obj.dbkey == dbkey + assert stored_obj.deleted == deleted + assert stored_obj.importable == importable + assert stored_obj.slug == slug + assert stored_obj.published == published + + def test_relationships( + self, + session, + cls_, + user, + visualization_revision, + visualization_tag_association, + visualization_annotation_association, + visualization_rating_association, + visualization_revision_factory, + visualization_user_share_association + ): + revision2 = visualization_revision_factory() + persist(session, revision2) + + obj = cls_() + obj.user = user + obj.latest_revision = visualization_revision + obj.revisions.append(revision2) + obj.tags.append(visualization_tag_association) + obj.annotations.append(visualization_annotation_association) + obj.ratings.append(visualization_rating_association) + obj.users_shared_with.append(visualization_user_share_association) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.user.id == user.id + assert stored_obj.latest_revision.id == visualization_revision.id + assert stored_obj.revisions == [revision2] + assert stored_obj.tags == [visualization_tag_association] + assert stored_obj.annotations == [visualization_annotation_association] + assert stored_obj.ratings == [visualization_rating_association] + # This doesn't test the average amount, just the mapping. + assert stored_obj.average_rating == visualization_rating_association.rating + assert stored_obj.users_shared_with == [visualization_user_share_association] + + delete_from_database(session, revision2) + + def test_average_rating( + self, + session, + visualization, + user, + visualization_rating_association_factory + ): + _run_average_rating_test( + session, visualization, user, visualization_rating_association_factory) + + +class TestVisualizationAnnotationAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'visualization_annotation_association' + assert has_index(cls_.__table__, ('annotation',)) + + def test_columns(self, session, cls_, visualization, user): + annotation = 'a' + obj = cls_() + obj.user = user + obj.visualization = visualization + obj.annotation = annotation + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.visualization_id == visualization.id + assert stored_obj.user_id == user.id + assert stored_obj.annotation == annotation + + def test_relationships(self, session, cls_, visualization, user): + obj = cls_() + obj.user = user + obj.visualization = visualization + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.visualization.id == visualization.id + assert stored_obj.user.id == user.id + + +class TestVisualizationRatingAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'visualization_rating_association' + + def test_columns(self, session, cls_, visualization, user): + rating = 9 + obj = cls_(user, visualization, rating) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.visualization_id == visualization.id + assert stored_obj.user_id == user.id + assert stored_obj.rating == rating + + def test_relationships(self, session, cls_, visualization, user): + obj = cls_(user, visualization, 1) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.visualization.id == visualization.id + assert stored_obj.user.id == user.id + + +class TestVisualizationRevision(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'visualization_revision' + assert has_index(cls_.__table__, ('dbkey',)) + + def test_columns(self, session, cls_, visualization): + visualization, title, dbkey, config = visualization, 'a', 'b', 'c' + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + obj = cls_(visualization, title, dbkey, config) + obj.create_time = create_time + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.visualization_id == visualization.id + assert stored_obj.title == title + assert stored_obj.dbkey == dbkey + assert stored_obj.config == config + + def test_relationships(self, session, cls_, visualization): + obj = cls_(visualization) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.visualization.id == visualization.id + + +class TestVisualizationTagAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'visualization_tag_association' + + def test_columns(self, session, cls_, visualization, tag, user): + user_tname, value, user_value = 'a', 'b', 'c' + obj = cls_(user=user, tag=tag, user_tname=user_tname, value=value) + obj.user_value = user_value + obj.visualization = visualization + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.visualization_id == visualization.id + assert stored_obj.tag_id == tag.id + assert stored_obj.user_id == user.id + assert stored_obj.user_tname == user_tname + assert stored_obj.value == value + assert stored_obj.user_value == user_value + + def test_relationships(self, session, cls_, visualization, tag, user): + obj = cls_(user=user, tag=tag) + obj.visualization = visualization + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.visualization.id == visualization.id + assert stored_obj.tag.id == tag.id + assert stored_obj.user.id == user.id + + +class TestVisualizationUserShareAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'visualization_user_share_association' + + def test_columns(self, session, cls_, visualization, user): + obj = cls_() + obj.visualization = visualization + obj.user = user + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.visualization_id == visualization.id + assert stored_obj.user_id == user.id + + def test_relationships(self, session, cls_, visualization, user): + obj = cls_() + obj.visualization = visualization + obj.user = user + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.visualization.id == visualization.id + assert stored_obj.user.id == user.id + + +class TestWorkerProcess(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'worker_process' + assert has_unique_constraint(cls_.__table__, ('server_name', 'hostname')) + + def test_columns(self, session, cls_): + server_name, hostname = get_unique_value(), 'a' + update_time = datetime.now() + obj = cls_(server_name, hostname) + obj.update_time = update_time + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.server_name == server_name + assert stored_obj.hostname == hostname + assert stored_obj.pid is None + assert stored_obj.update_time == update_time + + +class TestWorkflow(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow' + + def test_columns(self, session, cls_, stored_workflow, workflow): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + name = 'a' + has_cycles = True + has_errors = True + reports_config = 'b' + creator_metadata = 'c' + license = 'd' + uuid = uuid4() + + obj = cls_() + obj.create_time = create_time + obj.update_time = update_time + obj.stored_workflow = stored_workflow + obj.parent_workflow_id = workflow.id + obj.name = name + obj.has_cycles = has_cycles + obj.has_errors = has_errors + obj.reports_config = reports_config + obj.creator_metadata = creator_metadata + obj.license = license + obj.uuid = uuid + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id, unique=True) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.stored_workflow_id == stored_workflow.id + assert stored_obj.parent_workflow_id == workflow.id + assert stored_obj.name == name + assert stored_obj.has_cycles == has_cycles + assert stored_obj.has_errors == has_errors + assert stored_obj.reports_config == reports_config + assert stored_obj.creator_metadata == creator_metadata + assert stored_obj.license == license + assert stored_obj.uuid == uuid + + def test_relationships(self, session, cls_, stored_workflow, workflow, workflow_step_factory): + obj = cls_() + obj.stored_workflow = stored_workflow + obj.parent_workflow_id = workflow.id + + # Setup workflow steps to test attribures: steps, parent_workflow_step + workflow_step = workflow_step_factory(workflow=obj) + parent_workflow_step = workflow_step_factory(subworkflow=obj) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id, unique=True) + assert stored_obj.stored_workflow_id == stored_workflow.id + assert stored_obj.parent_workflow_id == workflow.id + assert stored_obj.steps[0].id == workflow_step.id + assert stored_obj.step_count == 1 + assert stored_obj.parent_workflow_steps[0].id == parent_workflow_step.id + + delete_from_database(session, [workflow_step, parent_workflow_step]) + + +class TestWorkflowInvocation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_invocation' + + def test_columns(self, session, cls_, workflow, history): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + state = 'a' + scheduler = 'b' + handler = 'c' + uuid = uuid4() + + obj = cls_() + obj.create_time = create_time + obj.update_time = update_time + obj.workflow = workflow + obj.state = state + obj.scheduler = scheduler + obj.handler = handler + obj.uuid = uuid + obj.history = history + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.workflow_id == workflow.id + assert stored_obj.state == state + assert stored_obj.scheduler == scheduler + assert stored_obj.handler == handler + assert stored_obj.uuid == uuid + assert stored_obj.history_id == history.id + + def test_relationships( + self, + session, + cls_, + workflow, + history, + workflow_invocation_output_dataset_association, + workflow_invocation_output_dataset_collection_association, + workflow_invocation_step, + workflow_invocation_to_subworkflow_invocation_association_factory, + workflow_request_input_parameter, + workflow_request_input_step_parameter, + workflow_request_step_state, + workflow_request_to_input_dataset_association, + workflow_request_to_input_dataset_collection_association, + workflow_invocation_output_value, + ): + subworkflow_invocation_assoc = \ + workflow_invocation_to_subworkflow_invocation_association_factory() + parent_workflow_invocation_assoc = \ + workflow_invocation_to_subworkflow_invocation_association_factory() + + obj = cls_() + obj.workflow = workflow + obj.history = history + obj.input_parameters.append(workflow_request_input_parameter) + obj.step_states.append(workflow_request_step_state) + obj.input_step_parameters.append(workflow_request_input_step_parameter) + obj.input_datasets.append(workflow_request_to_input_dataset_association) + obj.input_dataset_collections.append( + workflow_request_to_input_dataset_collection_association) + obj.subworkflow_invocations.append(subworkflow_invocation_assoc) + obj.steps.append(workflow_invocation_step) + obj.output_dataset_collections.append( + workflow_invocation_output_dataset_collection_association) + obj.output_datasets.append(workflow_invocation_output_dataset_association) + obj.parent_workflow_invocation_association.append(parent_workflow_invocation_assoc) + obj.output_values.append(workflow_invocation_output_value) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow.id == workflow.id + assert stored_obj.history.id == history.id + + assert stored_obj.input_parameters == [workflow_request_input_parameter] + assert stored_obj.step_states == [workflow_request_step_state] + assert stored_obj.input_step_parameters == [workflow_request_input_step_parameter] + assert stored_obj.input_datasets == [workflow_request_to_input_dataset_association] + assert (stored_obj.input_dataset_collections + == [workflow_request_to_input_dataset_collection_association]) + assert stored_obj.subworkflow_invocations == [subworkflow_invocation_assoc] + assert stored_obj.steps == [workflow_invocation_step] + assert (stored_obj.output_dataset_collections + == [workflow_invocation_output_dataset_collection_association]) + assert stored_obj.output_datasets == [workflow_invocation_output_dataset_association] + assert (stored_obj.parent_workflow_invocation_association + == [parent_workflow_invocation_assoc]) + assert stored_obj.output_values == [workflow_invocation_output_value] + + delete_from_database( + session, [subworkflow_invocation_assoc, parent_workflow_invocation_assoc]) + + +class TestWorkflowInvocationOutputDatasetAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_invocation_output_dataset_association' + + def test_columns( + self, + session, + cls_, + workflow_invocation, + workflow_step, + history_dataset_association, + workflow_output, + ): + obj = cls_() + obj.workflow_invocation = workflow_invocation + obj.workflow_step = workflow_step + obj.dataset = history_dataset_association + obj.workflow_output = workflow_output + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.workflow_invocation_id == workflow_invocation.id + assert stored_obj.workflow_step_id == workflow_step.id + assert stored_obj.dataset_id == history_dataset_association.id + assert stored_obj.workflow_output_id == workflow_output.id + + def test_relationships( + self, + session, + cls_, + workflow_invocation, + workflow_step, + history_dataset_association, + workflow_output, + ): + obj = cls_() + obj.workflow_invocation = workflow_invocation + obj.workflow_step = workflow_step + obj.dataset = history_dataset_association + obj.workflow_output = workflow_output + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_invocation.id == workflow_invocation.id + assert stored_obj.workflow_step.id == workflow_step.id + assert stored_obj.dataset.id == history_dataset_association.id + assert stored_obj.workflow_output.id == workflow_output.id + + +class TestWorkflowInvocationOutputDatasetCollectionAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_invocation_output_dataset_collection_association' + + def test_columns( + self, + session, + cls_, + workflow_invocation, + workflow_step, + history_dataset_collection_association, + workflow_output, + ): + obj = cls_() + obj.workflow_invocation = workflow_invocation + obj.workflow_step = workflow_step + obj.dataset_collection = history_dataset_collection_association + obj.workflow_output = workflow_output + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.workflow_invocation_id == workflow_invocation.id + assert stored_obj.workflow_step_id == workflow_step.id + assert stored_obj.dataset_collection_id == history_dataset_collection_association.id + assert stored_obj.workflow_output_id == workflow_output.id + + def test_relationships( + self, + session, + cls_, + workflow_invocation, + workflow_step, + history_dataset_collection_association, + workflow_output, + ): + obj = cls_() + obj.workflow_invocation = workflow_invocation + obj.workflow_step = workflow_step + obj.dataset_collection = history_dataset_collection_association + obj.workflow_output = workflow_output + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_invocation.id == workflow_invocation.id + assert stored_obj.workflow_step.id == workflow_step.id + assert stored_obj.dataset_collection.id == history_dataset_collection_association.id + assert stored_obj.workflow_output.id == workflow_output.id + + +class TestWorkflowInvocationOutputValue(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_invocation_output_value' + + def test_columns( + self, + session, + cls_, + workflow_invocation, + workflow_step, + workflow_output, + ): + value = 'a' + obj = cls_() + obj.workflow_invocation = workflow_invocation + obj.workflow_step = workflow_step + obj.workflow_output = workflow_output + obj.value = value + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.workflow_invocation_id == workflow_invocation.id + assert stored_obj.workflow_step_id == workflow_step.id + assert stored_obj.workflow_output_id == workflow_output.id + assert stored_obj.value == value + + def test_relationships( + self, + session, + cls_, + workflow_invocation, + workflow_step, + workflow_output, + workflow_invocation_step, + ): + # setup workflow_invocation_step to test the workflow_invocation_step attribute + workflow_invocation_step.workflow_invocation = workflow_invocation + workflow_invocation_step.workflow_step = workflow_step + persist(session, workflow_invocation_step) + + obj = cls_() + obj.workflow_invocation = workflow_invocation + obj.workflow_step = workflow_step + obj.workflow_output = workflow_output + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_invocation.id == workflow_invocation.id + assert stored_obj.workflow_step.id == workflow_step.id + assert stored_obj.workflow_output.id == workflow_output.id + assert stored_obj.workflow_invocation_step[0].id == workflow_invocation_step.id + + delete_from_database(session, [workflow_invocation_step]) + + +class TestWorkflowInvocationStep(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_invocation_step' + + def test_columns( + self, + session, + cls_, + workflow_invocation, + workflow_step, + job, + implicit_collection_jobs, + ): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + state, action = 'a', 'b' + + session.add(job) # must be bound to a session for lazy load of attributes + session.add(implicit_collection_jobs) # must be bound to a session for lazy load of attributes + + obj = cls_() + obj.create_time = create_time + obj.update_time = update_time + obj.workflow_invocation = workflow_invocation + obj.workflow_step = workflow_step + obj.state = state + obj.job = job + obj.implicit_collection_jobs = implicit_collection_jobs + obj.action = action + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.workflow_invocation_id == workflow_invocation.id + assert stored_obj.workflow_step_id == workflow_step.id + assert stored_obj.state == state + assert stored_obj.job_id == job.id + assert stored_obj.implicit_collection_jobs_id == implicit_collection_jobs.id + assert stored_obj.action == action + + def test_relationships( + self, + session, + cls_, + workflow_invocation, + workflow_step, + job, + implicit_collection_jobs, + workflow_invocation_step_output_dataset_collection_association, + workflow_invocation_step_output_dataset_association, + workflow_invocation_output_value, + ): + session.add(job) # must be bound to a session for lazy load of attributes + session.add(implicit_collection_jobs) # must be bound to a session for lazy load of attributes + + # setup workflow_invocation_output_value to test the output_value attribute + output_value = workflow_invocation_output_value + output_value.workflow_invocation = workflow_invocation + output_value.workflow_step = workflow_step + persist(session, output_value) + + obj = cls_() + obj.workflow_invocation = workflow_invocation + obj.workflow_step = workflow_step + obj.job = job + obj.implicit_collection_jobs = implicit_collection_jobs + obj.output_dataset_collections.append( + workflow_invocation_step_output_dataset_collection_association) + obj.output_datasets.append(workflow_invocation_step_output_dataset_association) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_invocation.id == workflow_invocation.id + assert stored_obj.workflow_step.id == workflow_step.id + assert stored_obj.job.id == job.id + assert stored_obj.implicit_collection_jobs.id == implicit_collection_jobs.id + assert (stored_obj.output_dataset_collections + == [workflow_invocation_step_output_dataset_collection_association]) + assert (stored_obj.output_datasets + == [workflow_invocation_step_output_dataset_association]) + assert stored_obj.output_value.id == workflow_invocation_output_value.id + + def test_subworkflow_invocation_attribute( + self, + session, + cls_, + workflow_step, + workflow_invocation_to_subworkflow_invocation_association_factory, + workflow_invocation_factory, + ): + # use defaults to create 2 workflows + workflow_invocation1 = workflow_invocation_factory() + workflow_invocation2 = workflow_invocation_factory() # this is the subworkflow invocation + + # store to retrieve object ids + persist(session, workflow_invocation1) + persist(session, workflow_invocation2) + persist(session, workflow_step) + + # setup assoc object and store + assoc = workflow_invocation_to_subworkflow_invocation_association_factory() + assoc.workflow_invocation_id = workflow_invocation1.id + assoc.subworkflow_invocation_id = workflow_invocation2.id + assoc.workflow_step_id = workflow_step.id + persist(session, assoc) + + # setup main object under test + obj = cls_() + obj.workflow_invocation = workflow_invocation1 + obj.workflow_step = workflow_step + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.subworkflow_invocation_id == workflow_invocation2.id + + # finish cleanup + persisted = [workflow_invocation1, workflow_invocation2, workflow_step, assoc] + delete_from_database(session, persisted) + + +class TestWorkflowInvocationStepOutputDatasetAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_invocation_step_output_dataset_association' + + def test_columns( + self, + session, + cls_, + workflow_invocation_step, + history_dataset_association + ): + output_name = 'a' + obj = cls_() + obj.workflow_invocation_step = workflow_invocation_step + obj.dataset = history_dataset_association + obj.output_name = output_name + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.workflow_invocation_step_id == workflow_invocation_step.id + assert stored_obj.dataset_id == history_dataset_association.id + assert stored_obj.output_name == output_name + + def test_relationships( + self, + session, + cls_, + workflow_invocation_step, + history_dataset_association + ): + obj = cls_() + obj.workflow_invocation_step = workflow_invocation_step + obj.dataset = history_dataset_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_invocation_step.id == workflow_invocation_step.id + assert stored_obj.dataset.id == history_dataset_association.id + + +class TestWorkflowInvocationStepOutputDatasetCollectionAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_invocation_step_output_dataset_collection_association' + + def test_columns( + self, + session, + cls_, + workflow_invocation_step, + workflow_step, + history_dataset_collection_association, + ): + output_name = 'a' + obj = cls_() + obj.workflow_invocation_step = workflow_invocation_step + obj.workflow_step_id = workflow_step.id + obj.dataset_collection = history_dataset_collection_association + obj.output_name = output_name + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.workflow_invocation_step_id == workflow_invocation_step.id + assert stored_obj.workflow_step_id == workflow_step.id + assert stored_obj.dataset_collection_id == history_dataset_collection_association.id + assert stored_obj.output_name == output_name + + def test_relationships( + self, + session, + cls_, + workflow_invocation_step, + history_dataset_collection_association, + ): + obj = cls_() + obj.workflow_invocation_step = workflow_invocation_step + obj.dataset_collection = history_dataset_collection_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_invocation_step.id == workflow_invocation_step.id + assert stored_obj.dataset_collection.id == history_dataset_collection_association.id + + +class TestWorkflowInvocationToSubworkflowInvocationAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_invocation_to_subworkflow_invocation_association' + + def test_columns( + self, + session, + cls_, + workflow_invocation, + workflow_step, + workflow, + workflow_invocation_factory, + ): + subworkflow_invocation = workflow_invocation_factory() + subworkflow_invocation.workflow = workflow + persist(session, subworkflow_invocation) + + obj = cls_() + obj.workflow_invocation_id = workflow_invocation.id + obj.subworkflow_invocation = subworkflow_invocation + obj.workflow_step = workflow_step + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.workflow_invocation_id == workflow_invocation.id + assert stored_obj.subworkflow_invocation_id == subworkflow_invocation.id + assert stored_obj.workflow_step_id == workflow_step.id + + delete_from_database(session, subworkflow_invocation) + + def test_relationships( + self, + session, + cls_, + workflow_invocation, + workflow_step, + workflow_invocation_factory, + ): + parent_workflow_invocation = workflow_invocation_factory() + persist(session, parent_workflow_invocation) + + obj = cls_() + obj.subworkflow_invocation = workflow_invocation # We need only 1 instance, so we use the fixture + obj.workflow_step = workflow_step + obj.parent_workflow_invocation = parent_workflow_invocation + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.subworkflow_invocation.id == workflow_invocation.id + assert stored_obj.workflow_step.id == workflow_step.id + assert stored_obj.parent_workflow_invocation.id == parent_workflow_invocation.id + + delete_from_database(session, parent_workflow_invocation) + + +class TestWorkflowOutput(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_output' + + def test_columns(self, session, cls_, workflow_step): + output_name, label, uuid = 'a', 'b', uuid4() + obj = cls_(workflow_step, output_name, label, uuid) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.workflow_step_id == workflow_step.id + assert stored_obj.output_name == output_name + assert stored_obj.label == label + assert stored_obj.uuid == uuid + + def test_relationships(self, session, cls_, workflow_step): + obj = cls_(workflow_step) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_step.id == workflow_step.id + + +class TestWorkflowRequestInputParameter(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_request_input_parameters' + + def test_columns(self, session, cls_, workflow_invocation): + name, value, type = 'a', 'b', 'c' + obj = cls_(name, value, type) + obj.workflow_invocation = workflow_invocation + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.workflow_invocation_id == workflow_invocation.id + assert stored_obj.name == name + assert stored_obj.value == value + assert stored_obj.type == type + + def test_relationships(self, session, cls_, workflow_invocation): + obj = cls_() + obj.workflow_invocation = workflow_invocation + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_invocation.id == workflow_invocation.id + + +class TestWorkflowRequestInputStepParameter(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_request_input_step_parameter' + + def test_columns(self, session, cls_, workflow_step, workflow_invocation): + parameter_value = 'a' + obj = cls_() + obj.workflow_invocation = workflow_invocation + obj.workflow_step = workflow_step + obj.parameter_value = parameter_value + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.workflow_invocation_id == workflow_invocation.id + assert stored_obj.workflow_step_id == workflow_step.id + assert stored_obj.parameter_value == parameter_value + + def test_relationships(self, session, cls_, workflow_step, workflow_invocation): + obj = cls_() + obj.workflow_invocation = workflow_invocation + obj.workflow_step = workflow_step + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_invocation.id == workflow_invocation.id + assert stored_obj.workflow_step.id == workflow_step.id + + +class TestWorkflowRequestStepState(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_request_step_states' + + def test_columns(self, session, cls_, workflow_step, workflow_invocation): + value = 'a' + obj = cls_(workflow_step, None, value) + obj.workflow_invocation = workflow_invocation + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.workflow_invocation_id == workflow_invocation.id + assert stored_obj.workflow_step_id == workflow_step.id + assert stored_obj.value == value + + def test_relationships(self, session, cls_, workflow_step, workflow_invocation): + obj = cls_(workflow_step) + obj.workflow_invocation = workflow_invocation + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_invocation.id == workflow_invocation.id + assert stored_obj.workflow_step.id == workflow_step.id + + +class TestWorkflowRequestToInputDatasetAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_request_to_input_dataset' + + def test_columns( + self, + session, + cls_, + workflow_step, + workflow_invocation, + history_dataset_association + ): + name = 'a' + obj = cls_() + obj.name = name + obj.workflow_invocation = workflow_invocation + obj.workflow_step = workflow_step + obj.dataset = history_dataset_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.workflow_invocation_id == workflow_invocation.id + assert stored_obj.workflow_step_id == workflow_step.id + assert stored_obj.dataset_id == history_dataset_association.id + + def test_relationships( + self, + session, + cls_, + workflow_step, + workflow_invocation, + history_dataset_association + ): + obj = cls_() + obj.workflow_invocation = workflow_invocation + obj.workflow_step = workflow_step + obj.dataset = history_dataset_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_invocation.id == workflow_invocation.id + assert stored_obj.workflow_step.id == workflow_step.id + assert stored_obj.dataset_id == history_dataset_association.id + + +class TestWorkflowRequestToInputDatasetCollectionAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_request_to_input_collection_dataset' + + def test_columns( + self, + session, + cls_, + workflow_step, + workflow_invocation, + history_dataset_collection_association + ): + name = 'a' + obj = cls_() + obj.name = name + obj.workflow_invocation = workflow_invocation + obj.workflow_step = workflow_step + obj.dataset_collection = history_dataset_collection_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.workflow_invocation_id == workflow_invocation.id + assert stored_obj.workflow_step_id == workflow_step.id + assert stored_obj.dataset_collection_id == history_dataset_collection_association.id + + def test_relationships( + self, + session, + cls_, + workflow_step, + workflow_invocation, + history_dataset_collection_association + ): + obj = cls_() + obj.workflow_invocation = workflow_invocation + obj.workflow_step = workflow_step + obj.dataset_collection = history_dataset_collection_association + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_invocation.id == workflow_invocation.id + assert stored_obj.workflow_step.id == workflow_step.id + assert stored_obj.dataset_collection.id == history_dataset_collection_association.id + + +class TestWorkflowStep(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_step' + + def test_columns(self, session, cls_, workflow, dynamic_tool, workflow_factory): + create_time = datetime.now() + update_time = create_time + timedelta(hours=1) + type = 'a' + tool_id = 'b' + tool_version = 'c' + tool_inputs = 'd' + tool_errors = 'e' + position = 'f' + config = 'g' + order_index = 'h' + label = 'k' + uuid = uuid4() + + subworkflow = workflow_factory() + persist(session, subworkflow) + + obj = cls_() + obj.create_time = create_time + obj.update_time = update_time + obj.workflow = workflow + obj.subworkflow = subworkflow + obj.dynamic_tool = dynamic_tool + obj.type = type + obj.tool_id = tool_id + obj.tool_version = tool_version + obj.tool_inputs = tool_inputs + obj.tool_errors = tool_errors + obj.position = position + obj.config = config + obj.order_index = order_index + obj.label = label + obj.uuid = uuid + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.create_time == create_time + assert stored_obj.update_time == update_time + assert stored_obj.workflow_id == workflow.id + assert stored_obj.subworkflow_id == subworkflow.id + assert stored_obj.dynamic_tool_id == dynamic_tool.id + assert stored_obj.type == type + assert stored_obj.tool_id == tool_id + assert stored_obj.tool_version == tool_version + assert stored_obj.tool_inputs == tool_inputs + assert stored_obj.tool_errors == tool_errors + assert stored_obj.position == position + assert stored_obj.config == config + assert stored_obj.order_index == order_index + assert stored_obj.uuid == uuid + assert stored_obj.label == label + + delete_from_database(session, subworkflow) + + def test_relationships( + self, + session, + cls_, + workflow, + dynamic_tool, + workflow_factory, + workflow_step_connection_factory, + ): + subworkflow = workflow_factory() + workflow_step_connection_in = workflow_step_connection_factory() + workflow_step_connection_out = workflow_step_connection_factory() + persist(session, subworkflow) + persist(session, workflow_step_connection_in) + persist(session, workflow_step_connection_out) + + obj = cls_() + obj.workflow = workflow + obj.subworkflow = subworkflow + obj.dynamic_tool = dynamic_tool + obj.parent_workflow_input_connections.append(workflow_step_connection_in) + obj.output_connections.append(workflow_step_connection_out) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow.id == workflow.id + assert stored_obj.subworkflow.id == subworkflow.id + assert stored_obj.dynamic_tool.id == dynamic_tool.id + assert stored_obj.parent_workflow_input_connections == [workflow_step_connection_in] + assert stored_obj.output_connections == [workflow_step_connection_out] + + persisted = [subworkflow, workflow_step_connection_in, workflow_step_connection_out] + delete_from_database(session, persisted) + + +class TestWorkflowStepAnnotationAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_step_annotation_association' + assert has_index(cls_.__table__, ('annotation',)) + + def test_columns(self, session, cls_, workflow_step, user): + annotation = 'a' + obj = cls_() + obj.user = user + obj.workflow_step = workflow_step + obj.annotation = annotation + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.workflow_step_id == workflow_step.id + assert stored_obj.user_id == user.id + assert stored_obj.annotation == annotation + + def test_relationships(self, session, cls_, workflow_step, user): + obj = cls_() + obj.user = user + obj.workflow_step = workflow_step + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_step.id == workflow_step.id + assert stored_obj.user.id == user.id + + +class TestWorkflowStepConnection(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_step_connection' + + def test_columns( + self, + session, + cls_, + workflow_step_input, + workflow_step, + workflow, + workflow_step_factory, + ): + output_name = 'a' + + output_workflow_step = workflow_step_factory() + output_workflow_step.workflow = workflow + persist(session, output_workflow_step) + + obj = cls_() + obj.output_step = output_workflow_step + obj.input_step_input = workflow_step_input + obj.output_name = output_name + obj.input_subworkflow_step = workflow_step + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.output_step_id == output_workflow_step.id + assert stored_obj.input_step_input_id == workflow_step_input.id + assert stored_obj.output_name == output_name + assert stored_obj.input_subworkflow_step_id == workflow_step.id + + delete_from_database(session, [output_workflow_step]) + + def test_relationships( + self, + session, + cls_, + workflow_step_input, + workflow_step, + workflow, + workflow_step_factory, + ): + output_workflow_step = workflow_step_factory() + output_workflow_step.workflow = workflow + persist(session, output_workflow_step) + + obj = cls_() + obj.output_step = output_workflow_step + obj.input_step_input = workflow_step_input + obj.input_subworkflow_step = workflow_step + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.output_step.id == output_workflow_step.id + assert stored_obj.input_step_input.id == workflow_step_input.id + assert stored_obj.input_subworkflow_step.id == workflow_step.id + + delete_from_database(session, [output_workflow_step]) + + +class TestWorkflowStepInput(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_step_input' + assert has_index(cls_.__table__, ('workflow_step_id', 'name')) + + def test_columns(self, session, cls_, workflow_step): + name = 'a' + merge_type = 'b' + scatter_type = 'c' + value_from = 'd' + value_from_type = 'e' + default_value = 'f' + default_value_set = True + runtime_value = True + + obj = cls_(workflow_step) + obj.name = name + obj.merge_type = merge_type + obj.scatter_type = scatter_type + obj.value_from = value_from + obj.value_from_type = value_from_type + obj.default_value = default_value + obj.default_value_set = default_value_set + obj.runtime_value = runtime_value + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.workflow_step_id == workflow_step.id + assert stored_obj.name == name + assert stored_obj.merge_type == merge_type + assert stored_obj.scatter_type == scatter_type + assert stored_obj.value_from == value_from + assert stored_obj.value_from_type == value_from_type + assert stored_obj.default_value == default_value + assert stored_obj.default_value_set == default_value_set + assert stored_obj.runtime_value == runtime_value + + def test_relationships(self, session, cls_, workflow_step, workflow_step_connection): + obj = cls_(workflow_step) + obj.connections.append(workflow_step_connection) + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_step_id == workflow_step.id + assert stored_obj.connections == [workflow_step_connection] + + +class TestWorkflowStepTagAssociation(BaseTest): + + def test_table(self, cls_): + assert cls_.__tablename__ == 'workflow_step_tag_association' + + def test_columns(self, session, cls_, workflow_step, tag, user): + user_tname, value, user_value = 'a', 'b', 'c' + obj = cls_(user=user, tag=tag, user_tname=user_tname, value=value) + obj.user_value = user_value + obj.workflow_step = workflow_step + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.id == obj_id + assert stored_obj.workflow_step_id == workflow_step.id + assert stored_obj.tag_id == tag.id + assert stored_obj.user_id == user.id + assert stored_obj.user_tname == user_tname + assert stored_obj.value == value + assert stored_obj.user_value == user_value + + def test_relationships(self, session, cls_, workflow_step, tag, user): + obj = cls_(user=user, tag=tag) + obj.workflow_step = workflow_step + + with dbcleanup(session, obj) as obj_id: + stored_obj = get_stored_obj(session, cls_, obj_id) + assert stored_obj.workflow_step.id == workflow_step.id + assert stored_obj.tag.id == tag.id + assert stored_obj.user.id == user.id + + +# Misc. helper fixtures. + +@pytest.fixture(scope='module') +def model(): + db_uri = 'sqlite:///:memory:' + return mapping.init('/tmp', db_uri, create_tables=True) + + +@pytest.fixture +def session(model): + Session = model.session + yield Session() + Session.remove() # Ensures we get a new session for each test + + +# Fixtures yielding persisted instances of models, deleted from the database on test exit. + +@pytest.fixture +def api_keys(model, session): + instance = model.APIKeys(key=get_unique_value()) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def cleanup_event(model, session): + instance = model.CleanupEvent() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def cloud_authz(model, session, user, user_authnz_token): + instance = model.CloudAuthz(user.id, 'a', 'b', user_authnz_token.id, 'c') + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def custos_authnz_token(model, session, user): + instance = model.CustosAuthnzToken(user, None, None, None, None, None, None, None) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def data_manager_history_association(model, session): + instance = model.DataManagerHistoryAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def data_manager_job_association(model, session): + instance = model.DataManagerJobAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def dataset(model, session): + instance = model.Dataset() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def dataset_collection(model, session): + instance = model.DatasetCollection(collection_type='a') + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def dataset_collection_element( + model, session, dataset_collection, history_dataset_association): + instance = model.DatasetCollectionElement( + collection=dataset_collection, element=history_dataset_association) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def dataset_hash(model, session): + instance = model.DatasetHash() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def dataset_permission(model, session, dataset): + instance = model.DatasetPermissions('a', dataset) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def dataset_source(model, session): + instance = model.DatasetSource() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def dataset_source_hash(model, session): + instance = model.DatasetSourceHash() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def default_history_permissions(model, session, history, role): + instance = model.DefaultHistoryPermissions(history, 'a', role) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def default_quota_association(model, session, quota): + type_ = model.DefaultQuotaAssociation.types.REGISTERED + instance = model.DefaultQuotaAssociation(type_, quota) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def default_user_permissions(model, session, user, role): + instance = model.DefaultUserPermissions(user, None, role) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def deferred_job(model, session): + instance = model.DeferredJob() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def dynamic_tool(model, session): + instance = model.DynamicTool() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def extended_metadata(model, session): + instance = model.ExtendedMetadata(None) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def extended_metadata_index(model, session, extended_metadata): + instance = model.ExtendedMetadataIndex(extended_metadata, None, None) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def form_definition(model, session, form_definition_current): + instance = model.FormDefinition(name='a', form_definition_current=form_definition_current) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def form_definition_current(model, session): + instance = model.FormDefinitionCurrent() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def form_values(model, session): + instance = model.FormValues() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def galaxy_session(model, session): + instance = model.GalaxySession(session_key=get_unique_value()) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def galaxy_session_history_association(model, session, galaxy_session, history): + instance = model.GalaxySessionToHistoryAssociation(galaxy_session, history) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def genome_index_tool_data(model, session): + instance = model.GenomeIndexToolData() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def group(model, session): + instance = model.Group(name=get_unique_value()) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def group_quota_association(model, session): + instance = model.GroupQuotaAssociation(None, None) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def group_role_association(model, session): + instance = model.GroupRoleAssociation(None, None) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def history(model, session): + instance = model.History() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def history_annotation_association(model, session): + instance = model.HistoryAnnotationAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def history_dataset_annotation_association(model, session): + instance = model.HistoryDatasetAnnotationAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def history_dataset_association(model, session, dataset): + instance = model.HistoryDatasetAssociation(dataset=dataset) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def history_dataset_association_annotation_association(model, session): + instance = model.HistoryDatasetAssociationAnnotationAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def history_dataset_association_rating_association(model, session): + instance = model.HistoryDatasetAssociationRatingAssociation(None, None) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def history_dataset_association_tag_association(model, session): + instance = model.HistoryDatasetAssociationTagAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def history_dataset_collection_annotation_association(model, session): + instance = model.HistoryDatasetCollectionAssociationAnnotationAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def history_dataset_collection_association(model, session): + instance = model.HistoryDatasetCollectionAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def history_dataset_collection_rating_association( + model, + session, + user, + history_dataset_collection_association, +): + instance = model.HistoryDatasetCollectionRatingAssociation( + user, history_dataset_collection_association) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def history_dataset_collection_tag_association(model, session): + instance = model.HistoryDatasetCollectionTagAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def history_rating_association(model, session, user, history): + instance = model.HistoryRatingAssociation(user, history) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def history_tag_association(model, session): + instance = model.HistoryTagAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def history_user_share_association(model, session): + instance = model.HistoryUserShareAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def implicit_collection_jobs(model, session): + instance = model.ImplicitCollectionJobs(populated_state='new') + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def implicit_collection_jobs_job_association(model, session): + instance = model.ImplicitCollectionJobsJobAssociation() + instance.order_index = 1 + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def implicitly_converted_dataset_association(model, session, history_dataset_association): + instance = model.ImplicitlyConvertedDatasetAssociation( + dataset=history_dataset_association, + parent=history_dataset_association, # using the same dataset; should work here. + ) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def implicitly_created_dataset_collection_input( + model, + session, + history_dataset_collection_association +): + instance = model.ImplicitlyCreatedDatasetCollectionInput( + None, history_dataset_collection_association) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def interactive_tool_entry_point(model, session): + instance = model.InteractiveToolEntryPoint() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def job(model, session): + instance = model.Job() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def job_container_association(model, session): + instance = model.JobContainerAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def job_export_history_archive(model, session): + instance = model.JobExportHistoryArchive() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def job_external_output_metadata(model, session, job, history_dataset_association): + instance = model.JobExternalOutputMetadata(job, history_dataset_association) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def job_metric_numeric(model, session): + instance = model.JobMetricNumeric(None, None, None) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def job_metric_text(model, session): + instance = model.JobMetricText(None, None, None) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def job_parameter(model, session): + instance = model.JobParameter(None, None) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def job_state_history(model, session, job): + instance = model.JobStateHistory(job) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def job_to_implicit_output_dataset_collection_association(model, session, dataset_collection): + instance = model.JobToImplicitOutputDatasetCollectionAssociation(None, dataset_collection) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def job_to_input_dataset_association(model, session, history_dataset_association): + instance = model.JobToInputDatasetAssociation(None, history_dataset_association) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def job_to_input_dataset_collection_association( + model, + session, + history_dataset_collection_association +): + instance = model.JobToInputDatasetCollectionAssociation( + None, history_dataset_collection_association) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def job_to_input_dataset_collection_element_association(model, session, dataset_collection_element): + instance = model.JobToInputDatasetCollectionElementAssociation(None, dataset_collection_element) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def job_to_input_library_dataset_association(model, session, library_dataset_dataset_association): + instance = model.JobToInputLibraryDatasetAssociation(None, library_dataset_dataset_association) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def job_to_output_dataset_association(model, session, history_dataset_association): + instance = model.JobToOutputDatasetAssociation(None, history_dataset_association) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def job_to_output_dataset_collection_association( + model, + session, + history_dataset_collection_association +): + instance = model.JobToOutputDatasetCollectionAssociation( + None, history_dataset_collection_association) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def job_to_output_library_dataset_association(model, session, library_dataset_dataset_association): + instance = model.JobToOutputLibraryDatasetAssociation(None, library_dataset_dataset_association) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library(model, session): + instance = model.Library() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library_dataset(model, session): + instance = model.LibraryDataset() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library_dataset_annotation_association(model, session): + instance = model.LibraryDatasetAnnotationAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library_dataset_collection_annotation_association(model, session): + instance = model.LibraryDatasetCollectionAnnotationAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library_dataset_collection_association(model, session): + instance = model.LibraryDatasetCollectionAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library_dataset_collection_rating_association(model, session): + instance = model.LibraryDatasetCollectionRatingAssociation(None, None) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library_dataset_collection_tag_association(model, session): + instance = model.LibraryDatasetCollectionTagAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library_dataset_dataset_association(model, session): + instance = model.LibraryDatasetDatasetAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library_dataset_dataset_association_permission( + model, + session, + library_dataset_dataset_association, + role +): + instance = model.LibraryDatasetDatasetAssociationPermissions( + 'a', library_dataset_dataset_association, role) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library_dataset_dataset_association_tag_association(model, session): + instance = model.LibraryDatasetDatasetAssociationTagAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library_dataset_dataset_info_association( + model, + session, + library_dataset_dataset_association, + form_definition, + form_values +): + instance = model.LibraryDatasetDatasetInfoAssociation( + library_dataset_dataset_association, form_definition, form_values) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library_dataset_permission(model, session, library_dataset, role): + instance = model.LibraryDatasetPermissions('a', library_dataset, role) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library_folder(model, session): + instance = model.LibraryFolder() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library_folder_info_association(model, session, library_folder, form_definition, form_values): + instance = model.LibraryFolderInfoAssociation(library_folder, form_definition, form_values) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library_folder_permission(model, session, library_folder, role): + instance = model.LibraryFolderPermissions('a', library_folder, role) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library_info_association(model, session, library, form_definition, form_values): + instance = model.LibraryInfoAssociation(library, form_definition, form_values) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def library_permission(model, session, library, role): + instance = model.LibraryPermissions('a', library, role) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def metadata_file(model, session): + instance = model.MetadataFile() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def page(model, session, user): + instance = model.Page() + instance.user = user + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def page_annotation_association(model, session): + instance = model.PageAnnotationAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def page_rating_association(model, session): + instance = model.PageRatingAssociation(None, None) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def page_revision(model, session, page): + instance = model.PageRevision() + instance.page = page + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def page_tag_association(model, session): + instance = model.PageTagAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def page_user_share_association(model, session): + instance = model.PageUserShareAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def password_reset_token(model, session, user): + token = get_unique_value() + instance = model.PasswordResetToken(user, token) + where_clause = type(instance).token == token + yield from dbcleanup_wrapper(session, instance, where_clause) + + +@pytest.fixture +def post_job_action(model, session): + instance = model.PostJobAction('a') + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def post_job_action_association(model, session, post_job_action, job): + instance = model.PostJobActionAssociation(post_job_action, job) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def quota(model, session): + instance = model.Quota(get_unique_value(), 'b') + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def role(model, session): + instance = model.Role(name=get_unique_value()) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def stored_workflow(model, session, user): + instance = model.StoredWorkflow() + instance.user = user + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def stored_workflow_annotation_association(model, session): + instance = model.StoredWorkflowAnnotationAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def stored_workflow_rating_association(model, session): + instance = model.StoredWorkflowRatingAssociation(None, None) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def stored_workflow_tag_association(model, session): + instance = model.StoredWorkflowTagAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def stored_workflow_user_share_association(model, session): + instance = model.StoredWorkflowUserShareAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def tag(model, session): + instance = model.Tag() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def task(model, session, job): + instance = model.Task(job, 'a', 'b') + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def task_metric_numeric(model, session): + instance = model. TaskMetricNumeric('a', 'b', 9) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def task_metric_text(model, session): + instance = model. TaskMetricText('a', 'b', 'c') + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def tool_tag_association(model, session): + instance = model.ToolTagAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def transfer_job(model, session): + instance = model.TransferJob() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def user(model, session): + instance = model.User(email=get_unique_value(), password='password') + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def user_address(model, session): + instance = model.UserAddress() + instance.name = 'a' + instance.address = 'b' + instance.city = 'c' + instance.state = 'd' + instance.postal_code = 'e' + instance.country = 'f' + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def user_authnz_token(model, session, user): + instance = model.UserAuthnzToken('a', 'b', 'c', 1, 'd', user) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def user_group_association(model, session): + instance = model.UserGroupAssociation(None, None) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def user_preference(model, session): + instance = model.UserPreference() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def user_quota_association(model, session): + instance = model.UserQuotaAssociation(None, None) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def user_role_association(model, session, user, role): + instance = model.UserRoleAssociation(user, role) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def visualization(model, session, user): + instance = model.Visualization() + instance.user = user + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def visualization_annotation_association(model, session): + instance = model.VisualizationAnnotationAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def visualization_rating_association(model, session, user, visualization): + instance = model.VisualizationRatingAssociation(user, visualization) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def visualization_revision(model, session, visualization): + instance = model.VisualizationRevision(visualization=visualization) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def visualization_tag_association(model, session): + instance = model.VisualizationTagAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def visualization_user_share_association(model, session): + instance = model.VisualizationUserShareAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow(model, session): + instance = model.Workflow() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_invocation(model, session, workflow): + instance = model.WorkflowInvocation() + instance.workflow = workflow + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_invocation_output_dataset_association(model, session): + instance = model.WorkflowInvocationOutputDatasetAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_invocation_output_dataset_collection_association(model, session): + instance = model.WorkflowInvocationOutputDatasetCollectionAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_invocation_output_value(model, session): + instance = model.WorkflowInvocationOutputValue() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_invocation_step(model, session, workflow_invocation, workflow_step): + instance = model.WorkflowInvocationStep() + instance.workflow_invocation = workflow_invocation + instance.workflow_step = workflow_step + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_invocation_step_output_dataset_association(model, session): + instance = model.WorkflowInvocationStepOutputDatasetAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_invocation_step_output_dataset_collection_association(model, session): + instance = model.WorkflowInvocationStepOutputDatasetCollectionAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_output(model, session, workflow_step): + instance = model.WorkflowOutput(workflow_step) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_request_input_parameter(model, session): + instance = model.WorkflowRequestInputParameter() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_request_input_step_parameter(model, session): + instance = model.WorkflowRequestInputStepParameter() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_request_step_state(model, session): + instance = model.WorkflowRequestStepState() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_request_to_input_dataset_association(model, session): + instance = model.WorkflowRequestToInputDatasetAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_request_to_input_dataset_collection_association(model, session): + instance = model.WorkflowRequestToInputDatasetCollectionAssociation() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_step(model, session, workflow): + instance = model.WorkflowStep() + instance.workflow = workflow + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_step_connection(model, session): + instance = model.WorkflowStepConnection() + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_step_input(model, session, workflow_step): + instance = model.WorkflowStepInput(workflow_step) + yield from dbcleanup_wrapper(session, instance) + + +@pytest.fixture +def workflow_step_tag_association(model, session): + instance = model.WorkflowStepTagAssociation() + yield from dbcleanup_wrapper(session, instance) + + +# Fixtures yielding factory functions. +# In some tests we may need more than one instance of the same model. We cannot reuse a model +# fixture, and we cannot pass multiple copies of the same fixture to one test. We have to +# instantiate a new instance of the model inside the test. However, a test should only know +# how to construct the model it is testing, so instead of constructing an object directly, +# a test calls a factory function, passed to it as a fixture. + +@pytest.fixture +def dataset_collection_factory(model): + def make_instance(*args, **kwds): + if 'collection_type' not in kwds: + kwds['collection_type'] = 'a' + return model.DatasetCollection(*args, **kwds) + return make_instance + + +@pytest.fixture +def history_dataset_association_factory(model): + def make_instance(*args, **kwds): + return model.HistoryDatasetAssociation(*args, **kwds) + return make_instance + + +@pytest.fixture +def history_dataset_collection_association_factory(model): + def make_instance(*args, **kwds): + return model.HistoryDatasetCollectionAssociation(*args, **kwds) + return make_instance + + +@pytest.fixture +def history_factory(model): + def make_instance(**kwds): + instance = model.History() + if 'deleted' in kwds: + instance.deleted = kwds['deleted'] + return instance + return make_instance + + +@pytest.fixture +def history_rating_association_factory(model): + def make_instance(*args, **kwds): + return model.HistoryRatingAssociation(*args, **kwds) + return make_instance + + +@pytest.fixture +def implicitly_converted_dataset_association_factory(model, history_dataset_association): + def make_instance(*args, **kwds): + instance = model.ImplicitlyConvertedDatasetAssociation( + dataset=history_dataset_association, + parent=history_dataset_association, # using the same dataset; should work here. + ) + return instance + return make_instance + + +@pytest.fixture +def library_dataset_dataset_association_factory(model): + def make_instance(*args, **kwds): + return model.LibraryDatasetDatasetAssociation(*args, **kwds) + return make_instance + + +@pytest.fixture +def library_folder_factory(model): + def make_instance(*args, **kwds): + return model.LibraryFolder(*args, **kwds) + return make_instance + + +@pytest.fixture +def page_rating_association_factory(model): + def make_instance(*args, **kwds): + return model.PageRatingAssociation(*args, **kwds) + return make_instance + + +@pytest.fixture +def stored_workflow_menu_entry_factory(model): + def make_instance(*args, **kwds): + return model.StoredWorkflowMenuEntry(*args, **kwds) + return make_instance + + +@pytest.fixture +def stored_workflow_rating_association_factory(model): + def make_instance(*args, **kwds): + return model.StoredWorkflowRatingAssociation(*args, **kwds) + return make_instance + + +@pytest.fixture +def stored_workflow_tag_association_factory(model): + def make_instance(*args, **kwds): + return model.StoredWorkflowTagAssociation(*args, **kwds) + return make_instance + + +@pytest.fixture +def visualization_rating_association_factory(model): + def make_instance(*args, **kwds): + return model.VisualizationRatingAssociation(*args, **kwds) + return make_instance + + +@pytest.fixture +def visualization_revision_factory(model, visualization): + def make_instance(*args, **kwds): + if 'visualization' not in kwds: + kwds['visualization'] = visualization + return model.VisualizationRevision(*args, **kwds) + return make_instance + + +@pytest.fixture +def workflow_factory(model): + def make_instance(*args, **kwds): + return model.Workflow(*args, **kwds) + return make_instance + + +@pytest.fixture +def workflow_invocation_factory(model, workflow): + def make_instance(**kwds): + instance = model.WorkflowInvocation() + instance.workflow = kwds.get('workflow', workflow) + return instance + return make_instance + + +@pytest.fixture +def workflow_invocation_to_subworkflow_invocation_association_factory(model): + def make_instance(*args, **kwds): + return model.WorkflowInvocationToSubworkflowInvocationAssociation(*args, **kwds) + return make_instance + + +@pytest.fixture +def workflow_step_connection_factory(model): + def make_instance(*args, **kwds): + return model.WorkflowStepConnection(*args, **kwds) + return make_instance + + +@pytest.fixture +def workflow_step_factory(model, workflow): + def make_instance(*args, **kwds): + instance = model.WorkflowStep() + instance.workflow = kwds.get('workflow', workflow) + instance.subworkflow = kwds.get('subworkflow') + return instance + return make_instance + + +# Test utilities + +def dbcleanup_wrapper(session, obj, where_clause=None): + with dbcleanup(session, obj, where_clause): + yield obj + + +@contextmanager +def dbcleanup(session, obj, where_clause=None): + """ + Use the session to store obj in database; delete from database on exit, bypassing the session. + + If obj does not have an id field, a SQLAlchemy WHERE clause should be provided to construct + a custom select statement. + """ + return_id = where_clause is None + + try: + obj_id = persist(session, obj, return_id) + yield obj_id + finally: + table = obj.__table__ + if where_clause is None: + where_clause = _get_default_where_clause(type(obj), obj_id) + stmt = delete(table).where(where_clause) + session.execute(stmt) + + +def persist(session, obj, return_id=True): + """ + Use the session to store obj in database, then remove obj from session, + so that on a subsequent load from the database we get a clean instance. + """ + session.add(obj) + session.flush() + obj_id = obj.id if return_id else None # save this before obj is expunged + session.expunge(obj) + return obj_id + + +def delete_from_database(session, objects): + """ + Delete each object in objects from database. + May be called at the end of a test if use of a context manager is impractical. + (Assume all objects have the id field as their primary key.) + """ + # Ensure we have a list of objects (check for list explicitly: a model can be iterable) + if not isinstance(objects, list): + objects = [objects] + + for obj in objects: + table = obj.__table__ + stmt = delete(table).where(table.c.id == obj.id) + session.execute(stmt) + + +def get_stored_obj(session, cls, obj_id=None, where_clause=None, unique=False): + # Either obj_id or where_clause must be provided, but not both + assert bool(obj_id) ^ (where_clause is not None) + if where_clause is None: + where_clause = _get_default_where_clause(cls, obj_id) + stmt = select(cls).where(where_clause) + result = session.execute(stmt) + # unique() is required if result contains joint eager loads against collections + # https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/2253 + if unique: + result = result.unique() + return result.scalar_one() + + +def _get_default_where_clause(cls, obj_id): + where_clause = cls.__table__.c.id == obj_id + return where_clause + + +def has_unique_constraint(table, fields): + for constraint in table.constraints: + if isinstance(constraint, UniqueConstraint): + col_names = {c.name for c in constraint.columns} + if set(fields) == col_names: + return True + + +def has_index(table, fields): + for index in table.indexes: + col_names = {c.name for c in index.columns} + if set(fields) == col_names: + return True + + +def get_unique_value(): + """Generate unique values to accommodate unique constraints.""" + return uuid4().hex + + +def are_same_entity_collections(collection1, collection2): + """ + The 2 arguments are collections of instances of models that have an `id` + attribute as their primary key. + Returns `True` if collections are the same size and contain the same + instances. Instance equality is determined by the object's `id` attribute, + not its Python object identifier. + """ + if len(collection1) != len(collection2): + return False + + collection1.sort(key=lambda item: item.id) + collection2.sort(key=lambda item: item.id) + + for item1, item2 in zip(collection1, collection2): + if item1.id != item2.id: + return False + return True + + +def _run_average_rating_test(session, obj, user, obj_rating_association_factory): + # obj has been expunged; to access its deferred properties, + # it needs to be added back to the session. + session.add(obj) + assert obj.average_rating is None # With no ratings, we expect None. + # Create ratings + to_cleanup = [] + for rating in (1, 2, 3, 4, 5): + obj_rating_assoc = obj_rating_association_factory(user, obj, rating) + persist(session, obj_rating_assoc) + to_cleanup.append(obj_rating_assoc) + assert obj.average_rating == 3.0 # Expect average after ratings added. + # Cleanup: remove ratings from database + delete_from_database(session, to_cleanup) diff --git a/test/unit/model/test_model.py b/test/unit/model/test_model.py deleted file mode 100644 index 7ca0b8650c8..00000000000 --- a/test/unit/model/test_model.py +++ /dev/null @@ -1,220 +0,0 @@ -import pytest -from sqlalchemy import ( - delete, - select, - UniqueConstraint, -) - -import galaxy.model.mapping as mapping - - -@pytest.fixture(scope='module') -def model(): - db_uri = 'sqlite:///:memory:' - return mapping.init('/tmp', db_uri, create_tables=True) - - -@pytest.fixture -def session(model): - Session = model.session - yield Session() - Session.remove() # Ensures we get a new session for each test - - -def test_Group_table(model): - tbl = model.Group.__table__ - assert tbl.name == 'galaxy_group' - - -def test_Group(model, session): - cls = model.Group - name = 'a' - obj = cls(name) - persist(session, obj) - - stmt = select(cls) - stored_obj = session.execute(stmt).scalar_one() - assert stored_obj.id - assert stored_obj.create_time - assert stored_obj.update_time - assert stored_obj.name == name - assert stored_obj.deleted is False - - cleanup(session, cls) - - -def test_Quota_table(model): - tbl = model.Quota.__table__ - assert tbl.name == 'quota' - - -def test_Quota(model, session): - cls = model.Quota - name, description = 'a', 'b' - obj = cls(name, description) - persist(session, obj) - - stmt = select(cls) - stored_obj = session.execute(stmt).scalar_one() - assert stored_obj.id - assert stored_obj.create_time - assert stored_obj.update_time - assert stored_obj.name == name - assert stored_obj.description == description - assert stored_obj.bytes == 0 - assert stored_obj.operation == '=' - assert stored_obj.deleted is False - - cleanup(session, cls) - - -def test_Role_table(model): - tbl = model.Role.__table__ - assert tbl.name == 'role' - - -def test_Role(model, session): - cls = model.Role - name, description = 'a', 'b' - obj = cls(name, description) - persist(session, obj) - - stmt = select(cls) - stored_obj = session.execute(stmt).scalar_one() - assert stored_obj.id - assert stored_obj.create_time - assert stored_obj.update_time - assert stored_obj.name == name - assert stored_obj.description == description - assert stored_obj.type == model.Role.types.SYSTEM - assert stored_obj.deleted is False - - cleanup(session, cls) - - -def test_WorkerProcess_table(model): - tbl = model.WorkerProcess.__table__ - assert tbl.name == 'worker_process' - assert has_unique_constraint(tbl, ('server_name', 'hostname')) - - -def test_WorkerProcess(model, session): - cls = model.WorkerProcess - server_name, hostname = 'a', 'b' - obj = cls(server_name, hostname) - persist(session, obj) - - stmt = select(cls) - stored_obj = session.execute(stmt).scalar_one() - assert stored_obj.id - assert stored_obj.server_name == server_name - assert stored_obj.hostname == hostname - assert stored_obj.pid is None - assert stored_obj.update_time - - cleanup(session, cls) - - -def test_PSAAssociation_table(model): - tbl = model.PSAAssociation.__table__ - assert tbl.name == 'psa_association' - - -def test_PSAAssociation(model, session): - cls = model.PSAAssociation - server_url, handle, secret, issued, lifetime, assoc_type = 'a', 'b', 'c', 1, 2, 'd' - obj = cls(server_url, handle, secret, issued, lifetime, assoc_type) - persist(session, obj) - - stmt = select(cls) - stored_obj = session.execute(stmt).scalar_one() - assert stored_obj.id - assert stored_obj.server_url == server_url - assert stored_obj.handle == handle - assert stored_obj.secret == secret - assert stored_obj.issued == issued - assert stored_obj.lifetime == lifetime - assert stored_obj.assoc_type == assoc_type - - cleanup(session, cls) - - -def test_PSACode_table(model): - tbl = model.PSACode.__table__ - assert tbl.name == 'psa_code' - assert has_unique_constraint(tbl, ('code', 'email')) - - -def test_PSACode(model, session): - cls = model.PSACode - email, code = 'a', 'b' - obj = cls(email, code) - persist(session, obj) - - stmt = select(cls) - stored_obj = session.execute(stmt).scalar_one() - assert stored_obj.id - assert stored_obj.email == email - assert stored_obj.code == code - - cleanup(session, cls) - - -def test_PSANonce_table(model): - tbl = model.PSANonce.__table__ - assert tbl.name == 'psa_nonce' - - -def test_PSANonce(model, session): - cls = model.PSANonce - server_url, timestamp, salt = 'a', 1, 'b' - obj = cls(server_url, timestamp, salt) - persist(session, obj) - - stmt = select(cls) - stored_obj = session.execute(stmt).scalar_one() - assert stored_obj.id - assert stored_obj.server_url - assert stored_obj.timestamp == timestamp - assert stored_obj.salt == salt - - cleanup(session, cls) - - -def test_PSAPartial_table(model): - tbl = model.PSAPartial.__table__ - assert tbl.name == 'psa_partial' - - -def test_PSAPartial(model, session): - cls = model.PSAPartial - token, data, next_step, backend = 'a', 'b', 1, 'c' - obj = cls(token, data, next_step, backend) - persist(session, obj) - - stmt = select(cls) - stored_obj = session.execute(stmt).scalar_one() - assert stored_obj.id - assert stored_obj.token == token - assert stored_obj.data == data - assert stored_obj.next_step == next_step - assert stored_obj.backend == backend - - cleanup(session, cls) - - -def persist(session, obj): - session.add(obj) - session.flush() - - -def cleanup(session, cls): - session.execute(delete(cls)) - - -def has_unique_constraint(table, fields): - for constraint in table.constraints: - if isinstance(constraint, UniqueConstraint): - col_names = {c.name for c in constraint.columns} - if set(fields) == col_names: - return True diff --git a/test/unit/model/test_test_mapping.py b/test/unit/model/test_test_mapping.py new file mode 100644 index 00000000000..14dc653b017 --- /dev/null +++ b/test/unit/model/test_test_mapping.py @@ -0,0 +1,230 @@ +""" +This module contains tests for the utility functions in the test_mapping module. +""" + +from contextlib import contextmanager + +import pytest +from sqlalchemy import ( + Column, + create_engine, + Index, + Integer, + select, + UniqueConstraint +) +from sqlalchemy.exc import NoResultFound +from sqlalchemy.orm import registry, Session + +from . test_mapping import ( + are_same_entity_collections, + dbcleanup, + dbcleanup_wrapper, + delete_from_database, + get_stored_obj, + has_index, + has_unique_constraint, + persist, +) + + +def test_persist(session): + """ + Verify item is stored in database. + We call persist() with default arg value: `return_id=True`. Passing `False` results + in the same functionality except the return value of the funtion is `None`. + """ + instance = Foo() + instance_id = persist(session, instance) # store instance in database + assert instance_id == 1 # id was assigned + assert instance not in session # instance was expunged from session + + stored_instance = _get_stored_instance_by_id(session, Foo, instance_id) + assert stored_instance.id == instance.id # instance can be retrieved by id + assert stored_instance is not instance # retrieved instance is not the same object + + +def test_get_stored_obj_must_have_obj_id_xor_where_clause(): + """ + Verify that function must be called with either obj_id or where_clause, but not both. + """ + with pytest.raises(AssertionError): + get_stored_obj(None, None, obj_id=1, where_clause='a') + with pytest.raises(AssertionError): + get_stored_obj(None, None, obj_id=None, where_clause=None) + + +def test_get_stored_obj_by_id(session): + """Verify item is retrieved from database by id.""" + instance = Foo() + id = persist(session, instance) + + stored_instance = get_stored_obj(session, Foo, id) + assert stored_instance.id == instance.id + + +def test_get_stored_obj_by_where_clause(session): + """Verify item is retrieved from database by a custom WHERE clause.""" + instance1 = Foo() + instance2 = Foo() + id1 = persist(session, instance1) + id2 = persist(session, instance2) + + where_clause = Foo.__table__.c.id == id1 + stored_instance = get_stored_obj(session, Foo, where_clause=where_clause) + assert stored_instance.id == instance1.id + + where_clause = Foo.__table__.c.id == id2 + stored_instance = get_stored_obj(session, Foo, where_clause=where_clause) + assert stored_instance.id == instance2.id + + +def test_delete_from_database_one_item(session): + """Verify item is deleted from database.""" + instance = Foo() + id = persist(session, instance) # store instance in database + + stored_instance = _get_stored_instance_by_id(session, Foo, id) + assert stored_instance is not None # instance is present in database + + delete_from_database(session, instance) # delete instance from database + + with pytest.raises(NoResultFound): # instance no longer present in database + stored_instance = _get_stored_instance_by_id(session, Foo, id) + + +def test_delete_from_database_multiple_items(session): + """Verify multiple items are deleted from database.""" + instance1 = Foo() + instance2 = Foo() + id1 = persist(session, instance1) + id2 = persist(session, instance2) + + delete_from_database(session, [instance1, instance2]) + + with pytest.raises(NoResultFound): + _get_stored_instance_by_id(session, Foo, id1) + with pytest.raises(NoResultFound): + _get_stored_instance_by_id(session, Foo, id2) + + +def test_dbcleanup_by_id(session): + instance = Foo() + with dbcleanup(session, instance) as instance_id: + stored_instance = _get_stored_instance_by_id(session, Foo, instance_id) + assert stored_instance # has been stored in the database + + with pytest.raises(NoResultFound): # has been deleted from the database + _get_stored_instance_by_id(session, Foo, instance_id) + + +def test_dbcleanup_by_where_clause(session): + instance = Foo() + where_clause = Foo.__table__.c.id == 1 + + with dbcleanup(session, instance, where_clause): + stored_instance = _get_stored_instance_by_id(session, Foo, where_clause) + assert stored_instance # has been stored in the database + + with pytest.raises(NoResultFound): # has been deleted from the database + _get_stored_instance_by_id(session, Foo, stored_instance.id) + + +def test_dbcleanup_wrapper(session): + """ + Verify dbcleanup_wrapper has same effect as dbcleanup context manager, + and yields the object instance. + """ + @contextmanager # we need a context manager to similate scope + def managed(a, b): + yield from dbcleanup_wrapper(a, b) + + instance = Foo() + # this will call dbcleanup_wrapper that stores instance in the database and returns a reference to it + with managed(session, instance) as instance2: + assert instance2 is instance # instance2 should be a reference to instance + stored_instance = _get_stored_instance_by_id(session, Foo, instance.id) + assert stored_instance # has been stored in the database + + # on exit we expect the entity to be deleted from the database + with pytest.raises(NoResultFound): # has been deleted from the database + _get_stored_instance_by_id(session, Foo, instance.id) + + +def test_has_index(session): + assert has_index(Bar.__table__, ('field1',)) + assert not has_index(Foo.__table__, ('field1',)) + + +def test_has_unique_constraint(session): + assert has_unique_constraint(Bar.__table__, ('field2',)) + assert not has_unique_constraint(Foo.__table__, ('field1',)) + + +def test_are_same_entity_collections(session): + foo1 = Foo() + foo2 = Foo() + foo3 = Foo() + persist(session, foo1) + persist(session, foo2) + persist(session, foo3) + + stored_foo1 = _get_stored_instance_by_id(session, Foo, foo1.id) + stored_foo2 = _get_stored_instance_by_id(session, Foo, foo2.id) + stored_foo3 = _get_stored_instance_by_id(session, Foo, foo3.id) + + expected = [foo1, foo2] + + assert are_same_entity_collections([stored_foo1, stored_foo2], expected) + assert are_same_entity_collections([stored_foo2, stored_foo1], expected) + assert not are_same_entity_collections([stored_foo1, stored_foo3], expected) + assert not are_same_entity_collections([stored_foo1, stored_foo1, stored_foo2], expected) + + +# Test utilities + +mapper_registry = registry() + + +@mapper_registry.mapped +class Foo: + __tablename__ = 'foo' + id = Column(Integer, primary_key=True) + field1 = Column(Integer) + + +@mapper_registry.mapped +class Bar: + __tablename__ = 'bar' + id = Column(Integer, primary_key=True) + field1 = Column(Integer) + field2 = Column(Integer) + __table_args__ = ( + Index('ix', 'field1'), + UniqueConstraint('field2'), + ) + + +@pytest.fixture(scope='module') +def engine(): + """Create connection engine. (Fixture is module-scoped).""" + db_uri = 'sqlite:///:memory:' # We only need sqlite for these tests + return create_engine(db_uri) + + +@pytest.fixture(scope='module') +def init(engine): + """Create database objects. (Fixture is module-scoped).""" + mapper_registry.metadata.create_all(engine) + + +@pytest.fixture +def session(init, engine): + """Provides a basic session object, closed on exit.""" + with Session(engine) as s: + yield s + + +def _get_stored_instance_by_id(session, cls_, id): + statement = select(Foo).where(cls_.__table__.c.id == id) + return session.execute(statement).scalar_one()