def add(self, id, obj, criteria={}, force=False, _check_id=True):
        """
        Add a :class:`Component <cqparts.Component>` instance to the database.

        :param id: unique id of entry, can be anything
        :type id: :class:`str`
        :param obj: component to be serialized, then added to the catalogue
        :type obj: :class:`Component <cqparts.Component>`
        :param criteria: arbitrary search criteria for the entry
        :type criteria: :class:`dict`
        :param force: if ``True``, entry is forcefully overwritten if it already
                      exists. Otherwise an exception is raised
        :type force: :class:`bool`
        :param _check_id: if ``False``, duplicate ``id`` is not tested
        :type _check_id: :class:`bool`

        :raises TypeError: on parameter issues
        :raises ValueError: if a duplicate db entry is detected (and ``force``
                            is not set)

        :return: index of new entry
        :rtype: :class:`int`
        """
        # Verify component
        if not isinstance(obj, Component):
            raise TypeError("can only add(%r), component is a %r" % (
                Component, type(obj)
            ))

        # Serialize object
        obj_data = obj.serialize()

        # Add to database
        q = tinydb.Query()
        if (force or _check_id) and self.items.count(q.id == id):
            if force:
                self.items.remove(q.id == id)
            else:
                raise ValueError("entry with id '%s' already exists" % (id))

        index = self.items.insert({
            'id': id,  # must be unique
            'criteria': criteria,
            'obj': obj_data,
        })

        return index