Ejemplo n.º 1
0
    def test_create_finds_existing_entity_in_db(self):
        Entity.c.save({'name': 'existing', 'company_id': 1000})
        existing = Entity.find_one({'company_id': 1000})

        loader = self._make_loader()
        loader.create_entity(name=u'Test', company_id=1000,
                             match_keys=('company_id',))
        cached = loader.entity_cache[('company_id',)][(1000,)]

        h.assert_equal(existing['_id'], cached['_id'])
        h.assert_equal(Entity.find({'company_id': 1000}).count(), 1)
Ejemplo n.º 2
0
 def test_loader_checks_duplicate_entities(self):
     entity = Entity(name=u'Test Entity')
     entity.save()
     duplicate = Entity(name=u'Test Entity')
     duplicate.save()
     h.assert_raises(ValueError, self._make_loader,
                       unique_keys=['name'])
Ejemplo n.º 3
0
 def _make_one(self, name, **kwargs):
     from openspending.model import Entity
     entity = kwargs
     entity['name'] = name
     new_id = Entity.c.save(entity, manipulate=True)
     return Entity.find_one({'_id': new_id})
Ejemplo n.º 4
0
 def test_create_entry_with_different_match_keys(self):
     loader = self._make_loader()
     loader.create_entity(name=u'Test', company_id=1000,
                          match_keys=('company_id',))
     h.assert_equal(len(loader.entity_cache[('company_id',)]), 1)
     h.assert_true(Entity.find_one({'company_id': 1000}) is not None)
Ejemplo n.º 5
0
    def create_entity(self, name=None, label=u'', description=u'',
                      _cache=None, match_keys=('name', ), **entity):
        '''\
        Create or update an :class:`openspending.model.Entity` object in the
        database when this is called for the entity the first time.
        An existing entity is looked up with the entitie's data for
        *match_keys*. By default we look up by name, but other data
        like company or tax ids may be more appropriate.

        The entry will only be created/updated if it is not in the
        ``_cache``.

        ``name``
            Name of the entity.
        ``label, description``
            label an description of the entity (unicodes)
        ``match_keys``
            The keys with which we try to find an existing entity
            in the database. default: ('name',). type: ``list`` or
            ``tuple``.
        ``**entity``
            Keyword arguments that are saved in the entity.
        ``_cache``
          Use the given ``dict`` like object for caching.
          Normally not used by callers. It can be used to force an
          update of an entity that was created/updated by an earlier
          call. With ``None`` (default), the ``Loader`` uses internal
          caching.

        Returns: The created ``Entity`` object.

        Raises:

        :exc:`AssertionError`
            If the name ends with a suffix used for REST, e.g. .json.
            If match_keys is not list or tuple.
        :exc:`KeyError`
            If a given match_key is not present in the entity.
        '''
        # assertions
        check_rest_suffix(name)
        if not isinstance(match_keys, (list, tuple)):
            raise AssertionError('match_keys has to be list or tuple')

        entity.update({'name': name,
                       'label': label,
                       'description': description})

        # prepare a cache for the match_keys combination
        if _cache is None:
            _cache = self.entity_cache
        cache = _cache.setdefault(match_keys, {})
        cache_key = tuple([entity[key] for key in match_keys])

        if not cache_key in cache:
            query = {}
            for key in match_keys:
                query[key] = entity[key]
            entity_obj = Entity.find_one(query)

            if entity_obj is None:
                operation = CREATE
            else:
                operation = UPDATE

            Entity.c.update(query, {"$set": entity}, upsert=True)
            new_entity = Entity.find_one(query)
            self._add_changeobj(Entity.c.name, new_entity['_id'],
                                new_entity, operation)
            cache[cache_key] = new_entity

        return cache[cache_key]