예제 #1
0
파일: message.py 프로젝트: Alpus/Eth
def _gen_find_command(coll, spec, projection, skip, limit, batch_size,
                      options, read_concern=DEFAULT_READ_CONCERN):
    """Generate a find command document."""
    cmd = SON([('find', coll)])
    if '$query' in spec:
        cmd.update([(_MODIFIERS[key], val) if key in _MODIFIERS else (key, val)
                    for key, val in spec.items()])
        if '$explain' in cmd:
            cmd.pop('$explain')
        if '$readPreference' in cmd:
            cmd.pop('$readPreference')
    else:
        cmd['filter'] = spec

    if projection:
        cmd['projection'] = projection
    if skip:
        cmd['skip'] = skip
    if limit:
        cmd['limit'] = abs(limit)
        if limit < 0:
            cmd['singleBatch'] = True
    if batch_size:
        cmd['batchSize'] = batch_size
    if read_concern.level:
        cmd['readConcern'] = read_concern.document

    if options:
        cmd.update([(opt, True)
                    for opt, val in _OPTIONS.items()
                    if options & val])
    return cmd
예제 #2
0
def simplify(case):  # TODO this is a hack
    if isinstance(case, SON) and "$ref" not in case:
        simplified = SON(case)  # make a copy!
        if random.choice([True, False]):
            # delete
            if not len(simplified.keys()):
                return (False, case)
            del simplified[random.choice(simplified.keys())]
            return (True, simplified)
        else:
            # simplify a value
            if not len(simplified.items()):
                return (False, case)
            (key, value) = random.choice(simplified.items())
            (success, value) = simplify(value)
            simplified[key] = value
            return (success, success and simplified or case)
    if isinstance(case, list):
        simplified = list(case)
        if random.choice([True, False]):
            # delete
            if not len(simplified):
                return (False, case)
            simplified.pop(random.randrange(len(simplified)))
            return (True, simplified)
        else:
            # simplify an item
            if not len(simplified):
                return (False, case)
            index = random.randrange(len(simplified))
            (success, value) = simplify(simplified[index])
            simplified[index] = value
            return (success, success and simplified or case)
    return (False, case)
예제 #3
0
def _gen_find_command(coll, spec, projection, skip, limit, batch_size, options,
                      read_concern, collation=None):
    """Generate a find command document."""
    cmd = SON([('find', coll)])
    if '$query' in spec:
        cmd.update([(_MODIFIERS[key], val) if key in _MODIFIERS else (key, val)
                    for key, val in spec.items()])
        if '$explain' in cmd:
            cmd.pop('$explain')
        if '$readPreference' in cmd:
            cmd.pop('$readPreference')
    else:
        cmd['filter'] = spec

    if projection:
        cmd['projection'] = projection
    if skip:
        cmd['skip'] = skip
    if limit:
        cmd['limit'] = abs(limit)
        if limit < 0:
            cmd['singleBatch'] = True
    if batch_size:
        cmd['batchSize'] = batch_size
    if read_concern.level:
        cmd['readConcern'] = read_concern.document
    if collation:
        cmd['collation'] = collation
    if options:
        cmd.update([(opt, True)
                    for opt, val in _OPTIONS.items()
                    if options & val])
    return cmd
예제 #4
0
def _gen_find_command(coll, spec, projection, skip, limit, batch_size, options, read_concern=DEFAULT_READ_CONCERN):
    """Generate a find command document."""
    cmd = SON([("find", coll)])
    if "$query" in spec:
        cmd.update([(_MODIFIERS[key], val) if key in _MODIFIERS else (key, val) for key, val in spec.items()])
        if "$explain" in cmd:
            cmd.pop("$explain")
        if "$readPreference" in cmd:
            cmd.pop("$readPreference")
    else:
        cmd["filter"] = spec

    if projection:
        cmd["projection"] = projection
    if skip:
        cmd["skip"] = skip
    if limit:
        cmd["limit"] = abs(limit)
        if limit < 0:
            cmd["singleBatch"] = True
    if batch_size:
        cmd["batchSize"] = batch_size
    if read_concern.level:
        cmd["readConcern"] = read_concern.document

    if options:
        cmd.update([(opt, True) for opt, val in _OPTIONS.items() if options & val])
    return cmd
예제 #5
0
    def to_mongo(self, use_db_field=True, fields=None):
        """
        Return as SON data ready for use with MongoDB.
        """
        if not fields:
            fields = []

        data = SON()
        data['_id'] = None
        data['_cls'] = self._class_name

        # only root fields ['test1.a', 'test2'] => ['test1', 'test2']
        root_fields = {f.split('.')[0] for f in fields}

        for field_name in self:
            if root_fields and field_name not in root_fields:
                continue

            value = self._data.get(field_name, None)
            field = self._fields.get(field_name)

            if field is None and self._dynamic:
                field = self._dynamic_fields.get(field_name)

            if value is not None:
                f_inputs = field.to_mongo.__code__.co_varnames
                ex_vars = {}
                if fields and 'fields' in f_inputs:
                    key = '%s.' % field_name
                    embedded_fields = [
                        i.replace(key, '') for i in fields if i.startswith(key)
                    ]

                    ex_vars['fields'] = embedded_fields

                if 'use_db_field' in f_inputs:
                    ex_vars['use_db_field'] = use_db_field

                value = field.to_mongo(value, **ex_vars)

            # Handle self generating fields
            if value is None and field._auto_gen:
                value = field.generate()
                self._data[field_name] = value

            if (value is not None) or (field.null):
                if use_db_field:
                    data[field.db_field] = value
                else:
                    data[field.name] = value

        # Only add _cls if allow_inheritance is True
        if not self._meta.get('allow_inheritance'):
            data.pop('_cls')

        return data
예제 #6
0
    def to_mongo(self, use_db_field=True, fields=None):
        """
        Return as SON data ready for use with MongoDB.
        """
        if not fields:
            fields = []

        data = SON()
        data['_id'] = None
        data['_cls'] = self._class_name

        # only root fields ['test1.a', 'test2'] => ['test1', 'test2']
        root_fields = set([f.split('.')[0] for f in fields])

        for field_name in self:
            if root_fields and field_name not in root_fields:
                continue

            value = self._data.get(field_name, None)
            field = self._fields.get(field_name)

            if field is None and self._dynamic:
                field = self._dynamic_fields.get(field_name)

            if value is not None:
                f_inputs = field.to_mongo.__code__.co_varnames
                ex_vars = {}
                if fields and 'fields' in f_inputs:
                    key = '%s.' % field_name
                    embedded_fields = [
                        i.replace(key, '') for i in fields
                        if i.startswith(key)]

                    ex_vars['fields'] = embedded_fields

                if 'use_db_field' in f_inputs:
                    ex_vars['use_db_field'] = use_db_field

                value = field.to_mongo(value, **ex_vars)

            # Handle self generating fields
            if value is None and field._auto_gen:
                value = field.generate()
                self._data[field_name] = value

            if value is not None:
                if use_db_field:
                    data[field.db_field] = value
                else:
                    data[field.name] = value

        # Only add _cls if allow_inheritance is True
        if not self._meta.get('allow_inheritance'):
            data.pop('_cls')

        return data
예제 #7
0
    def to_son(self, include_empty=True, exclude_fields=None, only_fields=None):
        """
        Return as a SON object.

        The content is identical to the result of 'to_mongo', except that empty
        fields are included and fields use their model names, instead of
        database names (e.g. '_id' -> 'id').

        Optionally, if include_empty is True (as it is by default), empty fields
        are included.

        Optionally, either of 'exclude_fields' or 'only_fields' (but not both)
        may be specified, containing an iterable of field names to explicitly
        include or exclude from the result. The 'id' field is always included.
        """
        if (exclude_fields is not None) and (only_fields is not None):
            raise Exception()

        # TODO: convert reference fields as {'id':.., 'label':..}

        # SON is ordered, so we must build a new one to change keys
        reverse_db_field_map = dict(self._reverse_db_field_map)
        reverse_db_field_map['_id'] = '_id'
        reverse_db_field_map['_cls'] = '_type'
        son = SON( (reverse_db_field_map[mongo_field], value)
                   for (mongo_field, value)
                   in self.to_mongo().iteritems() )

        # TODO: remove compatibility field
        son['id'] = son['_id']

        if include_empty:
            # 'to_mongo' omits empty fields
            for field_name in self:
                son.setdefault(field_name, None)

        if exclude_fields is not None:
            for field in exclude_fields:
                if field not in ['_id', '_type', 'id']:   # TODO: remove compatibility field
                    # use 'pop', in case 'include_empty' is False and the field doesn't exist
                    son.pop(field, None)
        elif only_fields is not None:
            only_fields = set(only_fields)
            # always include '_id' and (optionally) '_type'
            only_fields.add('_id')
            only_fields.add('_type')  # always include 'id'
            only_fields.add('id')  # TODO: remove compatibility field
            for field in son.iterkeys():
                if field not in only_fields:
                    del son[field]

        return son
예제 #8
0
    def _to_mongo(self, role=None):
        data = SON()
        data["_id"] = None
        data['_cls'] = self._class_name

        EmbeddedDocumentField = _import_class("EmbeddedDocumentField")
        GenericEmbeddedDocumentField = _import_class("GenericEmbeddedDocumentField")

        parsed_role, role_filter = self._find_role(role=role)

        for field_name in self:
            value = self._data.get(field_name, None)
            field = self._fields.get(field_name)
            if field is None and self._dynamic:
                field = self._dynamic_fields.get(field_name)

            if parsed_role and role_filter:
                if role_filter(field_name, value):
                    continue

            if value is not None:
                if isinstance(field, (EmbeddedDocumentField,
                                      GenericEmbeddedDocumentField)):
                    value = field.to_mongo(value, role=role)
                else:
                    value = field.to_mongo(value)

            # Handle self generating fields
            if value is None and field._auto_gen:
                value = field.generate()
                self._data[field_name] = value

            if value is not None:
                data[field.db_field] = value

        # If "_id" has not been set, then try and set it
        Document = _import_class("Document")
        if isinstance(self, Document):
            if data["_id"] is None:
                data["_id"] = self._data.get("id", None)

        if data['_id'] is None or (role_filter and
                                   role_filter("id", value)):
            data.pop('_id')

        # Only add _cls if allow_inheritance is True
        if (not hasattr(self, '_meta') or
           not self._meta.get('allow_inheritance', ALLOW_INHERITANCE)):
            data.pop('_cls')

        return data
예제 #9
0
    def to_mongo(self, use_db_field=True):
        """Return as SON data ready for use with MongoDB.
        """
        data = SON()
        data["_id"] = None
        data['_cls'] = self._class_name

        for field_name in self:
            value = self._data.get(field_name, None)
            field = self._fields.get(field_name)
            if field is None and self._dynamic:
                field = self._dynamic_fields.get(field_name)

            if value is not None:
                EmbeddedDocument = _import_class("EmbeddedDocument")
                if isinstance(value,
                              (EmbeddedDocument)) and use_db_field == False:
                    value = field.to_mongo(value, use_db_field)
                else:
                    value = field.to_mongo(value)

            # Handle self generating fields
            if value is None and field._auto_gen:
                value = field.generate()
                self._data[field_name] = value

            if value is not None:
                if use_db_field:
                    data[field.db_field] = value
                else:
                    data[field.name] = value

        # If "_id" has not been set, then try and set it
        Document = _import_class("Document")
        if isinstance(self, Document):
            if data["_id"] is None:
                data["_id"] = self._data.get("id", None)

        if data['_id'] is None:
            data.pop('_id')

        # Only add _cls if allow_inheritance is True
        if (not hasattr(self, '_meta')
                or not self._meta.get('allow_inheritance', ALLOW_INHERITANCE)):
            data.pop('_cls')

        return data
예제 #10
0
    def to_mongo(self):
        """Return as SON data ready for use with MongoDB.
        """
        data = SON()
        data["_id"] = None
        data['_cls'] = self._class_name
        traits = getattr(self.__class__, '_traits', None)
        if traits:
            data['_traits'] = [trait.__name__ for trait in traits]

        for field_name in self:
            value = self._data.get(field_name, None)
            field = self._fields.get(field_name)

            if value is not None:
                value = field.to_mongo(value)

            # Handle self generating fields
            if value is None and field._auto_gen:
                value = field.generate()
                self._data[field_name] = value

            if value is not None:
                data[field.db_field] = value

        # If "_id" has not been set, then try and set it
        if data["_id"] is None:
            data["_id"] = self._data.get("id", None)

        if data['_id'] is None:
            data.pop('_id')

        # Only add _cls if allow_inheritance is True
        if (not hasattr(self, '_meta') or
           not self._meta.get('allow_inheritance', ALLOW_INHERITANCE)):
            data.pop('_cls')

        if not self._dynamic:
            return data

        # Sort dynamic fields by key
        dynamic_fields = sorted(self._dynamic_fields.iteritems(),
                                key=operator.itemgetter(0))
        for name, field in dynamic_fields:
            data[name] = field.to_mongo(self._data.get(name, None))

        return data
예제 #11
0
    def to_mongo(self, use_db_field=True):
        """Return as SON data ready for use with MongoDB.
        """
        data = SON()
        data["_id"] = None
        data['_cls'] = self._class_name

        for field_name in self:
            value = self._data.get(field_name, None)
            field = self._fields.get(field_name)
            if field is None and self._dynamic:
                field = self._dynamic_fields.get(field_name)

            if value is not None:
                EmbeddedDocument = _import_class("EmbeddedDocument")
                if isinstance(value, (EmbeddedDocument)) and use_db_field==False:
                    value = field.to_mongo(value, use_db_field)
                else:
                    value = field.to_mongo(value)

            # Handle self generating fields
            if value is None and field._auto_gen:
                value = field.generate()
                self._data[field_name] = value

            if value is not None:
                if use_db_field:
                    data[field.db_field] = value
                else:
                    data[field.name] = value

        # If "_id" has not been set, then try and set it
        Document = _import_class("Document")
        if isinstance(self, Document):
            if data["_id"] is None:
                data["_id"] = self._data.get("id", None)

        if data['_id'] is None:
            data.pop('_id')

        # Only add _cls if allow_inheritance is True
        if (not hasattr(self, '_meta') or
           not self._meta.get('allow_inheritance', ALLOW_INHERITANCE)):
            data.pop('_cls')

        return data
예제 #12
0
def _gen_find_command(
    coll,
    spec,
    projection,
    skip,
    limit,
    batch_size,
    options,
    read_concern,
    collation=None,
    session=None,
    allow_disk_use=None,
):
    """Generate a find command document."""
    cmd = SON([("find", coll)])
    if "$query" in spec:
        cmd.update([(_MODIFIERS[key], val) if key in _MODIFIERS else (key, val)
                    for key, val in spec.items()])
        if "$explain" in cmd:
            cmd.pop("$explain")
        if "$readPreference" in cmd:
            cmd.pop("$readPreference")
    else:
        cmd["filter"] = spec

    if projection:
        cmd["projection"] = projection
    if skip:
        cmd["skip"] = skip
    if limit:
        cmd["limit"] = abs(limit)
        if limit < 0:
            cmd["singleBatch"] = True
    if batch_size:
        cmd["batchSize"] = batch_size
    if read_concern.level and not (session and session.in_transaction):
        cmd["readConcern"] = read_concern.document
    if collation:
        cmd["collation"] = collation
    if allow_disk_use is not None:
        cmd["allowDiskUse"] = allow_disk_use
    if options:
        cmd.update([(opt, True) for opt, val in _OPTIONS.items()
                    if options & val])

    return cmd
예제 #13
0
    def to_mongo(self):
        """Return as SON data ready for use with MongoDB.
        """
        data = SON()
        data["_id"] = None
        data['_cls'] = self._class_name

        for field_name in self:
            value = self._data.get(field_name, None)
            field = self._fields.get(field_name)

            if value is not None:
                value = field.to_mongo(value)

            # Handle self generating fields
            if value is None and field._auto_gen:
                value = field.generate()
                self._data[field_name] = value

            if value is not None:
                data[field.db_field] = value

        # If "_id" has not been set, then try and set it
        if data["_id"] is None:
            data["_id"] = self._data.get("id", None)

        if data['_id'] is None:
            data.pop('_id')

        # Only add _cls if allow_inheritance is True
        if (not hasattr(self, '_meta')
                or not self._meta.get('allow_inheritance', ALLOW_INHERITANCE)):
            data.pop('_cls')

        if not self._dynamic:
            return data

        # Sort dynamic fields by key
        dynamic_fields = sorted(self._dynamic_fields.iteritems(),
                                key=operator.itemgetter(0))
        for name, field in dynamic_fields:
            data[name] = field.to_mongo(self._data.get(name, None))

        return data
예제 #14
0
    def to_mongo(self,deref=True):
        """Return as SON data ready for use with MongoDB.
        """
        data = SON()
        data["_id"] = None
        data['_cls'] = self._class_name
        ReferenceField = _import_class('ReferenceField')
        for field_name in self:
            value = self._data.get(field_name, None)
            field = self._fields.get(field_name)
            if field is None and self._dynamic:
                field = self._dynamic_fields.get(field_name)

            if value is not None and not isinstance(value,ReferenceField):
                value = field.to_mongo(value)
            elif value is not None and isinstance(field,ReferenceField):
                value = field.to_mongo(value,deref)
            #print field,value

            # Handle self generating fields
            if value is None and field._auto_gen:
                value = field.generate()
                self._data[field_name] = value

            if value is not None:
                data[field.db_field] = value

        # If "_id" has not been set, then try and set it
        Document = _import_class("Document")
        if isinstance(self, Document):
            if data["_id"] is None:
                data["_id"] = self._data.get("id", None)

        if data['_id'] is None:
            data.pop('_id')

        # Only add _cls if allow_inheritance is True
        if (not hasattr(self, '_meta') or
           not self._meta.get('allow_inheritance', ALLOW_INHERITANCE)):
            data.pop('_cls')
        #print 'data',data
        return data
예제 #15
0
def _gen_find_command(coll, spec, projection, skip, limit, batch_size, options,
                      session, client, read_concern=DEFAULT_READ_CONCERN,
                      collation=None):
    """Generate a find command document."""
    cmd = SON([('find', coll)])
    if '$query' in spec:
        cmd.update([(_MODIFIERS[key], val) if key in _MODIFIERS else (key, val)
                    for key, val in spec.items()])
        if '$explain' in cmd:
            cmd.pop('$explain')
        if '$readPreference' in cmd:
            cmd.pop('$readPreference')
    else:
        cmd['filter'] = spec

    if projection:
        cmd['projection'] = projection
    if skip:
        cmd['skip'] = skip
    if limit:
        cmd['limit'] = abs(limit)
        if limit < 0:
            cmd['singleBatch'] = True
    if batch_size:
        cmd['batchSize'] = batch_size
    if read_concern.level:
        cmd['readConcern'] = read_concern.document
    if collation:
        cmd['collation'] = collation
    if options:
        cmd.update([(opt, True)
                    for opt, val in _OPTIONS.items()
                    if options & val])
    if session:
        cmd['lsid'] = session._use_lsid()
        if (session.options.causal_consistency
                and session.operation_time is not None):
            cmd.setdefault(
                'readConcern', {})['afterClusterTime'] = session.operation_time
    if client:
        client._send_cluster_time(cmd, session)
    return cmd
예제 #16
0
    def to_mongo(self):
        """Return as SON data ready for use with MongoDB.
        """
        data = SON()
        data["_id"] = None
        data["_cls"] = self._class_name

        for field_name in self:
            value = self._data.get(field_name, None)
            field = self._fields.get(field_name)
            if field is None and self._dynamic:
                field = self._dynamic_fields.get(field_name)

            if value is not None:
                value = field.to_mongo(value)

            # Handle self generating fields
            if value is None and field._auto_gen:
                value = field.generate()
                self._data[field_name] = value

            if value is not None:
                data[field.db_field] = value

        # If "_id" has not been set, then try and set it
        Document = _import_class("Document")
        if isinstance(self, Document):
            if data["_id"] is None:
                data["_id"] = self._data.get("id", None)

        if data["_id"] is None:
            data.pop("_id")

        # Only add _cls if allow_inheritance is True
        if not hasattr(self, "_meta") or not self._meta.get("allow_inheritance", ALLOW_INHERITANCE):
            data.pop("_cls")

        return data
예제 #17
0
    def to_mongo(self, use_db_field=True, fields=None):
        """
        Return as SON data ready for use with MongoDB.
        """
        if not fields:
            fields = []

        data = SON()
        data["_id"] = None
        data['_cls'] = self._class_name
        EmbeddedDocumentField = _import_class("EmbeddedDocumentField")
        # only root fields ['test1.a', 'test2'] => ['test1', 'test2']
        root_fields = set([f.split('.')[0] for f in fields])

        for field_name in self:
            if root_fields and field_name not in root_fields:
                continue

            value = self._data.get(field_name, None)
            field = self._fields.get(field_name)

            if field is None and self._dynamic:
                field = self._dynamic_fields.get(field_name)

            if value is not None:

                if isinstance(field, EmbeddedDocumentField):
                    if fields:
                        key = '%s.' % field_name
                        embedded_fields = [
                            i.replace(key, '') for i in fields
                            if i.startswith(key)
                        ]

                    else:
                        embedded_fields = []

                    value = field.to_mongo(value,
                                           use_db_field=use_db_field,
                                           fields=embedded_fields)
                else:
                    value = field.to_mongo(value)

            # Handle self generating fields
            if value is None and field._auto_gen:
                value = field.generate()
                self._data[field_name] = value

            if value is not None:
                if use_db_field:
                    data[field.db_field] = value
                else:
                    data[field.name] = value

        # If "_id" has not been set, then try and set it
        Document = _import_class("Document")
        if isinstance(self, Document):
            if data["_id"] is None:
                data["_id"] = self._data.get("id", None)

        if data['_id'] is None:
            data.pop('_id')

        # Only add _cls if allow_inheritance is True
        if (not hasattr(self, '_meta')
                or not self._meta.get('allow_inheritance', ALLOW_INHERITANCE)):
            data.pop('_cls')

        return data
예제 #18
0
    def to_mongo(self, use_db_field=True, fields=[]):
        """
        Return as SON data ready for use with MongoDB.
        """
        data = SON()
        data["_id"] = None
        data['_cls'] = self._class_name
        EmbeddedDocumentField = _import_class("EmbeddedDocumentField")
        # only root fields ['test1.a', 'test2'] => ['test1', 'test2']
        root_fields = set([f.split('.')[0] for f in fields])

        for field_name in self:
            if root_fields and field_name not in root_fields:
                continue

            value = self._data.get(field_name, None)
            field = self._fields.get(field_name)

            if field is None and self._dynamic:
                field = self._dynamic_fields.get(field_name)

            if value is not None:

                if isinstance(field, (EmbeddedDocumentField)):
                    if fields:
                        key = '%s.' % field_name
                        embedded_fields = [
                            i.replace(key, '') for i in fields
                            if i.startswith(key)]

                    else:
                        embedded_fields = []

                    value = field.to_mongo(value, use_db_field=use_db_field,
                                           fields=embedded_fields)
                else:
                    value = field.to_mongo(value)

            # Handle self generating fields
            if value is None and field._auto_gen:
                value = field.generate()
                self._data[field_name] = value

            if value is not None:
                if use_db_field:
                    data[field.db_field] = value
                else:
                    data[field.name] = value

        # If "_id" has not been set, then try and set it
        Document = _import_class("Document")
        if isinstance(self, Document):
            if data["_id"] is None:
                data["_id"] = self._data.get("id", None)

        if data['_id'] is None:
            data.pop('_id')

        # Only add _cls if allow_inheritance is True
        if (not hasattr(self, '_meta') or
                not self._meta.get('allow_inheritance', ALLOW_INHERITANCE)):
            data.pop('_cls')

        return data