예제 #1
0
 def test_populates_fields(self):
     field = Field('document:')
     self.assertEqual(field.field_type, 'document')
     self.assertEqual(field.path_parts, None)
     field = Field('metadata:foo.bar')
     self.assertEqual(field.field_type, 'metadata')
     self.assertEqual(field.path_parts, ['foo', 'bar'])
예제 #2
0
 def setup_class(cls):
     from_collection_field = CollectionField(Collection('from', 'path'),
                                             Field('document:'))
     to_collection_field = CollectionField(Collection('to', 'path'),
                                           Field('document:'))
     cls.i = CrossCollectionIndex("name", from_collection_field,
                                  to_collection_field)
예제 #3
0
 def setup_class(cls):
     collection_field = CollectionField(Collection('name', 'path'),
                                        Field('document:'))
     cls.i = SingleCollectionIndex("name", collection_field)
예제 #4
0
 def test_pass(self):
     CollectionField(
         Collection('name', 'path'),
         Field('document:'))
     self.assertEqual(1 + 1, 2)
예제 #5
0
 def test_name(self):
     field = Field('name:')
     self.assertEqual(field.run(self.d), 'Test document')
예제 #6
0
 def test_metadata(self):
     field = Field('metadata:foo.bar')
     self.assertEqual(field.run(self.d), 42)
     field = Field('metadata:foo.baz')
     self.assertEqual(field.run(self.d), None)
예제 #7
0
 def test_document(self):
     field = Field('document:')
     self.assertEqual(field.run(self.d), 'asdf')
예제 #8
0
 def test_marshal(self):
     field = Field('document:')
     self.assertEqual(field.marshal(), 'document:')
예제 #9
0
 def __init__(self, filter_obj):
     """creates a filter object from a dict"""
     self.field = Field(filter_obj['field'])
     self.operator = filter_obj['op']
     self.value = filter_obj['value']
예제 #10
0
 def test_create(self):
     f = Filter({'field': 'd:', 'op': 'eq', 'value': 'asdf'})
     self.assertEqual(f.field, Field('d:'))
     self.assertEqual(f.operator, 'eq')
     self.assertEqual(f.value, 'asdf')
예제 #11
0
    def from_object(cls, config_obj):
        """Parses a configuration object (as generated by loading a yaml
        configuration file) into an internal object used by the database
        """

        # Ensure there's only one key.
        if len(config_obj) != 1:
            raise cls.MalformedConfiguration(
                'config may only contain one root-level key')
        name, config_obj = config_obj.popitem()

        # Ensure that collections and indices keys exist and are lists.
        if 'collections' not in config_obj or 'indices' not in config_obj:
            raise cls.MalformedConfiguration(
                'config must contain `collections` and `indices` keys (even '
                'if they are empty lists)')
        if type(config_obj['collections']) not in [list, tuple]:
            raise cls.MalformedConfiguration(
                '`collections` must be a list (even if it is empty)')
        if type(config_obj['indices']) not in [list, tuple]:
            raise cls.MalformedConfiguration(
                '`indices` must be a list (even if it is empty)')

        # Fetch all collections.
        collections = {}
        for collection in config_obj['collections']:
            cname = collection.get('name', None)
            cpath = collection.get('path', None)

            # Ensure name and path are specified
            if cname is None or cpath is None:
                raise cls.MalformedConfiguration(
                    'collection `name` and `path` are required')
            collections[cname] = Collection(cname, cpath)
        del config_obj['collections']

        # Fetch and parse all indices
        indices = {}
        for index in config_obj['indices']:
            cname = index.get('name', None)
            cfrom = index.get('from', None)
            cto = index.get('to', None)

            # Ensure an index name and a from field are specified.
            if cname is None or cfrom is None:
                raise cls.MalformedConfiguration(
                    'index `name` and `from` fields are required')

            # Ensure that the referenced collection exists
            cfrom_collection = collections.get(cfrom[0], None)
            if cfrom_collection is None:
                raise cls.MalformedConfiguration(
                    'indicies must specify a valid collection by name in the '
                    'from field')
            cfrom_field = Field(cfrom[1])
            cf_from = CollectionField(cfrom_collection, cfrom_field)

            # Build a single or cross collection index depending on the
            # presence of a `to` collection field.
            if cto is None:
                indices[cname] = SingleCollectionIndex(cname, cf_from)
            else:
                cto_collection = collections.get(cto[0], None)
                if cto_collection is None:
                    raise cls.MalformedConfiguration(
                        'indicies must specify a valid collection by name in '
                        'the to field')
                cto_field = Field(cto[1])
                cf_to = CollectionField(cto_collection, cto_field)
                indices[cname] = CrossCollectionIndex(cname, cf_from, cf_to)
        del config_obj['indices']

        # Grab additional configuration values, supplying defaults if needed.
        options = DEFAULT_OPTIONS.copy()
        options.update(config_obj)

        return Configuration(name, collections, indices, options)