Example #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
Example #2
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
Example #3
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))
Example #4
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()
Example #5
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