Beispiel #1
0
def delete_code(code):
    """
    Delete a code from the DB.
    Check before that there are no output nodes.

    NOTE! Not thread safe... Do not use with many users accessing the DB
    at the same time.

    Implemented as a function on purpose, otherwise complicated logic would be
    needed to set the internal state of the object after calling
    computer.delete().
    """
    if not isinstance(code, Code):
        raise TypeError("code must be an instance of "
                        "aiida.orm.computer.Code")

    existing_outputs = code.get_outputs()

    if len(existing_outputs) != 0:
        raise InvalidOperation(
            "Unable to delete the requested code because it "
            "has {} output links".format(len(existing_outputs)))
    else:
        repo_folder = code._repository_folder
        from aiida.backends.sqlalchemy import session
        session.begin(subtransactions=True)
        try:
            code.dbnode.delete()
            repo_folder.erase()
            session.commit()
        except:
            session.rollback()
            raise
Beispiel #2
0
    def add_comment(self, content, user=None):
        from aiida.backends.sqlalchemy import session
        if self._to_be_stored:
            raise ModificationNotAllowed("Comments can be added only after "
                                         "storing the node")

        comment = DbComment(dbnode=self._dbnode, user=user, content=content)
        session.add(comment)
        session.commit()
Beispiel #3
0
 def _replace_dblink_from(self, src, label, link_type):
     from aiida.backends.sqlalchemy import session
     try:
         self._add_dblink_from(src, label)
     except UniquenessError:
         # I have to replace the link; I do it within a transaction
         try:
             self._remove_dblink_from(label)
             self._add_dblink_from(src, label, link_type)
             session.commit()
         except:
             session.rollback()
             raise
Beispiel #4
0
 def _do_create_link(self, src, label, link_type):
     from aiida.backends.sqlalchemy import session
     try:
         link = DbLink(input_id=src.dbnode.id,
                       output_id=self.dbnode.id,
                       label=label,
                       type=link_type.value)
         session.add(link)
         session.commit()
     except SQLAlchemyError as e:
         session.rollback()
         raise UniquenessError("There is already a link with the same "
                               "name (raw message was {})"
                               "".format(e))
Beispiel #5
0
    def release(self, owner="None"):
        if self.dblock == None:
            raise InternalError("No dblock present.")

        try:
            if (self.dblock.owner == owner):
                session.delete(self.dblock)
                session.commit()
                self.dblock = None
            else:
                raise ModificationNotAllowed("Only the owner can release the lock.")

        except:
            raise InternalError("Cannot release a lock, Reload the Daemon to fix the problem.")
Beispiel #6
0
    def _store_cached_input_links(self, with_transaction=True):
        """
        Store all input links that are in the local cache, transferring them
        to the DB.

        :note: This can be called only if all parents are already stored.

        :note: Links are stored only after the input nodes are stored. Moreover,
            link storage is done in a transaction, and if one of the links
            cannot be stored, an exception is raised and *all* links will remain
            in the cache.

        :note: This function can be called only after the node is stored.
           After that, it can be called multiple times, and nothing will be
           executed if no links are still in the cache.

        :parameter with_transaction: if False, no transaction is used. This
          is meant to be used ONLY if the outer calling function has already
          a transaction open!
        """

        if self._to_be_stored:
            raise ModificationNotAllowed(
                "Node with pk= {} is not stored yet".format(self.id))

        # This raises if there is an unstored node.
        self._check_are_parents_stored()
        # I have to store only those links where the source is already
        # stored
        links_to_store = list(self._inputlinks_cache.keys())

        for label in links_to_store:
            src, link_type = self._inputlinks_cache[label]
            self._add_dblink_from(src, label, link_type)
        # If everything went smoothly, clear the entries from the cache.
        # I do it here because I delete them all at once if no error
        # occurred; otherwise, links will not be stored and I
        # should not delete them from the cache (but then an exception
        # would have been raised, and the following lines are not executed)
        self._inputlinks_cache.clear()

        from aiida.backends.sqlalchemy import session
        if with_transaction:
            try:
                session.commit()
            except SQLAlchemyError as e:
                session.rollback()
Beispiel #7
0
    def add_nodes(self, nodes):
        if not self.is_stored:
            raise ModificationNotAllowed("Cannot add nodes to a group before "
                                         "storing")
        from aiida.orm.implementation.sqlalchemy.node import Node
        from aiida.backends.sqlalchemy import session

        # First convert to a list
        if isinstance(nodes, (Node, DbNode)):
            nodes = [nodes]

        if isinstance(
                nodes,
                basestring) or not isinstance(nodes, collections.Iterable):
            raise TypeError("Invalid type passed as the 'nodes' parameter to "
                            "add_nodes, can only be a Node, DbNode, or a list "
                            "of such objects, it is instead {}".format(
                                str(type(nodes))))

        list_nodes = []
        for node in nodes:
            if not isinstance(node, (Node, DbNode)):
                raise TypeError("Invalid type of one of the elements passed "
                                "to add_nodes, it should be either a Node or "
                                "a DbNode, it is instead {}".format(
                                    str(type(node))))

            if node.id is None:
                raise ValueError("At least one of the provided nodes is "
                                 "unstored, stopping...")
            if isinstance(node, Node):
                to_add = node.dbnode
            else:
                to_add = node

            if to_add not in self._dbgroup.dbnodes:
                # ~ list_nodes.append(to_add)
                self._dbgroup.dbnodes.append(to_add)
        session.commit()
Beispiel #8
0
    def store_all(self, with_transaction=True):
        """
        Store the node, together with all input links, if cached, and also the
        linked nodes, if they were not stored yet.

        :parameter with_transaction: if False, no transaction is used. This
          is meant to be used ONLY if the outer calling function has already
          a transaction open!
        """

        if not self._to_be_stored:
            raise ModificationNotAllowed(
                "Node with pk= {} was already stored".format(self.id))

        # For each parent, check that all its inputs are stored
        for link in self._inputlinks_cache:
            try:
                parent_node = self._inputlinks_cache[link][0]
                parent_node._check_are_parents_stored()
            except ModificationNotAllowed:
                raise ModificationNotAllowed(
                    "Parent node (UUID={}) has "
                    "unstored parents, cannot proceed (only direct parents "
                    "can be unstored and will be stored by store_all, not "
                    "grandparents or other ancestors".format(parent_node.uuid))

        self._store_input_nodes()
        self.store(with_transaction=False)
        self._store_cached_input_links(with_transaction=False)
        from aiida.backends.sqlalchemy import session

        if with_transaction:
            try:
                session.commit()
            except SQLAlchemyError as e:
                session.rollback()

        return self
Beispiel #9
0
 def _remove_dblink_from(self, label):
     from aiida.backends.sqlalchemy import session
     link = self.dbnode.outputs.filter_by(label=label).first()
     session.delete(link)
     session.commit()