# Path: invenio_records/dictutils.py
# def dict_lookup(source, lookup_key, parent=False):
#     """Make a lookup into a dict based on a dot notation.
# 
#     Examples of the supported dot notation:
# 
#     - ``'a'`` - Equivalent to ``source['a']``
#     - ``'a.b'`` - Equivalent to ``source['a']['b']``
#     - ``'a.b.0'`` - Equivalent to ``source['a']['b'][0]`` (for lists)
# 
#     List notation is also supported:
# 
#     - `['a']``
#     - ``['a','b']``
#     - ``['a','b', 0]``
# 
#     :param source: The dictionary object to perform the lookup in.
#     :param parent: If parent argument is True, returns the parent node of
#                    matched object.
#     :param lookup_key: A string using dot notation, or a list of keys.
#     """
#     # Copied from dictdiffer (CERN contributed part) and slightly modified.
#     keys = parse_lookup_key(lookup_key)
# 
#     if parent:
#         keys = keys[:-1]
# 
#     # Lookup the key
#     value = source
#     for key in keys:
#         try:
#             if isinstance(value, list):
#                 key = int(key)
#             value = value[key]
#         except (TypeError, IndexError, ValueError) as exc:
#             raise KeyError(lookup_key) from exc
#     return value
# 
# def dict_set(source, key, value):
#     """Set a value into a dict via a dot-notated key.
# 
#     This also creates missing key "paths".
# 
#     Examples of the supported dot notation:
# 
#     - ``'a'`` - Equivalent to ``source['a'] = value``
#     - ``'a.b'`` - Equivalent to ``source['a']['b'] = value``
#     - ``'a.b.0'`` - Equivalent to ``source['a']['b'][0] = value`` (for lists)
# 
#     List notation is also supported:
# 
#     - `['a']``
#     - ``['a','b']``
#     - ``['a','b', 0]``
# 
#     :param source: The dictionary object to set the value in.
#     :param key: A string using dot notation, or a list of keys.
#     :param value: The value to be set.
#     """
#     keys = parse_lookup_key(key)
#     parent = source
#     for key in keys[:-1]:
#         if isinstance(key, int):
#             parent = parent[key]
#         else:
#             parent = parent.setdefault(key, {})
#     parent[keys[-1]] = value
# 
# Path: invenio_records/dumpers/elasticsearch.py
# class ElasticsearchDumperExt:
#     """Interface for Elasticsearch dumper extensions."""
# 
#     def dump(self, record, data):
#         """Dump the data."""
# 
#     def load(self, data, record_cls):
#         """Load the data.
# 
#         Reverse the changes made by the dump method.
#         """


from ..dictutils import dict_lookup, dict_set
from .elasticsearch import ElasticsearchDumperExt
# Copyright (C) 2020 CERN.
#
# Invenio is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.

"""Relations dumper.

Dumper used to dump/load relations to/from an ElasticSearch body.
"""



class RelationDumperExt(ElasticsearchDumperExt):
    """Dumper for a relations field."""

    def __init__(self, key, fields=None):
        """Initialize the dumper."""
        self.key = key
        self.fields = fields

    def dump(self, record, data):
        """Dump relations."""
        relations = getattr(record, self.key)
        relations.dereference(fields=self.fields)
        relation_fields = self.fields or relations
        for rel_field_name in relation_fields:
            rel_field = getattr(relations, rel_field_name)
            try:
                dict_set(
                    data, rel_field.key,

# Path: invenio_records/dictutils.py
# def dict_lookup(source, lookup_key, parent=False):
#     """Make a lookup into a dict based on a dot notation.
# 
#     Examples of the supported dot notation:
# 
#     - ``'a'`` - Equivalent to ``source['a']``
#     - ``'a.b'`` - Equivalent to ``source['a']['b']``
#     - ``'a.b.0'`` - Equivalent to ``source['a']['b'][0]`` (for lists)
# 
#     List notation is also supported:
# 
#     - `['a']``
#     - ``['a','b']``
#     - ``['a','b', 0]``
# 
#     :param source: The dictionary object to perform the lookup in.
#     :param parent: If parent argument is True, returns the parent node of
#                    matched object.
#     :param lookup_key: A string using dot notation, or a list of keys.
#     """
#     # Copied from dictdiffer (CERN contributed part) and slightly modified.
#     keys = parse_lookup_key(lookup_key)
# 
#     if parent:
#         keys = keys[:-1]
# 
#     # Lookup the key
#     value = source
#     for key in keys:
#         try:
#             if isinstance(value, list):
#                 key = int(key)
#             value = value[key]
#         except (TypeError, IndexError, ValueError) as exc:
#             raise KeyError(lookup_key) from exc
#     return value
# 
# def dict_set(source, key, value):
#     """Set a value into a dict via a dot-notated key.
# 
#     This also creates missing key "paths".
# 
#     Examples of the supported dot notation:
# 
#     - ``'a'`` - Equivalent to ``source['a'] = value``
#     - ``'a.b'`` - Equivalent to ``source['a']['b'] = value``
#     - ``'a.b.0'`` - Equivalent to ``source['a']['b'][0] = value`` (for lists)
# 
#     List notation is also supported:
# 
#     - `['a']``
#     - ``['a','b']``
#     - ``['a','b', 0]``
# 
#     :param source: The dictionary object to set the value in.
#     :param key: A string using dot notation, or a list of keys.
#     :param value: The value to be set.
#     """
#     keys = parse_lookup_key(key)
#     parent = source
#     for key in keys[:-1]:
#         if isinstance(key, int):
#             parent = parent[key]
#         else:
#             parent = parent.setdefault(key, {})
#     parent[keys[-1]] = value
# 
# Path: invenio_records/dumpers/elasticsearch.py
# class ElasticsearchDumperExt:
#     """Interface for Elasticsearch dumper extensions."""
# 
#     def dump(self, record, data):
#         """Dump the data."""
# 
#     def load(self, data, record_cls):
#         """Load the data.
# 
#         Reverse the changes made by the dump method.
#         """


# Path: invenio_records/dumpers/relations.py
from ..dictutils import dict_lookup, dict_set
from .elasticsearch import ElasticsearchDumperExt

# Copyright (C) 2020 CERN.
#
# Invenio is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.

"""Relations dumper.

Dumper used to dump/load relations to/from an ElasticSearch body.
"""



class RelationDumperExt(ElasticsearchDumperExt):
    """Dumper for a relations field."""

    def __init__(self, key, fields=None):
        """Initialize the dumper."""
        self.key = key
        self.fields = fields

    def dump(self, record, data):
        """Dump relations."""
        relations = getattr(record, self.key)
        relations.dereference(fields=self.fields)
        relation_fields = self.fields or relations
        for rel_field_name in relation_fields:
            rel_field = getattr(relations, rel_field_name)
            try:
                dict_set(
                    data, rel_field.key,

                    dict_lookup(record, rel_field.key)